X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Ftriggers%2Ftrigger%2Fjumppads.qc;h=3c5019a5c38b71a1ddddf0433e4c30c3327e9239;hp=cc71897b18cc1890bab9cb460167b2731cbe0821;hb=38c2e33f2b643b4e9d1878ceb3330cc05406edcc;hpb=bed936bd935a8363fb38a620666c030dcb83ef92 diff --git a/qcsrc/common/triggers/trigger/jumppads.qc b/qcsrc/common/triggers/trigger/jumppads.qc index cc71897b18..3c5019a5c3 100644 --- a/qcsrc/common/triggers/trigger/jumppads.qc +++ b/qcsrc/common/triggers/trigger/jumppads.qc @@ -1,7 +1,6 @@ #include "jumppads.qh" // TODO: split target_push and put it in the target folder #ifdef SVQC -#include "jumppads.qh" #include void trigger_push_use(entity this, entity actor, entity trigger) @@ -9,7 +8,7 @@ void trigger_push_use(entity this, entity actor, entity trigger) if(teamplay) { this.team = actor.team; - this.SendFlags |= 2; + this.SendFlags |= SF_TRIGGER_UPDATE; } } #endif @@ -25,22 +24,20 @@ REGISTER_NET_LINKED(ENT_CLIENT_TARGET_PUSH) tgt - target entity (can be either a point or a model entity; if it is the latter, its midpoint is used) ht - jump height, measured from the higher one of org and tgt's midpoint + pushed_entity - object that is to be pushed Returns: velocity for the jump - the global trigger_push_calculatevelocity_flighttime is set to the total - jump time */ - -vector trigger_push_calculatevelocity(vector org, entity tgt, float ht) +vector trigger_push_calculatevelocity(vector org, entity tgt, float ht, entity pushed_entity) { float grav, sdist, zdist, vs, vz, jumpheight; vector sdir, torg; torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5; - grav = PHYS_GRAVITY(other); - if(PHYS_ENTGRAVITY(other)) - grav *= PHYS_ENTGRAVITY(other); + grav = PHYS_GRAVITY(NULL); + if(pushed_entity && PHYS_ENTGRAVITY(pushed_entity)) + grav *= PHYS_ENTGRAVITY(pushed_entity); zdist = torg.z - org.z; sdist = vlen(torg - org - zdist * '0 0 1'); @@ -88,6 +85,7 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht) if(zdist == 0) solution_x = solution.y; // solution_x is 0 in this case, so don't use it, but rather use solution_y (which will be sqrt(0.5 * jumpheight / grav), actually) + float flighttime; if(zdist < 0) { // down-jump @@ -96,14 +94,14 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht) // almost straight line type // jump apex is before the jump // we must take the larger one - trigger_push_calculatevelocity_flighttime = solution.y; + flighttime = solution.y; } else { // regular jump // jump apex is during the jump // we must take the larger one too - trigger_push_calculatevelocity_flighttime = solution.y; + flighttime = solution.y; } } else @@ -114,17 +112,17 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht) // almost straight line type // jump apex is after the jump // we must take the smaller one - trigger_push_calculatevelocity_flighttime = solution.x; + flighttime = solution.x; } else { // regular jump // jump apex is during the jump // we must take the larger one - trigger_push_calculatevelocity_flighttime = solution.y; + flighttime = solution.y; } } - vs = sdist / trigger_push_calculatevelocity_flighttime; + vs = sdist / flighttime; // finally calculate the velocity return sdir * vs + '0 0 1' * vz; @@ -137,7 +135,7 @@ bool jumppad_push(entity this, entity targ) if(this.enemy) { - targ.velocity = trigger_push_calculatevelocity(targ.origin, this.enemy, this.height); + targ.velocity = trigger_push_calculatevelocity(targ.origin, this.enemy, this.height, targ); } else if(this.target && this.target != "") { @@ -150,7 +148,7 @@ bool jumppad_push(entity this, entity targ) else RandomSelection_AddEnt(e, 1, 1); } - targ.velocity = trigger_push_calculatevelocity(targ.origin, RandomSelection_chosen_ent, this.height); + targ.velocity = trigger_push_calculatevelocity(targ.origin, RandomSelection_chosen_ent, this.height, targ); } else { @@ -208,13 +206,16 @@ bool jumppad_push(entity this, entity targ) centerprint(targ, this.message); } else + { targ.lastteleporttime = time; + targ.lastteleport_origin = targ.origin; + } if (!IS_DEAD(targ)) animdecide_setaction(targ, ANIMACTION_JUMP, true); } else - targ.jumppadcount = true; + targ.jumppadcount = 1; // reset tracking of who pushed you into a hazard (for kill credit) targ.pushltime = 0; @@ -252,7 +253,7 @@ void trigger_push_touch(entity this, entity toucher) return; if(this.team) - if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, toucher))) + if(((this.spawnflags & INVERT_TEAMS) == 0) == (DIFF_TEAM(this, toucher))) return; EXACTTRIGGER_TOUCH(this, toucher); @@ -272,48 +273,50 @@ void trigger_push_touch(entity this, entity toucher) #ifdef SVQC void trigger_push_link(entity this); void trigger_push_updatelink(entity this); -bool trigger_push_testorigin(entity e, entity targ, entity jp, vector org) +bool trigger_push_testorigin(entity tracetest_ent, entity targ, entity jp, vector org) { - setorigin(e, org); - tracetoss(e, e); + setorigin(tracetest_ent, org); + tracetoss(tracetest_ent, tracetest_ent); if(trace_startsolid) return false; - if(!jp.height) + if (!jp.height) { // since tracetoss starting from jumppad's origin often fails when target // is very close to real destination, start it directly from target's // origin instead - e.velocity_z = 0; - setorigin(e, targ.origin + stepheightvec); - tracetoss(e, e); - if(trace_startsolid) + vector ofs = '0 0 0'; + if (vdist(vec2(tracetest_ent.velocity), <, autocvar_sv_maxspeed)) + ofs = stepheightvec; + + tracetest_ent.velocity.z = 0; + setorigin(tracetest_ent, targ.origin + ofs); + tracetoss(tracetest_ent, tracetest_ent); + if (trace_startsolid && ofs.z) { - setorigin(e, targ.origin + stepheightvec / 2); - tracetoss(e, e); - if(trace_startsolid) + setorigin(tracetest_ent, targ.origin + ofs / 2); + tracetoss(tracetest_ent, tracetest_ent); + if (trace_startsolid && ofs.z) { - setorigin(e, targ.origin); - tracetoss(e, e); - if(trace_startsolid) + setorigin(tracetest_ent, targ.origin); + tracetoss(tracetest_ent, tracetest_ent); + if (trace_startsolid) return false; } } } - - if(e.move_movetype == MOVETYPE_NONE) - { - tracebox(trace_endpos, e.mins, e.maxs, trace_endpos - eZ * 1500, true, jp); - return true; - } - return false; + tracebox(trace_endpos, tracetest_ent.mins, tracetest_ent.maxs, trace_endpos - eZ * 1500, true, tracetest_ent); + return true; } #endif -void trigger_push_findtarget(entity this) + +/// if (item != NULL) returns true if the item can be reached by using this jumppad, false otherwise +/// if (item == NULL) tests jumppad's trajectory and eventually spawns waypoints for it (return value doesn't matter) +bool trigger_push_test(entity this, entity item) { // first calculate a typical start point for the jump vector org = (this.absmin + this.absmax) * 0.5; - org.z = this.absmax.z - PL_MIN_CONST.z; + org.z = this.absmax.z - PL_MIN_CONST.z - 7; if (this.target) { @@ -325,9 +328,23 @@ void trigger_push_findtarget(entity this) { ++n; #ifdef SVQC + if(t.move_movetype != MOVETYPE_NONE) + continue; + entity e = spawn(); setsize(e, PL_MIN_CONST, PL_MAX_CONST); - e.velocity = trigger_push_calculatevelocity(org, t, this.height); + e.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; + e.velocity = trigger_push_calculatevelocity(org, t, this.height, e); + + if(item) + { + setorigin(e, org); + tracetoss(e, e); + bool r = (trace_ent == item); + delete(e); + return r; + } + vel = e.velocity; vector best_target = '0 0 0'; vector best_org = '0 0 0'; @@ -351,7 +368,7 @@ void trigger_push_findtarget(entity this) vector flatdir = normalize(dist - eZ * dist.z); vector ofs = flatdir * 0.5 * min(fabs(this.absmax.x - this.absmin.x), fabs(this.absmax.y - this.absmin.y)); new_org = org + ofs; - e.velocity = trigger_push_calculatevelocity(new_org, t, this.height); + e.velocity = trigger_push_calculatevelocity(new_org, t, this.height, e); vel = e.velocity; if (vdist(vec2(e.velocity), <, autocvar_sv_maxspeed)) e.velocity = autocvar_sv_maxspeed * flatdir; @@ -363,7 +380,7 @@ void trigger_push_findtarget(entity this) valid_best_target = true; } new_org = org - ofs; - e.velocity = trigger_push_calculatevelocity(new_org, t, this.height); + e.velocity = trigger_push_calculatevelocity(new_org, t, this.height, e); vel = e.velocity; if (vdist(vec2(e.velocity), <, autocvar_sv_maxspeed)) e.velocity = autocvar_sv_maxspeed * flatdir; @@ -385,20 +402,23 @@ void trigger_push_findtarget(entity this) if(velxy < autocvar_sv_maxspeed) velxy = autocvar_sv_maxspeed; cost += vlen(vec2(best_target - t.origin)) / velxy; - waypoint_spawnforteleporter(this, best_target, cost); + waypoint_spawnforteleporter(this, best_target, cost, e); } } delete(e); #endif } + if(item) + return false; + if(!n) { // no dest! #ifdef SVQC objerror (this, "Jumppad with nonexistant target"); #endif - return; + return false; } else if(n == 1) { @@ -415,17 +435,30 @@ void trigger_push_findtarget(entity this) else { entity e = spawn(); - setorigin(e, org); setsize(e, PL_MIN_CONST, PL_MAX_CONST); + e.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; + setorigin(e, org); e.velocity = this.movedir; tracetoss(e, e); + if(item) + { + bool r = (trace_ent == item); + delete(e); + return r; + } if (!(boxesoverlap(this.absmin, this.absmax + eZ * 50, trace_endpos + PL_MIN_CONST, trace_endpos + PL_MAX_CONST))) - waypoint_spawnforteleporter(this, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity)); + waypoint_spawnforteleporter(this, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity), e); delete(e); } defer(this, 0.1, trigger_push_updatelink); #endif + return true; +} + +void trigger_push_findtarget(entity this) +{ + trigger_push_test(this, NULL); } #ifdef SVQC @@ -438,9 +471,7 @@ float trigger_push_send(entity this, entity to, float sf) WriteByte(MSG_ENTITY, this.active); WriteCoord(MSG_ENTITY, this.height); - WriteCoord(MSG_ENTITY, this.movedir_x); - WriteCoord(MSG_ENTITY, this.movedir_y); - WriteCoord(MSG_ENTITY, this.movedir_z); + WriteVector(MSG_ENTITY, this.movedir); trigger_common_write(this, true); @@ -449,7 +480,7 @@ float trigger_push_send(entity this, entity to, float sf) void trigger_push_updatelink(entity this) { - this.SendFlags |= 1; + this.SendFlags |= SF_TRIGGER_INIT; } void trigger_push_link(entity this) @@ -490,6 +521,8 @@ spawnfunc(trigger_push) trigger_push_link(this); // link it now + IL_PUSH(g_jumppads, this); + // this must be called to spawn the teleport waypoints for bots InitializeEntity(this, trigger_push_findtarget, INITPRIO_FINDTARGET); } @@ -501,9 +534,7 @@ bool target_push_send(entity this, entity to, float sf) WriteByte(MSG_ENTITY, this.cnt); WriteString(MSG_ENTITY, this.targetname); - WriteCoord(MSG_ENTITY, this.origin_x); - WriteCoord(MSG_ENTITY, this.origin_y); - WriteCoord(MSG_ENTITY, this.origin_z); + WriteVector(MSG_ENTITY, this.origin); WriteAngle(MSG_ENTITY, this.angles_x); WriteAngle(MSG_ENTITY, this.angles_y); @@ -545,23 +576,35 @@ void target_push_init2(entity this) target_push_init(this); // normal push target behaviour can be combined with a legacy pusher? } -spawnfunc(target_push) { target_push_init2(this); } -spawnfunc(info_notnull) { target_push_init(this); } -spawnfunc(target_position) { target_push_init(this); } +spawnfunc(target_push) +{ + target_push_init2(this); +} + +spawnfunc(info_notnull) +{ + target_push_init(this); +} +spawnfunc(target_position) +{ + target_push_init(this); +} #elif defined(CSQC) NET_HANDLE(ENT_CLIENT_TRIGGER_PUSH, bool isnew) { this.classname = "jumppad"; - int mytm = ReadByte(); if(mytm) { this.team = mytm - 1; } + int mytm = ReadByte(); + if(mytm) + { + this.team = mytm - 1; + } this.spawnflags = ReadInt24_t(); this.active = ReadByte(); this.height = ReadCoord(); - this.movedir_x = ReadCoord(); - this.movedir_y = ReadCoord(); - this.movedir_z = ReadCoord(); + this.movedir = ReadVector(); trigger_common_read(this, true); @@ -576,13 +619,8 @@ NET_HANDLE(ENT_CLIENT_TRIGGER_PUSH, bool isnew) void target_push_remove(entity this) { - //if(this.classname) - //strunzone(this.classname); - //this.classname = string_null; - - if(this.targetname) - strunzone(this.targetname); - this.targetname = string_null; + // strfree(this.classname); + strfree(this.targetname); } NET_HANDLE(ENT_CLIENT_TARGET_PUSH, bool isnew) @@ -590,9 +628,7 @@ NET_HANDLE(ENT_CLIENT_TARGET_PUSH, bool isnew) this.classname = "push_target"; this.cnt = ReadByte(); this.targetname = strzone(ReadString()); - this.origin_x = ReadCoord(); - this.origin_y = ReadCoord(); - this.origin_z = ReadCoord(); + this.origin = ReadVector(); this.angles_x = ReadAngle(); this.angles_y = ReadAngle();