12 const int polyline_length = 16;
13 .vector polyline[polyline_length];
14 void Porto_Draw(
entity this)
22 if (wepent.activeweapon != WEP_PORTO)
continue;
27 pos +=
v_right * -wepent.movedir.y
28 +
v_up * wepent.movedir.z;
30 if (wepent.angles_held_status)
36 wepent.polyline[0] = pos;
38 int portal_number = 0, portal1_idx = 1, portal_max = 2;
40 for (
int idx = 0; idx < n && idx < polyline_length - 1; )
42 traceline(pos, pos + 65536 * dir,
true,
this);
45 wepent.polyline[++idx] = pos;
68 if (portal_number >= portal_max)
break;
69 if (portal_number == 1) portal1_idx = idx;
71 for (
int idx = 0; idx < n - 1; ++idx)
73 vector p = wepent.polyline[idx], q = wepent.polyline[idx + 1];
74 if (idx == 0) p -=
view_up * 16;
75 vector rgb = (idx < portal1_idx) ?
'1 0 0' :
'0 0 1';
91 void W_Porto_Success(
entity this)
95 objerror(
this,
"Cannot succeed successfully: no owner\n");
103 void W_Porto_Fail(
entity this,
float failhard)
107 objerror(
this,
"Cannot fail successfully: no owner\n");
121 setsize(
this,
'-16 -16 0',
'16 16 48');
128 tracetoss(
this,
this);
133 Send_Notification(NOTIF_ONE, this.
realowner, MSG_CENTER, CENTER_PORTO_FAILED);
140 void W_Porto_Remove(
entity p)
142 if(p.porto_current.realowner == p && p.porto_current.classname ==
"porto")
144 W_Porto_Fail(p.porto_current, 1);
148 void W_Porto_Think(
entity this)
151 if(this.
realowner.playerid !=
this.playerid)
154 W_Porto_Fail(
this, 0);
164 if(toucher.classname ==
"portal")
180 if(this.
realowner.playerid !=
this.playerid)
195 W_Porto_Fail(
this, 0);
199 else if(this.
cnt == 0)
206 Send_Notification(NOTIF_ONE, this.
realowner, MSG_CENTER, CENTER_PORTO_CREATED_IN);
207 W_Porto_Success(
this);
213 W_Porto_Fail(
this, 0);
216 else if(this.
cnt == 1)
223 Send_Notification(NOTIF_ONE, this.
realowner, MSG_CENTER, CENTER_PORTO_CREATED_OUT);
224 W_Porto_Success(
this);
230 W_Porto_Fail(
this, 0);
240 Send_Notification(NOTIF_ONE, this.
realowner, MSG_CENTER, CENTER_PORTO_CREATED_IN);
250 W_Porto_Fail(
this, 0);
255 if(this.
realowner.portal_in.portal_id ==
this.portal_id)
261 Send_Notification(NOTIF_ONE, this.
realowner, MSG_CENTER, CENTER_PORTO_CREATED_OUT);
262 W_Porto_Success(
this);
268 W_Porto_Fail(
this, 0);
275 W_Porto_Fail(
this, 0);
292 gren.weaponentity_fld = weaponentity;
294 gren.owner = gren.realowner = actor;
295 gren.playerid = actor.playerid;
296 gren.bot_dodge =
true;
297 gren.bot_dodgerating = 200;
303 setsize(gren,
'0 0 0',
'0 0 0');
307 settouch(gren, W_Porto_Touch);
310 if(StatusEffects_active(STATUSEFFECT_Strength, actor))
316 gren.flags = FL_PROJECTILE;
320 gren.portal_id =
time;
321 actor.porto_current = gren;
322 gren.playerid = actor.playerid;
349 if(!actor.porto_current)
350 if(!actor.porto_forbidden)
353 W_Porto_Attack(thiswep, actor, weaponentity, 0);
358 if(!actor.porto_current)
359 if(!actor.porto_forbidden)
362 W_Porto_Attack(thiswep, actor, weaponentity, 1);
368 if(actor.(weaponentity).porto_v_angle_held)
371 actor.(weaponentity).porto_v_angle_held = 0;
377 actor.(weaponentity).porto_v_angle = actor.v_angle;
378 actor.(weaponentity).porto_v_angle_held = 1;
381 if(actor.(weaponentity).porto_v_angle_held)
385 if(!actor.porto_current)
386 if(!actor.porto_forbidden)
389 W_Porto_Attack(thiswep, actor, weaponentity, -1);
406 actor.porto_current =
NULL;
411 LOG_WARN(
"Since when does Porto send DamageInfo?");
const int PROJECTILE_PORTO_RED
#define WEP_CVAR_PRI(wepname, name)
#define PHYS_INPUT_BUTTON_ATCK2(s)
#define W_SetupProjVelocity_Basic(ent, pspeed, pspread)
bool bot_aim(entity this,.entity weaponentity, float shotspeed, float shotspeedupward, float maxshottime, float applygravity)
#define WEP_CVAR_SEC(wepname, name)
#define PROJECTILE_MAKETRIGGER(e)
#define REGISTER_MUTATOR(id, dependence)
float trace_dphitq3surfaceflags
vector warpzone_save_view_angles
entity viewmodels[MAX_WEAPONSLOTS]
float trace_dphitcontents
#define FOREACH_CLIENT(cond, body)
float MOVETYPE_BOUNCEMISSILE
void w_ready(Weapon thiswep, entity actor,.entity weaponentity, int fire)
#define WEP_CVAR(wepname, name)
#define STATIC_INIT(func)
during worldspawn
float DPCONTENTS_PLAYERCLIP
float Q3SURFACEFLAG_SLICK
#define METHOD(cname, name, prototype)
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
#define move_out_of_solid(e)
IntrusiveList g_bot_dodge
const int PROJECTILE_PORTO_BLUE
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
const int MAX_WEAPONSLOTS
bool weapon_prepareattack(Weapon thiswep, entity actor,.entity weaponentity, bool secondary, float attacktime)
float W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector velo,.entity weaponentity)
#define WEP_CVAR_BOTH(wepname, isprimary, name)
ERASEABLE vector reflect(vector dir, vector norm)
void Portal_ClearWithID(entity own, float id)
const float DRAWFLAG_NORMAL
#define PHYS_INPUT_BUTTON_ATCK(s)
#define W_SetupShot(ent, wepent, antilag, recoil, snd, chan, maxdamage, deathtype)
float Q3SURFACEFLAG_NOIMPACT
vector(float skel, float bonenum) _skel_get_boneabs_hidden
IntrusiveList g_projectiles
float Portal_SpawnOutPortalAtTrace(entity own, vector dir, float portal_id_val)
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
vector trigger_push_calculatevelocity(vector org, entity tgt, float ht, entity pushed_entity)
void weapon_thinkf(entity actor,.entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor,.entity weaponentity, int fire) func)
#define MUTATOR_CALLHOOK(id,...)
#define new_pure(class)
purely logical entities (.origin doesn't work)
void Portal_ClearAll_PortalsOnly(entity own)
vector trace_plane_normal
#define MUTATOR_HOOKFUNCTION(...)
int autocvar_chase_active
#define sound(e, c, s, v, a)
fields which are explicitly/manually set are marked with "M", fields set automatically are marked wit...
float Portal_SpawnInPortalAtTrace(entity own, vector dir, float portal_id_val)
IntrusiveList g_drawables
void set_movetype(entity this, int mt)