Crossfire Server, Branch 1.12
R12190
|
00001 /* 00002 * bwp - build wiki pages 00003 * 00004 * This program will sort out all monster archetypes and print wiki pages 00005 * for them, named 'a' through 'z'. It uses some *_template subroutines taken 00006 * from Ryo's mapper.c. It should compile if installed in server/trunk/utils. 00007 * Please direct all suggestions or corrections to aaron@baugher.biz (or 00008 * Mhoram on #crossfire). 00009 * 00010 * Compile command: gcc -g -O0 bwp.c -I../include ../common/libcross.a ../socket/libsocket.a -o bwp -lz -lcrypt -lm 00011 */ 00012 00013 /* 00014 * CrossFire, A Multiplayer game for X-windows 00015 * 00016 * Copyright (C) 2002-2006 Mark Wedel & Crossfire Development Team 00017 * Copyright (C) 1992 Frank Tore Johansen 00018 * 00019 * This program is free software; you can redistribute it and/or modify 00020 * it under the terms of the GNU General Public License as published by 00021 * the Free Software Foundation; either version 2 of the License, or 00022 * (at your option) any later version. 00023 * 00024 * This program is distributed in the hope that it will be useful, 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00027 * GNU General Public License for more details. 00028 * 00029 * You should have received a copy of the GNU General Public License 00030 * along with this program; if not, write to the Free Software 00031 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00032 * 00033 * The authors can be reached via e-mail at crossfire-devel@real-time.com 00034 */ 00035 00036 #define LO_NEWFILE 2 00037 #define MAX_SIZE 64 00038 #define NA "n/a" 00039 00040 #include <time.h> 00041 #include <stdio.h> 00042 #include <stdlib.h> 00043 #include <global.h> 00044 00045 char *monster_page_head; /* Head of wiki page of monsters */ 00046 char *monster_page_foot; /* Foot of wiki page of monsters */ 00047 char *monster_entry; /* A single monster entry */ 00048 char *monster_canuse_row; /* Can_use table row */ 00049 char *monster_protected_row; /* Protected table row */ 00050 char *monster_vulnerable_row; /* Vulnerable table row */ 00051 char *monster_special_row; /* Special table row */ 00052 char *monster_attack_row; /* Attack types table row */ 00053 char *monster_lore_row; /* Lore table row */ 00054 00055 typedef struct string_array { 00056 sint16 count; 00057 char **item; 00058 } String_Array; 00059 00069 const char *const flag_names[NUM_FLAGS+1] = { 00070 "alive", "wiz", NULL, NULL, "was_wiz", "applied", "unpaid", 00071 "can_use_shield", "no_pick", "client_anim_sync", "client_anim_random", /* 10 */ 00072 "is_animated", NULL /* slow_move */, 00073 NULL /* flying */, "monster", "friendly", "generator", 00074 "is_thrown", "auto_apply", "treasure", "player sold", /* 20 */ 00075 "see_invisible", "can_roll", "overlay_floor", 00076 "is_turnable", NULL /* walk_off */, NULL /* fly_on */, 00077 NULL /*fly_off*/, "is_used_up", "identified", "reflecting", /* 30 */ 00078 "changing", "splitting", "hitback", "startequip", 00079 "blocksview", "undead", "scared", "unaggressive", 00080 "reflect_missile", "reflect_spell", /* 40 */ 00081 "no_magic", "no_fix_player", "is_lightable", "tear_down", 00082 "run_away", NULL /*pass_thru */, NULL /*can_pass_thru*/, 00083 "pick_up", "unique", "no_drop", /* 50 */ 00084 NULL /* wizcast*/, "can_cast_spell", "can_use_scroll", "can_use_range", 00085 "can_use_bow", "can_use_armour", "can_use_weapon", 00086 "can_use_ring", "has_ready_range", "has_ready_bow", /* 60 */ 00087 "xrays", NULL, "is_floor", "lifesave", "no_strength", "sleep", 00088 "stand_still", "random_movement", "only_attack", "confused", /* 70 */ 00089 "stealth", NULL, NULL, "cursed", "damned", 00090 "see_anywhere", "known_magical", "known_cursed", 00091 "can_use_skill", "been_applied", /* 80 */ 00092 "has_ready_scroll", "can_use_rod", NULL, 00093 "can_use_horn", "make_invisible", "inv_locked", "is_wooded", 00094 "is_hilly", "has_ready_skill", "has_ready_weapon", /* 90 */ 00095 "no_skill_ident", "is_blind", "can_see_in_dark", "is_cauldron", 00096 "is_dust", "no_steal", "one_hit", NULL, "berserk", "neutral", /* 100 */ 00097 "no_attack", "no_damage", NULL, NULL, "activate_on_push", 00098 "activate_on_release", "is_water", "use_content_on_gen", NULL, "is_buildable", /* 110 */ 00099 NULL, "blessed", "known_blessed" 00100 }; 00101 00112 static char *cat_template(char *source, char *add) { 00113 if (!source) 00114 return add; 00115 source = realloc(source, strlen(source)+strlen(add)+1); 00116 strcat(source, add); 00117 free(add); 00118 return source; 00119 } 00120 00131 static int read_template(const char *name, char **buffer) { 00132 FILE *file; 00133 size_t size; 00134 struct stat info; 00135 00136 if (stat(name, &info)) { 00137 printf("Couldn't stat template %s!\n", name); 00138 return 1; 00139 } 00140 00141 (*buffer) = calloc(1, info.st_size+1); 00142 if (!(*buffer)) { 00143 printf("Template %s calloc failed!\n", name); 00144 return 1; 00145 } 00146 00147 if (info.st_size == 0) { 00148 (*buffer)[0] = '\0'; 00149 return 0; 00150 } 00151 00152 file = fopen(name, "rb"); 00153 if (!file) { 00154 printf("Couldn't open template %s!\n", name); 00155 free(*buffer); 00156 return 1; 00157 } 00158 if (fread(*buffer, info.st_size, 1, file) != 1) { 00159 printf("Couldn't read template %s!\n", name); 00160 free(*buffer); 00161 fclose(file); 00162 return 1; 00163 } 00164 fclose(file); 00165 return 0; 00166 } 00167 00185 static char *do_template(const char *template, const char **vars, const char **values) { 00186 int count = 0; 00187 const char *sharp = template; 00188 int maxlen = 0; 00189 int var = 0; 00190 char *result; 00191 char *current_result; 00192 const char *end; 00193 00194 while ((sharp = strchr(sharp, '#')) != NULL) { 00195 sharp++; 00196 count++; 00197 } 00198 if (!count) 00199 return strdup(template); 00200 if (count%2) { 00201 printf("Malformed template, mismatched #!\n"); 00202 return strdup(template); 00203 } 00204 00205 while (vars[var] != NULL) { 00206 if (strlen(values[var]) > maxlen) 00207 maxlen = strlen(values[var]); 00208 var++; 00209 } 00210 result = calloc(1, strlen(template)+maxlen*(count/2)+1); 00211 if (!result) 00212 return NULL; 00213 current_result = result; 00214 00215 sharp = template; 00216 while ((sharp = strchr(sharp, '#')) != NULL) { 00217 end = strchr(sharp+1, '#'); 00218 strncpy(current_result, template, sharp-template); 00219 if (end == sharp+1) { 00220 strcat(current_result, "#"); 00221 } else { 00222 current_result = current_result+strlen(current_result); 00223 var = 0; 00224 while (vars[var] != 0 && strncmp(vars[var], sharp+1, end-sharp-1)) 00225 var++; 00226 if (vars[var] == 0) 00227 printf("Wrong tag: %s\n", sharp); 00228 else 00229 strcpy(current_result, values[var]); 00230 } 00231 current_result = current_result+strlen(current_result); 00232 sharp = end+1; 00233 template = sharp; 00234 } 00235 strcat(current_result, template); 00236 return result; 00237 } 00238 00239 /**** Mhoram's code starts here *****/ 00240 00253 static void free_if_used(char *p) { 00254 if (p && strlen(p) > 0) { 00255 free(p); 00256 } 00257 } 00258 00271 static int sortbyname(const void *a, const void *b) { 00272 return (strcasecmp(*(const char **)a, *(const char **)b)); 00273 } 00274 00288 static int sort_archetypes(const void *a, const void *b) { 00289 archetype *aa; 00290 archetype *bb; 00291 00292 aa = *(archetype **)a; 00293 bb = *(archetype **)b; 00294 00295 return (strcasecmp(aa->clone.name, bb->clone.name)); 00296 } 00297 00310 void push(String_Array *array, const char *string) { 00311 sint16 i = array->count; 00312 00313 array->item[i] = strdup_local(string); 00314 array->count++; 00315 } 00316 00325 void free_data(String_Array *array) { 00326 int item; 00327 00328 for (item = 0; item < array->count; item++) 00329 free(array->item[item]); 00330 free(array->item); 00331 array->item = NULL; 00332 } 00333 00344 const char *join_with_comma(String_Array *array) { 00345 char *newtext; 00346 int i; 00347 00348 newtext = calloc(1, 1); 00349 qsort(array->item, array->count, sizeof(char *), sortbyname); 00350 for (i = 0; i < array->count; i++) { 00351 if (i) { 00352 newtext = realloc(newtext, strlen(newtext)+strlen(", ")+1); 00353 newtext = strncat(newtext, ", ", 2); 00354 } 00355 newtext = realloc(newtext, strlen(newtext)+strlen(array->item[i])+1); 00356 newtext = strncat(newtext, array->item[i], strlen(array->item[i])); 00357 } 00358 return newtext; 00359 } 00360 00361 int main(int argc, char *argv[]) { 00362 00363 archetype *at; 00364 int archnum = 0; 00365 archetype *monster[4000]; 00366 int i; 00367 char letter; 00368 char last_letter; 00369 char *wiki_page = NULL; 00370 char *monster_entries = NULL; 00371 00372 FILE *fp = NULL; 00373 FILE *image_list; 00374 char image_list_path[128]; 00375 char wikifile[128]; 00376 char *template; 00377 00378 const char *wikidir = "/tmp"; /* Should change this to come from command line? */ 00379 00380 init_globals(); 00381 init_library(); 00382 init_archetypes(); 00383 init_artifacts(); 00384 init_formulae(); 00385 init_readable(); 00386 00387 init_gods(); 00388 00389 /* Initialize templates */ 00390 if (read_template("templates/wiki/monster_page_head", &monster_page_head)) 00391 return; 00392 if (read_template("templates/wiki/monster_page_foot", &monster_page_foot)) 00393 return; 00394 if (read_template("templates/wiki/monster_entry", &monster_entry)) 00395 return; 00396 if (read_template("templates/wiki/monster_canuse_row", &monster_canuse_row)) 00397 return; 00398 if (read_template("templates/wiki/monster_protected_row", &monster_protected_row)) 00399 return; 00400 if (read_template("templates/wiki/monster_vulnerable_row", &monster_vulnerable_row)) 00401 return; 00402 if (read_template("templates/wiki/monster_special_row", &monster_special_row)) 00403 return; 00404 if (read_template("templates/wiki/monster_attack_row", &monster_attack_row)) 00405 return; 00406 if (read_template("templates/wiki/monster_lore_row", &monster_lore_row)) 00407 return; 00408 sprintf(image_list_path, "%s/image_list", wikidir); 00409 image_list = fopen(image_list_path, "w"); 00410 if (!image_list) { 00411 LOG(llevError, "Unable to open image list file!\n"); 00412 exit(1); 00413 } 00414 00415 /* Pick out the monster archetypes and sort them into an array */ 00416 for (at = first_archetype; at != NULL; at = at->next) { 00417 if (QUERY_FLAG(&at->clone, FLAG_MONSTER) 00418 && QUERY_FLAG(&at->clone, FLAG_ALIVE)) { 00419 monster[archnum++] = at; 00420 } 00421 } 00422 printf("Sorting..."); 00423 /* Calling qsort on monster, which is archetype** */ 00424 qsort(&monster[0], archnum, sizeof(archetype *), sort_archetypes); 00425 printf("done. %i items found\n", archnum); 00426 00427 last_letter = '\0'; 00428 00429 for (i = 0; i < archnum; i++) { 00430 at = monster[i]; 00431 if (at) { 00432 const char *key[16] = { NULL, }; 00433 const char *val[16] = { NULL, }; 00434 char buf[16][MAX_BUF]; 00435 int keycount = 0; 00436 int res; 00437 00438 letter = tolower(at->clone.name[0]); 00439 00440 LOG(llevInfo, "Doing archetype %s\n", at->name); 00441 00442 if (letter != last_letter) { /* New letter, new file */ 00443 if (fp) { 00444 keycount = 0; 00445 key[keycount] = NULL; 00446 template = do_template(monster_page_foot, key, val); 00447 res = fprintf(fp, "%s", template); 00448 free(template); 00449 template = NULL; 00450 if (res < 0) { 00451 LOG(llevError, "Unable to write to file!\n"); 00452 } 00453 fclose(fp); 00454 } 00455 00456 snprintf(wikifile, sizeof(wikifile), "%s/%c", wikidir, letter); 00457 fp = fopen(wikifile, "w"); 00458 if (!fp) { 00459 fprintf(stderr, "Unable to write to wiki file!\n"); 00460 exit(1); 00461 } 00462 00463 char letterindex[256] = ""; 00464 char letterindexnext[7]; 00465 char li; 00466 letterindexnext[0] = '\0'; 00467 for (li = 'a'; li <= 'z'; li++) { 00468 if (li == letter) { 00469 sprintf(letterindexnext, "%c ", toupper(li)); 00470 } else { 00471 sprintf(letterindexnext, "[[%c]] ", toupper(li)); 00472 } 00473 strncat(letterindex, letterindexnext, 256); 00474 } 00475 00476 keycount = 0; 00477 key[keycount] = "LETTER"; 00478 sprintf(buf[keycount], "%c", toupper(letter)); 00479 val[keycount++] = buf[keycount]; 00480 key[keycount] = "LETTERINDEX"; 00481 val[keycount++] = letterindex; 00482 key[keycount] = NULL; 00483 template = do_template(monster_page_head, key, val); 00484 res = fprintf(fp, template); 00485 free(template); 00486 if (res < 0) { 00487 LOG(llevError, "Unable to write to file!"); 00488 } 00489 last_letter = letter; 00490 } 00491 00492 /* add a monster entry */ 00493 char *canuse_row; 00494 char *protected_row; 00495 char *vulnerable_row; 00496 char *special_row; 00497 char *attack_row; 00498 char *lore_row; 00499 const int CANUSE_LENGTH = 16; 00500 String_Array canuse; 00501 String_Array resist; 00502 String_Array vulner; 00503 String_Array attack; 00504 String_Array special; 00505 /* Some flags that seemed useful; may need to add to this list. 00506 * *special_names[] is used because some of the names in 00507 * define.h are a bit awkward. Last one is negative to mark end. 00508 */ 00509 const sint8 special_flags[] = { 21, 93, 52, 38, 13, 32, 61, -1 }; 00510 const char *special_names[] = { 00511 "see invisible", 00512 "see in dark", 00513 "spellcaster", 00514 "unaggressive", 00515 "flying", 00516 "splitting", 00517 "x-ray vision" 00518 }; 00519 int j; 00520 00521 canuse.item = calloc(1, sizeof(const char *)*(CANUSE_LENGTH+1)); 00522 resist.item = calloc(1, sizeof(const char *)*(NROFATTACKS+1)); 00523 vulner.item = calloc(1, sizeof(const char *)*(NROFATTACKS+1)); 00524 attack.item = calloc(1, sizeof(const char *)*(NROFATTACKS+1)); 00525 special.item = calloc(1, sizeof(const char *)*(NROFATTACKS+1)); 00526 00527 /* Do lore row */ 00528 if (at->clone.lore) { 00529 key[keycount] = "LORE"; 00530 key[keycount+1] = NULL; 00531 val[keycount] = at->clone.lore; 00532 keycount++; 00533 lore_row = do_template(monster_lore_row, key, val); 00534 } else 00535 lore_row = strdup(""); 00536 00537 /* Do canuse row */ 00538 canuse.count = 0; 00539 keycount = 0; 00540 for (j = 1; j <= NUM_FLAGS; j++) { 00541 if (QUERY_FLAG(&at->clone, j) 00542 && flag_names[j] 00543 && !strncmp(flag_names[j], "can_use_", 8)) { 00544 push(&canuse, flag_names[j]+8); 00545 } 00546 } 00547 if (canuse.count) { 00548 key[keycount] = "CANUSE"; 00549 key[keycount+1] = NULL; 00550 val[keycount] = join_with_comma(&canuse); 00551 canuse_row = do_template(monster_canuse_row, key, val); 00552 free(val[keycount]); 00553 } else 00554 canuse_row = strdup(""); 00555 00556 /* Do protected/vulnerable rows */ 00557 resist.count = 0; 00558 vulner.count = 0; 00559 for (j = 0; j <= NROFATTACKS; j++) { 00560 if (at->clone.resist[j] && attacktype_desc[j]) { 00561 char rowtext[32]; 00562 00563 if (at->clone.resist[j] < 0) { 00564 sprintf(rowtext, "%s %i", attacktype_desc[j], at->clone.resist[j]); 00565 push(&vulner, rowtext); 00566 } else { 00567 sprintf(rowtext, "%s +%i", attacktype_desc[j], at->clone.resist[j]); 00568 push(&resist, rowtext); 00569 } 00570 } 00571 } 00572 keycount = 0; 00573 if (resist.count) { 00574 key[keycount] = "PROTECTED"; 00575 key[keycount+1] = NULL; 00576 val[keycount] = join_with_comma(&resist); 00577 protected_row = do_template(monster_protected_row, key, val); 00578 free(val[keycount]); 00579 } else 00580 protected_row = strdup(""); 00581 00582 keycount = 0; 00583 if (vulner.count) { 00584 key[keycount] = "VULNERABLE"; 00585 key[keycount+1] = NULL; 00586 val[keycount] = join_with_comma(&vulner); 00587 vulnerable_row = do_template(monster_vulnerable_row, key, val); 00588 free(val[keycount]); 00589 } else 00590 vulnerable_row = strdup(""); 00591 00592 /* Do attacktype row */ 00593 attack.count = 0; 00594 keycount = 0; 00595 val[keycount] = NULL; 00596 for (j = 0; j <= NROFATTACKS; j++) { 00597 if (at->clone.attacktype&(1U<<j)) { 00598 push(&attack, attacktype_desc[j]); 00599 } 00600 } 00601 if (attack.count) { 00602 key[keycount] = "ATTACKS"; 00603 key[keycount+1] = NULL; 00604 val[keycount] = join_with_comma(&attack); 00605 attack_row = do_template(monster_attack_row, key, val); 00606 free(val[keycount]); 00607 } else 00608 attack_row = strdup(""); 00609 00610 /* Do special row */ 00611 special.count = 0; 00612 keycount = 0; 00613 val[keycount] = NULL; 00614 for (j = 0; special_flags[j] >= 0; j++) { 00615 if (QUERY_FLAG(&at->clone, special_flags[j])) { 00616 push(&special, special_names[j]); 00617 } 00618 } 00619 if (special.count) { 00620 key[keycount] = "SPECIAL"; 00621 key[keycount+1] = NULL; 00622 val[keycount] = join_with_comma(&special); 00623 special_row = do_template(monster_special_row, key, val); 00624 free(val[keycount]); 00625 } else 00626 special_row = strdup(""); 00627 00628 keycount = 0; 00629 key[keycount] = "CANUSEROW"; 00630 val[keycount++] = canuse_row; 00631 key[keycount] = "PROTECTEDROW"; 00632 val[keycount++] = protected_row; 00633 key[keycount] = "VULNERABLEROW"; 00634 val[keycount++] = vulnerable_row; 00635 key[keycount] = "SPECIALROW"; 00636 val[keycount++] = attack_row; 00637 key[keycount] = "ATTACKROW"; 00638 val[keycount++] = special_row; 00639 key[keycount] = "LOREROW"; 00640 val[keycount++] = lore_row; 00641 key[keycount] = "XP"; 00642 sprintf(buf[keycount], "%li", at->clone.stats.exp); 00643 val[keycount++] = buf[keycount]; 00644 key[keycount] = "HP"; 00645 sprintf(buf[keycount], "%i", at->clone.stats.hp); 00646 val[keycount++] = buf[keycount]; 00647 key[keycount] = "AC"; 00648 sprintf(buf[keycount], "%i", at->clone.stats.ac); 00649 val[keycount++] = buf[keycount]; 00650 key[keycount] = "NAME"; 00651 val[keycount++] = at->clone.name; 00652 key[keycount] = "RACE"; 00653 if (at->clone.race) { 00654 val[keycount++] = at->clone.race; 00655 } else { 00656 val[keycount++] = NA; 00657 } 00658 if (at->clone.face->name) { 00659 key[keycount] = "FACE"; 00660 sprintf(buf[keycount], "{{http://aaron.baugher.biz/images/cf/%s.png}}", at->clone.face->name); 00661 val[keycount++] = buf[keycount]; 00662 sprintf(buf[keycount], "%s.png\n", at->clone.face->name); 00663 fprintf(image_list, buf[keycount]); 00664 } 00665 /* Plan to add generator face too, when I decide how */ 00666 key[keycount] = "GENFACE"; 00667 val[keycount++] = ""; 00668 key[keycount] = NULL; 00669 00670 template = do_template(monster_entry, key, val); 00671 fprintf(fp, template); 00672 free(template); 00673 template = NULL; 00674 00675 free_data(&canuse); 00676 free_data(&resist); 00677 free_data(&vulner); 00678 free_data(&attack); 00679 free_data(&special); 00680 free(canuse_row); 00681 free(protected_row); 00682 free(vulnerable_row); 00683 free(attack_row); 00684 free(special_row); 00685 free(lore_row); 00686 } else { 00687 LOG(llevError, "Something is very wrong.\n"); 00688 } 00689 } 00690 fclose(image_list); 00691 } 00692 00693 void set_map_timeout(void) { 00694 /* doesn't need to do anything */ 00695 } 00696 00697 #include <global.h> 00698 00699 /* some plagarized code from apply.c--I needed just these two functions 00700 without all the rest of the junk, so.... */ 00701 int auto_apply(object *op) { 00702 object *tmp = NULL; 00703 int i; 00704 00705 switch (op->type) { 00706 case SHOP_FLOOR: 00707 if (!HAS_RANDOM_ITEMS(op)) 00708 return 0; 00709 do { 00710 i = 10; /* let's give it 10 tries */ 00711 while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? op->stats.exp : 5)) == NULL && --i) 00712 ; 00713 if (tmp == NULL) 00714 return 0; 00715 if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED)) { 00716 free_object(tmp); 00717 tmp = NULL; 00718 } 00719 } while (!tmp); 00720 00721 tmp->x = op->x, 00722 tmp->y = op->y; 00723 SET_FLAG(tmp, FLAG_UNPAID); 00724 insert_ob_in_map(tmp, op->map, NULL, 0); 00725 CLEAR_FLAG(op, FLAG_AUTO_APPLY); 00726 identify(tmp); 00727 break; 00728 00729 case TREASURE: 00730 if (HAS_RANDOM_ITEMS(op)) 00731 while ((op->stats.hp--) > 0) 00732 create_treasure(op->randomitems, op, GT_ENVIRONMENT, op->stats.exp ? op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0); 00733 remove_ob(op); 00734 free_object(op); 00735 break; 00736 } 00737 00738 return tmp ? 1 : 0; 00739 } 00740 00741 /* fix_auto_apply goes through the entire map (only the first time 00742 * when an original map is loaded) and performs special actions for 00743 * certain objects (most initialization of chests and creation of 00744 * treasures and stuff). Calls auto_apply if appropriate. 00745 */ 00746 void fix_auto_apply(mapstruct *m) { 00747 object *tmp, *above = NULL; 00748 int x, y; 00749 00750 for (x = 0; x < MAP_WIDTH(m); x++) 00751 for (y = 0; y < MAP_HEIGHT(m); y++) 00752 for (tmp = GET_MAP_OB(m, x, y); tmp != NULL; tmp = above) { 00753 above = tmp->above; 00754 00755 if (QUERY_FLAG(tmp, FLAG_AUTO_APPLY)) 00756 auto_apply(tmp); 00757 else if (tmp->type == TREASURE) { 00758 if (HAS_RANDOM_ITEMS(tmp)) 00759 while ((tmp->stats.hp--) > 0) 00760 create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0); 00761 } 00762 if (tmp 00763 && tmp->arch 00764 && tmp->type != PLAYER 00765 && tmp->type != TREASURE 00766 && tmp->randomitems) { 00767 if (tmp->type == CONTAINER) { 00768 if (HAS_RANDOM_ITEMS(tmp)) 00769 while ((tmp->stats.hp--) > 0) 00770 create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0); 00771 } else if (HAS_RANDOM_ITEMS(tmp)) 00772 create_treasure(tmp->randomitems, tmp, GT_APPLY, m->difficulty, 0); 00773 } 00774 } 00775 for (x = 0; x < MAP_WIDTH(m); x++) 00776 for (y = 0; y < MAP_HEIGHT(m); y++) 00777 for (tmp = GET_MAP_OB(m, x, y); tmp != NULL; tmp = tmp->above) 00778 if (tmp->above 00779 && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL)) 00780 check_trigger(tmp, tmp->above); 00781 } 00782 00783 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00784 00790 void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *txt, const char *txt2) { 00791 fprintf(logfile, "%s\n", txt); 00792 } 00793 00794 void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format, ...) { 00795 va_list ap; 00796 va_start(ap, old_format); 00797 vfprintf(logfile, old_format, ap); 00798 va_end(ap); 00799 } 00800 00801 void ext_info_map(int color, const mapstruct *map, uint8 type, uint8 subtype, const char *str1, const char *str2) { 00802 fprintf(logfile, "ext_info_map: %s\n", str2); 00803 } 00804 00805 void move_firewall(object *ob) { 00806 } 00807 00808 void emergency_save(int x) { 00809 } 00810 00811 void clean_tmp_files(void) { 00812 } 00813 00814 void esrv_send_item(object *ob, object *obx) { 00815 } 00816 00817 void dragon_ability_gain(object *ob, int x, int y) { 00818 } 00819 00820 void set_darkness_map(mapstruct *m) { 00821 } 00822 00823 object *find_skill_by_number(object *who, int skillno) { 00824 return NULL; 00825 } 00826 00827 void esrv_del_item(player *pl, int tag) { 00828 } 00829 00830 void esrv_update_spells(player *pl) { 00831 } 00832 00833 void monster_check_apply(object *ob, object *obt) { 00834 } 00835 00836 void trap_adjust(object *ob, int x) { 00837 } 00838 00839 int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix) { 00840 return 0; 00841 } 00842 00843 int execute_global_event(int eventcode, ...) { 00844 return 0; 00845 } 00846 #endif /* dummy DOXYGEN_SHOULD_SKIP_THIS */