Topic: [TUTORIAL] Personalize your MOD (By Cartman34)
Hi,
I'll present you some things you have to know to modify your MOD but first you have to know you should not edit official MODs (CTF, DM & TDM) because it's illegal and clients will reject your server.
That's why I created my MOD "NSCTF" (Non Standard CTF) but I'll post it later, I need to check Copyrights...
This tutorial require knowledges in C/C++.
I'll name the MOD's displayed name "MODDN", the MOD's config name "MODCN" and the MOD's hidden name "MODHN" for my examples (Uppercase or lowercase names).
* Create your own MOD
MODs source files are in the directory /src/game/server/gamemodes/ .
Each MOD require the modhn.hpp and modhn.cpp files, you can copy it from another MOD, I think files name are understandable.
Then modify the file "/src/game/server/hooks.cpp":
- After others similar lines, add:
#include "gamemodes/modhn.hpp"
- In function mods_init(), after other similar lines but before the line starting with else, add lines
else if(strcmp(config.sv_gametype, "modcn") == 0)
game.controller = new GAMECONTROLLER_MODHN;
* [CTF]Change the flag capture range
Your MOD have to be a MOD derived from CTF.
This part explain to you how to change the flag capture range.
In your modhn.cpp file, in GAMECONTROLLER_MODHN::tick() method , there is the line:
if(distance(f->pos, flags[fi^1]->pos) < 32)
Change 32 by you own distance in pixel, 32px seems to be the tile size.
My change: 352.
* [CTF]Change the flag catch/return range
Your MOD have to be a MOD derived from CTF.
This part explain to you how to change the flag catch/return range.
In your modhn.cpp file, in GAMECONTROLLER_MODHN::tick() method , there is the line:
int num = game.world.find_entities(f->pos, 32.0f, (ENTITY**)close_characters, MAX_CLIENTS, NETOBJTYPE_CHARACTER);
Change 32.0f by you own distance in pixel (float), 32.0f seems to be the tile size.
My change: 96.0f.
* [CTF][FIX]Collision and the flag capture range
Your MOD have to be a MOD derived from CTF.
With my previous change about the flag capture range make some maps bugging.
This part explain to you how to fix it considering flag capture will be impossible through walls.
In your modhn.cpp file, in GAMECONTROLLER_MODHN::tick() method , there is the line:
if(distance(f->pos, flags[fi^1]->pos) < 32)
Where 32 could be another number according to your previous changes.
Change to:
if( distance(f->pos, flags[fi^1]->pos) < 32 && !col_intersect_line(f->pos, flags[fi^1]->pos, NULL, NULL) )
Don't forget to change again the number 32 according to your previous changes.
* Add the "Killing Spree" system to your MOD
- In your modhn.hpp file, in GAMECONTROLLER_MODHN definition , add to the public part:
unsigned int killingsprees[MAX_CLIENTS];
- In your modhn.cpp file, at the end of GAMECONTROLLER_NSCTF::GAMECONTROLLER_NSCTF(), add:
for( int i=0; i<MAX_CLIENTS; i++) {
killingsprees[i] = 0; //Initializing killing sprees array.
}
- In the same file, after:
int GAMECONTROLLER_NSCTF::on_character_death(class CHARACTER *victim, class PLAYER *killer, int weaponid)
{
GAMECONTROLLER::on_character_death(victim, killer, weaponid);
Add:
char buf[512];
if( killer != victim->player ) {
if( killingsprees[victim->player->client_id] >= 5 ) { //Victim was on a killing spree
int vksnb = 5;//5 is the minimum.
if( killingsprees[victim->player->client_id] >= 10 ) { //Begin the score steps with the maximum (10 here, but you can add other scores).
vksnb = 10;
}
str_format(buf, sizeof(buf), "%s %d-kills killing spree was ended by %s.", server_clientname(victim->player->client_id), vksnb, server_clientname(killer->client_id));
dbg_msg("game", buf);
game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf);
killer->score += (vksnb -(vksnb/5) -1);
}
killingsprees[killer->client_id] = killingsprees[killer->client_id]+1;
if( killingsprees[killer->client_id] >= 5 ) { //killer is on a killing spree
int kksnb = 0;//0 for not entering on a killing spree.
if( killingsprees[killer->client_id] == 5 ) {
kksnb = 5;
} else if( killingsprees[killer->client_id] == 10 ) {
kksnb = 10;
}
if( kksnb ) {
str_format(buf, sizeof(buf), "%s is on a killing spree with %d kills.", server_clientname(killer->client_id), kksnb );
dbg_msg("game", buf);
game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf);
killer->score += kksnb;
}
}
}
killingsprees[victim->player->client_id] = 0;
This is not the best way to implement killing sprees ont your server, it is the best way to implement it in your MOD.
Associate killing spree with the PLAYER would be better but here, it's not our business.
Ask me for questions/informations and report me for problems please.
You can join my home server on appart.cartman34.fr (instead of the usual IP address).