00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "config.h"
00019
00020 #include <stdio.h>
00021 #include <sys/file.h>
00022 #include <string.h>
00023 #include <math.h>
00024
00025 #define FAST_WHICHSPECIAL
00026
00027 #include "create.h"
00028
00029 #define _GLUE_C
00030
00031
00032 #include "mech.h"
00033 #include "mech.events.h"
00034 #include "debug.h"
00035 #include "mechrep.h"
00036 #include "mech.tech.h"
00037 #include "autopilot.h"
00038 #include "turret.h"
00039 #include "p.ds.turret.h"
00040 #include "coolmenu.h"
00041 #include "p.bsuit.h"
00042 #include "glue.h"
00043 #include "mux_tree.h"
00044 #include "powers.h"
00045 #include "ansi.h"
00046 #include "coolmenu.h"
00047 #include "mycool.h"
00048 #include "p.mux_tree.h"
00049 #include "p.mechfile.h"
00050 #include "p.mech.stat.h"
00051 #include "p.mech.partnames.h"
00052 #include "debug.h"
00053
00054
00055
00056
00057
00058
00059 int HandledCommand(dbref player, dbref loc, char *command);
00060
00061
00062 void CreateNewSpecialObject(dbref player, dbref key);
00063 void DisposeSpecialObject(dbref player, dbref key);
00064 void list_hashstat(dbref player, const char *tab_name, HASHTAB * htab);
00065 void raw_notify(dbref player, const char *msg);
00066 void AddEntry(Tree * tree, muxkey_t key, dtype_t type, dsize_t size,
00067 void *data);
00068 void DeleteEntry(Tree * tree, muxkey_t key);
00069 int SaveTree(FILE * f, Tree tree);
00070 void UpdateTree(FILE * f, Tree * tree, int (*sizefunc) (int));
00071 void GoThruTree(Tree tree, int (*func) (Node *));
00072
00073
00074 void *NewSpecialObject(int id, int type);
00075 void *FindObjectsData(dbref key);
00076 static Node *FindObjectsNode(dbref key);
00077 static void DoSpecialObjectHelp(dbref player, char *type, int id, int loc,
00078 int powerneeded, int objid, char *arg);
00079 void initialize_colorize();
00080
00081 #ifndef FAST_WHICHSPECIAL
00082
00083 #define WhichSpecialS WhichSpecial
00084 #define WhichType(node) WhichSpecial(NodeKey(node))
00085 int WhichSpecial(dbref key);
00086
00087 #else
00088
00089 #define WhichType(node) NodeType(node)
00090 int WhichSpecial(dbref key);
00091 static int WhichSpecialS(dbref key);
00092
00093 #endif
00094
00095
00096
00097 HASHTAB SpecialCommandHash[NUM_SPECIAL_OBJECTS];
00098 Tree xcode_tree = NULL;
00099 extern int map_sizefun();
00100
00101 static int Can_Use_Command(MECH * mech, int cmdflag)
00102 {
00103 #define TYPE2FLAG(a) \
00104 ((a)==CLASS_MECH?GFLAG_MECH:(a)==CLASS_VEH_GROUND?GFLAG_GROUNDVEH:\
00105 (a)==CLASS_AERO?GFLAG_AERO:DropShip(a)?GFLAG_DS:(a)==CLASS_VTOL?GFLAG_VTOL:\
00106 (a)==CLASS_VEH_NAVAL?GFLAG_NAVAL:\
00107 (a)==CLASS_BSUIT?GFLAG_BSUIT:\
00108 (a)==CLASS_MW?GFLAG_MW:0)
00109 int i;
00110
00111 if(!cmdflag)
00112 return 1;
00113 if(!mech || !(i = TYPE2FLAG(MechType(mech))))
00114 return 0;
00115 if(cmdflag > 0) {
00116 if(cmdflag & i)
00117 return 1;
00118 } else if(!((0 - cmdflag) & i))
00119 return 1;
00120 return 0;
00121 }
00122
00123 int HandledCommand_sub(dbref player, dbref location, char *command)
00124 {
00125 struct SpecialObjectStruct *typeOfObject;
00126 Node *n = NULL;
00127 int type;
00128 CommandsStruct *cmd;
00129 HASHTAB *damnedhash;
00130 char *tmpc, *tmpchar;
00131 int ishelp;
00132
00133 type = WhichSpecial(location);
00134 if(type < 0 || (SpecialObjects[type].datasize > 0 &&
00135 !(n = FindNode(xcode_tree, location)))) {
00136 if(type >= 0 || !Hardcode(location) || Zombie(location))
00137 return 0;
00138 if((type = WhichSpecialS(location)) >= 0) {
00139 if(SpecialObjects[type].datasize > 0)
00140 return 0;
00141 } else
00142 return 0;
00143 }
00144 #ifdef FAST_WHICHSPECIAL
00145 if(type > NUM_SPECIAL_OBJECTS)
00146 return 0;
00147 #endif
00148 typeOfObject = &SpecialObjects[type];
00149 damnedhash = &SpecialCommandHash[type];
00150 tmpc = strstr(command, " ");
00151 if(tmpc)
00152 *tmpc = 0;
00153 ishelp = !strcmp(command, "HELP");
00154 for(tmpchar = command; *tmpchar; tmpchar++)
00155 *tmpchar = ToLower(*tmpchar);
00156 cmd = (CommandsStruct *) hashfind(command, &SpecialCommandHash[type]);
00157 if(tmpc)
00158 *tmpc = ' ';
00159 if(cmd && (type != GTYPE_MECH || (type == GTYPE_MECH &&
00160 Can_Use_Command(((MECH *)
00161 (NodeData(n))),
00162 cmd->flag)))) {
00163 #define SKIPSTUFF(a) while (*a && *a != ' ') a++;while (*a == ' ') a++
00164 if(cmd->helpmsg[0] != '@' ||
00165 Have_MechPower(Owner(player), typeOfObject->power_needed)) {
00166 SKIPSTUFF(command);
00167 cmd->func(player, !n ? NULL : NodeData(n), command);
00168 } else
00169 notify(player, "Sorry, that command is restricted!");
00170 return 1;
00171 } else if(ishelp) {
00172 SKIPSTUFF(command);
00173 DoSpecialObjectHelp(player, typeOfObject->type, type, location,
00174 typeOfObject->power_needed, location, command);
00175 return 1;
00176 }
00177 return 0;
00178 }
00179
00180 #define OkayHcode(a) (a >= 0 && Hardcode(a) && !Zombie(a))
00181
00182
00183 int HandledCommand(dbref player, dbref loc, char *command)
00184 {
00185 dbref curr, temp;
00186
00187 if(Slave(player))
00188 return 0;
00189 if(strlen(command) > (LBUF_SIZE - MBUF_SIZE))
00190 return 0;
00191 if(OkayHcode(player) && HandledCommand_sub(player, player, command))
00192 return 1;
00193 if(OkayHcode(loc) && HandledCommand_sub(player, loc, command))
00194 return 1;
00195 SAFE_DOLIST(curr, temp, Contents(player)) {
00196 if(OkayHcode(curr))
00197 if(HandledCommand_sub(player, curr, command))
00198 return 1;
00199 #if 0
00200 if(Has_contents(curr))
00201 if(HandledCommand_contents(player, curr, command))
00202 return 1;
00203 #endif
00204 }
00205 return 0;
00206 }
00207
00208 void InitSpecialHash(int which);
00209 void initialize_partname_tables();
00210
00211 static MECH *global_kludge_mech;
00212 int global_specials = NUM_SPECIAL_OBJECTS;
00213
00214 static int remove_from_all_maps_func(Node * tmp)
00215 {
00216 if(WhichType(tmp) == GTYPE_MAP) {
00217 MAP *map;
00218 int i;
00219
00220 if(!(map = getMap(NodeKey(tmp))))
00221 return 1;
00222 for(i = 0; i < map->first_free; i++)
00223 if(map->mechsOnMap[i] == global_kludge_mech->mynum)
00224 map->mechsOnMap[i] = -1;
00225 }
00226 return 1;
00227 }
00228
00229 void mech_remove_from_all_maps(MECH * mech)
00230 {
00231 global_kludge_mech = mech;
00232 GoThruTree(xcode_tree, remove_from_all_maps_func);
00233 }
00234
00235 static dbref except_map = -1;
00236
00237 static int remove_from_all_maps_except_func(Node * tmp)
00238 {
00239 if(WhichType(tmp) == GTYPE_MAP) {
00240 int i;
00241 MAP *map;
00242
00243 if(NodeKey(tmp) == except_map)
00244 return 1;
00245 if(!(map = getMap(NodeKey(tmp))))
00246 return 1;
00247 for(i = 0; i < map->first_free; i++)
00248 if(map->mechsOnMap[i] == global_kludge_mech->mynum)
00249 map->mechsOnMap[i] = -1;
00250 }
00251 return 1;
00252 }
00253 void mech_remove_from_all_maps_except(MECH * mech, int num)
00254 {
00255 global_kludge_mech = mech;
00256 except_map = num;
00257 GoThruTree(xcode_tree, remove_from_all_maps_except_func);
00258 except_map = -1;
00259 }
00260
00261 static int load_update2(Node * tmp)
00262 {
00263 int i = WhichType(tmp);;
00264
00265 if(i == GTYPE_MECH)
00266 mech_map_consistency_check(NodeData(tmp));
00267 return 1;
00268 }
00269
00270 static int load_update4(Node * tmp)
00271 {
00272 MECH *mech;
00273 MAP *map;
00274
00275 if(WhichType(tmp) == GTYPE_MECH) {
00276 mech = NodeData(tmp);
00277 if(!(map = getMap(mech->mapindex))) {
00278
00279 if((map = getMap(Location(mech->mynum))))
00280 mech_Rsetmapindex(GOD, mech, tprintf("%d",
00281 Location(mech->mynum)));
00282 if(!(map = getMap(mech->mapindex)))
00283 return 1;
00284 }
00285 if(!Started(mech))
00286 return 1;
00287 StartSeeing(mech);
00288 UpdateRecycling(mech);
00289 MaybeMove(mech);
00290
00291 }
00292 return 1;
00293 }
00294
00295 static int load_update3(Node * tmp)
00296 {
00297 int i = WhichType(tmp);
00298
00299 if(i == GTYPE_MAP) {
00300 eliminate_empties((MAP *) NodeData(tmp));
00301 recalculate_minefields((MAP *) NodeData(tmp));
00302 }
00303 return 1;
00304 }
00305
00306 static FILE *global_file_kludge;
00307
00308 static int load_update1(Node * tmp)
00309 {
00310 MAP *map;
00311 int doh;
00312 char mapbuffer[MBUF_SIZE];
00313 MECH *mech;
00314 int i;
00315 int ctemp;
00316
00317 switch ((i = WhichType(tmp))) {
00318 case GTYPE_MAP:
00319 map = (MAP *) NodeData(tmp);
00320 bzero(map->mapobj, sizeof(map->mapobj));
00321 map->map = NULL;
00322 strcpy(mapbuffer, map->mapname);
00323 doh = (map->flags & MAPFLAG_MAPO);
00324 if(strcmp(map->mapname, "Default Map"))
00325 map_loadmap(1, map, mapbuffer);
00326 if(!strcmp(map->mapname, "Default Map") || !map->map)
00327 initialize_map_empty(map, NodeKey(tmp));
00328 if(!feof(global_file_kludge)) {
00329 load_mapdynamic(global_file_kludge, map);
00330 if(!feof(global_file_kludge))
00331 if(doh)
00332 load_mapobjs(global_file_kludge, map);
00333 }
00334 if(feof(global_file_kludge)) {
00335 map->first_free = 0;
00336 map->mechflags = NULL;
00337 map->mechsOnMap = NULL;
00338 map->LOSinfo = NULL;
00339 }
00340 debug_fixmap(GOD, map, NULL);
00341 break;
00342 case GTYPE_MECH:
00343 mech = (MECH *) NodeData(tmp);
00344 if(!(FlyingT(mech) && !Landed(mech))) {
00345 MechDesiredSpeed(mech) = 0;
00346 MechSpeed(mech) = 0;
00347 MechVerticalSpeed(mech) = 0;
00348 }
00349 ctemp = MechCocoon(mech);
00350 if(MechCocoon(mech)) {
00351 MechCocoon(mech) = 0;
00352 initiate_ood((dbref) GOD, mech, tprintf("%d %d %d", MechX(mech), MechY(mech), MechZ(mech)));
00353 MechCocoon(mech) = ctemp;
00354 }
00355
00356 if(!FlyingT(mech) && Started(mech) && Jumping(mech))
00357 mech_Rsetxy(GOD, (void *) mech, tprintf("%d %d", MechX(mech),MechY(mech)));
00358
00359 MechStatus(mech) &= ~(BLINDED | UNCONSCIOUS | JUMPING | TOWED);
00360 MechSpecials2(mech) &=
00361 ~(ECM_ENABLED | ECM_DISTURBANCE | ECM_PROTECTED |
00362 ECCM_ENABLED | ANGEL_ECM_ENABLED | ANGEL_ECCM_ENABLED |
00363 ANGEL_ECM_PROTECTED | ANGEL_ECM_DISTURBED);
00364 MechCritStatus(mech) &= ~(JELLIED | LOAD_OK | OWEIGHT_OK | SPEED_OK);
00365 MechWalkXPFactor(mech) = 999;
00366 MechCarrying(mech) = -1;
00367 MechBoomStart(mech) = 0;
00368 MechC3iNetworkSize(mech) = -1;
00369 MechHeatLast(mech) = 0;
00370 MechCommLast(mech) = 0;
00371 if(!(MechXPMod(mech)))
00372 MechXPMod(mech) = 1;
00373 for(i = 0; i < FREQS; i++)
00374 if(mech->freq[i] < 0)
00375 mech->freq[i] = 0;
00376 break;
00377 }
00378 return 1;
00379 }
00380
00381
00382
00383
00384 static int load_autopilot_data(Node * tmp)
00385 {
00386
00387 AUTO *autopilot;
00388 int i;
00389
00390 if(WhichType(tmp) == GTYPE_AUTO) {
00391
00392 autopilot = (AUTO *) NodeData(tmp);
00393
00394
00395
00396 autopilot->commands = dllist_create_list();
00397
00398
00399 autopilot->astar_path = NULL;
00400
00401
00402 autopilot->weaplist = NULL;
00403
00404
00405 for(i = 0; i < AUTO_PROFILE_MAX_SIZE; i++) {
00406 autopilot->profile[i] = NULL;
00407 }
00408
00409
00410
00411
00412
00413 if(!autopilot->mymechnum ||
00414 !(autopilot->mymech = getMech(autopilot->mymechnum))) {
00415 DoStopGun(autopilot);
00416 } else {
00417 if(Gunning(autopilot))
00418 DoStartGun(autopilot);
00419 }
00420
00421
00422 }
00423
00424 return 1;
00425
00426 }
00427
00428 static int get_specialobjectsize(int type)
00429 {
00430 if(type < 0 || type >= NUM_SPECIAL_OBJECTS)
00431 return -1;
00432 return SpecialObjects[type].datasize;
00433 }
00434
00435 #ifdef BT_ADVANCED_ECON
00436 static void load_econdb()
00437 {
00438 FILE *f;
00439
00440 extern unsigned long long int specialcost[SPECIALCOST_SIZE];
00441 extern unsigned long long int ammocost[AMMOCOST_SIZE];
00442 extern unsigned long long int weapcost[WEAPCOST_SIZE];
00443 extern unsigned long long int cargocost[CARGOCOST_SIZE];
00444 extern unsigned long long int bombcost[BOMBCOST_SIZE];
00445 int count;
00446
00447 fprintf(stderr, "LOADING: %s\n", mudconf.econ_db);
00448 f = fopen(mudconf.econ_db, "r");
00449 if(!f) {
00450 fprintf(stderr, "ERROR: %s not found.\n", mudconf.econ_db);
00451 return;
00452 }
00453 count =
00454 fread(&specialcost, sizeof(unsigned long long int), SPECIALCOST_SIZE,
00455 f);
00456 if(count < SPECIALCOST_SIZE) {
00457 fprintf(stderr, "ERROR: %s specialcost read : %d expected %d\n",
00458 mudconf.econ_db, count, SPECIALCOST_SIZE);
00459 fclose(f);
00460 return;
00461 }
00462 count =
00463 fread(&ammocost, sizeof(unsigned long long int), AMMOCOST_SIZE, f);
00464 if(count < AMMOCOST_SIZE) {
00465 fprintf(stderr, "ERROR: %s ammocost read : %d expected %d\n",
00466 mudconf.econ_db, count, AMMOCOST_SIZE);
00467 fclose(f);
00468 return;
00469 }
00470 count =
00471 fread(&weapcost, sizeof(unsigned long long int), WEAPCOST_SIZE, f);
00472 if(count < WEAPCOST_SIZE) {
00473 fprintf(stderr, "ERROR: %s weapcost read : %d expected %d\n",
00474 mudconf.econ_db, count, WEAPCOST_SIZE);
00475 fclose(f);
00476 return;
00477 }
00478 count =
00479 fread(&cargocost, sizeof(unsigned long long int), CARGOCOST_SIZE, f);
00480 if(count < CARGOCOST_SIZE) {
00481 fprintf(stderr, "ERROR: %s cargocost read : %d expected %d\n",
00482 mudconf.econ_db, count, CARGOCOST_SIZE);
00483 fclose(f);
00484 return;
00485 }
00486 count =
00487 fread(&bombcost, sizeof(unsigned long long int), BOMBCOST_SIZE, f);
00488 if(count < BOMBCOST_SIZE) {
00489 fprintf(stderr, "ERROR: %s bombcost read : %d expected %d\n",
00490 mudconf.econ_db, count, BOMBCOST_SIZE);
00491 fclose(f);
00492 return;
00493 }
00494 fclose(f);
00495 fprintf(stderr, "LOADING: %s (done)\n", mudconf.econ_db);
00496 }
00497 #endif
00498
00499 void heartbeat_init();
00500
00501 static void load_xcode()
00502 {
00503 FILE *f;
00504 byte xcode_version;
00505 int filemode;
00506
00507 initialize_colorize();
00508 fprintf(stderr, "LOADING: %s\n", mudconf.hcode_db);
00509 f = my_open_file(mudconf.hcode_db, "r", &filemode);
00510 if(!f) {
00511 fprintf(stderr, "ERROR: %s not found.\n", mudconf.hcode_db);
00512 return;
00513 }
00514 fread(&xcode_version, 1, 1, f);
00515 if(xcode_version != XCODE_VERSION) {
00516 fprintf(stderr,
00517 "LOADING: %s (skipped xcodetree - version difference: %d vs %d)\n",
00518 mudconf.hcode_db, (int) xcode_version, (int) XCODE_VERSION);
00519 return;
00520 }
00521 UpdateTree(f, &xcode_tree, get_specialobjectsize);
00522 global_file_kludge = f;
00523 GoThruTree(xcode_tree, load_update1);
00524 GoThruTree(xcode_tree, load_update2);
00525 GoThruTree(xcode_tree, load_update3);
00526 GoThruTree(xcode_tree, load_update4);
00527
00528
00529 GoThruTree(xcode_tree, load_autopilot_data);
00530
00531 if(!feof(f))
00532 loadrepairs(f);
00533
00534 my_close_file(f, &filemode);
00535 fprintf(stderr, "LOADING: %s (done)\n", mudconf.hcode_db);
00536 #ifdef BT_ADVANCED_ECON
00537 load_econdb();
00538 #endif
00539 heartbeat_init();
00540 }
00541
00542 static int zappable_node;
00543
00544 static int zap_check(Node * n)
00545 {
00546 if(zappable_node >= 0)
00547 return 0;
00548 if(!Hardcode(NodeKey(n))) {
00549 zappable_node = NodeKey(n);
00550 return 0;
00551 }
00552 return 1;
00553 }
00554
00555 void zap_unneccessary_hcode()
00556 {
00557 while (1) {
00558 zappable_node = -1;
00559 GoThruTree(xcode_tree, zap_check);
00560 if(zappable_node >= 0)
00561 DeleteEntry(&xcode_tree, zappable_node);
00562 else
00563 break;
00564 }
00565 }
00566
00567 void LoadSpecialObjects(void)
00568 {
00569 dbref i;
00570 int id, brand;
00571 int type;
00572 void *tmpdat;
00573
00574 muxevent_initialize();
00575 muxevent_count_initialize();
00576 init_stat();
00577 initialize_partname_tables();
00578 for(i = 0; MissileHitTable[i].key != -1; i++) {
00579 if(find_matching_vlong_part(MissileHitTable[i].name, NULL, &id,
00580 &brand))
00581 MissileHitTable[i].key = Weapon2I(id);
00582 else
00583 MissileHitTable[i].key = -2;
00584 }
00585
00586
00587 for(i = 0; i < mudstate.db_top; i++)
00588 if(Hardcode(i) && !Going(i) && !Halted(i)) {
00589 type = WhichSpecialS(i);
00590 if(type >= 0) {
00591 if(SpecialObjects[type].datasize > 0)
00592 tmpdat = NewSpecialObject(i, type);
00593 else
00594 tmpdat = NULL;
00595 } else
00596 c_Hardcode(i);
00597 }
00598 for(i = 0; i < NUM_SPECIAL_OBJECTS; i++) {
00599 InitSpecialHash(i);
00600 if(!SpecialObjects[i].updatefunc)
00601 SpecialObjects[i].updateTime = 0;
00602 }
00603 init_btechstats();
00604 load_xcode();
00605 zap_unneccessary_hcode();
00606 }
00607
00608 static FILE *global_file_kludge;
00609
00610 static int save_maps_func(Node * tmp)
00611 {
00612 MAP *map;
00613
00614 if(WhichType(tmp) == GTYPE_MAP) {
00615
00616 map = (MAP *) NodeData(tmp);
00617 save_mapdynamic(global_file_kludge, map);
00618 if(map->flags & MAPFLAG_MAPO)
00619 save_mapobjs(global_file_kludge, map);
00620 }
00621 return 1;
00622 }
00623
00624
00625
00626
00627
00628
00629
00630
00631 static int save_autopilot_data(Node * tmp)
00632 {
00633
00634 AUTO *a;
00635
00636 if(WhichType(tmp) == GTYPE_AUTO) {
00637
00638 a = (AUTO *) NodeData(tmp);
00639
00640
00641 auto_save_commands(global_file_kludge, a);
00642
00643
00644
00645 }
00646
00647 return 1;
00648
00649 }
00650
00651 void ChangeSpecialObjects(int i)
00652 {
00653
00654
00655
00656 }
00657
00658 #ifdef BT_ADVANCED_ECON
00659 static void save_econdb(char *target, int i)
00660 {
00661 FILE *f;
00662 extern unsigned long long int specialcost[SPECIALCOST_SIZE];
00663 extern unsigned long long int ammocost[AMMOCOST_SIZE];
00664 extern unsigned long long int weapcost[WEAPCOST_SIZE];
00665 extern unsigned long long int cargocost[CARGOCOST_SIZE];
00666 extern unsigned long long int bombcost[BOMBCOST_SIZE];
00667 int count;
00668
00669 switch (i) {
00670 case DUMP_KILLED:
00671 sprintf(target, "%s.KILLED", mudconf.econ_db);
00672 break;
00673 case DUMP_CRASHED:
00674 sprintf(target, "%s.CRASHED", mudconf.econ_db);
00675 break;
00676 default:
00677 sprintf(target, "%s.tmp", mudconf.econ_db);
00678 break;
00679 }
00680 f = fopen(target, "w");
00681 if(!f) {
00682 log_perror("SAVE", "FAIL", "Opening econ-save file", target);
00683 SendDB("ERROR occured during opening of new econ-savefile.");
00684 return;
00685 }
00686 count =
00687 fwrite(&specialcost, sizeof(unsigned long long int), SPECIALCOST_SIZE,
00688 f);
00689 if(count < SPECIALCOST_SIZE) {
00690 log_perror("SAVE", "FAIL",
00691 tprintf("ERROR: %s specialcost wrote : %d expected %d",
00692 target, count, SPECIALCOST_SIZE), target);
00693 SendDB("ERROR occured during saving of econ-save file");
00694 fclose(f);
00695 return;
00696 }
00697 count =
00698 fwrite(&ammocost, sizeof(unsigned long long int), AMMOCOST_SIZE, f);
00699 if(count < AMMOCOST_SIZE) {
00700 log_perror("SAVE", "FAIL",
00701 tprintf("ERROR: %s ammocost wrote : %d expected %d",
00702 target, count, AMMOCOST_SIZE), target);
00703 SendDB("ERROR occured during saving of econ-save file");
00704 fclose(f);
00705 return;
00706 }
00707 count =
00708 fwrite(&weapcost, sizeof(unsigned long long int), WEAPCOST_SIZE, f);
00709 if(count < WEAPCOST_SIZE) {
00710 log_perror("SAVE", "FAIL",
00711 tprintf("ERROR: %s weapcost wrote : %d expected %d",
00712 target, count, WEAPCOST_SIZE), target);
00713 SendDB("ERROR occured during saving of econ-save file");
00714 fclose(f);
00715 return;
00716 }
00717 count =
00718 fwrite(&cargocost, sizeof(unsigned long long int), CARGOCOST_SIZE, f);
00719 if(count < CARGOCOST_SIZE) {
00720 log_perror("SAVE", "FAIL",
00721 tprintf("ERROR: %s cargocost wrote : %d expected %d",
00722 target, count, CARGOCOST_SIZE), target);
00723 SendDB("ERROR occured during saving of econ-save file");
00724 fclose(f);
00725 return;
00726 }
00727 count =
00728 fwrite(&bombcost, sizeof(unsigned long long int), BOMBCOST_SIZE, f);
00729 if(count < BOMBCOST_SIZE) {
00730 log_perror("SAVE", "FAIL",
00731 tprintf("ERROR: %s bombcost wrote : %d expected %d",
00732 target, count, BOMBCOST_SIZE), target);
00733 SendDB("ERROR occured during saving of econ-save file");
00734 fclose(f);
00735 return;
00736 }
00737 fclose(f);
00738 if(i == DUMP_RESTART || i == DUMP_NORMAL) {
00739 if(rename(target, mudconf.econ_db) < 0) {
00740 log_perror("SAV", "FAIL", "Renaming econ-save file ", target);
00741 SendDB("ERROR occured during renaming of econ save-file.");
00742 }
00743 }
00744 }
00745 #endif
00746
00747 void SaveSpecialObjects(int i)
00748 {
00749 FILE *f;
00750 int filemode, count;
00751 byte xcode_version = XCODE_VERSION;
00752 char target[LBUF_SIZE];
00753
00754 switch (i) {
00755 case DUMP_KILLED:
00756 sprintf(target, "%s.KILLED", mudconf.hcode_db);
00757 break;
00758 case DUMP_CRASHED:
00759 sprintf(target, "%s.CRASHED", mudconf.hcode_db);
00760 break;
00761 default:
00762 sprintf(target, "%s.tmp", mudconf.hcode_db);
00763 break;
00764 }
00765 f = my_open_file(target, "w", &filemode);
00766 if(!f) {
00767 log_perror("SAV", "FAIL", "Opening new hcode-save file", target);
00768 SendDB("ERROR occured during opening of new hcode-savefile.");
00769 return;
00770 }
00771 fwrite(&xcode_version, 1, 1, f);
00772 count = SaveTree(f, xcode_tree);
00773 global_file_kludge = f;
00774
00775 GoThruTree(xcode_tree, save_maps_func);
00776
00777
00778
00779
00780 saverepairs(f);
00781 my_close_file(f, &filemode);
00782 if(i == DUMP_RESTART || i == DUMP_NORMAL) {
00783 if(rename(mudconf.hcode_db, tprintf("%s.prev", mudconf.hcode_db))
00784 < 0) {
00785 log_perror("SAV", "FAIL", "Renaming old hcode-save file ",
00786 target);
00787 SendDB("ERROR occured during renaming of old hcode save-file.");
00788 }
00789 if(rename(target, mudconf.hcode_db) < 0) {
00790 log_perror("SAV", "FAIL", "Renaming new hcode-save file ",
00791 target);
00792 SendDB("ERROR occured during renaming of new hcode save-file.");
00793 }
00794 }
00795 if(count)
00796 SendDB(tprintf("Hcode saved. %d xcode entries dumped.", count));
00797 #ifdef BT_ADVANCED_ECON
00798 save_econdb(target, i);
00799 #endif
00800 }
00801
00802 static int UpdateSpecialObject_func(Node * tmp)
00803 {
00804 int i;
00805
00806 i = WhichType(tmp);
00807 if(!SpecialObjects[i].updateTime)
00808 return 1;
00809 if((mudstate.now % SpecialObjects[i].updateTime))
00810 return 1;
00811 SpecialObjects[i].updatefunc(NodeKey(tmp), NodeData(tmp));
00812 return 1;
00813 }
00814
00815
00816
00817
00818
00819
00820 static time_t lastrun = 0;
00821 void UpdateSpecialObjects(void)
00822 {
00823 char *cmdsave;
00824 int i;
00825 int times = lastrun ? (mudstate.now - lastrun) : 1;
00826
00827 if(times > 20)
00828 times = 20;
00829
00830 cmdsave = mudstate.debug_cmd;
00831 for(i = 0; i < times; i++) {
00832 muxevent_run();
00833 mudstate.debug_cmd = (char *) "< Generic hcode update handler>";
00834 GoThruTree(xcode_tree, UpdateSpecialObject_func);
00835 }
00836 lastrun = mudstate.now;
00837 mudstate.debug_cmd = cmdsave;
00838 }
00839
00840 void *NewSpecialObject(int id, int type)
00841 {
00842 void *foo;
00843 int i;
00844 dbref *t;
00845
00846 if(SpecialObjects[type].datasize) {
00847 Create(foo, char, (i = SpecialObjects[type].datasize));
00848
00849 t = (dbref *) foo;
00850 *t = id;
00851 if(SpecialObjects[type].allocfreefunc)
00852 SpecialObjects[type].allocfreefunc(id, &(foo), SPECIAL_ALLOC);
00853 AddEntry(&xcode_tree, id, type, i, foo);
00854 }
00855 return foo;
00856 }
00857
00858 void CreateNewSpecialObject(dbref player, dbref key)
00859 {
00860 void *new;
00861 struct SpecialObjectStruct *typeOfObject;
00862 int type;
00863 char *str;
00864
00865 str = silly_atr_get(key, A_XTYPE);
00866 if(!(str && *str)) {
00867 notify(player,
00868 "You must first set the XTYPE using @xtype <object>=<type>");
00869 notify(player, "Valid XTYPEs include: MECH, MECHREP, MAP, DEBUG, "
00870 "AUTOPILOT, TURRET.");
00871 notify(player, "Resetting hardcode flag.");
00872 c_Hardcode(key);
00873 return;
00874 }
00875
00876
00877 type = WhichSpecialS(key);
00878 if(type > -1) {
00879
00880 typeOfObject = &SpecialObjects[type];
00881 if(typeOfObject->datasize) {
00882 new = NewSpecialObject(key, type);
00883 if(!new)
00884 notify(player, "Memory allocation failure!");
00885 }
00886 } else {
00887 notify(player, "That is not a valid XTYPE!");
00888 notify(player, "Valid XTYPEs include: MECH, MECHREP, MAP, DEBUG, "
00889 "AUTOPILOT, TURRET.");
00890 notify(player, "Resetting HARDCODE flag.");
00891 c_Hardcode(key);
00892 }
00893 }
00894
00895 void DisposeSpecialObject(dbref player, dbref key)
00896 {
00897 Node *tmp;
00898 int i;
00899 struct SpecialObjectStruct *typeOfObject;
00900
00901 tmp = FindNode(xcode_tree, key);
00902
00903 i = WhichSpecialS(key);
00904 if(i < 0) {
00905 notify(player,
00906 "CRITICAL: Unable to free data, inconsistency somewhere. Please");
00907 notify(player, "contact a wizard about this _NOW_!");
00908 return;
00909 }
00910 typeOfObject = &SpecialObjects[i];
00911
00912 if(typeOfObject->datasize > 0 && WhichSpecial(key) != i) {
00913 notify(player,
00914 "Semi-critical error has occured. For some reason the object's data differs\nfrom the data on the object. Please contact a wizard about this.");
00915 i = WhichSpecial(key);
00916 }
00917 if(tmp) {
00918 void *t = NodeData(tmp);
00919
00920 if(typeOfObject->allocfreefunc)
00921 typeOfObject->allocfreefunc(key, &NodeData(tmp), SPECIAL_FREE);
00922 NodeData(tmp) = NULL;
00923 DeleteEntry(&xcode_tree, key);
00924 muxevent_remove_data(t);
00925 free(t);
00926 } else if(typeOfObject->datasize > 0) {
00927 notify(player, "This object is not in the special object DBASE.");
00928 notify(player, "Please contact a wizard about this bug. ");
00929 }
00930 }
00931
00932 void Dump_Mech(dbref player, int type, char *typestr)
00933 {
00934 notify(player, "Support discontinued. Bother a wiz if this bothers you.");
00935 #if 0
00936 MECH *mech;
00937 char buff[100];
00938 int i, running = 0, count = 0;
00939 Node *temp;
00940
00941 notify(player, "ID # STATUS MAP # PILOT #");
00942 notify(player, "----------------------------------------");
00943 for(temp = TreeTop(xcode_tree); temp; temp = TreeNext(temp))
00944 if(WhichSpecial((i = NodeKey(temp))) == type) {
00945 mech = (MECH *) NodeData(temp);
00946 sprintf(buff, "#%5d %-8s #%5d #%5d", mech->mynum,
00947 !Started(mech) ? "SHUTDOWN" : "RUNNING", mech->mapindex,
00948 MechPilot(mech));
00949 notify(player, buff);
00950 if(MechStatus(mech) & STARTED)
00951 running++;
00952 count++;
00953 }
00954 sprintf(buff, "%d %ss running out of %d %ss allocated.", running,
00955 typestr, count, typestr);
00956 notify(player, buff);
00957 notify(player, "Done listing");
00958 #endif
00959 }
00960
00961 void DumpMechs(dbref player)
00962 {
00963 Dump_Mech(player, GTYPE_MECH, "mech");
00964 }
00965
00966 void DumpMaps(dbref player)
00967 {
00968 notify(player, "Support discontinued. Bother a wiz if this bothers you.");
00969 #if 0
00970 MAP *map;
00971 char buff[100];
00972 int j, count;
00973 Node *temp;
00974
00975 notify(player, "MAP # NAME X x Y MECHS");
00976 notify(player, "-------------------------------------------");
00977 for(temp = TreeTop(xcode_tree); temp; temp = TreeNext(temp))
00978 if(WhichSpecial(NodeKey(temp)) == GTYPE_MAP) {
00979 count = 0;
00980 map = (MAP *) NodeData(temp);
00981 for(j = 0; j < map->first_free; j++)
00982 if(map->mechsOnMap[j] != -1)
00983 count++;
00984 sprintf(buff, "#%5d %-17.17s %3d x%3d %d", map->mynum,
00985 map->mapname, map->map_width, map->map_height, count);
00986 notify(player, buff);
00987 }
00988 notify(player, "Done listing");
00989 #endif
00990 }
00991
00992
00993 #ifdef FAST_WHICHSPECIAL
00994 int WhichSpecial(dbref key)
00995 {
00996 Node *n;
00997
00998 if(!Good_obj(key))
00999 return -1;
01000 if(!Hardcode(key))
01001 return -1;
01002 if(!(n = FindObjectsNode(key)))
01003 return -1;
01004 return NodeType(n);
01005 }
01006
01007 #endif
01008
01009 #ifdef FAST_WHICHSPECIAL
01010 static int WhichSpecialS(dbref key)
01011 #else
01012 int WhichSpecial(dbref key)
01013 #endif
01014 {
01015 int i;
01016 int returnValue = -1;
01017 char *str;
01018
01019 if(!Hardcode(key))
01020 return -1;
01021 str = silly_atr_get(key, A_XTYPE);
01022 if(str && *str) {
01023 for(i = 0; i < NUM_SPECIAL_OBJECTS; i++) {
01024 if(!strcmp(SpecialObjects[i].type, str)) {
01025 returnValue = i;
01026 break;
01027 }
01028 }
01029 }
01030 return (returnValue);
01031 }
01032
01033 int IsMech(dbref num)
01034 {
01035 return WhichSpecial(num) == GTYPE_MECH;
01036 }
01037
01038 int IsAuto(dbref num)
01039 {
01040 return WhichSpecial(num) == GTYPE_AUTO;
01041 }
01042
01043 int IsMap(dbref num)
01044 {
01045 return WhichSpecial(num) == GTYPE_MAP;
01046 }
01047
01048
01049 static Node *FindObjectsNode(dbref key)
01050 {
01051 Node *tmp;
01052
01053 if((tmp = FindNode(xcode_tree, (int) key)))
01054 return tmp;
01055 return NULL;
01056 }
01057
01058 void *FindObjectsData(dbref key)
01059 {
01060 Node *tmp;
01061
01062 if((tmp = FindObjectsNode(key)))
01063 return NodeData(tmp);
01064 return NULL;
01065 }
01066
01067 char *center_string(char *c, int len)
01068 {
01069 static char buf[LBUF_SIZE];
01070 int l = strlen(c);
01071 int p, i;
01072
01073 p = MAX(0, (len - l) / 2);
01074 for(i = 0; i < p; i++)
01075 buf[i] = ' ';
01076 strcpy(buf + p, c);
01077 return buf;
01078 }
01079
01080 static void help_color_initialize(char *from, char *to)
01081 {
01082 int i;
01083 char buf[LBUF_SIZE];
01084
01085 for(i = 0; from[i] && from[i] != ' '; i++);
01086 if(from[i]) {
01087
01088
01089 strncpy(buf, from, i);
01090 buf[i] = 0;
01091 sprintf(to, "%s%s%s %s", "%ch%cb", buf, "%cn", &from[i + 1]);
01092
01093
01094 } else
01095 sprintf(to, "%s%s%s", "%cc", from, "%cn");
01096
01097 }
01098
01099 #define ONE_LINE_TEXTS
01100
01101 #ifdef ONE_LINE_TEXTS
01102 #define MLen CM_ONE
01103 #else
01104 #define MLen CM_TWO
01105 #endif
01106
01107 static char *do_ugly_things(coolmenu ** d, char *msg, int len, int initial)
01108 {
01109 coolmenu *c = *d;
01110 char *e;
01111 int i;
01112 char buf[LBUF_SIZE];
01113 char msg2[LBUF_SIZE];
01114
01115 strcpy(msg2, msg);
01116 #ifndef ONE_LINE_TEXTS
01117 if(!msg) {
01118 sim(" ", MLen);
01119 *d = c;
01120 return NULL;
01121 }
01122 #endif
01123 if(strlen(msg) < len) {
01124 if(initial) {
01125 if(initial > 0)
01126 help_color_initialize(msg, buf);
01127 else {
01128 for(i = 0; i < -initial; i++)
01129 buf[i] = ' ';
01130 strcpy(&buf[i], msg);
01131 }
01132 sim(buf, MLen);
01133 } else
01134 sim(msg, MLen);
01135 *d = c;
01136 return NULL;
01137 }
01138 for(e = msg2 + len - 1; *e != ' '; e--);
01139 *e = 0;
01140 if(initial) {
01141 if(initial > 0)
01142 help_color_initialize(msg2, buf);
01143 else {
01144 for(i = 0; i < -initial; i++)
01145 buf[i] = ' ';
01146 strcpy(&buf[i], msg2);
01147 }
01148 sim(buf, MLen);
01149 } else
01150 sim(msg2, MLen);
01151 *e = ' ';
01152 *d = c;
01153 if((*e + 1))
01154 return e + 1;
01155 return NULL;
01156 }
01157
01158 #define Len(s) ((!s || !*s) ? 0 : strlen(s))
01159
01160 #define TAB 3
01161
01162 static void cut_apart_helpmsgs(coolmenu ** d, char *msg1, char *msg2,
01163 int len, int initial)
01164 {
01165 int l1 = Len(msg1);
01166 int l2 = Len(msg2);
01167 int nl1, nl2;
01168
01169 #ifndef ONE_LINE_TEXTS
01170
01171 msg1 = do_ugly_things(d, msg1, len, initial);
01172 msg2 =
01173 do_ugly_things(d, msg2, initial ? len : len - TAB,
01174 initial ? 0 : 0 - TAB);
01175 if(!msg1 && !msg2)
01176 return;
01177 nl1 = Len(msg1);
01178 nl2 = Len(msg2);
01179 if(nl1 != l1 || nl2 != l2)
01180 cut_apart_helpmsgs(d, msg1, msg2, len, 0);
01181 #else
01182 int first = 1;
01183
01184 while (msg1 && *msg1) {
01185 msg1 = do_ugly_things(d, msg1, len * 2 - 1, first);
01186 nl1 = Len(msg1);
01187 if(nl1 == l1)
01188 break;
01189 l1 = nl1;
01190 first = 0;
01191 }
01192 while (msg2 && *msg2) {
01193 msg2 = do_ugly_things(d, msg2, len * 2 - TAB, 0 - TAB);
01194 nl2 = Len(msg2);
01195 if(nl2 == l2)
01196 break;
01197 l2 = nl2;
01198 }
01199
01200 #endif
01201 }
01202
01203 static void DoSpecialObjectHelp(dbref player, char *type, int id, int loc,
01204 int powerneeded, int objid, char *arg)
01205 {
01206 int i, j;
01207 MECH *mech = NULL;
01208 int pos[100][2];
01209 int count = 0, csho = 0;
01210 coolmenu *c = NULL;
01211 char buf[LBUF_SIZE];
01212 char *d;
01213 int dc;
01214
01215 if(id == GTYPE_MECH)
01216 mech = getMech(loc);
01217 bzero(pos, sizeof(pos));
01218 for(i = 0; SpecialObjects[id].commands[i].name; i++) {
01219 if(!SpecialObjects[id].commands[i].func &&
01220 (SpecialObjects[id].commands[i].helpmsg[0] != '@' ||
01221 Have_MechPower(Owner(player), powerneeded)))
01222 if(id != GTYPE_MECH ||
01223 Can_Use_Command(mech, SpecialObjects[id].commands[i].flag)) {
01224 if(count)
01225 pos[count - 1][1] = i - pos[count - 1][0];
01226 pos[count][0] = i;
01227 count++;
01228 }
01229 }
01230 if(count)
01231 pos[count - 1][1] = i - pos[count - 1][0];
01232 else {
01233 pos[0][0] = 0;
01234 pos[0][1] = i;
01235 count = 1;
01236 }
01237 sim(NULL, CM_ONE | CM_LINE);
01238 if(!arg || !*arg) {
01239 #define HELPMSG(a) \
01240 &SpecialObjects[id].commands[a].helpmsg[SpecialObjects[id].commands[a].helpmsg[0]=='@']
01241 for(i = 0; i < count; i++) {
01242 if(count > 1) {
01243 d = center_string(HELPMSG(pos[i][0]), 70);
01244 sim(tprintf("%s%s%s", "%cg", d, "%c"), CM_ONE);
01245 } else
01246 sim(tprintf("%s command listing: ", type),
01247 CM_ONE | CM_CENTER);
01248 for(j = pos[i][0] + (count == 1 ? 0 : 1);
01249 j < pos[i][0] + pos[i][1]; j++)
01250 if(SpecialObjects[id].commands[j].helpmsg[0] != '@' ||
01251 Have_MechPower(Owner(player), powerneeded))
01252 if(id != GTYPE_MECH ||
01253 Can_Use_Command(mech,
01254 SpecialObjects[id].commands[j].flag)) {
01255 strcpy(buf, SpecialObjects[id].commands[j].name);
01256 d = buf;
01257 while (*d && *d != ' ')
01258 d++;
01259 if(*d == ' ')
01260 *d = 0;
01261 sim(buf, CM_FOUR);
01262 csho++;
01263 }
01264 }
01265 if(!csho)
01266 vsi(tprintf
01267 ("There are no commands you are authorized to use here."));
01268 else {
01269 sim(NULL, CM_ONE | CM_LINE);
01270 if(count > 1)
01271 vsi("Additional info available with 'HELP SUBTOPIC'");
01272 else
01273 vsi("Additional info available with 'HELP ALL'");
01274 }
01275 } else {
01276
01277 if(!strcasecmp(arg, "all")) {
01278 if(count > 1) {
01279 vsi("ALL not available for objects with subcategories.");
01280 dc = -2;
01281 } else
01282 dc = -1;
01283 } else {
01284 if(count == 1) {
01285 vsi("This object doesn't have any other detailed help than 'HELP ALL'");
01286 dc = -2;
01287 } else {
01288 for(i = 0; i < count; i++)
01289 if(!strcasecmp(arg, HELPMSG(pos[i][0])))
01290 break;
01291 if(i == count) {
01292 vsi("Subcategory not found.");
01293 dc = -2;
01294 } else
01295 dc = i;
01296 }
01297 }
01298 if(dc > -2) {
01299 for(i = 0; i < count; i++)
01300 if(dc == -1 || i == dc) {
01301 if(count > 1)
01302 vsi(tprintf("%s%s%s", "%cg",
01303 center_string(HELPMSG(pos[i][0]), 70),
01304 "%c"));
01305 for(j = pos[i][0] + (count == 1 ? 0 : 1);
01306 j < pos[i][0] + pos[i][1]; j++)
01307 if(SpecialObjects[id].commands[j].helpmsg[0] !=
01308 '@' || Have_MechPower(Owner(player), powerneeded))
01309 if(id != GTYPE_MECH ||
01310 Can_Use_Command(mech,
01311 SpecialObjects[id].commands[j].
01312 flag))
01313 cut_apart_helpmsgs(&c,
01314 SpecialObjects[id].
01315 commands[j].name,
01316 HELPMSG(j), 37, 1);
01317 }
01318 }
01319 }
01320 sim(NULL, CM_ONE | CM_LINE);
01321 ShowCoolMenu(player, c);
01322 KillCoolMenu(c);
01323 }
01324
01325 void InitSpecialHash(int which)
01326 {
01327 char *tmp, *tmpc;
01328 int i;
01329 char buf[MBUF_SIZE];
01330
01331 hashinit(&SpecialCommandHash[which], 20 * HASH_FACTOR);
01332 for(i = 0; (tmp = SpecialObjects[which].commands[i].name); i++) {
01333 if(!SpecialObjects[which].commands[i].func)
01334 continue;
01335 tmpc = buf;
01336 for(; *tmp && *tmp != ' '; tmp++)
01337 *(tmpc++) = ToLower(*tmp);
01338 *tmpc = 0;
01339 if((tmpc = strstr(buf, " ")))
01340 *tmpc = 0;
01341 hashadd(buf, (int *) &SpecialObjects[which].commands[i],
01342 &SpecialCommandHash[which]);
01343 }
01344 }
01345
01346 void handle_xcode(dbref player, dbref obj, int from, int to)
01347 {
01348 if(from == to)
01349 return;
01350 if(!to) {
01351 s_Hardcode(obj);
01352 DisposeSpecialObject(player, obj);
01353 c_Hardcode(obj);
01354 } else
01355 CreateNewSpecialObject(player, obj);
01356 }
01357
01358 #define DEFAULT 0
01359 #define ANSI_START "\033["
01360 #define ANSI_START_LEN 2
01361 #define ANSI_END "m"
01362 #define ANSI_END_LEN 1
01363
01364 struct color_entry {
01365 int bit;
01366 int negbit;
01367 char ltr;
01368 char *string;
01369 char *sstring;
01370 } color_table[] = {
01371 {
01372 0x0008, 7, 'n', ANSI_NORMAL, NULL}, {
01373 0x0001, 0, 'h', ANSI_HILITE, NULL}, {
01374 0x0002, 0, 'i', ANSI_INVERSE, NULL}, {
01375 0x0004, 0, 'f', ANSI_BLINK, NULL}, {
01376 0x0010, 0, 'x', ANSI_BLACK, NULL}, {
01377 0x0010, 0x10, 'l', ANSI_BLACK, NULL}, {
01378 0x0020, 0, 'r', ANSI_RED, NULL}, {
01379 0x0040, 0, 'g', ANSI_GREEN, NULL}, {
01380 0x0080, 0, 'y', ANSI_YELLOW, NULL}, {
01381 0x0100, 0, 'b', ANSI_BLUE, NULL}, {
01382 0x0200, 0, 'm', ANSI_MAGENTA, NULL}, {
01383 0x0400, 0, 'c', ANSI_CYAN, NULL}, {
01384 0x0800, 0, 'w', ANSI_WHITE, NULL}, {
01385 0, 0, 0, NULL, NULL}
01386 };
01387
01388 #define CHARS 256
01389
01390 char colorc_reverse[CHARS];
01391
01392 void initialize_colorize()
01393 {
01394 int i;
01395 char buf[20];
01396 char *c;
01397
01398 c = buf + ANSI_START_LEN;
01399 for(i = 0; i < CHARS; i++)
01400 colorc_reverse[i] = DEFAULT;
01401 for(i = 0; color_table[i].string; i++) {
01402 colorc_reverse[(short) color_table[i].ltr] = i;
01403 strcpy(buf, color_table[i].string);
01404 buf[strlen(buf) - ANSI_END_LEN] = 0;
01405 color_table[i].sstring = strdup(c);
01406 }
01407
01408 }
01409
01410 #undef notify
01411 char *colorize(dbref player, char *from)
01412 {
01413 char *to;
01414 char *p, *q;
01415 int color_wanted = 0;
01416 int i;
01417 int cnt;
01418
01419 q = to = alloc_lbuf("colorize");
01420 #if 1
01421 for(p = from; *p; p++) {
01422 if(*p == '%' && *(p + 1) == 'c') {
01423 p += 2;
01424 if(*p <= 0)
01425 i = DEFAULT;
01426 else
01427 i = colorc_reverse[(short) *p];
01428 if(i == DEFAULT && *p != 'n')
01429 p--;
01430 color_wanted &= ~color_table[i].negbit;
01431 color_wanted |= color_table[i].bit;
01432 } else {
01433 if(color_wanted && Ansi(player)) {
01434 *q = 0;
01435
01436 strcpy(q, ANSI_START);
01437 q += ANSI_START_LEN;
01438 cnt = 0;
01439 for(i = 0; color_table[i].string; i++)
01440 if(color_wanted & color_table[i].bit &&
01441 color_table[i].bit != color_table[i].negbit) {
01442 if(cnt)
01443 *q++ = ';';
01444 strcpy(q, color_table[i].sstring);
01445 q += strlen(color_table[i].sstring);
01446 cnt++;
01447 }
01448 strcpy(q, ANSI_END);
01449 q += ANSI_END_LEN;
01450 color_wanted = 0;
01451 }
01452 *q++ = *p;
01453 }
01454 }
01455 *q = 0;
01456 if(color_wanted && Ansi(player)) {
01457
01458 strcpy(q, ANSI_START);
01459 q += ANSI_START_LEN;
01460 cnt = 0;
01461 for(i = 0; color_table[i].string; i++)
01462 if(color_wanted & color_table[i].bit &&
01463 color_table[i].bit != color_table[i].negbit) {
01464 if(cnt)
01465 *q++ = ';';
01466 strcpy(q, color_table[i].sstring);
01467 q += strlen(color_table[i].sstring);
01468 cnt++;
01469 }
01470 strcpy(q, ANSI_END);
01471 q += ANSI_END_LEN;
01472 color_wanted = 0;
01473 }
01474 #else
01475 strcpy(to, p);
01476 #endif
01477 return to;
01478 }
01479
01480 void mecha_notify(dbref player, char *msg)
01481 {
01482 char *tmp;
01483
01484 tmp = colorize(player, msg);
01485 raw_notify(player, tmp);
01486 free_lbuf(tmp);
01487 }
01488
01489 void mecha_notify_except(dbref loc, dbref player, dbref exception, char *msg)
01490 {
01491 dbref first;
01492
01493 if(loc != exception)
01494 notify_checked(loc, player, msg,
01495 (MSG_ME_ALL | MSG_F_UP | MSG_S_INSIDE | MSG_NBR_EXITS_A
01496 | MSG_COLORIZE));
01497 DOLIST(first, Contents(loc)) {
01498 if(first != exception) {
01499 notify_checked(first, player, msg,
01500 (MSG_ME | MSG_F_DOWN | MSG_S_OUTSIDE |
01501 MSG_COLORIZE));
01502 }
01503 }
01504 }
01505
01506
01507
01508
01509
01510 void ResetSpecialObjects()
01511 {
01512 #if 0
01513 int i;
01514
01515 for(i = FIRST_TECH_EVENT; i <= LAST_TECH_EVENT; i++)
01516 while (muxevent_run_by_type(i));
01517 #endif
01518 muxevent_run_by_type(EVENT_HIDE);
01519 muxevent_run_by_type(EVENT_BLINDREC);
01520 }
01521
01522 MAP *getMap(dbref d)
01523 {
01524 Node *tmp;
01525
01526 if(!(tmp = FindObjectsNode(d)))
01527 return NULL;
01528 if(NodeType(tmp) != GTYPE_MAP)
01529 return NULL;
01530 return (MAP *) NodeData(tmp);
01531 }
01532
01533 MECH *getMech(dbref d)
01534 {
01535 Node *tmp;
01536
01537 if(!(Good_obj(d)))
01538 return NULL;
01539 if(!(Hardcode(d)))
01540 return NULL;
01541 if(!(tmp = FindObjectsNode(d)))
01542 return NULL;
01543 if(NodeType(tmp) != GTYPE_MECH)
01544 return NULL;
01545 return (MECH *) NodeData(tmp);
01546 }