/* 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 #include #include 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); }