1153 lines
21 KiB
C
1153 lines
21 KiB
C
|
|
||
|
/*
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|