public static void R_LavaSplash(ref Vector3 org) { Vector3 dir; for (int i = -16; i < 16; i++) { for (int j = -16; j < 16; j++) { for (int k = 0; k < 1; k++) { particle_t p = AllocParticle(); if (p == null) { return; } p.die = (float)(cl.time + 2 + (Random() & 31) * 0.02); p.color = 224 + (Random() & 7); p.type = ptype_t.pt_slowgrav; dir.X = j * 8 + (Random() & 7); dir.Y = i * 8 + (Random() & 7); dir.Z = 256; p.org = org + dir; p.org.Z += Random() & 63; Mathlib.Normalize(ref dir); float vel = 50 + (Random() & 63); p.vel = dir * vel; } } } }
public static void SV_AirAccelerate(Vector3 wishveloc) { float wishspd = Mathlib.Normalize(ref wishveloc); if (wishspd > 30) { wishspd = 30; } float currentspeed = Vector3.Dot(ToVector(ref sv_player.v.velocity), wishveloc); float addspeed = wishspd - currentspeed; if (addspeed <= 0) { return; } float accelspeed = (float)(sv_accelerate.value * wishspeed * host_framtime); if (accelspeed > addspeed) { accelspeed = addspeed; } wishveloc *= accelspeed; sv_player.v.velocity.x += wishveloc.X; sv_player.v.velocity.y += wishveloc.Y; sv_player.v.velocity.z += wishveloc.Z; }
public static void R_TeleportSplash(ref Vector3 org) { for (int i = -16; i < 16; i += 4) { for (int j = -16; j < 16; j += 4) { for (int k = -24; k < 32; k += 4) { particle_t p = AllocParticle(); if (p == null) { return; } p.die = (float)(cl.time + 0.2 + (Random() & 7) * 0.02); p.color = 7 + (Random() & 7); p.type = ptype_t.pt_slowgrav; Vector3 dir = new Vector3(j * 8, i * 8, k * 8); p.org = org + new Vector3(i + (Random() & 3), j + (Random() & 3), k + (Random() & 3)); Mathlib.Normalize(ref dir); float vel = 50 + (Random() & 63); p.vel = dir * vel; } } } }
static unsafe void PF_normalize() { float * value1 = G_VECTOR(q_shared.OFS_PARM0); Vector3 tmp; Copy(value1, out tmp); Mathlib.Normalize(ref tmp); G_VECTOR(ref tmp); }
public static void DropPunchAngle() { Vector3 v = ToVector(ref sv_player.v.punchangle); double len = Mathlib.Normalize(ref v) - 10 * host_framtime; if (len < 0) { len = 0; } v *= (float)len; Mathlib.Copy(ref v, out sv_player.v.punchangle); }
public static bool IsCollinear(float[] prev, float[] cur, float[] next) { Vector3 v1 = new Vector3(cur[0] - prev[0], cur[1] - prev[1], cur[2] - prev[2]); Mathlib.Normalize(ref v1); Vector3 v2 = new Vector3(next[0] - prev[0], next[1] - prev[1], next[2] - prev[2]); Mathlib.Normalize(ref v2); v1 -= v2; return((Math.Abs(v1.X) <= q_shared.COLINEAR_EPSILON) && (Math.Abs(v1.Y) <= q_shared.COLINEAR_EPSILON) && (Math.Abs(v1.Z) <= q_shared.COLINEAR_EPSILON)); }
public static void SV_AirMove() { Vector3 pangles = ToVector(ref sv_player.v.angles); Mathlib.AngleVectors(ref pangles, out forward, out right, out up); float fmove = cmd.forwardmove; float smove = cmd.sidemove; // hack to not let you back into teleporter if (sv.time < sv_player.v.teleport_time && fmove < 0) { fmove = 0; } Vector3 wishvel = forward * fmove + right * smove; if ((int)sv_player.v.movetype != q_shared.MOVETYPE_WALK) { wishvel.Z = cmd.upmove; } else { wishvel.Z = 0; } wishdir = wishvel; wishspeed = Mathlib.Normalize(ref wishdir); if (wishspeed > sv_maxspeed.value) { wishvel *= sv_maxspeed.value / wishspeed; wishspeed = sv_maxspeed.value; } if (sv_player.v.movetype == q_shared.MOVETYPE_NOCLIP) { // noclip Mathlib.Copy(ref wishvel, out sv_player.v.velocity); } else if (onground) { SV_UserFriction(); SV_Accelerate(); } else { // not on ground, so little effect on velocity SV_AirAccelerate(wishvel); } }
static void SND_Spatialize(channel_t ch) { // anything coming from the view entity will allways be full volume if (ch.entnum == cl.viewentity) { ch.leftvol = ch.master_vol; ch.rightvol = ch.master_vol; return; } // calculate stereo seperation and distance attenuation sfx_t snd = ch.sfx; Vector3 source_vec = ch.origin - listener_origin; float dist = Mathlib.Normalize(ref source_vec) * ch.dist_mult; float dot = Vector3.Dot(listener_right, source_vec); float rscale, lscale; if (shm.channels == 1) { rscale = 1.0f; lscale = 1.0f; } else { rscale = 1.0f + dot; lscale = 1.0f - dot; } // add in distance effect float scale = (1.0f - dist) * rscale; ch.rightvol = (int)(ch.master_vol * scale); if (ch.rightvol < 0) { ch.rightvol = 0; } scale = (1.0f - dist) * lscale; ch.leftvol = (int)(ch.master_vol * scale); if (ch.leftvol < 0) { ch.leftvol = 0; } }
public static void V_ParseDamage() { int armor = Reader.MSG_ReadByte(); int blood = Reader.MSG_ReadByte(); Vector3 from = Reader.ReadCoords(); float count = blood * 0.5f + armor * 0.5f; if (count < 10) { count = 10; } cl.faceanimtime = (float)cl.time + 0.2f; // put sbar face into pain frame cl.cshifts[q_shared.CSHIFT_DAMAGE].percent += (int)(3 * count); if (cl.cshifts[q_shared.CSHIFT_DAMAGE].percent < 0) { cl.cshifts[q_shared.CSHIFT_DAMAGE].percent = 0; } if (cl.cshifts[q_shared.CSHIFT_DAMAGE].percent > 150) { cl.cshifts[q_shared.CSHIFT_DAMAGE].percent = 150; } if (armor > blood) { cl.cshifts[q_shared.CSHIFT_DAMAGE].destcolor[0] = 200; cl.cshifts[q_shared.CSHIFT_DAMAGE].destcolor[1] = 100; cl.cshifts[q_shared.CSHIFT_DAMAGE].destcolor[2] = 100; } else if (armor != 0) { cl.cshifts[q_shared.CSHIFT_DAMAGE].destcolor[0] = 220; cl.cshifts[q_shared.CSHIFT_DAMAGE].destcolor[1] = 50; cl.cshifts[q_shared.CSHIFT_DAMAGE].destcolor[2] = 50; } else { cl.cshifts[q_shared.CSHIFT_DAMAGE].destcolor[0] = 255; cl.cshifts[q_shared.CSHIFT_DAMAGE].destcolor[1] = 0; cl.cshifts[q_shared.CSHIFT_DAMAGE].destcolor[2] = 0; } // // calculate view angle kicks // entity_t ent = cl_entities[cl.viewentity]; from -= ent.origin; // VectorSubtract (from, ent->origin, from); Mathlib.Normalize(ref from); Vector3 forward, right, up; Mathlib.AngleVectors(ref ent.angles, out forward, out right, out up); float side = Vector3.Dot(from, right); v_dmg_roll = count * side * v_kickroll.value; side = Vector3.Dot(from, forward); v_dmg_pitch = count * side * v_kickpitch.value; v_dmg_time = v_kicktime.value; }
static void PF_aim() { edict_t ent = G_EDICT(q_shared.OFS_PARM0); float speed = G_FLOAT(q_shared.OFS_PARM1); Vector3 start = ToVector(ref ent.v.origin); start.Z += 20; // try sending a trace straight Vector3 dir; Mathlib.Copy(ref pr_global_struct.v_forward, out dir); Vector3 end = start + dir * 2048; trace_t tr = SV_Move(ref start, ref q_shared.ZeroVector, ref q_shared.ZeroVector, ref end, 0, ent); if (tr.ent != null && tr.ent.v.takedamage == q_shared.DAMAGE_AIM && (teamplay.value == 0 || ent.v.team <= 0 || ent.v.team != tr.ent.v.team)) { G_VECTOR(ref pr_global_struct.v_forward); return; } // try all possible entities Vector3 bestdir = dir; float bestdist = sv_aim.value; edict_t bestent = null; for (int i = 1; i < sv.num_edicts; i++) { edict_t check = sv.edicts[i]; if (check.v.takedamage != q_shared.DAMAGE_AIM) { continue; } if (check == ent) { continue; } if (teamplay.value != 0 && ent.v.team > 0 && ent.v.team == check.v.team) { continue; // don't aim at teammate } v3f tmp; Mathlib.VectorAdd(ref check.v.mins, ref check.v.maxs, out tmp); Mathlib.VectorMA(ref check.v.origin, 0.5f, ref tmp, out tmp); Mathlib.Copy(ref tmp, out end); dir = end - start; Mathlib.Normalize(ref dir); float dist = Vector3.Dot(dir, ToVector(ref pr_global_struct.v_forward)); if (dist < bestdist) { continue; // to far to turn } tr = SV_Move(ref start, ref q_shared.ZeroVector, ref q_shared.ZeroVector, ref end, 0, ent); if (tr.ent == check) { // can shoot at this one bestdist = dist; bestent = check; } } if (bestent != null) { v3f dir2, end2; Mathlib.VectorSubtract(ref bestent.v.origin, ref ent.v.origin, out dir2); float dist = Mathlib.DotProduct(ref dir2, ref pr_global_struct.v_forward); Mathlib.VectorScale(ref pr_global_struct.v_forward, dist, out end2); end2.z = dir2.z; Mathlib.Normalize(ref end2); G_VECTOR(ref end2); } else { G_VECTOR(ref bestdir); } }
public static void R_RocketTrail(ref Vector3 start, ref Vector3 end, int type) { Vector3 vec = end - start; float len = Mathlib.Normalize(ref vec); int dec; if (type < 128) { dec = 3; } else { dec = 1; type -= 128; } while (len > 0) { len -= dec; particle_t p = AllocParticle(); if (p == null) { return; } p.vel = Vector3.Zero; p.die = (float)cl.time + 2; switch (type) { case 0: // rocket trail p.ramp = (Random() & 3); p.color = _Ramp3[(int)p.ramp]; p.type = ptype_t.pt_fire; p.org = new Vector3(start.X + ((Random() % 6) - 3), start.Y + ((Random() % 6) - 3), start.Z + ((Random() % 6) - 3)); break; case 1: // smoke smoke p.ramp = (Random() & 3) + 2; p.color = _Ramp3[(int)p.ramp]; p.type = ptype_t.pt_fire; p.org = new Vector3(start.X + ((Random() % 6) - 3), start.Y + ((Random() % 6) - 3), start.Z + ((Random() % 6) - 3)); break; case 2: // blood p.type = ptype_t.pt_grav; p.color = 67 + (Random() & 3); p.org = new Vector3(start.X + ((Random() % 6) - 3), start.Y + ((Random() % 6) - 3), start.Z + ((Random() % 6) - 3)); break; case 3: case 5: // tracer p.die = (float)cl.time + 0.5f; p.type = ptype_t.pt_static; if (type == 3) { p.color = 52 + ((_TracerCount & 4) << 1); } else { p.color = 230 + ((_TracerCount & 4) << 1); } _TracerCount++; p.org = start; if ((_TracerCount & 1) != 0) { p.vel.X = 30 * vec.Y; // Uze: why??? p.vel.Y = 30 * -vec.X; } else { p.vel.X = 30 * -vec.Y; p.vel.Y = 30 * vec.X; } break; case 4: // slight blood p.type = ptype_t.pt_grav; p.color = 67 + (Random() & 3); p.org = new Vector3(start.X + ((Random() % 6) - 3), start.Y + ((Random() % 6) - 3), start.Z + ((Random() % 6) - 3)); len -= 3; break; case 6: // voor trail p.color = 9 * 16 + 8 + (Random() & 3); p.type = ptype_t.pt_static; p.die = (float)cl.time + 0.3f; p.org = new Vector3(start.X + ((Random() % 15) - 8), start.Y + ((Random() % 15) - 8), start.Z + ((Random() % 15) - 8)); break; } start += vec; } }
public static void CL_UpdateTEnts() { num_temp_entities = 0; // update lightning for (int i = 0; i < q_shared.MAX_BEAMS; i++) { beam_t b = cl_beams[i]; if (b.model == null || b.endtime < cl.time) { continue; } // if coming from the player, update the start position if (b.entity == cl.viewentity) { b.start = cl_entities[cl.viewentity].origin; } // calculate pitch and yaw Vector3 dist = b.end - b.start; float yaw, pitch, forward; if (dist.Y == 0 && dist.X == 0) { yaw = 0; if (dist.Z > 0) { pitch = 90; } else { pitch = 270; } } else { yaw = (int)(Math.Atan2(dist.Y, dist.X) * 180 / Math.PI); if (yaw < 0) { yaw += 360; } forward = (float)Math.Sqrt(dist.X * dist.X + dist.Y * dist.Y); pitch = (int)(Math.Atan2(dist.Z, forward) * 180 / Math.PI); if (pitch < 0) { pitch += 360; } } // add new entities for the lightning Vector3 org = b.start; float d = Mathlib.Normalize(ref dist); while (d > 0) { entity_t ent = CL_NewTempEntity(); if (ent == null) { return; } ent.origin = org; ent.model = b.model; ent.angles.X = pitch; ent.angles.Y = yaw; ent.angles.Z = Random() % 360; org += dist * 30; // Uze: is this code bug (i is outer loop variable!!!) or what?????????????? //for (i=0 ; i<3 ; i++) // org[i] += dist[i]*30; d -= 30; } } }
public static void R_DrawAliasModel(entity_t e) { model_t clmodel = currententity.model; Vector3 mins = currententity.origin + clmodel.mins; Vector3 maxs = currententity.origin + clmodel.maxs; if (R_CullBox(ref mins, ref maxs)) { return; } r_entorigin = currententity.origin; modelorg = r_origin - r_entorigin; // // get lighting information // ambientlight = shadelight = R_LightPoint(ref currententity.origin); // allways give the gun some light if (e == cl.viewent && ambientlight < 24) { ambientlight = shadelight = 24; } for (int lnum = 0; lnum < q_shared.MAX_DLIGHTS; lnum++) { if (cl_dlights[lnum].die >= cl.time) { Vector3 dist = currententity.origin - cl_dlights[lnum].origin; float add = cl_dlights[lnum].radius - dist.Length; if (add > 0) { ambientlight += add; //ZOID models should be affected by dlights as well shadelight += add; } } } // clamp lighting so it doesn't overbright as much if (ambientlight > 128) { ambientlight = 128; } if (ambientlight + shadelight > 192) { shadelight = 192 - ambientlight; } // ZOID: never allow players to go totally black int playernum = Array.IndexOf(cl_entities, currententity, 0, cl.maxclients); if (playernum >= 1)// && i <= cl.maxclients) { if (ambientlight < 8) { ambientlight = shadelight = 8; } } // HACK HACK HACK -- no fullbright colors, so make torches full light if (clmodel.name == "progs/flame2.mdl" || clmodel.name == "progs/flame.mdl") { ambientlight = shadelight = 256; } shadedots = anorm_dots[((int)(e.angles.Y * (q_shared.SHADEDOT_QUANT / 360.0))) & (q_shared.SHADEDOT_QUANT - 1)]; shadelight = shadelight / 200.0f; double an = e.angles.Y / 180.0 * Math.PI; shadevector.X = (float)Math.Cos(-an); shadevector.Y = (float)Math.Sin(-an); shadevector.Z = 1; Mathlib.Normalize(ref shadevector); // // locate the proper data // aliashdr_t paliashdr = Mod_Extradata(currententity.model); c_alias_polys += paliashdr.numtris; // // draw all the triangles // GL_DisableMultitexture(); GL.PushMatrix(); R_RotateForEntity(e); if (clmodel.name == "progs/eyes.mdl" && gl_doubleeys.value != 0) { Vector3 v = paliashdr.scale_origin; v.Z -= (22 + 8); GL.Translate(v); // double size of eyes, since they are really hard to see in gl GL.Scale(paliashdr.scale * 2.0f); } else { GL.Translate(paliashdr.scale_origin); GL.Scale(paliashdr.scale); } int anim = (int)(cl.time * 10) & 3; GL_Bind(paliashdr.gl_texturenum[currententity.skinnum, anim]); // we can't dynamically colormap textures, so they are cached // seperately for the players. Heads are just uncolored. if (currententity.colormap != vid.colormap && gl_nocolors.value == 0 && playernum >= 1) { GL_Bind(playertextures - 1 + playernum); } if (gl_smoothmodels.value != 0) { GL.ShadeModel(ShadingModel.Smooth); } GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Modulate); if (gl_affinemodels.value != 0) { GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Fastest); } R_SetupAliasFrame(currententity.frame, paliashdr); GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Replace); GL.ShadeModel(ShadingModel.Flat); if (gl_affinemodels.value != 0) { GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest); } GL.PopMatrix(); if (r_shadows.value != 0) { GL.PushMatrix(); R_RotateForEntity(e); GL.Disable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.Color4(0, 0, 0, 0.5f); GL_DrawAliasShadow(paliashdr, lastposenum); GL.Enable(EnableCap.Texture2D); GL.Disable(EnableCap.Blend); GL.Color4(1f, 1, 1, 1); GL.PopMatrix(); } }
public static void SV_WaterMove() { // // user intentions // Vector3 pangle = ToVector(ref sv_player.v.v_angle); Mathlib.AngleVectors(ref pangle, out forward, out right, out up); Vector3 wishvel = forward * cmd.forwardmove + right * cmd.sidemove; if (cmd.forwardmove == 0 && cmd.sidemove == 0 && cmd.upmove == 0) { wishvel.Z -= 60; // drift towards bottom } else { wishvel.Z += cmd.upmove; } float wishspeed = wishvel.Length; if (wishspeed > sv_maxspeed.value) { wishvel *= sv_maxspeed.value / wishspeed; wishspeed = sv_maxspeed.value; } wishspeed *= 0.7f; // // water friction // float newspeed, speed = Mathlib.Length(ref sv_player.v.velocity); if (speed != 0) { newspeed = (float)(speed - host_framtime * speed * sv_friction.value); if (newspeed < 0) { newspeed = 0; } Mathlib.VectorScale(ref sv_player.v.velocity, newspeed / speed, out sv_player.v.velocity); } else { newspeed = 0; } // // water acceleration // if (wishspeed == 0) { return; } float addspeed = wishspeed - newspeed; if (addspeed <= 0) { return; } Mathlib.Normalize(ref wishvel); float accelspeed = (float)(sv_accelerate.value * wishspeed * host_framtime); if (accelspeed > addspeed) { accelspeed = addspeed; } wishvel *= accelspeed; sv_player.v.velocity.x += wishvel.X; sv_player.v.velocity.y += wishvel.Y; sv_player.v.velocity.z += wishvel.Z; }