ENTITY* heroEnt;
ENTITY* ghost1Ent;
ENTITY* portal1Ent;
ENTITY* portal2Ent;
void calculatePortal(ENTITY* ent, VECTOR* srcPos, VECTOR* dstPos, ANGLE* srcAng, ANGLE* dstAng){
if(!heroEnt){ return; }
ANGLE tempAng;
vec_fill(tempAng.pan, 0);
VECTOR tempPos;
vec_fill(tempPos.x, 0);
ang_diff(tempAng.pan, dstAng.pan, srcAng.pan);
vec_set(tempPos.x, srcPos.x);
vec_sub(tempPos.x, heroEnt.x);
vec_rotate(tempPos.x, tempAng.pan);
// vec_inverse(tempPos.x); // uncomment this to mirror player's position at destination portal (comment ang_rotate 180 bellow!)
vec_add(tempPos.x, dstPos.x);
ANGLE temp2Ang, endAng;
vec_fill(temp2Ang.pan, 0);
vec_fill(endAng.pan, 0);
ang_diff(temp2Ang.pan, srcAng.pan, heroEnt.pan);
vec_inverse(temp2Ang.pan);
ang_rotate(temp2Ang.pan, vector(180, 0, 0));
vec_set(endAng.pan, dstAng.pan);
ang_add(endAng.pan, temp2Ang.pan);
// if player far away from us:
if(vec_dist(heroEnt.x, ent.x) > 25){
if(!is(ent.parent, INVISIBLE)){
set(ent.parent, INVISIBLE);
}
}
else{
if(is(ent.parent, INVISIBLE)){
reset(ent.parent, INVISIBLE);
}
vec_set(ent.parent.x, tempPos.x);
vec_set(ent.parent.pan, endAng.pan);
VECTOR tempVec;
vec_fill(tempVec.x, 0);
vec_set(tempVec.x, vector(2.5, 0, 0));
vec_rotate(tempVec.x, ent.parent.pan);
vec_add(tempVec.x, ent.parent.x);
draw_point3d(tempVec.x, COLOR_RED, 100, 1);
}
}
void portal1(){
VECTOR tempVec;
vec_fill(tempVec.x, 0);
portal1Ent = my;
vec_set(my.scale_x, vector(0.05, 1, 1));
my.pan += random(360);
set(my, LIGHT | UNLIT | PASSABLE);
vec_set(my.blue, COLOR_RED);
my.parent = ent_create(CUBE_MDL, my.x, NULL);
vec_set(my.parent.scale_x, vector(0.25, 0.25, 0.25));
set(my.parent, TRANSLUCENT | LIGHT | UNLIT | PASSABLE);
vec_set(my.parent.blue, COLOR_RED);
while(!portal2Ent){ wait(1); }
while(1){
my.pan += 5 * (key_cul - key_cur) * time_step;
my.x += 5 * (key_t - key_g) * time_step;
my.y += 5 * (key_f - key_h) * time_step;
vec_set(tempVec.x, vector(5, 0, 0));
vec_rotate(tempVec.x, my.pan);
vec_add(tempVec.x, my.x);
draw_line3d(tempVec.x, NULL, 100);
draw_line3d(tempVec.x, COLOR_RED, 100);
draw_line3d(my.x, COLOR_RED, 100);
draw_point3d(tempVec.x, COLOR_RED, 100, 1);
calculatePortal(my, my.x, portal2Ent.x, my.pan, portal2Ent.pan);
wait(1);
}
}
void portal2(){
VECTOR tempVec;
vec_fill(tempVec.x, 0);
portal2Ent = my;
vec_set(my.scale_x, vector(0.05, 1, 1));
my.pan += random(360);
set(my, LIGHT | UNLIT | PASSABLE);
vec_set(my.blue, COLOR_GREEN);
my.parent = ent_create(CUBE_MDL, my.x, NULL);
vec_set(my.parent.scale_x, vector(0.25, 0.25, 0.25));
set(my.parent, TRANSLUCENT | LIGHT | UNLIT | PASSABLE);
vec_set(my.parent.blue, COLOR_GREEN);
while(!portal1Ent){ wait(1); }
while(1){
my.pan += 5 * (key_cuu - key_cud) * time_step;
my.x += 5 * (key_i - key_k) * time_step;
my.y += 5 * (key_j - key_l) * time_step;
vec_set(tempVec.x, vector(5, 0, 0));
vec_rotate(tempVec.x, my.pan);
vec_add(tempVec.x, my.x);
draw_line3d(tempVec.x, NULL, 100);
draw_line3d(tempVec.x, COLOR_GREEN, 100);
draw_line3d(my.x, COLOR_GREEN, 100);
draw_point3d(tempVec.x, COLOR_GREEN, 100, 1);
calculatePortal(my, my.x, portal1Ent.x, my.pan, portal1Ent.pan);
wait(1);
}
}
void main(){
fps_max = 60;
level_load("");
random_seed(0);
// create portals:
ent_create(CUBE_MDL, vector(-25, 25, 0), portal1);
ent_create(CUBE_MDL, vector(25, -25, 0), portal2);
VECTOR tempVec;
vec_fill(tempVec.x, 0);
heroEnt = ent_create(CUBE_MDL, nullvector, NULL);
vec_set(heroEnt.scale_x, vector(0.25, 0.25, 0.25));
set(heroEnt, TRANSLUCENT | LIGHT | UNLIT);
vec_set(heroEnt.blue, COLOR_WHITE);
c_setminmax(heroEnt);
sun_light = 0;
set(camera, ISOMETRIC);
camera.arc = 10;
camera.z = 100;
camera.tilt = -90;
while(1){
DEBUG_VAR(heroEnt.pan, 210);
DEBUG_VAR(portal1Ent.pan, 250);
DEBUG_VAR(portal2Ent.pan, 270);
heroEnt.skill1 = 5 * (key_w - key_s) * time_step;
heroEnt.skill2 = 5 * (key_a - key_d) * time_step;
heroEnt.pan += 5 * (key_z - key_x) * time_step;
c_move(heroEnt, nullvector, heroEnt.skill1, IGNORE_PASSABLE | GLIDE);
vec_set(tempVec.x, vector(2.5, 0, 0));
vec_rotate(tempVec.x, heroEnt.pan);
vec_add(tempVec.x, heroEnt.x);
draw_point3d(tempVec.x, COLOR_RED, 100, 1);
draw_text("green and red cubes are 'ghost' players position in the destination portals\nwhite cube is player, and those two red/green lines are portals\nyou can see the way they are facing from the lines comming out of portals\nthe green one is source portal and the other one is destination portal (and visa versa)\nuse cursor keys to rotate the portals use WSAD to move the player around \nand TGFH and IKJL to move portals", 10, 10, COLOR_WHITE);
wait(1);
}
}