Changes in Q2Java 0.9.5

Three big changes this time: the grappling hook code has been split from CTF, the code responsible for changing levels has been split from BaseQ2, and the code responsible for generating the DOM documents describing a level has been generalized and made more flexible.

The GrapplingHook code still resides in the q2java.ctf package, but is not tied directly to the CTFPlayer class anymore. A new gamelet named q2java.ctf.GrapplingHook can stick a grappling hook in the inventory of any instance or q2java.baseq2.Player - which means you can use the GH in plain DM, Paranoia, BountyHunters, and hopefully in any future Q2Java game.

The basic level changing code, which watches the timelimit and fraglimit, initiates intermission, and chooses which map comes next has been placed in a new gamelet named q2java.baseq2.LevelChanger. This gamelet can easily be extended to use some other method of choosing maps or deciding when to change. However, if this gamelet or something similar to it isn't loaded, the server will never change maps.

The Game class now creates a barebones DOM document when a level first starts, and fires off a GameStatusEvent.GAME_BUILD_DOCUMENT event to give interested objects (such as barryp.map.XMLMaps gamelets) a chance to place map info into the document. It then checks to see if the gamelets have supplied any entity info, and if they either haven't at all or have included the <include-default-entities/> tag, the Game will cause the string passed up from the .bsp file by the Engine to be parsed so that default entity info is included in the document before firing GameStatusEvent.GAME_PRESPAWN. This new scheme makes it easy for multiple sources to contribute to the initial level document.

