/// <summary> /// ED_Print /// For debugging /// </summary> public unsafe static void Print(edict_t ed) { if (ed.free) { Con.Print("FREE\n"); return; } Con.Print("\nEDICT {0}:\n", Server.NumForEdict(ed)); for (int i = 1; i < _Progs.numfielddefs; i++) { ddef_t d = _FieldDefs[i]; string name = GetString(d.s_name); if (name.Length > 2 && name[name.Length - 2] == '_') { continue; // skip _x, _y, _z vars } int type = d.type & ~DEF_SAVEGLOBAL; int offset; if (ed.IsV(d.ofs, out offset)) { fixed(void *ptr = &ed.v) { int *v = (int *)ptr + offset; if (IsEmptyField(type, v)) { continue; } Con.Print("{0,15} ", name); Con.Print("{0}\n", ValueString((etype_t)d.type, (void *)v)); } } else { fixed(void *ptr = ed.fields) { int *v = (int *)ptr + offset; if (IsEmptyField(type, v)) { continue; } Con.Print("{0,15} ", name); Con.Print("{0}\n", ValueString((etype_t)d.type, (void *)v)); } } } }
/// <summary> /// PR_ValueString /// </summary> static unsafe string ValueString(etype_t type, void *val) { string result; type &= (etype_t) ~DEF_SAVEGLOBAL; switch (type) { case etype_t.ev_string: result = GetString(*(int *)val); break; case etype_t.ev_entity: result = "entity " + Server.NumForEdict(Server.ProgToEdict(*(int *)val)); break; case etype_t.ev_function: dfunction_t f = _Functions[*(int *)val]; result = GetString(f.s_name) + "()"; break; case etype_t.ev_field: ddef_t def = FindField(*(int *)val); result = "." + GetString(def.s_name); break; case etype_t.ev_void: result = "void"; break; case etype_t.ev_float: result = (*(float *)val).ToString("F1", CultureInfo.InvariantCulture.NumberFormat); break; case etype_t.ev_vector: result = String.Format(CultureInfo.InvariantCulture.NumberFormat, "{0,5:F1} {1,5:F1} {2,5:F1}", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]); break; case etype_t.ev_pointer: result = "pointer"; break; default: result = "bad type " + type.ToString(); break; } return(result); }
/* * ============== * PF_setspawnparms * ============== */ static void PF_setspawnparms() { edict_t ent = GetEdict(OFS.OFS_PARM0); int i = Server.NumForEdict(ent); if (i < 1 || i > Server.svs.maxclients) { Progs.RunError("Entity is not a client"); } // copy spawn parms out of the client_t client_t client = Server.svs.clients[i - 1]; Progs.GlobalStruct.SetParams(client.spawn_parms); }
/* * ================= * PF_centerprint * * single print to a specific client * * centerprint(clientent, value) * ================= */ static void PF_centerprint() { int entnum = Server.NumForEdict(GetEdict(OFS.OFS_PARM0)); string s = PF_VarString(1); if (entnum < 1 || entnum > Server.svs.maxclients) { Con.Print("tried to centerprint to a non-client\n"); return; } client_t client = Server.svs.clients[entnum - 1]; client.message.WriteChar(Protocol.svc_centerprint); client.message.WriteString(s); }
//============================================================================ /// <summary> /// PF_stuffcmd /// Sends text over to the client's execution buffer /// stuffcmd (clientent, value) /// </summary> static void PF_stuffcmd() { int entnum = Server.NumForEdict(GetEdict(OFS.OFS_PARM0)); if (entnum < 1 || entnum > Server.svs.maxclients) { Progs.RunError("Parm 0 not a client"); } string str = GetString(OFS.OFS_PARM1); client_t old = Host.HostClient; Host.HostClient = Server.svs.clients[entnum - 1]; Host.ClientCommands("{0}", str); Host.HostClient = old; }
/// <summary> /// PR_UglyValueString /// Returns a string describing *data in a type specific manner /// Easier to parse than PR_ValueString /// </summary> static unsafe string UglyValueString(etype_t type, eval_t *val) { type &= (etype_t) ~DEF_SAVEGLOBAL; string result; switch (type) { case etype_t.ev_string: result = GetString(val->_string); break; case etype_t.ev_entity: result = Server.NumForEdict(Server.ProgToEdict(val->edict)).ToString(); break; case etype_t.ev_function: dfunction_t f = _Functions[val->function]; result = GetString(f.s_name); break; case etype_t.ev_field: ddef_t def = FindField(val->_int); result = GetString(def.s_name); break; case etype_t.ev_void: result = "void"; break; case etype_t.ev_float: result = val->_float.ToString("F6", CultureInfo.InvariantCulture.NumberFormat); break; case etype_t.ev_vector: result = String.Format(CultureInfo.InvariantCulture.NumberFormat, "{0:F6} {1:F6} {2:F6}", val->vector[0], val->vector[1], val->vector[2]); break; default: result = "bad type " + type.ToString(); break; } return(result); }
/* * ============= * PF_nextent * * entity nextent(entity) * ============= */ static void PF_nextent() { int i = Server.NumForEdict(GetEdict(OFS.OFS_PARM0)); while (true) { i++; if (i == Server.sv.num_edicts) { ReturnEdict(Server.sv.edicts[0]); return; } edict_t ent = Server.EdictNum(i); if (!ent.free) { ReturnEdict(ent); return; } } }
/// <summary> /// Host_Spawn_f /// </summary> private static void Spawn_f() { if (Cmd.Source == cmd_source_t.src_command) { Con.Print("spawn is not valid from the console\n"); return; } if (Host.HostClient.spawned) { Con.Print("Spawn not valid -- allready spawned\n"); return; } edict_t ent; // run the entrance script if (Server.sv.loadgame) { // loaded games are fully inited allready // if this is the last client to be connected, unpause Server.sv.paused = false; } else { // set up the edict ent = Host.HostClient.edict; ent.Clear(); //memset(&ent.v, 0, progs.entityfields * 4); ent.v.colormap = Server.NumForEdict(ent); ent.v.team = (Host.HostClient.colors & 15) + 1; ent.v.netname = Progs.NewString(Host.HostClient.name); // copy spawn parms out of the client_t Progs.GlobalStruct.SetParams(Host.HostClient.spawn_parms); // call the spawn function Progs.GlobalStruct.time = (float)Server.sv.time; Progs.GlobalStruct.self = Server.EdictToProg(Server.Player); Progs.Execute(Progs.GlobalStruct.ClientConnect); if ((Sys.GetFloatTime() - Host.HostClient.netconnection.connecttime) <= Server.sv.time) { Con.DPrint("{0} entered the game\n", Host.HostClient.name); } Progs.Execute(Progs.GlobalStruct.PutClientInServer); } // send all current names, colors, and frag counts MsgWriter msg = Host.HostClient.message; msg.Clear(); // send time of update msg.WriteByte(Protocol.svc_time); msg.WriteFloat((float)Server.sv.time); for (int i = 0; i < Server.svs.maxclients; i++) { client_t client = Server.svs.clients[i]; msg.WriteByte(Protocol.svc_updatename); msg.WriteByte(i); msg.WriteString(client.name); msg.WriteByte(Protocol.svc_updatefrags); msg.WriteByte(i); msg.WriteShort(client.old_frags); msg.WriteByte(Protocol.svc_updatecolors); msg.WriteByte(i); msg.WriteByte(client.colors); } // send all current light styles for (int i = 0; i < QDef.MAX_LIGHTSTYLES; i++) { msg.WriteByte(Protocol.svc_lightstyle); msg.WriteByte((char)i); msg.WriteString(Server.sv.lightstyles[i]); } // // send some stats // msg.WriteByte(Protocol.svc_updatestat); msg.WriteByte(QStats.STAT_TOTALSECRETS); msg.WriteLong((int)Progs.GlobalStruct.total_secrets); msg.WriteByte(Protocol.svc_updatestat); msg.WriteByte(QStats.STAT_TOTALMONSTERS); msg.WriteLong((int)Progs.GlobalStruct.total_monsters); msg.WriteByte(Protocol.svc_updatestat); msg.WriteByte(QStats.STAT_SECRETS); msg.WriteLong((int)Progs.GlobalStruct.found_secrets); msg.WriteByte(Protocol.svc_updatestat); msg.WriteByte(QStats.STAT_MONSTERS); msg.WriteLong((int)Progs.GlobalStruct.killed_monsters); // // send a fixangle // Never send a roll angle, because savegames can catch the server // in a state where it is expecting the client to correct the angle // and it won't happen if the game was just loaded, so you wind up // with a permanent head tilt ent = Server.EdictNum(1 + Host.ClientNum); msg.WriteByte(Protocol.svc_setangle); msg.WriteAngle(ent.v.angles.x); msg.WriteAngle(ent.v.angles.y); msg.WriteAngle(0); Server.WriteClientDataToMessage(Server.Player, Host.HostClient.message); msg.WriteByte(Protocol.svc_signonnum); msg.WriteByte(3); Host.HostClient.sendsignon = true; }
static void PF_WriteEntity() { WriteDest.WriteShort(Server.NumForEdict(GetEdict(OFS.OFS_PARM1))); }
static void PF_eprint() { Progs.PrintNum(Server.NumForEdict(GetEdict(OFS.OFS_PARM0))); }