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_diff(tempPos.x, srcPos.x, heroEnt.x);
vec_rotate(tempPos.x, tempAng.pan);
vec_inverse(tempPos.x);
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_set(endAng.pan, dstAng.pan);
vec_inverse(temp2Ang.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);
}
}
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);
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);
draw_text("green and red cubes are 'ghost' players position in the destination portals\nwhite cube is player, and those two white lines are portals\nyou can see the way they are facing from the lines comming out of portals\nthe one near by the player is source portal and the other\none is destination portal, use cursor keys to rotate the portals\nuse WSAD to move the player around and TGFH and IKJL to move portals", 10, 10, COLOR_WHITE);
wait(1);
}
}