]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Move MOVETYPE_FLY to ecs
authorTimePath <andrew.hardaker1995@gmail.com>
Sat, 25 Jun 2016 03:04:43 +0000 (13:04 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Sat, 25 Jun 2016 03:47:28 +0000 (13:47 +1000)
13 files changed:
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/dpdefs/doc.md
qcsrc/ecs/_lib.inc
qcsrc/ecs/_lib.qh [new file with mode: 0644]
qcsrc/ecs/components/physics.qh
qcsrc/ecs/systems/physics.qc
qcsrc/lib/_all.inc
qcsrc/lib/iter.qh
qcsrc/lib/vector.qh
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/sv_main.qc

index 8100f6b7972e0e7d01c1a3a59b1e1f0934c7c3f1..caa62e03607a408195f55151ffda88e348c46738 100644 (file)
@@ -240,6 +240,7 @@ void trigger_push_touch(entity this)
        if (other.flags & FL_PROJECTILE)
        {
                other.angles = vectoangles (other.velocity);
+               other.com_phys_gravity_factor = 1;
                switch(other.movetype)
                {
                        case MOVETYPE_FLY:
index 09cb77c8bd9a5b2774d8178f48bccc195bead691..1fc3cb4b1a71ac0ae217beeaad83106652cfe2cc 100644 (file)
@@ -202,8 +202,12 @@ void W_Electro_TouchExplode(entity this)
        W_Electro_Explode(this);
 }
 
+
+void sys_phys_update_single(entity this);
+
 void W_Electro_Bolt_Think(entity this)
 {
+       sys_phys_update_single(this);
        if(time >= this.ltime)
        {
                this.use(this, NULL, NULL);
@@ -252,6 +256,7 @@ void W_Electro_Bolt_Think(entity this)
                        { this.nextthink = min(time + WEP_CVAR_PRI(electro, midaircombo_interval), this.ltime); }
        }
        else { this.nextthink = this.ltime; }
+       this.nextthink = time;
 }
 
 void W_Electro_Attack_Bolt(Weapon thiswep, entity actor)
@@ -285,7 +290,7 @@ void W_Electro_Attack_Bolt(Weapon thiswep, entity actor)
        proj.projectiledeathtype = WEP_ELECTRO.m_id;
        setorigin(proj, w_shotorg);
 
-       proj.movetype = MOVETYPE_FLY;
+       if (IS_CSQC) proj.movetype = MOVETYPE_FLY;
        W_SetupProjVelocity_PRI(proj, electro);
        proj.angles = vectoangles(proj.velocity);
        settouch(proj, W_Electro_TouchExplode);
@@ -296,6 +301,8 @@ void W_Electro_Attack_Bolt(Weapon thiswep, entity actor)
        CSQCProjectile(proj, true, PROJECTILE_ELECTRO_BEAM, true);
 
        MUTATOR_CALLHOOK(EditProjectile, actor, proj);
+       proj.com_phys_pos = proj.origin;
+       proj.com_phys_vel = proj.velocity;
 }
 
 void W_Electro_Orb_Touch(entity this)
index 240eec0c1cf5d7fd1f8a79e170eb407917347e06..01fa43aaf28d2669bdc0132b2ecc5df5ad503c80 100644 (file)
@@ -55,6 +55,21 @@ float sound_starttime;
 
 # SVQC
 
+Main loop:
+* SV_Physics()
+    * StartFrame()
+    * if (force_retouch)
+        * foreach entity:
+            * .touch()
+    * foreach client:
+        * PlayerPreThink()
+        * .think()
+        * PlayerPostThink()
+    * foreach nonclient:
+        * .think()
+    * EndFrame()
+
+
 ```
 
 .entity clientcamera;
index ef8e67c58a907020961cde32d164e49472df35f3..726f693e9e8149e36ce0af9c29c6d81942c40382 100644 (file)
@@ -1,59 +1,4 @@
-/** Components always interpolate from the previous state */
-#define COMPONENT(com) \
-       void com_##com##_interpolate(entity it, float a); \
-       .bool com_##com
-
-#define FOREACH_COMPONENT(com, body) FOREACH_ENTITY_FLOAT(com_##com, true, body)
-
-
-#define EVENT(T, args) .bool evt_##T##_listener; .void args evt_##T
-
-#define emit(T, ...) \
-       MACRO_BEGIN \
-       FOREACH_ENTITY_FLOAT_ORDERED(evt_##T##_listener, true, it.evt_##T(__VA_ARGS__)); \
-       MACRO_END
-
-#define subscribe(listener, T, fn) \
-       MACRO_BEGIN \
-       listener.evt_##T = (fn); \
-       listener.evt_##T##_listener = true; \
-       MACRO_END
-
-
-/**
- * framelimit 0 is no limit, interpolation does not apply
- * framerate below minfps will result in less than 100% speed
- */
-#define SYSTEM(sys, frameLimit, minfps) \
-       void sys_##sys##_update(entity this, float dt); \
-       float autocvar_xon_sys_##sys##_dt = ((frameLimit) ? (1 / (frameLimit)) : 0); \
-       float autocvar_xon_sys_##sys##_minfps = (1 / (1 / (minfps)))
-
-#define SYSTEM_UPDATE(sys) \
-       MACRO_BEGIN \
-       static float t = 0; \
-       float dt = autocvar_xon_sys_##sys##_dt; \
-       float minfps = autocvar_xon_sys_##sys##_minfps; \
-       static float accumulator = 0; \
-       float a = 0; \
-       if (dt) { \
-               accumulator += min(frametime, 1 / (minfps)); \
-       } else { \
-               accumulator += frametime; \
-               dt = accumulator; \
-               a = 1; \
-       } \
-       while (accumulator >= dt) \
-       { \
-               time = t; \
-               FOREACH_COMPONENT(sys, sys_##sys##_update(it, dt)); \
-               t += dt; \
-               accumulator -= dt; \
-       } \
-       if (!a) a = accumulator / dt; \
-       FOREACH_COMPONENT(sys, com_##sys##_interpolate(it, a)); \
-       MACRO_END
-
+#include "_lib.qh"
 
 #include "_mod.inc"
 #include "components/_mod.inc"
diff --git a/qcsrc/ecs/_lib.qh b/qcsrc/ecs/_lib.qh
new file mode 100644 (file)
index 0000000..a617c73
--- /dev/null
@@ -0,0 +1,57 @@
+#pragma once
+
+/** Components always interpolate from the previous state */
+#define COMPONENT(com) \
+       void com_##com##_interpolate(entity it, float a); \
+       .bool com_##com
+
+#define FOREACH_COMPONENT(com, body) FOREACH_ENTITY_FLOAT(com_##com, true, body)
+
+
+#define EVENT(T, args) .bool evt_##T##_listener; .void args evt_##T
+
+#define emit(T, ...) \
+       MACRO_BEGIN \
+       FOREACH_ENTITY_FLOAT_ORDERED(evt_##T##_listener, true, it.evt_##T(__VA_ARGS__)); \
+       MACRO_END
+
+#define subscribe(listener, T, fn) \
+       MACRO_BEGIN \
+       listener.evt_##T = (fn); \
+       listener.evt_##T##_listener = true; \
+       MACRO_END
+
+
+/**
+ * framelimit 0 is no limit, interpolation does not apply
+ * framerate below minfps will result in less than 100% speed
+ */
+#define SYSTEM(sys, frameLimit, minfps) \
+       void sys_##sys##_update(entity this, float dt); \
+       float autocvar_xon_sys_##sys##_dt = ((frameLimit) ? (1 / (frameLimit)) : 0); \
+       float autocvar_xon_sys_##sys##_minfps = (1 / (1 / (minfps)))
+
+#define SYSTEM_UPDATE(sys) \
+       MACRO_BEGIN \
+       static float t = 0; \
+       float dt = autocvar_xon_sys_##sys##_dt; \
+       float minfps = autocvar_xon_sys_##sys##_minfps; \
+       static float accumulator = 0; \
+       float a = 0; \
+       if (dt) { \
+               accumulator += min(frametime, 1 / (minfps)); \
+       } else { \
+               accumulator += frametime; \
+               dt = accumulator; \
+               a = 1; \
+       } \
+       while (accumulator >= dt) \
+       { \
+               time = t; \
+               FOREACH_COMPONENT(sys, sys_##sys##_update(it, dt)); \
+               t += dt; \
+               accumulator -= dt; \
+       } \
+       if (!a) a = accumulator / dt; \
+       FOREACH_COMPONENT(sys, com_##sys##_interpolate(it, a)); \
+       MACRO_END
index 14e010ab2d6bb46363607407b2cbf9ea1fb02051..377e1d1d8e27ca602cca0f92d9c64ef6a44ae657 100644 (file)
@@ -15,6 +15,7 @@ COMPONENT(phys);
 .float com_phys_friction;
 
 .vector com_phys_gravity;
+.float com_phys_gravity_factor;
 // TODO: remove
 .bool com_phys_ground;
 .bool com_phys_air;
index 14f1d30ab8cd028e741c92651a84b9080cba0f7b..7267a48644303ad98e939bc0b74782d0e2528c6c 100644 (file)
@@ -4,9 +4,14 @@
 .int disableclientprediction;
 
 void sys_phys_simulate(entity this, float dt);
+void sys_phys_simulate_simple(entity this, float dt);
 
 void sys_phys_update(entity this, float dt)
 {
+       if (!IS_CLIENT(this)) {
+               sys_phys_simulate_simple(this, dt);
+               return;
+       }
        sys_in_update(this, dt);
 
        sys_phys_fix(this, dt);
@@ -150,6 +155,7 @@ void sys_phys_update(entity this, float dt)
        this.lastclassname = this.classname;
 }
 
+/** for players */
 void sys_phys_simulate(entity this, float dt)
 {
        const vector g = -this.com_phys_gravity;
@@ -391,3 +397,97 @@ void sys_phys_simulate(entity this, float dt)
        }
        PM_ClientMovement_Move(this);
 }
+
+.entity groundentity;
+/** for other entities */
+void sys_phys_simulate_simple(entity this, float dt)
+{
+       vector mn = this.mins;
+       vector mx = this.maxs;
+
+       vector g = '0 0 0';
+       if (this.com_phys_gravity_factor && !g) g = '0 0 -1' * PHYS_GRAVITY(NULL);
+
+       vector acc = this.com_phys_acc;
+       vector vel = this.com_phys_vel;
+       vector pos = this.com_phys_pos;
+
+       // SV_Physics_Toss
+
+       vel += g * dt;
+
+       this.angles += dt * this.avelocity;
+       float movetime = dt;
+       for (int i = 0; i < MAX_CLIP_PLANES && movetime > 0; i++) {
+               vector push = vel * movetime;
+               vector p0 = pos;
+               vector p1 = p0 + push;
+               // SV_PushEntity
+               tracebox(p0, mn, mx, p1, MOVE_NORMAL, this);
+               if (!trace_startsolid) {
+                       bool hit = trace_fraction < 1;
+                       pos = trace_endpos;
+                       entity ent = trace_ent;
+                       // SV_LinkEdict_TouchAreaGrid
+                       if (this.solid != SOLID_NOT) {
+                               FOREACH_ENTITY_RADIUS_ORDERED(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin), true, {
+                                       if (it.solid != SOLID_TRIGGER || it == this) continue;
+                                       if (gettouch(it) && boxesoverlap(it.absmin, it.absmax, this.absmin, this.absmax)) {
+                                           // SV_LinkEdict_TouchAreaGrid_Call
+                                           trace_allsolid = false;
+                                           trace_startsolid = false;
+                                           trace_fraction = 1;
+                                           trace_inwater = false;
+                                           trace_inopen = true;
+                                           trace_endpos = it.origin;
+                                           trace_plane_normal = '0 0 1';
+                                           trace_plane_dist = 0;
+                                           trace_ent = this;
+                                           trace_dpstartcontents = 0;
+                                           trace_dphitcontents = 0;
+                                           trace_dphitq3surfaceflags = 0;
+                                           trace_dphittexturename = string_null;
+                                           gettouch(it)((other = this, it));
+                                           vel = this.velocity;
+                                       }
+                               });
+                       }
+                       if (hit && this.solid >= SOLID_TRIGGER && (!IS_ONGROUND(this) || this.groundentity != ent)) {
+                               // SV_Impact (ent, trace);
+                               tracebox(p0, mn, mx, p1, MOVE_NORMAL, this);
+                               void(entity) touched = gettouch(this);
+                               if (touched && this.solid != SOLID_NOT) {
+                                       touched((other = ent, this));
+                               }
+                               void(entity) touched2 = gettouch(ent);
+                               if (this && ent && touched2 && ent.solid != SOLID_NOT) {
+                                       trace_endpos = ent.origin;
+                                       trace_plane_normal *= -1;
+                                       trace_plane_dist *= -1;
+                                       trace_ent = this;
+                                       trace_dpstartcontents = 0;
+                                       trace_dphitcontents = 0;
+                                       trace_dphitq3surfaceflags = 0;
+                                       trace_dphittexturename = string_null;
+                                       touched2((other = this, ent));
+                               }
+                       }
+               }
+               // end SV_PushEntity
+               if (wasfreed(this)) { return; }
+               tracebox(p0, mn, mx, p1, MOVE_NORMAL, this);
+               if (trace_fraction == 1) { break; }
+               movetime *= 1 - min(1, trace_fraction);
+               ClipVelocity(vel, trace_plane_normal, vel, 1);
+       }
+
+       this.com_phys_acc = acc;
+       this.com_phys_vel = vel;
+       this.com_phys_pos = pos;
+       setorigin(this, this.com_phys_pos);
+}
+
+void sys_phys_update_single(entity this)
+{
+       sys_phys_simulate_simple(this, frametime);
+}
index d121f1e661371e121a65d56e358ebb4ddbc39ac3..1d63a28e540425d8e6b12e5fcbf0fd853f652aca 100644 (file)
@@ -248,3 +248,8 @@ void    isnt_bool(float this) { print(ftos(this)); }
        #define CSQC_Ent_Remove _CSQC_Ent_Remove
 #endif
 #undef ENGINE_EVENT
+
+#ifndef MENUQC
+       #include <ecs/_lib.qh>
+       #include <ecs/components/_mod.qh>
+#endif
index c21d02121347d34b79042a31809ccd421693ab3f..49c2a41e856257b76214284d9ac1ae455561b2e8 100644 (file)
             if (cond) LAMBDA(body) \
         } \
     } MACRO_END
+#define MUTEX_LOCK(this) MACRO_BEGIN \
+       if (this) LOG_SEVEREF("Loop mutex held by %s", this); \
+       this = __FUNC__; \
+MACRO_END
+#define MUTEX_UNLOCK(this) MACRO_BEGIN \
+       this = string_null; \
+MACRO_END
 #define _FOREACH_ENTITY_FIND_UNORDERED(id, T, fld, match, cond, body) \
        MACRO_BEGIN { \
-               if (_FOREACH_ENTITY_FIND_##T##_##id##mutex) LOG_SEVEREF("Loop mutex held by %s", _FOREACH_ENTITY_FIND_##T##_##id##mutex); \
-               _FOREACH_ENTITY_FIND_##T##_##id##mutex = __FUNC__; \
+               MUTEX_LOCK(_FOREACH_ENTITY_FIND_##T##_##id##mutex); \
                entity _foundchain_first = _findchain##T##_tofield(fld, match, _FOREACH_ENTITY_FIND_##T##_next##id); \
                FOREACH_LIST(_foundchain, _FOREACH_ENTITY_FIND_##T##_next##id, cond, body); \
-               _FOREACH_ENTITY_FIND_##T##_##id##mutex = string_null; \
+               MUTEX_UNLOCK(_FOREACH_ENTITY_FIND_##T##_##id##mutex); \
        } MACRO_END
 
 #define FOREACH_ENTITY(cond, body) ORDERED(FOREACH_ENTITY)(cond, body)
 
 #ifndef MENUQC
 entity(vector org, float rad, .entity tofield) _findchainradius_tofield = #22;
-#define FOREACH_ENTITY_RADIUS(org, dist, cond, body) FOREACH_ENTITY_RADIUS_UNORDERED(org, dist, cond, body)
+#define FOREACH_ENTITY_RADIUS(org, dist, cond, body) ORDERED(FOREACH_ENTITY_RADIUS)(org, dist, cond, body)
 .entity _FOREACH_ENTITY_FIND_radius_next; noref string _FOREACH_ENTITY_FIND_radius_mutex;
 #define FOREACH_ENTITY_RADIUS_UNORDERED(org, dist, cond, body) _FOREACH_ENTITY_FIND_UNORDERED(, radius, org, dist, cond, body)
+.entity _FOREACH_ENTITY_FIND_radius_nexttmp; noref string _FOREACH_ENTITY_FIND_radius_tmpmutex;
+#define FOREACH_ENTITY_RADIUS_ORDERED(org, dist, cond, body) \
+MACRO_BEGIN \
+       entity _rev_first = NULL; \
+       _FOREACH_ENTITY_FIND_UNORDERED(tmp, radius, org, dist, cond, (it._FOREACH_ENTITY_FIND_radius_nexttmp = _rev_first, _rev_first = it)); \
+       MUTEX_LOCK(_FOREACH_ENTITY_FIND_radius_tmpmutex); \
+       FOREACH_LIST(_rev, _FOREACH_ENTITY_FIND_radius_nexttmp, true, body); \
+       MUTEX_UNLOCK(_FOREACH_ENTITY_FIND_radius_tmpmutex); \
+MACRO_END
 #endif
 
 #define FOREACH_ENTITY_FLOAT(fld, match, body) ORDERED(FOREACH_ENTITY_FLOAT)(fld, match, body)
index 98b15115c8f40af83533683b978d548ac3b7efee..10e8ed8c437f98983b55945e0e938bf9f5d73e0f 100644 (file)
@@ -131,6 +131,17 @@ vector vec_reflect(vector vel, vector norm, float bounce)
        return vel - (1 + bounce) * (vel * norm) * norm;
 }
 
+vector vec_epsilon(vector this, float eps)
+{
+       if (this.x > -eps && this.x < eps) this.x = 0;
+       if (this.y > -eps && this.y < eps) this.y = 0;
+       if (this.z > -eps && this.z < eps) this.z = 0;
+       return this;
+}
+
+#define ClipVelocity(in, normal, out, overbounce) \
+       (out = vec_epsilon(vec_reflect(in, normal, (overbounce) - 1), 0.1))
+
 #ifndef MENUQC
        vector get_corner_position(entity box, int corner)
        {
index c959bafd0efabee4f3d41e7e818c6675d5799cbd..3ae2f27f397b3509fb1919e24972834dc3deb382 100644 (file)
@@ -1983,7 +1983,7 @@ string GotoMap(string m)
                return "Map switch will happen after scoreboard.";
 }
 
-
+void systems_update();
 void EndFrame()
 {
        anticheat_endframe();
@@ -2015,6 +2015,7 @@ void EndFrame()
                PlayerState s = PS(it);
                s.ps_push(s, it);
        });
+       systems_update();
 }
 
 
index 2c206cf1a78112959ba04c9efefd4c966223235f..e4d9156f6653308dbf8df3ab9d45bad3323951a6 100644 (file)
@@ -1031,8 +1031,7 @@ bool SUB_NoImpactCheck(entity this, entity toucher)
        // these stop the projectile from moving, so...
        if(trace_dphitcontents == 0)
        {
-               //dprint("A hit happened with zero hit contents... DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct.\n");
-               LOG_TRACEF("A hit from a projectile happened with no hit contents! DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct. (edict: %d, classname: %s, origin: %s)\n", etof(this), this.classname, vtos(this.origin));
+               LOG_TRACEF("A hit from a projectile happened with no hit contents! DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct. (edict: %i, classname: %s, origin: %v)", this, this.classname, this.origin);
                checkclient(this);
        }
     if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
index 8b4d2c22cf4ecea7cc8300e5c55f7371d40e6713..dc2019792b134bbf826f86ddf232f3402fdf70c3 100644 (file)
@@ -154,6 +154,7 @@ float game_delay_last;
 
 bool autocvar_sv_autopause = true;
 float RedirectionThink();
+void systems_update();
 void sys_phys_update(entity this, float dt);
 void StartFrame()
 {