I have recently finished a rather elaborate "world map" for a GiP, and while it works the way I want it to work, it includes two designer sins- code being distributed over several scripts, and quite a bit of repetitive code. Maybe someone has a better idea, or some general pointers- I can script alright but sometimes I have a hard time finding an efficient (but more obscure) solution :)
First things first, the player aquires a map that can be used to fast-travel between locations. The map is initially almost empty but fills up during the game when new locations are pointed out by other characters.
Locations are represented by graphics that overlay the world map's "city grid". I am using objects placed within the worldmap room. Since these graphics are of irregular shape and often overlap, I am not using them for mouse click detection.
Instead I have a separate GUI with small "marker" buttons, small enough to never overlap. There is one button corresponding to one map "spot" object. I even created them in the same order, so that button[1] is the marker for object[1].
To unlock map locations, I wrote a function in GlobalScript and imported it so that its accessible from anywhere in the game. There is also a matching "lock" function. I included an enum with entries for all map locations which I pass as a parameter to make the code more readable:
function UnlockMapSpot(MapSpots ms)
{
if (ms == eMsLemonadeFactory)
{
gvMapSpot01Unlocked = true;
}
...
}
And here is where I am sure that things could be done more efficiently. Since you can only acess objects by name while in their room script file, I use global variables to keep track of everything, and that means I have the map room process a lot of stuff each time it is entered.
The "unlock function" only sets the global variable.
The worldmap room script checks the global variables, and makes objects and buttons visible according to that global variable's state.
This all works. It's not even too complicated, and the constant updates are necessary, too, because map spots can also vanish from the map. Still, I think there should be an easier way.
Any ideas?
Well, I would use same general method, actually: set the room "config" in global script and update room state at room load.
However, I suggest use an array(s) instead of separate variables. Since you already have locations enumerated, you can use their enum constants as array indices:
function UnlockMapSpot(MapSpots ms)
{
MapSpotsUnlocked[ms] = true;
}
Go in this direction, and this would greatly simplify things.
See, that's what I mean. Array, of course! Cleaned up things a lot already, thanks!
Still three places where map-related code is stored, though. Is there no workaround to getting an object reference from a script outside the room script?
If you use
object[ID].SetPosition(x ,y); // or any other object function
//or
if(Object.GetAtScreenXY(mouse.x, mouse.y) == object[ID])
It uses the object of that ID number in whatever room you're currently in, no matter what script it's put in.
Quote from: Scarab on Fri 19/07/2013 10:03:26
object[ID].SetPosition(x ,y); // or any other object function
It uses the object of that ID number in whatever room you're currently in, no matter what script it's put in.
Right... just make sure this function never called from
different room.
Just saying :)
Quote from: Scarab on Fri 19/07/2013 10:03:26
object[ID].SetPosition(x ,y); // or any other object function
It uses the object of that ID number in whatever room you're currently in, no matter what script it's put in.
[/quote]
I'd like to avoid that. As CW said there is a lot of potential for errors there. Object names would be preferred. Still, with the array in place the whole thing is a good deal tidier. If that's all that can be done I won't complain!