00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "lev_things.h"
00023
00024 #include "globals.h"
00025 #include <limits.h>
00026 #include "lev_data.h"
00027 #include "obj_slabs.h"
00028 #include "obj_things.h"
00029 #include "lev_column.h"
00030
00031
00032
00033
00034 const is_thing_subtype search_tngtype_func[]={
00035 is_spellbook,is_dngspecbox,is_crtrlair,
00036 is_trapbox,is_trap,is_creature,
00037 is_door,is_effectgen,is_statue,
00038 is_furniture,is_food,is_gold,
00039 is_torch,is_heartflame,is_polebar,
00040 is_lit_thing,is_herogate,is_dnheart,
00041 is_doorkey,
00042 };
00043
00044 const char *search_tngtype_names[]={
00045 "Spell books","Dung.Specials","Creature lairs",
00046 "Trap boxes","Deployed traps","Creatures",
00047 "Deployed doors","Effect Generatr","Statues",
00048 "Furniture items","Food (chickens)","Gold things",
00049 "Torches","Heart flames","Poles and bars",
00050 "Lit things","Hero gates","Dungeon hearts",
00051 "Door keys",
00052 };
00053
00054
00055
00056
00057
00058 short things_verify(struct LEVEL *lvl, char *err_msg,struct IPOINT_2D *errpt)
00059 {
00060 struct VERIFY_OPTIONS child_verif_opt;
00061
00062 child_verif_opt.tlsize.x=lvl->tlsize.x;
00063 child_verif_opt.tlsize.y=lvl->tlsize.y;
00064 child_verif_opt.subsize.x=lvl->subsize.x;
00065 child_verif_opt.subsize.y=lvl->subsize.y;
00066 strcpy(child_verif_opt.err_msg,"Unknown error");
00067
00068 const int arr_entries_x=lvl->tlsize.x*MAP_SUBNUM_X;
00069 const int arr_entries_y=lvl->tlsize.y*MAP_SUBNUM_Y;
00070
00071 int i, j, k;
00072 for (i=0; i < arr_entries_y; i++)
00073 {
00074 for (j=0; j < arr_entries_x; j++)
00075 {
00076 unsigned short slab=get_tile_slab(lvl, i/MAP_SUBNUM_X, j/MAP_SUBNUM_Y);
00077 unsigned int creatures_on_subtl=0;
00078 unsigned int effectgenrts_on_subtl=0;
00079 unsigned int traps_on_subtl=0;
00080 unsigned int lit_things_on_subtl=0;
00081 unsigned int doors_on_subtl=0;
00082 unsigned int booksboxes_on_subtl=0;
00083 int things_count=get_thing_subnums(lvl,i,j);
00084 int categr=-1;
00085 unsigned short subtp_x,subtp_y,subtp_h;
00086 for (k=0; k <things_count ; k++)
00087 {
00088 unsigned char *thing = get_thing(lvl,i,j,k);
00089 short result=thing_verify(thing,&child_verif_opt);
00090 if (result!=VERIF_OK)
00091 {
00092 errpt->x=i/MAP_SUBNUM_X;
00093 errpt->y=j/MAP_SUBNUM_Y;
00094 sprintf(err_msg,"%s at slab %d,%d.",child_verif_opt.err_msg,errpt->x,errpt->y);
00095 return result;
00096 }
00097 unsigned char type_idx=get_thing_type(thing);
00098
00099 if (type_idx==THING_TYPE_ITEM)
00100 {
00101
00102 int sen_tl;
00103 sen_tl=get_thing_sensitile(thing);
00104 unsigned short stype_idx=get_thing_subtype(thing);
00105 int auto_sen_tl;
00106 auto_sen_tl=compute_item_sensitile(lvl,thing);
00107 if ((sen_tl!=auto_sen_tl)&&(!is_torchcndl(thing))&&(!is_spinningtng(thing))&&
00108 (!is_statue(thing))&&(!is_dncrucial(thing))&&(!is_furniture(thing)))
00109 {
00110 errpt->x=i/MAP_SUBNUM_X;
00111 errpt->y=j/MAP_SUBNUM_Y;
00112 sprintf(err_msg,"%s for %s at slab %d,%d.","Sensitive tile incorrectly set",
00113 get_item_subtype_fullname(stype_idx),errpt->x,errpt->y);
00114 return VERIF_WARN;
00115 }
00116
00117 if (((stype_idx==ITEM_SUBTYPE_GLDHOARD1)||(stype_idx==ITEM_SUBTYPE_GLDHOARD2)||
00118 (stype_idx==ITEM_SUBTYPE_GLDHOARD3)||(stype_idx==ITEM_SUBTYPE_GLDHOARD4)||
00119 (stype_idx==ITEM_SUBTYPE_GLDHOARD5))&&(slab!=SLAB_TYPE_TREASURE))
00120 {
00121 errpt->x=i/MAP_SUBNUM_X;
00122 errpt->y=j/MAP_SUBNUM_Y;
00123 sprintf(err_msg,"%s put outside of %s on slab %d,%d.",
00124 get_item_subtype_fullname(stype_idx),
00125 get_slab_fullname(SLAB_TYPE_TREASURE), errpt->x, errpt->y);
00126 return VERIF_WARN;
00127 }
00128
00129 if ((get_thing_subtypes_arridx(thing)==categr)&&(get_thing_subtpos_x(thing)==subtp_x)&&
00130 (get_thing_subtpos_y(thing)==subtp_y)&&(get_thing_subtpos_h(thing)==subtp_h)&&
00131 (!is_gold(thing))&&(!is_food(thing)))
00132 {
00133 errpt->x=i/MAP_SUBNUM_X;
00134 errpt->y=j/MAP_SUBNUM_Y;
00135 sprintf(err_msg,"Multiple %s with %s on slab %d,%d.",
00136 get_thing_category_fullname(categr),"exactly same position",
00137 errpt->x,errpt->y);
00138 return VERIF_WARN;
00139 }
00140 categr=get_thing_subtypes_arridx(thing);
00141 subtp_x=get_thing_subtpos_x(thing);
00142 subtp_y=get_thing_subtpos_y(thing);
00143 subtp_h=get_thing_subtpos_h(thing);
00144 }
00145 if (type_idx==THING_TYPE_DOOR)
00146 {
00147 unsigned short stype_idx=get_thing_subtype(thing);
00148
00149 if (((stype_idx==DOOR_SUBTYPE_WOOD)&&(slab!=SLAB_TYPE_DOORWOOD1)&&(slab!=SLAB_TYPE_DOORWOOD2)) ||
00150 ((stype_idx==DOOR_SUBTYPE_BRACED)&&(slab!=SLAB_TYPE_DOORBRACE1)&&(slab!=SLAB_TYPE_DOORBRACE2)) ||
00151 ((stype_idx==DOOR_SUBTYPE_IRON)&&(slab!=SLAB_TYPE_DOORIRON1)&&(slab!=SLAB_TYPE_DOORIRON2)) ||
00152 ((stype_idx==DOOR_SUBTYPE_MAGIC)&&(slab!=SLAB_TYPE_DOORMAGIC1)&&(slab!=SLAB_TYPE_DOORMAGIC2)))
00153 {
00154 errpt->x=i/MAP_SUBNUM_X;
00155 errpt->y=j/MAP_SUBNUM_Y;
00156 sprintf(err_msg,"%s %s thing put on %s slab at %d,%d.",
00157 get_door_subtype_fullname(stype_idx),get_thing_type_fullname(type_idx),
00158 get_slab_fullname(slab), errpt->x, errpt->y);
00159 return VERIF_WARN;
00160 }
00161 }
00162 if (is_creature(thing)) creatures_on_subtl++;
00163 if (is_trap(thing)) traps_on_subtl++;
00164 if (is_effectgen(thing)) effectgenrts_on_subtl++;
00165 if (is_lit_thing(thing)) lit_things_on_subtl++;
00166 if (is_door(thing)) doors_on_subtl++;
00167 if (is_spellbook(thing)||is_dngspecbox(thing)||is_trapbox(thing)
00168 ||is_doorbox(thing)) booksboxes_on_subtl++;
00169 }
00170 char *err_objcount=NULL;
00171 char *err_objtype=NULL;
00172 if (creatures_on_subtl>5)
00173 { err_objcount="five"; err_objtype=get_thing_type_fullname(THING_TYPE_CREATURE); }
00174 if (traps_on_subtl>3)
00175 { err_objcount="three"; err_objtype=get_thing_type_fullname(THING_TYPE_TRAP); }
00176 if (effectgenrts_on_subtl>3)
00177 { err_objcount="three"; err_objtype=get_thing_type_fullname(THING_TYPE_EFFECTGEN); }
00178 if (lit_things_on_subtl>2)
00179 { err_objcount="two"; err_objtype="lit"; }
00180 if (doors_on_subtl>1)
00181 { err_objcount="one"; err_objtype=get_thing_type_fullname(THING_TYPE_DOOR); }
00182 if (booksboxes_on_subtl>1)
00183 { err_objcount="one"; err_objtype="book/box"; }
00184 if (err_objcount!=NULL)
00185 {
00186 errpt->x=i/MAP_SUBNUM_X;
00187 errpt->y=j/MAP_SUBNUM_Y;
00188 sprintf(err_msg,"More than %s %s thing at one subtile on slab %d,%d.",
00189 err_objcount,err_objtype,errpt->x,errpt->y);
00190 return VERIF_WARN;
00191 }
00192 }
00193 }
00194 return VERIF_OK;
00195 }
00196
00197 char *get_search_tngtype_name(unsigned short idx)
00198 {
00199 int count=sizeof(search_tngtype_names)/sizeof(char *);
00200 if (idx<count)
00201 return (char *)search_tngtype_names[idx];
00202 else
00203 return "unknown(?!)";
00204 }
00205
00206 is_thing_subtype get_search_tngtype_func(unsigned short idx)
00207 {
00208 int count=sizeof(search_tngtype_func)/sizeof(is_thing_subtype);
00209 if ((idx<count)&&(search_tngtype_func[idx]!=NULL))
00210 return search_tngtype_func[idx];
00211 else
00212 return NULL;
00213 }
00214
00215 char *get_search_objtype_name(unsigned short idx)
00216 {
00217 const int count=3;
00218 if (idx>=count)
00219 return get_search_tngtype_name(idx-count);
00220 switch (idx)
00221 {
00222 case 0: return "Clear results";
00223 case 1: return "Action points";
00224 case 2: return "Static lights";
00225 }
00226 }
00227
00228
00229
00230
00231
00232 unsigned char *find_next_object_on_map(struct LEVEL *lvl, int *tx, int *ty, unsigned short srch_idx)
00233 {
00234 const int count=3;
00235 if (srch_idx>=count)
00236 {
00237 is_thing_subtype check_func=get_search_tngtype_func(srch_idx-count);
00238 return find_next_thing_on_map(lvl,tx,ty,check_func);
00239 }
00240 switch (srch_idx)
00241 {
00242 case 1: return find_next_actnpt_on_map(lvl,tx,ty);
00243 case 2: return find_next_stlight_on_map(lvl,tx,ty);
00244 case 0:
00245 default:
00246 message_log(" find_next_object_on_map: search index %d too small",srch_idx);
00247 return NULL;
00248 }
00249 }
00250
00251 unsigned short get_search_objtype_count(void)
00252 {
00253 unsigned short count=3;
00254 count+=sizeof(search_tngtype_func)/sizeof(is_thing_subtype);
00255 return count;
00256 }
00257
00258
00259
00260
00261 short set_door_lock(struct LEVEL *lvl, unsigned char *thing, unsigned char nlock)
00262 {
00263 if (thing==NULL) return false;
00264 unsigned short sx=get_thing_subtile_x(thing);
00265 unsigned short sy=get_thing_subtile_y(thing);
00266 unsigned char *thing_key=NULL;
00267 unsigned int tng_num=get_thing_subnums(lvl,sx,sy);
00268 while (tng_num>0)
00269 {
00270 tng_num--;
00271 thing_key=get_thing(lvl,sx,sy,tng_num);
00272 if ((get_thing_type(thing_key)==THING_TYPE_ITEM) &&
00273 (get_thing_subtype(thing_key)==ITEM_SUBTYPE_SPINNKEY))
00274 break;
00275 thing_key=NULL;
00276 }
00277 if (nlock==DOOR_PASS_UNLOCKED)
00278 {
00279 if (thing_key!=NULL)
00280 thing_del(lvl,sx,sy,tng_num);
00281 } else
00282 {
00283 if (thing_key==NULL)
00284 {
00285 thing_key = create_doorkey(lvl,sx,sy,ITEM_SUBTYPE_SPINNKEY);
00286 thing_add(lvl,thing_key);
00287 }
00288 }
00289 set_thing_level(thing,nlock);
00290 return true;
00291 }
00292
00293
00294
00295
00296 unsigned char get_door_lock(const unsigned char *thing)
00297 {
00298 return get_thing_level(thing);
00299 }
00300
00301
00302
00303
00304 unsigned char compute_door_orientation(const struct LEVEL *lvl, unsigned char *thing)
00305 {
00306 unsigned short tx=get_thing_subtile_x(thing)/MAP_SUBNUM_X;
00307 unsigned short ty=get_thing_subtile_y(thing)/MAP_SUBNUM_Y;
00308
00309 if (get_door_orientation(thing)==DOOR_ORIENT_NSPASS)
00310 {
00311 unsigned short slab_e=get_tile_slab(lvl, tx+1, ty);
00312 unsigned short slab_w=get_tile_slab(lvl, tx-1, ty);
00313 if (slab_is_tall(slab_e)&&slab_is_tall(slab_w))
00314 return DOOR_ORIENT_NSPASS;
00315 else
00316 return DOOR_ORIENT_EWPASS;
00317 } else
00318 {
00319 unsigned short slab_n=get_tile_slab(lvl, tx, ty-1);
00320 unsigned short slab_s=get_tile_slab(lvl, tx, ty+1);
00321 if (slab_is_tall(slab_n)&&slab_is_tall(slab_s))
00322 return DOOR_ORIENT_EWPASS;
00323 else
00324 return DOOR_ORIENT_NSPASS;
00325 }
00326 }
00327
00328
00329
00330
00331 unsigned short get_free_herogate_number(const struct LEVEL *lvl)
00332 {
00333 return get_free_herogate_number_next(lvl,1);
00334 }
00335
00336
00337
00338
00339
00340 unsigned short get_free_herogate_number_next(const struct LEVEL *lvl,const unsigned short start)
00341 {
00342 unsigned int used_size=start+16;
00343 unsigned char *used=NULL;
00344 if (!create_herogate_number_used_arr(lvl,&used,&used_size))
00345 return start;
00346 int new_num=start;
00347 while (new_num<used_size)
00348 {
00349 if (used[new_num]==0) break;
00350 new_num++;
00351 }
00352 free(used);
00353 return new_num;
00354 }
00355
00356
00357
00358
00359
00360 unsigned short get_free_herogate_number_prev(const struct LEVEL *lvl,const unsigned short start)
00361 {
00362 unsigned int used_size=start+2;
00363 unsigned char *used=NULL;
00364 if (!create_herogate_number_used_arr(lvl,&used,&used_size))
00365 return start;
00366 int new_num=start;
00367 while (new_num>1)
00368 {
00369 if (used[new_num]==0) break;
00370 new_num--;
00371 }
00372 free(used);
00373 return new_num;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382 short create_herogate_number_used_arr(const struct LEVEL *lvl,unsigned char **used,unsigned int *used_size)
00383 {
00384
00385 const int arr_entries_x=lvl->tlsize.x*MAP_SUBNUM_X;
00386 const int arr_entries_y=lvl->tlsize.y*MAP_SUBNUM_Y;
00387 int k;
00388 *used_size=max(lvl->stats.hero_gates_count+16,*used_size);
00389 *used=malloc((*used_size)*sizeof(unsigned char));
00390 if (*used==NULL) return false;
00391 for (k=0;k<(*used_size);k++)
00392 (*used)[k]=0;
00393 int cy, cx;
00394 for (cy=0; cy<arr_entries_y; cy++)
00395 {
00396 for (cx=0; cx<arr_entries_x; cx++)
00397 {
00398 int num_subs=lvl->tng_subnums[cx][cy];
00399 for (k=0; k<num_subs; k++)
00400 {
00401 char *thing=get_thing(lvl,cx,cy,k);
00402 unsigned char stype_idx=get_thing_subtype(thing);
00403 if (stype_idx==ITEM_SUBTYPE_HEROGATE)
00404 {
00405 unsigned short cnum=get_thing_level(thing);
00406 if (cnum<(*used_size))
00407 (*used)[cnum]++;
00408 else
00409 (*used)[0]++;
00410 }
00411 }
00412 }
00413 }
00414 return true;
00415 }
00416
00417
00418
00419
00420
00421 short owned_things_count(int *count,struct LEVEL *lvl,
00422 unsigned char type_idx,unsigned char stype_idx)
00423 {
00424
00425 const int arr_entries_x=lvl->tlsize.x*MAP_SUBNUM_X;
00426 const int arr_entries_y=lvl->tlsize.y*MAP_SUBNUM_Y;
00427 int i,j,k;
00428 for (i=0; i < arr_entries_y; i++)
00429 for (j=0; j < arr_entries_x; j++)
00430 {
00431 int things_count=get_thing_subnums(lvl,i,j);
00432 for (k=0; k <things_count ; k++)
00433 {
00434 unsigned char *thing = get_thing(lvl,i,j,k);
00435 unsigned char type_id2=get_thing_type(thing);
00436 unsigned char stype_id2=get_thing_subtype(thing);
00437 if ((type_idx==type_id2)&&(stype_idx==stype_id2))
00438 {
00439 unsigned char own=get_thing_owner(thing);
00440 if (own>=PLAYERS_COUNT)
00441 count[PLAYER_UNSET]++;
00442 else
00443 count[own]++;
00444 }
00445 }
00446 }
00447 return true;
00448 }
00449
00450
00451
00452
00453
00454 unsigned char *find_lit_thing_on_square_radius1(struct LEVEL *lvl, int tx, int ty)
00455 {
00456 int i,k;
00457 for (k=ty-1;k<=ty+1;k++)
00458 for (i=tx-1;i<=tx+1;i++)
00459 {
00460 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
00461 {
00462 unsigned char *thing;
00463 thing=find_thing_on_tile(lvl,i,k,is_lit_thing);
00464 if (thing!=NULL) return thing;
00465 }
00466 }
00467 return NULL;
00468 }
00469
00470
00471
00472
00473
00474
00475 unsigned char *find_thing_on_tile(struct LEVEL *lvl, int tx, int ty, is_thing_subtype check_func)
00476 {
00477 int sx, sy, i;
00478 for (sx=tx*3; sx < tx*3+3; sx++)
00479 for (sy=ty*3; sy < ty*3+3; sy++)
00480 {
00481 int count=get_thing_subnums(lvl,sx,sy);
00482 for (i=0; i <count; i++)
00483 {
00484 unsigned char *thing;
00485 thing=get_thing(lvl,sx,sy,i);
00486 if (check_func(thing))
00487 return thing;
00488 }
00489 }
00490 return NULL;
00491 }
00492
00493
00494
00495
00496
00497
00498
00499 unsigned char *find_next_thing_on_map(struct LEVEL *lvl, int *tx, int *ty, is_thing_subtype check_func)
00500 {
00501 message_log(" find_next_thing_on_map: starting");
00502 if (check_func==NULL) return NULL;
00503 if ((*ty)<0) {(*tx)=-1;(*ty)=0;};
00504 if ((*tx)<0) (*tx)=-1;
00505 do {
00506
00507 (*tx)++;
00508 while (*tx>=lvl->tlsize.x)
00509 {
00510 (*tx)-=lvl->tlsize.x;
00511 (*ty)++;
00512 }
00513
00514 unsigned char *thing;
00515 thing=find_thing_on_tile(lvl,*tx,*ty,check_func);
00516 if (thing!=NULL) return thing;
00517 } while ((*ty)<lvl->tlsize.y);
00518 return NULL;
00519 }
00520
00521 unsigned char *find_next_actnpt_on_map(struct LEVEL *lvl, int *tx, int *ty)
00522 {
00523 message_log(" find_next_actnpt_on_map: starting");
00524 if ((*ty)<0) {(*tx)=-1;(*ty)=0;};
00525 if ((*tx)<0) (*tx)=-1;
00526 do {
00527
00528 (*tx)++;
00529 while ((*tx)>=lvl->tlsize.x)
00530 {
00531 (*tx)-=lvl->tlsize.x;
00532 (*ty)++;
00533 }
00534
00535 unsigned char *actnpt;
00536 int sx,sy;
00537 for (sx=(*tx)*3;sx<(*tx)*3+3;sx++)
00538 for (sy=(*ty)*3;sy<(*ty)*3+3;sy++)
00539 {
00540 actnpt=get_actnpt(lvl,sx,sy,0);
00541 if (actnpt!=NULL) return actnpt;
00542 }
00543 } while ((*ty)<lvl->tlsize.y);
00544 return NULL;
00545 }
00546
00547 unsigned char *find_next_stlight_on_map(struct LEVEL *lvl, int *tx, int *ty)
00548 {
00549 message_log(" find_next_stlight_on_map: starting");
00550 if ((*ty)<0) {(*tx)=-1;(*ty)=0;};
00551 if ((*tx)<0) (*tx)=-1;
00552 do {
00553
00554 (*tx)++;
00555 while ((*tx)>=lvl->tlsize.x)
00556 {
00557 (*tx)-=lvl->tlsize.x;
00558 (*ty)++;
00559 }
00560
00561 unsigned char *stlight;
00562 int sx,sy;
00563 for (sx=(*tx)*3;sx<(*tx)*3+3;sx++)
00564 for (sy=(*ty)*3;sy<(*ty)*3+3;sy++)
00565 {
00566 stlight=get_stlight(lvl,sx,sy,0);
00567 if (stlight!=NULL) return stlight;
00568 }
00569 } while ((*ty)<lvl->tlsize.y);
00570 return NULL;
00571 }
00572
00573
00574
00575
00576 unsigned short compute_torch_sensitile(const struct LEVEL *lvl, unsigned char *thing)
00577 {
00578 unsigned short sx=get_thing_subtile_x(thing);
00579 unsigned short sy=get_thing_subtile_y(thing);
00580 int tx=sx/MAP_SUBNUM_X;
00581 int ty=sy/MAP_SUBNUM_Y;
00582 int ntx=tx+(int)(sx%MAP_SUBNUM_X)-1;
00583 int nty=ty+(int)(sy%MAP_SUBNUM_Y)-1;
00584 if (ntx<0) ntx=0;
00585 if (ntx>=lvl->tlsize.x) ntx=lvl->tlsize.x-1;
00586 if (nty<0) nty=0;
00587 if (nty>=lvl->tlsize.x) nty=lvl->tlsize.x-1;
00588 if ((ntx==tx)&&(nty==ty))
00589 return ty*lvl->tlsize.x+tx;
00590 unsigned short slab;
00591
00592
00593 slab=get_tile_slab(lvl,ntx,ty);
00594 if (slab_needs_adjacent_torch(slab))
00595 return ty*lvl->tlsize.x+ntx;
00596
00597 slab=get_tile_slab(lvl,tx,nty);
00598 if (slab_needs_adjacent_torch(slab))
00599 return nty*lvl->tlsize.x+tx;
00600
00601 slab=get_tile_slab(lvl,ntx,nty);
00602 if (slab_needs_adjacent_torch(slab))
00603 return nty*lvl->tlsize.x+ntx;
00604
00605
00606 slab=get_tile_slab(lvl,ntx,ty);
00607 if (slab_is_tall(slab))
00608 return ty*lvl->tlsize.x+ntx;
00609
00610 slab=get_tile_slab(lvl,tx,nty);
00611 if (slab_is_tall(slab))
00612 return nty*lvl->tlsize.x+tx;
00613
00614 slab=get_tile_slab(lvl,ntx,nty);
00615 if (slab_is_tall(slab))
00616 return nty*lvl->tlsize.x+ntx;
00617 return THING_SENSITILE_NONE;
00618 }
00619
00620
00621
00622
00623 unsigned short compute_effectgen_sensitile(const struct LEVEL *lvl, unsigned char *thing)
00624 {
00625 unsigned short sx=get_thing_subtile_x(thing);
00626 unsigned short sy=get_thing_subtile_y(thing);
00627 int tx=sx/MAP_SUBNUM_X;
00628 int ty=sy/MAP_SUBNUM_Y;
00629 return ty*lvl->tlsize.x+tx;
00630 }
00631
00632
00633
00634
00635 unsigned short compute_item_sensitile(const struct LEVEL *lvl, unsigned char *thing)
00636 {
00637 unsigned short sx=get_thing_subtile_x(thing);
00638 unsigned short sy=get_thing_subtile_y(thing);
00639 int tx=sx/MAP_SUBNUM_X;
00640 int ty=sy/MAP_SUBNUM_Y;
00641 unsigned short stype_idx;
00642 stype_idx=get_thing_subtype(thing);
00643 unsigned short slab_type;
00644 slab_type=get_tile_slab(lvl,tx,ty);
00645 int categr=get_thing_subtypes_arridx(thing);
00646 switch (categr)
00647 {
00648 case THING_CATEGR_EFFCTGEN:
00649 return compute_effectgen_sensitile(lvl, thing);
00650 case THING_CATEGR_STATUE:
00651 case THING_CATEGR_HEARTFLAME:
00652 case THING_CATEGR_ROOMEQUIP:
00653 case THING_CATEGR_POLEBAR:
00654 case THING_CATEGR_FURNITURE:
00655 if (slab_is_room(slab_type))
00656 return ty*lvl->tlsize.x+tx;
00657 else
00658 return THING_SENSITILE_NONE;
00659 case THING_CATEGR_TORCHCNDL:
00660 if (is_torch(thing))
00661 return compute_torch_sensitile(lvl,thing);
00662 else
00663 if (slab_is_room(slab_type))
00664 return ty*lvl->tlsize.x+tx;
00665 else
00666 return THING_SENSITILE_NONE;
00667 case THING_CATEGR_ITEMEFFCT:
00668 if ((stype_idx==ITEM_SUBTYPE_TEMPLESPN)&&(slab_is_room(slab_type)))
00669 return ty*lvl->tlsize.x+tx;
00670 else
00671 return THING_SENSITILE_NONE;
00672 case THING_CATEGR_DNCRUCIAL:
00673 if (stype_idx==ITEM_SUBTYPE_HEROGATE)
00674 return THING_SENSITILE_NONE;
00675 else
00676 return ty*lvl->tlsize.x+tx;
00677 case THING_CATEGR_SPINNTNG:
00678 case THING_CATEGR_CREATLAIR:
00679 case THING_CATEGR_FOOD:
00680 return ty*lvl->tlsize.x+tx;
00681 case THING_CATEGR_GOLD:
00682
00683
00684
00685 return THING_SENSITILE_NONE;
00686 case THING_CATEGR_NULL:
00687 case THING_CATEGR_SPECIALBOX:
00688 case THING_CATEGR_SPELLBOOK:
00689 case THING_CATEGR_WRKSHOPBOX:
00690 case THING_CATEGR_UNKNOWN:
00691 case THING_CATEGR_PWHAND:
00692 default:
00693 return THING_SENSITILE_NONE;
00694
00695 case THING_CATEGR_TRAP:
00696 case THING_CATEGR_DOOR:
00697 case THING_CATEGR_CREATR:
00698 return 0;
00699 }
00700 }
00701
00702
00703
00704
00705 unsigned char *create_door(struct LEVEL *lvl, unsigned int sx, unsigned int sy, unsigned char stype_idx)
00706 {
00707 unsigned char *thing;
00708 thing = create_thing(sx,sy);
00709 set_thing_type(thing,THING_TYPE_DOOR);
00710 set_thing_subtype(thing,stype_idx);
00711 set_thing_owner(thing,get_tile_owner(lvl,sx/MAP_SUBNUM_X,sy/MAP_SUBNUM_Y));
00712
00713 set_thing_subtpos(thing,128,128);
00714 set_thing_subtile_h(thing,5);
00715 set_door_orientation(thing,compute_door_orientation(lvl,thing));
00716 set_thing_sensitile(thing,get_free_indexedthing_number(lvl));
00717
00718 set_thing_level(thing,DOOR_PASS_UNLOCKED);
00719 return thing;
00720 }
00721
00722 unsigned char *create_torch(const struct LEVEL *lvl, unsigned int sx, unsigned int sy, unsigned char stype_idx)
00723 {
00724 unsigned char *thing;
00725 thing = create_thing(sx,sy);
00726 set_thing_type(thing,THING_TYPE_ITEM);
00727 set_thing_subtype(thing,stype_idx);
00728 set_thing_owner(thing,get_tile_owner(lvl,sx/MAP_SUBNUM_X,sy/MAP_SUBNUM_Y));
00729
00730 unsigned char sub_x=0x080;
00731 unsigned char sub_y=0x080;
00732 unsigned char subtl_h=2;
00733 unsigned char subpos_h=224;
00734 if ((sx%MAP_SUBNUM_X)==0)
00735 sub_x=0x040;
00736 else
00737 if ((sx%MAP_SUBNUM_X)==2)
00738 sub_x=0x0c0;
00739 else
00740 if ((sy%MAP_SUBNUM_Y)==0)
00741 sub_y=0x040;
00742 else
00743 if ((sy%MAP_SUBNUM_Y)==2)
00744 sub_y=0x0c0;
00745 if (((sx%MAP_SUBNUM_X)==1)&&((sy%MAP_SUBNUM_Y)==1))
00746 {
00747 subtl_h=3;
00748 subpos_h=0;
00749 }
00750 set_thing_subtpos(thing,sub_x,sub_y);
00751 set_thing_subtile_h(thing,subtl_h);
00752 set_thing_subtpos_h(thing,subpos_h);
00753
00754 unsigned short sensitile=compute_torch_sensitile(lvl,thing);
00755 set_thing_sensitile(thing,sensitile);
00756 return thing;
00757 }
00758
00759 unsigned char *create_doorkey(const struct LEVEL *lvl, unsigned int sx, unsigned int sy, unsigned char stype_idx)
00760 {
00761 unsigned char *thing;
00762 thing = create_thing(sx,sy);
00763 int tx=sx/MAP_SUBNUM_X;
00764 int ty=sy/MAP_SUBNUM_Y;
00765 set_thing_type(thing,THING_TYPE_ITEM);
00766 set_thing_subtype(thing,stype_idx);
00767 set_thing_owner(thing,get_tile_owner(lvl,tx,ty));
00768
00769 set_thing_subtile_h(thing,4);
00770 set_thing_subtpos_h(thing,0x000);
00771 set_thing_subtpos(thing,0x080,0x080);
00772
00773 unsigned short sensitile=compute_item_sensitile(lvl,thing);
00774 set_thing_sensitile(thing,sensitile);
00775 return thing;
00776 }
00777
00778
00779
00780
00781 unsigned char *create_effectgen(const struct LEVEL *lvl,unsigned int sx, unsigned int sy, unsigned char stype_idx)
00782 {
00783 unsigned char *thing;
00784 thing = create_thing(sx,sy);
00785 set_thing_type(thing,THING_TYPE_EFFECTGEN);
00786 set_thing_subtype(thing,stype_idx);
00787 set_thing_owner(thing,get_tile_owner(lvl,sx/MAP_SUBNUM_X,sy/MAP_SUBNUM_Y));
00788 set_thing_range_subtile(thing,5);
00789 unsigned short sensitile=compute_effectgen_sensitile(lvl,thing);
00790 set_thing_sensitile(thing,sensitile);
00791 return thing;
00792 }
00793
00794
00795
00796
00797 unsigned char *create_creature(const struct LEVEL *lvl,unsigned int sx, unsigned int sy, unsigned char stype_idx)
00798 {
00799 unsigned char *thing;
00800 thing = create_thing(sx,sy);
00801 set_thing_type(thing,THING_TYPE_CREATURE);
00802 set_thing_subtype(thing,stype_idx);
00803 set_thing_owner(thing,get_tile_owner(lvl,sx/MAP_SUBNUM_X,sy/MAP_SUBNUM_Y));
00804 set_thing_level(thing,0);
00805 set_thing_sensitile(thing,get_free_indexedthing_number(lvl));
00806 return thing;
00807 }
00808
00809
00810
00811
00812 unsigned char *create_trap(const struct LEVEL *lvl,unsigned int sx, unsigned int sy, unsigned char stype_idx)
00813 {
00814 unsigned char *thing;
00815 thing = create_thing(sx,sy);
00816 set_thing_type(thing,THING_TYPE_TRAP);
00817 set_thing_subtype(thing,stype_idx);
00818 set_thing_owner(thing,get_tile_owner(lvl,sx/MAP_SUBNUM_X,sy/MAP_SUBNUM_Y));
00819 set_thing_sensitile(thing,get_free_indexedthing_number(lvl));
00820 return thing;
00821 }
00822
00823
00824
00825
00826 unsigned short get_free_indexedthing_number(const struct LEVEL *lvl)
00827 {
00828
00829 const int arr_entries_x=lvl->tlsize.x*MAP_SUBNUM_X;
00830 const int arr_entries_y=lvl->tlsize.y*MAP_SUBNUM_Y;
00831 int k;
00832 int used_size=lvl->stats.doors_count+lvl->stats.traps_count+lvl->stats.creatures_count+16;
00833 unsigned char *used=malloc(used_size*sizeof(unsigned char));
00834 for (k=0;k<used_size;k++)
00835 used[k]=0;
00836 int cy, cx;
00837 for (cy=0; cy<arr_entries_y; cy++)
00838 {
00839 for (cx=0; cx<arr_entries_x; cx++)
00840 {
00841 int num_subs=lvl->tng_subnums[cx][cy];
00842 for (k=0; k<num_subs; k++)
00843 {
00844 char *thing=get_thing(lvl,cx,cy,k);
00845 if (is_trap(thing)||is_door(thing)||is_creature(thing))
00846 {
00847 unsigned short sensitl=get_thing_sensitile(thing);
00848 if (sensitl<used_size) used[sensitl]=1;
00849 }
00850 }
00851 }
00852 }
00853
00854 int new_num=1;
00855 while (used[new_num]>0) new_num++;
00856 free(used);
00857 return new_num;
00858 }
00859
00860
00861
00862
00863
00864 unsigned char *create_item_adv(const struct LEVEL *lvl, unsigned int sx, unsigned int sy, unsigned char stype_idx)
00865 {
00866 unsigned char *thing;
00867 int tx=sx/MAP_SUBNUM_X;
00868 int ty=sy/MAP_SUBNUM_Y;
00869 if (is_torch_stype(stype_idx))
00870 {
00871 thing=create_torch(lvl,sx,sy,stype_idx);
00872 } else
00873 if (stype_idx==ITEM_SUBTYPE_HEROGATE)
00874 {
00875 thing=create_item(lvl,sx,sy,stype_idx);
00876 set_thing_owner(thing,PLAYER_GOOD);
00877
00878 set_thing_level(thing,get_free_herogate_number(lvl));
00879 unsigned short sensitile=compute_item_sensitile(lvl,thing);
00880 set_thing_sensitile(thing,sensitile);
00881 } else
00882 if (stype_idx==ITEM_SUBTYPE_DNHEART)
00883 {
00884 thing=create_item(lvl,sx,sy,stype_idx);
00885 set_thing_subtile_h(thing,3);
00886 unsigned short sensitile=compute_item_sensitile(lvl,thing);
00887 set_thing_sensitile(thing,sensitile);
00888 } else
00889 if (is_heartflame_stype(stype_idx))
00890 {
00891 thing=create_item(lvl,sx,sy,stype_idx);
00892 set_thing_subtile_h(thing,2);
00893 unsigned short sensitile=compute_item_sensitile(lvl,thing);
00894 set_thing_sensitile(thing,sensitile);
00895 } else
00896 if (stype_idx==ITEM_SUBTYPE_PRISONBAR)
00897 {
00898 thing=create_item(lvl,sx,sy,stype_idx);
00899 set_thing_subtpos(thing,128,128);
00900 unsigned short sensitile=compute_item_sensitile(lvl,thing);
00901 set_thing_sensitile(thing,sensitile);
00902 } else
00903 if (stype_idx==ITEM_SUBTYPE_SPINNKEY)
00904 {
00905 thing=create_doorkey(lvl,sx,sy,stype_idx);
00906 } else
00907 {
00908 thing=create_item(lvl,sx,sy,stype_idx);
00909 unsigned short sensitile=compute_item_sensitile(lvl,thing);
00910 set_thing_sensitile(thing,sensitile);
00911 }
00912 return thing;
00913 }
00914
00915
00916
00917
00918
00919 void remove_automade_obj_for_whole_map(struct LEVEL *lvl)
00920 {
00921 int i,k;
00922 for (k=0;k<lvl->tlsize.y;k++)
00923 for (i=0;i<lvl->tlsize.x;i++)
00924 remove_automade_obj_for_slab(lvl, i, k);
00925 }
00926
00927
00928
00929
00930
00931
00932 void update_obj_for_whole_map(struct LEVEL *lvl)
00933 {
00934 int i,k;
00935 for (k=0;k<lvl->tlsize.y;k++)
00936 for (i=0;i<lvl->tlsize.x;i++)
00937 update_clmaffective_obj_for_slab(lvl, i, k);
00938 }
00939
00940
00941
00942
00943
00944 void update_obj_for_square_radius1(struct LEVEL *lvl, int tx, int ty)
00945 {
00946 int i,k;
00947 for (k=ty-1;k<=ty+1;k++)
00948 for (i=tx-1;i<=tx+1;i++)
00949 {
00950 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
00951 update_clmaffective_obj_for_slab(lvl, i, k);
00952 }
00953 }
00954
00955
00956
00957
00958 void update_obj_for_square(struct LEVEL *lvl, int tx_first, int tx_last,
00959 int ty_first, int ty_last)
00960 {
00961 int i,k;
00962 for (k=ty_first;k<=ty_last;k++)
00963 for (i=tx_first;i<=tx_last;i++)
00964 {
00965 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
00966 update_clmaffective_obj_for_slab(lvl, i, k);
00967 }
00968 }
00969
00970 void remove_automade_obj_for_slab(struct LEVEL *lvl, int tx, int ty)
00971 {
00972 unsigned short slab=get_tile_slab(lvl,tx,ty);
00973 int sx, sy, i;
00974 for (sx=tx*3; sx < tx*3+3; sx++)
00975 for (sy=ty*3; sy < ty*3+3; sy++)
00976 {
00977 int last_stlight=get_stlight_subnums(lvl,sx,sy)-1;
00978 for (i=last_stlight; i >=0; i--)
00979 stlight_del(lvl,sx, sy, i);
00980 int last_thing=get_thing_subnums(lvl,sx,sy)-1;
00981 for (i=last_thing; i>=0; i--)
00982 {
00983 char *thing=get_thing(lvl,sx,sy,i);
00984 short should_delete=false;
00985 int categr=get_thing_subtypes_arridx(thing);
00986 switch (categr)
00987 {
00988
00989 case THING_CATEGR_CREATR:
00990 case THING_CATEGR_SPECIALBOX:
00991 case THING_CATEGR_SPELLBOOK:
00992 case THING_CATEGR_WRKSHOPBOX:
00993 case THING_CATEGR_TRAP:
00994 case THING_CATEGR_GOLD:
00995 break;
00996
00997 case THING_CATEGR_STATUE:
00998 case THING_CATEGR_FURNITURE:
00999 if (is_room_inventory(thing) && slab_is_room(slab))
01000 should_delete=true;
01001 break;
01002
01003 case THING_CATEGR_DNCRUCIAL:
01004 {
01005 unsigned short stype_idx=get_thing_subtype(thing);
01006 if (stype_idx!=ITEM_SUBTYPE_HEROGATE)
01007 should_delete=true;
01008 };break;
01009
01010 case THING_CATEGR_NULL:
01011 case THING_CATEGR_EFFCTGEN:
01012 case THING_CATEGR_ITEMEFFCT:
01013 case THING_CATEGR_CREATLAIR:
01014 case THING_CATEGR_DOOR:
01015 case THING_CATEGR_SPINNTNG:
01016 case THING_CATEGR_FOOD:
01017 case THING_CATEGR_TORCHCNDL:
01018 case THING_CATEGR_HEARTFLAME:
01019 case THING_CATEGR_POLEBAR:
01020 case THING_CATEGR_ROOMEQUIP:
01021 case THING_CATEGR_PWHAND:
01022 case THING_CATEGR_UNKNOWN:
01023 default:
01024 should_delete=true;
01025 break;
01026 }
01027
01028 unsigned char expect_slb=get_usual_thing_slab(thing);
01029 if ((expect_slb!=slab)&&
01030 ((expect_slb!=SLAB_TYPE_CLAIMED)||(slab_is_tall(slab))))
01031 should_delete=true;
01032
01033 if (should_delete)
01034 thing_del(lvl,sx, sy, i);
01035 }
01036 }
01037 }
01038
01039 void update_clmaffective_obj_for_slab(struct LEVEL *lvl, int tx, int ty)
01040 {
01041 remove_misplaced_objs_on_slab(lvl,tx,ty);
01042 unsigned short slab=get_tile_slab(lvl,tx,ty);
01043 if (slab_is_room(slab))
01044 {
01045 update_room_things_on_slab(lvl,tx,ty);
01046 } else
01047 if (slab_is_door(slab))
01048 {
01049 update_door_things_on_slab(lvl,tx,ty);
01050 } else
01051 if (slab_needs_adjacent_torch(slab))
01052 {
01053 update_torch_things_near_slab(lvl,tx,ty);
01054 }
01055 }
01056
01057
01058
01059
01060 void remove_misplaced_objs_on_slab(struct LEVEL *lvl, int tx, int ty)
01061 {
01062 unsigned short slab=get_tile_slab(lvl,tx,ty);
01063 int sx, sy, i;
01064 for (sx=tx*3; sx < tx*3+3; sx++)
01065 for (sy=ty*3; sy < ty*3+3; sy++)
01066 {
01067 int last_thing=get_thing_subnums(lvl,sx,sy)-1;
01068 for (i=last_thing; i>=0; i--)
01069 {
01070 char *thing=get_thing(lvl,sx,sy,i);
01071 unsigned char expect_slb=get_usual_thing_slab(thing);
01072 if ((expect_slb!=slab)&&
01073 ((expect_slb!=SLAB_TYPE_CLAIMED)||(slab_is_tall(slab))))
01074 thing_del(lvl,sx, sy, i);
01075 }
01076 }
01077 }
01078
01079
01080
01081
01082
01083
01084
01085 void update_room_things_on_slab(struct LEVEL *lvl, int tx, int ty)
01086 {
01087 unsigned short slab=get_tile_slab(lvl,tx,ty);
01088 switch (slab)
01089 {
01090 case SLAB_TYPE_PORTAL:
01091 create_things_slb_room(delete_room_things,delete_room_things,
01092 delete_room_things,update_things_slb_portal_inside,delete_room_things,
01093 lvl, tx, ty);
01094 break;
01095 case SLAB_TYPE_TREASURE:
01096 create_things_slb_room(delete_room_things,delete_room_things,
01097 update_things_slb_treasure_corner,delete_room_things,delete_room_things,
01098 lvl, tx, ty);
01099 break;
01100 case SLAB_TYPE_PRISONCASE:
01101 create_things_slb_room_simple(update_things_slb_prison,lvl,tx,ty);
01102 break;
01103 case SLAB_TYPE_TORTURE:
01104 create_things_slb_room(update_things_slb_torture_edge,update_things_slb_torture_edge,
01105 update_things_slb_torture_edge,update_things_slb_torture_inside,update_things_slb_torture_inside,
01106 lvl, tx, ty);
01107 break;
01108 case SLAB_TYPE_TRAINING:
01109 create_things_slb_room(delete_room_things,delete_room_things,
01110 update_things_slb_training_corner,update_things_slb_training_inside,delete_room_things,
01111 lvl, tx, ty);
01112 break;
01113 case SLAB_TYPE_DUNGHEART:
01114 create_things_slb_room(delete_room_things,delete_room_things,
01115 update_things_slb_dungheart_corner,update_things_slb_dungheart_inside,delete_room_things,
01116 lvl, tx, ty);
01117 break;
01118 case SLAB_TYPE_WORKSHOP:
01119 create_things_slb_room(delete_room_things,delete_room_things,
01120 update_things_slb_workshop_corner,update_things_slb_workshop_inside,delete_room_things,
01121 lvl, tx, ty);
01122 break;
01123 case SLAB_TYPE_SCAVENGER:
01124 create_things_slb_room(delete_room_things,delete_room_things,
01125 update_things_slb_scavenger_corner,update_things_slb_scavenger_inside,delete_room_things,
01126 lvl, tx, ty);
01127 break;
01128 case SLAB_TYPE_TEMPLE:
01129 create_things_slb_room(delete_room_things,delete_room_things,
01130 update_things_slb_temple_corner,delete_room_things,delete_room_things,
01131 lvl, tx, ty);
01132 break;
01133 case SLAB_TYPE_GRAVEYARD:
01134 create_things_slb_room(update_things_slb_graveyard_floor,update_things_slb_graveyard_floor,
01135 update_things_slb_graveyard_corner,update_things_slb_graveyard_floor,update_things_slb_graveyard_floor,
01136 lvl, tx, ty);
01137 break;
01138 case SLAB_TYPE_HATCHERY:
01139 create_things_slb_room(delete_room_things,delete_room_things,
01140 update_things_slb_hatchery_corner,delete_room_things,delete_room_things,
01141 lvl, tx, ty);
01142 break;
01143 case SLAB_TYPE_BRIDGE:
01144 create_things_slb_room_simple(delete_room_things,lvl,tx,ty);
01145 break;
01146 case SLAB_TYPE_GUARDPOST:
01147 create_things_slb_room_simple(update_things_slb_guardpost_floor,lvl,tx,ty);
01148 break;
01149 case SLAB_TYPE_BARRACKS:
01150 create_things_slb_room(delete_room_things,delete_room_things,
01151 update_things_slb_barracks_corner,delete_room_things,delete_room_things,
01152 lvl, tx, ty);
01153 break;
01154 case SLAB_TYPE_LIBRARY:
01155 case SLAB_TYPE_LAIR:
01156 default:
01157 create_things_slb_room_simple(delete_room_things,lvl,tx,ty);
01158 break;
01159 }
01160 }
01161
01162
01163
01164
01165
01166
01167
01168 void update_door_things_on_slab(struct LEVEL *lvl, int tx, int ty)
01169 {
01170 unsigned char door_subtype;
01171 unsigned short slab=get_tile_slab(lvl,tx,ty);
01172 switch (slab)
01173 {
01174 case SLAB_TYPE_DOORWOOD1:
01175 case SLAB_TYPE_DOORWOOD2:
01176 door_subtype=DOOR_SUBTYPE_WOOD;
01177 break;
01178 case SLAB_TYPE_DOORBRACE1:
01179 case SLAB_TYPE_DOORBRACE2:
01180 door_subtype=DOOR_SUBTYPE_BRACED;
01181 break;
01182 case SLAB_TYPE_DOORIRON1:
01183 case SLAB_TYPE_DOORIRON2:
01184 door_subtype=DOOR_SUBTYPE_IRON;
01185 break;
01186 case SLAB_TYPE_DOORMAGIC1:
01187 case SLAB_TYPE_DOORMAGIC2:
01188 door_subtype=DOOR_SUBTYPE_MAGIC;
01189 break;
01190 default:
01191 door_subtype=DOOR_SUBTYPE_WOOD;
01192 break;
01193 }
01194
01195 unsigned char *thing=NULL;
01196 unsigned char *sec_thing;
01197 int sx, sy, i;
01198 for (sx=tx*3; sx < tx*3+3; sx++)
01199 for (sy=ty*3; sy < ty*3+3; sy++)
01200 for (i=get_thing_subnums(lvl,sx,sy)-1; i >=0; i--)
01201 {
01202 sec_thing=get_thing(lvl,sx,sy,i);
01203 if (is_door(sec_thing))
01204 {
01205
01206 if (thing!=NULL)
01207 thing_del(lvl,sx, sy, i);
01208 else
01209 {
01210
01211
01212 thing=sec_thing;
01213 thing_drop(lvl,sx, sy, i);
01214 }
01215 }
01216 }
01217
01218 if (thing==NULL)
01219 {
01220 thing=create_door(lvl, tx*MAP_SUBNUM_X+1, ty*MAP_SUBNUM_Y+1, door_subtype);
01221 } else
01222
01223 {
01224 set_thing_subtype(thing,door_subtype);
01225 set_thing_subtile(thing,tx*MAP_SUBNUM_X+1,ty*MAP_SUBNUM_Y+1);
01226 set_door_lock(lvl, thing, get_door_lock(thing));
01227 set_door_orientation(thing,compute_door_orientation(lvl,thing));
01228 }
01229 thing_add(lvl,thing);
01230 }
01231
01232
01233
01234
01235
01236
01237
01238
01239 void update_torch_things_near_slab(struct LEVEL *lvl, int tx, int ty)
01240 {
01241 const unsigned short dir_a[]={IDIR_WEST, IDIR_NORTH, IDIR_EAST, IDIR_SOUTH};
01242 const unsigned short dir_b[]={IDIR_EAST, IDIR_SOUTH, IDIR_WEST, IDIR_NORTH};
01243 int i;
01244 short allow_torch[9];
01245
01246 for (i=0;i<9;i++)
01247 {
01248 int cur_tx,cur_ty;
01249 cur_tx=tx+idir_subtl_x[i]-1;
01250 cur_ty=ty+idir_subtl_y[i]-1;
01251 unsigned short slab;
01252 slab=get_tile_slab(lvl,cur_tx,cur_ty);
01253 allow_torch[i]=slab_allows_torch(slab);
01254 }
01255
01256 for (i=0;i<4;i++)
01257 if (allow_torch[dir_a[i]])
01258 {
01259 int cur_tx,cur_ty;
01260 cur_tx=tx+idir_subtl_x[dir_a[i]]-1;
01261 cur_ty=ty+idir_subtl_y[dir_a[i]]-1;
01262
01263 if (find_lit_thing_on_square_radius1(lvl,cur_tx,cur_ty)==NULL)
01264 {
01265 int sx,sy;
01266 sx=cur_tx*3+idir_subtl_x[dir_b[i]];
01267 sy=cur_ty*3+idir_subtl_y[dir_b[i]];
01268 update_thing_slb_room_one_item_subtl(lvl,sx,sy,ITEM_SUBTYPE_TORCH,false);
01269 }
01270 }
01271 }
01272
01273
01274
01275
01276
01277 void create_things_slb_room(cr_tng_func cr_floor,cr_tng_func cr_edge,
01278 cr_tng_func cr_corner,cr_tng_func cr_inside,cr_tng_func cr_nearinsd,
01279 struct LEVEL *lvl, int tx, int ty)
01280 {
01281 const unsigned short dir_a[]={IDIR_NORTH, IDIR_NORTH, IDIR_SOUTH, IDIR_SOUTH};
01282 const unsigned short dir_b[]={IDIR_WEST, IDIR_EAST, IDIR_EAST, IDIR_WEST};
01283 const unsigned short dir_c[]={IDIR_NW, IDIR_NE, IDIR_SE, IDIR_SW};
01284 const unsigned short dir_x[]={0, 2, 2, 0};
01285 const unsigned short dir_y[]={0, 0, 2, 2};
01286 unsigned char *surr_slb=(unsigned char *)malloc(9*sizeof(unsigned char));
01287 unsigned char *surr_own=(unsigned char *)malloc(9*sizeof(unsigned char));
01288 get_slab_surround(surr_slb,surr_own,NULL,lvl,tx,ty);
01289 unsigned short slab=surr_slb[IDIR_CENTR];
01290 unsigned char ownr=surr_own[IDIR_CENTR];
01291 struct UPOINT_2D corner_pos={1,1};
01292
01293 if ((surr_slb[IDIR_NORTH]==slab)&&(surr_own[IDIR_NORTH]==ownr) &&
01294 (surr_slb[IDIR_EAST]==slab)&&(surr_own[IDIR_EAST]==ownr) &&
01295 (surr_slb[IDIR_SOUTH]==slab)&&(surr_own[IDIR_SOUTH]==ownr) &&
01296 (surr_slb[IDIR_WEST]==slab)&&(surr_own[IDIR_WEST]==ownr))
01297 {
01298 int i;
01299 for (i=0;i<4;i++)
01300 {
01301 if ((surr_slb[dir_c[i]]!=slab)||(surr_own[dir_c[i]]!=ownr))
01302 {
01303 corner_pos.x=dir_x[i];
01304 corner_pos.y=dir_y[i];
01305 }
01306 }
01307
01308 if ((corner_pos.x==1)||(corner_pos.y==1))
01309 {
01310 corner_pos.x=dir_x[0];
01311 corner_pos.y=dir_y[0];
01312 cr_inside(lvl,tx,ty,surr_slb,surr_own,corner_pos);
01313 } else
01314 {
01315
01316
01317 cr_nearinsd(lvl,tx,ty,surr_slb,surr_own,corner_pos);
01318 }
01319 return;
01320 }
01321
01322 if (((surr_slb[IDIR_NORTH]==slab)&&(surr_own[IDIR_NORTH]==ownr) &&
01323 (surr_slb[IDIR_NE]==slab)&&(surr_own[IDIR_NE]==ownr) &&
01324 (surr_slb[IDIR_EAST]==slab)&&(surr_own[IDIR_EAST]==ownr) &&
01325 (surr_slb[IDIR_SE]==slab)&&(surr_own[IDIR_SE]==ownr) &&
01326 (surr_slb[IDIR_SOUTH]==slab)&&(surr_own[IDIR_SOUTH]==ownr)))
01327 {
01328 corner_pos.x=dir_x[3];
01329 corner_pos.y=dir_y[3];
01330 }
01331 if (((surr_slb[IDIR_EAST]==slab)&&(surr_own[IDIR_EAST]==ownr) &&
01332 (surr_slb[IDIR_SE]==slab)&&(surr_own[IDIR_SE]==ownr) &&
01333 (surr_slb[IDIR_SOUTH]==slab)&&(surr_own[IDIR_SOUTH]==ownr) &&
01334 (surr_slb[IDIR_SW]==slab)&&(surr_own[IDIR_SW]==ownr) &&
01335 (surr_slb[IDIR_WEST]==slab)&&(surr_own[IDIR_WEST]==ownr)))
01336 {
01337 corner_pos.x=dir_x[0];
01338 corner_pos.y=dir_y[0];
01339 }
01340 if (((surr_slb[IDIR_SOUTH]==slab)&&(surr_own[IDIR_SOUTH]==ownr) &&
01341 (surr_slb[IDIR_SW]==slab)&&(surr_own[IDIR_SW]==ownr) &&
01342 (surr_slb[IDIR_WEST]==slab)&&(surr_own[IDIR_WEST]==ownr) &&
01343 (surr_slb[IDIR_NW]==slab)&&(surr_own[IDIR_NW]==ownr) &&
01344 (surr_slb[IDIR_NORTH]==slab)&&(surr_own[IDIR_NORTH]==ownr)))
01345 {
01346 corner_pos.x=dir_x[1];
01347 corner_pos.y=dir_y[1];
01348 }
01349 if (((surr_slb[IDIR_WEST]==slab)&&(surr_own[IDIR_WEST]==ownr) &&
01350 (surr_slb[IDIR_NW]==slab)&&(surr_own[IDIR_NW]==ownr) &&
01351 (surr_slb[IDIR_NORTH]==slab)&&(surr_own[IDIR_NORTH]==ownr) &&
01352 (surr_slb[IDIR_NE]==slab)&&(surr_own[IDIR_NE]==ownr) &&
01353 (surr_slb[IDIR_EAST]==slab)&&(surr_own[IDIR_EAST]==ownr)))
01354 {
01355 corner_pos.x=dir_x[2];
01356 corner_pos.y=dir_y[2];
01357 }
01358 if ((corner_pos.x!=1)&&(corner_pos.y!=1))
01359 {
01360 cr_edge(lvl,tx,ty,surr_slb,surr_own,corner_pos);
01361 return;
01362 }
01363
01364
01365 if (((surr_slb[IDIR_NORTH]==slab)&&(surr_own[IDIR_NORTH]==ownr) &&
01366 (surr_slb[IDIR_EAST]==slab)&&(surr_own[IDIR_EAST]==ownr) &&
01367 ((surr_slb[IDIR_SOUTH]!=slab)||(surr_own[IDIR_SOUTH]!=ownr)) &&
01368 ((surr_slb[IDIR_WEST]!=slab)||(surr_own[IDIR_WEST]!=ownr))))
01369 {
01370 corner_pos.x=dir_x[3];
01371 corner_pos.y=dir_y[3];
01372 }
01373 if (((surr_slb[IDIR_EAST]==slab)&&(surr_own[IDIR_EAST]==ownr) &&
01374 (surr_slb[IDIR_SOUTH]==slab)&&(surr_own[IDIR_SOUTH]==ownr) &&
01375 ((surr_slb[IDIR_NORTH]!=slab)||(surr_own[IDIR_NORTH]!=ownr)) &&
01376 ((surr_slb[IDIR_WEST]!=slab)||(surr_own[IDIR_WEST]!=ownr))))
01377 {
01378 corner_pos.x=dir_x[0];
01379 corner_pos.y=dir_y[0];
01380 }
01381 if (((surr_slb[IDIR_SOUTH]==slab)&&(surr_own[IDIR_SOUTH]==ownr) &&
01382 (surr_slb[IDIR_WEST]==slab)&&(surr_own[IDIR_WEST]==ownr) &&
01383 ((surr_slb[IDIR_NORTH]!=slab)||(surr_own[IDIR_NORTH]!=ownr)) &&
01384 ((surr_slb[IDIR_EAST]!=slab)||(surr_own[IDIR_EAST]!=ownr))))
01385 {
01386 corner_pos.x=dir_x[1];
01387 corner_pos.y=dir_y[1];
01388 }
01389 if (((surr_slb[IDIR_WEST]==slab)&&(surr_own[IDIR_WEST]==ownr) &&
01390 (surr_slb[IDIR_NORTH]==slab)&&(surr_own[IDIR_NORTH]==ownr) &&
01391 ((surr_slb[IDIR_SOUTH]!=slab)||(surr_own[IDIR_SOUTH]!=ownr)) &&
01392 ((surr_slb[IDIR_EAST]!=slab)||(surr_own[IDIR_EAST]!=ownr))))
01393 {
01394 corner_pos.x=dir_x[2];
01395 corner_pos.y=dir_y[2];
01396 }
01397
01398 if ((corner_pos.x!=1)&&(corner_pos.y!=1))
01399 {
01400 cr_corner(lvl,tx,ty,surr_slb,surr_own,corner_pos);
01401 return;
01402 }
01403 corner_pos.x=dir_x[0];
01404 corner_pos.y=dir_y[0];
01405
01406 cr_floor(lvl,tx,ty,surr_slb,surr_own,corner_pos);
01407 }
01408
01409
01410
01411
01412 void create_things_slb_room_simple(cr_tng_func cr_any,
01413 struct LEVEL *lvl, int tx, int ty)
01414 {
01415 unsigned char *surr_slb=(unsigned char *)malloc(9*sizeof(unsigned char));
01416 unsigned char *surr_own=(unsigned char *)malloc(9*sizeof(unsigned char));
01417 get_slab_surround(surr_slb,surr_own,NULL,lvl,tx,ty);
01418 struct UPOINT_2D corner_pos={0,0};
01419 unsigned short slab=surr_slb[IDIR_CENTR];
01420 unsigned char ownr=surr_own[IDIR_CENTR];
01421
01422 cr_any(lvl,tx,ty,surr_slb,surr_own,corner_pos);
01423 }
01424
01425 void delete_room_things(struct LEVEL *lvl, const int tx, const int ty,
01426 const unsigned char *surr_slb,const unsigned char *surr_own,
01427 const struct UPOINT_2D corner_pos)
01428 {
01429 int sx, sy;
01430 for (sx=tx*MAP_SUBNUM_X; sx < (tx+1)*MAP_SUBNUM_X; sx++)
01431 for (sy=ty*MAP_SUBNUM_Y; sy < (ty+1)*MAP_SUBNUM_Y; sy++)
01432 {
01433 delete_room_things_subtl(lvl,sx,sy);
01434 }
01435 }
01436
01437 void delete_room_things_subtl(struct LEVEL *lvl, int sx, int sy)
01438 {
01439 int last_thing=get_thing_subnums(lvl,sx,sy)-1;
01440 int i;
01441 for (i=last_thing; i>=0; i--)
01442 {
01443 unsigned char *thing=get_thing(lvl,sx,sy,i);
01444 if (is_room_inventory(thing))
01445 {
01446
01447
01448 if (is_torch(thing))
01449 if (subtl_is_near_tall_slab(lvl,sx,sy))
01450 continue;
01451
01452 thing_del(lvl,sx, sy, i);
01453 }
01454 }
01455 }
01456
01457 void update_things_slb_portal_inside(struct LEVEL *lvl, const int tx, const int ty,
01458 const unsigned char *surr_slb,const unsigned char *surr_own,
01459 const struct UPOINT_2D corner_pos)
01460 {
01461 int sx, sy, i;
01462 unsigned char *thing_eff=NULL;
01463 unsigned char *thing_eff2=NULL;
01464 for (sx=tx*MAP_SUBNUM_X; sx < (tx+1)*MAP_SUBNUM_X; sx++)
01465 for (sy=ty*MAP_SUBNUM_Y; sy < (ty+1)*MAP_SUBNUM_Y; sy++)
01466 {
01467 int last_thing=get_thing_subnums(lvl,sx,sy)-1;
01468 for (i=last_thing; i>=0; i--)
01469 {
01470 unsigned char *thing=get_thing(lvl,sx,sy,i);
01471 if (is_room_inventory(thing))
01472 {
01473 unsigned char stype_idx=get_thing_subtype(thing);
01474 if (is_effectgen(thing)&&(stype_idx==EFCTGEN_SUBTP_ENTRICE)&&(thing_eff==NULL))
01475 thing_eff=thing;
01476 else
01477
01478 if (is_effectgen(thing)&&(stype_idx==EFCTGEN_SUBTP_ENTRICE)&&(thing_eff2==NULL))
01479 thing_eff2=thing;
01480 else
01481 thing_del(lvl,sx, sy, i);
01482 }
01483 }
01484 }
01485 sx=tx*MAP_SUBNUM_X+1;
01486 sy=ty*MAP_SUBNUM_Y+1;
01487 if (thing_eff==NULL)
01488 {
01489 thing_eff=create_effectgen(lvl,sx,sy, EFCTGEN_SUBTP_ENTRICE);
01490 thing_add(lvl,thing_eff);
01491 } else
01492 {
01493
01494 set_thing_owner(thing_eff,get_tile_owner(lvl,tx,ty));
01495 }
01496
01497 if (thing_eff2!=NULL)
01498 {
01499
01500 set_thing_owner(thing_eff2,get_tile_owner(lvl,tx,ty));
01501 }
01502 }
01503
01504 unsigned char *update_thing_slb_room_one_central_item(struct LEVEL *lvl, int tx, int ty,
01505 unsigned char itm_stype_idx,short allow_create)
01506 {
01507 int sx, sy, i;
01508 unsigned char *thing_dst=NULL;
01509 short other_thing_at_center=false;
01510 for (sx=tx*MAP_SUBNUM_X; sx < (tx+1)*MAP_SUBNUM_X; sx++)
01511 for (sy=ty*MAP_SUBNUM_Y; sy < (ty+1)*MAP_SUBNUM_Y; sy++)
01512 {
01513 int last_thing=get_thing_subnums(lvl,sx,sy)-1;
01514 for (i=last_thing; i>=0; i--)
01515 {
01516 unsigned char *thing=get_thing(lvl,sx,sy,i);
01517 if (is_room_inventory(thing))
01518 {
01519 unsigned char type_idx=get_thing_type(thing);
01520 unsigned char stype_idx=get_thing_subtype(thing);
01521 if ((type_idx==THING_TYPE_ITEM)&&(stype_idx==itm_stype_idx)&&(thing_dst==NULL))
01522 {
01523 thing_dst=thing;
01524 } else
01525
01526 if ((type_idx==THING_TYPE_ITEM)&&(is_torch_stype(stype_idx))&&(!is_torch_stype(itm_stype_idx)))
01527 {
01528 if ((sx==tx*MAP_SUBNUM_X+1)&&(sy==ty*MAP_SUBNUM_Y+1))
01529 other_thing_at_center=true;
01530 } else
01531 {
01532 thing_del(lvl,sx, sy, i);
01533 }
01534 } else
01535 {
01536 if ((sx==tx*MAP_SUBNUM_X+1)&&(sy==ty*MAP_SUBNUM_Y+1))
01537 other_thing_at_center=true;
01538 }
01539 }
01540 }
01541 sx=tx*MAP_SUBNUM_X+1;
01542 sy=ty*MAP_SUBNUM_Y+1;
01543 if (thing_dst==NULL)
01544 {
01545 if ((!other_thing_at_center)&&(allow_create))
01546 {
01547 thing_dst=create_item_adv(lvl,sx,sy,itm_stype_idx);
01548 thing_add(lvl,thing_dst);
01549 }
01550 } else
01551 {
01552
01553 set_thing_owner(thing_dst,get_tile_owner(lvl,tx,ty));
01554 }
01555 return thing_dst;
01556 }
01557
01558 unsigned char *update_thing_slb_room_one_item_subtl(struct LEVEL *lvl, int sx, int sy,
01559 unsigned char itm_stype_idx, short allow_delete)
01560 {
01561 int i;
01562 unsigned char *thing_dst=NULL;
01563 short other_thing_there=false;
01564 int last_thing=get_thing_subnums(lvl,sx,sy)-1;
01565 for (i=last_thing; i>=0; i--)
01566 {
01567 unsigned char *thing=get_thing(lvl,sx,sy,i);
01568 if (is_room_inventory(thing))
01569 {
01570 unsigned char type_idx=get_thing_type(thing);
01571 unsigned char stype_idx=get_thing_subtype(thing);
01572 if ((type_idx==THING_TYPE_ITEM)&&(stype_idx==itm_stype_idx)&&(thing_dst==NULL))
01573 {
01574 thing_dst=thing;
01575 } else
01576
01577 if ((type_idx==THING_TYPE_ITEM)&&(is_torch_stype(stype_idx))&&(!is_torch_stype(itm_stype_idx)))
01578 {
01579 other_thing_there=true;
01580 } else
01581 if (allow_delete)
01582 {
01583 thing_del(lvl,sx, sy, i);
01584 }
01585 } else
01586 {
01587 other_thing_there=true;
01588 }
01589 }
01590 if (thing_dst==NULL)
01591 {
01592 if (!other_thing_there)
01593 {
01594 thing_dst=create_item_adv(lvl,sx,sy,itm_stype_idx);
01595 thing_add(lvl,thing_dst);
01596 }
01597 } else
01598 {
01599
01600 set_thing_owner(thing_dst,get_tile_owner(lvl,sx/MAP_SUBNUM_X,sy/MAP_SUBNUM_Y));
01601 }
01602 return thing_dst;
01603 }
01604
01605 void update_things_slb_training_inside(struct LEVEL *lvl, const int tx, const int ty,
01606 const unsigned char *surr_slb,const unsigned char *surr_own,
01607 const struct UPOINT_2D corner_pos)
01608 {
01609 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_TRAINPOST,true);
01610 }
01611
01612 void update_things_slb_scavenger_inside(struct LEVEL *lvl, const int tx, const int ty,
01613 const unsigned char *surr_slb,const unsigned char *surr_own,
01614 const struct UPOINT_2D corner_pos)
01615 {
01616 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_SCAVNGEYE,true);
01617 }
01618
01619 void update_things_slb_graveyard_floor(struct LEVEL *lvl, const int tx, const int ty,
01620 const unsigned char *surr_slb,const unsigned char *surr_own,
01621 const struct UPOINT_2D corner_pos)
01622 {
01623 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_GRAVSTONE,true);
01624 }
01625
01626 void update_things_slb_workshop_inside(struct LEVEL *lvl, const int tx, const int ty,
01627 const unsigned char *surr_slb,const unsigned char *surr_own,
01628 const struct UPOINT_2D corner_pos)
01629 {
01630 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_WRKSHPMCH,true);
01631 }
01632
01633 void update_things_slb_torture_inside(struct LEVEL *lvl, const int tx, const int ty,
01634 const unsigned char *surr_slb,const unsigned char *surr_own,
01635 const struct UPOINT_2D corner_pos)
01636 {
01637 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_TORTURER,true);
01638 }
01639
01640 void update_things_slb_treasure_corner(struct LEVEL *lvl, const int tx, const int ty,
01641 const unsigned char *surr_slb,const unsigned char *surr_own,
01642 const struct UPOINT_2D corner_pos)
01643 {
01644 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_CANDLSTCK,true);
01645 }
01646
01647 void update_things_slb_torture_edge(struct LEVEL *lvl, const int tx, const int ty,
01648 const unsigned char *surr_slb,const unsigned char *surr_own,
01649 const struct UPOINT_2D corner_pos)
01650 {
01651 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_TORTSPIKE,true);
01652 }
01653
01654 void update_things_slb_training_corner(struct LEVEL *lvl, const int tx, const int ty,
01655 const unsigned char *surr_slb,const unsigned char *surr_own,
01656 const struct UPOINT_2D corner_pos)
01657 {
01658 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_TORCH,true);
01659 }
01660
01661 void update_things_slb_scavenger_corner(struct LEVEL *lvl, const int tx, const int ty,
01662 const unsigned char *surr_slb,const unsigned char *surr_own,
01663 const struct UPOINT_2D corner_pos)
01664 {
01665 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_TORCH,true);
01666 }
01667
01668 void update_things_slb_hatchery_corner(struct LEVEL *lvl, const int tx, const int ty,
01669 const unsigned char *surr_slb,const unsigned char *surr_own,
01670 const struct UPOINT_2D corner_pos)
01671 {
01672 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_TORCH,true);
01673 }
01674
01675 void update_things_slb_temple_corner(struct LEVEL *lvl, const int tx, const int ty,
01676 const unsigned char *surr_slb,const unsigned char *surr_own,
01677 const struct UPOINT_2D corner_pos)
01678 {
01679 unsigned char *thing;
01680 thing=update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_TEMPLESTA,true);
01681 set_thing_subtile_h(thing,2);
01682 }
01683
01684 void update_things_slb_workshop_corner(struct LEVEL *lvl, const int tx, const int ty,
01685 const unsigned char *surr_slb,const unsigned char *surr_own,
01686 const struct UPOINT_2D corner_pos)
01687 {
01688 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_ANVIL,true);
01689 }
01690
01691 void update_things_slb_barracks_corner(struct LEVEL *lvl, const int tx, const int ty,
01692 const unsigned char *surr_slb,const unsigned char *surr_own,
01693 const struct UPOINT_2D corner_pos)
01694 {
01695 int sx, sy, i;
01696 short allow_torch=0;
01697 if (slab_is_wall(surr_slb[(1)*3+(corner_pos.x)]))
01698 allow_torch|=1;
01699 if (slab_is_wall(surr_slb[(corner_pos.y)*3+(1)]))
01700 allow_torch|=2;
01701 unsigned char *thing_trch=NULL;
01702 for (sx=tx*MAP_SUBNUM_X; sx < (tx+1)*MAP_SUBNUM_X; sx++)
01703 for (sy=ty*MAP_SUBNUM_Y; sy < (ty+1)*MAP_SUBNUM_Y; sy++)
01704 {
01705 int last_thing=get_thing_subnums(lvl,sx,sy)-1;
01706 for (i=last_thing; i>=0; i--)
01707 {
01708 unsigned char *thing=get_thing(lvl,sx,sy,i);
01709 if (is_room_inventory(thing))
01710 {
01711 unsigned char type_idx=get_thing_type(thing);
01712 unsigned char stype_idx=get_thing_subtype(thing);
01713
01714 if ((type_idx==THING_TYPE_ITEM)&&(is_torch_stype(stype_idx))&&(allow_torch>0)&&(thing_trch==NULL))
01715 {
01716 thing_trch=thing;
01717 continue;
01718 } else
01719 {
01720 thing_del(lvl,sx, sy, i);
01721 }
01722 }
01723 }
01724 }
01725 if (allow_torch>0)
01726 {
01727 if ((allow_torch&1)==1)
01728 {
01729 sx=tx*MAP_SUBNUM_X+corner_pos.x;
01730 sy=ty*MAP_SUBNUM_Y+1;
01731 } else
01732 {
01733 sx=tx*MAP_SUBNUM_X+1;
01734 sy=ty*MAP_SUBNUM_Y+corner_pos.y;
01735 }
01736 if (thing_trch==NULL)
01737 {
01738 thing_trch=create_item_adv(lvl,sx,sy,ITEM_SUBTYPE_TORCH);
01739 thing_add(lvl,thing_trch);
01740 } else
01741 {
01742 set_thing_owner(thing_trch,get_tile_owner(lvl,tx,ty));
01743 if (allow_torch<3)
01744 set_thing_subtile(thing_trch,sx,sy);
01745
01746 unsigned short sensitile=compute_torch_sensitile(lvl,thing_trch);
01747 set_thing_sensitile(thing_trch,sensitile);
01748 }
01749 }
01750 sx=tx*MAP_SUBNUM_X+2-corner_pos.x;
01751 sy=ty*MAP_SUBNUM_Y+2-corner_pos.y;
01752 }
01753
01754 void update_things_slb_dungheart_corner(struct LEVEL *lvl, const int tx, const int ty,
01755 const unsigned char *surr_slb,const unsigned char *surr_own,
01756 const struct UPOINT_2D corner_pos)
01757 {
01758 unsigned char flame_stype;
01759 switch (surr_own[IDIR_CENTR])
01760 {
01761 case PLAYER0:
01762 flame_stype=ITEM_SUBTYPE_HEARTFLMR;
01763 break;
01764 case PLAYER1:
01765 flame_stype=ITEM_SUBTYPE_HEARTFLMB;
01766 break;
01767 case PLAYER2:
01768 flame_stype=ITEM_SUBTYPE_HEARTFLMG;
01769 break;
01770 case PLAYER3:
01771 flame_stype=ITEM_SUBTYPE_HEARTFLMY;
01772 break;
01773 case PLAYER_GOOD:
01774 case PLAYER_UNSET:
01775 default:
01776 flame_stype=0;
01777 break;
01778 }
01779 if (flame_stype!=0)
01780 update_thing_slb_room_one_central_item(lvl,tx,ty,flame_stype,true);
01781 else
01782 delete_room_things(lvl,tx,ty,surr_slb,surr_own,corner_pos);
01783 }
01784
01785 void update_things_slb_dungheart_inside(struct LEVEL *lvl, const int tx, const int ty,
01786 const unsigned char *surr_slb,const unsigned char *surr_own,
01787 const struct UPOINT_2D corner_pos)
01788 {
01789 unsigned char own=surr_own[IDIR_CENTR];
01790 if (own>=PLAYERS_COUNT) own=PLAYER_UNSET;
01791 if (own==PLAYER_UNSET)
01792 {
01793 delete_room_things(lvl,tx,ty,surr_slb,surr_own,corner_pos);
01794 return;
01795 }
01796
01797 int hearts[PLAYERS_COUNT];
01798 int i;
01799 for (i=0; i < PLAYERS_COUNT; i++)
01800 hearts[i]=0;
01801 owned_things_count(hearts,lvl,THING_TYPE_ITEM,ITEM_SUBTYPE_DNHEART);
01802 update_thing_slb_room_one_central_item(lvl,tx,ty,ITEM_SUBTYPE_DNHEART,(hearts[own]==0));
01803 }
01804
01805 void update_things_slb_graveyard_corner(struct LEVEL *lvl, const int tx, const int ty,
01806 const unsigned char *surr_slb,const unsigned char *surr_own,
01807 const struct UPOINT_2D corner_pos)
01808 {
01809 int sx, sy, i;
01810 const unsigned char itm_stype_idx=ITEM_SUBTYPE_GRAVSTONE;
01811 const unsigned char eff_stype_idx=EFCTGEN_SUBTP_DRYICE;
01812 short allow_torch=0;
01813 if (slab_is_wall(surr_slb[(1)*3+(corner_pos.x)]))
01814 allow_torch|=1;
01815 if (slab_is_wall(surr_slb[(corner_pos.y)*3+(1)]))
01816 allow_torch|=2;
01817 unsigned char *thing_dst=NULL;
01818 unsigned char *thing_eff=NULL;
01819 unsigned char *thing_trch=NULL;
01820 for (sx=tx*MAP_SUBNUM_X; sx < (tx+1)*MAP_SUBNUM_X; sx++)
01821 for (sy=ty*MAP_SUBNUM_Y; sy < (ty+1)*MAP_SUBNUM_Y; sy++)
01822 {
01823 int last_thing=get_thing_subnums(lvl,sx,sy)-1;
01824 for (i=last_thing; i>=0; i--)
01825 {
01826 unsigned char *thing=get_thing(lvl,sx,sy,i);
01827 if (is_room_inventory(thing))
01828 {
01829 unsigned char type_idx=get_thing_type(thing);
01830 unsigned char stype_idx=get_thing_subtype(thing);
01831 if ((type_idx==THING_TYPE_ITEM)&&(stype_idx==itm_stype_idx)&&(thing_dst==NULL))
01832 thing_dst=thing;
01833 else
01834 if ((type_idx==THING_TYPE_EFFECTGEN)&&(stype_idx==eff_stype_idx)&&(thing_eff==NULL))
01835 thing_eff=thing;
01836 else
01837
01838 if ((type_idx==THING_TYPE_ITEM)&&(is_torch_stype(stype_idx))&&(allow_torch>0)&&(thing_trch==NULL))
01839 {
01840 thing_trch=thing;
01841 continue;
01842 } else
01843 {
01844 thing_del(lvl,sx, sy, i);
01845 }
01846 }
01847 }
01848 }
01849 sx=tx*MAP_SUBNUM_X+1;
01850 sy=ty*MAP_SUBNUM_Y+1;
01851 if (thing_dst==NULL)
01852 {
01853 thing_dst=create_item_adv(lvl,sx,sy,itm_stype_idx);
01854 thing_add(lvl,thing_dst);
01855 } else
01856 {
01857 set_thing_owner(thing_dst,get_tile_owner(lvl,tx,ty));
01858 }
01859 if (allow_torch>0)
01860 {
01861 if ((allow_torch&1)==1)
01862 {
01863 sx=tx*MAP_SUBNUM_X+corner_pos.x;
01864 sy=ty*MAP_SUBNUM_Y+1;
01865 } else
01866 {
01867 sx=tx*MAP_SUBNUM_X+1;
01868 sy=ty*MAP_SUBNUM_Y+corner_pos.y;
01869 }
01870 if (thing_trch==NULL)
01871 {
01872 thing_trch=create_item_adv(lvl,sx,sy,ITEM_SUBTYPE_TORCH);
01873 thing_add(lvl,thing_trch);
01874 } else
01875 {
01876 set_thing_owner(thing_trch,get_tile_owner(lvl,tx,ty));
01877 if (allow_torch<3)
01878 set_thing_subtile(thing_trch,sx,sy);
01879
01880 unsigned short sensitile=compute_torch_sensitile(lvl,thing_trch);
01881 set_thing_sensitile(thing_trch,sensitile);
01882 }
01883 }
01884 sx=tx*MAP_SUBNUM_X+2-corner_pos.x;
01885 sy=ty*MAP_SUBNUM_Y+2-corner_pos.y;
01886 if (thing_eff==NULL)
01887 {
01888 thing_eff=create_effectgen(lvl,sx,sy,eff_stype_idx);
01889 thing_add(lvl,thing_eff);
01890 } else
01891 {
01892
01893 set_thing_owner(thing_eff,get_tile_owner(lvl,tx,ty));
01894 }
01895 }
01896
01897 void update_things_slb_guardpost_floor(struct LEVEL *lvl, const int tx, const int ty,
01898 const unsigned char *surr_slb,const unsigned char *surr_own,
01899 const struct UPOINT_2D corner_pos)
01900 {
01901 unsigned char flag_stype;
01902 switch (surr_own[IDIR_CENTR])
01903 {
01904 case PLAYER0:
01905 flag_stype=ITEM_SUBTYPE_GURDFLAGR;
01906 break;
01907 case PLAYER1:
01908 flag_stype=ITEM_SUBTYPE_GURDFLAGB;
01909 break;
01910 case PLAYER2:
01911 flag_stype=ITEM_SUBTYPE_GURDFLAGG;
01912 break;
01913 case PLAYER3:
01914 flag_stype=ITEM_SUBTYPE_GURDFLAGY;
01915 break;
01916 case PLAYER_GOOD:
01917 case PLAYER_UNSET:
01918 default:
01919 flag_stype=ITEM_SUBTYPE_FLAGPOST;
01920 break;
01921 }
01922 unsigned char *thing=update_thing_slb_room_one_central_item(lvl,tx,ty,flag_stype,true);
01923 set_thing_subtile_h(thing,2);
01924 }
01925
01926 void update_things_slb_prison(struct LEVEL *lvl, const int tx, const int ty,
01927 const unsigned char *surr_slb,const unsigned char *surr_own,
01928 const struct UPOINT_2D corner_pos)
01929 {
01930 unsigned short slab=surr_slb[IDIR_CENTR];
01931 unsigned char ownr=surr_own[IDIR_CENTR];
01932 unsigned char pris_bars[9];
01933 int i;
01934 for (i=0;i<9;i++)
01935 pris_bars[i]=false;
01936
01937 if (((surr_slb[IDIR_NORTH]!=slab)||(surr_own[IDIR_NORTH]!=ownr)) &&
01938 !slab_is_tall(surr_slb[IDIR_NORTH]))
01939 pris_bars[IDIR_NORTH]=true;
01940 if (((surr_slb[IDIR_EAST]!=slab)||(surr_own[IDIR_EAST]!=ownr)) &&
01941 !slab_is_tall(surr_slb[IDIR_EAST]))
01942 pris_bars[IDIR_EAST]=true;
01943 if (((surr_slb[IDIR_SOUTH]!=slab)||(surr_own[IDIR_SOUTH]!=ownr)) &&
01944 !slab_is_tall(surr_slb[IDIR_SOUTH]))
01945 pris_bars[IDIR_SOUTH]=true;
01946 if (((surr_slb[IDIR_WEST]!=slab)||(surr_own[IDIR_WEST]!=ownr)) &&
01947 !slab_is_tall(surr_slb[IDIR_WEST]))
01948 pris_bars[IDIR_WEST]=true;
01949
01950 if ((pris_bars[IDIR_NORTH]==true)||(pris_bars[IDIR_EAST]==true))
01951 pris_bars[IDIR_NE]=true;
01952 if ((pris_bars[IDIR_NORTH]==true)||(pris_bars[IDIR_WEST]==true))
01953 pris_bars[IDIR_NW]=true;
01954 if ((pris_bars[IDIR_SOUTH]==true)||(pris_bars[IDIR_WEST]==true))
01955 pris_bars[IDIR_SW]=true;
01956 if ((pris_bars[IDIR_SOUTH]==true)||(pris_bars[IDIR_EAST]==true))
01957 pris_bars[IDIR_SE]=true;
01958
01959 for (i=0;i<9;i++)
01960 {
01961 int sx=tx*3+idir_subtl_x[i];
01962 int sy=ty*3+idir_subtl_y[i];
01963 if (pris_bars[i])
01964 {
01965
01966 update_thing_slb_room_one_item_subtl(lvl,sx,sy,ITEM_SUBTYPE_PRISONBAR,true);
01967 } else
01968 {
01969
01970 delete_room_things_subtl(lvl,sx,sy);
01971 }
01972 }
01973 }
01974
01975
01976
01977
01978
01979 void update_obj_subpos_and_height_for_whole_map(struct LEVEL *lvl)
01980 {
01981 int i,k;
01982 for (k=0;k<lvl->tlsize.y;k++)
01983 for (i=0;i<lvl->tlsize.x;i++)
01984 update_things_subpos_and_height_for_slab(lvl, i, k);
01985 }
01986
01987
01988
01989
01990
01991 void update_obj_subpos_and_height_for_square_radius1(struct LEVEL *lvl, int tx, int ty)
01992 {
01993 int i,k;
01994 for (k=ty-1;k<=ty+1;k++)
01995 for (i=tx-1;i<=tx+1;i++)
01996 {
01997 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
01998 update_things_subpos_and_height_for_slab(lvl, i, k);
01999 }
02000 }
02001
02002
02003
02004
02005
02006 void update_obj_subpos_and_height_for_square(struct LEVEL *lvl, int tx_first, int tx_last,
02007 int ty_first, int ty_last)
02008 {
02009 int i,k;
02010 for (k=ty_first;k<=ty_last;k++)
02011 for (i=tx_first;i<=tx_last;i++)
02012 {
02013 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
02014 update_things_subpos_and_height_for_slab(lvl, i, k);
02015 }
02016 }
02017
02018
02019
02020
02021
02022 short update_things_subpos_and_height_for_slab(struct LEVEL *lvl, int tx, int ty)
02023 {
02024 int sx, sy, i;
02025 short result=true;
02026 unsigned short clm_height[9];
02027 for (sx=tx*3; sx < tx*3+3; sx++)
02028 for (sy=ty*3; sy < ty*3+3; sy++)
02029 {
02030
02031 for (i=0;i<9;i++)
02032 {
02033 int cur_sx,cur_sy;
02034 cur_sx=sx+idir_subtl_x[i]-1;
02035 cur_sy=sy+idir_subtl_y[i]-1;
02036 unsigned char *clmentry;
02037 clmentry=get_subtile_column(lvl,cur_sx,cur_sy);
02038 clm_height[i]=get_clm_entry_height(clmentry);
02039 }
02040 int last_thing=get_thing_subnums(lvl,sx,sy)-1;
02041 for (i=last_thing; i>=0; i--)
02042 {
02043 char *thing=get_thing(lvl,sx,sy,i);
02044 result&=update_thing_subpos_and_height(clm_height,thing);
02045 }
02046 }
02047 return result;
02048 }
02049
02050
02051
02052
02053
02054 short update_thing_subpos_and_height(unsigned short *clm_height,unsigned char *thing)
02055 {
02056 if (thing==NULL) return false;
02057 unsigned char stype_idx=get_thing_subtype(thing);
02058 int sx, sy, i;
02059 sx=get_thing_subtile_x(thing);
02060 sy=get_thing_subtile_y(thing);
02061
02062 if (is_door(thing))
02063 {
02064 unsigned char sub_x=0x080;
02065 unsigned char sub_y=0x080;
02066 unsigned char subtl_h=clm_height[IDIR_CENTR];
02067 unsigned char subpos_h=0;
02068 if (subtl_h<4) { subtl_h=4; subpos_h=0; }
02069 if (subtl_h>7) { subtl_h=7; subpos_h=255; }
02070 set_thing_subtpos(thing,sub_x,sub_y);
02071 set_thing_subtile_h(thing,subtl_h);
02072 set_thing_subtpos_h(thing,subpos_h);
02073 } else
02074 if (is_doorkey(thing))
02075 {
02076 unsigned char sub_x=0x080;
02077 unsigned char sub_y=0x080;
02078 unsigned char subtl_h=clm_height[IDIR_CENTR]-1;
02079 unsigned char subpos_h=0;
02080 if (subtl_h<1) { subtl_h=1; subpos_h=0; }
02081 if (subtl_h>7) { subtl_h=7; subpos_h=255; }
02082 set_thing_subtpos(thing,sub_x,sub_y);
02083 set_thing_subtile_h(thing,subtl_h);
02084 set_thing_subtpos_h(thing,subpos_h);
02085 } else
02086 if (is_heartflame(thing))
02087 {
02088 unsigned char sub_x=0x080;
02089 unsigned char sub_y=0x080;
02090 unsigned char subtl_h=clm_height[IDIR_CENTR];
02091 unsigned char subpos_h=0;
02092 if (subtl_h<1) { subtl_h=1; subpos_h=0; }
02093 if (subtl_h>7) { subtl_h=7; subpos_h=255; }
02094 set_thing_subtpos(thing,sub_x,sub_y);
02095 set_thing_subtile_h(thing,subtl_h);
02096 set_thing_subtpos_h(thing,subpos_h);
02097 } else
02098 if (is_torch(thing))
02099 {
02100 const unsigned short dir_a[]={IDIR_WEST, IDIR_NORTH, IDIR_EAST, IDIR_SOUTH,
02101 IDIR_NW, IDIR_NE, IDIR_SE, IDIR_SW};
02102 const unsigned short dir_a_subx[]={0x040, 0x080, 0x0c0, 0x080,
02103 0x040, 0x0c0, 0x0c0, 0x040};
02104 const unsigned short dir_a_suby[]={0x080, 0x040, 0x080, 0x0c0,
02105 0x040, 0x040, 0x0c0, 0x0c0};
02106 unsigned char sub_x=0x080;
02107 unsigned char sub_y=0x080;
02108 unsigned char subtl_h=clm_height[IDIR_CENTR]+1;
02109 unsigned char subpos_h=224;
02110
02111 for (i=0;i<8;i++)
02112 if (clm_height[dir_a[i]]>subtl_h)
02113 {
02114 sub_x=dir_a_subx[i];
02115 sub_y=dir_a_suby[i];
02116
02117 break;
02118 }
02119
02120 if (((sx%MAP_SUBNUM_X)==1)&&((sy%MAP_SUBNUM_Y)==1))
02121 {
02122 subtl_h=clm_height[IDIR_CENTR]+2;
02123 subpos_h=0;
02124 }
02125 if (subtl_h<2) { subtl_h=2; subpos_h=0; }
02126 if (subtl_h>7) { subtl_h=7; subpos_h=255; }
02127 set_thing_subtpos(thing,sub_x,sub_y);
02128 set_thing_subtile_h(thing,subtl_h);
02129 set_thing_subtpos_h(thing,subpos_h);
02130 }
02131 return true;
02132 }
02133
02134
02135
02136
02137
02138 void remove_noncrucial_room_things(struct LEVEL *lvl,int tx, int ty)
02139 {
02140 int sx, sy, i;
02141 for (sx=tx*3; sx < tx*3+3; sx++)
02142 for (sy=ty*3; sy < ty*3+3; sy++)
02143 {
02144 int last_thing=get_thing_subnums(lvl,sx,sy)-1;
02145 for (i=last_thing; i>=0; i--)
02146 {
02147 char *thing=get_thing(lvl,sx,sy,i);
02148 if (is_room_inventory(thing) && (!is_dncrucial(thing)))
02149 thing_del(lvl,sx, sy, i);
02150 }
02151 }
02152 }
02153
02154
02155
02156
02157
02158 short subtl_in_effectgen_range(struct LEVEL *lvl,unsigned int sx,unsigned int sy)
02159 {
02160 const int arr_entries_x=lvl->tlsize.x*MAP_SUBNUM_X;
02161 const int arr_entries_y=lvl->tlsize.y*MAP_SUBNUM_Y;
02162 int curr_sx, curr_sy, i;
02163 for (curr_sx=0; curr_sx < arr_entries_x; curr_sx++)
02164 for (curr_sy=0; curr_sy < arr_entries_y; curr_sy++)
02165 {
02166 int last_thing=get_thing_subnums(lvl,curr_sx,curr_sy)-1;
02167 for (i=last_thing; i>=0; i--)
02168 {
02169 char *thing=get_thing(lvl,curr_sx,curr_sy,i);
02170 if (is_effectgen(thing))
02171 if (subtl_in_thing_range(thing,sx,sy))
02172 return true;
02173 }
02174 }
02175 return false;
02176 }
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191 long get_nearest_thing_idx(struct LEVEL *lvl,
02192 const unsigned int ssx,const unsigned int ssy,
02193 unsigned int *sx,unsigned int *sy,unsigned int *num)
02194 {
02195
02196 if (lvl==NULL) return -1;
02197 int range;
02198 unsigned int best_sx, best_sy;
02199 int best_num;
02200 unsigned long best_dist;
02201 best_sx=0;best_sy=0;best_num=-1;best_dist=ULONG_MAX;
02202 short found_previously=0;
02203 int range_limit=max(lvl->subsize.x,lvl->subsize.y);
02204
02205 for (range=0; range<range_limit; range++)
02206 {
02207 int test_sx,test_sy;
02208 int test_num;
02209 unsigned long test_dist;
02210
02211 int sx_llimit,sx_hlimit;
02212 int sy_llimit,sy_hlimit;
02213 sx_llimit=(ssx>>8)-range;
02214 sx_hlimit=(ssx>>8)+range;
02215 sy_llimit=(ssy>>8)-range;
02216 sy_hlimit=(ssy>>8)+range;
02217 if (sx_llimit>=(int)lvl->subsize.x) sx_llimit=lvl->subsize.x-1;
02218 if (sx_llimit<0) sx_llimit=0;
02219 if (sx_hlimit>=(int)lvl->subsize.x) sx_hlimit=lvl->subsize.x-1;
02220 if (sx_hlimit<0) sx_hlimit=0;
02221 if (sy_llimit>=(int)lvl->subsize.y) sy_llimit=lvl->subsize.y-1;
02222 if (sy_llimit<0) sy_llimit=0;
02223 if (sy_hlimit>=(int)lvl->subsize.y) sy_hlimit=lvl->subsize.y-1;
02224 if (sy_hlimit<0) sy_hlimit=0;
02225
02226 if (best_num>=0) found_previously=1;
02227
02228 for (test_sy=sy_llimit;test_sy<=sy_hlimit;test_sy++)
02229 {
02230 int num_limit;
02231
02232 test_sx=sx_llimit;
02233
02234 num_limit=get_thing_subnums(lvl,test_sx,test_sy);
02235 for (test_num=0;test_num<=num_limit;test_num++)
02236 {
02237 unsigned char *thing=get_thing(lvl,test_sx,test_sy,test_num);
02238 test_dist=get_thing_distance_adv(thing,ssx,ssy);
02239 if (test_dist<best_dist)
02240 {
02241 best_sx=test_sx;
02242 best_sy=test_sy;
02243 best_num=test_num;
02244 best_dist=test_dist;
02245 }
02246 }
02247 test_sx=sx_hlimit;
02248
02249 num_limit=get_thing_subnums(lvl,test_sx,test_sy);
02250 for (test_num=0;test_num<=num_limit;test_num++)
02251 {
02252 unsigned char *thing=get_thing(lvl,test_sx,test_sy,test_num);
02253 test_dist=get_thing_distance_adv(thing,ssx,ssy);
02254 if (test_dist<best_dist)
02255 {
02256 best_sx=test_sx;
02257 best_sy=test_sy;
02258 best_num=test_num;
02259 best_dist=test_dist;
02260 }
02261 }
02262 }
02263 for (test_sx=sx_llimit+1;test_sx<sx_hlimit;test_sx++)
02264 {
02265 int num_limit;
02266
02267 test_sy=sy_llimit;
02268
02269 num_limit=get_thing_subnums(lvl,test_sx,test_sy);
02270 for (test_num=0;test_num<=num_limit;test_num++)
02271 {
02272 unsigned char *thing=get_thing(lvl,test_sx,test_sy,test_num);
02273 test_dist=get_thing_distance_adv(thing,ssx,ssy);
02274 if (test_dist<best_dist)
02275 {
02276 best_sx=test_sx;
02277 best_sy=test_sy;
02278 best_num=test_num;
02279 best_dist=test_dist;
02280 }
02281 }
02282 test_sy=sy_hlimit;
02283
02284 num_limit=get_thing_subnums(lvl,test_sx,test_sy);
02285 for (test_num=0;test_num<=num_limit;test_num++)
02286 {
02287 unsigned char *thing=get_thing(lvl,test_sx,test_sy,test_num);
02288 test_dist=get_thing_distance_adv(thing,ssx,ssy);
02289 if (test_dist<best_dist)
02290 {
02291 best_sx=test_sx;
02292 best_sy=test_sy;
02293 best_num=test_num;
02294 best_dist=test_dist;
02295 }
02296 }
02297 }
02298
02299 if (found_previously) break;
02300 }
02301 if (best_num<0)
02302 {
02303
02304 return -1;
02305 }
02306
02307 *sx=best_sx;
02308 *sy=best_sy;
02309 *num=best_num;
02310 return best_dist;
02311 }
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326 long get_nearest_object_idx(struct LEVEL *lvl,
02327 const unsigned int ssx,const unsigned int ssy,
02328 unsigned int *sx,unsigned int *sy,unsigned int *z)
02329 {
02330
02331 if (lvl==NULL) return -1;
02332 int range;
02333 unsigned int best_sx, best_sy;
02334 int best_z;
02335 unsigned long best_dist;
02336 best_sx=0;best_sy=0;best_z=-1;best_dist=ULONG_MAX;
02337 short found_previously=0;
02338 int range_limit=max(lvl->subsize.x,lvl->subsize.y);
02339
02340 for (range=0; range<range_limit; range++)
02341 {
02342 int test_sx,test_sy;
02343 int test_z;
02344 unsigned long test_dist;
02345
02346 int sx_llimit,sx_hlimit;
02347 int sy_llimit,sy_hlimit;
02348 sx_llimit=(ssx>>8)-range;
02349 sx_hlimit=(ssx>>8)+range;
02350 sy_llimit=(ssy>>8)-range;
02351 sy_hlimit=(ssy>>8)+range;
02352 if (sx_llimit>=(int)lvl->subsize.x) sx_llimit=lvl->subsize.x-1;
02353 if (sx_llimit<0) sx_llimit=0;
02354 if (sx_hlimit>=(int)lvl->subsize.x) sx_hlimit=lvl->subsize.x-1;
02355 if (sx_hlimit<0) sx_hlimit=0;
02356 if (sy_llimit>=(int)lvl->subsize.y) sy_llimit=lvl->subsize.y-1;
02357 if (sy_llimit<0) sy_llimit=0;
02358 if (sy_hlimit>=(int)lvl->subsize.y) sy_hlimit=lvl->subsize.y-1;
02359 if (sy_hlimit<0) sy_hlimit=0;
02360
02361 if (best_z>=0) found_previously=1;
02362
02363 for (test_sy=sy_llimit;test_sy<=sy_hlimit;test_sy++)
02364 {
02365 int num_limit;
02366
02367 test_sx=sx_llimit;
02368
02369 num_limit=get_object_subnums(lvl,test_sx,test_sy);
02370 for (test_z=0;test_z<=num_limit;test_z++)
02371 {
02372 unsigned char *obj;
02373 obj=get_object(lvl,test_sx,test_sy,test_z);
02374 switch (get_object_type(lvl,test_sx,test_sy,test_z))
02375 {
02376 case OBJECT_TYPE_THING:
02377 test_dist=get_thing_distance_adv(obj,ssx,ssy);
02378 break;
02379 case OBJECT_TYPE_ACTNPT:
02380 test_dist=get_actnpt_distance_adv(obj,ssx,ssy);
02381 break;
02382 case OBJECT_TYPE_STLIGHT:
02383 test_dist=get_stlight_distance_adv(obj,ssx,ssy);
02384 break;
02385 default:
02386 test_dist=ULONG_MAX;
02387 break;
02388 }
02389 if (test_dist<best_dist)
02390 {
02391 best_sx=test_sx;
02392 best_sy=test_sy;
02393 best_z=test_z;
02394 best_dist=test_dist;
02395 }
02396 }
02397 test_sx=sx_hlimit;
02398
02399 num_limit=get_object_subnums(lvl,test_sx,test_sy);
02400 for (test_z=0;test_z<=num_limit;test_z++)
02401 {
02402 unsigned char *obj;
02403 obj=get_object(lvl,test_sx,test_sy,test_z);
02404 switch (get_object_type(lvl,test_sx,test_sy,test_z))
02405 {
02406 case OBJECT_TYPE_THING:
02407 test_dist=get_thing_distance_adv(obj,ssx,ssy);
02408 break;
02409 case OBJECT_TYPE_ACTNPT:
02410 test_dist=get_actnpt_distance_adv(obj,ssx,ssy);
02411 break;
02412 case OBJECT_TYPE_STLIGHT:
02413 test_dist=get_stlight_distance_adv(obj,ssx,ssy);
02414 break;
02415 default:
02416 test_dist=ULONG_MAX;
02417 break;
02418 }
02419 if (test_dist<best_dist)
02420 {
02421 best_sx=test_sx;
02422 best_sy=test_sy;
02423 best_z=test_z;
02424 best_dist=test_dist;
02425 }
02426 }
02427 }
02428 for (test_sx=sx_llimit+1;test_sx<sx_hlimit;test_sx++)
02429 {
02430 int num_limit;
02431
02432 test_sy=sy_llimit;
02433
02434 num_limit=get_object_subnums(lvl,test_sx,test_sy);
02435 for (test_z=0;test_z<=num_limit;test_z++)
02436 {
02437 unsigned char *obj;
02438 obj=get_object(lvl,test_sx,test_sy,test_z);
02439 switch (get_object_type(lvl,test_sx,test_sy,test_z))
02440 {
02441 case OBJECT_TYPE_THING:
02442 test_dist=get_thing_distance_adv(obj,ssx,ssy);
02443 break;
02444 case OBJECT_TYPE_ACTNPT:
02445 test_dist=get_actnpt_distance_adv(obj,ssx,ssy);
02446 break;
02447 case OBJECT_TYPE_STLIGHT:
02448 test_dist=get_stlight_distance_adv(obj,ssx,ssy);
02449 break;
02450 default:
02451 test_dist=ULONG_MAX;
02452 break;
02453 }
02454 if (test_dist<best_dist)
02455 {
02456 best_sx=test_sx;
02457 best_sy=test_sy;
02458 best_z=test_z;
02459 best_dist=test_dist;
02460 }
02461 }
02462 test_sy=sy_hlimit;
02463
02464 num_limit=get_object_subnums(lvl,test_sx,test_sy);
02465 for (test_z=0;test_z<=num_limit;test_z++)
02466 {
02467 unsigned char *obj;
02468 obj=get_object(lvl,test_sx,test_sy,test_z);
02469 switch (get_object_type(lvl,test_sx,test_sy,test_z))
02470 {
02471 case OBJECT_TYPE_THING:
02472 test_dist=get_thing_distance_adv(obj,ssx,ssy);
02473 break;
02474 case OBJECT_TYPE_ACTNPT:
02475 test_dist=get_actnpt_distance_adv(obj,ssx,ssy);
02476 break;
02477 case OBJECT_TYPE_STLIGHT:
02478 test_dist=get_stlight_distance_adv(obj,ssx,ssy);
02479 break;
02480 default:
02481 test_dist=ULONG_MAX;
02482 break;
02483 }
02484 if (test_dist<best_dist)
02485 {
02486 best_sx=test_sx;
02487 best_sy=test_sy;
02488 best_z=test_z;
02489 best_dist=test_dist;
02490 }
02491 }
02492 }
02493
02494 if (found_previously) break;
02495 }
02496 if (best_z<0)
02497 {
02498
02499 return -1;
02500 }
02501
02502 *sx=best_sx;
02503 *sy=best_sy;
02504 *z=best_z;
02505 return best_dist;
02506 }