#ifdef WORKINDP #define show_scoreboard sb_showscores #endif #define RSES_NOLERP 1 #define RSES_NOROTATE 2 #define RSES_NOTRAILS 4 #define RSES_NOLIGHTS 8 float show_scoreboard; string dbgstr; vector mousepos; void() CSQC_Shutdown = {}; //check engine extensions, and give suitable warning void() checkengineversion = { if (checkextension("FTE_STRINGS")) { isdp = substring(" ", 0, -1) == ""; if (isdp) print("broken FTE_STRINGS support\n"); } else print("no FTE_STRINGS support, this mod might crash... sorry\n"); }; float(float isnew) RefreshOther = { self.drawmask = MASK_ENGINE; setmodelindex(self, self.modelindex); if (self.entnum <= maxclients) RefreshPlayer(isnew); else if (self.colormap) self.modelindex = 0; //don't show dead bodies, we do dying ourselves. return PREDRAW_AUTOADD; }; float(string centertext) centerprinted = { //warning! //centertext is a temporary string! //warning! return false; //we don't want to handle it, let the engine do it. }; .float classnum; void(float isnew) CSQC_Ent_Update = { local float classtype; local var void(float isnew) fnc; classtype = readbyte(); //remove if the class changed. if (self.classnum != classtype) { if (self.removefunc) self.removefunc(); isnew = true; self.classnum = classtype; } fnc = ParseEntityClass[classtype]; if (!fnc) error("Unrecognised entity class: Your csqc needs updating"); fnc(isnew); // if (isnew) // print("csqc ", self.model, " updated at ", vtos(self.origin), "\n"); }; void() regcommands = { registercommand("tetris"); registercommand("skinchooser"); registercommand("randomskin"); registercommand("test"); registercommand("+showscores"); registercommand("-showscores"); registercommand("+showteamscores"); registercommand("-showteamscores"); registercommand("osgk"); registercommand("osgk_command"); registercommand("osgk_resize"); registercommand("osgk_mousemove"); registercommand("osgk_keypress"); registercommand("test_viewinfo"); }; float(string str) CSQC_ConsoleCommand = { local float args; args = tokenize(str); switch(argv(0)) { case "test": sendevent("testevent", "fsev", 64, "hello world", player_local, '73 72 71'); break; case "tetris": Menu_Tetris(); break; case "skinchooser": Menu_SkinChooser(); break; case "randomskin": SelectRandomSkin(); break; case "+showscores": show_scoreboard = 1; return false; case "+showteamscores": show_scoreboard = 2; return false; case "-showscores": case "-showteamscores": show_scoreboard = 0; return false; case "osgk": Menu_OSGK(argv(1)); break; case "osgk_command": gecko_navigate(argv(1), argv(2)); break; case "osgk_keypress": gecko_keyevent(argv(1), stof(argv(2)), 2); break; case "osgk_resize": gecko_resize(argv(1), stof(argv(2)), stof(argv(3))); break; case "osgk_mousemove": gecko_mousemove(argv(1), stof(argv(2)), stof(argv(3))); break; case "test_viewinfo": if (player_local) { print(sprintf("View origin is at %v\n", vieworg)); print(sprintf("local player entity %i is num %g on server, at %v\n", player_local, player_local.entnum, player_local.origin)); } else print("Local player entity is not known. Engine is providing the default view origin.\n"); break; default: return false; } return true; }; void(string line) CSQC_Parse_StuffCmd = { print("stufftext: ", line); localcmd(line); }; float(string msg) CSQC_Parse_CenterPrint = { print("centerprint: "); print(msg); print("\n"); cprint(msg); return false; }; void(string msg, float type) CSQC_Parse_Print = { print("print: "); print(msg); /* if (dbgstr) strunzone(dbgstr); dbgstr = strzone(msg); */ }; void() CSQC_Ent_Remove = //the ent disappeared on the server. { if (self.removefunc) self.removefunc(); remove(self); }; entity viewentity; //note that a better way of animating weapon firing would be as a response to an event, or as a clientside predicted thing. void(entity ve) DoThatViewModelThing = { float newframe, newmodel; newframe = getstatf(STAT_WEAPONFRAME); newmodel = getstatf(STAT_WEAPONMODEL); if (newmodel != ve.modelindex) { //changed entirly. ve.modelindex = newmodel; ve.frame2 = ve.frame = newframe; ve.lerptime = time; } else if (newframe != ve.frame) { ve.frame2 = ve.frame; ve.frame = newframe; ve.lerptime = time; } ve.lerpfrac = 1-(time-ve.lerptime)*10; ve.origin = '0 0 0'; ve.angles = '0 0 0'; }; void(float apilevel, string enginename, float engineversion) CSQC_Init = { __using renderflags; checkengineversion(); precache_model("progs/eyes.mdl"); precache_model("progs/player.mdl"); precache_model("progs/missile.mdl"); precache_sound("zombie/z_gib.wav"); precache_sound("player/udeath.wav"); precache_sound("weapons/r_exp3.wav"); viewentity = spawn(); viewentity.renderflags = RF_VIEWMODEL|RF_DEPTHHACK; regcommands(); if (checkextension("EXT_CSQC_1")) { // deltalisten("*", RefreshOther, 0); //catch-all deltalisten("progs/player.mdl", RefreshPlayer, RSES_NOLERP|RSES_NOROTATE); //animate players/player-corpses } }; void(entity ent) CSQC_DrawViewModel = { __using shaderforname, checkbuiltin, forceshader; if (player_local.sveffects & SVE_INVIS) { if (!checkbuiltin(shaderforname)) return; ent.forceshader = shaderforname("powerups/invisibility"); } else ent.forceshader = 0; ent.fatness = 0; DoThatViewModelThing(ent); #ifdef WORKINDP //DP doesn't support RF_VIEWMODEL //so hack around that ent.renderflags = RF_DEPTHHACK; //nope, not a view model, that just breaks things ent.origin = vieworg; ent.angles = input_angles; ent.angles_x *= autocvar(r_meshpitch, -1); #endif addentity(ent); if ((player_local.sveffects & SVE_QUAD) && checkbuiltin(shaderforname)) { ent.fatness = -2; ent.forceshader = shaderforname("powerups/quad"); addentity(ent); } if ((player_local.sveffects & SVE_GOD) && checkbuiltin(shaderforname)) { ent.fatness = -2.8; ent.forceshader = shaderforname("powerups/regen"); addentity(ent); } } //a bit of fun void() CSQC_Input_Frame = { /* if (input_buttons == 1) input_buttons = 2; else if (input_buttons == 2) input_buttons = 1;*/ }; void() CSQC_Delta_Remove = { if (self == player_local) player_local = world; // print("delt ", ftos(self.modelindex), "(", self.model, ") removed\n"); if (self.removefunc) self.removefunc(); remove(self); }; float (float event, float parama, float paramb, float paramc) CSQC_InputEvent = { if (event == IE_KEYDOWN) { switch(CVARF(cg_editor)) { case 1: if (editor_lights_key(parama, paramb)) return true; break; case 2: if (editor_terrain_key(parama, paramb)) return true; break; } } else if (event == IE_MOUSEABS) mousepos = [parama, paramb]; else if (event == IE_MOUSEDELTA) { //move it... mousepos += [parama, paramb]; //bound it. vector ssize = getviewprop(VF_SCREENVSIZE); mousepos_x = bound(0, mousepos_x, ssize_x); mousepos_y = bound(0, mousepos_y, ssize_y); } return Menu_InputEvent(event, parama, paramb); }; void(float width, float height, float do2d) CSQC_UpdateView = { float hudtype = CVARF(cg_hudtype); chasecam = CVARF(cg_thirdPerson); if (getstatf(STAT_HEALTH) <= 0) chasecam = 1; clearscene(); //force fullscreen views (ignore viewsize). setviewprop(VF_MIN, '0 0 0'); setviewprop(VF_SIZE_X, width); setviewprop(VF_SIZE_Y, height); #if 0 setviewprop(VF_MIN_X, width/2); setviewprop(VF_MIN_Y, height/2); setviewprop(VF_SIZE_X, width/2); setviewprop(VF_SIZE_Y, height/2); #endif if (hudtype != 1) { setviewprop(VF_DRAWENGINESBAR, 0); } else { setviewprop(VF_DRAWENGINESBAR, 1); } setviewprop(VF_DRAWCROSSHAIR, !player_local || !checkbuiltin(project)); addentities(MASK_NORMAL|MASK_ENGINE); if (player_local) { setviewprop(VF_ORIGIN, vieworg); setviewprop(VF_ANGLES, view_angles); makevectors(view_angles); SetListener(vieworg, v_forward, v_right, v_up); if (!chasecam) { CSQC_DrawViewModel(viewentity); } } else { //engine didn't tell us about our player entity. that's not right... addentities(MASK_ENGINEVIEWMODEL); } switch(CVARF(cg_editor)) { case 1: /*add light ents*/ editor_lights_add(); hudtype = 0; break; case 2: break; } renderscene(); if (do2d) { switch(CVARF(cg_editor)) { case 1: /*add light ents*/ editor_lights_overlay(); hudtype = 0; break; case 2: break; default: if (hudtype) Hud_Draw(hudtype, show_scoreboard, width, height); //quicky `project` test if (player_local) { if (checkbuiltin(project)) { setviewprop(VF_DRAWCROSSHAIR, 0); vector shotorg = player_local.origin+'0 0 16'; //quake is weird. traceline(shotorg, shotorg + v_forward*8192, FALSE, player_local); drawcharacter(project(trace_endpos)-'4 4', '+', '8 8', '1 1 1',1); } if (autocvar(cg_unprojecttest, FALSE)) { static float nexttime; nexttime += clframetime; drawcharacter(mousepos-'4 4', '+', '8 8', '1 1 1',1); if (nexttime > 1) { vector near = unproject([mousepos_x,mousepos_y,0]); vector far = unproject([mousepos_x,mousepos_y,1]); traceline(near, far, FALSE, player_local); te_explosion(trace_endpos); nexttime-=1; } } } break; } Menu_Think(); } if (dbgstr) { // drawrawstring('16 64 0', dbgstr, '16 16 16', '1 1 1', 0.5); // drawstring('16 80 0', dbgstr, '16 16 16', 0.5); } }; void(float vwidth, float vheight, float notmenu) CSQC_UpdateViewLoading = { drawfill([0,0],[vwidth,vheight], [0,0,0],1, 0); const vector tsize = '24 24'; string text = "CSQCTest is Loading!\nPlease wait..."; vector pos = ([vwidth,vheight]-[8,stringwidth(text,TRUE,tsize)])*0.5; drawstring(pos, text, tsize, '1 1 1',1,0); };