Some scripting stuff for you:
Code:
make_new_playerangle(normal_in,normal_out,playerangles)
{
playervec=anglestoforward(playerangles);
normal_both=cross_prod(out,in); //do not write in,out, it fucks stuff up
if(normal_both==(0,0,0))
{
if(dot_prod(normal_in,normal_out)>0)
{
//portal_normals are pointing in same direction, turn vec around
output=maps\mp\_utility::vectorscale(playervec,-1);
}
else
{
//portal normals are opposite, portals are facing one another, do nothing to playervec
output=playervec;
}
//both portal_normals are paralleled
//do something here
}
else
{
normal_in2=cross_prod(normal_in,normal_both);
normal_out2=cross_prod(normal_both,normal_out);
normal_both=vectornormalize(normal_both);
normal_in2=vectornormalize(normal_in2);
normal_out2=vectornormalize(normal_out2);
part_normal=dot_prod(normal_in,playervec);
part_right=dot_prod(normal_in2,playervec);
part_up=dot_prod(normal_both,playervec);
vec_part_up_out=maps\mp\_utility::vectorscale(normal_both*part_up);
vec_part_right_out=maps\mp\_utility::vectorscale(normal_out2,part_right);
vec_part_normal_out=maps\mp\_utility::vectorscale(normal_out,-1*part_normal);
output=vec_part_up_out+vec_part_right_out+vec_part_normal_out;
}
return output;
}
calc_other_vecs(trace,user)
{
uservec=anglestoforward(user getplayerangles());
up=vectornormalize(uservec-maps\mp\_utility::vectorscale(trace["normal"],dot_prod(trace["normal"],uservec));
right=cross_prod(up,trace["normal"]);
}
cross_prod(vec1,vec2)
{
return ((vec1[1]*vec2[2]-vec1[2]*vec2[1]),(vec1[2]*vec2[0]-vec1[0]*vec2[2]),(vec1[0]*vec2[1]-vec1[1]*vec2[0]));
}
dot_prod(vec1,vec2)
{
return (vec1[0]*vec2[0]+vec1[1]*vec2[1]+vec1[2]*vec2[2]);
}
and
Code:
player()
{
self endon("disconnect");
self endon("killed_player");
self endon("spawned_player");
self.firstportal=undefined;
self.secondportal=undefined;
self.oldorg=self.origin;
for(;;)
{
if(isdefined(self.firstportal)&&isdefined(self.secondportal))
{
//check for proximity to portals here
//firstportal:
S=self.origin-self.firstportal.origin;
R=s-maps\mp\_utility::vectorscale(self.firstportal.normal,dot(self.firstportal.normal,s));
if(distancesquared(R,(0,0,0))<100*100)
{
//lined up in front of the portal
if(dot(S,self.firstportal.normal)>0)
{
//located at the right side of the portal
if(dot(maps\mp\_utility::vectorscale(self.oldorg-self.origin,1.5)+S,self.firstportal.normal)<0)
{
//walking for 0.075 sec in that same direction should let you bump into the portal
self.origin=self.secondportal.origin;
speed=distance(self.oldorg,self.origin);
damage=int(speed);
self.health+=damage;
vdir=self.secondportal.normal;
//do some damage here in the self.secondportal.normal direction, depending on speed
self.oldorg=self.origin;
}
}
}
//secondportal:
S=self.origin-self.secondportal.origin;
R=s-maps\mp\_utility::vectorscale(self.secondportal.normal,dot(self.secondportal.normal,s));
if(distancesquared(R,(0,0,0))<100*100)
{
//lined up in front of the portal
if(dot(S,self.secondportal.normal)>0)
{
//located at the right side of the portal
if(dot(maps\mp\_utility::vectorscale(self.oldorg-self.origin,1.5)+S,self.secondportal.normal)<0)
{
//walking for 0.075 sec in that same direction should let you bump into the portal
self.origin=self.firstportal.origin;
speed=distance(self.oldorg,self.origin);
damage=int(speed);
self.health+=damage;
vdir=self.firstportal.normal;
//do some damage here in the self.firstportal.normal direction, depending on speed
self.oldorg=self.origin;
}
}
}
}
self.oldorg=self.origin;
wait 0.05;
}
}
dot(vec1,vec2)
{
if(!isdefined(vec1)||!isdefined(vec2))
return 0;
else
return vec1[0]*vec2[0]+vec1[1]*vec2[1]+vec1[2]*vec2[2];
}
This code is free-to-use, if you credit me in the main menu OR in the hud, and add some credits to the readme.txt in the clientiwd