/*
Based on pkmode src
*/
/// Sample Hercules Plugin
#include "common/hercules.h" /* Should always be the first Hercules file included! (if you don't make it first, you won't be able to use interfaces) */
#include "common/memmgr.h"
#include "common/mmo.h"
#include "common/socket.h"
#include "common/strlib.h"
#include "common/nullpo.h"
#include "common/timer.h"
#include "map/clif.h"
#include "map/pc.h"
#include "map/battle.h"
#include "map/script.h"
#include "common/HPMDataCheck.h" /* should always be the last Hercules file included! (if you don't make it last, it'll intentionally break compile time) */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
HPExport struct hplugin_info pinfo = {
"Pkmode", // Plugin name
SERVER_TYPE_MAP,// Which server types this plugin works with?
"0.1", // Plugin version
HPM_VERSION, // HPM Version (don't change, macro is automatically updated)
};
struct pkmode_data_struct {
struct {
unsigned int pk_mode : 1;
} state;
int64 pk_mode_tick;
};
struct Battle_Config battle_config;
int pc_setnewpc_post(int retVal, struct map_session_data *sd, int *account_id, int *char_id, int *login_id1, unsigned int *client_tick, int *sex, int *fd)
{
struct pkmode_data_struct *pksd;
if (!(pksd = getFromMSD(sd, 0))) {
CREATE(pksd, struct pkmode_data_struct, 1);
pksd->pk_mode_tick = timer->gettick();
addToMSD(sd, pksd, 0, true);
}
return retVal;
}
ACMD(pkmode) {
struct pkmode_data_struct *pksd;
int64 tick;
if (!(pksd = getFromMSD(sd, 0))) {
return 0;
}
tick = timer->gettick();
nullpo_retr(-1, sd);
nullpo_retr(-1, pksd);
if (map->list[sd->bl.m].flag.pvp || map->list[sd->bl.m].flag.gvg || map->list[sd->bl.m].flag.gvg_castle || map->list[sd->bl.m].flag.gvg_dungeon) {
clif->message(sd->fd, "You can only change your PK state on non-PVP maps.");
return false;
}
if (DIFF_TICK(pksd->pk_mode_tick, tick) > 0) { //check the delay before use this command again
clif->message(sd->fd, "You cannot turn OFF your PK state twice within just 15 minutes.");
return false;
}
else {
if (!pksd->state.pk_mode) {
pksd->state.pk_mode = 1;
clif->message(sd->fd, "Your PK state is now OFF");
pksd->pk_mode_tick = tick + 0; //set the delay here
}
else {
pksd->state.pk_mode = 0;
clif->message(sd->fd, "Your PK state is now ON");
pksd->pk_mode_tick = tick + 1500000; //set the delay here
}
}
return true;
}
int battle_check_target_post(int retVal, struct block_list *src, struct block_list *target, int flag)
{
struct block_list *s_bl = src, *t_bl = target;
struct pkmode_data_struct *pksd;
int16 m; //map
if (retVal <= 0) return retVal; // Don't do anything
if (s_bl->type != BL_PC && s_bl->type != BL_SKILL) return retVal;
nullpo_ret(src);
nullpo_ret(target);
m = target->m;
if ((t_bl = battle->get_master(target)) == NULL)
t_bl = target;
if ((s_bl = battle->get_master(src)) == NULL)
s_bl = src;
switch (t_bl->type)
{
case BL_PC:
{
const struct map_session_data *sd = BL_UCCAST(BL_PC, t_bl);
if (!(pksd = getFromMSD(sd, 0))) {
return 0;
}
switch (battle->get_current_skill(src)) {
case SN_WINDWALK: // add more like this for other skills with same issue
return retVal;
}
if (t_bl == s_bl)
break;
if (map->list[m].flag.pvp && pksd->state.pk_mode && s_bl->type != BL_MOB)
return 0;
}
}
switch(s_bl->type)
{
case BL_PC:
{
const struct map_session_data *sd = BL_UCCAST(BL_PC, s_bl);
if (!(pksd = getFromMSD(sd, 0))) {
return 0;
}
if (s_bl != t_bl) {
if (map->list[m].flag.pvp && pksd->state.pk_mode && t_bl->type != BL_MOB)
return 0;
}
}
}
return retVal;;
}
// pc.h stuffs here
// learn how to append to structs.
/* run when server starts */
HPExport void plugin_init (void) {
addAtcommand("pk",pkmode);//link our '@sample' command
addHookPost("pc->setnewpc", pc_setnewpc_post);
addHookPost("battle->check_target", battle_check_target_post);
}