public static edict_t NEXT_EDICT(edict_t e) { if (e.index + 1 < server.sv.edicts.Length) { return server.sv.edicts[e.index + 1]; } return null; }
public static void SV_ExecuteUserCommand(String s) { Com.Dprintln("SV_ExecuteUserCommand:" + s); SV_USER.ucmd_t u = null; Cmd.TokenizeString(s.ToCharArray(), true); SV_USER.sv_player = SV_MAIN.sv_client.edict; var i = 0; for ( ; i < SV_USER.ucmds.Length; i++) { u = SV_USER.ucmds[i]; if (Cmd.Argv(0).Equals(u.name)) { u.r.Run(); break; } } if (i == SV_USER.ucmds.Length && SV_INIT.sv.state == Defines.ss_game) { Cmd.ClientCommand(SV_USER.sv_player); } }
/** * PF_cprintf * * Print to a single client. */ public static void PF_cprintf(edict_t ent, int level, string fmt) { var n = 0; if (ent != null) { n = ent.index; if (n < 1 || n > SV_MAIN.maxclients.value) { Com.Error(Defines.ERR_DROP, "cprintf to a non-client"); } } if (ent != null) { SV_SEND.SV_ClientPrintf(SV_INIT.svs.clients[n - 1], level, fmt); } else { Com.Printf(fmt); } }
public static void SV_Impact(edict_t e1, edict_t e2) { int old_self = pr_global_struct.self; int old_other = pr_global_struct.other; pr_global_struct.time = (float)sv.time; if (e1.v.touch != 0 && e1.v.solid != q_shared.SOLID_NOT) { pr_global_struct.self = EDICT_TO_PROG(e1); pr_global_struct.other = EDICT_TO_PROG(e2); PR_ExecuteProgram(e1.v.touch); } if (e2.v.touch != 0 && e2.v.solid != q_shared.SOLID_NOT) { pr_global_struct.self = EDICT_TO_PROG(e2); pr_global_struct.other = EDICT_TO_PROG(e1); PR_ExecuteProgram(e2.v.touch); } pr_global_struct.self = old_self; pr_global_struct.other = old_other; }
/** * PF_setmodel * * Also sets mins and maxs for inline bmodels. */ public static void PF_setmodel(edict_t ent, string name) { int i; cmodel_t mod; if (name == null) { Com.Error(Defines.ERR_DROP, "PF_setmodel: NULL"); } i = SV_INIT.SV_ModelIndex(name); ent.s.modelindex = i; // if it is an inline model, get the size information for it if (name.StartsWith("*")) { mod = CM.InlineModel(name); Math3D.VectorCopy(mod.mins, ent.mins); Math3D.VectorCopy(mod.maxs, ent.maxs); SV_WORLD.SV_LinkEdict(ent); } }
/////////////////////////////////////// public static edict_t[] SV_TestEntityPosition(edict_t ent) { trace_t trace; int mask; if (ent.clipmask != 0) { mask = ent.clipmask; } else { mask = Defines.MASK_SOLID; } trace = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, ent.s.origin, ent, mask); if (trace.startsolid) { return(GameBase.g_edicts); } return(null); }
public static void ChasePrev(edict_t ent) { int i; edict_t e; if (ent.client.chase_target == null) { return; } i = ent.client.chase_target.index; do { i--; if (i < 1) { i = (int)GameBase.maxclients.value; } e = GameBase.g_edicts[i]; if (!e.inuse) { continue; } if (!e.client.resp.spectator) { break; } }while (e != ent.client.chase_target); ent.client.chase_target = e; ent.client.update_chase = true; }
public static void ChaseNext(edict_t ent) { int i; edict_t e; if (null == ent.client.chase_target) { return; } i = ent.client.chase_target.index; do { i++; if (i > GameBase.maxclients.value) { i = 1; } e = GameBase.g_edicts[i]; if (!e.inuse) { continue; } if (!e.client.resp.spectator) { break; } }while (e != ent.client.chase_target); ent.client.chase_target = e; ent.client.update_chase = true; }
public override void Die(edict_t self, edict_t inflictor, edict_t attacker, int damage, float[] point) { int n; if (self.health <= self.gib_health) { GameBase.gi.Sound(self, Defines.CHAN_VOICE, GameBase.gi.Soundindex("misc/udeath.wav"), 1, Defines.ATTN_NORM, 0); for (n = 0; n < 2; n++) { GameMisc.ThrowGib(self, "models/objects/gibs/bone/tris.md2", damage, Defines.GIB_ORGANIC); } for (n = 0; n < 4; n++) { GameMisc.ThrowGib(self, "models/objects/gibs/sm_meat/tris.md2", damage, Defines.GIB_ORGANIC); } GameMisc.ThrowHead(self, "models/objects/gibs/head2/tris.md2", damage, Defines.GIB_ORGANIC); self.deadflag = Defines.DEAD_DEAD; return; } if (self.deadflag == Defines.DEAD_DEAD) { return; } GameBase.gi.Sound(self, Defines.CHAN_VOICE, sound_death, 1, Defines.ATTN_NORM, 0); self.deadflag = Defines.DEAD_DEAD; self.takedamage = Defines.DAMAGE_YES; self.s.skinnum = 1; if (Lib.Random() < 0.5) { self.monsterinfo.currentmove = mutant_move_death1; } else { self.monsterinfo.currentmove = mutant_move_death2; } }
public static void SV_Physics_Pusher(edict_t ent) { float oldltime = ent.v.ltime; float thinktime = ent.v.nextthink; float movetime; if (thinktime < ent.v.ltime + host_framtime) { movetime = thinktime - ent.v.ltime; if (movetime < 0) { movetime = 0; } } else { movetime = (float)host_framtime; } if (movetime != 0) { SV_PushMove(ent, movetime); // advances ent.v.ltime if not blocked } if (thinktime > oldltime && thinktime <= ent.v.ltime) { ent.v.nextthink = 0; pr_global_struct.time = (float)sv.time; pr_global_struct.self = EDICT_TO_PROG(ent); pr_global_struct.other = EDICT_TO_PROG(sv.edicts[0]); PR_ExecuteProgram(ent.v.think); if (ent.free) { return; } } }
public override void Pain(edict_t self, edict_t other, float kick, int damage) { if (self.health < (self.max_health / 2)) { self.s.skinnum = 1; } if (GameBase.level.time < self.pain_debounce_time) { if ((self.velocity[2] > 100) && (self.monsterinfo.currentmove == gladiator_move_pain)) { self.monsterinfo.currentmove = gladiator_move_pain_air; } return; } self.pain_debounce_time = GameBase.level.time + 3; if (Lib.Random() < 0.5) { GameBase.gi.Sound(self, Defines.CHAN_VOICE, sound_pain1, 1, Defines.ATTN_NORM, 0); } else { GameBase.gi.Sound(self, Defines.CHAN_VOICE, sound_pain2, 1, Defines.ATTN_NORM, 0); } if (GameBase.skill.value == 3) { return; } if (self.velocity[2] > 100) { self.monsterinfo.currentmove = gladiator_move_pain_air; } else { self.monsterinfo.currentmove = gladiator_move_pain; } }
public static void SP_monster_berserk(edict_t self) { if (GameBase.deathmatch.value != 0) { GameUtil.G_FreeEdict(self); return; } sound_pain = GameBase.gi.Soundindex("berserk/berpain2.wav"); sound_die = GameBase.gi.Soundindex("berserk/berdeth2.wav"); sound_idle = GameBase.gi.Soundindex("berserk/beridle1.wav"); sound_punch = GameBase.gi.Soundindex("berserk/attack.wav"); sound_search = GameBase.gi.Soundindex("berserk/bersrch1.wav"); sound_sight = GameBase.gi.Soundindex("berserk/sight.wav"); self.s.modelindex = GameBase.gi.Modelindex("models/monsters/berserk/tris.md2"); Math3D.VectorSet(self.mins, -16, -16, -24); Math3D.VectorSet(self.maxs, 16, 16, 32); self.movetype = Defines.MOVETYPE_STEP; self.solid = Defines.SOLID_BBOX; self.health = 240; self.gib_health = -60; self.mass = 250; self.pain = berserk_pain; self.die = berserk_die; self.monsterinfo.stand = berserk_stand; self.monsterinfo.walk = berserk_walk; self.monsterinfo.run = berserk_run; self.monsterinfo.dodge = null; self.monsterinfo.attack = null; self.monsterinfo.melee = berserk_melee; self.monsterinfo.sight = berserk_sight; self.monsterinfo.search = berserk_search; self.monsterinfo.currentmove = berserk_move_stand; self.monsterinfo.scale = MODEL_SCALE; GameBase.gi.Linkentity(self); GameAI.walkmonster_start.Think(self); }
/** * Cmd_Say_f */ public static void Say_f(edict_t ent, bool team, bool arg0) { int i, j; edict_t other; string text; gclient_t cl; if (Cmd.Argc() < 2 && !arg0) { return; } if (0 == ((int)GameBase.dmflags.value & (Defines.DF_MODELTEAMS | Defines.DF_SKINTEAMS))) { team = false; } if (team) { text = "(" + ent.client.pers.netname + "): "; } else { text = "" + ent.client.pers.netname + ": "; } if (arg0) { text += Cmd.Argv(0); text += " "; text += Cmd.Args(); } else { if (Cmd.Args().StartsWith("\"")) { text += Cmd.Args()[1..];
/** * M_MoveToGoal. */ public static void M_MoveToGoal(edict_t ent, float dist) { var goal = ent.goalentity; if (ent.groundentity == null && (ent.flags & (Defines.FL_FLY | Defines.FL_SWIM)) == 0) { return; } // if the next step hits the enemy, return immediately if (ent.enemy != null && SV.SV_CloseEnough(ent, ent.enemy, dist)) { return; } // bump around... if ((Lib.rand() & 3) == 1 || !SV.SV_StepDirection(ent, ent.ideal_yaw, dist)) { if (ent.inuse) { SV.SV_NewChaseDir(ent, goal, dist); } } }
public override void Touch(edict_t self, edict_t other, cplane_t plane, csurface_t surf) { if (self.health <= 0) { self.touch = null; return; } if (other.takedamage != 0) { if (Math3D.VectorLength(self.velocity) > 400) { float[] point = new float[] { 0, 0, 0 }; float[] normal = new float[] { 0, 0, 0 }; int damage; Math3D.VectorCopy(self.velocity, normal); Math3D.VectorNormalize(normal); Math3D.VectorMA(self.s.origin, self.maxs[0], normal, point); damage = (int)(40 + 10 * Lib.Random()); GameCombat.T_Damage(other, self, self, self.velocity, point, normal, damage, damage, 0, Defines.MOD_UNKNOWN); } } if (!M.M_CheckBottom(self)) { if (self.groundentity != null) { self.monsterinfo.nextframe = FRAME_attack02; self.touch = null; } return; } self.touch = null; }
/** * Decides running or standing according to flag AI_STAND_GROUND. */ public static void HuntTarget(edict_t self) { float[] vec = { 0, 0, 0 }; self.goalentity = self.enemy; if ((self.monsterinfo.aiflags & Defines.AI_STAND_GROUND) != 0) { self.monsterinfo.stand.think(self); } else { self.monsterinfo.run.think(self); } Math3D.VectorSubtract(self.enemy.s.origin, self.s.origin, vec); self.ideal_yaw = Math3D.vectoyaw(vec); // wait a while before first attack if (0 == (self.monsterinfo.aiflags & Defines.AI_STAND_GROUND)) { GameUtil.AttackFinished(self, 1); } }
public static void SV_MoveToGoal() { edict_t ent = PROG_TO_EDICT(pr_global_struct.self); edict_t goal = PROG_TO_EDICT(ent.v.goalentity); float dist = G_FLOAT(q_shared.OFS_PARM0); if (((int)ent.v.flags & (q_shared.FL_ONGROUND | q_shared.FL_FLY | q_shared.FL_SWIM)) == 0) { G_FLOAT((float)0); return; } // if the next step hits the enemy, return immediately if (PROG_TO_EDICT(ent.v.enemy) != sv.edicts[0] && SV_CloseEnough(ent, goal, dist)) { return; } // bump around... if ((Random() & 3) == 1 || !SV_StepDirection(ent, ent.v.ideal_yaw, dist)) { SV_NewChaseDir(ent, goal, dist); } }
/** * Strafe sideways, but stay at aproximately the same range. */ public static void ai_run_slide(edict_t self, float distance) { float ofs; self.ideal_yaw = GameAI.enemy_yaw; M.M_ChangeYaw(self); if (self.monsterinfo.lefty != 0) { ofs = 90; } else { ofs = -90; } if (M.M_walkmove(self, self.ideal_yaw + ofs, distance)) { return; } self.monsterinfo.lefty = 1 - self.monsterinfo.lefty; M.M_walkmove(self, self.ideal_yaw - ofs, distance); }
public static void SP_monster_boss2(edict_t self) { if (GameBase.deathmatch.value != 0) { GameUtil.G_FreeEdict(self); return; } sound_pain1 = GameBase.gi.Soundindex("bosshovr/bhvpain1.wav"); sound_pain2 = GameBase.gi.Soundindex("bosshovr/bhvpain2.wav"); sound_pain3 = GameBase.gi.Soundindex("bosshovr/bhvpain3.wav"); sound_death = GameBase.gi.Soundindex("bosshovr/bhvdeth1.wav"); sound_search1 = GameBase.gi.Soundindex("bosshovr/bhvunqv1.wav"); self.s.sound = GameBase.gi.Soundindex("bosshovr/bhvengn1.wav"); self.movetype = Defines.MOVETYPE_STEP; self.solid = Defines.SOLID_BBOX; self.s.modelindex = GameBase.gi.Modelindex("models/monsters/boss2/tris.md2"); Math3D.VectorSet(self.mins, -56, -56, 0); Math3D.VectorSet(self.maxs, 56, 56, 80); self.health = 2000; self.gib_health = -200; self.mass = 1000; self.flags |= Defines.FL_IMMUNE_LASER; self.pain = boss2_pain; self.die = boss2_die; self.monsterinfo.stand = boss2_stand; self.monsterinfo.walk = boss2_walk; self.monsterinfo.run = boss2_run; self.monsterinfo.attack = boss2_attack; self.monsterinfo.search = boss2_search; self.monsterinfo.checkattack = Boss2_CheckAttack; GameBase.gi.Linkentity(self); self.monsterinfo.currentmove = boss2_move_stand; self.monsterinfo.scale = MODEL_SCALE; GameAI.flymonster_start.Think(self); }
public static bool SV_RunThink(edict_t ent) { float thinktime; thinktime = ent.v.nextthink; if (thinktime <= 0 || thinktime > sv.time + host_framtime) { return(true); } if (thinktime < sv.time) { thinktime = (float)sv.time; // don't let things stay in the past. } // it is possible to start that way // by a trigger with a local time. ent.v.nextthink = 0; pr_global_struct.time = thinktime; pr_global_struct.self = EDICT_TO_PROG(ent); pr_global_struct.other = EDICT_TO_PROG(sv.edicts[0]); PR_ExecuteProgram(ent.v.think); return(!ent.free); }
public override bool Think(edict_t self) { float[] start = new float[] { 0, 0, 0 }, target = new float[] { 0, 0, 0 }; float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 }; float[] vec = new float[] { 0, 0, 0 }; int flash_number; if (self.s.frame == FRAME_attak111) { flash_number = Defines.MZ2_INFANTRY_MACHINEGUN_1; Math3D.AngleVectors(self.s.angles, forward, right, null); Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[flash_number], forward, right, start); if (self.enemy != null) { Math3D.VectorMA(self.enemy.s.origin, -0.2F, self.enemy.velocity, target); target[2] += self.enemy.viewheight; Math3D.VectorSubtract(target, start, forward); Math3D.VectorNormalize(forward); } else { Math3D.AngleVectors(self.s.angles, forward, right, null); } } else { flash_number = Defines.MZ2_INFANTRY_MACHINEGUN_2 + (self.s.frame - FRAME_death211); Math3D.AngleVectors(self.s.angles, forward, right, null); Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[flash_number], forward, right, start); Math3D.VectorSubtract(self.s.angles, aimangles[flash_number - Defines.MZ2_INFANTRY_MACHINEGUN_2], vec); Math3D.AngleVectors(vec, forward, null, null); } Monster.Monster_fire_bullet(self, start, forward, 3, 4, Defines.DEFAULT_BULLET_HSPREAD, Defines.DEFAULT_BULLET_VSPREAD, flash_number); return(true); }
/** * Cmd_InvUse_f. */ public static void InvUse_f(edict_t ent) { gitem_t it; Cmd.ValidateSelectedItem(ent); if (ent.client.pers.selected_item == -1) { SV_GAME.PF_cprintfhigh(ent, "No item to use.\n"); return; } it = GameItemList.itemlist[ent.client.pers.selected_item]; if (it.use == null) { SV_GAME.PF_cprintfhigh(ent, "Item is not usable.\n"); return; } it.use.use(ent, it); }
public override bool Think(edict_t self) { float[] start = new float[] { 0, 0, 0 }; float[] forward = new float[] { 0, 0, 0 }, right = new float[] { 0, 0, 0 }; float[] end = new float[] { 0, 0, 0 }; float[] dir = new float[] { 0, 0, 0 }; int effect; if ((self.s.frame == FRAME_attak104) || (self.s.frame == FRAME_attak107)) { effect = Defines.EF_HYPERBLASTER; } else { effect = 0; } Math3D.AngleVectors(self.s.angles, forward, right, null); Math3D.G_ProjectSource(self.s.origin, M_Flash.monster_flash_offset[Defines.MZ2_FLOAT_BLASTER_1], forward, right, start); Math3D.VectorCopy(self.enemy.s.origin, end); end[2] += self.enemy.viewheight; Math3D.VectorSubtract(end, start, dir); Monster.Monster_fire_blaster(self, start, dir, 1, 1000, Defines.MZ2_FLOAT_BLASTER_1, effect); return(true); }
/** * Cmd_Noclip_f * * argv(0) noclip. */ public static void Noclip_f(edict_t ent) { string msg; if (GameBase.deathmatch.value != 0 && GameBase.sv_cheats.value == 0) { SV_GAME.PF_cprintfhigh(ent, "You must run the server with '+set cheats 1' to enable this command.\n"); return; } if (ent.movetype == Defines.MOVETYPE_NOCLIP) { ent.movetype = Defines.MOVETYPE_WALK; msg = "noclip OFF\n"; } else { ent.movetype = Defines.MOVETYPE_NOCLIP; msg = "noclip ON\n"; } SV_GAME.PF_cprintfhigh(ent, msg); }
/** * Cmd_Use_f * * Use an inventory item. */ public static void Use_f(edict_t ent) { int index; gitem_t it; string s; s = Cmd.Args(); it = GameItems.FindItem(s); Com.dprintln("using:" + s); if (it == null) { SV_GAME.PF_cprintfhigh(ent, "unknown item: " + s + "\n"); return; } if (it.use == null) { SV_GAME.PF_cprintfhigh(ent, "Item is not usable.\n"); return; } index = GameItems.ITEM_INDEX(it); if (0 == ent.client.pers.inventory[index]) { SV_GAME.PF_cprintfhigh(ent, "Out of item: " + s + "\n"); return; } it.use.use(ent, it); }
/** * Cmd_God_f * * Sets client to godmode * * argv(0) god */ public static void God_f(edict_t ent) { string msg; if (GameBase.deathmatch.value != 0 && GameBase.sv_cheats.value == 0) { SV_GAME.PF_cprintfhigh(ent, "You must run the server with '+set cheats 1' to enable this command.\n"); return; } ent.flags ^= Defines.FL_GODMODE; if (0 == (ent.flags & Defines.FL_GODMODE)) { msg = "godmode OFF\n"; } else { msg = "godmode ON\n"; } SV_GAME.PF_cprintf(ent, Defines.PRINT_HIGH, msg); }
/** * Cmd_Notarget_f * * Sets client to notarget * * argv(0) notarget. */ public static void Notarget_f(edict_t ent) { string msg; if (GameBase.deathmatch.value != 0 && GameBase.sv_cheats.value == 0) { SV_GAME.PF_cprintfhigh(ent, "You must run the server with '+set cheats 1' to enable this command.\n"); return; } ent.flags ^= Defines.FL_NOTARGET; if (0 == (ent.flags & Defines.FL_NOTARGET)) { msg = "notarget OFF\n"; } else { msg = "notarget ON\n"; } SV_GAME.PF_cprintfhigh(ent, msg); }
/** * Cmd_Help_f * * Display the current help message. * */ public static void Help_f(edict_t ent) { // this is for backwards compatability if (GameBase.deathmatch.value != 0) { Cmd.Score_f(ent); return; } ent.client.showinventory = false; ent.client.showscores = false; if (ent.client.showhelp && ent.client.pers.game_helpchanged == GameBase.game.helpchanged) { ent.client.showhelp = false; return; } ent.client.showhelp = true; ent.client.pers.helpchanged = 0; PlayerHud.HelpComputer(ent); }
/** * Kills all entities that would touch the proposed new positioning of ent. * Ent should be unlinked before calling this! */ public static bool KillBox(edict_t ent) { trace_t tr; while (true) { tr = GameBase.gi.trace(ent.s.origin, ent.mins, ent.maxs, ent.s.origin, null, Defines.MASK_PLAYERSOLID); if (tr.ent == null || tr.ent == GameBase.g_edicts[0]) { break; } // nail it GameCombat.T_Damage( tr.ent, ent, ent, Globals.vec3_origin, ent.s.origin, Globals.vec3_origin, 100000, 0, Defines.DAMAGE_NO_PROTECTION, Defines.MOD_TELEFRAG ); // if we didn't kill it, fail if (tr.ent.solid != 0) { return(false); } } return(true); // all clear }
static unsafe void PF_findradius() { edict_t chain = sv.edicts[0]; float *org = G_VECTOR(q_shared.OFS_PARM0); float rad = G_FLOAT(q_shared.OFS_PARM1); Vector3 vorg; Copy(org, out vorg); for (int i = 1; i < sv.num_edicts; i++) { edict_t ent = sv.edicts[i]; if (ent.free) { continue; } if (ent.v.solid == q_shared.SOLID_NOT) { continue; } Vector3 v = vorg - (ToVector(ref ent.v.origin) + (ToVector(ref ent.v.mins) + ToVector(ref ent.v.maxs)) * 0.5f); if (v.Length > rad) { continue; } ent.v.chain = EDICT_TO_PROG(chain); chain = ent; } RETURN_EDICT(chain); }
public override void Pain(edict_t self, edict_t other, float kick, int damage) { if (self.health < (self.max_health / 2)) { self.s.skinnum = 1; } if (GameBase.level.time < self.pain_debounce_time) { return; } self.pain_debounce_time = GameBase.level.time + 3; if ((Lib.Rand() & 1) != 0) { GameBase.gi.Sound(self, Defines.CHAN_VOICE, sound_pain, 1, Defines.ATTN_NORM, 0); } else { GameBase.gi.Sound(self, Defines.CHAN_VOICE, sound_pain2, 1, Defines.ATTN_NORM, 0); } if (GameBase.skill.value == 3) { return; } if (damage <= 10) { self.monsterinfo.currentmove = gunner_move_pain3; } else if (damage <= 25) { self.monsterinfo.currentmove = gunner_move_pain2; } else { self.monsterinfo.currentmove = gunner_move_pain1; } }
/* ================= ED_ClearEdict Sets everything to NULL ================= */ static void ED_ClearEdict(edict_t e) { e.v.clear(); //memset (&e->v, 0, progs->entityfields * 4); e.free = false; }
static void RETURN_EDICT(edict_t e) { pr_globals_write(OFS_RETURN, EDICT_TO_PROG(e)); }
/* ================= ED_Free Marks the edict as free FIXME: walk all entities and NULL out references to this entity ================= */ static void ED_Free(edict_t ed) { world.SV_UnlinkEdict(ed); // unlink from world bsp ed.free = true; ed.v.model = 0; ed.v.takedamage = 0; ed.v.modelindex = 0; ed.v.colormap = 0; ed.v.skin = 0; ed.v.frame = 0; mathlib.VectorCopy(mathlib.vec3_origin, ed.v.origin); mathlib.VectorCopy(mathlib.vec3_origin, ed.v.angles); ed.v.nextthink = -1; ed.v.solid = 0; ed.freetime = server.sv.time; }
/* ==================== ED_ParseEdict Parses an edict out of the given string, returning the new position ed should be a properly initialized empty edict. Used for initial level load and for savegames. ==================== */ public static void ED_ParseEdict(char[] data, ref int ofs, edict_t ent) { ddef_t key; bool anglehack; bool init; string keyname = StringExtensions.StringOfLength(256); int n; init = false; // clear it if (ent != server.sv.edicts[0]) // hack ent.v.clear(); //memset (&ent->v, 0, progs->entityfields * 4); // go through all the dictionary pairs while (true) { // parse key common.COM_Parse(data, ref ofs); if (common.com_token[0] == '}') break; if (ofs == -1) sys_linux.Sys_Error("ED_ParseEntity: EOF without closing brace"); // anglehack is to allow QuakeEd to write single scalar angles // and allow them to be turned into vectors. (FIXME...) if (common.com_token.CompareTo("angle") == 0) { common.com_token = "angles"; anglehack = true; } else anglehack = false; // FIXME: change light to _light to get rid of this hack if (common.com_token.CompareTo("light") == 0) common.com_token = "light_lev"; // hack for single light def keyname = common.com_token; // another hack to fix heynames with trailing spaces keyname.TrimEnd(); // parse value common.COM_Parse(data, ref ofs); if (ofs == -1) sys_linux.Sys_Error("ED_ParseEntity: EOF without closing brace"); if (common.com_token[0] == '}') sys_linux.Sys_Error("ED_ParseEntity: closing brace without data"); init = true; // keynames with a leading underscore are used for utility comments, // and are immediately discarded by quake if (keyname[0] == '_') continue; key = ED_FindField(keyname); if (key == null) { console.Con_Printf("'" + keyname + "' is not a field\n"); continue; } if (anglehack) { string temp = StringExtensions.StringOfLength(32); temp = common.com_token; common.com_token = "0 " + temp + " 0"; } if (!ED_ParseEpair(ent.v, key, keyname, common.com_token)) host.Host_Error("ED_ParseEdict: parse error"); } if (!init) ent.free = true; }
//#define G_FUNCTION(o) (*(func_t *)&pr_globals[o]) static string E_STRING(edict_t e, int o) { return pr_string(cast_int(readentvar(e.v, o))); }
public static int EDICT_TO_PROG(edict_t e) { return e.index * pr_edict_size; }
/* ============= ED_Print For debugging ============= */ public static string ED_Print(edict_t ed) { string output = "\nEDICT " + NUM_FOR_EDICT(ed) + ":\n"; int l; ddef_t d; int v; int i; int j; string name; int type; if (ed.free) { return "FREE\n"; } for (i = 1; i < progs.numfielddefs; i++) { d = pr_fielddefs[i]; name = pr_string(d.s_name); try { if (name[name.Length - 2] == '_') { continue; // skip _x, _y, _z vars } //// if the value is still all 0, skip the field var field = ed.v.GetType().GetField(name); var prop = ed.v.GetType().GetProperty(name); globalval value = null; string valStr = null; type = d.type & ~DEF_SAVEGLOBAL; if (field == null && prop == null) { if (d.ofs > 104) { //if ((etype_t)type == etype_t.ev_float) //{ // value = ed.v.variables[d.ofs - 105]; // if ((double)value == 0.0) continue; //} //else if ((etype_t)type == etype_t.ev_string) //{ // valStr = pr_string(cast_int(ed.v.variables[d.ofs - 105])); // if (valStr == "") continue; //} //else //{ // throw new Exception("not implmemetned: " + type); //} var tempval = ed.v.variables[d.ofs - 105]; if (tempval == null) continue; switch ((etype_t)type) { case etype_t.ev_function: value = ed.v.variables[d.ofs - 105]; break; case etype_t.ev_string: valStr = pr_string(cast_int(ed.v.variables[d.ofs - 105])); if (valStr == "") continue; break; case etype_t.ev_entity: var testVal = NUM_FOR_EDICT(PROG_TO_EDICT(cast_int(tempval))); if (testVal == 0) { continue; } value = cast_int(tempval); break; case etype_t.ev_field: case etype_t.ev_void: case etype_t.ev_pointer: case etype_t.ev_float: if (cast_float(tempval) == 0.0) continue; value = tempval; break; case etype_t.ev_vector: if (cast_float(ed.v.variables[d.ofs - 105]) == 0 && cast_float(ed.v.variables[d.ofs - 105 + 1]) == 0 && cast_float(ed.v.variables[d.ofs - 105 + 2]) == 0) { continue; } value = new double[] { cast_float(ed.v.variables[d.ofs - 105]), cast_float( ed.v.variables[d.ofs - 105+1]), cast_float(ed.v.variables[d.ofs - 105+2]) }; break; default: throw new Exception("not implmemetned: " + type); } } else { throw new Exception("d.ofs wrong"); } } else { globalval theValue = null; //todo maybe use getvalue extension method that gets the globalval with the type? object theValueObject = field == null ? prop.GetValue(ed.v, null) : field.GetValue(ed.v); if (field != null) { if (field.FieldType == typeof(double[])) { theValue = (double[])theValueObject; } else if (field.FieldType == typeof(double)) { theValue = (double)theValueObject; } else if (field.FieldType == typeof(int)) { theValue = (int)theValueObject; } } else { if (prop.PropertyType == typeof(double[])) { theValue = (double[])theValueObject; } else if (prop.PropertyType == typeof(double)) { theValue = (double)theValueObject; } else if (prop.PropertyType == typeof(int)) { theValue = (int)theValueObject; } } switch ((etype_t)type) { case etype_t.ev_function: case etype_t.ev_string: value = cast_int(theValue); if ((int)value == 0) { continue; } break; case etype_t.ev_entity: var testVal = NUM_FOR_EDICT(PROG_TO_EDICT(cast_int(theValue))); if (testVal == 0) { continue; } value = cast_int(theValue); break; case etype_t.ev_field: case etype_t.ev_void: case etype_t.ev_pointer: case etype_t.ev_float: value = theValue; if ((double)value == 0.0) { continue; } break; case etype_t.ev_vector: value = theValue; var dblVal = (double[])value; if (dblVal[0] == 0 && dblVal[1] == 0 && dblVal[2] == 0) { continue; } break; } } output += name; l = name.Length; while (l++ < 15) { output += " "; } output += (valStr ?? PR_ValueString(d.type, value)) + "\n"; } catch (Exception e) { output += "-----------\nBAD ON " + name + " type: " + d.type + "\n" + e.Message #if SILVERLIGHT + e.StackTrace #endif + e + output + "\n------------------------------\n"; } } return output; }
static void SetMinMaxSize(edict_t e, double[] min, double[] max, bool rotate) { double[] angles; double[] rmin = new double[3] {0, 0, 0}, rmax = new double[3] {0, 0, 0}; double[][] bounds = new double[2][]; double[] xvector = new double[2], yvector = new double[2]; double a; double[] @base = new double[3] {0, 0, 0}, transformed = new double[3] {0, 0, 0}; int i, j, k, l; for (int kk = 0; kk < 2; kk++) bounds[kk] = new double[3] {0, 0, 0}; for (i=0 ; i<3 ; i++) if (min[i] > max[i]) PR_RunError ("backwards mins/maxs"); rotate = false; // FIXME: implement rotation properly again if (!rotate) { mathlib.VectorCopy (min, rmin); mathlib.VectorCopy (max, rmax); } else { // find min / max for rotations angles = e.v.angles; a = angles[1]/180 * mathlib.M_PI; xvector[0] = Math.Cos(a); xvector[1] = Math.Sin(a); yvector[0] = -Math.Sin(a); yvector[1] = Math.Cos(a); mathlib.VectorCopy (min, bounds[0]); mathlib.VectorCopy (max, bounds[1]); rmin[0] = rmin[1] = rmin[2] = 9999; rmax[0] = rmax[1] = rmax[2] = -9999; for (i=0 ; i<= 1 ; i++) { @base[0] = bounds[i][0]; for (j=0 ; j<= 1 ; j++) { @base[1] = bounds[j][1]; for (k=0 ; k<= 1 ; k++) { @base[2] = bounds[k][2]; // transform the point transformed[0] = xvector[0]*@base[0] + yvector[0]*@base[1]; transformed[1] = xvector[1]*@base[0] + yvector[1]*@base[1]; transformed[2] = @base[2]; for (l=0 ; l<3 ; l++) { if (transformed[l] < rmin[l]) rmin[l] = transformed[l]; if (transformed[l] > rmax[l]) rmax[l] = transformed[l]; } } } } } // set derived values mathlib.VectorCopy (rmin, e.v.mins); mathlib.VectorCopy (rmax, e.v.maxs); mathlib.VectorSubtract (max, min, e.v.size); world. SV_LinkEdict(e, false); }
public static int NUM_FOR_EDICT(edict_t e) { int b; b = e.index; if (b < 0 || b >= server.sv.num_edicts) sys_linux.Sys_Error("NUM_FOR_EDICT: bad pointer"); return b; }