00001
00017
00018
00019 #include "lev_column.h"
00020
00021 #include "obj_column_def.h"
00022 #include "obj_column.h"
00023 #include "lev_data.h"
00024 #include "globals.h"
00025 #include "obj_slabs.h"
00026 #include "obj_things.h"
00027 #include "graffiti.h"
00028
00029 char const INF_STANDARD_LTEXT[]="Standard";
00030 char const INF_ANCIENT_LTEXT[]="Ancient";
00031 char const INF_WINTER_LTEXT[]="Winter";
00032 char const INF_SNAKE_LTEXT[]="Snake key";
00033 char const INF_FACE_LTEXT[]="Stone face";
00034 char const INF_BRESTS_LTEXT[]="Big breasts";
00035 char const INF_RGANCNT_LTEXT[]="Rough Ancient";
00036 char const INF_SKULL_LTEXT[]="Skull relief";
00037
00041 const char * const inf_texture_fullnames[]={
00042 INF_STANDARD_LTEXT,INF_ANCIENT_LTEXT,INF_WINTER_LTEXT,
00043 INF_SNAKE_LTEXT,INF_FACE_LTEXT,INF_BRESTS_LTEXT,
00044 INF_RGANCNT_LTEXT,INF_SKULL_LTEXT,
00045 };
00046
00055 void set_clm(struct LEVEL *lvl, int num, unsigned int use, int base,
00056 int c0, int c1, int c2, int c3, int c4, int c5, int c6, int c7)
00057 {
00058 unsigned char *clmentry;
00059 struct COLUMN_REC *clm_rec;
00060 clmentry = (unsigned char *)(lvl->clm[num]);
00061 clm_rec=create_column_rec();
00062 fill_column_rec_sim(clm_rec,use, base, c0, c1, c2, c3, c4, c5, c6, c7);
00063 set_clm_entry(clmentry, clm_rec);
00064 free_column_rec(clm_rec);
00065 }
00066
00080 void set_clm_ent_idx(struct LEVEL *lvl,int num, unsigned int use, int permanent,
00081 int lintel, int height, unsigned int solid, int base, int orientation,
00082 int c0, int c1, int c2, int c3, int c4, int c5, int c6, int c7)
00083 {
00084 unsigned char *clmentry;
00085 struct COLUMN_REC *clm_rec;
00086 clmentry = (unsigned char *)(lvl->clm[num]);
00087 clm_rec=create_column_rec();
00088 fill_column_rec(clm_rec,use, permanent, lintel, height, solid,
00089 base, orientation, c0, c1, c2, c3, c4, c5, c6, c7);
00090 set_clm_entry(clmentry, clm_rec);
00091 free_column_rec(clm_rec);
00092 }
00093
00104 int column_find_or_create(struct LEVEL *lvl,struct COLUMN_REC *clm_rec)
00105 {
00106 if (clm_rec==NULL) return 0;
00107 int num=-1;
00108 unsigned char *clmentry;
00109
00110 struct COLUMN_REC *clm_rec2;
00111 clm_rec2=create_column_rec();
00112 for (num=0;num<COLUMN_ENTRIES;num++)
00113 {
00114 if (clm_entry_is_used(lvl,num))
00115 {
00116 clmentry = (unsigned char *)(lvl->clm[num]);
00117 get_clm_entry(clm_rec2, clmentry);
00118 if (compare_column_recs(clm_rec,clm_rec2))
00119 break;
00120 }
00121 }
00122 free_column_rec(clm_rec2);
00123
00124 if ((num<0)||(num>=COLUMN_ENTRIES))
00125 {
00126 num=column_get_free_index(lvl);
00127 if ((num>=0)&&(num<COLUMN_ENTRIES))
00128 {
00129 clmentry = (unsigned char *)(lvl->clm[num]);
00130 set_clm_entry(clmentry, clm_rec);
00131 }
00132 }
00133
00134
00135 if ((num<0)||(num>=COLUMN_ENTRIES))
00136 return 0;
00137
00138 clmentry = (unsigned char *)(lvl->clm[num]);
00139
00140 if (clm_rec->permanent) set_clm_entry_permanent(clmentry,1);
00141
00142 return num;
00143 }
00144
00151 int column_get_free_index(struct LEVEL *lvl)
00152 {
00153 int num;
00154 unsigned char *clmentry;
00155
00156
00157 for (num=1;num<COLUMN_ENTRIES;num++)
00158 {
00159 if (!clm_entry_is_used(lvl,num))
00160 return num;
00161 }
00162 return -1;
00163 }
00164
00171 void update_datclm_for_whole_map(struct LEVEL *lvl)
00172 {
00173
00174
00175 level_clear_datclm(lvl);
00176 add_permanent_columns(lvl);
00177
00178
00179 int i,k;
00180 for (k=0;k<lvl->tlsize.y;k++)
00181 for (i=0;i<lvl->tlsize.x;i++)
00182 update_datclm_for_slab(lvl, i, k);
00183
00184
00185 update_dat_last_column(lvl,SLAB_TYPE_ROCK);
00186
00187
00188 for (k=0;k<lvl->tlsize.y;k++)
00189 for (i=0;i<lvl->tlsize.x;i++)
00190 update_tile_wib_entries(lvl,i,k);
00191
00192
00193 for (k=0;k<lvl->tlsize.y;k++)
00194 for (i=0;i<lvl->tlsize.x;i++)
00195 {
00196 update_tile_wlb_entry(lvl,i,k);
00197 update_tile_flg_entries(lvl,i,k);
00198 }
00199
00200 update_clm_utilize_counters(lvl);
00201 }
00202
00211 void update_datclm_for_square_radius1(struct LEVEL *lvl, int tx, int ty)
00212 {
00213 int i,k;
00214 for (k=ty-1;k<=ty+1;k++)
00215 for (i=tx-1;i<=tx+1;i++)
00216 {
00217 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
00218 update_datclm_for_slab(lvl, i, k);
00219 }
00220
00221 for (k=ty-2;k<=ty+2;k++)
00222 for (i=tx-2;i<=tx+2;i++)
00223 {
00224 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
00225 update_tile_wib_entries(lvl,i,k);
00226 }
00227
00228 for (k=ty-2;k<=ty+2;k++)
00229 for (i=tx-2;i<=tx+2;i++)
00230 {
00231 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
00232 {
00233 update_tile_wlb_entry(lvl,i,k);
00234 update_tile_flg_entries(lvl,i,k);
00235 }
00236 }
00237 }
00238
00247 void update_datclm_for_square(struct LEVEL *lvl, int tx_first, int tx_last,
00248 int ty_first, int ty_last)
00249 {
00250 int i,k;
00251 for (k=ty_first;k<=ty_last;k++)
00252 for (i=tx_first;i<=tx_last;i++)
00253 {
00254 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
00255 update_datclm_for_slab(lvl, i, k);
00256 }
00257
00258 for (k=ty_first-1;k<=ty_last+1;k++)
00259 for (i=tx_first-1;i<=tx_last+1;i++)
00260 {
00261 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
00262 update_tile_wib_entries(lvl,i,k);
00263 }
00264
00265 for (k=ty_first-1;k<=ty_last+1;k++)
00266 for (i=tx_first-1;i<=tx_last+1;i++)
00267 {
00268 if ((i>=0) && (k>=0) && (i<lvl->tlsize.x) && (k<lvl->tlsize.y))
00269 {
00270 update_tile_wlb_entry(lvl,i,k);
00271 update_tile_flg_entries(lvl,i,k);
00272 }
00273 }
00274 }
00275
00283 void update_datclm_for_slab(struct LEVEL *lvl, int tx, int ty)
00284 {
00285
00286 unsigned char *surr_slb=(unsigned char *)malloc(9*sizeof(unsigned char));
00287 unsigned char *surr_own=(unsigned char *)malloc(9*sizeof(unsigned char));
00288 unsigned char **surr_tng=(unsigned char **)malloc(9*sizeof(unsigned char *));
00289 get_slab_surround(surr_slb,surr_own,surr_tng,lvl,tx,ty);
00290 int i;
00291
00292 message_log(" update_datclm_for_slab: Refreshing slab %d tile at %d,%d",(int)surr_slb[IDIR_CENTR],tx,ty);
00293 struct COLUMN_REC *clm_recs[9];
00294 for (i=0;i<9;i++)
00295 clm_recs[i]=create_column_rec();
00296 create_columns_for_slab(clm_recs,&(lvl->optns),surr_slb,surr_own,surr_tng);
00297
00298 if (slab_has_custom_columns(lvl, tx, ty))
00299 update_custom_columns_for_slab(clm_recs,lvl,tx,ty);
00300
00301 set_new_datclm_values(lvl, tx, ty, clm_recs);
00302
00303 for (i=0;i<9;i++)
00304 free_column_rec(clm_recs[i]);
00305 free(surr_slb);
00306 free(surr_own);
00307 free(surr_tng);
00308 }
00309
00319 void get_slab_surround(unsigned char *surr_slb,unsigned char *surr_own,
00320 unsigned char **surr_tng,const struct LEVEL *lvl,int tx, int ty)
00321 {
00322
00323
00324
00325 int arr_entries_x=lvl->tlsize.x*MAP_SUBNUM_X;
00326 int arr_entries_y=lvl->tlsize.y*MAP_SUBNUM_Y;
00327
00328 int i,k;
00329 int s_idx;
00330
00331 if (surr_tng!=NULL)
00332 {
00333 for (i=0;i<3;i++)
00334 for (k=0;k<3;k++)
00335 surr_tng[k*3+i]=NULL;
00336 }
00337
00338 for (i=-1;i<=1;i++)
00339 for (k=-1;k<=1;k++)
00340 {
00341 s_idx=i+1+(k+1)*3;
00342 if ((tx+i<0)||(ty+k<0)||(tx+i>lvl->tlsize.x)||(ty+k>lvl->tlsize.y))
00343 {
00344 if (surr_slb!=NULL)
00345 surr_slb[s_idx]=SLAB_TYPE_ROCK;
00346 if (surr_own!=NULL)
00347 surr_own[s_idx]=PLAYER_UNSET;
00348 }
00349 else
00350 {
00351 if (surr_slb!=NULL)
00352 surr_slb[s_idx]=get_tile_slab(lvl,tx+i,ty+k);
00353 if (surr_own!=NULL)
00354 {
00355 surr_own[s_idx]=get_tile_owner(lvl,tx+i,ty+k);
00356 if (surr_own[s_idx]>PLAYER_UNSET)
00357 surr_own[s_idx]=PLAYER_UNSET;
00358 }
00359 }
00360 }
00361
00362 if (surr_tng!=NULL)
00363 {
00364 for (i=-2;i<=2;i++)
00365 for (k=-2;k<=2;k++)
00366 {
00367
00368 if (((i==-2)||(i==2))&&((k==-2)||(k==2))) continue;
00369
00370 s_idx=0;
00371 if (i>1) { s_idx+=2; }
00372 else if (i>-1) s_idx+=i+1;
00373 if (k>1) s_idx+=2*3;
00374 else if (k>-1) s_idx+=(k+1)*3;
00375
00376 int sx=tx*MAP_SUBNUM_X+i+1;
00377 int sy=ty*MAP_SUBNUM_Y+k+1;
00378 int tng_num;
00379 if ((sx<0)||(sy<0)||(sx>=arr_entries_x)||(sy>=arr_entries_y))
00380 continue;
00381 tng_num=get_thing_subnums(lvl,sx,sy);
00382 while (tng_num>0)
00383 {
00384 tng_num--;
00385 unsigned char *thing=get_thing(lvl,sx,sy,tng_num);
00386 if (is_clmaffective_thing(thing))
00387 surr_tng[s_idx]=thing;
00388 }
00389 }
00390 }
00391 }
00392
00403 void set_new_datclm_values(struct LEVEL *lvl, int tx, int ty, struct COLUMN_REC *clm_recs[9])
00404 {
00405 int i;
00406 for (i=0;i<9;i++)
00407 {
00408 int sx=tx*MAP_SUBNUM_X+idir_subtl_x[i];
00409 int sy=ty*MAP_SUBNUM_Y+idir_subtl_y[i];
00410 set_new_datclm_entry(lvl,sx,sy,clm_recs[i]);
00411 }
00412 }
00413
00424 void set_new_datclm_entry(struct LEVEL *lvl, int sx, int sy, struct COLUMN_REC *clm_rec)
00425 {
00426 unsigned int clmidx;
00427
00428 clmidx=get_dat_subtile(lvl, sx, sy);
00429 clm_utilize_dec(lvl,clmidx);
00430
00431
00432 int dat_entry;
00433 dat_entry=column_find_or_create(lvl,clm_rec);
00434 clm_utilize_inc(lvl,dat_entry);
00435
00436 set_dat_subtile(lvl,sx,sy,dat_entry);
00437 }
00438
00446 void clm_utilize_dec(struct LEVEL *lvl, int clmidx)
00447 {
00448 if ((clmidx<0)||(clmidx>=COLUMN_ENTRIES))
00449 return;
00450 lvl->clm_utilize[clmidx]--;
00451 unsigned char *clmentry;
00452 clmentry=lvl->clm[clmidx];
00453 if (clmentry!=NULL)
00454 clm_entry_use_dec(clmentry);
00455
00456 if ((lvl->clm_utilize[clmidx]<1)&&(get_clm_entry_permanent(clmentry)==0))
00457 {
00458 lvl->clm_utilize[clmidx]=0;
00459 clear_clm_entry(clmentry);
00460 }
00461 }
00462
00470 void clm_utilize_inc(struct LEVEL *lvl, int clmidx)
00471 {
00472 if ((clmidx<0)||(clmidx>=COLUMN_ENTRIES))
00473 return;
00474 lvl->clm_utilize[clmidx]++;
00475 unsigned char *clmentry;
00476 clmentry=lvl->clm[clmidx];
00477 if (clmentry!=NULL)
00478 clm_entry_use_inc(clmentry);
00479 }
00480
00490 short columns_verify(struct LEVEL *lvl, char *err_msg,struct IPOINT_2D *errpt)
00491 {
00492
00493 short result;
00494 int i,k;
00495 for (i=0; i<COLUMN_ENTRIES; i++)
00496 {
00497 result=clm_verify_entry(lvl->clm[i],err_msg);
00498 if (result!=VERIF_OK)
00499 {
00500 sprintf(err_msg,"%s in column %d.",err_msg,i);
00501 int sx,sy;
00502 sx=-1;sy=-1;
00503 if (find_dat_entry(lvl,&sx,&sy,i))
00504 {
00505 errpt->x=sx/MAP_SUBNUM_X;
00506 errpt->y=sy/MAP_SUBNUM_Y;
00507 } else
00508 {
00509 errpt->x=-1;errpt->y=-1;
00510 }
00511 return result;
00512 }
00513 }
00514 return VERIF_OK;
00515 }
00516
00524 void update_clm_utilize_counters(struct LEVEL *lvl)
00525 {
00526 int clmidx;
00527
00528 for (clmidx=0; clmidx<COLUMN_ENTRIES; clmidx++)
00529 {
00530 lvl->clm_utilize[clmidx]=0;
00531 }
00532
00533 int cx,cy;
00534 for (cy=0; cy < lvl->subsize.y; cy++)
00535 for (cx=0; cx < lvl->subsize.x; cx++)
00536 {
00537 clmidx=get_dat_subtile(lvl, cx, cy);
00538 if ((clmidx>=0)&&(clmidx<COLUMN_ENTRIES))
00539 lvl->clm_utilize[clmidx]++;
00540 }
00541 }
00542
00548 void update_tile_wib_entries(struct LEVEL *lvl, int tx, int ty)
00549 {
00550 int i,k;
00551 struct COLUMN_REC *clm_rec;
00552 struct COLUMN_REC *clm_rec_n;
00553 struct COLUMN_REC *clm_rec_w;
00554 struct COLUMN_REC *clm_rec_nw;
00555 clm_rec=create_column_rec();
00556 clm_rec_n=create_column_rec();
00557 clm_rec_w=create_column_rec();
00558 clm_rec_nw=create_column_rec();
00559 for (k=0;k<MAP_SUBNUM_Y;k++)
00560 for (i=0;i<MAP_SUBNUM_X;i++)
00561 {
00562 int sx=tx*MAP_SUBNUM_X+i;
00563 int sy=ty*MAP_SUBNUM_Y+k;
00564 short wib_entry;
00565 if (get_cust_col(lvl,sx,sy)!=NULL)
00566 {
00567 wib_entry=get_cust_col_wib_entry(lvl,sx,sy);
00568 } else
00569 {
00570 get_subtile_column_rec(lvl, clm_rec_nw, sx-1, sy-1);
00571 get_subtile_column_rec(lvl, clm_rec_n, sx, sy-1);
00572 get_subtile_column_rec(lvl, clm_rec_w, sx-1, sy);
00573 get_subtile_column_rec(lvl, clm_rec, sx , sy);
00574 wib_entry=column_wib_entry(clm_rec,clm_rec_n,clm_rec_w,clm_rec_nw);
00575 }
00576 set_subtl_wib(lvl, tx*MAP_SUBNUM_X+i, ty*MAP_SUBNUM_Y+k, wib_entry);
00577 }
00578 free_column_rec(clm_rec);
00579 free_column_rec(clm_rec_n);
00580 free_column_rec(clm_rec_w);
00581 free_column_rec(clm_rec_nw);
00582 }
00583
00589 void update_tile_wlb_entry(struct LEVEL *lvl, int tx, int ty)
00590 {
00591 unsigned short wlb_val;
00592 unsigned short slab;
00593 slab=get_tile_slab(lvl,tx,ty);
00594 switch (slab)
00595 {
00596 case SLAB_TYPE_LAVA:
00597 wlb_val=TILE_WLB_LAVA;
00598 break;
00599 case SLAB_TYPE_WATER:
00600 wlb_val=TILE_WLB_WATER;
00601 break;
00602 case SLAB_TYPE_BRIDGE:
00603 wlb_val=get_tile_wlb(lvl,tx,ty);
00604 if ((wlb_val!=TILE_WLB_LAVA)&&(wlb_val!=TILE_WLB_WATER))
00605 {
00606
00607 int sib_water=slab_siblings_oftype(lvl,tx,ty,SLAB_TYPE_WATER);
00608 int sib_lava=slab_siblings_oftype(lvl,tx,ty,SLAB_TYPE_LAVA);
00609 if (sib_lava>sib_water)
00610 wlb_val=TILE_WLB_LAVA;
00611 else
00612 wlb_val=TILE_WLB_WATER;
00613 }
00614 break;
00615 default:
00616 wlb_val=TILE_WLB_SOLID;
00617 break;
00618 }
00619 set_tile_wlb(lvl,tx,ty,wlb_val);
00620 }
00621
00627 void update_tile_flg_entries(struct LEVEL *lvl, int tx, int ty)
00628 {
00629 unsigned short slab;
00630 slab=get_tile_slab(lvl,tx,ty);
00631 unsigned char owner;
00632 owner=get_tile_owner(lvl,tx,ty);
00633 int i,k;
00634 for (k=0;k<MAP_SUBNUM_Y;k++)
00635 for (i=0;i<MAP_SUBNUM_X;i++)
00636 {
00637 int sx=tx*MAP_SUBNUM_X+i;
00638 int sy=ty*MAP_SUBNUM_Y+k;
00639
00640 short corner=true;
00641 int crnr_x;
00642 int crnr_y;
00643
00644 if ((k==0)&&(i==0))
00645 {
00646 crnr_x=1;crnr_y=1;
00647 } else
00648 if ((k==2)&&(i==0))
00649 {
00650 crnr_x=1;crnr_y=-1;
00651 } else
00652 if ((k==0)&&(i==2))
00653 {
00654 crnr_x=-1;crnr_y=1;
00655 } else
00656 if ((k==2)&&(i==2))
00657 {
00658 crnr_x=-1;crnr_y=-1;
00659 } else
00660 {
00661 crnr_x=0;crnr_y=0;
00662 }
00663 if (((slab==get_tile_slab(lvl,tx+crnr_x,ty))&&(owner==get_tile_owner(lvl,tx+crnr_x,ty))) ||
00664 ((slab==get_tile_slab(lvl,tx,ty+crnr_y))&&(owner==get_tile_owner(lvl,tx,ty+crnr_y))))
00665 corner=false;
00666 unsigned short flg_val;
00667 flg_val=compute_flg_for_tile(slab,corner);
00668 set_subtl_flg(lvl,sx,sy,flg_val);
00669 }
00670 }
00671
00678 unsigned short compute_flg_for_tile(unsigned short slab,short corner)
00679 {
00680 if (slab_is_wall(slab))
00681 return 0x0c0;
00682 if (slab_is_room(slab))
00683 {
00684 if (corner)
00685 return 0x054;
00686 else
00687 return 0x016;
00688 }
00689 if (slab_is_door(slab))
00690 {
00691 if (corner)
00692 return 0x002;
00693 else
00694 return 0x140;
00695 }
00696 if (slab_is_short(slab))
00697 return 0x002;
00698 if (slab_is_wealth(slab))
00699 return 0x041;
00700 switch (slab)
00701 {
00702 case SLAB_TYPE_EARTH:
00703 case SLAB_TYPE_TORCHDIRT:
00704 return 0x060;
00705 default:
00706 return 0x0d0;
00707 }
00708 }
00709
00716 unsigned char *get_subtile_column(const struct LEVEL *lvl, int sx, int sy)
00717 {
00718 if (lvl->clm==NULL)
00719 return NULL;
00720 unsigned int clmidx;
00721 clmidx=get_dat_subtile(lvl, sx, sy);
00722 if ((clmidx<0)||(clmidx>=COLUMN_ENTRIES))
00723 return NULL;
00724 return (unsigned char *)(lvl->clm[clmidx]);
00725 }
00726
00734 short get_subtile_column_rec(const struct LEVEL *lvl, struct COLUMN_REC *clm_rec, int sx, int sy)
00735 {
00736 unsigned char *clmentry;
00737 clmentry=get_subtile_column(lvl,sx,sy);
00738 if (clmentry==NULL)
00739 {
00740
00741 fill_column_rock(clm_rec, PLAYER_UNSET);
00742 return false;
00743 }
00744 get_clm_entry(clm_rec, clmentry);
00745 return true;
00746 }
00747
00754 unsigned short get_subtile_column_height(struct LEVEL *lvl, int sx, int sy)
00755 {
00756 unsigned char *clmentry;
00757 clmentry=get_subtile_column(lvl,sx,sy);
00758 if (clmentry==NULL)
00759 return 0;
00760 return get_clm_entry_height(clmentry);
00761 }
00762
00769 unsigned short get_subtile_column_solid(struct LEVEL *lvl, int sx, int sy)
00770 {
00771 unsigned char *clmentry;
00772 clmentry=get_subtile_column(lvl,sx,sy);
00773 if (clmentry==NULL)
00774 return 0;
00775 return get_clm_entry_solid(clmentry);
00776 }
00777
00785 void set_dat_subtile(struct LEVEL *lvl, int sx, int sy, int d)
00786 {
00787 unsigned int val;
00788 val = 0x10000-d;
00789 set_dat_val(lvl,sx,sy,val);
00790 }
00791
00798 unsigned int get_dat_subtile(const struct LEVEL *lvl, const unsigned int sx, const unsigned int sy)
00799 {
00800 unsigned int val;
00801 val=0x10000-get_dat_val(lvl,sx,sy);
00802
00803 return val&0x0ffff;
00804 }
00805
00815 void set_dat(struct LEVEL *lvl, int x, int y, int tl, int tm, int tr,
00816 int ml, int mm, int mr, int bl, int bm, int br)
00817 {
00818 set_dat_subtile(lvl, x*3, y*3, tl);
00819 set_dat_subtile(lvl, x*3+1, y*3, tm);
00820 set_dat_subtile(lvl, x*3+2, y*3, tr);
00821 set_dat_subtile(lvl, x*3, y*3+1, ml);
00822 set_dat_subtile(lvl, x*3+1, y*3+1, mm);
00823 set_dat_subtile(lvl, x*3+2, y*3+1, mr);
00824 set_dat_subtile(lvl, x*3, y*3+2, bl);
00825 set_dat_subtile(lvl, x*3+1, y*3+2, bm);
00826 set_dat_subtile(lvl, x*3+2, y*3+2, br);
00827 }
00828
00836 void set_dat_unif (struct LEVEL *lvl, int x, int y, int d)
00837 {
00838 set_dat (lvl, x, y, d, d, d, d, d, d, d, d, d);
00839 }
00840
00852 short find_dat_entry(const struct LEVEL *lvl, int *sx, int *sy, const unsigned int clm_idx)
00853 {
00854 if (((*sx)<0)||((*sy)<0))
00855 { (*sx)=-1; (*sy)=0; }
00856 do {
00857 (*sx)++;
00858 if ((*sx)>=lvl->subsize.x)
00859 { (*sx)=0; (*sy)++; }
00860 if ((*sy)>=lvl->subsize.x)
00861 {
00862 (*sx)=-1; (*sy)=-1;
00863 return false;
00864 }
00865 } while (get_dat_subtile(lvl,*sx,*sy) != clm_idx);
00866 return true;
00867 }
00868
00878 short dat_verify(struct LEVEL *lvl, char *err_msg,struct IPOINT_2D *errpt)
00879 {
00880
00881 int i, k;
00882 for (k=0; k<lvl->subsize.y; k++)
00883 for (i=0; i<lvl->subsize.x; i++)
00884 {
00885 int dat_idx=get_dat_subtile(lvl, i, k);
00886 if ((dat_idx<0)||(dat_idx>=COLUMN_ENTRIES))
00887 {
00888 errpt->x=i/MAP_SUBNUM_X;
00889 errpt->y=k/MAP_SUBNUM_Y;
00890 sprintf(err_msg,"DAT index out of bounds at slab %d,%d.",errpt->x,errpt->y);
00891 return VERIF_ERROR;
00892 }
00893 }
00894 return VERIF_OK;
00895 }
00896
00905 short clm_entry_is_used(const struct LEVEL *lvl,unsigned int clmidx)
00906 {
00907 unsigned char *clmentry;
00908 clmentry = (unsigned char *)(lvl->clm[clmidx]);
00909 if (clmentry==NULL) return false;
00910 unsigned int permanent=get_clm_entry_permanent(clmentry);
00911 return (lvl->clm_utilize[clmidx]>0)||(permanent);
00912 }
00913
00923 short update_dat_last_column(struct LEVEL *lvl, unsigned short slab)
00924 {
00925
00926 unsigned char *surr_slb=(unsigned char *)malloc(9*sizeof(unsigned char));
00927 unsigned char *surr_own=(unsigned char *)malloc(9*sizeof(unsigned char));
00928 unsigned char **surr_tng=(unsigned char **)malloc(9*sizeof(unsigned char *));
00929 get_slab_surround(surr_slb,surr_own,surr_tng,lvl,lvl->tlsize.x,lvl->tlsize.y);
00930 surr_slb[IDIR_CENTR]=slab;
00931 int i;
00932
00933 struct COLUMN_REC *clm_recs[9];
00934 for (i=0;i<9;i++)
00935 clm_recs[i]=create_column_rec();
00936 create_columns_for_slab(clm_recs,&(lvl->optns),surr_slb,surr_own,surr_tng);
00937
00938 int sx, sy;
00939 sx=lvl->subsize.x-1;
00940 for (sy=0; sy<lvl->subsize.y; sy++)
00941 set_new_datclm_entry(lvl,sx,sy,clm_recs[(sy%MAP_SUBNUM_Y)*MAP_SUBNUM_X]);
00942 sy=lvl->subsize.y-1;
00943 for (sx=0; sx<lvl->subsize.x; sx++)
00944 set_new_datclm_entry(lvl,sx,sy,clm_recs[sx%MAP_SUBNUM_X]);
00945
00946 for (i=0;i<9;i++)
00947 free_column_rec(clm_recs[i]);
00948 free(surr_slb);
00949 free(surr_own);
00950 free(surr_tng);
00951 return ERR_NONE;
00952 }
00953
00963 short slab_has_custom_columns(struct LEVEL *lvl, int tx, int ty)
00964 {
00965 if (cust_cols_num_on_tile(lvl,tx,ty)>0)
00966 return true;
00967 if (graffiti_idx(lvl,tx,ty)>=0)
00968 return true;
00969 return false;
00970 }
00971
00980 int update_custom_columns_for_slab(struct COLUMN_REC *clm_recs[9],struct LEVEL *lvl, int tx, int ty)
00981 {
00982 int mod_clms=0;
00983 if (cust_cols_num_on_tile(lvl,tx,ty)>0)
00984 mod_clms+=place_cust_clms_on_slab(clm_recs,lvl,tx,ty);
00985 if (graffiti_idx(lvl,tx,ty)>=0)
00986 mod_clms+=place_graffiti_on_slab(clm_recs,lvl,tx,ty);
00987 return mod_clms;
00988 }
00989
00998 int place_cust_clms_on_slab(struct COLUMN_REC *clm_recs[9],struct LEVEL *lvl, int tx, int ty)
00999 {
01000 int mod_clms=0;
01001 int i,k;
01002 for (k=0;k<3;k++)
01003 {
01004 int sy=ty*3+k;
01005 for (i=0;i<3;i++)
01006 {
01007 int sx=tx*3+i;
01008 struct COLUMN_REC *cclm_rec;
01009 cclm_rec=get_cust_col_rec(lvl,sx,sy);
01010 if (cclm_rec!=NULL)
01011 {
01012 clm_rec_copy(clm_recs[k*3+i],cclm_rec);
01013 mod_clms++;
01014 }
01015 }
01016 }
01017 return mod_clms;
01018 }
01019
01029 short cust_col_add_or_update(struct LEVEL *lvl,int sx,int sy,struct DK_CUSTOM_CLM *ccol)
01030 {
01031 if ((lvl==NULL)||(lvl->cust_clm_lookup==NULL)) return false;
01032 if ((ccol==NULL)||(ccol->rec==NULL)) return false;
01033 int idx;
01034
01035 struct DK_CUSTOM_CLM *ccol_old;
01036 ccol_old=get_cust_col(lvl,sx,sy);
01037 if (ccol_old!=NULL)
01038 cust_col_del(lvl,sx,sy);
01039
01040 set_cust_col(lvl,sx,sy,ccol);
01041 if (lvl->optns.datclm_auto_update)
01042 {
01043 update_datclm_for_slab(lvl,sx/3,sy/3);
01044 update_tile_wib_entries(lvl,sx/3,sy/3);
01045 update_tile_wlb_entry(lvl,sx/3,sy/3);
01046 update_tile_flg_entries(lvl,sx/3,sy/3);
01047 }
01048 return true;
01049 }
01050
01057 int cust_cols_num_on_tile(struct LEVEL *lvl, int tx, int ty)
01058 {
01059
01060 int sx_max=(tx+1)*MAP_SUBNUM_X;
01061 int sy_max=(ty+1)*MAP_SUBNUM_Y;
01062 int sx,sy;
01063 int count=0;
01064 for (sx=tx*MAP_SUBNUM_X;sx<sx_max;sx++)
01065 for (sy=ty*MAP_SUBNUM_Y;sy<sy_max;sy++)
01066 if (get_cust_col(lvl,sx,sy)!=NULL) count++;
01067 return count;
01068 }
01069
01078 struct DK_CUSTOM_CLM *get_cust_col(struct LEVEL *lvl, int sx, int sy)
01079 {
01080 int i;
01081 if ((lvl==NULL)||(lvl->cust_clm_lookup==NULL))
01082 return NULL;
01083 if ((sx<0)||(sx>=lvl->subsize.x)||(sy<0)||(sy>=lvl->subsize.y))
01084 return NULL;
01085 return lvl->cust_clm_lookup[sx][sy];
01086 }
01087
01096 struct COLUMN_REC *get_cust_col_rec(struct LEVEL *lvl, int sx, int sy)
01097 {
01098 struct DK_CUSTOM_CLM *ccol=get_cust_col(lvl,sx,sy);
01099 if (ccol==NULL) return NULL;
01100 return ccol->rec;
01101 }
01102
01110 unsigned short get_cust_col_wib_entry(struct LEVEL *lvl, int sx, int sy)
01111 {
01112 struct DK_CUSTOM_CLM *ccol=get_cust_col(lvl,sx,sy);
01113 if (ccol==NULL) return COLUMN_WIB_SKEW;
01114 return ccol->wib_val;
01115 }
01116
01127 short set_cust_col(struct LEVEL *lvl,int sx,int sy,struct DK_CUSTOM_CLM *ccol)
01128 {
01129 int i;
01130 if ((lvl==NULL)||(lvl->cust_clm_lookup==NULL))
01131 return false;
01132 if ((sx<0)||(sx>=lvl->subsize.x)||(sy<0)||(sy>=lvl->subsize.y))
01133 return false;
01134 if ((ccol==NULL)||(ccol->rec==NULL))
01135 return false;
01136 lvl->cust_clm_lookup[sx][sy]=ccol;
01137 lvl->cust_clm_count++;
01138 return true;
01139 }
01140
01146 unsigned int get_cust_clm_count(struct LEVEL *lvl)
01147 {
01148 if (lvl==NULL) return 0;
01149 return lvl->cust_clm_count;
01150 }
01151
01157 struct DK_CUSTOM_CLM *create_cust_col(void)
01158 {
01159 struct DK_CUSTOM_CLM *ccol;
01160
01161 ccol = (struct DK_CUSTOM_CLM *)malloc(sizeof(struct DK_CUSTOM_CLM));
01162 if (ccol==NULL)
01163 {
01164 message_error("Cannot alloc memory for custom column item");
01165 return NULL;
01166 }
01167 ccol->wib_val=COLUMN_WIB_SKEW;
01168 ccol->rec=create_column_rec();
01169 return ccol;
01170 }
01171
01179 short cust_col_del(struct LEVEL *lvl, int sx, int sy)
01180 {
01181 int i;
01182 if ((lvl==NULL)||(lvl->cust_clm_lookup==NULL))
01183 return false;
01184 if ((sx<0)||(sx>=lvl->subsize.x)||(sy<0)||(sy>=lvl->subsize.y))
01185 return false;
01186 struct DK_CUSTOM_CLM *ccol;
01187 ccol=lvl->cust_clm_lookup[sx][sy];
01188 lvl->cust_clm_lookup[sx][sy]=NULL;
01189 if (ccol==NULL) return false;
01190
01191 lvl->cust_clm_count--;
01192
01193 free_column_rec(ccol->rec);
01194 free(ccol);
01195 return true;
01196 }
01197
01205 int cust_cols_del_for_tile(struct LEVEL *lvl, int tx, int ty)
01206 {
01207
01208 int sx_max=(tx+1)*MAP_SUBNUM_X;
01209 int sy_max=(ty+1)*MAP_SUBNUM_Y;
01210 int sx,sy;
01211 int count=0;
01212 for (sx=tx*MAP_SUBNUM_X;sx<sx_max;sx++)
01213 for (sy=ty*MAP_SUBNUM_Y;sy<sy_max;sy++)
01214 if (cust_col_del(lvl,sx,sy)) count++;
01215 return count;
01216 }
01217
01218
01219
01220
01221
01222
01223 char *get_texture_fullname(unsigned short inf_type)
01224 {
01225 int types_count=sizeof(inf_texture_fullnames)/sizeof(char *);
01226 if (inf_type<types_count)
01227 return (char *)inf_texture_fullnames[inf_type];
01228 else
01229 return "unknown(?!)";
01230 }