Adding an Upgrade
Trosnoth upgrades are defined in trosnoth/model/upgrades.py
. Each upgrade is represented a subclass of Upgrade
. To define a new upgrade:
- Create a subclass of
Upgrade
. - Make sure you apply the
@registerUpgrade
decorator to your upgrade class. - Set
upgradeType
to a single byte that will be uniquely used to represent this upgrade when communicating over the network. (See below for a list of upgrades and their codes.) - Set
requiredStars
(cost) andtimeRemaining
(duration) - Set
name
to the name that should be used for this upgrade in the UI. - Set
action
to a unique string to be used in the UI event system for this upgrade (we generally just use the upgrade name in lower case). - Set
order
to a number that's used to determine the ordering of upgrades when listed in the UI. - Set
defaultKey
to the key that should be used to select this upgrade, or leave it asNone
for no keyboard shortcut. - Set
iconPath
to the name of the icon image file, withintrosnoth/data/sprites
. - Read the section on server and client timing below, and decide whether your upgrade needs the
doNotWaitForServer
flag to be set. - Write the upgrade code (see section below).
Server and client timing
For most upgrades, when a player requests the upgrade, there's a short delay while the message is sent to the server, which responds to confirm that the upgrade can be purchased. This is by far the simplest way for an upgrade to operate, and usually, this short delay is allowable. If this delay is ok for your upgrade, then you don't have to do anything special.
In rare cases (e.g. when firing a grenade), the exact position of the player when they purchased the upgrade is important. For these upgrades, a flag can be set on the class, doNotWaitForServer = True
. If this flag is set, then if the client thinks that the upgrade can be purchased, it goes ahead on that assumption. Then, once the server has double-checked and replied, either upgrade.serverVerified()
or upgrade.deniedByServer()
will be called on the client. If you are writing this kind of upgrade, make sure you think about what to do in the deniedByServer()
case. This can happen if other players on your team use your team's stars before your request reaches the server.
Writing upgrade code
Writing the upgrade code will be different depending on what your upgrade does. You may need to:
-
Write code that happens when the upgrade is used. The simplest way to do this is to override one or more of the following methods:
-
use()
: this is called when the upgrade is used (after the server confirms that's ok) -
timeIsUp()
: use this to perform a specific action when the upgrade timer runs out (e.g. explode the grenade) -
delete()
: called when the upgrade stops for any reason (e.g. time runs out, or user cancels it). You can override this method to undo things that you did inuse()
. But don't forget to call thesuper()
method or the upgrade won't actually be deleted.
-
-
Modify some of the game logic (e.g. in
universe.py
orplayer.py
) to respond to the fact that the player has an upgrade. You can check if the player has your upgrade usingisinstance(player.upgrade, MyUpgradeClass)
, orplayer.upgrade is not None and player.upgrade.upgradeType == MyUpgradeClass.upgradeType
. -
Update the UI to show the upgrade. The code to look at for this will be under
trosnoth/trosnothgui/ingame/
. Generally, start looking inviewManager.py
, then maybesprites.py
anduniversegui.py
.
Existing Upgrades
The following list contains current upgrades and their codes. Those marked as (special) cannot be used in the game unless the server has specifically enabled them.
- Shield:
's'
- Phase shift:
'h'
(special) - Turret:
't'
(special) - Minimap disruption:
'm'
- Grenade:
'g'
- Ricochet:
'r'
- Ninja:
'n'
- Shoxwave:
'w'
- Machine gun:
'x'
- Bomber:
'b'
- Respawn freezer:
'f'
(special) - Directatorship:
'd'
(special)