123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- #include "game_logic.h"
- #include "water.h"
- #include "Berusky3d_kofola_interface.h"
- WATER_STRUCT wsWater;
- extern LEVELINFO Level;
- int w_Check_Oclussion(int x, int y, int z)
- {
- int real;
- int xs = x - 1;
- int ys = y - 1;
- int i, j, c = 0;
- if (ys < 0 || ys + 2 > Level.Size[1] || xs < 0 || xs + 2 > Level.Size[0])
- return 1;
- for (i = xs; i < xs + 3; i++)
- for (j = ys; j < ys + 3; j++) {
- gl_Logical2Real(i, j, z + 1, &real, &Level);
- if (Level.Level[real])
- if (Level.Level[real]->p_Object->Class == 2)
- c++;
- }
- if (c > 1)
- return 1;
- else
- return 0;
- }
- int w_Check_Oclussion_Vertical(int x, int y, int z)
- {
- int real;
- int ys = y - 1;
- int j, c = 0;
- if (ys < 0 || ys + 3 > Level.Size[1])
- return 1;
- for (j = ys; j < ys + 3; j++) {
- gl_Logical2Real(x, j, z + 1, &real, &Level);
- if (Level.Level[real])
- if (Level.Level[real]->p_Object->Class == 2)
- c++;
- }
- if (c > 1)
- return 1;
- else
- return 0;
- }
- int w_Check_Oclussion_Horizontal(int x, int y, int z)
- {
- int real;
- int xs = x - 1;
- int i, c = 0;
- if (xs < 0 || xs + 3 > Level.Size[0])
- return 1;
- for (i = xs; i < xs + 3; i++) {
- gl_Logical2Real(i, y, z + 1, &real, &Level);
- if (Level.Level[real])
- if (Level.Level[real]->p_Object->Class == 2)
- c++;
- }
- if (c > 1)
- return 1;
- else
- return 0;
- }
- int w_Find_Top(int x, int y, int z)
- {
- int real;
- int i;
- for (i = y; i < Level.Size[1]; i++) {
- gl_Logical2Real(x, i, z + 1, &real, &Level);
- if (Level.Level[real])
- if (Level.Level[real]->p_Object->Class == 2
- && w_Check_Oclussion(x, i, z))
- return i - 1;
- }
- return Level.Size[1] - 1;
- }
- int w_Find_Bottom(int x, int y, int z)
- {
- int real;
- int i;
- for (i = y; i >= 0; i--) {
- gl_Logical2Real(x, i, z + 1, &real, &Level);
- if (Level.Level[real])
- if (Level.Level[real]->p_Object->Class == 2
- && w_Check_Oclussion(x, i, z))
- return i + 1;
- }
- return 0;
- }
- int w_Find_Left(int x, int y, int z)
- {
- int real;
- int i;
- for (i = x; i >= 0; i--) {
- gl_Logical2Real(i, y, z + 1, &real, &Level);
- if (Level.Level[real])
- if (Level.Level[real]->p_Object->Class == 2
- && w_Check_Oclussion(i, y, z))
- return i + 1;
- }
- return 0;
- }
- int w_Find_Right(int x, int y, int z)
- {
- int real;
- int i;
- for (i = x; i < Level.Size[0]; i++) {
- gl_Logical2Real(i, y, z + 1, &real, &Level);
- if (Level.Level[real])
- if (Level.Level[real]->p_Object->Class == 2
- && w_Check_Oclussion(i, y, z))
- return i - 1;
- }
- return Level.Size[0] - 1;
- }
- float w_Count_Size(WATER_BOUNDARY * pBoundary)
- {
- return (pBoundary->Top - pBoundary->Bottom) * (pBoundary->Right -
- pBoundary->Left);
- }
- float w_Count_Aspect_Ratio(WATER_BOUNDARY * pBoundary)
- {
- float a, b;
- a = pBoundary->Top - pBoundary->Bottom;
- b = pBoundary->Right - pBoundary->Left;
- if (a > b)
- return b / a;
- else
- return a / b;
- }
- void w_Add_Boundary(int Top, int Left, int Bottom, int Right, int Height)
- {
- float fTop, fLeft, fBottom, fRight, fHeight;
- BOD b;
- WATER_BOUNDARY *pBoundary = wsWater.pFirst;
- if (Left == -1)
- return;
- kom_get_fyz_souradnice(Left, 0, Top, &b);
- fTop = b.z + 1;
- fLeft = b.x - 1;
- kom_get_fyz_souradnice(Right, Height, Bottom, &b);
- fBottom = b.z - 1;
- fRight = b.x + 1;
- fHeight = b.y;
- while (pBoundary) {
- if (pBoundary->Top == fTop &&
- pBoundary->Left == fLeft &&
- pBoundary->Bottom == fBottom &&
- pBoundary->Right == fRight && pBoundary->Height == fHeight)
- return;
- pBoundary = pBoundary->pNext;
- }
- pBoundary = (WATER_BOUNDARY *) malloc(sizeof(WATER_BOUNDARY));
- pBoundary->Top = fTop;
- pBoundary->Left = fLeft;
- pBoundary->Bottom = fBottom;
- pBoundary->Right = fRight;
- pBoundary->Height = fHeight;
- pBoundary->pNext = NULL;
- pBoundary->Size = w_Count_Size(pBoundary);
- pBoundary->AspectRatio = w_Count_Aspect_Ratio(pBoundary);
- wsWater.iCount++;
- if (!wsWater.pFirst) {
- wsWater.pFirst = pBoundary;
- wsWater.pLast = pBoundary;
- return;
- }
- wsWater.pLast->pNext = pBoundary;
- wsWater.pLast = pBoundary;
- }
- void w_Construct_Boundary(int x, int y, int z)
- {
- int Top, Left = -1, Bottom, Right = Level.Size[0] + 1, nLeft, nRight;
- int i;
- Top = w_Find_Top(x, y, z);
- Bottom = w_Find_Bottom(x, y, z);
- for (i = Bottom; i <= Top; i++) {
- nLeft = w_Find_Left(x, i, z);
- nRight = w_Find_Right(x, i, z);
- if (nLeft > Left)
- Left = nLeft;
- if (nRight < Right)
- Right = nRight;
- }
- w_Add_Boundary(Top, Left, Bottom, Right, z);
- }
- void w_Create_Water_Boundaries(void)
- {
- int real;
- int i, j, k;
- wsWater.iCount = 0;
- wsWater.pFirst = NULL;
- wsWater.pLast = NULL;
- for (i = 0; i < Level.Size[2]; i += 2)
- for (j = 0; j < Level.Size[0]; j++)
- for (k = 0; k < Level.Size[1]; k++) {
- gl_Logical2Real(j, k, i, &real, &Level);
- if (Level.Level[real])
- if (Level.Level[real]->p_Object->Class == 12)
- w_Construct_Boundary(j, k, i);
- }
- return;
- }
- void w_Release_Water_Boundaries(void)
- {
- WATER_BOUNDARY *pBoundary = wsWater.pFirst;
- WATER_BOUNDARY *pLBoundary;
- while (pBoundary) {
- pLBoundary = pBoundary;
- pBoundary = pBoundary->pNext;
- kprintf(1, "free((void *) pLBoundary)");
- free((void *) pLBoundary);
- }
- wsWater.iCount = 0;
- wsWater.pFirst = NULL;
- wsWater.pLast = NULL;
- }
- void w_Choose_Random_Boundary(WATER_BOUNDARY * pBoundary, float fx, float fy,
- float fz)
- {
- int iBoundary;
- int iCount = 0;
- WATER_BOUNDARY *pTBoundary = wsWater.pFirst;
- while (pTBoundary) {
- if (fx >= pTBoundary->Left && fx <= pTBoundary->Right &&
- fy >= pTBoundary->Bottom && fy <= pTBoundary->Top &&
- fz >= pTBoundary->Height - 0.25f && fz <= pTBoundary->Height + 0.25f)
- iCount++;
- pTBoundary = pTBoundary->pNext;
- }
- if (!iCount)
- return;
- iBoundary = rand() % iCount;
- iCount = 0;
- pTBoundary = wsWater.pFirst;
- while (pTBoundary) {
- if (iCount == iBoundary) {
- pBoundary->Bottom = pTBoundary->Bottom;
- pBoundary->Top = pTBoundary->Top;
- pBoundary->Right = pTBoundary->Right;
- pBoundary->Left = pTBoundary->Left;
- return;
- }
- iCount++;
- pTBoundary = pTBoundary->pNext;
- }
- }
- void w_Choose_Max_Size_Boundary(WATER_BOUNDARY * pBoundary, float fx,
- float fy, float fz)
- {
- int iBoundary;
- int iCount = 0;
- float max_size = 0;
- WATER_BOUNDARY *pTBoundary = wsWater.pFirst;
- while (pTBoundary) {
- if (fx >= pTBoundary->Left && fx <= pTBoundary->Right &&
- fy >= pTBoundary->Bottom && fy <= pTBoundary->Top &&
- fz >= pTBoundary->Height - 0.25f && fz <= pTBoundary->Height + 0.25f &&
- pTBoundary->Size > max_size) {
- iBoundary = iCount;
- max_size = pTBoundary->Size;
- }
- iCount++;
- pTBoundary = pTBoundary->pNext;
- }
- if (!iCount)
- return;
- iCount = 0;
- pTBoundary = wsWater.pFirst;
- while (pTBoundary) {
- if (iCount == iBoundary) {
- pBoundary->Bottom = pTBoundary->Bottom;
- pBoundary->Top = pTBoundary->Top;
- pBoundary->Right = pTBoundary->Right;
- pBoundary->Left = pTBoundary->Left;
- return;
- }
- iCount++;
- pTBoundary = pTBoundary->pNext;
- }
- }
- void w_Choose_Size_Heuristics_Boundary(WATER_BOUNDARY * pBoundary, float fx,
- float fy, float fz)
- {
- int iBoundary = -1;
- int iCount = 0;
- float max_size = 0;
- WATER_BOUNDARY *pTBoundary = wsWater.pFirst;
- while (pTBoundary) {
- if (fx >= pTBoundary->Left && fx <= pTBoundary->Right &&
- fy >= pTBoundary->Bottom && fy <= pTBoundary->Top &&
- fz >= pTBoundary->Height - 0.25f && fz <= pTBoundary->Height + 0.25f &&
- pTBoundary->Size * pTBoundary->AspectRatio > max_size) {
- iBoundary = iCount;
- max_size = pTBoundary->Size * pTBoundary->AspectRatio;
- }
- iCount++;
- pTBoundary = pTBoundary->pNext;
- }
- if (!iCount)
- return;
- iCount = 0;
- pTBoundary = wsWater.pFirst;
- while (pTBoundary) {
- if (iCount == iBoundary) {
- pBoundary->Bottom = pTBoundary->Bottom;
- pBoundary->Top = pTBoundary->Top;
- pBoundary->Right = pTBoundary->Right;
- pBoundary->Left = pTBoundary->Left;
- return;
- }
- iCount++;
- pTBoundary = pTBoundary->pNext;
- }
- }
- void w_Choose_Best_Boundary(WATER_BOUNDARY * pBoundary, float fx, float fy,
- float fz, int Method)
- {
- switch (Method) {
- case WATER_BOUNDARY_METHOD_RANDOM:
- w_Choose_Random_Boundary(pBoundary, fx, fy, fz);
- break;
- case WATER_BOUNDARY_METHOD_MAX_SIZE:
- w_Choose_Max_Size_Boundary(pBoundary, fx, fy, fz);
- break;
- case WATER_BOUNDARY_METHOD_SIZE_HEURISTICS:
- w_Choose_Size_Heuristics_Boundary(pBoundary, fx, fy, fz);
- break;
- }
- }
|