00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "obj_slabs.h"
00022
00023 #include <math.h>
00024 #include "lev_data.h"
00025 #include "globals.h"
00026 #include "obj_things.h"
00027
00028 char const SLB_UNKN_LTEXT[]="Unknown slab";
00029 char const SLB_ROCK_LTEXT[]="Rock";
00030 char const SLB_GOLD_LTEXT[]="Gold";
00031 char const SLB_EARTH_LTEXT[]="Earth";
00032 char const SLB_TORCHDIRT_LTEXT[]="Torch plate earth";
00033 char const SLB_WALLDRAPE_LTEXT[]="Wall with drape";
00034 char const SLB_WALLTORCH_LTEXT[]="Wall with torch";
00035 char const SLB_WALLWTWINS_LTEXT[]="Wall with twins";
00036 char const SLB_WALLWWOMAN_LTEXT[]="Wall with woman";
00037 char const SLB_WALLPAIRSHR_LTEXT[]="Wall w/pair shag.";
00038 char const SLB_PATH_LTEXT[]="Path";
00039 char const SLB_CLAIMED_LTEXT[]="Claimed ground";
00040 char const SLB_LAVA_LTEXT[]="Lava";
00041 char const SLB_WATER_LTEXT[]="Water";
00042 char const SLB_PORTAL_LTEXT[]="Entrance";
00043 char const SLB_TREASURE_LTEXT[]="Treasure room";
00044 char const SLB_LIBRARY_LTEXT[]="Library";
00045 char const SLB_PRISON_LTEXT[]="Prison";
00046 char const SLB_TORTURE_LTEXT[]="Torture chamber";
00047 char const SLB_TRAINING_LTEXT[]="Training room";
00048 char const SLB_DUNGHEART_LTEXT[]="Dungeon heart";
00049 char const SLB_WORKSHOP_LTEXT[]="Workshop";
00050 char const SLB_SCAVENGER_LTEXT[]="Scavenger room";
00051 char const SLB_TEMPLE_LTEXT[]="Temple";
00052 char const SLB_GRAVEYARD_LTEXT[]="Graveyard";
00053 char const SLB_HATCHERY_LTEXT[]="Hatchery";
00054 char const SLB_LAIR_LTEXT[]="Lair";
00055 char const SLB_BARRACKS_LTEXT[]="Barracks";
00056 char const SLB_DOORWOOD_LTEXT[]="Wooden door";
00057 char const SLB_DOORBRACE_LTEXT[]="Braced door";
00058 char const SLB_DOORIRON_LTEXT[]="Iron door";
00059 char const SLB_DOORMAGIC_LTEXT[]="Magic door";
00060 char const SLB_BRIDGE_LTEXT[]="Bridge";
00061 char const SLB_GEMS_LTEXT[]="Gems";
00062 char const SLB_GUARDPOST_LTEXT[]="Guard post";
00063
00064 const char *owner_fullnames[]={"Keeper 0 (Human)", "Keeper 1 (blue)", "Keeper 2 (green)",
00065 "Keeper 3 (yellow)", "Heroes (Player4)", "Unclaimed/Unowned"};
00066 const char *owner_colornames[]={"Red", "Blue", "Green",
00067 "Yellow", "White", "Unowned"};
00068
00069 const unsigned char owners_list[]={
00070 PLAYER0, PLAYER1, PLAYER2, PLAYER3,
00071 PLAYER_GOOD, PLAYER_UNSET
00072 };
00073
00074 const unsigned short slabs_space[]={
00075 SLAB_TYPE_PATH, SLAB_TYPE_CLAIMED, SLAB_TYPE_LAVA,
00076 SLAB_TYPE_WATER,
00077 };
00078
00079 const unsigned short slabs_liquid[]={
00080 SLAB_TYPE_LAVA, SLAB_TYPE_WATER,
00081 };
00082
00083 const unsigned short slabs_short_unclmabl[]={
00084 SLAB_TYPE_PATH, SLAB_TYPE_LAVA, SLAB_TYPE_WATER,
00085 };
00086
00087 const unsigned short slabs_wealth[]={
00088 SLAB_TYPE_GOLD, SLAB_TYPE_GEMS,
00089 };
00090
00091 const unsigned short slabs_tall_unclmabl[]={
00092 SLAB_TYPE_ROCK, SLAB_TYPE_GOLD, SLAB_TYPE_EARTH,
00093 SLAB_TYPE_TORCHDIRT, SLAB_TYPE_GEMS
00094 };
00095
00096 const unsigned short slabs_walls[]={
00097 SLAB_TYPE_WALLDRAPE, SLAB_TYPE_WALLTORCH, SLAB_TYPE_WALLWTWINS,
00098 SLAB_TYPE_WALLWWOMAN, SLAB_TYPE_WALLPAIRSHR,
00099 };
00100
00101 const unsigned short slabs_rooms[]={
00102 SLAB_TYPE_DUNGHEART,SLAB_TYPE_PORTAL, SLAB_TYPE_TREASURE,
00103 SLAB_TYPE_LIBRARY, SLAB_TYPE_PRISONCASE, SLAB_TYPE_TORTURE,
00104 SLAB_TYPE_TRAINING, SLAB_TYPE_WORKSHOP, SLAB_TYPE_SCAVENGER,
00105 SLAB_TYPE_TEMPLE, SLAB_TYPE_GRAVEYARD, SLAB_TYPE_HATCHERY,
00106 SLAB_TYPE_LAIR, SLAB_TYPE_BARRACKS, SLAB_TYPE_BRIDGE,
00107 SLAB_TYPE_GUARDPOST,
00108 };
00109
00110 const unsigned short slabs_doors[]={
00111 SLAB_TYPE_DOORWOOD1, SLAB_TYPE_DOORWOOD2,
00112 SLAB_TYPE_DOORBRACE1, SLAB_TYPE_DOORBRACE2,
00113 SLAB_TYPE_DOORIRON1, SLAB_TYPE_DOORIRON2,
00114 SLAB_TYPE_DOORMAGIC1, SLAB_TYPE_DOORMAGIC2,
00115 };
00116
00117 const char *all_slabs_fullnames[]={
00118
00119 SLB_ROCK_LTEXT,SLB_GOLD_LTEXT,
00120 SLB_EARTH_LTEXT,SLB_TORCHDIRT_LTEXT,
00121 SLB_WALLDRAPE_LTEXT,SLB_WALLTORCH_LTEXT,
00122 SLB_WALLWTWINS_LTEXT,SLB_WALLWWOMAN_LTEXT,
00123 SLB_WALLPAIRSHR_LTEXT,SLB_UNKN_LTEXT,
00124 SLB_PATH_LTEXT,SLB_CLAIMED_LTEXT,
00125 SLB_LAVA_LTEXT,SLB_WATER_LTEXT,
00126 SLB_PORTAL_LTEXT,SLB_UNKN_LTEXT,
00127 SLB_TREASURE_LTEXT,SLB_UNKN_LTEXT,
00128 SLB_LIBRARY_LTEXT,SLB_UNKN_LTEXT,
00129 SLB_PRISON_LTEXT,SLB_UNKN_LTEXT,
00130 SLB_TORTURE_LTEXT,SLB_UNKN_LTEXT,
00131 SLB_TRAINING_LTEXT,SLB_UNKN_LTEXT,
00132 SLB_DUNGHEART_LTEXT,SLB_UNKN_LTEXT,
00133 SLB_WORKSHOP_LTEXT,SLB_UNKN_LTEXT,
00134 SLB_SCAVENGER_LTEXT,SLB_UNKN_LTEXT,
00135 SLB_TEMPLE_LTEXT,SLB_UNKN_LTEXT,
00136 SLB_GRAVEYARD_LTEXT,SLB_UNKN_LTEXT,
00137 SLB_HATCHERY_LTEXT,SLB_UNKN_LTEXT,
00138 SLB_LAIR_LTEXT,SLB_UNKN_LTEXT,
00139 SLB_BARRACKS_LTEXT,SLB_UNKN_LTEXT,
00140 SLB_DOORWOOD_LTEXT,SLB_DOORWOOD_LTEXT,
00141 SLB_DOORBRACE_LTEXT,SLB_DOORBRACE_LTEXT,
00142 SLB_DOORIRON_LTEXT,SLB_DOORIRON_LTEXT,
00143 SLB_DOORMAGIC_LTEXT,SLB_DOORMAGIC_LTEXT,
00144 SLB_UNKN_LTEXT,SLB_BRIDGE_LTEXT,
00145 SLB_GEMS_LTEXT,SLB_GUARDPOST_LTEXT,
00146 };
00147
00148 unsigned char get_owner_next(unsigned char plyr_idx)
00149 {
00150 plyr_idx++;
00151 if (plyr_idx<PLAYERS_COUNT) return plyr_idx;
00152 return 0;
00153 }
00154
00155 unsigned char get_owner_prev(unsigned char plyr_idx)
00156 {
00157 plyr_idx--;
00158 if (plyr_idx<PLAYERS_COUNT) return plyr_idx;
00159 return PLAYERS_COUNT-1;
00160 }
00161
00162
00163
00164
00165 void update_slab_owners(struct LEVEL *lvl)
00166 {
00167
00168 int tx, ty;
00169 for (ty=0; ty<lvl->tlsize.y; ty++)
00170 for (tx=0; tx<lvl->tlsize.x; tx++)
00171 {
00172 unsigned short slb=get_tile_slab(lvl, tx, ty);
00173 if (!slab_is_clmabl(slb))
00174 set_tile_owner(lvl,tx,ty,PLAYER_UNSET);
00175 }
00176
00177 int sx, sy;
00178 sx=lvl->subsize.x-1;
00179 for (sy=0; sy<lvl->subsize.y; sy++)
00180 set_subtl_owner(lvl,sx,sy,PLAYER_UNSET);
00181 sy=lvl->subsize.y-1;
00182 for (sx=0; sx<lvl->subsize.x; sx++)
00183 set_subtl_owner(lvl,sx,sy,PLAYER_UNSET);
00184 }
00185
00186
00187
00188
00189
00190
00191 short place_room_rndpos(struct LEVEL *lvl,const unsigned short rslab,
00192 const unsigned char rown,const struct IPOINT_2D *rsize)
00193 {
00194 int surrnd_size=20;
00195 struct IPOINT_2D rpos;
00196 while (surrnd_size>4)
00197 {
00198 int lottery_count;
00199 for (lottery_count=0;lottery_count<16;lottery_count++)
00200 {
00201 rpos.x=(surrnd_size>>1)+1+rnd(lvl->tlsize.x-surrnd_size);
00202 rpos.y=(surrnd_size>>1)+1+rnd(lvl->tlsize.y-surrnd_size);
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 }
00213 surrnd_size--;
00214 }
00215
00216 return false;
00217 }
00218
00219
00220
00221
00222 char *get_owner_type_fullname(unsigned char own_idx)
00223 {
00224 int types_count=sizeof(owner_fullnames)/sizeof(char *);
00225 if (own_idx<types_count)
00226 return (char *)owner_fullnames[own_idx];
00227 else
00228 return "unknown(?!)";
00229 }
00230
00231
00232
00233
00234 char *get_owner_type_colorname(unsigned char own_idx)
00235 {
00236 int types_count=sizeof(owner_colornames)/sizeof(char *);
00237 if (own_idx<types_count)
00238 return (char *)owner_colornames[own_idx];
00239 else
00240 return "unknown(?!)";
00241 }
00242
00243
00244
00245
00246 short slab_is_central(struct LEVEL *lvl,int tx,int ty)
00247 {
00248
00249 if ((tx<=0) || (ty<=0) || (tx+1>=lvl->tlsize.x) || (ty+1>=lvl->tlsize.y))
00250 return false;
00251
00252 int i, j;
00253 unsigned short slab=get_tile_slab(lvl,tx,ty);
00254 unsigned char owner=get_tile_owner(lvl,tx,ty);
00255
00256 for (i=tx-1; i<=tx+1; i++)
00257 for (j=ty-1; j<=ty+1; j++)
00258 if ((slab!=get_tile_slab(lvl,i,j))||(owner!=get_tile_owner(lvl,i,j)))
00259 return false;
00260 return true;
00261 }
00262
00263
00264
00265
00266
00267 short slabs_verify(struct LEVEL *lvl, char *err_msg,struct IPOINT_2D *errpt)
00268 {
00269
00270 int max_tl_idx_x=lvl->tlsize.x-1;
00271 int max_tl_idx_y=lvl->tlsize.y-1;
00272 short result;
00273 int i,j;
00274 for (i=1; i < max_tl_idx_y; i++)
00275 for (j=1; j < max_tl_idx_x; j++)
00276 {
00277 result=slab_verify_entry(get_tile_slab(lvl,i,j),err_msg);
00278 if (result!=VERIF_OK)
00279 {
00280 errpt->x=i;
00281 errpt->y=j;
00282 return result;
00283 }
00284 }
00285 return VERIF_OK;
00286 }
00287
00288
00289
00290
00291
00292
00293 int slab_siblings_oftype(struct LEVEL *lvl,int x,int y,unsigned short slab_type)
00294 {
00295 int amount=0;
00296
00297 int i, j;
00298
00299 for (i=x-1; i<=x+1; i++)
00300 for (j=y-1; j<=y+1; j++)
00301 {
00302 if ((i>=0) && (j>=0) && (i<lvl->tlsize.x) && (j<lvl->tlsize.y))
00303 if (get_tile_slab(lvl,i,j)==slab_type)
00304 amount++;
00305 }
00306 return amount;
00307 }
00308
00309 short slab_is_room(unsigned short slab_type)
00310 {
00311 int array_count=sizeof(slabs_rooms)/sizeof(unsigned short);
00312
00313 int idx=arr_ushort_pos(slabs_rooms,slab_type,array_count);
00314 if (idx>=0) return true;
00315 return false;
00316 }
00317
00318 short slab_is_door(unsigned short slab_type)
00319 {
00320 int array_count=sizeof(slabs_doors)/sizeof(unsigned short);
00321
00322 int idx=arr_ushort_pos(slabs_doors,slab_type,array_count);
00323 if (idx>=0) return true;
00324 return false;
00325 }
00326
00327 short slab_is_wall(unsigned short slab_type)
00328 {
00329 int array_count=sizeof(slabs_walls)/sizeof(unsigned short);
00330
00331 int idx=arr_ushort_pos(slabs_walls,slab_type,array_count);
00332 if (idx>=0) return true;
00333 return false;
00334 }
00335
00336 unsigned short get_random_wall_slab(void)
00337 {
00338 int array_count=sizeof(slabs_walls)/sizeof(unsigned short);
00339
00340 int idx=rnd(array_count);
00341 return slabs_walls[idx];
00342 }
00343
00344 short slab_is_wealth(unsigned short slab_type)
00345 {
00346 int array_count=sizeof(slabs_wealth)/sizeof(unsigned short);
00347 int idx=arr_ushort_pos(slabs_wealth,slab_type,array_count);
00348 if (idx>=0) return true;
00349 return false;
00350 }
00351
00352 short slab_is_space(unsigned short slab_type)
00353 {
00354 int array_count=sizeof(slabs_space)/sizeof(unsigned short);
00355
00356 int idx=arr_ushort_pos(slabs_space,slab_type,array_count);
00357 if (idx>=0) return true;
00358 return false;
00359 }
00360
00361 short slab_is_liquid(unsigned short slab_type)
00362 {
00363 int array_count=sizeof(slabs_liquid)/sizeof(unsigned short);
00364
00365 int idx=arr_ushort_pos(slabs_liquid,slab_type,array_count);
00366 if (idx>=0) return true;
00367 return false;
00368 }
00369
00370 short slab_is_tall_unclmabl(unsigned short slab_type)
00371 {
00372 int array_count=sizeof(slabs_tall_unclmabl)/sizeof(unsigned short);
00373
00374 int idx=arr_ushort_pos(slabs_tall_unclmabl,slab_type,array_count);
00375 if (idx>=0) return true;
00376 return false;
00377 }
00378
00379 short slab_is_short_unclmabl(unsigned short slab_type)
00380 {
00381 int array_count=sizeof(slabs_short_unclmabl)/sizeof(unsigned short);
00382
00383 int idx=arr_ushort_pos(slabs_short_unclmabl,slab_type,array_count);
00384 if (idx>=0) return true;
00385 return false;
00386 }
00387
00388 short slab_is_short(unsigned short slab_type)
00389 {
00390
00391 if (slab_is_room(slab_type)) return true;
00392
00393 if (slab_is_space(slab_type)) return true;
00394 return false;
00395 }
00396
00397 short slab_is_tall(unsigned short slab_type)
00398 {
00399 if (slab_is_tall_unclmabl(slab_type)) return true;
00400 if (slab_is_wall(slab_type)) return true;
00401 return false;
00402 }
00403
00404 short slab_is_short_clmabl(unsigned short slab_type)
00405 {
00406
00407 if (slab_is_room(slab_type)) return true;
00408
00409 if (slab_is_door(slab_type)) return true;
00410 if (slab_type==SLAB_TYPE_CLAIMED) return true;
00411 return false;
00412 }
00413
00414 short slab_is_claimedgnd(unsigned short slab_type)
00415 {
00416 if (slab_is_door(slab_type)) return true;
00417 if (slab_type==SLAB_TYPE_CLAIMED) return true;
00418 return false;
00419 }
00420
00421 short slab_is_clmabl(unsigned short slab_type)
00422 {
00423 if (slab_is_short_unclmabl(slab_type)) return false;
00424 if (slab_is_tall_unclmabl(slab_type)) return false;
00425 return true;
00426 }
00427
00428
00429
00430
00431 short slab_allows_torch(unsigned short slab_type)
00432 {
00433 if (!slab_is_short(slab_type)) return false;
00434 if (slab_is_room(slab_type)) return false;
00435 if (slab_is_liquid(slab_type)) return false;
00436 return true;
00437 }
00438
00439
00440
00441
00442 short slab_needs_adjacent_torch(unsigned short slab_type)
00443 {
00444 if (slab_type==SLAB_TYPE_TORCHDIRT) return true;
00445 if (slab_type==SLAB_TYPE_WALLTORCH) return true;
00446 return false;
00447 }
00448
00449
00450
00451
00452 void slab_draw_smear(struct LEVEL *lvl,int startx,int starty,int startr,
00453 int endx,int endy,int endr,int bend,unsigned short slab_type)
00454 {
00455 int dist_x=(startx-endx);
00456 int dist_y=(starty-endy);
00457 int distance=floor(sqrt(pow(dist_x,2)+pow(dist_y,2))+0.5f);
00458 if (distance<1) distance=1;
00459 int cx,cy,r;
00460 int i;
00461 for (i=0;i<distance;i++)
00462 {
00463 int ir=distance-i-1;
00464 float bend_val=2.0f*sqrt(pow(distance/2,2)-pow(i-distance/2,2))*(float)bend/distance;
00465 int bend_x,bend_y;
00466 bend_x=floor((bend_val*(float)dist_y)/(float)distance+0.5f);
00467 bend_y=floor((bend_val*(float)dist_x)/(float)distance+0.5f);
00468
00469 cx=(startx*ir+endx*i)/distance+bend_x;
00470 cy=(starty*ir+endy*i)/distance-bend_y;
00471 r= (startr*ir+endr*i)/distance;
00472
00473 slab_draw_circle(lvl,cx,cy,r,slab_type);
00474 }
00475 }
00476
00477 void slab_draw_circle(struct LEVEL *lvl,int x,int y,int rad,unsigned short slab_type)
00478 {
00479 int i,j;
00480 int cx,cy;
00481 for (i=-rad;i<rad;i++)
00482 for (j=-rad;j<rad;j++)
00483 {
00484 cx=x+i;
00485 cy=y+j;
00486 if ((cx>=0) && (cy>=0) && (cx<lvl->tlsize.x) && (cy<lvl->tlsize.y))
00487 {
00488 int crad=floor(sqrt(i*i+j*j)+0.5);
00489 if (crad<rad)
00490 set_tile_slab(lvl,cx,cy,slab_type);
00491 }
00492 }
00493 }
00494
00495
00496
00497
00498 short slab_verify_entry(unsigned short slab_type, char *err_msg)
00499 {
00500 if (slab_is_door(slab_type)) return VERIF_OK;
00501 if (slab_is_room(slab_type)) return VERIF_OK;
00502 if (slab_is_wall(slab_type)) return VERIF_OK;
00503 if (slab_is_space(slab_type)) return VERIF_OK;
00504 if (slab_is_tall_unclmabl(slab_type)) return VERIF_OK;
00505 sprintf(err_msg,"Unknown slab entry %d",(int)slab_type);
00506 return VERIF_WARN;
00507 }
00508
00509
00510
00511
00512 char *get_slab_fullname(unsigned short slb_type)
00513 {
00514 int types_count=sizeof(all_slabs_fullnames)/sizeof(char *);
00515 if (slb_type<types_count)
00516 return (char *)all_slabs_fullnames[slb_type];
00517 else
00518 return "unknown(?!)";
00519 }
00520
00521 short subtl_is_near_tall_slab(struct LEVEL *lvl,unsigned int sx,unsigned int sy)
00522 {
00523 int tx=sx/MAP_SUBNUM_X;
00524 int ty=sy/MAP_SUBNUM_Y;
00525 int subtl_x=sx%MAP_SUBNUM_X;
00526 int subtl_y=sy%MAP_SUBNUM_Y;
00527 unsigned short slab;
00528 const int sub_val[]= {0, 2};
00529 const int til_delta[]={-1,1};
00530 int i,k;
00531
00532 for (i=0;i<2;i++)
00533 {
00534 if (subtl_x==sub_val[i])
00535 {
00536 slab=get_tile_slab(lvl,tx+til_delta[i],ty);
00537 if (slab_is_tall(slab)) return true;
00538 }
00539 if (subtl_y==sub_val[i])
00540 {
00541 slab=get_tile_slab(lvl,tx,ty+til_delta[i]);
00542 if (slab_is_tall(slab)) return true;
00543 }
00544 }
00545
00546 for (k=0;k<2;k++)
00547 for (i=0;i<2;i++)
00548 {
00549 if ((subtl_x==sub_val[i])&&(subtl_y==sub_val[k]))
00550 {
00551 slab=get_tile_slab(lvl,tx+til_delta[i],ty+til_delta[k]);
00552 if (slab_is_tall(slab)) return true;
00553 }
00554 }
00555 return false;
00556 }