1#include "client.qh" 2#include "common.qh" 3 4#if defined(CSQC) 5 #include <client/autocvars.qh> 6 #include <lib/csqcmodel/cl_model.qh> 7#elif defined(MENUQC) 8#elif defined(SVQC) 9#endif 10 11void WarpZone_Fade_PreDraw(entity this) 12{ 13 vector org; 14 org = getpropertyvec(VF_ORIGIN); 15 if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones 16 this.alpha = 0; 17 else if(this.warpzone_fadestart) 18 this.alpha = bound(0, (this.warpzone_fadeend - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.warpzone_fadeend - this.warpzone_fadestart), 1); 19 else 20 this.alpha = 1; 21 //printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs)); 22 if(this.alpha <= 0) 23 this.drawmask = 0; 24 else 25 this.drawmask = MASK_NORMAL; 26} 27 28void WarpZone_Touch(entity this, entity toucher); 29NET_HANDLE(ENT_CLIENT_WARPZONE, bool isnew) 30{ 31 warpzone_warpzones_exist = 1; 32 if (!this.enemy) 33 { 34 this.enemy = new(warpzone_from); 35 } 36 this.classname = "trigger_warpzone"; 37 38 if(isnew) 39 IL_PUSH(g_warpzones, this); 40 41 int f = ReadByte(); 42 this.warpzone_isboxy = (f & 1); 43 if(f & 4) 44 { 45 this.origin_x = ReadCoord(); 46 this.origin_y = ReadCoord(); 47 this.origin_z = ReadCoord(); 48 } 49 else 50 this.origin = '0 0 0'; 51 this.modelindex = ReadShort(); 52 this.mins_x = ReadCoord(); 53 this.mins_y = ReadCoord(); 54 this.mins_z = ReadCoord(); 55 this.maxs_x = ReadCoord(); 56 this.maxs_y = ReadCoord(); 57 this.maxs_z = ReadCoord(); 58 this.scale = ReadByte() / 16; 59 this.enemy.oldorigin_x = ReadCoord(); 60 this.enemy.oldorigin_y = ReadCoord(); 61 this.enemy.oldorigin_z = ReadCoord(); 62 this.enemy.avelocity_x = ReadCoord(); 63 this.enemy.avelocity_y = ReadCoord(); 64 this.enemy.avelocity_z = ReadCoord(); 65 this.oldorigin_x = ReadCoord(); 66 this.oldorigin_y = ReadCoord(); 67 this.oldorigin_z = ReadCoord(); 68 this.avelocity_x = ReadCoord(); 69 this.avelocity_y = ReadCoord(); 70 this.avelocity_z = ReadCoord(); 71 72 if(f & 2) 73 { 74 this.warpzone_fadestart = ReadShort(); 75 this.warpzone_fadeend = max(this.warpzone_fadestart + 1, ReadShort()); 76 } 77 else 78 { 79 this.warpzone_fadestart = 0; 80 this.warpzone_fadeend = 0; 81 } 82 83 // common stuff 84 WarpZone_SetUp(this, this.enemy.oldorigin, this.enemy.avelocity, this.oldorigin, this.avelocity); 85 86 // link me 87 //setmodel(this, this.model); 88 setorigin(this, this.origin); 89 setsize(this, this.mins, this.maxs); 90 91 // how to draw 92 // engine currently wants this 93 setpredraw(this, WarpZone_Fade_PreDraw); 94 95 //settouch(this, WarpZone_Touch); 96 return true; 97} 98 99NET_HANDLE(ENT_CLIENT_WARPZONE_CAMERA, bool isnew) 100{ 101 warpzone_cameras_exist = 1; 102 this.classname = "func_warpzone_camera"; 103 104 int f = ReadByte(); 105 if(f & 4) 106 { 107 this.origin_x = ReadCoord(); 108 this.origin_y = ReadCoord(); 109 this.origin_z = ReadCoord(); 110 } 111 else 112 this.origin = '0 0 0'; 113 this.modelindex = ReadShort(); 114 this.mins_x = ReadCoord(); 115 this.mins_y = ReadCoord(); 116 this.mins_z = ReadCoord(); 117 this.maxs_x = ReadCoord(); 118 this.maxs_y = ReadCoord(); 119 this.maxs_z = ReadCoord(); 120 this.scale = ReadByte() / 16; 121 this.oldorigin_x = ReadCoord(); 122 this.oldorigin_y = ReadCoord(); 123 this.oldorigin_z = ReadCoord(); 124 this.avelocity_x = ReadCoord(); 125 this.avelocity_y = ReadCoord(); 126 this.avelocity_z = ReadCoord(); 127 128 if(f & 2) 129 { 130 this.warpzone_fadestart = ReadShort(); 131 this.warpzone_fadeend = max(this.warpzone_fadestart + 1, ReadShort()); 132 } 133 else 134 { 135 this.warpzone_fadestart = 0; 136 this.warpzone_fadeend = 0; 137 } 138 139 // common stuff 140 WarpZone_Camera_SetUp(this, this.oldorigin, this.avelocity); 141 142 // engine currently wants this 143 this.drawmask = MASK_NORMAL; 144 145 // link me 146 //setmodel(this, this.model); 147 setorigin(this, this.origin); 148 setsize(this, this.mins, this.maxs); 149 150 // how to draw 151 // engine currently wants this 152 setpredraw(this, WarpZone_Fade_PreDraw); 153 return true; 154} 155 156void CL_RotateMoves(vector ang) = #638; 157NET_HANDLE(ENT_CLIENT_WARPZONE_TELEPORTED, bool isnew) 158{ 159 this.classname = "warpzone_teleported"; 160 vector v; 161 v.x = ReadCoord(); 162 v.y = ReadCoord(); 163 v.z = ReadCoord(); 164 return = true; 165 if (!isnew) return; 166 this.warpzone_transform = v; 167 setproperty(VF_CL_VIEWANGLES, WarpZone_TransformVAngles(this, getpropertyvec(VF_CL_VIEWANGLES))); 168 if(checkextension("DP_CSQC_ROTATEMOVES")) 169 CL_RotateMoves(v); 170 //CL_RotateMoves('0 90 0'); 171} 172 173float warpzone_fixingview; 174float warpzone_fixingview_drawexteriormodel; 175 176void WarpZone_View_Outside() 177{ 178 if(!warpzone_fixingview) 179 return; 180 warpzone_fixingview = 0; 181 cvar_set("r_drawexteriormodel", ftos(warpzone_fixingview_drawexteriormodel)); 182} 183 184void WarpZone_View_Inside() 185{ 186 if(autocvar_chase_active) 187 { 188 WarpZone_View_Outside(); 189 return; 190 } 191 if(warpzone_fixingview) 192 return; 193 warpzone_fixingview = 1; 194 warpzone_fixingview_drawexteriormodel = cvar("r_drawexteriormodel"); 195 cvar_set("r_drawexteriormodel", "0"); 196} 197 198vector WarpZone_FixNearClip(vector o, vector c0, vector c1, vector c2, vector c3) 199{ 200 vector mi, ma; 201 entity e; 202 float pd; 203 204 mi.x = min(o.x, c0_x, c1_x, c2_x, c3_x); 205 ma.x = max(o.x, c0_x, c1_x, c2_x, c3_x); 206 mi.y = min(o.y, c0_y, c1_y, c2_y, c3_y); 207 ma.y = max(o.y, c0_y, c1_y, c2_y, c3_y); 208 mi.z = min(o.z, c0_z, c1_z, c2_z, c3_z); 209 ma.z = max(o.z, c0_z, c1_z, c2_z, c3_z); 210 211 e = WarpZone_Find(mi, ma); 212 if(e) 213 { 214 if(WarpZone_PlaneDist(e, o) < 0) 215 return '0 0 0'; 216 // can't really be, though, but if it is, this is not my warpzone, but a random different one in the same mins/maxs 217 pd = min( 218 WarpZone_PlaneDist(e, c0), 219 WarpZone_PlaneDist(e, c1), 220 WarpZone_PlaneDist(e, c2), 221 WarpZone_PlaneDist(e, c3) 222 ); 223 if(pd < 0) 224 return e.warpzone_forward * -pd; 225 } 226 227 return '0 0 0'; 228} 229 230void WarpZone_FixPMove() 231{ 232 entity e = WarpZone_Find(pmove_org, pmove_org); 233 if(e) 234 { 235 pmove_org = WarpZone_TransformOrigin(e, pmove_org); 236 input_angles = WarpZone_TransformVAngles(e, input_angles); 237 } 238} 239 240#ifndef KEEP_ROLL 241float autocvar_cl_rollkillspeed = 10; 242#endif 243void WarpZone_FixView() 244{ 245 entity e; 246 vector org, ang, nearclip, corner0, corner1, corner2, corner3, o; 247 248 warpzone_save_view_origin = org = getpropertyvec(VF_ORIGIN); 249 warpzone_save_view_angles = ang = getpropertyvec(VF_ANGLES); 250 251 e = WarpZone_Find(org, org); 252 if(e) 253 { 254 org = WarpZone_TransformOrigin(e, org); 255 ang = WarpZone_TransformVAngles(e, ang); 256 WarpZone_View_Inside(); 257 } 258 else 259 WarpZone_View_Outside(); 260 261#ifndef KEEP_ROLL 262 float rick; 263 float f; 264 static float rollkill; 265 if (STAT(HEALTH) > 0 || STAT(HEALTH) == -666 || STAT(HEALTH) == -2342) 266 { 267 f = 0; 268 // reset roll when passing through a warpzone that change player's roll angle 269 if(autocvar_cl_rollkillspeed) 270 f = max(0, (1 - frametime * autocvar_cl_rollkillspeed)); 271 if(rollkill) 272 rollkill = 0; 273 } 274 else 275 { 276 f = 1; 277 // roll the view when killed (v_deathtilt) 278 if(autocvar_cl_rollkillspeed) 279 { 280 rollkill += frametime * autocvar_cl_rollkillspeed; 281 f = min(1, rollkill); 282 } 283 else if(rollkill) 284 rollkill = 0; 285 } 286 287 rick = getproperty(VF_CL_VIEWANGLES_Z); 288 rick *= f; 289 setproperty(VF_CL_VIEWANGLES_Z, rick); 290 ang.z *= f; 291#endif 292 293 setproperty(VF_ORIGIN, org); 294 setproperty(VF_ANGLES, ang); 295 296 nearclip = '0 0 1' * (cvar("r_nearclip") * 1.125); 297 corner0 = cs_unproject('0 0 0' + nearclip); 298 corner1 = cs_unproject('1 0 0' * cvar("vid_conwidth") + nearclip); 299 corner2 = cs_unproject('0 1 0' * cvar("vid_conheight") + nearclip); 300 corner3 = cs_unproject('1 0 0' * cvar("vid_conwidth") + '0 1 0' * cvar("vid_conheight") + nearclip); 301 o = WarpZone_FixNearClip(org, corner0, corner1, corner2, corner3); 302 if(o != '0 0 0') 303 setproperty(VF_ORIGIN, org + o); 304} 305 306void WarpZone_Shutdown() 307{ 308 WarpZone_View_Outside(); 309} 310