Source cod
of'course simple one without particle effects, shaders... just portals
I hope it'll work
You may f.e. not closing portals to create nice loop when enemy is falling and
fallig and falling...
Have fun
Code:
/////////////////////////////////////////////
/////////| Portals script |//////////////////
//////| as always free to use ;) |/////////
/////////////////////////////////////////////
//| TomPo |///////////////| 12-05-'07 |//
/////////////////////////////////////////////
/*
Main idea of portals: (of'course main idea so probably not the best one) ;)
- 2 cameras, 2 portals
- camera_1 is at portal_1 position but displaying on portal_2 and vice versa
- camera_1 (displaying on portal_2) is looking at the same direction as portal_1
- so looking at portal_1 we can see what the portal_2 is seeing
- every portal has own "helper" (var) looking at him
- so when we are lookig at portal we are changing pan of another camera by diff between us and the portal's
helper we standing at becouse this second camera is dispaying on portal we are looking on, and we can see the changes
- and finaly every portal has own exit to teleport player
Hints
- use heigh resolution sprite's bmap like 1024x768 - to get better view quality
- if you use models... skin them with heigh resolution bmap
*/
////////////////// VERIABLES /////////////////////////////
entity* portal_1; entity* portal_2; //nothing to explain
var portals_count =0; //number of portals
var portal_1_exit[3]; var portal_2_exit[3]; //place where player will go out
var temp_ang_1; var temp_ang_2; //temp ang to calculate diferences between player and portal we looking at
////////////////// CAMERAS ///////////////////////////
view camera {layer = 0; flags = VISIBLE;}
view camera_portal_1 {layer = -1;arc = 60; aspect=0.5; size_x = 1024; size_y = 768;}
view camera_portal_2 {layer = -1;arc = 60; aspect=0.5; size_x = 1024; size_y = 768;}
//play with aspect to have a good ratio
//////////////////////////////////////////////////////////////////////////////////////////////////
/*========================================= PORTAL START =======================================*/
//////////////////////////////////////////////////////////////////////////////////////////////////
///////////////// PORTALS ///////////////////////////
/// PORTAL 1 ///////////////////////////////////////
function portal_1_fun
{
portal_1 = me;
my.oriented = on; my.facing = off; my.passable = on; my.transparent = on; my.overlay = on;
vec_add(my.x,normal); //move portal 1 quant away from wall/floor
while(me)
{
if(vec_dist(my.x,player.x) < 200) //if player is close
{
if(portals_count == 1){wait(1);} //if only one portal do nothing
else
{
vec_set(player.x,portal_2_exit.x); //teleport player to portal_2
player.pan = portal_2.pan; //turn him
portals_count =0; //close portals
}
}
if(portals_count ==0){portals_count =0; ent_remove(me); break;} //remove me if 0 portals
wait(1);
}
}
//// PORTAL 2 ///////////////////////////////////////
function portal_2_fun
{
portal_2 = me;
my.oriented = on; my.facing = off; my.passable = on; my.transparent = on; my.overlay = on;
vec_add(my.x,normal);
while(me)
{
if(portal_1 != 0) //LETS FUN BEGIN... if portal_1 exist
{
vec_set(portal_1_exit, nullvector); portal_1_exit.x = 100; // set portal exit 100 quants from portal with
vec_rotate(portal_1_exit, portal_1.pan); vec_add(portal_1_exit, portal_1.x);// the same direction
vec_lerp(temp,portal_1_exit.x,portal_1.x,0.5); //place camera 50 quants away from portal
vec_set(camera_portal_1.x,temp); // to avoid looking through the walls/floor
temp_ang_1 = portal_1.pan + 180; // helper var with value oposit to portal pan "look at portal"
vec_set(portal_2_exit, nullvector); portal_2_exit.x = 100; //the same with second exit,camera and helper
vec_rotate(portal_2_exit, portal_2.pan); vec_add(portal_2_exit, portal_2.x);
vec_lerp(temp,portal_2_exit.x,portal_2.x,0.5);
vec_set(camera_portal_2.x,temp);
temp_ang_2 = portal_2.pan + 180;
camera_portal_1.bmap = bmap_for_entity(portal_2,0); //play what first portal "see" at second portal
camera_portal_1.pan = portal_1.pan; //the same pan and tilt
camera_portal_1.tilt = portal_1.tilt;
camera_portal_1.visible = on; //make view visible
camera_portal_2.bmap = bmap_for_entity(portal_1,0); //the same with second one
camera_portal_2.pan = portal_2.pan;
camera_portal_2.tilt = portal_2.tilt;
camera_portal_2.visible = on;
if(portal_1.tilt ==0)&&(portal_2.tilt ==0) //if portal is not on the floor or ceiling
{
camera_portal_2.tilt += camera.tilt; //camera_2 tilt has the same tilt what portal 2 + main camera tilt
camera_portal_1.tilt += camera.tilt;
camera_portal_2.pan -= (temp_ang_1 - player.pan); //camera_2 pan (viewing on portal_1) has the same pan as
camera_portal_1.pan -= (temp_ang_2 - player.pan); //portal_2 and it's changing with diference between
} // player pan and opposite pan of portal we looking at
}
if(portals_count ==0){portals_count =0; ent_remove(me);break;}
wait(1);
}
}
//////////// CREATE/CLOSE PORTALS /////////////////
function create_portal
{
temp.x = screen_size.x /2 ; temp.y = screen_size.y /2;
temp.z = 10000; vec_for_screen(temp,CAMERA); //trace from middle of the screen to far away in deph view
result = c_trace (camera.x, temp, IGNORE_ME | IGNORE_PASSABLE | IGNORE_SPRITES);
portals_count +=1; //with LMB add one portal
//create portal at traced target and pan/tilt him with wall/floor etc
if(portals_count == 1){you=ent_create("portal_mdl.mdl",target.x,portal_1_fun); vec_to_angle(you.pan,normal);}
if(portals_count == 2){you=ent_create("portal_2_mdl.mdl",target.x,portal_2_fun); vec_to_angle(you.pan,normal);}
//if two portals in level, close them, wait 1 to avoid empty pointers and create firs portal
if(portals_count > 2){portals_count =0;wait(1);create_portal();}
}
function close_portals
{
portals_count = 0; //close portals
}
//////////////// KEYS /////////////////////////////
on_mouse_left = create_portal;
on_mouse_right = close_portals;
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////// END ///////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////