這將刪除頁面 "Creating achievement plugins"
。請三思而後行。
Achievements are stored in an SQLite3 database. It's acceptable for single-server use, though it shouldn't be too difficult to adapt this to other database implementations (most queries are threaded).
There are three tables:
achievements
: This stores the base list of achievements. An achievement name is mapped to
its unique identifier, and there is a constraint for non-duplicate achievement names. The other
columns are for custom display implementations and are probably deprecated.achievement_status
: This stores the progress of players' achievements. It refers to the
achievement_id
in the previous table (probably should make it a foreign key), and associates
it with a Steam account and some arbitrary data that plugins can use to track achievement
progress / state. The achieved
column is a Unix timestamp; an achievement is considered
unlocked if the value in the column is non-zero.achievement_languages
: Maps achievement names from the achievements
table to language
shortcodes, to localized names and descriptions. This is used to display / manage translated
strings for players.The plugin will handle populating most of these; you just need to run the provided init script to create the empty database and update the localization strings to set human-friendly names / descriptions once you've declared some achievements.
Calling CustomAchievement
looks up the given name in the database and returns an existing ID,
or allocates a new ID in the database and returns that if the name doesn't already exist.
#include <custom_achievements>
// store the achievement identifier in global scope
CustomAchievement g_OneShotAchievement;
// you may want to use a library availability callback to make sure everything gets updated
public void OnAllPluginsLoaded() {
g_OneShotAchievement = CustomAchievement("#some_achievement", AchievementStyle_Single);
}
The database will fill in a placeholder localized name / description in the
achievement_languages
table for the default server language.
One-shot achievements don't have any persistent state associated with them, other than being flagged as achieved or not.
When a player does something achievement-worthy, all you need to do is call
CustomAchievement.Award()
with a client index.
void ClientDoesSomethingCool(int client) {
g_OneShotAchievement.Award(client);
}
If the player hasn't already obtained this achievement, all the nearby players will see the achievement particles and a message in chat telling players about their feat.
Every achievement can have metadata associated with each Steam account. Metadata is an arbitrary string; it's up to the plugin to decide what to store there and how to parse it.
// in this example, achievement metadata is a string representation of an integer value
// assume that g_ProgressAchievement was previously initalized and include is present
CustomAchievement g_ProgressAchievement;
int g_nThingCount[MAXPLAYERS + 1];
public void OnClientAuthorized(int client) {
// reset count while we wait for the threaded query to call back
g_nThingCount[client] = 0;
g_ProgressAchievement.FetchMetadata(client, OnProgressLoaded, GetClientUserId(client));
}
// last argument is `any data` but we're storing an `int userid` there
public void OnProgressLoaded(CustomAchievement achievement, const char[] metadata, int userid) {
int client = GetClientOfUserId(userid);
if (client) {
g_nThingCount[client] = StringToInt(metadata);
}
}
public void OnClientDisconnect(int client) {
char numberValue[16];
IntToString(g_nThingCount[client], numberValue, sizeof(numberValue));
g_ProgressAchievement.StoreMetadata(client, numberValue);
}
void ClientDidCoolThingButDoItAgainProbably(int client) {
if (g_nThingCount[client]++ > 5) {
g_ProgressAchievement.Award(client);
}
}
Metadata is meant to keep everything in one place (making it easy to join tables when you want to present that information to players). If you don't need that functionality, Client Preferences might be preferable as a primary data source.
There isn't a built-in one; sorry. I personally use an MOTD view with a static page that fetches player data from my server's monolithic API backend and parses it out client-side.
Grab the data directly from the database with your choice of technology and parse out the achievement-specific metadata.
這將刪除頁面 "Creating achievement plugins"
。請三思而後行。