#include "mutators/_mod.inc"
#include "gamemodes/_mod.inc"
+
+#include "achievements.qc"
#include <common/util.qc>
#include <common/viewloc.qc>
#include <common/wepent.qc>
+#include <common/achievements.qc>
#include <common/util.qh>
#include <common/viewloc.qh>
#include <common/wepent.qh>
+#include <common/achievements.qh>
--- /dev/null
+#include "achievements.qh"
+
+void Achievements_attach(entity this) {
+ this.achievements = NEW(Achievements, this);
+}
+
+void Achievements_detach(entity this) {
+ if (this.achievements) {
+ this.achievements = NULL;
+ delete(this.achievements);
+ }
+ return;
+}
+
+void Achievements_set_achievement_value(entity this, string achieve, int value) {
+
+ if (achieve == "triple_kill") { this.triple_kill = value; }
+ if (achieve == "rage") { this.rage = value; }
+ if (achieve == "massacre") { this.massacre = value; }
+ if (achieve == "mayhem") { this.mayhem = value; }
+ if (achieve == "berserker") { this.berserker = value; }
+ if (achieve == "carnage") { this.carnage = value; }
+ if (achieve == "armageddon") { this.armageddon = value; }
+
+ if (achieve == "firstblood") { this.firstblood = value; }
+
+ if (achieve == "airshot") { this.airshot = value; }
+ if (achieve == "amazing") { this.amazing = value; }
+ if (achieve == "awesome") { this.awesome = value; }
+ if (achieve == "botlike") { this.botlike = value; }
+ if (achieve == "electrobitch") { this.electrobitch = value; }
+ if (achieve == "impressive") { this.impressive = value; }
+ if (achieve == "flyingyoda") { this.flyingyoda = value; }
+ if (achieve == "multirailed") { this.multirailed = value; }
+
+ return;
+}
+
+int Achievements_get_achievement_value(entity this, string achieve) {
+
+ if (achieve == "triple_kill") { return this.triple_kill; }
+ if (achieve == "rage") { return this.rage; }
+ if (achieve == "massacre") { return this.massacre; }
+ if (achieve == "mayhem") { return this.mayhem; }
+ if (achieve == "berserker") { return this.berserker; }
+ if (achieve == "carnage") { return this.carnage; }
+ if (achieve == "armageddon") { return this.armageddon; }
+
+ if (achieve == "firstblood") { return this.firstblood; }
+
+ if (achieve == "airshot") { return this.airshot; }
+ if (achieve == "amazing") { return this.amazing; }
+ if (achieve == "awesome") { return this.awesome; }
+ if (achieve == "botlike") { return this.botlike; }
+ if (achieve == "electrobitch") { return this.electrobitch; }
+ if (achieve == "impressive") { return this.impressive; }
+ if (achieve == "flyingyoda") { return this.flyingyoda; }
+ if (achieve == "multirailed") { return this.multirailed; }
+
+ return 0;
+}
+
+void Achievements_add_achievement_value(entity this, string achieve, int value) {
+ Achievements_set_achievement_value(this, achieve, Achievements_get_achievement_value(this, achieve)+value);
+}
+
+void Achievements_inc_achievement(entity this, string achieve) {
+ return Achievements_add_achievement_value(this, achieve, 1);
+}
+
+void Achievements_announce(Achievements this, entity whom, string title, string achieve) {
+ #ifdef SVQC
+ centerprint(whom, strcat(title, " [", ftos(this.get_achievement_value(this, achieve)), "]"));
+ #endif
+}
\ No newline at end of file
--- /dev/null
+#pragma once
+
+CLASS(Achievements, Object)
+
+ ATTRIB(Achievements, player, entity);
+
+ //Kill achievements
+ ATTRIB(Achievements, triple_kill, int, 0);
+ ATTRIB(Achievements, rage, int, 0);
+ ATTRIB(Achievements, massacre, int, 0);
+ ATTRIB(Achievements, mayhem, int, 0);
+ ATTRIB(Achievements, berserker, int, 0);
+ ATTRIB(Achievements, carnage, int, 0);
+ ATTRIB(Achievements, armageddon, int, 0);
+
+ //Boolean achievements (can be set only once)
+ ATTRIB(Achievements, firstblood, bool, 0);
+
+ //Notificated achievements
+ ATTRIB(Achievements, airshot, int, 0);
+ ATTRIB(Achievements, amazing, int, 0);
+ ATTRIB(Achievements, awesome, int, 0);
+ ATTRIB(Achievements, botlike, int, 0);
+ ATTRIB(Achievements, electrobitch, int, 0);
+ ATTRIB(Achievements, impressive, int, 0);
+ ATTRIB(Achievements, flyingyoda, int, 0); //In Yoda maybe incorrect conditions
+ ATTRIB(Achievements, multirailed, int, 0);
+
+ METHOD(Achievements, set_achievement_value, void(Achievements this, string achieve, int value));
+ METHOD(Achievements, get_achievement_value, int(Achievements this, string achieve));
+ METHOD(Achievements, add_achievement_value, void(Achievements this, string achieve, int value));
+ METHOD(Achievements, inc_achievement, void(Achievements this, string achieve));
+ METHOD(Achievements, announce, void(Achievements this, entity whom, string title, string achieve));
+
+ CONSTRUCTOR(Achievements, entity aplayer)
+ {
+ CONSTRUCT(Achievements);
+ this.player = aplayer;
+ }
+
+ENDCLASS(Achievements)
+
+.Achievements achievements;
+
+void Achievements_attach(entity this);
+void Achievements_detach(entity this);
#include <common/mutators/mutator/overkill/oknex.qh>
+#include <common/achievements.qh>
+
STATIC_METHOD(Client, Add, void(Client this, int _team))
{
ClientConnect(this);
PlayerStats_GameReport_AddEvent(sprintf("kills-%d", this.playerid));
+ Achievements_attach(this);
+
// always track bots, don't ask for cl_allow_uidtracking
if (IS_BOT_CLIENT(this))
PlayerStats_GameReport_AddPlayer(this);
ReadyCount();
if (vote_called && IS_REAL_CLIENT(this)) VoteCount(false);
+ Achievements_detach(this);
+
ONREMOVE(this);
}