ew-engine/hq engine src/gl_localmenu.c

1153 lines
21 KiB
C
Raw Permalink Normal View History

2006-10-08 00:00:00 +00:00
/*
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "quakedef.h"
///////////////////////////
//
// - - - MenuSystem
//
// GPL code
cvar_t menu_0 = { "menu_0",""};//option 0 Gfx/String ..
cvar_t menu_1 = { "menu_1",""};//option 1
cvar_t menu_2 = { "menu_2",""};//option 2
cvar_t menu_3 = { "menu_3",""};//option 3
cvar_t menu_4 = { "menu_4",""};//option 4
cvar_t menu_5 = { "menu_5",""};
cvar_t menu_6 = { "menu_6",""};
cvar_t menu_7 = { "menu_7",""};
cvar_t menu_8 = { "menu_8",""};
cvar_t menu_9 = { "menu_9",""};
cvar_t menu_select = { "menu_select","0"};//option selected (highlight)
cvar_t menu_mode = { "menu_mode","0"};//0=nomenu, 2=gfx, 1=string
cvar_t menu_items = { "menu_items","0"};//n# items
cvar_t menu_scale = { "menu_scale","2"};//scale
cvar_t xmenu_0 = { "xmenu_0",""};//Title - command
cvar_t xmenu_1 = { "xmenu_1",""};//option 1
cvar_t xmenu_2 = { "xmenu_2",""};//option 2
cvar_t xmenu_3 = { "xmenu_3",""};//option 3
cvar_t xmenu_4 = { "xmenu_4",""};//option 4
cvar_t xmenu_5 = { "xmenu_5",""};
cvar_t xmenu_6 = { "xmenu_6",""};
cvar_t xmenu_7 = { "xmenu_7",""};
cvar_t xmenu_8 = { "xmenu_8",""};
cvar_t xmenu_9 = { "xmenu_9",""};
cvar_t menu_image = { "menu_image","gfx/menu.tga"};
cvar_t menu_actual = { "menu_actual","menu_0"};
cvar_t minimap = { "minimap","0"};//scale
//cvar_t menu_extra[MAX_EXTRAMENUS];
//cvar_t menu_xextra[MAX_EXTRAMENUS];
void Menu_Down_f(void)
{
static char menusel[100];
Cvar_SetValue("menu_select", (float)menu_select.value + 1);//down a element
if( menu_select.value > menu_items.value)
{
Cvar_SetValue("menu_select", 1);//Init of menu
}
};
void Menu_Up_f(void)
{
static char menusel[100];
Cvar_SetValue("menu_select", (float)menu_select.value - 1);
if( menu_select.value < 1)
{
Cvar_SetValue("menu_select", (float)menu_items.value );//Top of menu
}
};
void Menu_Big_f(void)
{
Cvar_SetValue("menu_scale", (float)menu_scale.value + 1);
}
void Menu_Small_f(void)
{
if (menu_scale.value>1)
Cvar_SetValue("menu_scale", (float)menu_scale.value - 1);
}
void Menu_Exec_f(void)
{
static char menusel[100];
int i = menu_select.value;
if(!menu_mode.value)
return;
if (menu_select.value > menu_items.value)
return;
#define EXEC( themenu ) Cbuf_AddText (themenu.string);Cbuf_AddText ("\n");
switch( i)
{
case 1:
EXEC( xmenu_1 );
break;
case 2:
EXEC( xmenu_2 );
break;
case 3:
EXEC( xmenu_3 );
break;
case 4:
EXEC( xmenu_4 );
break;
case 5:
EXEC( xmenu_5 );
break;
case 6:
EXEC( xmenu_6 );
break;
case 7:
EXEC( xmenu_7 );
break;
case 8:
EXEC( xmenu_8 );
break;
case 9:
EXEC( xmenu_9 );
break;
default:
break;
}
}
/*
void ExecMenu_f(void)
{
Cbuf_AddText ("menu main\n");
}*/
void Menu_Clear_f (void)
{
Cvar_Set("menu_0","" );
Cvar_Set("menu_1","" );
Cvar_Set("menu_2","" );
Cvar_Set("menu_3","" );
Cvar_Set("menu_4","" );
Cvar_Set("menu_5","" );
Cvar_Set("menu_6","" );
Cvar_Set("menu_7","" );
Cvar_Set("menu_8","" );
Cvar_Set("menu_9","" );
Cvar_Set("xmenu_0","" );
Cvar_Set("xmenu_1","" );
Cvar_Set("xmenu_2","" );
Cvar_Set("xmenu_3","" );
Cvar_Set("xmenu_4","" );
Cvar_Set("xmenu_5","" );
Cvar_Set("xmenu_6","" );
Cvar_Set("xmenu_7","" );
Cvar_Set("xmenu_8","" );
Cvar_Set("xmenu_9","" );
}
void GetMenuSelect( int i, cvar_t ** menu, cvar_t **xmenu)
{
switch(i)
{
case 1: *menu=&menu_1;*xmenu = &xmenu_1; break;
case 2: *menu=&menu_2;*xmenu = &xmenu_2; break;
case 3: *menu=&menu_3;*xmenu = &xmenu_3; break;
case 4: *menu=&menu_4;*xmenu = &xmenu_4; break;
case 5: *menu=&menu_5;*xmenu = &xmenu_5; break;
case 6: *menu=&menu_6;*xmenu = &xmenu_6; break;
case 7: *menu=&menu_7;*xmenu = &xmenu_7; break;
case 8: *menu=&menu_8;*xmenu = &xmenu_8; break;
case 9: *menu=&menu_9;*xmenu = &xmenu_9; break;
default:
*menu = &menu_0;
*xmenu = &xmenu_0;
break;
}
};
void AddItem_f(void )
{
cvar_t * menu, *xmenu;
char *label,*value ;
char buf[1024];
int c;
c = Cmd_Argc( );
label = Cmd_Argv(1);
value = Cmd_Argv(2);
sprintf(buf,"%d",c=(menu_items.value + 1));
Cvar_Set("menu_items",buf);
GetMenuSelect(c=menu_items.value,&menu,&xmenu);
Cvar_Set(menu->name,label);
Cvar_Set(xmenu->name,value);
};
void FillAutoMap ();
void GlobalUpdate ();
void RunAutomap_f(void)
{
if (minimap.value < 5)
{
Con_Printf("filling automap..\n");
FillAutoMap();
}
else
{
Con_Printf("filling wpmap..\n");
GlobalUpdate();
}
};
void WPStart_f(void);
void LoadHUD_f(void);
void UnloadHUD_f(void);
void listHUD_f (void);
void CL_LocalMenus_Init(void)
{
//Labels / gfx files
Cvar_RegisterVariable (&menu_0);
Cvar_RegisterVariable (&menu_1);
Cvar_RegisterVariable (&menu_2);
Cvar_RegisterVariable (&menu_3);
Cvar_RegisterVariable (&menu_4);
Cvar_RegisterVariable (&menu_5);
Cvar_RegisterVariable (&menu_6);
Cvar_RegisterVariable (&menu_7);
Cvar_RegisterVariable (&menu_8);
Cvar_RegisterVariable (&menu_9);
//Config
Cvar_RegisterVariable (&menu_select);
Cvar_RegisterVariable (&menu_mode);
Cvar_RegisterVariable (&menu_items);
Cvar_RegisterVariable (&menu_scale);
Cvar_RegisterVariable (&menu_image);
//Commands
Cvar_RegisterVariable (&xmenu_0);
Cvar_RegisterVariable (&xmenu_1);
Cvar_RegisterVariable (&xmenu_2);
Cvar_RegisterVariable (&xmenu_3);
Cvar_RegisterVariable (&xmenu_4);
Cvar_RegisterVariable (&xmenu_5);
Cvar_RegisterVariable (&xmenu_6);
Cvar_RegisterVariable (&xmenu_7);
Cvar_RegisterVariable (&xmenu_8);
Cvar_RegisterVariable (&xmenu_9);
Cmd_AddCommand ("menu_up", Menu_Up_f);
Cmd_AddCommand ("menu_down", Menu_Down_f);
Cmd_AddCommand ("menu_big", Menu_Big_f);
Cmd_AddCommand ("menu_small", Menu_Small_f);
Cmd_AddCommand ("menu_exec", Menu_Exec_f);
Cmd_AddCommand ("menu_clear", Menu_Clear_f);
Cmd_AddCommand ("additem", AddItem_f);
// Cmd_AddCommand ("execmenu", ExecMenu_f);
//Minimap
Cmd_AddCommand ("runautomap", RunAutomap_f);
Cvar_RegisterVariable (&minimap);
//WP Matrix
Cmd_AddCommand ("wpstart", WPStart_f);
Cmd_AddCommand ("loadhud", LoadHUD_f);
Cmd_AddCommand ("unloadhud", UnloadHUD_f);
Cmd_AddCommand ("listhud", listHUD_f);
}
#define MENUBASE 20
void Draw_StringMult (int x, int y, char *str, int maxlen, int mult);
void DrawQ_String (float x, float y, char *string, int maxlen, float scalex, float scaley, float red, float green, float blue, float alpha, int flags)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3f(red,green,blue);
Draw_StringMult(x,y,string,maxlen,scalex);
glColor3f(1,1,1);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
};
typedef struct
{
int texnum;
float sl, tl, sh, th;
} glpic_t;
void DrawQ_Pic (float x, float y, char *picname, float width, float height, float red, float green, float blue, float alpha, int flags)
{
glpic_t *gl;
qpic_t *pic = Draw_CachePic(picname);
gl = (glpic_t *)pic->data;
glColor4f (red,green,blue,alpha);
glBindTexture (GL_TEXTURE_2D, gl->texnum);
glBegin (GL_QUADS);
glTexCoord2f (gl->sl, gl->tl);
glVertex2f (x, y);
glTexCoord2f (gl->sh, gl->tl);
glVertex2f (x+width, y);
glTexCoord2f (gl->sh, gl->th);
glVertex2f (x+width, y+height);
glTexCoord2f (gl->sl, gl->th);
glVertex2f (x, y+height);
glEnd ();
glColor4f (1,1,1,1);//Draw_AlphaPic()
}
int COM_FileExists(char *filename);
void AutomapOnDraw ();
void UpdateLocalMenus ()
{
int i;
char * menusel;
char nullmenu[] = "";
int y= MENUBASE;
int x= 65*0.5*menu_scale.value;
AutomapOnDraw();//Tei, move to a better location?
if (!menu_mode.value )
return;
//320x205
if (strcmp(menu_image.string,"") && COM_FileExists(menu_image.string) )
{
DrawQ_Pic(0,0, menu_image.string, 320*0.5*menu_scale.value, 205*0.5*menu_scale.value, 1, 1, 1, 0.9f, 0);
}
#define SayScreen(stringie) DrawQ_String(x,y,stringie.string,100,4*menu_scale.value,4*menu_scale.value,0.4f,1,0.4f,1,0);
#define SayNext y += 6 * menu_scale.value;
//SayScreen(menu_0);
//Title Highlithed
DrawQ_String(x,y,menu_0.string,100,4*menu_scale.value,4*menu_scale.value,0.5f,1,0.5f,1,0);
SayNext;
SayNext;
SayScreen(menu_1);
SayNext;
SayScreen(menu_2);
SayNext;
SayScreen(menu_3);
SayNext;
SayScreen(menu_4);
SayNext;
SayScreen(menu_5);
SayNext;
SayScreen(menu_6);
SayNext;
SayScreen(menu_7);
SayNext;
SayScreen(menu_8);
SayNext;
SayScreen(menu_9);
if(menu_select.value)
{
y= MENUBASE + 6*menu_scale.value * (menu_select.value+1);
switch (i=menu_select.value)//a ugly way to pass a integer
{
case 0:
menusel = nullmenu;
break;
case 1:
menusel = menu_1.string;
break;
case 2:
menusel = menu_2.string;
break;
case 3:
menusel = menu_3.string;
break;
case 4:
menusel = menu_4.string;
break;
case 5:
menusel = menu_5.string;
break;
case 6:
menusel = menu_6.string;
break;
case 7:
menusel = menu_7.string;
break;
case 8:
menusel = menu_8.string;
break;
case 9:
menusel = menu_9.string;
break;
default:
menusel = nullmenu;
break;
}
DrawQ_String(x,y,menusel,100,4*menu_scale.value,4*menu_scale.value,1,1,1,1,0);
DrawQ_String(x-4*menu_scale.value,y,"\x8d",100,4*menu_scale.value,4*menu_scale.value,1,1,1,1,0);
}
}
// -------------------------------------------------
typedef struct automap_s
{
float height;//solid = 4096
} automap_t;
#define AUTOMAPX 200
#define AUTOMAPY AUTOMAPX
automap_t automap[AUTOMAPX][AUTOMAPY];
#define MAXMAP 4096
//#define CONTENTS_EMPTY -1
int HeightMapInt(int x, int y)
{
vec3_t org;
int c,t;
org[0]=x;
org[1]=y;
org[2]=0;
if (SV_PointContents (org) != CONTENTS_EMPTY)
return 4000;
for(t=0;t<200;t++)
{
org[2] -= 32;
c = SV_PointContents (org);
if(c!=CONTENTS_EMPTY)
return org[2];
}
return org[2];
};
float TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
float TTraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
float playerz;
float HeightMapFloat(int x, int y)
{
vec3_t org, end, dumy;
float f;
org[0]=x;
org[1]=y;
org[2]=playerz;
VectorCopy( org, end);
end[2] = -4096;
f = TTraceLine( org, end, dumy,dumy);
return f;
};
void UpdateHeight(int i, int j)
{
automap[i][j].height = HeightMapFloat( i*40-4000,j*40-4000);
}
float GetHeight(int i, int j)
{
bound(0,i,200);
bound(0,j,200);
return automap[i][j].height;
}
void FillAutoMap ()
{
int i,j;
playerz = cl_entities[cl.viewentity].origin[2];
for (i=0; i<AUTOMAPX;i++)
{
for (j=0; j<AUTOMAPY;j++)
{
//automap[i][j].height = HeightMapInt( i*MAXMAP-(MAXMAP/2),j*MAXMAP-(MAXMAP/2));
UpdateHeight(i,j);
}
}
};
void Draw_Pixel (int x, int y, float c)
{
/* if (c<0.25)
glColor3f (0,c,0);
else
if (c<0.5)
glColor3f(c,c,0);
else*/
glColor3f(c,c,c);
glVertex2f (x,y);
//glVertex2f (x+w, y);
//glVertex2f (x+w, y+h);
//glVertex2f (x, y+h);
}
void PixelToOrigin(int *x, int *y)
{
x[0] = x[0] * 40 - 4000;
y[0] = y[0] * 40 - 4000;
};
void OriginToPixels(float *x, float *y)
{
// x[0] = x[0]/40 + 4000;
// y[0] = y[0]/40 + 4000;
x[0] = 200 - (x[0]+4000)/40;
y[0] = (y[0]+4000)/40;
};
void MatrixWPOnDraw();
void GlobalDrawLinks();
int tics;
void AutomapOnDraw ()
{
int i,j;
float c;
vec3_t red,loc;
red[0]=red[1]=red[2]=255;
// MatrixWPOnDraw();
GlobalDrawLinks();
if (!minimap.value)
return;
glDisable (GL_TEXTURE_2D);
glBegin(GL_POINTS);
//rot = cl_entities[cl.viewentity].angles[1];
//Con_Printf("rot: %f\n",rot);
//glRotatef(rot,1,0,0);
for (i=0; i<AUTOMAPX;i++)
{
for (j=0; j<AUTOMAPY;j++)
{
c = automap[i][j].height;
if (c!=1)
//Draw_Fill ( AUTOMAPX-i, j, 2, 2, bound(0,255 * c,255));
Draw_Pixel ( AUTOMAPX-i, j, c);
}
}
loc[0] = cl_entities[cl.viewentity].origin[0];
loc[1] = cl_entities[cl.viewentity].origin[1];
//Con_Printf("pp1 %f, p2 %f \n",loc[0],loc[1]);
OriginToPixels(&loc[0],&loc[1]);
//Con_Printf("p1 %f, p2 %f \n",loc[0],loc[1]);
Draw_Pixel ( loc[0], loc[1], 1);
Draw_Pixel ( loc[0]-1, loc[1], 1);
Draw_Pixel ( loc[0]+1, loc[1], 1);
Draw_Pixel ( loc[0], loc[1]-1, 1);
Draw_Pixel ( loc[0], loc[1]+1, 1);
glEnd();
glColor3f (1,1,1);
glEnable (GL_TEXTURE_2D);
if (minimap.value == 2)//Autoupdate 1
{
playerz = cl_entities[cl.viewentity].origin[2];
UpdateHeight(200-lhrandom(loc[0]-2,loc[0]+2),lhrandom(loc[1]-2,loc[1]+2));
}
else
if (minimap.value == 3)
{
//Con_Printf("p1 %f, p2 %f \n",200-loc[0],loc[1]);
tics++;
if ( GetHeight(200-loc[0],loc[1]) == 1 && lhrandom(0,10)<5 && tics>50)
{
tics = 0;
RunAutomap_f();
}
}
}
// - - - - - - - -
//
// RouteBuilder Approach 1
//
typedef struct waypoint_s
{
vec3_t self;//solid = 4096
vec3_t target;
int link;
int points;
qboolean free;
} waypoint_t;
#define MAX_WP 200
waypoint_t wpmap[MAX_WP];
waypoint_t target;
#define MINDIS 155
#define MAXDIS 200
void NewWP(int i)
{
wpmap[i].free = true;
wpmap[i].link = 0;
wpmap[i].points = 0;
}
void ClearWP()
{
int i;
for(i=1; i<MAX_WP;i++)
{
NewWP(i);
}
}
int GetNextWP()
{
int i;
for(i=1; i<MAX_WP;i++)
{
if (wpmap[i].free)
return i;
}
return 0;
}
int GetFreeWP()
{
int i;
for(i=1; i<MAX_WP;i++)
{
if (wpmap[i].free)
return i;
}
i = lhrandom(1,MAX_WP-1);//force!
NewWP(i);
return i;
}
int SmartGetFreeWP()
{
int i;
int maxpoints = 1000;
int selected = 0;
for(i=1; i<MAX_WP;i++)
{
if (wpmap[i].free)
return i;
}
for(i=1; i<MAX_WP;i++)
{
if (wpmap[i].points<maxpoints)
{
maxpoints = wpmap[i].points;
selected = i;
}
}
if (!selected)
selected = GetFreeWP();
//NewWP(selected);
return selected;
}
void WPSet(int i,vec3_t self, vec3_t target)
{
if (!i) return;
VectorCopy(self, wpmap[i].self);
VectorCopy(target, wpmap[i].target);
// Con_Printf("t1: %f,.%f..\n",wpmap[i].self[0],wpmap[i].target[0]);
wpmap[i].free = false;
}
void R_BeamColor (vec3_t origin, vec3_t end,vec3_t color);
void MatrixWPOnDraw()
{
vec3_t color;
int i;
color[0] = color[1] = color[2] = 255;
for(i=1; i<MAX_WP;i++)
{
if (!wpmap[i].free)
R_BeamColor(wpmap[i].self,wpmap[i].target,color);
}
}
cvar_t telecheat_x,telecheat_y,telecheat_z;
void WPStart_f(void)
{
int i;
Con_Printf("Init WP Matrix\n");
ClearWP();
VectorCopy(cl_entities[cl.viewentity].origin,target.self);
target.target[0] = telecheat_x.value;
target.target[1] = telecheat_y.value;
target.target[2] = telecheat_z.value;
i = GetFreeWP();
if (!i) return;
WPSet(i,target.self,target.target);
}
void WPAdd( vec3_t self, vec3_t target)
{
int i;
i = GetFreeWP();
if (!i) return;
WPSet(i,self,target);
}
int GetNearestWP(vec3_t target)
{
int i,dx, min;
vec3_t vdx;
int selected=0;
min = 8192;
for(i=1; i<MAX_WP;i++)
{
if( wpmap[i].free)
continue;
if( VectorCompare(target,wpmap[i].self) )
continue;
VectorSubtract(target, wpmap[i].self, vdx);
dx = Length(vdx);
if (dx < min)
{
min = dx;
selected = i;
}
}
return selected;
}
void RecurseIncPointsWP(int i)
{
if(!i) return;
wpmap[i].points ++;
if(wpmap[i].link)
RecurseIncPointsWP(wpmap[i].link);
}
void WPAddSmart( vec3_t self, vec3_t target)
{
int i,j, dx,dx2;
vec3_t vdx;
// trace_t trace;
if(Length(self)<10 ||Length(target)<10 )
return;
VectorSubtract(self,target,vdx);
dx2 = Length(vdx);
if(dx2 <MINDIS)
return;// Not needed
if (dx2> MAXDIS) //Too long
{
i = GetNearestWP(self); //get nearest
if (!i) return;
VectorSubtract(self,wpmap[i].self,vdx);
dx = Length(vdx);
if (dx<MINDIS || dx>MAXDIS)
{
return;
}
VectorSubtract(wpmap[i].self,target,vdx);
dx = Length(vdx);
if (dx>dx2)
{
return; //not better
}
//Is valid, set to it
j = SmartGetFreeWP();
if (!j) return;
WPSet(j,self,wpmap[i].self);
wpmap[j].link = i;
wpmap[j].points =1 ;
RecurseIncPointsWP( j);
return;
}
i = SmartGetFreeWP();
if (!i) return;
WPSet(i,self,target);
wpmap[i].points = 1;//Start for direct location route
}
// Approach 2
#define MAXLINKS 8
typedef struct map_s
{
vec3_t org;
vec3_t wp;
qboolean free;
float ncode;
struct map_s * links[MAXLINKS];
int numlinks;
} map_t;
#define SCALEX 50
map_t map[SCALEX][SCALEX];
void UpdateMap(int x, int y)
{
vec3_t end, normal, impact;
float f;
map[x][y].numlinks = 0;
map[x][y].org[0]=x * 80 * 2 - 4000*2;
map[x][y].org[1]=y * 80 * 2- 4000*2;
map[x][y].org[2]=playerz;
VectorCopy( map[x][y].org, end);
end[2] = -4096;
f = TTraceLine( map[x][y].org, end, impact,normal);
if (f==1)
map[x][y].free = false;
else
map[x][y].free = true;
impact[2] += 16;
VectorCopy( impact, map[x][y].wp );
map[x][y].ncode = normal[0]+normal[1]+normal[2];
};
void GlobalUpdate ()
{
int j,k;
for(j=0;j<SCALEX;j++)
for(k=0;k<SCALEX;k++)
UpdateMap(j,k);
}
int TestLink(map_t * m1, map_t * m2)
{
vec3_t dumy, dif, med, meddown;
float len, hdif;
float testdown;
if ((!m1->free) || (!m2->free))
return false;
if( TTraceLine( m1->wp, m2->wp, dumy,dumy)<1 )
return false;
VectorSubtract(m1->wp, m2->wp, dif);
len = Length(dif);
if (len>190)//165
return false;
hdif = fabs( m1->wp[2] - m2->wp[2]);
//if(hdif> 64)
// return false;
if (hdif>16)
testdown = 32;
else
testdown = 64;
//return false;
VectorMA(m1->wp,0.5,dif,med);
VectorCopy(med, meddown);
meddown[2] -= testdown;
if( TTraceLine( med, meddown, dumy,dumy)==1 )
return false;
#define DXZONE 64
VectorCopy(m2->wp, dumy);
dumy[0] += DXZONE;
dumy[1] += DXZONE;
if (SV_PointContents(dumy)!=CONTENTS_EMPTY)
return false;
VectorCopy(m2->wp, dumy);
dumy[0] -= DXZONE;
dumy[1] -= DXZONE;
if (SV_PointContents(dumy)!=CONTENTS_EMPTY)
return false;
VectorCopy(m2->wp, dumy);
dumy[0] -= DXZONE;
dumy[1] += DXZONE;
if (SV_PointContents(dumy)!=CONTENTS_EMPTY)
return false;
VectorCopy(m2->wp, dumy);
dumy[0] += DXZONE;
dumy[1] -= DXZONE;
if (SV_PointContents(dumy)!=CONTENTS_EMPTY)
return false;
return true;
};
void DoLink(map_t *m1, map_t *m2)
{
if (m1->numlinks >= MAXLINKS)
return;
m1->links[m1->numlinks] = m2;
m1->numlinks ++;
}
#define TESTLINK(m1,m2) if (TestLink(m1,m2)) {DoLink(m1,m2);DoLink(m2,m1);};
void RandomLink ()
{
int j, k;
map_t * m1, *m2;
k =lhrandom(1,SCALEX-1);
j =lhrandom(1,SCALEX-1);
m1 = & map[j][k];
m2 = & map[j-1][k-1];TESTLINK(m1,m2);
m2 = & map[j-1][k];TESTLINK(m1,m2);
m2 = & map[j-1][k+1];TESTLINK(m1,m2);
m2 = & map[j+1][k-1];TESTLINK(m1,m2);
m2 = & map[j+1][k];TESTLINK(m1,m2);
m2 = & map[j+1][k+1];TESTLINK(m1,m2);
m2 = & map[j][k-1];TESTLINK(m1,m2);
m2 = & map[j][k+1];TESTLINK(m1,m2);
}
void DrawLinks(map_t *m)
{
vec3_t color;
int j;
if (!m->free)
return;
if (!m->numlinks)
return;
color[0] = color[1] = color[2] = 255;
for(j =0;j< m->numlinks;j++)
{
if(lhrandom(0,100)<10)
R_BeamColor(m->wp,m->links[j]->wp ,color);
//glVertex3fv (m->wp);
//glVertex3fv (m->links[j]->wp);
//glLine(m->wp, m->links[j]->wp, 1,1,1);
//Con_Printf("hello drawlink\n");
}
};
void GlobalDrawLinks()
{
int j,k;
RandomLink ();
//glDisable(GL_DEPTH_TEST);
//glEnable(GL_TEXTURE_2D);
//glDisable(GL_TEXTURE_2D);
//glBegin(GL_LINES);
//glColor3f (1,1,1);
for(j=0;j<SCALEX;j++)
for(k=0;k<SCALEX;k++)
DrawLinks(&map[j][k]);
//glEnd();
//glEnable(GL_TEXTURE_2D);
}