Medal System

This article covers the medal system which is developed alongside base melees in the base melee repository. A standalone download will be available on Lorry shortly. Described briefly, the medal system is a rule which awards player medals for crazy or courageous achievements.


Description

The medal system is a rule which can be added to any OpenClonk scenario and awards medals to players. Medals are awarded for special or courageous achievements and come with rewards in the sense of clunkers. For examples of medals have a look at the complete list of medals in the basic rule. Medals themselves are represented by single definitions in OpenClonk and the player can earn more than one of each type. The medal system should incentivize players to undertake more courageous and experimental actions and result into more fun while playing. The amount of medals you have earned can be viewed by typing

  /medals

in the chat dialogue while being ingame. The medals earned by other players can be viewed by clicking on their names in the menu that has appeared.

List of Medals

The list of all medals in the current version of the medal rule is given here.

Medal Index Reward Description
Hat-trick 1 25 Awarded when three enemies are killed in a row.
Miner 2 50 Awarded for mining at least one thousand clunkers during a single round.
Decorated 3 50 Awarded when you get awarded with more than ten medals in a single round.
Kamikaze 4 25 Awarded when you kill yourself and an enemy clonk simultaneously.
Pyromania 5 40 Awarded for setting 100 objects on fire in a single round.
Critical Hit 6 20 Awarded for dealing more than 40 damage in a single hit.
Demolition 7 50 Awarded for destroying ten structures.
Heroic 8 40 Awarded when a crew member survives more than 250 damage points.
Chain Reaction 9 20 Awarded for setting of a chain reaction of firestone explosions.
Rocketeer 10 25 Awarded for killing an enemy clonk with a rocket explosion.
Construction 11 40 Awarded for aiding in the construction of ten buildings.

Proposals for medals also have been made, see this list.

Medal Index Reward Description
Eagle Eye ?? ?? Awarded for a kill with a ranged weapon outside your viewing range.

Feel free to add proposals here by updating this wiki page.

Medal Scripting

Now we dive into the mode technical part of the medal system and explain how medals can be created. If you want to create a medal yourself this is a must read. A medal is a single object definition with a script, possibly supported by multiple appendto scripts. The medal definition is placed in

  Medals.ocd/

and the appendto scripts are placed in a

  System.ocg/

folder located inside the medal definition. The latest version of the medal rule can be found here and should always be used when developing new medals. If you want to create a new medal, first copy the template medal and rename the object to your new medal name. Also be sure to change the ID and the StringTables of the medal.

Medal Basics

Now let's have a look at the template medal's scripts and walk through the code. First we find the usual header, where you can put your name as author and a local variable for the medal's name // A medal should have a name. local Name = "$Name$"; and a local variable for the description // A medal should have description. local Description = "$Description$"; These entries should remain the same, and will automatically grab the right translation from your already up to date string tables.

There are three other trivial entries as well // A medal should have this function and return true. public func IsMedal() { return true; } this piece of script you can also leave as is. It just tells any other object requesting that this definition is in fact a medal! Then we have // A medal should have this function and return a unique index. // Consult the list of existing medals to get a unique index. // The medal index can be any integer between 0 and 254. public func GetMedalIndex() { return 0; } The internal storing of medals in the player file and or league requires medals to have a unique identifier. This identifier has to be between 0 and 254 cause of league requirements on the storage of extra data. If you add a medal you can make sure the identifier is unique by looking into the MedalList.txt and add your medal there when you want to contribute to the medal rule. As last we have // A medal can have a reward in clunker which needs to be // returned by this function. public func GetMedalReward() { return 0; } which should return the reward a player gets in clunker when being awarded this medal. Keep this a fair amount based on the difficulty and likelihood to obtain such a medal.

Medal Scripts

Now that we have covered the basics we can actually go to the code of a medal. The medal rule performs certain callbacks to the medals by terms of definition calls of the form Medal_Template->~OnMedalCallback(int param); The full list of callbacks is also available in the template medal's scripts and are listed here. // Called when the round starts, technically when the rule is created. public func OnRoundStart() { //Log("OnRoundStart() callback has been done in %i.", Medal_Template); return; }

// Called when the round is finished, i.e. when all players are eliminated // or all goals are fulfilled. public func OnRoundFinish() { //Log("OnRoundFinish() callback has been done in %i.", Medal_Template); return; }

// Called when a player is initialized. public func OnInitializePlayer(int plr) { //Log("OnInitializePlayer(%d) callback has been done in %i.", plr, Medal_Template); return; }

// Called when a player is removed. public func OnRemovePlayer(int plr) { //Log("OnRemovePlayer(%d) callback has been done in %i.", plr, Medal_Template); return; }

// Called when a crew member dies. public func OnCrewDeath(object crew, int killed_by) { //Log("OnCrewDeath(%v, %d) callback has been done in %i.", crew, killed_by, Medal_Template); return; }

// Called when a medal is awarded to a player. public func OnMedalAwarded(id medal, int to_plr) { //Log("OnMedalAwarded(%i, %d) callback has been done in %i.", medal, to_plr, Medal_Template); return; } The comments explain when the callback is being called by the medal rule. A medal can then be awarded to a player by making a definition call to the medal rule of the form Rule_Medals->AwardMedal(medal_id, plr); Now we have all the ingredients to make our kill medal script.

Example: Kill Medal

Now that we have discussed all features of the medal, we can start to code our own simple medal. For this purpose let's assume we want to award a medal for a simple single kill. The kill should of course be made by an existing player and should be done on an enemy player. Also the kill may only be awarded when the rule is active, that is when the round is running (from game start to game over).

So the most simple implementation would be to use the OnCrewDeath callback in the medal script. The kill medal then may look like this /*-- Medal Properties --*/

local Name = "$Name$"; local Description = "$Description$";

public func IsMedal() { return true; } public func GetMedalIndex() { return 1; } public func GetMedalReward() { return 25; }

/*-- Medal Scripts --*/

// Called when a crew member dies. public func OnCrewDeath(object crew, int killed_by) { // Award a medal if the killer is not the owner of the crew. if (killed_by != NO_OWNER) if (Hostile(crew->GetOwner(), killed_by)) Rule_Medals->~AwardMedal(Medal_Kill, killed_by); return; } The first few lines of the code define the basic properties of the medal and then in line 12 the real code starts. Every time a crew member dies the OnCrewDeath callback is made and the medal can check if this death should be awarded with a medal. Now we check whether the killer is a real player in line 16. Then check whether the killer was hostile to the killed crew member in line 17, if so we award the medal in line 18. This concludes the simple kill medal script and now it should work in game.