#include <amxmodx>
#include <amxmisc>
#include <rtd_core>
#define PLUGIN_NAME "[.:HGS:.] Roll the Dice Modular: Core"
#define PLUGIN_AUTHOR "Glaster"
#define PLUGIN_VERSION "1.4"
#define RTD_COOLDOWN 60
#define MAX_LEN 128
#define ADMIN_ACCESS ADMIN_RCON
new g_iMenuPage[33];
new g_iSelectedRarity[33];
new Array:g_PluginNames[3], g_EffectFunctions[3], g_EffectNames[3];
new g_EffectCounts[3]
new playersUsageTime[32];
new iMinRarity = 0;
new iMaxRarity = 100;
// For case when only Normal and Ultra Rare rarity present
new iGapMin = -1;
new iGapMax = -1;
static const rarityNames[][] = {
"",
" a Rare effect",
" a Ultra Rare effect"
};
static const rarityServerNames[][] = {
"Normal",
"Rare",
"Ultra Rare"
};
public plugin_init(){
register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
for (new i = 0; i <= EFFECT_ULTRA_RARE; i++) {
g_PluginNames[i] = ArrayCreate(MAX_LEN);
g_EffectFunctions[i] = ArrayCreate(MAX_LEN);
g_EffectNames[i] = ArrayCreate(MAX_LEN);
}
register_clcmd("say rtd","cmdRollTheDice");
register_clcmd("say /rtd","cmdRollTheDice");
register_clcmd("say rollthedice","cmdRollTheDice");
register_clcmd("say_team rtd","cmdRollTheDice");
register_clcmd("say_team /rtd","cmdRollTheDice");
register_clcmd("say_team rollthedice","cmdRollTheDice");
// Admin commands
register_clcmd("say /rtdtest", "cmdRTDTestMenu");
register_clcmd("say_team /rtdtest", "cmdRTDTestMenu");
register_clcmd("amx_rtdtest", "cmdRTDTestMenu", ADMIN_ACCESS, "- Opens RTD effect testing menu");
server_print("")
}
public plugin_natives(){
register_library("rtd_core");
register_native("rtdc_register_effect", "native_register_effect");
}
public native_register_effect(plugin, params){
new name[32], version[32], author[32], fileName[32], status[32];
get_plugin(plugin, fileName, 31, name, 31, version, 31, author, 31, status, 31);
if (params != 3){
server_print("[RTD CORE] Plugin %s was not loaded: invalid amount of parameters. Received: %d", fileName, params);
return -1;
}
new effectFunction[32], effectName[32];
get_string(1, effectFunction, charsmax(effectFunction));
get_string(2, effectName, charsmax(effectName));
new iRarity = get_param(3);
if (iRarity < EFFECT_NORMAL || iRarity > EFFECT_ULTRA_RARE) {
log_amx("[RTD] Invalid rarity value: %d", iRarity);
return -1;
}
ArrayPushString(g_PluginNames[iRarity], fileName);
ArrayPushString(g_EffectFunctions[iRarity], effectFunction);
ArrayPushString(g_EffectNames[iRarity], effectName);
g_EffectCounts[iRarity]++;
resetRarityParams();
server_print("[RTD CORE] Effect %s (%s) has been succesfully registered (Rarity: %s)", effectName, fileName, rarityServerNames[iRarity]);
return 0;
}
public client_disconnected(id){
playersUsageTime[id] = 0;
}
public __roll_effect(id, iRarity){
new index = random_num(0, g_EffectCounts[iRarity] - 1);
new pluginName[64], funcName[64], effectName[64];
ArrayGetString(g_PluginNames[iRarity], index, pluginName, charsmax(pluginName));
ArrayGetString(g_EffectFunctions[iRarity], index, funcName, charsmax(funcName));
ArrayGetString(g_EffectNames[iRarity], index, effectName, charsmax(effectName));
if (callfunc_begin(funcName, pluginName)) {
callfunc_push_int(id);
callfunc_end();
new name[32];
get_user_name(id, name, charsmax(name));
client_print(0, print_chat, "[RTD] %s has rolled%s %s! Type rtd in chat to roll the dice!", name, rarityNames[iRarity], effectName);
} else {
server_print("[RTD] Failed to execute effect: %s in plugin %s", funcName, pluginName);
}
}
public cmdRollTheDice(iPlayer){
if (!hasRegisteredEffects()){
server_print("[RTD CORE] ERROR! No effect plugins registered!");
return;
}
new iCurrentTime = get_systime();
if (iCurrentTime - playersUsageTime[iPlayer] >= RTD_COOLDOWN){
playersUsageTime[iPlayer] = iCurrentTime;
new iRarity = rollRarity()
__roll_effect(iPlayer, iRarity)
} else {
client_print(iPlayer, print_center, "It's not time yet to roll the dice!^n^nWait for %d seconds", playersUsageTime[iPlayer] + 60 - get_systime());
}
}
public hasRegisteredEffects(){
return g_EffectCounts[EFFECT_NORMAL] != 0 || g_EffectCounts[EFFECT_RARE] != 0 || g_EffectCounts[EFFECT_ULTRA_RARE] != 0;
}
public resetRarityParams(){
if (hasRegisteredEffects()){
// All rarities present
if (g_EffectCounts[EFFECT_NORMAL] > 0 && g_EffectCounts[EFFECT_RARE] > 0 && g_EffectCounts[EFFECT_ULTRA_RARE] > 0){
iMinRarity = 0;
iMaxRarity = 100;
}
// Only Normal rarity present
else if (g_EffectCounts[EFFECT_NORMAL] > 0 && g_EffectCounts[EFFECT_RARE] == 0 && g_EffectCounts[EFFECT_ULTRA_RARE] == 0){
iMaxRarity = EFFECT_RARE_PERCENT -1;
}
// Only Rare rarity present
else if (g_EffectCounts[EFFECT_NORMAL] == 0 && g_EffectCounts[EFFECT_RARE] > 0 && g_EffectCounts[EFFECT_ULTRA_RARE] == 0){
iMinRarity = EFFECT_NORMAL_PERCENT + 1;
iMaxRarity = EFFECT_ULTRA_RARE_PERCENT - 1;
}
// Only Ultra Rare rarity present
else if (g_EffectCounts[EFFECT_NORMAL] == 0 && g_EffectCounts[EFFECT_RARE] == 0 && g_EffectCounts[EFFECT_ULTRA_RARE] > 0){
iMinRarity = EFFECT_RARE_PERCENT + 1;
iMaxRarity = EFFECT_ULTRA_RARE_PERCENT;
}
// Only normal and Rare rarities present
else if (g_EffectCounts[EFFECT_NORMAL] > 0 && g_EffectCounts[EFFECT_RARE] >0 && g_EffectCounts[EFFECT_ULTRA_RARE] == 0 ){
iMinRarity = 0;
iMaxRarity = EFFECT_ULTRA_RARE_PERCENT;
}
// Only Rare and Ultra Rare rarities present
else if (g_EffectCounts[EFFECT_NORMAL] == 0 && g_EffectCounts[EFFECT_RARE] > 0 && g_EffectCounts[EFFECT_ULTRA_RARE] > 0 ){
iMinRarity = EFFECT_RARE_PERCENT;
iMaxRarity = EFFECT_ULTRA_RARE_PERCENT;
}
// Only Normal and Ultra Rare rarities present
else {
iMinRarity = 0;
iMaxRarity = EFFECT_NORMAL_PERCENT;
iGapMin = EFFECT_RARE_PERCENT + 1;
iGapMax = 100;
}
}
}
public rollRarity(){
if (iGapMin == -1){
new iRarityValue = random_num(iMinRarity, iMaxRarity);
return valueToRarity(iRarityValue);
} else {
new iFirstGap = random_num(iMinRarity, iMaxRarity);
new iSecondGap = random_num(iGapMin, iGapMax);
new iGapSelected = random_num(0, 1);
if (iGapSelected == 0){
return valueToRarity(iFirstGap);
}
return valueToRarity(iSecondGap);
}
}
public valueToRarity(const iRarity){
if (iRarity < EFFECT_NORMAL_PERCENT+1){
return EFFECT_NORMAL
}
if (iRarity < EFFECT_ULTRA_RARE_PERCENT){
return EFFECT_RARE
}
return EFFECT_ULTRA_RARE;
}
public cmdRTDTestMenu(id){
if (!(get_user_flags(id) & ADMIN_ACCESS)){
client_print(id, print_chat, "[RTD] You don't have access to this command.");
return PLUGIN_HANDLED;
}
if (!hasRegisteredEffects()){
client_print(id, print_chat, "[RTD] No effects registered yet!");
return PLUGIN_HANDLED;
}
g_iMenuPage[id] = 0;
showRaritySelectionMenu(id);
return PLUGIN_HANDLED;
}
public showRaritySelectionMenu(id){
new menu = menu_create("\r[RTD Admin]\w Select Effect Rarity:^n", "rarityMenuHandler");
new rarityText[64];
if (g_EffectCounts[EFFECT_NORMAL] > 0){
formatex(rarityText, charsmax(rarityText), "Normal Effects \y(%d)^n", g_EffectCounts[EFFECT_NORMAL]);
menu_additem(menu, rarityText, "0");
}
if (g_EffectCounts[EFFECT_RARE] > 0){
formatex(rarityText, charsmax(rarityText), "Rare Effects \y(%d)^n", g_EffectCounts[EFFECT_RARE]);
menu_additem(menu, rarityText, "1");
}
if (g_EffectCounts[EFFECT_ULTRA_RARE] > 0){
formatex(rarityText, charsmax(rarityText), "Ultra Rare Effects \y(%d)^n", g_EffectCounts[EFFECT_ULTRA_RARE]);
menu_additem(menu, rarityText, "2");
}
menu_setprop(menu, MPROP_EXIT, MEXIT_ALL);
menu_display(id, menu, 0);
}
public rarityMenuHandler(id, menu, item){
if (item == MENU_EXIT){
menu_destroy(menu);
return PLUGIN_HANDLED;
}
new data[6], access, callback;
menu_item_getinfo(menu, item, access, data, charsmax(data), _, _, callback);
g_iSelectedRarity[id] = str_to_num(data);
menu_destroy(menu);
showEffectListMenu(id);
return PLUGIN_HANDLED;
}
public showEffectListMenu(id){
new iRarity = g_iSelectedRarity[id];
new title[128];
formatex(title, charsmax(title), "\r[RTD Admin]\w %s Effects:", rarityServerNames[iRarity]);
new menu = menu_create(title, "effectListMenuHandler");
new effectName[64], itemData[6];
for (new i = 0; i < g_EffectCounts[iRarity]; i++){
ArrayGetString(g_EffectNames[iRarity], i, effectName, charsmax(effectName));
formatex(itemData, charsmax(itemData), "%d", i);
formatex(effectName, charsmax(effectName), "%s^n", effectName);
menu_additem(menu, effectName, itemData);
}
menu_setprop(menu, MPROP_BACKNAME, "Back");
menu_setprop(menu, MPROP_NEXTNAME, "Next");
menu_setprop(menu, MPROP_EXITNAME, "Exit");
menu_display(id, menu, g_iMenuPage[id]);
}
public effectListMenuHandler(id, menu, item){
if (item == MENU_EXIT){
menu_destroy(menu);
g_iMenuPage[id] = 0;
showRaritySelectionMenu(id);
return PLUGIN_HANDLED;
}
new data[6], access, callback;
menu_item_getinfo(menu, item, access, data, charsmax(data), _, _, callback);
new effectIndex = str_to_num(data);
menu_destroy(menu);
showPlayerSelectionMenu(id, effectIndex);
return PLUGIN_HANDLED;
}
public showPlayerSelectionMenu(id, effectIndex){
new title[128];
new iRarity = g_iSelectedRarity[id];
new effectName[64];
ArrayGetString(g_EffectNames[iRarity], effectIndex, effectName, charsmax(effectName));
formatex(title, charsmax(title), "\r[RTD Admin]\w Apply '%s' to:^n", effectName);
new menu = menu_create(title, "playerSelectionHandler");
// Store effect index in first item's info
new itemData[32];
formatex(itemData, charsmax(itemData), "%d", effectIndex);
new players[32], numPlayers, playerName[32];
get_players(players, numPlayers, "ach"); // alive, not bots, not hltv
for (new i = 0; i < numPlayers; i++){
new player = players[i];
get_user_name(player, playerName, charsmax(playerName));
new playerData[6];
formatex(playerData, charsmax(playerData), "%d|%d", effectIndex, player);
menu_additem(menu, playerName, playerData);
}
if (numPlayers == 0){
menu_additem(menu, "\dNo players available", "-1");
}
menu_setprop(menu, MPROP_BACKNAME, "Back");
menu_setprop(menu, MPROP_EXITNAME, "Cancel");
menu_display(id, menu, 0);
}
public playerSelectionHandler(id, menu, item){
if (item == MENU_EXIT){
menu_destroy(menu);
showEffectListMenu(id);
return PLUGIN_HANDLED;
}
new data[32], access, callback;
menu_item_getinfo(menu, item, access, data, charsmax(data), _, _, callback);
menu_destroy(menu);
new effectIndex, targetPlayer;
new parts[2][16];
// Parse data: "effectIndex|playerID"
new pos = contain(data, "|");
if (pos != -1){
copy(parts[0], charsmax(parts[]), data[0]);
parts[0][pos] = EOS;
copy(parts[1], charsmax(parts[]), data[pos + 1]);
effectIndex = str_to_num(parts[0]);
targetPlayer = str_to_num(parts[1]);
if (targetPlayer > 0 && is_user_connected(targetPlayer)){
applyEffectToPlayer(id, targetPlayer, effectIndex);
}
}
showPlayerSelectionMenu(id, effectIndex);
return PLUGIN_HANDLED;
}
public applyEffectToPlayer(admin, target, effectIndex){
new iRarity = g_iSelectedRarity[admin];
new pluginName[64], funcName[64], effectName[64];
ArrayGetString(g_PluginNames[iRarity], effectIndex, pluginName, charsmax(pluginName));
ArrayGetString(g_EffectFunctions[iRarity], effectIndex, funcName, charsmax(funcName));
ArrayGetString(g_EffectNames[iRarity], effectIndex, effectName, charsmax(effectName));
if (callfunc_begin(funcName, pluginName)){
callfunc_push_int(target);
callfunc_end();
new adminName[32], targetName[32];
get_user_name(admin, adminName, charsmax(adminName));
get_user_name(target, targetName, charsmax(targetName));
client_print(admin, print_chat, "[RTD] Applied '%s' to %s", effectName, targetName);
client_print(0, print_chat, "[RTD Admin] %s applied '%s' to %s", adminName, effectName, targetName);
} else {
client_print(admin, print_chat, "[RTD] Failed to apply effect!");
}
}