RENAMED TAGS AND FUNCTIONS
------------------------------------
In order to have a little more consistency, I've renamed some of the elements in dock screens.
The <OnInit> element for a screen has been renamed to <OnScreenInit>.
The <Initialize> element for a pane has been renamed to <OnPaneInit>.
The <Initialize> element for a display panel has been renamed to <OnDisplayInit>.
In all cases, the old names still work, so there is full compatibility with old mods. But new mods should start using the new names.
I've also deprecated the scrExitDock function and replaced it with a scrExitScreen function (for reasons described below).
NESTED SCREENS
-------------------
Imagine this example: You are creating a dock screen and you want one of your actions to show the looting screen. When looting is done, you want to return to your screen.
The current way of doing this is to create an action like this:
Code: Select all
<Action name="Loot" ...>
(block Nil
(setq gPrevScreen "MyDockScreen")
(scrShowScreen gScreen &dsLoot;)
)
</Action>
In 1.04 I've implemented a new attribute on <DockScreen>:
Code: Select all
<DockScreen UNID="&dsLoot;" nestedScreen="true">
...
Inside of dsLoot (the nested screen) an action can call:
(scrExitScreen gScreen)
The above will return to the original screen and pane that invoked the nested screen.
If the nested screen wants to force an undock (and not return to the original screen) it can call:
(scrExitScreen gScreen 'forceUndock)
Note that with this implementation, callers don't have to do anything special. They can still invoke a nested screen with scrShowScreen.
CHOOSING AN INITIAL SCREEN
----------------------------------
Today, a station can define its first screen using the dockScreen= attribute. But sometimes you want the first screen to change depending on circumstances. For example, if the ship is contaminated you might want to show the decontamination screen instead of the default one.
The old way to do that is to add an <OnScreenInit> (previously <OnInit>) on a dock screen and call scrShowScreen if you want to redirect to a different screen.
Again, this works well, but it is somewhat limiting.
1.04 adds a new event to stations (and ships with dock ports):
Code: Select all
<Events>
<GetDockScreen>
(switch
{ship is radioactive}
(list &dsDecontaminate; 10)
{mission success}
(list "MissionSuccess" 4)
Nil
)
</GetDockScreen>
</Events>
[I'll describe how priorities work a little further down.]
As always, you can specify a dock screen as either an UNID (in which case we look for a global dock screen) or as a string, which makes the engine look for any dock screens contained by the station.
[Note that GetDockScreen (and all events that start with Get...) must NOT have any side-effects. That is, you can't make any assumptions about how many times it will get called or what will be done with the result. In particular, you cannot assume that the screen that you return will actually be shown, because it could be overridden later (see below).]
But GetDockScreen alone is not very interesting. The real power comes from having a global version of that event:
GetGlobalDockScreen
As you might imagine, GetGlobalDockScreen is an event that can be added to any type. It is called whenever the player docks with anything, and it is allowed to return a dock screen to show instead of the station's default screen.
For example, instead of having every commonwealth station check for a contaminated ship, we can now do this globally:
Code: Select all
<Sovereign UNID="&svCommonwealth;">
<Events>
<GetGlobalDockScreen>
(if (and {we docked with a commonwealth station}
{ship is radioactive})
(list &dsDecontaminate; 10)
Nil
)
</GetGlobalDockScreen>
</Events>
</Sovereign>
[Remember: As with all global events, the type that the event is attached to does NOT alter how the event is called. Although the event above is attached to the svCommonwealth sovereign, the event will be called regardless of what station we dock with--that's why we have to explicitly check to see if we've docked with a Commonwealth station.]
Perhaps you are starting to see why the priority field is necessary. There are now potentially multiple pieces of code telling us what screen to show:
1. Multiple types with a <GetGlobalDockScreen> could tell us to show different screens.
2. The station's <GetDockScreen> could tell us to show a particular screen.
To resolve this conflict we simply pick the screen with the highest priority. For example, if a station's <GetDockScreen> tells us to show the "MissionComplete" screen with priority 4, but a <GetGlobalDockScreen> tells us to show dsDecontaminate with priority 10, then we will show the dsDecontaminate screen.
Note: If the screen returned by <GetDockScreen> or <GetGlobalDockScreen> is a nestedScreen, then we will ask for a screen again when the nested screen exits. In the example above, if dsDecontaminate is a nested screen, then after it decontaminates the ship and exits, we call <GetDockScreen> and <GetGlobalDockScreen> again. This time, the "MissionComplete" screen wins, so we show that screen.
ADDING NEW ACTIONS
-------------------------
1.04 adds a new function:
Code: Select all
(scrAddAction gScreen actionID pos label [key] [special] code)
actionID is a string to identify the action (use it in calls like scrEnableAction).
pos is the position of the action. 0 inserts the action before all other actions; 1 inserts it after the first action, etc.
label is the label for the action.
key is the short-cut key for the action.
special can be either 'cancel, 'default, 'nextKey, or 'prevKey to set those short-cuts to the action.
code is the code to execute when the action is selected by the user.
Of course, the real use for this function is to add new actions to existing screen. The OnGlobalPaneInit event allows you to do that:
Code: Select all
<Events>
<OnGlobalPaneInit>
; aScreenUNID is the UNID of the screen being shown
; aScreen is the screen name (if this is a local screen)
; aPane is the pane being shown
(if (and (eq aScreenUNID &dsShipInterior;) (eq aPane "Default"))
(scrAddAction
gScreen
'myNewAction
3
"Do something cool"
{some code}
)
)
</OnGlobalPaneInit>
</Events>
This technique will allow multiple mods to add entries to the ship's status screen without having to override the whole screen.
Of course, the usual limits for the number of actions per pane still applies.
NEW ATTRIBUTES
--------------------
In 1.04 I've converted many stations to use the new techniques above. I'm using attributes on a station to determine which screens to invoke. If you are creating (e.g.,) new Commonwealth stations, you should use the following attributes instead of the intCommonwealthOnInit function. Search the XMLs for <GetGlobalDockScreen> to see how these are used.
Any station with the "blackMarket" attribute will refuse docking unless you have a Black Market ID and will check for debts to the Black Market.
Any station with the "commonwealthCustoms" attribute will check for contamination, slaves, contraband, etc.
Any station with the "corporateCustoms" attribute will check for contamination and crimes against the Corporate Hierarchy. If a station has the "corporateDecon" attribute, then the player will be decontaminated (otherwise, docking will be refused).
Any station with the "commonwealthFleet" attribute will check for Fleet crimes, etc.
Any station with the "ringers" attribute will check for crimes against the Ringers.
Any station with the "sistersOfDomina" attribute will check for contamination.
COMPATIBILITY
------------------
The new mechanics introduce in 1.04 should not break any mods, but some other changes to Transcendence.xml might cause some problems.
In particular, I've migrated many of the special screens (such as decontamination) that used to be called in <OnScreenInit> to use <GetGlobalDockScreen>.
In many cases, functions like intCommonwealtOnInit have been removed, because they were no longer needed. If your mod relied on those functions, then you should either make your own copy or migrate to the new techniques.
Of course, none of the new techniques will work on version 1.0. Starting in 1.04 the engine will accept extensions marked as version "1.1". If you have an extension that requires 1.04 or higher, then you should mark it as "1.1" (because this is part of the 1.1 stream).