X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fclient%2Fmain.qc;h=6be7fa0474e2a158379fe6bbdf58f494995d2660;hb=b683bf23a495d3b1b3f6df3bda75bfe0f069ab05;hp=6fbef76ef60462eaa8ba555465b551c7834e7156;hpb=5b22584122d4354ab7819853d0fa5219d14d832e;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index 6fbef76ef..6be7fa047 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -1,8 +1,6 @@ #include "main.qh" -#include "_all.qh" #include "controlpoint.qh" -#include "csqcmodel_hooks.qh" #include "damage.qh" #include "effects.qh" #include "generator.qh" @@ -13,45 +11,27 @@ #include "laser.qh" #include "mapvoting.qh" #include "modeleffects.qh" +#include "mutators/events.qh" #include "particles.qh" +#include "quickmenu.qh" #include "scoreboard.qh" #include "shownames.qh" #include "tuba.qh" #include "t_items.qh" #include "wall.qh" - -#include "../common/vehicles/all.qh" - -#include "mutators/events.qh" - #include "weapons/projectile.qh" - -#include "../common/buffs.qh" -#include "../common/deathtypes.qh" -#include "../common/effects.qh" +#include "../common/deathtypes/all.qh" +#include "../common/items/all.qh" #include "../common/mapinfo.qh" -#include "../common/monsters/all.qh" -#include "../common/nades.qh" +#include "../common/minigames/cl_minigames.qh" +#include "../common/minigames/cl_minigames_hud.qh" #include "../common/net_notice.qh" -#include "../common/notifications.qh" -#include "../common/stats.qh" -#include "../common/teams.qh" - -#include "../common/items/all.qh" - -#include "../common/mutators/base.qh" - -#include "../common/weapons/all.qh" - -#include "../csqcmodellib/cl_model.qh" -#include "../csqcmodellib/interpolate.qh" - #include "../common/triggers/include.qh" - #include "../common/turrets/cl_turrets.qh" -#include "../common/turrets/turrets.qh" - -#include "../warpzonelib/client.qh" +#include "../common/vehicles/all.qh" +#include "../lib/csqcmodel/cl_model.qh" +#include "../lib/csqcmodel/interpolate.qh" +#include "../lib/warpzone/client.qh" // -------------------------------------------------------------------------- // BEGIN REQUIRED CSQC FUNCTIONS @@ -62,8 +42,7 @@ void clearentity(entity e) { if (!clearentity_ent) { - clearentity_ent = spawn(); - clearentity_ent.classname = "clearentity"; + clearentity_ent = new(clearentity); } int n = e.entnum; copyentity(clearentity_ent, e); @@ -83,6 +62,8 @@ void menu_sub_null() { } +void draw_null(entity this) { } + string forcefog; void ConsoleCommand_macro_init(); void CSQC_Init(void) @@ -125,6 +106,10 @@ void CSQC_Init(void) registercvar("cl_jumpspeedcap_min", ""); registercvar("cl_jumpspeedcap_max", ""); + registercvar("cl_multijump", "0"); + + registercvar("cl_spawn_near_teammate", "1"); + gametype = 0; // hud_fields uses strunzone on the titles! @@ -144,24 +129,13 @@ void CSQC_Init(void) // needs to be done so early because of the constants they create static_init(); - CALL_ACCUMULATED_FUNCTION(RegisterTurrets); - CALL_ACCUMULATED_FUNCTION(RegisterNotifications); - CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); - CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels); - - initialize_minigames(); + static_init_late(); + static_init_precache(); // precaches - precache_model("null"); - precache_sound("misc/hit.wav"); - precache_sound("misc/typehit.wav"); - generator_precache(); Projectile_Precache(); - Hook_Precache(); - GibSplash_Precache(); Tuba_Precache(); - CSQCPlayer_Precache(); if(autocvar_cl_reticle) { @@ -323,7 +297,10 @@ void Playerchecker_Think() { // player connected if (!e) - playerslots[i] = e = spawn(); + { + playerslots[i] = e = new(playerslot); + make_pure(e); + } e.sv_entnum = i; e.ping = 0; e.ping_packetloss = 0; @@ -342,8 +319,8 @@ void Porto_Init(); void TrueAim_Init(); void PostInit(void) { - entity playerchecker; - playerchecker = spawn(); + entity playerchecker = new(playerchecker); + make_pure(playerchecker); playerchecker.think = Playerchecker_Think; playerchecker.nextthink = time + 0.2; @@ -395,33 +372,32 @@ float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary) void Ent_RemoveEntCS() {SELFPARAM(); - entcs_receiver[self.sv_entnum] = world; + entcs_receiver[self.sv_entnum] = NULL; } void Ent_ReadEntCS() {SELFPARAM(); - int sf; + make_pure(this); + this.classname = "entcs_receiver"; InterpolateOrigin_Undo(); + int sf = ReadByte(); - self.classname = "entcs_receiver"; - sf = ReadByte(); - - if(sf & 1) + if(sf & BIT(0)) self.sv_entnum = ReadByte(); - if(sf & 2) + if (sf & BIT(1)) { self.origin_x = ReadShort(); self.origin_y = ReadShort(); self.origin_z = ReadShort(); setorigin(self, self.origin); } - if(sf & 4) + if (sf & BIT(2)) { self.angles_y = ReadByte() * 360.0 / 256; self.angles_x = self.angles_z = 0; } - if(sf & 8) + if (sf & BIT(3)) self.healthvalue = ReadByte() * 10; - if(sf & 16) + if (sf & BIT(4)) self.armorvalue = ReadByte() * 10; entcs_receiver[self.sv_entnum] = self; @@ -446,6 +422,7 @@ void Ent_RemovePlayerScore() void Ent_ReadPlayerScore() {SELFPARAM(); + make_pure(this); int i, n; bool isNew; entity o; @@ -468,9 +445,13 @@ void Ent_ReadPlayerScore() self.sv_entnum = n; - if (!(playerslots[self.sv_entnum])) - playerslots[self.sv_entnum] = spawn(); - o = self.owner = playerslots[self.sv_entnum]; + o = playerslots[self.sv_entnum]; + if (!o) + { + o = playerslots[self.sv_entnum] = new(playerslot); + make_pure(o); + } + self.owner = o; o.sv_entnum = self.sv_entnum; o.gotscores = 1; @@ -504,6 +485,7 @@ void Ent_ReadPlayerScore() void Ent_ReadTeamScore() {SELFPARAM(); + make_pure(this); int i; entity o; @@ -533,6 +515,7 @@ void Ent_ReadTeamScore() void Ent_ClientData() { + make_pure(self); float newspectatee_status; int f = ReadByte(); @@ -582,11 +565,12 @@ void Ent_ClientData() void Ent_Nagger() { + make_pure(self); int i, j, b, f; int nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS - if(!(nags & 4)) + if(!(nags & BIT(2))) { if(vote_called_vote) strunzone(vote_called_vote); @@ -598,7 +582,7 @@ void Ent_Nagger() vote_active = 1; } - if(nags & 64) + if(nags & BIT(6)) { vote_yescount = ReadByte(); vote_nocount = ReadByte(); @@ -606,7 +590,7 @@ void Ent_Nagger() vote_highlighted = ReadChar(); } - if(nags & 128) + if(nags & BIT(7)) { if(vote_called_vote) strunzone(vote_called_vote); @@ -628,15 +612,16 @@ void Ent_Nagger() } } - ready_waiting = (nags & 1); - ready_waiting_for_me = (nags & 2); - vote_waiting = (nags & 4); - vote_waiting_for_me = (nags & 8); - warmup_stage = (nags & 16); + ready_waiting = (nags & BIT(0)); + ready_waiting_for_me = (nags & BIT(1)); + vote_waiting = (nags & BIT(2)); + vote_waiting_for_me = (nags & BIT(3)); + warmup_stage = (nags & BIT(4)); } void Ent_EliminatedPlayers() { + make_pure(self); int i, j, b, f; int sf = ReadByte(); @@ -658,45 +643,40 @@ void Ent_EliminatedPlayers() void Ent_RandomSeed() { - float s; + make_pure(self); prandom_debug(); - s = ReadShort(); + float s = ReadShort(); psrandom(s); } -void Ent_ReadAccuracy(void) +void Ent_ReadAccuracy() { - int f, w; + make_pure(self); int sf = ReadInt24_t(); - if(sf == 0) - { - for(w = 0; w <= WEP_LAST - WEP_FIRST; ++w) + if (sf == 0) { + for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w) weapon_accuracy[w] = -1; return; } - for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w) - { - if(sf & f) - { + int f = 1; + for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w) { + if (sf & f) { int b = ReadByte(); - if(b == 0) + if (b == 0) weapon_accuracy[w] = -1; - else if(b == 255) + else if (b == 255) weapon_accuracy[w] = 1.0; // no better error handling yet, sorry else weapon_accuracy[w] = (b - 1.0) / 100.0; } - if(f == 0x800000) - f = 1; - else - f *= 2; + f = (f == 0x800000) ? 1 : f * 2; } } -void Spawn_Draw(void) -{SELFPARAM(); - pointparticles(self.cnt, self.origin + '0 0 28', '0 0 2', bound(0, frametime, 0.1)); +void Spawn_Draw(entity this) +{ + __pointparticles(this.cnt, this.origin + '0 0 28', '0 0 2', bound(0, frametime, 0.1)); } void Ent_ReadSpawnPoint(float is_new) // entity for spawnpoint @@ -707,11 +687,11 @@ void Ent_ReadSpawnPoint(float is_new) // entity for spawnpoint spn_origin.y = ReadShort(); spn_origin.z = ReadShort(); - if(is_new) - { + //if(is_new) + //{ self.origin = spn_origin; setsize(self, PL_MIN_CONST, PL_MAX_CONST); - droptofloor(); + //droptofloor(); /*if(autocvar_cl_spawn_point_model) // needs a model first { @@ -740,7 +720,7 @@ void Ent_ReadSpawnPoint(float is_new) // entity for spawnpoint self.draw = Spawn_Draw; } - } + //} //printf("Ent_ReadSpawnPoint(is_new = %d); origin = %s, team = %d, effect = %d\n", is_new, vtos(self.origin), teamnum, self.cnt); } @@ -766,16 +746,16 @@ void Ent_ReadSpawnEvent(float is_new) { switch(teamnum) { - case NUM_TEAM_1: pointparticles(particleeffectnum(EFFECT_SPAWN_RED), self.origin, '0 0 0', 1); break; - case NUM_TEAM_2: pointparticles(particleeffectnum(EFFECT_SPAWN_BLUE), self.origin, '0 0 0', 1); break; - case NUM_TEAM_3: pointparticles(particleeffectnum(EFFECT_SPAWN_YELLOW), self.origin, '0 0 0', 1); break; - case NUM_TEAM_4: pointparticles(particleeffectnum(EFFECT_SPAWN_PINK), self.origin, '0 0 0', 1); break; - default: pointparticles(particleeffectnum(EFFECT_SPAWN_NEUTRAL), self.origin, '0 0 0', 1); break; + case NUM_TEAM_1: pointparticles(EFFECT_SPAWN_RED, self.origin, '0 0 0', 1); break; + case NUM_TEAM_2: pointparticles(EFFECT_SPAWN_BLUE, self.origin, '0 0 0', 1); break; + case NUM_TEAM_3: pointparticles(EFFECT_SPAWN_YELLOW, self.origin, '0 0 0', 1); break; + case NUM_TEAM_4: pointparticles(EFFECT_SPAWN_PINK, self.origin, '0 0 0', 1); break; + default: pointparticles(EFFECT_SPAWN_NEUTRAL, self.origin, '0 0 0', 1); break; } } if(autocvar_cl_spawn_event_sound) { - sound(self, CH_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTEN_NORM); + sound(self, CH_TRIGGER, SND_SPAWN, VOL_BASE, ATTEN_NORM); } } } @@ -802,16 +782,15 @@ void Ent_RadarLink(); void Ent_Init(); void Ent_ScoresInfo(); void CSQC_Ent_Update(float bIsNewEntity) -{SELFPARAM(); - float t; - float savetime; - t = ReadByte(); +{ + SELFPARAM(); + int t = ReadByte(); if(autocvar_developer_csqcentities) - LOG_INFOF("CSQC_Ent_Update(%d) with self=%i self.entnum=%d self.enttype=%d t=%d\n", bIsNewEntity, self, self.entnum, self.enttype, t); + LOG_INFOF("CSQC_Ent_Update(%d) with self=%i self.entnum=%d self.enttype=%d t=%d\n", bIsNewEntity, this, this.entnum, this.enttype, t); // set up the "time" global for received entities to be correct for interpolation purposes - savetime = time; + float savetime = time; if(servertime) { time = servertime; @@ -824,14 +803,13 @@ void CSQC_Ent_Update(float bIsNewEntity) } #ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED - if(self.enttype) + if(this.enttype) { - if(t != self.enttype || bIsNewEntity) + if(t != this.enttype || bIsNewEntity) { - //print("A CSQC entity changed its type!\n"); - LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(self), self.entnum, self.enttype, t); + LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(this), this.entnum, this.enttype, t); Ent_Remove(); - clearentity(self); + clearentity(this); bIsNewEntity = 1; } } @@ -839,78 +817,83 @@ void CSQC_Ent_Update(float bIsNewEntity) { if(!bIsNewEntity) { - LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(self), self.entnum, t); + LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(this), this.entnum, t); bIsNewEntity = 1; } } #endif - self.enttype = t; + this.enttype = t; + bool done = false; + FOREACH(LinkedEntities, it.m_id == t, LAMBDA( + it.m_read(this, bIsNewEntity); + done = true; + break; + )); + if (!done) switch(t) { - case ENT_CLIENT_MUTATOR: { + #define HANDLE(t) case t: this.classname = #t; this.sourceLocFile = __FILE__; this.sourceLocLine = __LINE__; + HANDLE(ENT_CLIENT_MUTATOR) { int mutID = ReadMutator(); if (!MUTATOR_CALLHOOK(CSQC_Ent_Update, mutID, bIsNewEntity)) - error(sprintf("Unknown mutator type in CSQC_Ent_Update (mutID: %d, edict: %d, classname: %s)\n", mutID, num_for_edict(self), self.classname)); + error(sprintf("Unknown mutator type in CSQC_Ent_Update (mutID: %d, edict: %d, classname: %s)\n", mutID, num_for_edict(this), this.classname)); break; } - case ENT_CLIENT_ENTCS: Ent_ReadEntCS(); break; - case ENT_CLIENT_SCORES: Ent_ReadPlayerScore(); break; - case ENT_CLIENT_TEAMSCORES: Ent_ReadTeamScore(); break; - case ENT_CLIENT_POINTPARTICLES: Ent_PointParticles(); break; - case ENT_CLIENT_RAINSNOW: Ent_RainOrSnow(); break; - case ENT_CLIENT_LASER: Ent_Laser(); break; - case ENT_CLIENT_NAGGER: Ent_Nagger(); break; - case ENT_CLIENT_ELIMINATEDPLAYERS: Ent_EliminatedPlayers(); break; - case ENT_CLIENT_RADARLINK: Ent_RadarLink(); break; - case ENT_CLIENT_PROJECTILE: Ent_Projectile(); break; - case ENT_CLIENT_GIBSPLASH: Ent_GibSplash(bIsNewEntity); break; - case ENT_CLIENT_DAMAGEINFO: Ent_DamageInfo(bIsNewEntity); break; - case ENT_CLIENT_INIT: Ent_Init(); break; - case ENT_CLIENT_SCORES_INFO: Ent_ScoresInfo(); break; - case ENT_CLIENT_MAPVOTE: Ent_MapVote(); break; - case ENT_CLIENT_CLIENTDATA: Ent_ClientData(); break; - case ENT_CLIENT_RANDOMSEED: Ent_RandomSeed(); break; - case ENT_CLIENT_WALL: Ent_Wall(); break; - case ENT_CLIENT_MODELEFFECT: Ent_ModelEffect(bIsNewEntity); break; - case ENT_CLIENT_TUBANOTE: Ent_TubaNote(bIsNewEntity); break; - case ENT_CLIENT_WARPZONE: WarpZone_Read(bIsNewEntity); break; - case ENT_CLIENT_WARPZONE_CAMERA: WarpZone_Camera_Read(bIsNewEntity); break; - case ENT_CLIENT_WARPZONE_TELEPORTED: WarpZone_Teleported_Read(bIsNewEntity); break; - case ENT_CLIENT_TRIGGER_MUSIC: Ent_ReadTriggerMusic(); break; - case ENT_CLIENT_HOOK: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK); break; - case ENT_CLIENT_INVENTORY: Inventory_Read(self); break; - case ENT_CLIENT_ARC_BEAM: Ent_ReadArcBeam(bIsNewEntity); break; - case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break; - case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break; - case ENT_CLIENT_TURRET: ent_turret(); break; - case ENT_CLIENT_GENERATOR: ent_generator(); break; - case ENT_CLIENT_CONTROLPOINT_ICON: ent_cpicon(); break; - case ENT_CLIENT_MODEL: CSQCModel_Read(bIsNewEntity); break; - case ENT_CLIENT_ITEM: ItemRead(bIsNewEntity); break; - case ENT_CLIENT_BUMBLE_RAYGUN: bumble_raygun_read(bIsNewEntity); break; - case ENT_CLIENT_SPAWNPOINT: Ent_ReadSpawnPoint(bIsNewEntity); break; - case ENT_CLIENT_SPAWNEVENT: Ent_ReadSpawnEvent(bIsNewEntity); break; - case ENT_CLIENT_NOTIFICATION: Read_Notification(bIsNewEntity); break; - case ENT_CLIENT_HEALING_ORB: ent_healer(); break; - case ENT_CLIENT_MINIGAME: ent_read_minigame(); break; - case ENT_CLIENT_VIEWLOC: ent_viewloc(); break; - case ENT_CLIENT_VIEWLOC_TRIGGER: ent_viewloc_trigger(); break; - case ENT_CLIENT_LADDER: ent_func_ladder(); break; - case ENT_CLIENT_TRIGGER_PUSH: ent_trigger_push(); break; - case ENT_CLIENT_TARGET_PUSH: ent_target_push(); break; - case ENT_CLIENT_CONVEYOR: ent_conveyor(); break; - case ENT_CLIENT_DOOR: ent_door(); break; - case ENT_CLIENT_PLAT: ent_plat(); break; - case ENT_CLIENT_SWAMP: ent_swamp(); break; - case ENT_CLIENT_CORNER: ent_corner(); break; - case ENT_CLIENT_KEYLOCK: ent_keylock(); break; - case ENT_CLIENT_TRAIN: ent_train(); break; - case ENT_CLIENT_TRIGGER_IMPULSE: ent_trigger_impulse(); break; - case ENT_CLIENT_EFFECT: Read_Effect(bIsNewEntity); break; - + HANDLE(ENT_CLIENT_ENTCS) Ent_ReadEntCS(); break; + HANDLE(ENT_CLIENT_SCORES) Ent_ReadPlayerScore(); break; + HANDLE(ENT_CLIENT_TEAMSCORES) Ent_ReadTeamScore(); break; + HANDLE(ENT_CLIENT_POINTPARTICLES) Ent_PointParticles(); break; + HANDLE(ENT_CLIENT_RAINSNOW) Ent_RainOrSnow(); break; + HANDLE(ENT_CLIENT_LASER) Ent_Laser(); break; + HANDLE(ENT_CLIENT_NAGGER) Ent_Nagger(); break; + HANDLE(ENT_CLIENT_ELIMINATEDPLAYERS) Ent_EliminatedPlayers(); break; + HANDLE(ENT_CLIENT_RADARLINK) Ent_RadarLink(); break; + HANDLE(ENT_CLIENT_PROJECTILE) Ent_Projectile(); break; + HANDLE(ENT_CLIENT_DAMAGEINFO) Ent_DamageInfo(bIsNewEntity); break; + HANDLE(ENT_CLIENT_INIT) Ent_Init(); break; + HANDLE(ENT_CLIENT_SCORES_INFO) Ent_ScoresInfo(); break; + HANDLE(ENT_CLIENT_MAPVOTE) Ent_MapVote(); break; + HANDLE(ENT_CLIENT_CLIENTDATA) Ent_ClientData(); break; + HANDLE(ENT_CLIENT_RANDOMSEED) Ent_RandomSeed(); break; + HANDLE(ENT_CLIENT_WALL) Ent_Wall(); break; + HANDLE(ENT_CLIENT_MODELEFFECT) Ent_ModelEffect(bIsNewEntity); break; + HANDLE(ENT_CLIENT_TUBANOTE) Ent_TubaNote(bIsNewEntity); break; + HANDLE(ENT_CLIENT_WARPZONE) WarpZone_Read(bIsNewEntity); break; + HANDLE(ENT_CLIENT_WARPZONE_CAMERA) WarpZone_Camera_Read(bIsNewEntity); break; + HANDLE(ENT_CLIENT_WARPZONE_TELEPORTED) WarpZone_Teleported_Read(bIsNewEntity); break; + HANDLE(ENT_CLIENT_TRIGGER_MUSIC) Ent_ReadTriggerMusic(); break; + HANDLE(ENT_CLIENT_HOOK) Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK); break; + HANDLE(ENT_CLIENT_INVENTORY) Inventory_Read(this); break; + HANDLE(ENT_CLIENT_ARC_BEAM) Ent_ReadArcBeam(bIsNewEntity); break; + HANDLE(ENT_CLIENT_ACCURACY) Ent_ReadAccuracy(); break; + HANDLE(ENT_CLIENT_AUXILIARYXHAIR) Net_AuXair2(bIsNewEntity); break; + HANDLE(ENT_CLIENT_TURRET) ent_turret(); break; + HANDLE(ENT_CLIENT_GENERATOR) ent_generator(); break; + HANDLE(ENT_CLIENT_CONTROLPOINT_ICON) ent_cpicon(this); break; + HANDLE(ENT_CLIENT_MODEL) CSQCModel_Read(bIsNewEntity); break; + HANDLE(ENT_CLIENT_ITEM) ItemRead(bIsNewEntity); break; + HANDLE(ENT_CLIENT_BUMBLE_RAYGUN) bumble_raygun_read(bIsNewEntity); break; + HANDLE(ENT_CLIENT_SPAWNPOINT) Ent_ReadSpawnPoint(bIsNewEntity); break; + HANDLE(ENT_CLIENT_SPAWNEVENT) Ent_ReadSpawnEvent(bIsNewEntity); break; + HANDLE(ENT_CLIENT_NOTIFICATION) Read_Notification(bIsNewEntity); break; + HANDLE(ENT_CLIENT_MINIGAME) ent_read_minigame(); break; + HANDLE(ENT_CLIENT_VIEWLOC) ent_viewloc(); break; + HANDLE(ENT_CLIENT_VIEWLOC_TRIGGER) ent_viewloc_trigger(); break; + HANDLE(ENT_CLIENT_LADDER) ent_func_ladder(); break; + HANDLE(ENT_CLIENT_TRIGGER_PUSH) ent_trigger_push(); break; + HANDLE(ENT_CLIENT_TARGET_PUSH) ent_target_push(); break; + HANDLE(ENT_CLIENT_CONVEYOR) ent_conveyor(); break; + HANDLE(ENT_CLIENT_DOOR) ent_door(); break; + HANDLE(ENT_CLIENT_PLAT) ent_plat(); break; + HANDLE(ENT_CLIENT_SWAMP) ent_swamp(); break; + HANDLE(ENT_CLIENT_CORNER) ent_corner(); break; + HANDLE(ENT_CLIENT_KEYLOCK) ent_keylock(); break; + HANDLE(ENT_CLIENT_TRAIN) ent_train(); break; + HANDLE(ENT_CLIENT_TRIGGER_IMPULSE) ent_trigger_impulse(); break; + #undef HANDLE default: - //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype)); - error(sprintf("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n", self.enttype, num_for_edict(self), self.classname)); + //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), this.enttype)); + error(sprintf("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n", this.enttype, num_for_edict(this), this.classname)); break; } @@ -932,13 +915,13 @@ void Ent_Remove() if(self.snd_looping > 0) { - sound(self, self.snd_looping, "misc/null.wav", VOL_BASE, autocvar_g_jetpack_attenuation); + sound(self, self.snd_looping, SND_Null, VOL_BASE, autocvar_g_jetpack_attenuation); self.snd_looping = 0; } self.enttype = 0; self.classname = ""; - self.draw = menu_sub_null; + self.draw = draw_null; self.entremove = menu_sub_null; // TODO possibly set more stuff to defaults } @@ -981,7 +964,7 @@ void CSQC_Parse_Print(string strMessage) if(autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_Print(\"%s\")\n", strMessage); - LOG_INFO(ColorTranslateRGB(strMessage)); + print(ColorTranslateRGB(strMessage)); } // CSQC_Parse_CenterPrint : Provides the centerprint_hud string in the first parameter that the server provided. @@ -1009,7 +992,7 @@ void Gamemode_Init(); void Ent_ScoresInfo() {SELFPARAM(); int i; - self.classname = "ent_client_scores_info"; + make_pure(this); gametype = ReadInt24_t(); HUD_ModIcons_SetFunc(); for(i = 0; i < MAX_SCORE; ++i) @@ -1032,7 +1015,7 @@ void Ent_ScoresInfo() void Ent_Init() {SELFPARAM(); - self.classname = "ent_client_init"; + make_pure(this); nb_pb_period = ReadByte() / 32; //Accuracy of 1/32th @@ -1068,6 +1051,8 @@ void Ent_Init() g_trueaim_minrange = ReadCoord(); g_balance_porto_secondary = ReadByte(); + MUTATOR_CALLHOOK(Ent_Init); + if(!postinit) PostInit(); } @@ -1271,7 +1256,7 @@ void Net_WeaponComplain() // CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer. // You must ALWAYS first acquire the temporary ID, which is sent as a byte. // Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event. -float CSQC_Parse_TempEntity() +bool CSQC_Parse_TempEntity() { // Acquire TE ID int nTEID = ReadByte(); @@ -1279,6 +1264,10 @@ float CSQC_Parse_TempEntity() if (autocvar_developer_csqcentities) LOG_INFOF("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID); + FOREACH(TempEntities, it.m_id == nTEID, LAMBDA( + it.m_read(NULL, true); + return true; + )); switch (nTEID) { case TE_CSQC_MUTATOR: