Skip to main content

News

Topic: I say Hello, you say... (Read 10727 times) previous topic - next topic

0 Members and 1 Guest are viewing this topic.
  • FBnil
  • [*][*]
Re: I say Hello, you say...
Reply #15
Love the portal idea, maybe you can check my teleporthica demo (type it in in google, gets you 1 anwser). Here is the API. It is fairly complete.
It has that same thing you were talking about classrooms. You can define 1 empy room, and make a hallway jump to that empty room each time, but you can give each room a different title, so it does not feel like it is the same room. And then use a WarpBack() function to warp to where you warped from, getting to the right spot of the hallway.
One thing I now, after reading your text, want to do is to automatically calculate the warp back offset (to not warp onto the trigger). Warp delay was for that, but I think the latter is better now (will be a setting of course)


Code: [Select]

//___________________________________
//                                   \
// Teleporthica MapChange Engine.  version 1.3 $Id: teleporthica.js 108 2008-07-18 21:23:47Z nilton $
//___________________________________/
/*
To change to a map, when you want several entry points is impossible with ChangeMap() only.
You may only need this:

RequireScript("teleporthica.js");

And then you can use:

WarpXY(rmpfilename,x,y,tonewlayer); //(x,y) in Pixels
or
WarpTo(rmpfilename,tx,ty,tonewlayer); //(tx,ty) in Tiles

The values of x, y and layer will be taken from the EntryPoint if ommited.
But to get more functionality, you need to set up some things.


*** SHORTWRITES ***

Shortwrite the Warp() and WarpXY() functions, now they are easy to call,
these functions are automatically created for you:

Warp = function(r,p,t,r,i,f) {return MapChange.warp(r,p,t,r,i,f);}
WarpXY = function(r,x,y,l,t,r,i,f) {return MapChange.warpXY(r,x,y,l,t,r,i,f);}
WarpTo = function(r,tx,ty,l,t,r,i,f) {return MapChange.warpTo(r,tx,ty,l,t,r,i,f);}
WarpBack = function(retrigger,msg,run,fade) {return MapChange.warpBack(retrigger,msg,run,fade);}
SeamlessWarpXY = function(new_map,new_XX,new_YY) {MapChange.SeamlessWarpXY(new_map,new_XX,new_YY);}

(For the parameters you can use, see the real functions below in the code)

*** WARP points ***

Inside the Entry script of a map (or in the mapEnter function, if using BindScript),
set the mapname and WARP points:

WARP = {
mapname: "How did I end up here?", // The name of the map
NorthernEntry : {
tx: 52,
ty: 21,
  run: "ResetPuzzle(1)",
face: COMMAND_FACE_NORTH,
name: "Alternative map name" // Overrides mapname
}, 
StairsDownToCatacombs: { tx:46, ty:22, dx:8 },
Upstairs: { x:162, y:230, layer:2}
GoingUp: { tx:null, ty:-1 }
}


where tx and ty are tile coordinates (not pixels!), x and y also exist, for the ones that
want pixelperfect placement. dx and dy exist to offset by pixels. If the warppoint does not exist,
then Warp() will default to the entrypoint. The layer has to be specified only if you need to
warp to another layer than the entrypoint has. run is for when you also need to execute something
complex like a sound. face runs QueuePersonCommand(person,<face>, true); to face a direction.
Each value can be ommited, in that case, the defaults will be taken from the entrypoint.
if tx, x, ty, y or layer is undefined, then that value will be taken from the entrypoint.
if tx, x, ty, y or layer is null, then that value will be taken from the previous map.
if tx, x, ty, y or layer are -1, then that maximum possible value will be used (minus 1).

Then, at a place in any map where you want an exitpoint, define a trigger with 
Warp(rmpfilename,warppoint,titlemsg,run,wbinfo,fade) for example:

Warp('mymap.rmp','NorthernEntry');

Or, you can also use the classical:

WarpXY(rmpfilename,x,y,tonewlayer,titlemsg,run,warpbackInfoObject)

These (x,y) are in pixels, use WarpTo() when specifying tiles (the function has
the same order of parameters).

WarpTo(rmpfilename,tx,ty,tonewlayer,titlemsg,run,warpbackInfoObject)

In the end, everything is optional and you can only use: WarpTo('level2.rmp',1,10);

titlemsg will override any set mapname
run Additional command you want to run, after the map change and the repositioning of the input person and after the run defined in the warppoint.
wbinfo Is the WarpBack info, I'll explain that in a moment
fade during this warp, use this fade.

*** Special warp functions ***

If you need to fake you're entering the map you are currently in (to reset the puzzles on
the map, for example) then use:

MapChange.warpRestart();

If you need to warp back to the map, just before you came to the current map
(for example: to return from a cutscene), use:

WarpBack();

If you are unsure if the WarpBack() will warp you back to a place where another trigger
will warp you, use:

WarpBack(true)

WarpBack will warp you back to the previous map/place, but dont use it unless its a room with no other warps out.
WarpBack is useful for a hall with lots of doors that warp you to the same empty room (you make one single map of an empty room).
This way, each time you return to the correct door in the hall.
In order to WarpBack() correctly, you need to give the previous warp with WarpBack Information.

A warpbackInfoObject can contain the following information:

x:   When using warpback, it will warp to this x (in pixels)
dx:  When using warpback, it will offset dx pixels
tx:  When using warpback, it will warp to this x (in tiles)
dtx: When using warpback, it will offset dtx tiles (it automatically centers the sprite on that tile)
                y:   When using warpback, it will warp to this y (in pixels)
                dy:  When using warpback, it will offset dy pixels
                ty:  When using warpback, it will warp to this y (in tiles)
                dty: When using warpback, it will offset dty tiles (it automatically centers the sprite on that tile)
layer: Layer
dir: Facing direction of the input person
name: Name of the input person
rmp: Name of the previous map


So, lets say we have a door and we enter into it going up, and that when we warp back, we dont want to be standing on that trigger again.
We want us to warp back to one tile down, so dty=1

Warp('emptyroom.rmp', 'EmptyRoom', 'An empty room', {dty:1} )

Then, from the empty room we exit with:

WarpBack();

note: You can use more values together in the warpbackInfoObject, just separate them with ",".
example: warp to Y tile 5 (ty=4 + dty=1). and X 338 pixels (x=340 + dx=-2)

Warp('emptyroom.rmp', 'EmptyRoom', 'An empty room', {dty:1, x:340,dx:-2,ty:4} );


run this when you just entered a dungeon:

MapChange.storeWarpBackInfo();

Then, when you need to immediately exit the dungeon, just
MapChange.restoreWarpBackInfo(); MapChange.warpBack(true);
You could also manage your own warpback point, or use these functions to restore to a savespot
(note that maybe you'll want a mix of loading a savegame, but keeping all experience)



MapChange.SeamlessWarpXY() is a very special warp type, it allows to move to another map in a
zelda-link-to-the-past style. It works better on maps that are of equal size.
You call it inside the map SCRIPT_ON_LEAVE_MAP_* scripts like so:
NORTH: SeamlessWarpXY("map.rmp", null, -1);
EAST:  SeamlessWarpXY("map.rmp", 0, null);
SOUTH: SeamlessWarpXY("map.rmp", null, 0);
WEST:  SeamlessWarpXY("map.rmp", -1, null);

Note that a screenshot is taken from both maps, so to get rid of the statusbar (if you have one)
You may want to clear the renderscript/set the renderscript before running this, or even better,
put this in your renderscript code:  if(!MapChange.active) { <Do your statbar things here>}
You can still draw the statusbar while scrolling to the next map, just redefine .scrollUpdateAndDraw()
Also, make something obstruct at the edge of 4 maps, or bad things will happen.


*** Tweaking ***

You can redefine these functions:
.preWarp() is everything you need to do before warping, after fading out.
Just like .postWarp() is what you redefine after a warp, before fading in.
.showName() is what you redefine after a warp, after fading in.
MapChange.active is 0 when not active, 2 when fading out, and 1 just before fading in. (and 3 when seamless-ing)

To change the fade-in speed from the current fade to 50, just: code somewhere MapChange.fadeInFrames=50;
You can also change the way the current fade is done by directly redefining MapChange.fadeIn();
The best way to create fade is to define your own, at the end of this file you can see
MapChange.DefineFade('grayfade', .... );
Note that fadeIn() and fadeOut() only get called once, from there overload UpdateAndDraw() if you need to loop.

For example, I've already coded spotfade, so to activate it do this:

MapChange.setFade('spot');


*** FLAGS ***

MapChange.maps holds information about visited maps, you may want to use/save this information.
To make our life easier, define a global variable like so:

var FLAGS = {MAP:MapChange.maps};

If you use Spheritype, maybe even this:

var FLAGS = { MAP: MapChange.maps, STATE: ScriptBind.world.state, MAPS: ScriptBind.world.maps };

This object can hold events that have happened. Do not confuse with EventMarker[], which can be resetted each time a cutscene starts.
FLAGS.MAP will hold flags of events that happen inside a certain map. We can check things like:
if(FLAGS.MAP[GetCurrentMap()].hasgrabbedtheloot) {...};
Be scarse with those objects, as they are all loaded/saved. Note that you can also use:
if(FLAGS.myevent1==true){...};

Flags are usefull when we have a one-time treasure or cutscene that playes only once, we can mark it inside this object with a persistant flag.

function hasHappened(it,val){ if(val==undefined) return FLAGS[it]; return FLAGS[it]=val; }


*** DO NOT CREATE CIRCULAR WARPPOINTS ***

Its bad when you warp on top of a trigger that warps you elsewhere, it will trigger this warp
and you'll probably be back on the same place you triggered from, or worse, stuck being
triggered back and forth between triggers. The way to avoid it is create a trigger at tile (X,Y)
and return at tile (X,Y+1) when you would be walking south ( (X+1,Y)) when walking east, etc.)
If you do need circular warppoints, increase this variable like so:  MapChange.delaybetweenwarps=300;

*/