Changes in Java Classes
q2java.baseq2.BaseQ2
Removed
Barry
Everything related to changing levels - from watching the fraglimit and timelimit to deciding what the next map will be. This has all been split off into a new gamelet q2java.baseq2.LevelChanger. If that gamelet or one similar to it isn't loaded, the map will never change now.
q2java.baseq2.GenericWeapon
Added
Barry
getOwner() method - to complement setOwner()
q2java.baseq2.LevelChanger
Added
Barry
New gamelet responsible for deciding when to change levels, initiating the intermission mode, and choosing the next map. Can easily be extended or replaced with other gamelets that choose maps in a different way.
q2java.baseq2.Player
Change
Barry
Class now implements GameStatusListener so it can listen for notifications of when to begin intermission.
Change
Barry
The two variations of addWeapon() are now public (was needed to support the new GrapplingHook gamelet).
Added
Barry
getIntermissionSpot() for choosing where a player should be placed during intermission.
Change
CheezHankrn
playerThink() now avoids calling fWeapon.weaponThink() if fWeapon is null - in preparation for future code that might have players wielding no weapons at some points. More work needs to be done though, since there's no real easy way to put the player in a no-weapon state - the game currently assumes you at least have a handblaster.
Change
Barry
print() method updated to pay better attention to the destination field of a PrintEvent, and display messages on the new PRINT_TALK_PRIVATE channel slightly differently than plain PRINT_TALK messages.
Change
Barry
spawn() now fires a PlayerStateEvent.STATE_SPAWNED event to let interested objects know the player has spawned (the GrapplingHook gamelet is interested in this so it can slip a grappling hook weapon into the player's inventory)
Change
Barry
startIntermission() now calls getIntermissionSpot() to find an intermission spot - rather than being passed that info as a parameter. This means that different players may now see different intermission spots (unlike stock Q2), but that should just make life more interesting.
Change
Barry
teleport() now fires a PlayerStateEvent.STATE_TELEPORTED event to let interested objects know the Player has made a -drastic- change in position. (The grappling hook is interested in this - since it needs to reset if a player teleports).
q2java.baseq2.event.PlayerStateEvent
Added
Barry
STATE_TELEPORTED constant for events signalling that the player has stepped through a teleporter.
Removed
Barry
STATE_SUSPENDEDSTOP constant wasn't being used, and had the same value as STATE_INVALID.
q2java.baseq2.spawn.item_breather
Change
Barry
stateChanged() altered to only reset on death or disconnection, didn't want to reset when the player goes through a teleporter
q2java.baseq2.spawn.item_enviro
Change
Barry
stateChanged() altered to only reset on death or disconnection, didn't want to reset when the player goes through a teleporter
q2java.baseq2.spawn.item_health_mega
Change
Barry
stateChanged() altered to only reset on death or disconnection, didn't want to reset when the player goes through a teleporter
q2java.baseq2.spawn.item_invulnerability
Change
Barry
stateChanged() altered to only reset on death or disconnection, didn't want to reset when the player goes through a teleporter
q2java.baseq2.spawn.item_quad
Change
Barry
stateChanged() altered to only reset on death or disconnection, didn't want to reset when the player goes through a teleporter
q2java.baseq2.spawn.worldspawn
Removed
Barry
worldspawn no longer does anything with the "nextmap" spawn parameter. Anything interested in that info (such as the new LevelChanger gamelet) can examine the level document to find it.
q2java.core.DefaultLevelDocumentFactory
Removed
Barry
Class removed, most code now moved to q2java.core.GameUtil
q2java.core.Game
Removed
Barry
Everything related to the obsolete LevelDocumentFactory interface including setLevelDocumentFactory() and getLevelDocumentFactory().
Fix
Barry
bprint() was causing double messages to be displayed on the console. Now it -only- fires off a PrintEvent, so it'll be up to some other code, probably some type of gamelet, to relay the message down to the console.
Added
Barry
getCurrentMapName() for finding out the current map name (duh). This info -could- be gotten from the level document, but the level document could also be screwed with, so the Game class now keeps a copy of the info that can be relied on.
Added
Barry
getOccupancySupport() to get access to the object the Game class uses to fire off OccupancyEvents.
Added
Barry
startIntermission() to fire off a new GameStatusEvent to let objects know that they should go into intermission mode. The new LevelChanger gamelet calls this when it decides it's time to move on.
Change
Barry
startLevel() reworked to allow multiple objects to contribute to building the DOM document describing the level, by creating a mostly-empty level document and firing off a GameStatusEvent.GAME_BUILD_DOCUMENT event when the level is first starting. startLevel() also fills in the document with the info passed up from the .bsp file by the Q2 engine if necessary.
q2java.core.Gamelet
Change
Barry
grabPlayers() now fires off a OccupancyEvent.PLAYER_CLASSCHANGE to let interested objects know that player classes are changing. (Was necessary for the grappling hook gamelet, so it could register itself with the new player objects).
q2java.core.GameUtil
Added
Barry
buildLevelDocument() can either build a mostly-empty level document that can be filled in by various sources, of a full one if a map entString is passed.
Added
Barry
parseAngle3f() and parsePoint3f() moved back here from the obsolete q2java.core.DefaultLevelDocumentFactory
Added
Barry
parseEntString() can parse a map's entString and insert the data into an existing DOM document. Used by buildLevelDocument() and Game.startLevel().
q2java.core.LevelDocumentFactory
Removed
Barry
This interface is no longer needed due to the new level document building system.
q2java.core.XMLTools
Added
Barry
copy() method can copy nodes from one document to another - handy for merging multiple map data sources together.
q2java.core.event.GameStatusEvent
Added
Barry
GAME_INTERMISSION constant for events that signal when intermission should begin
Added
Barry
GAME_BUILD_DOCUMENT constant for events that signal when objects should consider contributing info to the next level's document
Added
Barry
getMapEntities() and getSpawnpoint() to find out about what was specified by the engine during the GAME_BUILD_DOCUMENT event.
Removed
Barry
constructor taking (int, String) parameters wasn't being used.
q2java.core.event.PrintEvent
Added
Barry
PRINT_TALK_PRIVATE constant added as a channel for private messages
Change
Barry
getEvent() and releaseEvent() made public.
q2java.ctf.CTFPlayer
Change
Barry
clearSettings() no longer worries about giving the player a grappling hook. This means that in order to have a GH in CTF, you must load the GrapplingHook gamelet in addition to the CTF gamelet.
Change
Barry
playerThink() no longer is aware of the grappling hook - the hook itself is now smart enough to register as a PlayerMoveListener and do what it needs when a PlayerMoveEvent is fired from inside q2java.baseq2.Player.playerThink().
Removed
Barry
teleport() method that overrode q2java.baseq2.Player.teleport() no longer needed since the grappling hook is smart enough to listen for PlayerStateEvent.PLAYER_TELEPORTED and reset itself as necessary.
q2java.ctf.GrappleWeapon
Added
Barry
This class used to be named q2java.ctf.spawn.weapon_grapple, but since that's not an item that appears in maps, it seemed cleaner to move it outside the q2java.ctf.spawn package.
Added
Barry
Objects of this class register as PlayerMoveListeners when the weapon is active, and playerMoved() is called so the hook gets a chance to pull the player along.
Added
Barry
Objects of this class register as PlayerStateListeners so they can watch for the player teleporting and reset the weapon if that happens..
q2java.ctf.GrapplingHook
Added
Barry
New gamelet that should add the grappling hook to q2java.baseq2.Player or any subclass.
q2java.ctf.spawn.weapon_grapple
Added
Barry
This class was renamed to q2java.ctf.GrappleWeapon since that's not an item that appears in maps, and seemed cleaner to move it outside the q2java.ctf.spawn package.

Q2Java homepage