public static void SV_Init() { for (int i = 0; i < _BoxClipNodes.Length; i++) { _BoxClipNodes[i].children = new short[2]; } for (int i = 0; i < _BoxPlanes.Length; i++) { _BoxPlanes[i] = new mplane_t(); } for (int i = 0; i < sv_areanodes.Length; i++) { sv_areanodes[i] = new areanode_t(); } sv_friction = new cvar_t("sv_friction", "4", false, true); edgefriction = new cvar_t("edgefriction", "2"); sv_stopspeed = new cvar_t("sv_stopspeed", "100"); sv_gravity = new cvar_t("sv_gravity", "800", false, true); sv_maxvelocity = new cvar_t("sv_maxvelocity", "2000"); sv_nostep = new cvar_t("sv_nostep", "0"); sv_maxspeed = new cvar_t("sv_maxspeed", "320", false, true); sv_accelerate = new cvar_t("sv_accelerate", "10"); sv_aim = new cvar_t("sv_aim", "0.93"); sv_idealpitchscale = new cvar_t("sv_idealpitchscale", "0.8"); for (int i = 0; i < q_shared.MAX_MODELS; i++) { localmodels[i] = "*" + i.ToString(); } }
/* * ==================== SV_AreaEdicts_r * * ==================== */ public static void SV_AreaEdicts_r(areanode_t node) { link_t l, next, start; edict_t check; // touch linked edicts if (SV_WORLD.area_type == Defines.AREA_SOLID) { start = node.solid_edicts; } else { start = node.trigger_edicts; } for (l = start.next; l != start; l = next) { next = l.next; check = (edict_t)l.o; if (check.solid == Defines.SOLID_NOT) { continue; // deactivated } if (check.absmin[0] > SV_WORLD.area_maxs[0] || check.absmin[1] > SV_WORLD.area_maxs[1] || check.absmin[2] > SV_WORLD.area_maxs[2] || check.absmax[0] < SV_WORLD.area_mins[0] || check.absmax[1] < SV_WORLD.area_mins[1] || check.absmax[2] < SV_WORLD.area_mins[2]) { continue; // not touching } if (SV_WORLD.area_count == SV_WORLD.area_maxcount) { Com.Printf("SV_AreaEdicts: MAXCOUNT\n"); return; } SV_WORLD.area_list[SV_WORLD.area_count] = check; SV_WORLD.area_count++; } if (node.axis == -1) { return; // terminal node } // recurse down both sides if (SV_WORLD.area_maxs[node.axis] > node.dist) { SV_WORLD.SV_AreaEdicts_r(node.children[0]); } if (SV_WORLD.area_mins[node.axis] < node.dist) { SV_WORLD.SV_AreaEdicts_r(node.children[1]); } }
public static void SV_TouchLinks(edict_t ent, areanode_t node) { // touch linked edicts link_t next; for (link_t l = node.trigger_edicts.Next; l != node.trigger_edicts; l = next) { next = l.Next; edict_t touch = (edict_t)l.Owner;// EDICT_FROM_AREA(l); if (touch == ent) { continue; } if (touch.v.touch == 0 || touch.v.solid != q_shared.SOLID_TRIGGER) { continue; } if (ent.v.absmin.x > touch.v.absmax.x || ent.v.absmin.y > touch.v.absmax.y || ent.v.absmin.z > touch.v.absmax.z || ent.v.absmax.x < touch.v.absmin.x || ent.v.absmax.y < touch.v.absmin.y || ent.v.absmax.z < touch.v.absmin.z) { continue; } int old_self = pr_global_struct.self; int old_other = pr_global_struct.other; pr_global_struct.self = EDICT_TO_PROG(touch); pr_global_struct.other = EDICT_TO_PROG(ent); pr_global_struct.time = (float)sv.time; PR_ExecuteProgram(touch.v.touch); pr_global_struct.self = old_self; pr_global_struct.other = old_other; } // recurse down both sides if (node.axis == -1) { return; } if (Mathlib.Comp(ref ent.v.absmax, node.axis) > node.dist) { SV_TouchLinks(ent, node.children[0]); } if (Mathlib.Comp(ref ent.v.absmin, node.axis) < node.dist) { SV_TouchLinks(ent, node.children[1]); } }
public static areanode_t SV_CreateAreaNode(int depth, ref Vector3 mins, ref Vector3 maxs) { areanode_t anode = sv_areanodes[sv_numareanodes]; sv_numareanodes++; anode.trigger_edicts.Clear(); anode.solid_edicts.Clear(); if (depth == q_shared.AREA_DEPTH) { anode.axis = -1; anode.children[0] = anode.children[1] = null; return(anode); } Vector3 size = maxs - mins; Vector3 mins1 = mins; Vector3 mins2 = mins; Vector3 maxs1 = maxs; Vector3 maxs2 = maxs; if (size.X > size.Y) { anode.axis = 0; anode.dist = 0.5f * (maxs.X + mins.X); maxs1.X = mins2.X = anode.dist; } else { anode.axis = 1; anode.dist = 0.5f * (maxs.Y + mins.Y); maxs1.Y = mins2.Y = anode.dist; } anode.children[0] = SV_CreateAreaNode(depth + 1, ref mins2, ref maxs2); anode.children[1] = SV_CreateAreaNode(depth + 1, ref mins1, ref maxs1); return(anode); }
static void SV_ClipToLinks(areanode_t node, moveclip_t clip) { common.link_t l, next; prog.edict_t touch; trace_t trace; // touch linked edicts for (l = node.solid_edicts.next; l != node.solid_edicts; l = next) { //Debug.WriteLine("ClipToLinks_for_num " + ClipToLinks_for_num); ClipToLinks_for_num++; next = l.next; touch = prog. EDICT_FROM_AREA(l); if (touch.v.solid == server.SOLID_NOT) { continue; } if (touch == clip.passedict) { continue; } if (touch.v.solid == server. SOLID_TRIGGER) sys_linux. Sys_Error ("Trigger in clipping list"); if (clip.type == MOVE_NOMONSTERS && touch.v.solid != server.SOLID_BSP) continue; if (clip.boxmins[0] > touch.v.absmax[0] || clip.boxmins[1] > touch.v.absmax[1] || clip.boxmins[2] > touch.v.absmax[2] || clip.boxmaxs[0] < touch.v.absmin[0] || clip.boxmaxs[1] < touch.v.absmin[1] || clip.boxmaxs[2] < touch.v.absmin[2]) { continue; } //if (clip.passedict && clip.passedict.v.size[0] && !touch.v.size[0]) if (clip.passedict !=null && clip.passedict.v.size[0] != 0 && !(touch.v.size[0] != 0)) { continue; // points never interact } // might intersect, so do an exact clip if (clip.trace.allsolid) { return; } if (clip.passedict != null) { if (prog.PROG_TO_EDICT(touch.v.owner) == clip.passedict) { continue; // don't clip against own missiles } if (prog.PROG_TO_EDICT(clip.passedict.v.owner) == touch) { continue; // don't clip against owner } } if (((int)touch.v.flags & server.FL_MONSTER) != 0) trace = SV_ClipMoveToEntity (touch, clip.start, clip.mins2, clip.maxs2, clip.end); else trace = SV_ClipMoveToEntity (touch, clip.start, clip.mins, clip.maxs, clip.end); if (trace.allsolid || trace.startsolid || trace.fraction < clip.trace.fraction) { trace.ent = touch; if (clip.trace.startsolid) { clip.trace = trace; clip.trace.startsolid = true; } else clip.trace = trace; } else if (trace.startsolid) clip.trace.startsolid = true; } // recurse down both sides if (node.axis == -1) return; if (clip.boxmaxs[node.axis] > node.dist) { SV_ClipToLinks(node.children[0], clip); } if (clip.boxmins[node.axis] < node.dist) { SV_ClipToLinks(node.children[1], clip); } }
static void SV_TouchLinks(prog.edict_t ent, areanode_t node) { common.link_t l, next; prog.edict_t touch; int old_self, old_other; tchlinksFunc++; // touch linked edicts for (l = node.trigger_edicts.next; l != node.trigger_edicts; l = next) { //Debug.WriteLine("SV_TouchLinks loop "+ tchlinks); tchlinks++; next = l.next; touch = prog.EDICT_FROM_AREA(l); if (touch == ent) continue; if (!(touch.v.touch != 0) || touch.v.solid != server.SOLID_TRIGGER) continue; if (ent.v.absmin[0] > touch.v.absmax[0] || ent.v.absmin[1] > touch.v.absmax[1] || ent.v.absmin[2] > touch.v.absmax[2] || ent.v.absmax[0] < touch.v.absmin[0] || ent.v.absmax[1] < touch.v.absmin[1] || ent.v.absmax[2] < touch.v.absmin[2]) continue; old_self = prog.pr_global_struct[0].self; old_other = prog.pr_global_struct[0].other; prog.pr_global_struct[0].self = prog.EDICT_TO_PROG(touch); prog.pr_global_struct[0].other = prog.EDICT_TO_PROG(ent); prog.pr_global_struct[0].time = server.sv.time; prog.PR_ExecuteProgram(prog.pr_functions[touch.v.touch]); prog.pr_global_struct[0].self = old_self; prog.pr_global_struct[0].other = old_other; } // recurse down both sides if (node.axis == -1) { return; } if (ent.v.absmax[node.axis] > node.dist) { SV_TouchLinks(ent, node.children[0]); } if (ent.v.absmin[node.axis] < node.dist) { SV_TouchLinks(ent, node.children[1]); } }
/* =============== SV_CreateAreaNode =============== */ static areanode_t SV_CreateAreaNode(int depth, double[] mins, double[] maxs) { areanode_t anode= new areanode_t(); double[] size = new double[3] {0, 0, 0}; double[] mins1 = new double[3] {0, 0, 0}, maxs1 = new double[3] {0, 0, 0}, mins2 = new double[3] {0, 0, 0}, maxs2 = new double[3] {0, 0, 0}; anode = sv_areanodes[sv_numareanodes]; sv_numareanodes++; //Debug.WriteLine("SV_CreateAreaNode"); common.ClearLink(anode.trigger_edicts); common.ClearLink(anode.solid_edicts); if (depth == AREA_DEPTH) { anode.axis = -1; anode.children[0] = anode.children[1] = null; return anode; } mathlib.VectorSubtract(maxs, mins, size); if (size[0] > size[1]) anode.axis = 0; else anode.axis = 1; anode.dist = 0.5 * (maxs[anode.axis] + mins[anode.axis]); mathlib. VectorCopy(mins, mins1); mathlib. VectorCopy(mins, mins2); mathlib. VectorCopy(maxs, maxs1); mathlib. VectorCopy(maxs, maxs2); maxs1[anode.axis] = mins2[anode.axis] = anode.dist; anode.children[0] = SV_CreateAreaNode(depth + 1, mins2, maxs2); anode.children[1] = SV_CreateAreaNode(depth + 1, mins1, maxs1); return anode; }
private static areanode_t[] Init_areanode_t(int count) { var nodes = new areanode_t[count]; for (int i = 0; i < count; i++) nodes[i] = new areanode_t(); return nodes; }
public static void SV_LinkEdict(edict_t ent, bool touch_triggers) { if (ent.area.Prev != null) { SV_UnlinkEdict(ent); // unlink from old position } if (ent == sv.edicts[0]) { return; // don't add the world } if (ent.free) { return; } // set the abs box Mathlib.VectorAdd(ref ent.v.origin, ref ent.v.mins, out ent.v.absmin); Mathlib.VectorAdd(ref ent.v.origin, ref ent.v.maxs, out ent.v.absmax); // // to make items easier to pick up and allow them to be grabbed off // of shelves, the abs sizes are expanded // if (((int)ent.v.flags & q_shared.FL_ITEM) != 0) { ent.v.absmin.x -= 15; ent.v.absmin.y -= 15; ent.v.absmax.x += 15; ent.v.absmax.y += 15; } else { // because movement is clipped an epsilon away from an actual edge, // we must fully check even when bounding boxes don't quite touch ent.v.absmin.x -= 1; ent.v.absmin.y -= 1; ent.v.absmin.z -= 1; ent.v.absmax.x += 1; ent.v.absmax.y += 1; ent.v.absmax.z += 1; } // link to PVS leafs ent.num_leafs = 0; if (ent.v.modelindex != 0) { SV_FindTouchedLeafs(ent, sv.worldmodel.nodes[0]); } if (ent.v.solid == q_shared.SOLID_NOT) { return; } // find the first node that the ent's box crosses areanode_t node = sv_areanodes[0]; while (true) { if (node.axis == -1) { break; } if (Mathlib.Comp(ref ent.v.absmin, node.axis) > node.dist) { node = node.children[0]; } else if (Mathlib.Comp(ref ent.v.absmax, node.axis) < node.dist) { node = node.children[1]; } else { break; // crosses the node } } // link it in if (ent.v.solid == q_shared.SOLID_TRIGGER) { ent.area.InsertBefore(node.trigger_edicts); } else { ent.area.InsertBefore(node.solid_edicts); } // if touch_triggers, touch all entities at this node and decend for more if (touch_triggers) { SV_TouchLinks(ent, sv_areanodes[0]); } }
public static void SV_ClipToLinks(areanode_t node, moveclip_t clip) { link_t next; trace_t trace; // touch linked edicts for (link_t l = node.solid_edicts.Next; l != node.solid_edicts; l = next) { next = l.Next; edict_t touch = (edict_t)l.Owner;// EDICT_FROM_AREA(l); if (touch.v.solid == q_shared.SOLID_NOT) { continue; } if (touch == clip.passedict) { continue; } if (touch.v.solid == q_shared.SOLID_TRIGGER) { Sys_Error("Trigger in clipping list"); } if (clip.type == q_shared.MOVE_NOMONSTERS && touch.v.solid != q_shared.SOLID_BSP) { continue; } if (clip.boxmins.X > touch.v.absmax.x || clip.boxmins.Y > touch.v.absmax.y || clip.boxmins.Z > touch.v.absmax.z || clip.boxmaxs.X < touch.v.absmin.x || clip.boxmaxs.Y < touch.v.absmin.y || clip.boxmaxs.Z < touch.v.absmin.z) { continue; } if (clip.passedict != null && clip.passedict.v.size.x != 0 && touch.v.size.x == 0) { continue; // points never interact } // might intersect, so do an exact clip if (clip.trace.allsolid) { return; } if (clip.passedict != null) { if (PROG_TO_EDICT(touch.v.owner) == clip.passedict) { continue; // don't clip against own missiles } if (PROG_TO_EDICT(clip.passedict.v.owner) == touch) { continue; // don't clip against owner } } if (((int)touch.v.flags & q_shared.FL_MONSTER) != 0) { trace = SV_ClipMoveToEntity(touch, ref clip.start, ref clip.mins2, ref clip.maxs2, ref clip.end); } else { trace = SV_ClipMoveToEntity(touch, ref clip.start, ref clip.mins, ref clip.maxs, ref clip.end); } if (trace.allsolid || trace.startsolid || trace.fraction < clip.trace.fraction) { trace.ent = touch; if (clip.trace.startsolid) { clip.trace = trace; clip.trace.startsolid = true; } else { clip.trace = trace; } } else if (trace.startsolid) { clip.trace.startsolid = true; } } // recurse down both sides if (node.axis == -1) { return; } if (Mathlib.Comp(ref clip.boxmaxs, node.axis) > node.dist) { SV_ClipToLinks(node.children[0], clip); } if (Mathlib.Comp(ref clip.boxmins, node.axis) < node.dist) { SV_ClipToLinks(node.children[1], clip); } }