summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/HPMmap.c51
-rw-r--r--src/map/HPMmap.h6
-rw-r--r--src/map/atcommand.c532
-rw-r--r--src/map/atcommand.h1
-rw-r--r--src/map/battle.c48
-rw-r--r--src/map/battle.h24
-rw-r--r--src/map/battleground.c6
-rw-r--r--src/map/battleground.h6
-rw-r--r--src/map/chrif.c12
-rw-r--r--src/map/chrif.h16
-rw-r--r--src/map/clif.c926
-rw-r--r--src/map/clif.h57
-rw-r--r--src/map/elemental.c14
-rw-r--r--src/map/elemental.h10
-rw-r--r--src/map/guild.c8
-rw-r--r--src/map/guild.h4
-rw-r--r--src/map/homunculus.c2
-rw-r--r--src/map/homunculus.h2
-rw-r--r--src/map/instance.c90
-rw-r--r--src/map/instance.h10
-rw-r--r--src/map/irc-bot.c6
-rw-r--r--src/map/irc-bot.h8
-rw-r--r--src/map/itemdb.c10
-rw-r--r--src/map/itemdb.h9
-rw-r--r--src/map/map.c117
-rw-r--r--src/map/map.h42
-rw-r--r--src/map/mapreg.h2
-rw-r--r--src/map/mapreg_sql.c2
-rw-r--r--src/map/mercenary.c4
-rw-r--r--src/map/mercenary.h4
-rw-r--r--src/map/mob.c81
-rw-r--r--src/map/mob.h30
-rw-r--r--src/map/npc.c107
-rw-r--r--src/map/npc.h16
-rw-r--r--src/map/packets_struct.h255
-rw-r--r--src/map/party.c3
-rw-r--r--src/map/party.h2
-rw-r--r--src/map/pc.c159
-rw-r--r--src/map/pc.h106
-rw-r--r--src/map/pet.c29
-rw-r--r--src/map/pet.h20
-rw-r--r--src/map/script.c214
-rw-r--r--src/map/script.h7
-rw-r--r--src/map/skill.c435
-rw-r--r--src/map/skill.h75
-rw-r--r--src/map/status.c4651
-rw-r--r--src/map/status.h12
-rw-r--r--src/map/unit.c38
-rw-r--r--src/map/unit.h24
49 files changed, 4513 insertions, 3780 deletions
diff --git a/src/map/HPMmap.c b/src/map/HPMmap.c
index 3ba9ae725..ca4a7a2e8 100644
--- a/src/map/HPMmap.c
+++ b/src/map/HPMmap.c
@@ -11,6 +11,7 @@
#include "map.h"
//
+#include "atcommand.h"
#include "chat.h"
#include "chrif.h"
#include "duel.h"
@@ -33,6 +34,18 @@
#include <string.h>
#include <time.h>
+struct HPM_atcommand_list {
+ //tracking currently not enabled
+ // - requires modifying how plugins calls atcommand creation
+ // - needs load/unload during runtime support
+ //unsigned int pID;/* plugin id */
+ char name[ATCOMMAND_LENGTH];
+ AtCommandFunc func;
+};
+
+struct HPM_atcommand_list *atcommand_list = NULL;
+unsigned int atcommand_list_items = 0;
+
void HPM_map_addToMSD(struct map_session_data *sd, void *data, unsigned int id, unsigned int type, bool autofree) {
struct HPluginData *HPData;
unsigned int i;
@@ -103,4 +116,40 @@ void HPM_map_plugin_load_sub(struct hplugin *plugin) {
plugin->hpi->addToMSD = HPM->import_symbol("addToMSD",plugin->idx);
plugin->hpi->getFromMSD = HPM->import_symbol("getFromMSD",plugin->idx);
plugin->hpi->removeFromMSD = HPM->import_symbol("removeFromMSD",plugin->idx);
-} \ No newline at end of file
+}
+
+bool HPM_map_add_atcommand(char *name, AtCommandFunc func) {
+ unsigned int i = 0;
+
+ for(i = 0; i < atcommand_list_items; i++) {
+ if( !strcmpi(atcommand_list[i].name,name) ) {
+ ShowDebug("HPM_map_add_atcommand: duplicate command '%s', skipping...\n", name);
+ return false;
+ }
+ }
+
+ i = atcommand_list_items;
+
+ RECREATE(atcommand_list, struct HPM_atcommand_list , ++atcommand_list_items);
+
+ safestrncpy(atcommand_list[i].name, name, sizeof(atcommand_list[i].name));
+ atcommand_list[i].func = func;
+
+ return true;
+}
+
+void HPM_map_atcommands(void) {
+ unsigned int i;
+
+ for(i = 0; i < atcommand_list_items; i++) {
+ if( !atcommand->add(atcommand_list[i].name,atcommand_list[i].func) ) {
+ ShowDebug("HPM_map_atcommands: duplicate command '%s', skipping...\n", atcommand_list[i].name);
+ continue;
+ }
+ }
+}
+
+void HPM_map_do_final(void) {
+ if( atcommand_list )
+ aFree(atcommand_list);
+}
diff --git a/src/map/HPMmap.h b/src/map/HPMmap.h
index a6cac4ace..96515772b 100644
--- a/src/map/HPMmap.h
+++ b/src/map/HPMmap.h
@@ -5,6 +5,7 @@
#define _HPM_MAP_
#include "../common/cbasetypes.h"
+#include "../map/atcommand.h"
struct hplugin;
struct map_session_data;
@@ -13,6 +14,11 @@ void HPM_map_addToMSD(struct map_session_data *sd, void *data, unsigned int id,
void *HPM_map_getFromMSD(struct map_session_data *sd, unsigned int id, unsigned int type);
void HPM_map_removeFromMSD(struct map_session_data *sd, unsigned int id, unsigned int type);
+bool HPM_map_add_atcommand(char *name, AtCommandFunc func);
+void HPM_map_atcommands(void);
+
void HPM_map_plugin_load_sub(struct hplugin *plugin);
+void HPM_map_do_final(void);
+
#endif /* _HPM_MAP_ */
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 980f61ad9..ed5852b76 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -45,6 +45,7 @@
#include "mapreg.h"
#include "quest.h"
#include "searchstore.h"
+#include "HPMmap.h"
#include <stdio.h>
#include <stdlib.h>
@@ -384,9 +385,7 @@ ACMD(mapmove) {
unsigned short mapindex;
short x = 0, y = 0;
int16 m = -1;
-
- nullpo_retr(-1, sd);
-
+
memset(map_name, '\0', sizeof(map_name));
if (!message || !*message ||
@@ -435,7 +434,6 @@ ACMD(mapmove) {
ACMD(where) {
struct map_session_data* pl_sd;
- nullpo_retr(-1, sd);
memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
@@ -463,9 +461,7 @@ ACMD(where) {
*------------------------------------------*/
ACMD(jumpto) {
struct map_session_data *pl_sd = NULL;
-
- nullpo_retr(-1, sd);
-
+
if (!message || !*message) {
clif->message(fd, msg_txt(911)); // Please enter a player name (usage: @jumpto/@warpto/@goto <char name/ID>).
return false;
@@ -504,9 +500,7 @@ ACMD(jumpto) {
ACMD(jump)
{
short x = 0, y = 0;
-
- nullpo_retr(-1, sd);
-
+
memset(atcmd_output, '\0', sizeof(atcmd_output));
sscanf(message, "%hd %hd", &x, &y);
@@ -554,9 +548,7 @@ ACMD(who) {
*/
int display_type = 1;
int map_id = -1;
-
- nullpo_retr(-1, sd);
-
+
if (strstr(command, "map") != NULL) {
if (sscanf(message, "%15s %23s", map_name, player_name) < 1 || (map_id = map->mapname2mapid(map_name)) < 0)
map_id = sd->bl.m;
@@ -650,9 +642,7 @@ ACMD(whogm)
char player_name[NAME_LENGTH];
struct guild *g;
struct party_data *p;
-
- nullpo_retr(-1, sd);
-
+
memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(match_text, '\0', sizeof(match_text));
memset(player_name, '\0', sizeof(player_name));
@@ -726,9 +716,7 @@ ACMD(whogm)
/*==========================================
*
*------------------------------------------*/
-ACMD(save)
-{
- nullpo_retr(-1, sd);
+ACMD(save) {
pc->setsavepoint(sd, sd->mapindex, sd->bl.x, sd->bl.y);
if (sd->status.pet_id > 0 && sd->pd)
@@ -746,9 +734,7 @@ ACMD(save)
*------------------------------------------*/
ACMD(load) {
int16 m;
-
- nullpo_retr(-1, sd);
-
+
m = map->mapindex2mapid(sd->status.save_point.map);
if (m >= 0 && map->list[m].flag.nowarpto && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
clif->message(fd, msg_txt(249)); // You are not authorized to warp to your save map.
@@ -771,9 +757,7 @@ ACMD(load) {
ACMD(speed)
{
int speed;
-
- nullpo_retr(-1, sd);
-
+
memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message || sscanf(message, "%d", &speed) < 1) {
@@ -782,15 +766,21 @@ ACMD(speed)
return false;
}
- if (speed < 0) {
+ sd->state.permanent_speed = 0;
+
+ if (speed < 0)
sd->base_status.speed = DEFAULT_WALK_SPEED;
- sd->state.permanent_speed = 0; // Remove lock when set back to default speed.
- } else {
+ else
sd->base_status.speed = cap_value(speed, MIN_WALK_SPEED, MAX_WALK_SPEED);
- sd->state.permanent_speed = 1; // Set lock when set to non-default speed.
- }
+
status_calc_bl(&sd->bl, SCB_SPEED);
- clif->message(fd, msg_txt(8)); // Speed changed.
+
+ if( sd->base_status.speed != DEFAULT_WALK_SPEED ) {
+ sd->state.permanent_speed = 1; // Set lock when set to non-default speed.
+ clif->message(fd, msg_txt(8)); // Speed changed.
+ } else
+ clif->message(fd, msg_txt(172)); //Speed returned to normal.
+
return true;
}
@@ -799,8 +789,6 @@ ACMD(speed)
*------------------------------------------*/
ACMD(storage)
{
- nullpo_retr(-1, sd);
-
if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag)
return false;
@@ -820,8 +808,6 @@ ACMD(storage)
*------------------------------------------*/
ACMD(guildstorage)
{
- nullpo_retr(-1, sd);
-
if (!sd->status.guild_id) {
clif->message(fd, msg_txt(252));
return false;
@@ -851,7 +837,6 @@ ACMD(guildstorage)
ACMD(option)
{
int param1 = 0, param2 = 0, param3 = 0;
- nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d %d %d", &param1, &param2, &param3) < 1 || param1 < 0 || param2 < 0 || param3 < 0)
{// failed to match the parameters so inform the user of the options
@@ -883,7 +868,6 @@ ACMD(option)
*
*------------------------------------------*/
ACMD(hide) {
- nullpo_retr(-1, sd);
if (sd->sc.option & OPTION_INVISIBLE) {
sd->sc.option &= ~OPTION_INVISIBLE;
if (sd->disguise != -1 )
@@ -927,7 +911,6 @@ ACMD(jobchange)
{
int job = 0, upper = 0;
const char* text;
- nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d %d", &job, &upper) < 1) {
int i;
@@ -989,7 +972,6 @@ ACMD(jobchange)
*------------------------------------------*/
ACMD(kill)
{
- nullpo_retr(-1, sd);
status_kill(&sd->bl);
clif->message(sd->fd, msg_txt(13)); // A pity! You've died.
if (fd != sd->fd)
@@ -1002,7 +984,6 @@ ACMD(kill)
*------------------------------------------*/
ACMD(alive)
{
- nullpo_retr(-1, sd);
if (!status->revive(&sd->bl, 100, 100)) {
clif->message(fd, msg_txt(667));
return false;
@@ -1018,7 +999,6 @@ ACMD(alive)
ACMD(kami)
{
unsigned long color=0;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -1054,7 +1034,6 @@ ACMD(kami)
ACMD(heal)
{
int hp = 0, sp = 0; // [Valaris] thanks to fov
- nullpo_retr(-1, sd);
sscanf(message, "%d %d", &hp, &sp);
@@ -1116,7 +1095,6 @@ ACMD(item)
struct item item_tmp;
struct item_data *item_data;
int get_count, i;
- nullpo_retr(-1, sd);
memset(item_name, '\0', sizeof(item_name));
@@ -1172,7 +1150,6 @@ ACMD(item2)
int item_id, number = 0;
int identify = 0, refine = 0, attr = 0;
int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
- nullpo_retr(-1, sd);
memset(item_name, '\0', sizeof(item_name));
@@ -1244,7 +1221,6 @@ ACMD(item2)
ACMD(itemreset)
{
int i;
- nullpo_retr(-1, sd);
for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0) {
@@ -1262,7 +1238,7 @@ ACMD(itemreset)
ACMD(baselevelup)
{
int level=0, i=0, status_point=0;
- nullpo_retr(-1, sd);
+
level = atoi(message);
if (!message || !*message || !level) {
@@ -1322,7 +1298,6 @@ ACMD(baselevelup)
ACMD(joblevelup)
{
int level=0;
- nullpo_retr(-1, sd);
level = atoi(message);
@@ -1375,9 +1350,7 @@ ACMD(help) {
const char *command_name = NULL;
char *default_command = "help";
AtCommandInfo *tinfo = NULL;
-
- nullpo_retr(-1, sd);
-
+
if (!message || !*message) {
command_name = default_command; // If no command_name specified, display help for @help.
} else {
@@ -1461,7 +1434,6 @@ int atcommand_pvpoff_sub(struct block_list *bl,va_list ap)
}
ACMD(pvpoff) {
- nullpo_retr(-1, sd);
if (!map->list[sd->bl.m].flag.pvp) {
clif->message(fd, msg_txt(160)); // PvP is already Off.
@@ -1499,7 +1471,6 @@ int atcommand_pvpon_sub(struct block_list *bl,va_list ap)
}
ACMD(pvpon) {
- nullpo_retr(-1, sd);
if (map->list[sd->bl.m].flag.pvp) {
clif->message(fd, msg_txt(161)); // PvP is already On.
@@ -1524,7 +1495,6 @@ ACMD(pvpon) {
*
*------------------------------------------*/
ACMD(gvgoff) {
- nullpo_retr(-1, sd);
if (!map->list[sd->bl.m].flag.gvg) {
clif->message(fd, msg_txt(162)); // GvG is already Off.
@@ -1545,7 +1515,6 @@ ACMD(gvgoff) {
*
*------------------------------------------*/
ACMD(gvgon) {
- nullpo_retr(-1, sd);
if (map->list[sd->bl.m].flag.gvg) {
clif->message(fd, msg_txt(163)); // GvG is already On.
@@ -1567,7 +1536,6 @@ ACMD(gvgon) {
ACMD(model)
{
int hair_style = 0, hair_color = 0, cloth_color = 0;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -1599,7 +1567,6 @@ ACMD(model)
ACMD(dye)
{
int cloth_color = 0;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -1626,7 +1593,6 @@ ACMD(dye)
ACMD(hair_style)
{
int hair_style = 0;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -1653,7 +1619,6 @@ ACMD(hair_style)
ACMD(hair_color)
{
int hair_color = 0;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -1729,9 +1694,7 @@ ACMD(go)
{ MAP_MALAYA, 242, 211 }, // 34=Malaya Port
{ MAP_ECLAGE, 110, 39 }, // 35=Eclage
};
-
- nullpo_retr(-1, sd);
-
+
memset(map_name, '\0', sizeof(map_name));
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -1881,7 +1844,6 @@ ACMD(monster)
int i, k, range;
short mx, my;
unsigned int size;
- nullpo_retr(-1, sd);
memset(name, '\0', sizeof(name));
memset(monster, '\0', sizeof(monster));
@@ -1988,7 +1950,6 @@ int atkillmonster_sub(struct block_list *bl, va_list ap)
ACMD(killmonster) {
int map_id, drop_flag;
char map_name[MAP_NAME_LENGTH_EXT];
- nullpo_retr(-1, sd);
memset(map_name, '\0', sizeof(map_name));
@@ -2015,7 +1976,6 @@ ACMD(refine)
{
int i,j, position = 0, refine = 0, current_position, final_refine;
int count;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -2095,7 +2055,6 @@ ACMD(produce)
int item_id, attribute = 0, star = 0;
struct item_data *item_data;
struct item tmp_item;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(item_name, '\0', sizeof(item_name));
@@ -2151,7 +2110,6 @@ ACMD(produce)
ACMD(memo)
{
int position = 0;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -2186,7 +2144,6 @@ ACMD(memo)
*------------------------------------------*/
ACMD(gat) {
int y;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -2211,7 +2168,6 @@ ACMD(gat) {
ACMD(displaystatus)
{
int i, type, flag, tick, val1 = 0, val2 = 0, val3 = 0;
- nullpo_retr(-1, sd);
if (!message || !*message || (i = sscanf(message, "%d %d %d %d %d %d", &type, &flag, &tick, &val1, &val2, &val3)) < 1) {
clif->message(fd, msg_txt(1009)); // Please enter a status type/flag (usage: @displaystatus <status type> <flag> <tick> {<val1> {<val2> {<val3>}}}).
@@ -2283,7 +2239,6 @@ ACMD(skillpoint)
{
int point;
unsigned int new_skill_point;
- nullpo_retr(-1, sd);
if (!message || !*message || (point = atoi(message)) == 0) {
clif->message(fd, msg_txt(1011)); // Please enter a number (usage: @skpoint <number of points>).
@@ -2331,7 +2286,6 @@ ACMD(skillpoint)
ACMD(zeny)
{
int zeny=0, ret=-1;
- nullpo_retr(-1, sd);
if (!message || !*message || (zeny = atoi(message)) == 0) {
clif->message(fd, msg_txt(1012)); // Please enter an amount (usage: @zeny <amount>).
@@ -2359,7 +2313,6 @@ ACMD(param) {
const char* param[] = { "str", "agi", "vit", "int", "dex", "luk" };
short* stats[6];
//we don't use direct initialization because it isn't part of the c standard.
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -2419,7 +2372,6 @@ ACMD(stat_all) {
int index, count, value, max, new_value;
short* stats[6];
//we don't use direct initialization because it isn't part of the c standard.
- nullpo_retr(-1, sd);
stats[0] = &sd->status.str;
stats[1] = &sd->status.agi;
@@ -2478,7 +2430,6 @@ ACMD(guildlevelup)
int level = 0;
short added_level;
struct guild *guild_info;
- nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d", &level) < 1 || level == 0) {
clif->message(fd, msg_txt(1014)); // Please enter a valid level (usage: @guildlvup/@guildlvlup <# of levels>).
@@ -2518,7 +2469,6 @@ ACMD(makeegg)
{
struct item_data *item_data;
int id, pet_id;
- nullpo_retr(-1, sd);
if (!message || !*message) {
clif->message(fd, msg_txt(1015)); // Please enter a monster/egg name/ID (usage: @makeegg <pet>).
@@ -2556,7 +2506,6 @@ ACMD(makeegg)
*------------------------------------------*/
ACMD(hatch)
{
- nullpo_retr(-1, sd);
if (sd->status.pet_id <= 0)
clif->sendegg(sd);
else {
@@ -2574,7 +2523,6 @@ ACMD(petfriendly)
{
int friendly;
struct pet_data *pd;
- nullpo_retr(-1, sd);
if (!message || !*message || (friendly = atoi(message)) < 0) {
clif->message(fd, msg_txt(1016)); // Please enter a valid value (usage: @petfriendly <0-1000>).
@@ -2611,7 +2559,6 @@ ACMD(pethungry)
{
int hungry;
struct pet_data *pd;
- nullpo_retr(-1, sd);
if (!message || !*message || (hungry = atoi(message)) < 0) {
clif->message(fd, msg_txt(1017)); // Please enter a valid number (usage: @pethungry <0-100>).
@@ -2645,7 +2592,6 @@ ACMD(pethungry)
ACMD(petrename)
{
struct pet_data *pd;
- nullpo_retr(-1, sd);
if (!sd->status.pet_id || !sd->pd) {
clif->message(fd, msg_txt(184)); // Sorry, but you have no pet.
return false;
@@ -2670,7 +2616,6 @@ ACMD(petrename)
ACMD(recall) {
struct map_session_data *pl_sd = NULL;
- nullpo_retr(-1, sd);
if (!message || !*message) {
clif->message(fd, msg_txt(1018)); // Please enter a player name (usage: @recall <char name/ID>).
@@ -2712,7 +2657,6 @@ ACMD(recall) {
*------------------------------------------*/
ACMD(char_block)
{
- nullpo_retr(-1, sd);
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
@@ -2748,7 +2692,6 @@ ACMD(char_ban)
int year, month, day, hour, minute, second, value;
time_t timestamp;
struct tm *tmtime;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
@@ -2829,7 +2772,6 @@ ACMD(char_ban)
*------------------------------------------*/
ACMD(char_unblock)
{
- nullpo_retr(-1, sd);
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
@@ -2850,7 +2792,6 @@ ACMD(char_unblock)
*------------------------------------------*/
ACMD(char_unban)
{
- nullpo_retr(-1, sd);
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
@@ -2870,7 +2811,6 @@ ACMD(char_unban)
*
*------------------------------------------*/
ACMD(night) {
- nullpo_retr(-1, sd);
if (map->night_flag != 1) {
pc->map_night_timer(pc->night_timer_tid, 0, 0, 1);
@@ -2886,7 +2826,6 @@ ACMD(night) {
*
*------------------------------------------*/
ACMD(day) {
- nullpo_retr(-1, sd);
if (map->night_flag != 0) {
pc->map_day_timer(pc->day_timer_tid, 0, 0, 1);
@@ -2905,9 +2844,7 @@ ACMD(doom)
{
struct map_session_data* pl_sd;
struct s_mapiterator* iter;
-
- nullpo_retr(-1, sd);
-
+
iter = mapit_getallusers();
for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) )
{
@@ -2932,9 +2869,7 @@ ACMD(doommap)
{
struct map_session_data* pl_sd;
struct s_mapiterator* iter;
-
- nullpo_retr(-1, sd);
-
+
iter = mapit_getallusers();
for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) )
{
@@ -2970,9 +2905,7 @@ ACMD(raise)
{
struct map_session_data* pl_sd;
struct s_mapiterator* iter;
-
- nullpo_retr(-1, sd);
-
+
iter = mapit_getallusers();
for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) )
if( pc_isdead(pl_sd) )
@@ -2991,9 +2924,7 @@ ACMD(raisemap)
{
struct map_session_data* pl_sd;
struct s_mapiterator* iter;
-
- nullpo_retr(-1, sd);
-
+
iter = mapit_getallusers();
for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) )
if (sd->bl.m == pl_sd->bl.m && pc_isdead(pl_sd) )
@@ -3011,7 +2942,6 @@ ACMD(raisemap)
ACMD(kick)
{
struct map_session_data *pl_sd;
- nullpo_retr(-1, sd);
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
@@ -3043,7 +2973,6 @@ ACMD(kickall)
{
struct map_session_data* pl_sd;
struct s_mapiterator* iter;
- nullpo_retr(-1, sd);
iter = mapit_getallusers();
for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) )
@@ -3065,7 +2994,6 @@ ACMD(kickall)
*------------------------------------------*/
ACMD(allskill)
{
- nullpo_retr(-1, sd);
pc->allskillup(sd); // all skills
sd->status.skill_point = 0; // 0 skill points
clif->updatestatus(sd, SP_SKILLPOINT); // update
@@ -3080,7 +3008,6 @@ ACMD(allskill)
ACMD(questskill)
{
uint16 skill_id, index;
- nullpo_retr(-1, sd);
if (!message || !*message || (skill_id = atoi(message)) <= 0)
{// also send a list of skills applicable to this command
@@ -3123,7 +3050,6 @@ ACMD(questskill)
ACMD(lostskill)
{
uint16 skill_id, index;
- nullpo_retr(-1, sd);
if (!message || !*message || (skill_id = atoi(message)) <= 0)
{// also send a list of skills applicable to this command
@@ -3169,7 +3095,6 @@ ACMD(spiritball)
{
int max_spiritballs;
int number;
- nullpo_retr(-1, sd);
max_spiritballs = min(ARRAYLENGTH(sd->spirit_timer), 0x7FFF);
@@ -3196,7 +3121,6 @@ ACMD(spiritball)
ACMD(party)
{
char party_name[NAME_LENGTH];
- nullpo_retr(-1, sd);
memset(party_name, '\0', sizeof(party_name));
@@ -3217,7 +3141,6 @@ ACMD(guild)
{
char guild_name[NAME_LENGTH];
int prev;
- nullpo_retr(-1, sd);
memset(guild_name, '\0', sizeof(guild_name));
@@ -3236,7 +3159,6 @@ ACMD(guild)
ACMD(breakguild)
{
- nullpo_retr(-1, sd);
if (sd->status.guild_id) { // Check if the player has a guild
struct guild *g;
@@ -3269,7 +3191,6 @@ ACMD(breakguild)
*
*------------------------------------------*/
ACMD(agitstart) {
- nullpo_retr(-1, sd);
if (map->agit_flag == 1) {
clif->message(fd, msg_txt(73)); // War of Emperium is currently in progress.
return false;
@@ -3286,7 +3207,6 @@ ACMD(agitstart) {
*
*------------------------------------------*/
ACMD(agitstart2) {
- nullpo_retr(-1, sd);
if (map->agit2_flag == 1) {
clif->message(fd, msg_txt(404)); // "War of Emperium SE is currently in progress."
return false;
@@ -3303,7 +3223,6 @@ ACMD(agitstart2) {
*
*------------------------------------------*/
ACMD(agitend) {
- nullpo_retr(-1, sd);
if (map->agit_flag == 0) {
clif->message(fd, msg_txt(75)); // War of Emperium is currently not in progress.
return false;
@@ -3320,7 +3239,6 @@ ACMD(agitend) {
*
*------------------------------------------*/
ACMD(agitend2) {
- nullpo_retr(-1, sd);
if (map->agit2_flag == 0) {
clif->message(fd, msg_txt(406)); // "War of Emperium SE is currently not in progress."
return false;
@@ -3337,8 +3255,6 @@ ACMD(agitend2) {
* @mapexit - shuts down the map server
*------------------------------------------*/
ACMD(mapexit) {
- nullpo_retr(-1, sd);
-
map->do_shutdown();
return true;
}
@@ -3351,7 +3267,6 @@ ACMD(idsearch)
char item_name[100];
unsigned int i, match;
struct item_data *item_array[MAX_SEARCH];
- nullpo_retr(-1, sd);
memset(item_name, '\0', sizeof(item_name));
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -3387,7 +3302,6 @@ ACMD(recallall)
struct map_session_data* pl_sd;
struct s_mapiterator* iter;
int count;
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -3434,7 +3348,6 @@ ACMD(guildrecall)
int count;
char guild_name[NAME_LENGTH];
struct guild *g;
- nullpo_retr(-1, sd);
memset(guild_name, '\0', sizeof(guild_name));
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -3492,7 +3405,6 @@ ACMD(partyrecall)
char party_name[NAME_LENGTH];
struct party_data *p;
int count;
- nullpo_retr(-1, sd);
memset(party_name, '\0', sizeof(party_name));
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -3544,7 +3456,6 @@ ACMD(partyrecall)
*------------------------------------------*/
ACMD(reloaditemdb)
{
- nullpo_retr(-1, sd);
itemdb->reload();
clif->message(fd, msg_txt(97)); // Item database has been reloaded.
@@ -3555,7 +3466,6 @@ ACMD(reloaditemdb)
*
*------------------------------------------*/
ACMD(reloadmobdb) {
- nullpo_retr(-1, sd);
mob->reload();
pet->read_db();
homun->reload();
@@ -3572,7 +3482,6 @@ ACMD(reloadmobdb) {
*------------------------------------------*/
ACMD(reloadskilldb)
{
- nullpo_retr(-1, sd);
skill->reload();
homun->reload_skill();
elemental->reload_skilldb();
@@ -3680,7 +3589,6 @@ ACMD(reloadscript) {
struct s_mapiterator* iter;
struct map_session_data* pl_sd;
- nullpo_retr(-1, sd);
//atcommand_broadcast( fd, sd, "@broadcast", "Server is reloading scripts..." );
//atcommand_broadcast( fd, sd, "@broadcast", "You will feel a bit of lag at this point !" );
@@ -3732,9 +3640,7 @@ ACMD(mapinfo) {
int i, m_id, chat_num = 0, list = 0, vend_num = 0;
unsigned short m_index;
char mapname[24];
-
- nullpo_retr(-1, sd);
-
+
memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(mapname, '\0', sizeof(mapname));
memset(direction, '\0', sizeof(direction));
@@ -3975,8 +3881,6 @@ ACMD(mapinfo) {
*------------------------------------------*/
ACMD(mount_peco)
{
- nullpo_retr(-1, sd);
-
if (sd->disguise != -1) {
clif->message(fd, msg_txt(212)); // Cannot mount while in disguise.
return false;
@@ -4040,7 +3944,6 @@ ACMD(mount_peco)
ACMD(guildspy) {
char guild_name[NAME_LENGTH];
struct guild *g;
- nullpo_retr(-1, sd);
memset(guild_name, '\0', sizeof(guild_name));
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -4080,7 +3983,6 @@ ACMD(guildspy) {
ACMD(partyspy) {
char party_name[NAME_LENGTH];
struct party_data *p;
- nullpo_retr(-1, sd);
memset(party_name, '\0', sizeof(party_name));
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -4121,7 +4023,6 @@ ACMD(partyspy) {
ACMD(repairall)
{
int count, i;
- nullpo_retr(-1, sd);
count = 0;
for (i = 0; i < MAX_INVENTORY; i++) {
@@ -4149,7 +4050,6 @@ ACMD(repairall)
*------------------------------------------*/
ACMD(nuke) {
struct map_session_data *pl_sd;
- nullpo_retr(-1, sd);
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
@@ -4180,9 +4080,7 @@ ACMD(nuke) {
ACMD(tonpc) {
char npcname[NAME_LENGTH+1];
struct npc_data *nd;
-
- nullpo_retr(-1, sd);
-
+
memset(npcname, 0, sizeof(npcname));
if (!message || !*message || sscanf(message, "%23[^\n]", npcname) < 1) {
@@ -4209,7 +4107,6 @@ ACMD(tonpc) {
ACMD(shownpc)
{
char NPCname[NAME_LENGTH+1];
- nullpo_retr(-1, sd);
memset(NPCname, '\0', sizeof(NPCname));
@@ -4235,7 +4132,6 @@ ACMD(shownpc)
ACMD(hidenpc)
{
char NPCname[NAME_LENGTH+1];
- nullpo_retr(-1, sd);
memset(NPCname, '\0', sizeof(NPCname));
@@ -4284,7 +4180,6 @@ ACMD(unloadnpc)
{
struct npc_data *nd;
char NPCname[NAME_LENGTH+1];
- nullpo_retr(-1, sd);
memset(NPCname, '\0', sizeof(NPCname));
@@ -4354,7 +4249,6 @@ ACMD(servertime) {
time_t time_server; // variable for number of seconds (used with time() function)
struct tm *datetime; // variable for time in structure ->tm_mday, ->tm_sec, ...
char temp[CHAT_SIZE_MAX];
- nullpo_retr(-1, sd);
memset(temp, '\0', sizeof(temp));
@@ -4372,7 +4266,8 @@ ACMD(servertime) {
} else if (battle_config.night_duration == 0) {
if (map->night_flag == 1) { // we start with night
timer_data = timer->get(pc->day_timer_tid);
- sprintf(temp, msg_txt(233), txt_time(DIFF_TICK(timer_data->tick,timer->gettick())/1000)); // Game time: The game is actualy in night for %s.
+ sprintf(temp, msg_txt(233), // Game time: The game is actually in night for %s.
+ txt_time((unsigned int)(DIFF_TICK(timer_data->tick,timer->gettick())/1000)));
clif->message(fd, temp);
clif->message(fd, msg_txt(234)); // Game time: After, the game will be in permanent daylight.
} else
@@ -4380,7 +4275,8 @@ ACMD(servertime) {
} else if (battle_config.day_duration == 0) {
if (map->night_flag == 0) { // we start with day
timer_data = timer->get(pc->night_timer_tid);
- sprintf(temp, msg_txt(235), txt_time(DIFF_TICK(timer_data->tick,timer->gettick())/1000)); // Game time: The game is actualy in daylight for %s.
+ sprintf(temp, msg_txt(235), // Game time: The game is actualy in daylight for %s.
+ txt_time((unsigned int)(DIFF_TICK(timer_data->tick,timer->gettick())/1000)));
clif->message(fd, temp);
clif->message(fd, msg_txt(236)); // Game time: After, the game will be in permanent night.
} else
@@ -4389,22 +4285,28 @@ ACMD(servertime) {
if (map->night_flag == 0) {
timer_data = timer->get(pc->night_timer_tid);
timer_data2 = timer->get(pc->day_timer_tid);
- sprintf(temp, msg_txt(235), txt_time(DIFF_TICK(timer_data->tick,timer->gettick())/1000)); // Game time: The game is actualy in daylight for %s.
+ sprintf(temp, msg_txt(235), // Game time: The game is actualy in daylight for %s.
+ txt_time((unsigned int)(DIFF_TICK(timer_data->tick,timer->gettick())/1000)));
clif->message(fd, temp);
if (DIFF_TICK(timer_data->tick, timer_data2->tick) > 0)
- sprintf(temp, msg_txt(237), txt_time(DIFF_TICK(timer_data->interval,DIFF_TICK(timer_data->tick,timer_data2->tick)) / 1000)); // Game time: After, the game will be in night for %s.
+ sprintf(temp, msg_txt(237), // Game time: After, the game will be in night for %s.
+ txt_time((unsigned int)(DIFF_TICK(timer_data->interval,DIFF_TICK(timer_data->tick,timer_data2->tick)) / 1000)));
else
- sprintf(temp, msg_txt(237), txt_time(DIFF_TICK(timer_data2->tick,timer_data->tick)/1000)); // Game time: After, the game will be in night for %s.
+ sprintf(temp, msg_txt(237), // Game time: After, the game will be in night for %s.
+ txt_time((unsigned int)(DIFF_TICK(timer_data2->tick,timer_data->tick)/1000)));
clif->message(fd, temp);
} else {
timer_data = timer->get(pc->day_timer_tid);
timer_data2 = timer->get(pc->night_timer_tid);
- sprintf(temp, msg_txt(233), txt_time(DIFF_TICK(timer_data->tick,timer->gettick()) / 1000)); // Game time: The game is actualy in night for %s.
+ sprintf(temp, msg_txt(233), // Game time: The game is actualy in night for %s.
+ txt_time((unsigned int)(DIFF_TICK(timer_data->tick,timer->gettick()) / 1000)));
clif->message(fd, temp);
if (DIFF_TICK(timer_data->tick,timer_data2->tick) > 0)
- sprintf(temp, msg_txt(239), txt_time((timer_data->interval - DIFF_TICK(timer_data->tick, timer_data2->tick)) / 1000)); // Game time: After, the game will be in daylight for %s.
+ sprintf(temp, msg_txt(239), // Game time: After, the game will be in daylight for %s.
+ txt_time((unsigned int)((timer_data->interval - DIFF_TICK(timer_data->tick, timer_data2->tick)) / 1000)));
else
- sprintf(temp, msg_txt(239), txt_time(DIFF_TICK(timer_data2->tick, timer_data->tick) / 1000)); // Game time: After, the game will be in daylight for %s.
+ sprintf(temp, msg_txt(239), // Game time: After, the game will be in daylight for %s.
+ txt_time((unsigned int)(DIFF_TICK(timer_data2->tick, timer_data->tick) / 1000)));
clif->message(fd, temp);
}
sprintf(temp, msg_txt(238), txt_time(timer_data->interval / 1000)); // Game time: A day cycle has a normal duration of %s.
@@ -4450,7 +4352,6 @@ ACMD(jail) {
struct map_session_data *pl_sd;
int x, y;
unsigned short m_index;
- nullpo_retr(-1, sd);
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
@@ -4540,7 +4441,6 @@ ACMD(jailfor) {
char * modif_p;
int jailtime = 0,x,y;
short m_index = 0;
- nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%255s %23[^\n]",atcmd_output,atcmd_player_name) < 2) {
clif->message(fd, msg_txt(400)); //Usage: @jailfor <time> <character name>
@@ -4650,8 +4550,6 @@ ACMD(jailtime)
{
int year, month, day, hour, minute;
- nullpo_retr(-1, sd);
-
if (!sd->sc.data[SC_JAILED]) {
clif->message(fd, msg_txt(1139)); // You are not in jail.
return false;
@@ -4682,7 +4580,6 @@ ACMD(jailtime)
ACMD(disguise)
{
int id = 0;
- nullpo_retr(-1, sd);
if (!message || !*message) {
clif->message(fd, msg_txt(1143)); // Please enter a Monster/NPC name/ID (usage: @disguise <name/ID>).
@@ -4734,7 +4631,6 @@ ACMD(disguiseall)
int mob_id=0;
struct map_session_data *pl_sd;
struct s_mapiterator* iter;
- nullpo_retr(-1, sd);
if (!message || !*message) {
clif->message(fd, msg_txt(1145)); // Please enter a Monster/NPC name/ID (usage: @disguiseall <name/ID>).
@@ -4811,7 +4707,6 @@ ACMD(disguiseguild)
*------------------------------------------*/
ACMD(undisguise)
{
- nullpo_retr(-1, sd);
if (sd->disguise != -1) {
pc->disguise(sd, -1);
clif->message(fd, msg_txt(124)); // Undisguise applied.
@@ -4829,7 +4724,6 @@ ACMD(undisguise)
ACMD(undisguiseall) {
struct map_session_data *pl_sd;
struct s_mapiterator* iter;
- nullpo_retr(-1, sd);
iter = mapit_getallusers();
for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) )
@@ -4851,7 +4745,6 @@ ACMD(undisguiseguild)
struct map_session_data *pl_sd;
struct guild *g;
int i;
- nullpo_retr(-1, sd);
memset(guild_name, '\0', sizeof(guild_name));
@@ -4881,7 +4774,7 @@ ACMD(exp)
{
char output[CHAT_SIZE_MAX];
double nextb, nextj;
- nullpo_retr(-1, sd);
+
memset(output, '\0', sizeof(output));
nextb = pc->nextbaseexp(sd);
@@ -4903,7 +4796,6 @@ ACMD(exp)
*------------------------------------------*/
ACMD(broadcast)
{
- nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -4923,8 +4815,6 @@ ACMD(broadcast)
*------------------------------------------*/
ACMD(localbroadcast)
{
- nullpo_retr(-1, sd);
-
memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!message || !*message) {
@@ -4946,7 +4836,6 @@ ACMD(email)
{
char actual_email[100];
char new_email[100];
- nullpo_retr(-1, sd);
memset(actual_email, '\0', sizeof(actual_email));
memset(new_email, '\0', sizeof(new_email));
@@ -4981,7 +4870,6 @@ ACMD(email)
ACMD(effect)
{
int type = 0, flag = 0;
- nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d", &type) < 1) {
clif->message(fd, msg_txt(1152)); // Please enter an effect number (usage: @effect <effect number>).
@@ -4999,7 +4887,6 @@ ACMD(effect)
*------------------------------------------*/
ACMD(killer)
{
- nullpo_retr(-1, sd);
sd->state.killer = !sd->state.killer;
if(sd->state.killer)
@@ -5016,7 +4903,6 @@ ACMD(killer)
* enable other people killing you
*------------------------------------------*/
ACMD(killable) {
- nullpo_retr(-1, sd);
sd->state.killable = !sd->state.killable;
if(sd->state.killable)
@@ -5033,7 +4919,6 @@ ACMD(killable) {
* turn skills on for the map
*------------------------------------------*/
ACMD(skillon) {
- nullpo_retr(-1, sd);
map->list[sd->bl.m].flag.noskill = 0;
clif->message(fd, msg_txt(244));
return true;
@@ -5044,7 +4929,6 @@ ACMD(skillon) {
* Turn skills off on the map
*------------------------------------------*/
ACMD(skilloff) {
- nullpo_retr(-1, sd);
map->list[sd->bl.m].flag.noskill = 1;
clif->message(fd, msg_txt(243));
return true;
@@ -5057,7 +4941,7 @@ ACMD(skilloff) {
ACMD(npcmove) {
int x = 0, y = 0, m;
struct npc_data *nd = 0;
- nullpo_retr(-1, sd);
+
memset(atcmd_player_name, '\0', sizeof atcmd_player_name);
if (!message || !*message || sscanf(message, "%d %d %23[^\n]", &x, &y, atcmd_player_name) < 3) {
@@ -5096,7 +4980,6 @@ ACMD(addwarp)
unsigned short m;
struct npc_data* nd;
- nullpo_retr(-1, sd);
memset(warpname, '\0', sizeof(warpname));
if (!message || !*message || sscanf(message, "%31s %d %d %23[^\n]", mapname, &x, &y, warpname) < 4) {
@@ -5127,7 +5010,6 @@ ACMD(addwarp)
*------------------------------------------*/
ACMD(follow) {
struct map_session_data *pl_sd = NULL;
- nullpo_retr(-1, sd);
if (!message || !*message) {
if (sd->followtarget == -1)
@@ -5163,7 +5045,7 @@ ACMD(follow) {
ACMD(dropall)
{
int i;
- nullpo_retr(-1, sd);
+
for (i = 0; i < MAX_INVENTORY; i++) {
if (sd->status.inventory[i].amount) {
if(sd->status.inventory[i].equip != 0)
@@ -5181,7 +5063,6 @@ ACMD(dropall)
ACMD(storeall)
{
int i;
- nullpo_retr(-1, sd);
if (sd->state.storage_flag != 1)
{ //Open storage.
@@ -5207,7 +5088,6 @@ ACMD(storeall)
ACMD(clearstorage)
{
int i, j;
- nullpo_retr(-1, sd);
if (sd->state.storage_flag == 1) {
clif->message(fd, msg_txt(250));
@@ -5229,7 +5109,6 @@ ACMD(cleargstorage)
int i, j;
struct guild *g;
struct guild_storage *guild_storage;
- nullpo_retr(-1, sd);
g = sd->guild;
@@ -5268,7 +5147,6 @@ ACMD(cleargstorage)
ACMD(clearcart)
{
int i;
- nullpo_retr(-1, sd);
if (pc_iscarton(sd) == 0) {
clif->message(fd, msg_txt(1396)); // You do not have a cart to be cleaned.
@@ -5302,9 +5180,7 @@ ACMD(skillid) {
DBKey key;
DBData *data;
char partials[MAX_SKILLID_PARTIAL_RESULTS][MAX_SKILLID_PARTIAL_RESULTS_LEN];
-
- nullpo_retr(-1, sd);
-
+
if (!message || !*message) {
clif->message(fd, msg_txt(1163)); // Please enter a skill name to look up (usage: @skillid <skill name>).
return false;
@@ -5348,7 +5224,6 @@ ACMD(useskill) {
uint16 skill_id;
uint16 skill_lv;
char target[100];
- nullpo_retr(-1, sd);
if(!message || !*message || sscanf(message, "%hu %hu %23[^\n]", &skill_id, &skill_lv, target) != 3) {
clif->message(fd, msg_txt(1165)); // Usage: @useskill <skill ID> <skill level> <target>
@@ -5389,10 +5264,9 @@ ACMD(useskill) {
*------------------------------------------*/
ACMD(displayskill) {
struct status_data *st;
- unsigned int tick;
+ int64 tick;
uint16 skill_id;
uint16 skill_lv = 1;
- nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%hu %hu", &skill_id, &skill_lv) < 1) {
clif->message(fd, msg_txt(1166)); // Usage: @displayskill <skill ID> {<skill level>}
@@ -5416,7 +5290,6 @@ ACMD(skilltree) {
int meets, j, c=0;
char target[NAME_LENGTH];
struct skill_tree_entry *ent;
- nullpo_retr(-1, sd);
if(!message || !*message || sscanf(message, "%hu %23[^\r\n]", &skill_id, target) != 2) {
clif->message(fd, msg_txt(1167)); // Usage: @skilltree <skill ID> <target>
@@ -5486,9 +5359,7 @@ void getring(struct map_session_data* sd) {
ACMD(marry) {
struct map_session_data *pl_sd = NULL;
char player_name[NAME_LENGTH] = "";
-
- nullpo_retr(-1, sd);
-
+
if (!message || !*message || sscanf(message, "%23s", player_name) != 1) {
clif->message(fd, msg_txt(1172)); // Usage: @marry <char name>
return false;
@@ -5517,8 +5388,6 @@ ACMD(marry) {
*------------------------------------------*/
ACMD(divorce)
{
- nullpo_retr(-1, sd);
-
if (pc->divorce(sd) != 0) {
sprintf(atcmd_output, msg_txt(1175), sd->status.name); // '%s' is not married.
clif->message(fd, atcmd_output);
@@ -5561,7 +5430,6 @@ ACMD(changelook)
* Turns on/off Autotrade for a specific player
*------------------------------------------*/
ACMD(autotrade) {
- nullpo_retr(-1, sd);
if( map->list[sd->bl.m].flag.autotrade != battle_config.autotrade_mapflag ) {
clif->message(fd, msg_txt(1179)); // Autotrade is not allowed on this map.
@@ -5598,7 +5466,6 @@ ACMD(autotrade) {
ACMD(changegm) {
struct guild *g;
struct map_session_data *pl_sd;
- nullpo_retr(-1, sd);
if (sd->status.guild_id == 0 || (g = sd->guild) == NULL || strcmp(g->master,sd->status.name)) {
clif->message(fd, msg_txt(1181)); // You need to be a Guild Master to use this command.
@@ -5629,7 +5496,6 @@ ACMD(changegm) {
* Changes the leader of a party.
*------------------------------------------*/
ACMD(changeleader) {
- nullpo_retr(-1, sd);
if( !message[0] ) {
clif->message(fd, msg_txt(1185)); // Usage: @changeleader <party_member_name>
@@ -5650,7 +5516,6 @@ ACMD(partyoption)
struct party_data *p;
int mi, option;
char w1[16], w2[16];
- nullpo_retr(-1, sd);
if (sd->status.party_id == 0 || (p = party->search(sd->status.party_id)) == NULL)
{
@@ -5692,7 +5557,7 @@ ACMD(partyoption)
ACMD(autoloot)
{
int rate;
- nullpo_retr(-1, sd);
+
// autoloot command without value
if(!message || !*message)
{
@@ -5819,25 +5684,25 @@ ACMD(autolootitem)
* Credits:
* chriser,Aleos
*------------------------------------------*/
-ACMD(autoloottype){
+ACMD(autoloottype) {
int i;
uint8 action = 3; // 1=add, 2=remove, 3=help+list (default), 4=reset
enum item_types type = -1;
int ITEM_NONE = 0;
-
+
if (message && *message) {
if (message[0] == '+') {
message++;
action = 1;
- }
- else if (message[0] == '-') {
+ } else if (message[0] == '-') {
message++;
action = 2;
- }
- else if (!strcmp(message,"reset"))
+ } else if (strcmp(message,"reset") == 0) {
action = 4;
+ }
- if (action < 3) { // add or remove
+ if (action < 3) {
+ // add or remove
if (strncmp(message, "healing", 3) == 0)
type = IT_HEALING;
else if (strncmp(message, "usable", 3) == 0)
@@ -5883,16 +5748,21 @@ ACMD(autoloottype){
clif->message(fd, atcmd_output);
break;
case 3:
- clif->message(fd, msg_txt(1495)); // To add an item type to the list, use "@aloottype +<type name>". To remove an item type, use "@aloottype -<type name>".
- clif->message(fd, msg_txt(1496)); // Type List: healing, usable, etc, weapon, armor, card, petegg, petarmor, ammo
- clif->message(fd, msg_txt(1497)); // "@aloottype reset" will clear your autoloottype list.
- if (sd->state.autoloottype == ITEM_NONE)
- clif->message(fd, msg_txt(1498)); // Your autoloottype list is empty.
- else {
- clif->message(fd, msg_txt(1499)); // Item types on your autoloottype list:
- for(i=0; i < IT_MAX; i++){
+ clif->message(fd, msg_txt(38)); // Invalid location number, or name.
+
+ {
+ // attempt to find the text help string
+ const char *text = atcommand_help_string(info);
+ if (text) clif->messageln(fd, text); // send the text to the client
+ }
+
+ if (sd->state.autoloottype == ITEM_NONE) {
+ clif->message(fd, msg_txt(1495)); // Your autoloottype list is empty.
+ } else {
+ clif->message(fd, msg_txt(1496)); // Item types on your autoloottype list:
+ for(i=0; i < IT_MAX; i++) {
if (sd->state.autoloottype&(1<<i)) {
- sprintf(atcmd_output, " '%s'", itemdb->typename(i));
+ sprintf(atcmd_output, " '%s'", itemdb->typename(i));
clif->message(fd, atcmd_output);
}
}
@@ -5900,37 +5770,17 @@ ACMD(autoloottype){
break;
case 4:
sd->state.autoloottype = ITEM_NONE;
- clif->message(fd, msg_txt(1500)); // Your autoloottype list has been reset.
+ clif->message(fd, msg_txt(1497)); // Your autoloottype list has been reset.
break;
}
- return 0;
+ return true;
}
-/**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
-/*==========================================
- * It is made to rain.
- *------------------------------------------*/
-//ACMD(rain) {
-// nullpo_retr(-1, sd);
-// if (map->list[sd->bl.m].flag.rain) {
-// map->list[sd->bl.m].flag.rain=0;
-// clif->weather(sd->bl.m);
-// clif->message(fd, msg_txt(1201)); // The rain has stopped.
-// } else {
-// map->list[sd->bl.m].flag.rain=1;
-// clif->weather(sd->bl.m);
-// clif->message(fd, msg_txt(1202)); // It has started to rain.
-// }
-// return true;
-//}
-
/*==========================================
* It is made to snow.
*------------------------------------------*/
ACMD(snow) {
- nullpo_retr(-1, sd);
+
if (map->list[sd->bl.m].flag.snow) {
map->list[sd->bl.m].flag.snow=0;
clif->weather(sd->bl.m);
@@ -5948,7 +5798,7 @@ ACMD(snow) {
* Cherry tree snowstorm is made to fall. (Sakura)
*------------------------------------------*/
ACMD(sakura) {
- nullpo_retr(-1, sd);
+
if (map->list[sd->bl.m].flag.sakura) {
map->list[sd->bl.m].flag.sakura=0;
clif->weather(sd->bl.m);
@@ -5965,7 +5815,7 @@ ACMD(sakura) {
* Clouds appear.
*------------------------------------------*/
ACMD(clouds) {
- nullpo_retr(-1, sd);
+
if (map->list[sd->bl.m].flag.clouds) {
map->list[sd->bl.m].flag.clouds=0;
clif->weather(sd->bl.m);
@@ -5983,7 +5833,7 @@ ACMD(clouds) {
* Different type of clouds using effect 516
*------------------------------------------*/
ACMD(clouds2) {
- nullpo_retr(-1, sd);
+
if (map->list[sd->bl.m].flag.clouds2) {
map->list[sd->bl.m].flag.clouds2=0;
clif->weather(sd->bl.m);
@@ -6001,7 +5851,7 @@ ACMD(clouds2) {
* Fog hangs over.
*------------------------------------------*/
ACMD(fog) {
- nullpo_retr(-1, sd);
+
if (map->list[sd->bl.m].flag.fog) {
map->list[sd->bl.m].flag.fog=0;
clif->weather(sd->bl.m);
@@ -6018,7 +5868,7 @@ ACMD(fog) {
* Fallen leaves fall.
*------------------------------------------*/
ACMD(leaves) {
- nullpo_retr(-1, sd);
+
if (map->list[sd->bl.m].flag.leaves) {
map->list[sd->bl.m].flag.leaves=0;
clif->weather(sd->bl.m);
@@ -6036,7 +5886,7 @@ ACMD(leaves) {
* Fireworks appear.
*------------------------------------------*/
ACMD(fireworks) {
- nullpo_retr(-1, sd);
+
if (map->list[sd->bl.m].flag.fireworks) {
map->list[sd->bl.m].flag.fireworks=0;
clif->weather(sd->bl.m);
@@ -6054,11 +5904,7 @@ ACMD(fireworks) {
* Clearing Weather Effects by Dexity
*------------------------------------------*/
ACMD(clearweather) {
- nullpo_retr(-1, sd);
- /**
- * No longer available, keeping here just in case it's back someday. [Ind]
- **/
- //map->list[sd->bl.m].flag.rain=0;
+
map->list[sd->bl.m].flag.snow=0;
map->list[sd->bl.m].flag.sakura=0;
map->list[sd->bl.m].flag.clouds=0;
@@ -6103,9 +5949,7 @@ ACMD(mobsearch)
int mob_id;
int number = 0;
struct s_mapiterator* it;
-
- nullpo_retr(-1, sd);
-
+
if (!message || !*message || sscanf(message, "%99[^\n]", mob_name) < 1) {
clif->message(fd, msg_txt(1218)); // Please enter a monster name (usage: @mobsearch <monster name>).
return false;
@@ -6228,9 +6072,7 @@ ACMD(pettalk)
{
char mes[100],temp[100];
struct pet_data *pd;
-
- nullpo_retr(-1, sd);
-
+
if ( battle_config.min_chat_delay ) {
if( DIFF_TICK(sd->cantalk_tick, timer->gettick()) > 0 )
return true;
@@ -6355,9 +6197,7 @@ ACMD(summon)
int mob_id = 0;
int duration = 0;
struct mob_data *md;
- unsigned int tick=timer->gettick();
-
- nullpo_retr(-1, sd);
+ int64 tick=timer->gettick();
if (!message || !*message || sscanf(message, "%23s %d", name, &duration) < 1)
{
@@ -6403,7 +6243,6 @@ ACMD(summon)
ACMD(adjgroup)
{
int new_group = 0;
- nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d", &new_group) != 1) {
clif->message(fd, msg_txt(1226)); // Usage: @adjgroup <group_id>
@@ -6426,7 +6265,6 @@ ACMD(adjgroup)
*------------------------------------------*/
ACMD(trade) {
struct map_session_data *pl_sd = NULL;
- nullpo_retr(-1, sd);
if (!message || !*message) {
clif->message(fd, msg_txt(1230)); // Please enter a player name (usage: @trade <char name>).
@@ -6449,7 +6287,6 @@ ACMD(trade) {
ACMD(setbattleflag)
{
char flag[128], value[128];
- nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%127s %127s", flag, value) != 2) {
clif->message(fd, msg_txt(1231)); // Usage: @setbattleflag <flag> <value>
@@ -6471,7 +6308,6 @@ ACMD(setbattleflag)
*------------------------------------------*/
ACMD(unmute) {
struct map_session_data *pl_sd = NULL;
- nullpo_retr(-1, sd);
if (!message || !*message) {
clif->message(fd, msg_txt(1234)); // Please enter a player name (usage: @unmute <char name>).
@@ -6503,7 +6339,6 @@ ACMD(uptime)
{
unsigned long seconds = 0, day = 24*60*60, hour = 60*60,
minute = 60, days = 0, hours = 0, minutes = 0;
- nullpo_retr(-1, sd);
seconds = timer->get_uptime();
days = seconds/day;
@@ -6526,7 +6361,7 @@ ACMD(uptime)
ACMD(changesex)
{
int i;
- nullpo_retr(-1, sd);
+
pc->resetskill(sd,4);
// to avoid any problem with equipment and invalid sex, equipment is unequiped.
for( i=0; i<EQI_MAX; i++ )
@@ -6541,7 +6376,6 @@ ACMD(changesex)
ACMD(mute) {
struct map_session_data *pl_sd = NULL;
int manner;
- nullpo_retr(-1, sd);
if (!message || !*message || sscanf(message, "%d %23[^\n]", &manner, atcmd_player_name) < 1) {
clif->message(fd, msg_txt(1237)); // Usage: @mute <time> <char name>
@@ -6580,7 +6414,6 @@ ACMD(mute) {
*------------------------------------------*/
ACMD(refresh)
{
- nullpo_retr(-1, sd);
clif->refresh(sd);
return true;
}
@@ -6589,7 +6422,6 @@ ACMD(refreshall)
{
struct map_session_data* iter_sd;
struct s_mapiterator* iter;
- nullpo_retr(-1, sd);
iter = mapit_getallusers();
for (iter_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); iter_sd = (TBL_PC*)mapit->next(iter))
@@ -6605,9 +6437,7 @@ ACMD(refreshall)
ACMD(identify)
{
int i,num;
-
- nullpo_retr(-1, sd);
-
+
for(i=num=0;i<MAX_INVENTORY;i++){
if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].identify!=1){
num++;
@@ -6623,7 +6453,7 @@ ACMD(identify)
ACMD(misceffect) {
int effect = 0;
- nullpo_retr(-1, sd);
+
if (!message || !*message)
return false;
if (sscanf(message, "%d", &effect) < 1)
@@ -6638,7 +6468,6 @@ ACMD(misceffect) {
*------------------------------------------*/
ACMD(mail)
{
- nullpo_ret(sd);
mail->openmail(sd);
return true;
}
@@ -6796,9 +6625,7 @@ ACMD(showmobs)
int mob_id;
int number = 0;
struct s_mapiterator* it;
-
- nullpo_retr(-1, sd);
-
+
if(sscanf(message, "%99[^\n]", mob_name) < 0)
return false;
@@ -6854,8 +6681,6 @@ ACMD(homlevel) {
TBL_HOM * hd;
int level = 0;
enum homun_type htype;
-
- nullpo_retr(-1, sd);
if( !message || !*message || ( level = atoi(message) ) < 1 ) {
clif->message(fd, msg_txt(1253)); // Please enter a level adjustment (usage: @homlevel <number of levels>).
@@ -6911,8 +6736,6 @@ ACMD(homlevel) {
*------------------------------------------*/
ACMD(homevolution)
{
- nullpo_retr(-1, sd);
-
if ( !homun_alive(sd->hd) ) {
clif->message(fd, msg_txt(1254)); // You do not have a homunculus.
return false;
@@ -6929,7 +6752,6 @@ ACMD(homevolution)
ACMD(hommutate) {
int homun_id;
enum homun_type m_class, m_id;
- nullpo_retr(-1, sd);
if( !homun_alive(sd->hd) ) {
clif->message(fd, msg_txt(1254)); // You do not have a homunculus.
@@ -6958,7 +6780,6 @@ ACMD(hommutate) {
*------------------------------------------*/
ACMD(makehomun) {
int homunid;
- nullpo_retr(-1, sd);
if (!message || !*message) {
clif->message(fd, msg_txt(1256)); // Please enter a homunculus ID (usage: @makehomun <homunculus id>).
@@ -6996,9 +6817,7 @@ ACMD(makehomun) {
ACMD(homfriendly)
{
int friendly = 0;
-
- nullpo_retr(-1, sd);
-
+
if ( !homun_alive(sd->hd) ) {
clif->message(fd, msg_txt(1254)); // You do not have a homunculus.
return false;
@@ -7023,9 +6842,7 @@ ACMD(homfriendly)
ACMD(homhungry)
{
int hungry = 0;
-
- nullpo_retr(-1, sd);
-
+
if ( !homun_alive(sd->hd) ) {
clif->message(fd, msg_txt(1254)); // You do not have a homunculus.
return false;
@@ -7050,9 +6867,7 @@ ACMD(homhungry)
ACMD(homtalk)
{
char mes[100],temp[100];
-
- nullpo_retr(-1, sd);
-
+
if ( battle_config.min_chat_delay ) {
if( DIFF_TICK(sd->cantalk_tick, timer->gettick()) > 0 )
return true;
@@ -7086,7 +6901,6 @@ ACMD(homtalk)
ACMD(hominfo) {
struct homun_data *hd;
struct status_data *st;
- nullpo_retr(-1, sd);
if ( !homun_alive(sd->hd) ) {
clif->message(fd, msg_txt(1254)); // You do not have a homunculus.
@@ -7124,9 +6938,7 @@ ACMD(homstats)
struct s_homunculus_db *db;
struct s_homunculus *hom;
int lv, min, max, evo;
-
- nullpo_retr(-1, sd);
-
+
if ( !homun_alive(sd->hd) ) {
clif->message(fd, msg_txt(1254)); // You do not have a homunculus.
return false;
@@ -7188,7 +7000,6 @@ ACMD(homstats)
}
ACMD(homshuffle) {
- nullpo_retr(-1, sd);
if(!sd->hd)
return false; // nothing to do
@@ -7389,7 +7200,6 @@ int atcommand_mutearea_sub(struct block_list *bl,va_list ap)
ACMD(mutearea) {
int time;
- nullpo_ret(sd);
if (!message || !*message) {
clif->message(fd, msg_txt(1297)); // Please enter a time in minutes (usage: @mutearea/@stfu <time in minutes>).
@@ -7410,7 +7220,6 @@ ACMD(rates)
{
char buf[CHAT_SIZE_MAX];
- nullpo_ret(sd);
memset(buf, '\0', sizeof(buf));
snprintf(buf, CHAT_SIZE_MAX, msg_txt(1298), // Experience rates: Base %.2fx / Job %.2fx
@@ -7436,7 +7245,6 @@ ACMD(rates)
ACMD(me)
{
char tempmes[CHAT_SIZE_MAX];
- nullpo_retr(-1, sd);
memset(tempmes, '\0', sizeof(tempmes));
memset(atcmd_output, '\0', sizeof(atcmd_output));
@@ -7465,7 +7273,6 @@ ACMD(me)
ACMD(size)
{
int size = 0;
- nullpo_retr(-1, sd);
size = cap_value(atoi(message),SZ_SMALL,SZ_BIG);
@@ -7520,7 +7327,6 @@ ACMD(sizeguild)
char guild_name[NAME_LENGTH];
struct map_session_data *pl_sd;
struct guild *g;
- nullpo_retr(-1, sd);
memset(guild_name, '\0', sizeof(guild_name));
@@ -7559,9 +7365,7 @@ ACMD(sizeguild)
* @monsterignore
* => Makes monsters ignore you. [Valaris]
*------------------------------------------*/
-ACMD(monsterignore)
-{
- nullpo_retr(-1, sd);
+ACMD(monsterignore) {
if (!sd->state.monster_ignore) {
sd->state.monster_ignore = 1;
@@ -7577,9 +7381,7 @@ ACMD(monsterignore)
* @fakename
* => Gives your character a fake name. [Valaris]
*------------------------------------------*/
-ACMD(fakename)
-{
- nullpo_retr(-1, sd);
+ACMD(fakename){
if( !message || !*message )
{
@@ -7624,7 +7426,7 @@ ACMD(mapflag) {
char flag_name[100];
short flag=0,i;
- nullpo_retr(-1, sd);
+
memset(flag_name, '\0', sizeof(flag_name));
if (!message || !*message || (sscanf(message, "%99s %hd", flag_name, &flag) < 1)) {
@@ -7642,7 +7444,7 @@ ACMD(mapflag) {
CHECKFLAG(nojobexp); CHECKFLAG(nomobloot); CHECKFLAG(nomvploot); CHECKFLAG(nightenabled);
CHECKFLAG(nodrop); CHECKFLAG(novending); CHECKFLAG(loadevent);
CHECKFLAG(nochat); CHECKFLAG(partylock); CHECKFLAG(guildlock); CHECKFLAG(src4instance);
- CHECKFLAG(notomb);
+ CHECKFLAG(notomb); CHECKFLAG(nocashshop);
clif->message(sd->fd," ");
clif->message(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
clif->message(sd->fd,msg_txt(1313)); // Type "@mapflag available" to list the available mapflags.
@@ -7679,7 +7481,7 @@ ACMD(mapflag) {
SETFLAG(nojobexp); SETFLAG(nomobloot); SETFLAG(nomvploot); SETFLAG(nightenabled);
SETFLAG(nodrop); SETFLAG(novending); SETFLAG(loadevent);
SETFLAG(nochat); SETFLAG(partylock); SETFLAG(guildlock); SETFLAG(src4instance);
- SETFLAG(notomb);
+ SETFLAG(notomb); SETFLAG(nocashshop);
clif->message(sd->fd,msg_txt(1314)); // Invalid flag name or flag.
clif->message(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
@@ -7691,7 +7493,7 @@ ACMD(mapflag) {
clif->message(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
clif->message(sd->fd,"fog, fireworks, sakura, leaves, nobaseexp, nojobexp, nomobloot,");
clif->message(sd->fd,"nomvploot, nightenabled, nodrop, novending, loadevent, nochat, partylock,");
- clif->message(sd->fd,"guildlock, src4instance, notomb");
+ clif->message(sd->fd,"guildlock, src4instance, notomb, nocashshop");
#undef CHECKFLAG
#undef SETFLAG
@@ -7909,43 +7711,45 @@ ACMD(cash)
char output[128];
int value;
int ret=0;
- nullpo_retr(-1, sd);
if( !message || !*message || (value = atoi(message)) == 0 ) {
clif->message(fd, msg_txt(1322)); // Please enter an amount.
return false;
}
- if( !strcmpi(command+1,"cash") )
- {
+ if( !strcmpi(command+1,"cash") ) {
if( value > 0 ) {
if( (ret=pc->getcash(sd, value, 0)) >= 0){
- sprintf(output, msg_txt(505), ret, sd->cashPoints);
- clif->disp_onlyself(sd, output, strlen(output));
- }
- else clif->message(fd, msg_txt(149)); // Unable to decrease the number/value.
+ // If this option is set, the message is already sent by pc function
+ if( !battle_config.cashshop_show_points ){
+ sprintf(output, msg_txt(505), ret, sd->cashPoints);
+ clif->disp_onlyself(sd, output, strlen(output));
+ }
+ } else
+ clif->message(fd, msg_txt(149)); // Unable to decrease the number/value.
} else {
if( (ret=pc->paycash(sd, -value, 0)) >= 0){
sprintf(output, msg_txt(410), ret, sd->cashPoints);
clif->disp_onlyself(sd, output, strlen(output));
- }
- else clif->message(fd, msg_txt(41)); // Unable to decrease the number/value.
+ } else
+ clif->message(fd, msg_txt(41)); // Unable to decrease the number/value.
}
- }
- else
- { // @points
+ } else { // @points
if( value > 0 ) {
- if( (ret=pc->getcash(sd, 0, value)) >= 0){
- sprintf(output, msg_txt(506), ret, sd->kafraPoints);
- clif->disp_onlyself(sd, output, strlen(output));
- }
- else clif->message(fd, msg_txt(149)); // Unable to decrease the number/value.
+ if( (ret=pc->getcash(sd, 0, value)) >= 0) {
+ // If this option is set, the message is already sent by pc function
+ if( !battle_config.cashshop_show_points ){
+ sprintf(output, msg_txt(506), ret, sd->kafraPoints);
+ clif->disp_onlyself(sd, output, strlen(output));
+ }
+ } else
+ clif->message(fd, msg_txt(149)); // Unable to decrease the number/value.
} else {
if( (ret=pc->paycash(sd, -value, -value)) >= 0){
sprintf(output, msg_txt(411), ret, sd->kafraPoints);
clif->disp_onlyself(sd, output, strlen(output));
- }
- else clif->message(fd, msg_txt(41)); // Unable to decrease the number/value.
+ } else
+ clif->message(fd, msg_txt(41)); // Unable to decrease the number/value.
}
}
@@ -8056,7 +7860,6 @@ ACMD(feelreset)
* AUCTION SYSTEM
*------------------------------------------*/
ACMD(auction) {
- nullpo_ret(sd);
if( !battle_config.feature_auction ) {
clif->colormes(sd->fd,COLOR_RED,msg_txt(1484));
@@ -8073,8 +7876,6 @@ ACMD(auction) {
*------------------------------------------*/
ACMD(ksprotection)
{
- nullpo_retr(-1,sd);
-
if( sd->state.noks ) {
sd->state.noks = 0;
clif->message(fd, msg_txt(1325)); // [ K.S Protection Inactive ]
@@ -8105,7 +7906,6 @@ ACMD(ksprotection)
* Map Kill Steal Protection Setting
*------------------------------------------*/
ACMD(allowks) {
- nullpo_retr(-1,sd);
if( map->list[sd->bl.m].flag.allowks ) {
map->list[sd->bl.m].flag.allowks = 0;
@@ -8117,9 +7917,7 @@ ACMD(allowks) {
return true;
}
-ACMD(resetstat)
-{
- nullpo_retr(-1, sd);
+ACMD(resetstat) {
pc->resetstate(sd);
sprintf(atcmd_output, msg_txt(207), sd->status.name);
@@ -8127,9 +7925,7 @@ ACMD(resetstat)
return true;
}
-ACMD(resetskill)
-{
- nullpo_retr(-1,sd);
+ACMD(resetskill) {
pc->resetskill(sd,1);
sprintf(atcmd_output, msg_txt(206), sd->status.name);
@@ -8149,9 +7945,7 @@ ACMD(itemlist)
const struct item* items;
int size;
StringBuf buf;
-
- nullpo_retr(-1, sd);
-
+
if( strcmp(command+1, "storagelist") == 0 ) {
location = "storage";
items = sd->status.storage.items;
@@ -8351,14 +8145,11 @@ ACMD(stats)
return true;
}
-ACMD(delitem)
-{
+ACMD(delitem) {
char item_name[100];
int nameid, amount = 0, total, idx;
struct item_data* id;
-
- nullpo_retr(-1, sd);
-
+
if( !message || !*message || ( sscanf(message, "\"%99[^\"]\" %d", item_name, &amount) < 2 && sscanf(message, "%99s %d", item_name, &amount) < 2 ) || amount < 1 )
{
clif->message(fd, msg_txt(1355)); // Please enter an item name/ID, a quantity, and a player name (usage: #delitem <player> <item_name_or_ID> <quantity>).
@@ -8417,17 +8208,15 @@ ACMD(delitem)
/*==========================================
* Custom Fonts
*------------------------------------------*/
-ACMD(font)
-{
+ACMD(font) {
int font_id;
- nullpo_retr(-1,sd);
font_id = atoi(message);
if( font_id == 0 )
{
- if( sd->user_font )
+ if( sd->status.font )
{
- sd->user_font = 0;
+ sd->status.font = 0;
clif->message(fd, msg_txt(1356)); // Returning to normal font.
clif->font(sd);
}
@@ -8439,9 +8228,9 @@ ACMD(font)
}
else if( font_id < 0 || font_id > 9 )
clif->message(fd, msg_txt(1359)); // Invalid font. Use a value from 0 to 9.
- else if( font_id != sd->user_font )
+ else if( font_id != sd->status.font )
{
- sd->user_font = font_id;
+ sd->status.font = font_id;
clif->font(sd);
clif->message(fd, msg_txt(1360)); // Font changed.
}
@@ -9772,24 +9561,39 @@ void atcommand_basecommands(void) {
ACMD_DEF(costume),
ACMD_DEF(skdebug),
};
- AtCommandInfo* cmd;
int i;
for( i = 0; i < ARRAYLENGTH(atcommand_base); i++ ) {
- if(atcommand->exists(atcommand_base[i].command)) { // Should not happen if atcommand_base[] array is OK
+ if(!atcommand->add(atcommand_base[i].command,atcommand_base[i].func)) { // Should not happen if atcommand_base[] array is OK
ShowDebug("atcommand_basecommands: duplicate ACMD_DEF for '%s'.\n", atcommand_base[i].command);
continue;
}
- CREATE(cmd, AtCommandInfo, 1);
- safestrncpy(cmd->command, atcommand_base[i].command, sizeof(cmd->command));
- cmd->func = atcommand_base[i].func;
- cmd->help = NULL;/* start as null dear */
- cmd->log = true;
- strdb_put(atcommand->db, cmd->command, cmd);
}
+
+ /* @commands from plugins */
+ HPM_map_atcommands();
+
return;
}
+bool atcommand_add(char *name,AtCommandFunc func) {
+ AtCommandInfo* cmd;
+
+ if(atcommand->exists(name)) //caller will handle/display on false
+ return false;
+
+ CREATE(cmd, AtCommandInfo, 1);
+
+ safestrncpy(cmd->command, name, sizeof(cmd->command));
+ cmd->func = func;
+ cmd->help = NULL;
+ cmd->log = true;
+
+ strdb_put(atcommand->db, cmd->command, cmd);
+
+ return true;
+}
+
/*==========================================
* Command lookup functions
*------------------------------------------*/
@@ -9975,6 +9779,9 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message
sprintf(atcmd_msg, "%s", message);
}
+ if( battle_config.idletime_criteria & BCIDLE_ATCOMMAND )
+ sd->idletime = last_tick;
+
//Clearing these to be used once more.
memset(command, '\0', sizeof(command));
memset(params, '\0', sizeof(params));
@@ -10298,30 +10105,14 @@ bool atcommand_can_use2(struct map_session_data *sd, const char *command, AtComm
return false;
}
bool atcommand_hp_add(char *name, AtCommandFunc func) {
- AtCommandInfo* cmd;
-
+ /* if commands are added after group permissions are thrown in, they end up with no permissions */
+ /* so we restrict commands to be linked in during boot */
if( runflag == MAPSERVER_ST_RUNNING ) {
ShowDebug("atcommand_hp_add: Commands can't be added after server is ready, skipping '%s'...\n",name);
return false;
}
- if( atcommand->db == NULL )
- atcommand->db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH);
-
- if( atcommand->exists(name) ) {
- ShowDebug("atcommand_hp_add: duplicate command '%s', skipping...\n", name);
- return false;
- }
-
- CREATE(cmd, AtCommandInfo, 1);
-
- safestrncpy(cmd->command, name, sizeof(cmd->command));
- cmd->func = func;
- cmd->help = NULL;/* start as null dear */
- cmd->log = true;
-
- strdb_put(atcommand->db, cmd->command, cmd);
- return true;
+ return HPM_map_add_atcommand(name,func);
}
/**
@@ -10407,4 +10198,5 @@ void atcommand_defaults(void) {
atcommand->cmd_db_clear_sub = atcommand_db_clear_sub;
atcommand->doload = atcommand_doload;
atcommand->base_commands = atcommand_basecommands;
+ atcommand->add = atcommand_add;
}
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index 603abc0cc..63c38e4d1 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -110,6 +110,7 @@ struct atcommand_interface {
int (*cmd_db_clear_sub) (DBKey key, DBData *data, va_list args);
void (*doload) (void);
void (*base_commands) (void);
+ bool (*add) (char *name, AtCommandFunc func);
};
struct atcommand_interface *atcommand;
diff --git a/src/map/battle.c b/src/map/battle.c
index fb950860e..94222f663 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -196,7 +196,7 @@ struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int
return bl_list[rnd()%c];
}
-int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) {
+int battle_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) {
struct delay_damage *dat = (struct delay_damage *)data;
if ( dat ) {
@@ -244,7 +244,7 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) {
return 0;
}
-int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects) {
+int battle_delay_damage(int64 tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects) {
struct delay_damage *dat;
struct status_change *sc;
nullpo_ret(src);
@@ -349,7 +349,7 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
y = sg->val3 & 0xffff;
skill->unitsetting(src,su->group->skill_id,su->group->skill_lv,x,y,1);
sg->val3 = -1;
- sg->limit = DIFF_TICK(timer->gettick(),sg->tick)+300;
+ sg->limit = DIFF_TICK32(timer->gettick(),sg->tick)+300;
}
}
}
@@ -2938,27 +2938,6 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
status->change_spread(bl, src); // Deadly infect attacked side
-
- if( sc && sc->data[SC__SHADOWFORM] ) {
- struct block_list *s_bl = map->id2bl(sc->data[SC__SHADOWFORM]->val2);
- if( !s_bl || s_bl->m != bl->m ) { // If the shadow form target is not present remove the sc.
- status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- } else if( status->isdead(s_bl) || !battle->check_target(src,s_bl,BCT_ENEMY)) { // If the shadow form target is dead or not your enemy remove the sc in both.
- status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- if( s_bl->type == BL_PC )
- ((TBL_PC*)s_bl)->shadowform_id = 0;
- } else {
- if( (--sc->data[SC__SHADOWFORM]->val3) < 0 ) { // If you have exceded max hits supported, remove the sc in both.
- status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- if( s_bl->type == BL_PC )
- ((TBL_PC*)s_bl)->shadowform_id = 0;
- } else {
- status->damage(bl, s_bl, damage, 0, clif->damage(s_bl, s_bl, timer->gettick(), 500, 500, damage, -1, 0, 0), 0);
- return ATK_NONE;
- }
- }
- }
-
}
//SC effects from caster side.
@@ -5290,14 +5269,14 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int64 rdamage, int64 ldama
status_zap(tbl, rhp, rsp);
}
// Deals the same damage to targets in area. [pakpil]
-int battle_damage_area( struct block_list *bl, va_list ap) {
- unsigned int tick;
+int battle_damage_area(struct block_list *bl, va_list ap) {
+ int64 tick;
int amotion, dmotion, damage;
struct block_list *src;
nullpo_ret(bl);
- tick=va_arg(ap, unsigned int);
+ tick = va_arg(ap, int64);
src=va_arg(ap,struct block_list *);
amotion=va_arg(ap,int);
dmotion=va_arg(ap,int);
@@ -5323,7 +5302,7 @@ int battle_damage_area( struct block_list *bl, va_list ap) {
/*==========================================
* Do a basic physical attack (call trough unit_attack_timer)
*------------------------------------------*/
-enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, unsigned int tick, int flag) {
+enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, int64 tick, int flag) {
struct map_session_data *sd = NULL, *tsd = NULL;
struct status_data *sstatus, *tstatus;
struct status_change *sc, *tsc;
@@ -5533,7 +5512,13 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
map->freeblock_lock();
- battle->delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion, true);
+ if( skill->check_shadowform(target, damage, wd.div_) ){
+ if( !status->isdead(target) )
+ skill->additional_effect(src, target, 0, 0, wd.flag, wd.dmg_lv, tick);
+ if( wd.dmg_lv > ATK_BLOCK)
+ skill->counter_additional_effect(src, target, 0, 0, wd.flag,tick);
+ }else
+ battle->delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion, true);
if( tsc ) {
if( tsc->data[SC_DEVOTION] ) {
struct status_change_entry *sce = tsc->data[SC_DEVOTION];
@@ -6485,6 +6470,7 @@ static const struct _battle_data {
{ "guild_notice_changemap", &battle_config.guild_notice_changemap, 2, 0, 2, },
{ "feature.banking", &battle_config.feature_banking, 1, 0, 1, },
{ "feature.auction", &battle_config.feature_auction, 0, 0, 2, },
+ { "idletime_criteria", &battle_config.idletime_criteria, 0x25, 1, INT_MAX, },
{ "mon_trans_disable_in_gvg", &battle_config.mon_trans_disable_in_gvg, 0, 0, 1, },
};
@@ -6631,7 +6617,7 @@ void Hercules_report(char* date, char *time_c) {
#undef BFLAG_LENGTH
}
-static int Hercules_report_timer(int tid, unsigned int tick, int id, intptr_t data) {
+static int Hercules_report_timer(int tid, int64 tick, int id, intptr_t data) {
if( chrif->isconnected() ) {/* char server relays it, so it must be online. */
Hercules_report(__DATE__,__TIME__);
}
@@ -6775,7 +6761,7 @@ int battle_config_read(const char* cfgName)
void do_init_battle(void) {
battle->delay_damage_ers = ers_new(sizeof(struct delay_damage),"battle.c::delay_damage_ers",ERS_OPT_CLEAR);
- timer->add_func_list(battle_delay_damage_sub, "battle_delay_damage_sub");
+ timer->add_func_list(battle->delay_damage_sub, "battle_delay_damage_sub");
#ifndef STATS_OPT_OUT
timer->add_func_list(Hercules_report_timer, "Hercules_report_timer");
diff --git a/src/map/battle.h b/src/map/battle.h
index 1aa07b2be..bf08ab8d6 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -454,7 +454,7 @@ struct Battle_Config {
int max_walk_path;
int item_enabled_npc;
int packet_obfuscation;
-
+ int idletime_criteria;
int gm_ignore_warpable_area;
int client_accept_chatdori; // [Ai4rei/Mirei]
@@ -467,6 +467,20 @@ struct Battle_Config {
int mon_trans_disable_in_gvg;
} battle_config;
+/* criteria for battle_config.idletime_critera */
+enum e_battle_config_idletime {
+ BCIDLE_WALK = 0x001,
+ BCIDLE_USESKILLTOID = 0x002,
+ BCIDLE_USESKILLTOPOS = 0x004,
+ BCIDLE_USEITEM = 0x008,
+ BCIDLE_ATTACK = 0x010,
+ BCIDLE_CHAT = 0x020,
+ BCIDLE_SIT = 0x040,
+ BCIDLE_EMOTION = 0x080,
+ BCIDLE_DROPITEM = 0x100,
+ BCIDLE_ATCOMMAND = 0x200,
+};
+
// Dammage delayed info
struct delay_damage {
int src_id;
@@ -504,11 +518,11 @@ struct battle_interface {
/* battlegrounds final damage calculation */
int64 (*calc_bg_damage) (struct block_list *src, struct block_list *bl, int64 damage, int div_, uint16 skill_id, uint16 skill_lv, int flag);
/* normal weapon attack */
- enum damage_lv (*weapon_attack) (struct block_list *bl, struct block_list *target, unsigned int tick, int flag);
+ enum damage_lv (*weapon_attack) (struct block_list *bl, struct block_list *target, int64 tick, int flag);
/* calculate weapon attack */
struct Damage (*calc_weapon_attack) (struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int wflag);
/* delays damage or skills by a timer */
- int (*delay_damage) (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects);
+ int (*delay_damage) (int64 tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects);
/* drain damage */
void (*drain) (struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int boss);
/* damage return/reflect */
@@ -552,7 +566,7 @@ struct battle_interface {
int (*get_targeted_sub) (struct block_list *bl, va_list ap);
int (*get_enemy_sub) (struct block_list *bl, va_list ap);
int (*get_enemy_area_sub) (struct block_list *bl, va_list ap);
- int (*delay_damage_sub) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*delay_damage_sub) (int tid, int64 tick, int id, intptr_t data);
int (*blewcount_bonus) (struct map_session_data *sd, uint16 skill_id);
/* skill range criteria */
int (*range_type) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv);
@@ -573,7 +587,7 @@ struct battle_interface {
/* picks a random enemy within the specified range */
struct block_list* (*get_enemy_area) (struct block_list *src, int x, int y, int range, int type, int ignore_id);
/* damages area, originally for royal guard's reflect damage */
- int (*damage_area) ( struct block_list *bl, va_list ap);
+ int (*damage_area) (struct block_list *bl, va_list ap);
};
struct battle_interface *battle;
diff --git a/src/map/battleground.c b/src/map/battleground.c
index e7fe4085b..62688659e 100644
--- a/src/map/battleground.c
+++ b/src/map/battleground.c
@@ -249,7 +249,7 @@ int bg_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) {
return 0;
}
-int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int bg_send_xy_timer(int tid, int64 tick, int id, intptr_t data) {
bg->team_db->foreach(bg->team_db, bg->send_xy_timer_sub, tick);
return 0;
}
@@ -534,7 +534,7 @@ void bg_begin(struct bg_arena *arena) {
/* currently running only on solo mode so we do it evenly */
}
}
-int bg_begin_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int bg_begin_timer(int tid, int64 tick, int id, intptr_t data) {
bg->begin(bg->arena[id]);
bg->arena[id]->begin_timer = INVALID_TIMER;
return 0;
@@ -553,7 +553,7 @@ void bg_queue_pregame(struct bg_arena *arena) {
}
arena->begin_timer = timer->add( timer->gettick() + (arena->pregame_duration*1000), bg->begin_timer, arena->id, 0 );
}
-int bg_fillup_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int bg_fillup_timer(int tid, int64 tick, int id, intptr_t data) {
bg->queue_pregame(bg->arena[id]);
bg->arena[id]->fillup_timer = INVALID_TIMER;
return 0;
diff --git a/src/map/battleground.h b/src/map/battleground.h
index 1c224e1c2..a5e540924 100644
--- a/src/map/battleground.h
+++ b/src/map/battleground.h
@@ -84,9 +84,9 @@ struct battleground_interface {
int (*id2pos) (int queue_id, int account_id);
void (*queue_pc_cleanup) (struct map_session_data *sd);
void (*begin) (struct bg_arena *arena);
- int (*begin_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*begin_timer) (int tid, int64 tick, int id, intptr_t data);
void (*queue_pregame) (struct bg_arena *arena);
- int (*fillup_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*fillup_timer) (int tid, int64 tick, int id, intptr_t data);
void (*queue_ready_ack) (struct bg_arena *arena, struct map_session_data *sd, bool response);
void (*match_over) (struct bg_arena *arena, bool canceled);
void (*queue_check) (struct bg_arena *arena);
@@ -102,7 +102,7 @@ struct battleground_interface {
int (*team_get_id) (struct block_list *bl);
int (*send_message) (struct map_session_data *sd, const char *mes, int len);
int (*send_xy_timer_sub) (DBKey key, DBData *data, va_list ap);
- int (*send_xy_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*send_xy_timer) (int tid, int64 tick, int id, intptr_t data);
/* */
void (*config_read) (void);
};
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 5308eada9..a13217060 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -682,7 +682,7 @@ int auth_db_cleanup_sub(DBKey key, DBData *data, va_list ap) {
return 0;
}
-int auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data) {
+int auth_db_cleanup(int tid, int64 tick, int id, intptr_t data) {
chrif_check(0);
chrif->auth_db->foreach(chrif->auth_db, chrif->auth_db_cleanup_sub);
return 0;
@@ -1139,7 +1139,7 @@ int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the
#ifdef ENABLE_SC_SAVING
int i, count=0;
- unsigned int tick;
+ int64 tick;
struct status_change_data data;
struct status_change *sc = &sd->sc;
const struct TimerData *td;
@@ -1159,7 +1159,7 @@ int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the
td = timer->get(sc->data[i]->timer);
if (td == NULL || td->func != status->change_timer || DIFF_TICK(td->tick,tick) < 0)
continue;
- data.tick = DIFF_TICK(td->tick,tick); //Duration that is left before ending.
+ data.tick = DIFF_TICK32(td->tick,tick); //Duration that is left before ending.
} else
data.tick = -1; //Infinite duration
data.type = i;
@@ -1212,6 +1212,8 @@ int chrif_load_scdata(int fd) {
data = (struct status_change_data*)RFIFOP(fd,14 + i*sizeof(struct status_change_data));
status->change_start(&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15);
}
+
+ pc->scdata_received(sd);
#endif
return 0;
@@ -1462,7 +1464,7 @@ int chrif_parse(int fd) {
return 0;
}
-int send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data) {
+int send_usercount_tochar(int tid, int64 tick, int id, intptr_t data) {
chrif_check(-1);
WFIFOHEAD(chrif->fd,4);
@@ -1509,7 +1511,7 @@ int send_users_tochar(void) {
* timerFunction
* Chk the connection to char server, (if it down)
*------------------------------------------*/
-int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data) {
+int check_connect_char_server(int tid, int64 tick, int id, intptr_t data) {
static int displayed = 0;
if ( chrif->fd <= 0 || session[chrif->fd] == NULL ) {
if ( !displayed ) {
diff --git a/src/map/chrif.h b/src/map/chrif.h
index 0617a6702..9df4b9931 100644
--- a/src/map/chrif.h
+++ b/src/map/chrif.h
@@ -30,11 +30,11 @@ enum sd_state { ST_LOGIN, ST_LOGOUT, ST_MAPCHANGE };
struct auth_node {
int account_id, char_id;
int login_id1, login_id2, sex, fd;
- time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
- struct map_session_data *sd; //Data from logged on char.
- struct mmo_charstatus *char_dat; //Data from char server.
- unsigned int node_created; //timestamp for node timeouts
- enum sd_state state; //To track whether player was login in/out or changing maps.
+ time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
+ struct map_session_data *sd; //Data from logged on char.
+ struct mmo_charstatus *char_dat; //Data from char server.
+ int64 node_created; //timestamp for node timeouts
+ enum sd_state state; //To track whether player was login in/out or changing maps.
};
/*=====================================
@@ -109,15 +109,15 @@ struct chrif_interface {
void (*skillid2idx) (int fd);
bool (*sd_to_auth) (TBL_PC* sd, enum sd_state state);
- int (*check_connect_char_server) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*check_connect_char_server) (int tid, int64 tick, int id, intptr_t data);
bool (*auth_logout) (TBL_PC* sd, enum sd_state state);
void (*save_ack) (int fd);
int (*reconnect) (DBKey key, DBData *data, va_list ap);
int (*auth_db_cleanup_sub) (DBKey key, DBData *data, va_list ap);
void (*char_ask_name_answer) (int acc, const char* player_name, uint16 type, uint16 answer);
int (*auth_db_final) (DBKey key, DBData *data, va_list ap);
- int (*send_usercount_tochar) (int tid, unsigned int tick, int id, intptr_t data);
- int (*auth_db_cleanup) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*send_usercount_tochar) (int tid, int64 tick, int id, intptr_t data);
+ int (*auth_db_cleanup) (int tid, int64 tick, int id, intptr_t data);
int (*connect) (int fd);
int (*connectack) (int fd);
diff --git a/src/map/clif.c b/src/map/clif.c
index 060509807..c1e7cb1c9 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -56,6 +56,13 @@
struct clif_interface clif_s;
+/* re-usable */
+static struct packet_itemlist_normal itemlist_normal;
+static struct packet_itemlist_equip itemlist_equip;
+static struct packet_storelist_normal storelist_normal;
+static struct packet_storelist_equip storelist_equip;
+static struct packet_viewequip_ack viewequip_list;
+
//#define DUMP_UNKNOWN_PACKET
//#define DUMP_INVALID_PACKET
@@ -282,7 +289,7 @@ int clif_send_sub(struct block_list *bl, va_list ap) {
len = va_arg(ap,int);
nullpo_ret(src_bl = va_arg(ap,struct block_list*));
type = va_arg(ap,int);
-
+
switch(type) {
case AREA_WOS:
if (bl == src_bl)
@@ -314,6 +321,10 @@ int clif_send_sub(struct block_list *bl, va_list ap) {
#endif
}
+ /* unless visible, hold it here */
+ if( clif->ally_only && !sd->special_state.intravision && battle->check_target( src_bl, &sd->bl, BCT_ENEMY ) > 0 )
+ return 0;
+
WFIFOHEAD(fd, len);
if (WFIFOP(fd,0) == buf) {
ShowError("WARNING: Invalid use of clif->send function\n");
@@ -595,12 +606,12 @@ void clif_authok(struct map_session_data *sd)
struct packet_authok p;
p.PacketType = authokType;
- p.startTime = timer->gettick();
+ p.startTime = (unsigned int)timer->gettick();
WBUFPOS(&p.PosDir[0],0,sd->bl.x,sd->bl.y,sd->ud.dir); /* do the stupid client math */
p.xSize = p.ySize = 5; /* not-used */
#if PACKETVER >= 20080102
- p.font = sd->user_font; // FIXME: Font is currently not saved.
+ p.font = sd->status.font;
#endif
clif->send(&p,sizeof(p),&sd->bl,SELF);
@@ -707,7 +718,7 @@ void clif_dropflooritem(struct flooritem_data* fitem) {
#if PACKETVER >= 20130000 /* not sure date */
p.type = itemtype(itemdb_type(fitem->item_data.nameid));
#endif
- p.IsIdentified = fitem->item_data.identify;
+ p.IsIdentified = fitem->item_data.identify ? 1 : 0;
p.xPos = fitem->bl.x;
p.yPos = fitem->bl.y;
p.subX = fitem->subx;
@@ -787,14 +798,13 @@ void clif_clearunit_area(struct block_list* bl, clr_type type)
/// Used to make monsters with player-sprites disappear after dying
/// like normal monsters, because the client does not remove those
/// automatically.
-int clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr_t data) {
+int clif_clearunit_delayed_sub(int tid, int64 tick, int id, intptr_t data) {
struct block_list *bl = (struct block_list *)data;
clif->clearunit_area(bl, (clr_type) id);
ers_free(clif->delay_clearunit_ers,bl);
return 0;
}
-void clif_clearunit_delayed(struct block_list* bl, clr_type type, unsigned int tick)
-{
+void clif_clearunit_delayed(struct block_list* bl, clr_type type, int64 tick) {
struct block_list *tbl = ers_alloc(clif->delay_clearunit_ers, struct block_list);
memcpy (tbl, bl, sizeof (struct block_list));
timer->add(tick, clif->clearunit_delayed_sub, (int)type, (intptr_t)tbl);
@@ -900,7 +910,7 @@ void clif_set_unit_idle2(struct block_list* bl, struct map_session_data *tsd, en
p.GEmblemVer = status->get_emblem_id(bl);
p.honor = (sd) ? sd->status.manner : 0;
p.virtue = (sc) ? sc->opt3 : 0;
- p.isPKModeON = (sd) ? sd->status.karma : 0;
+ p.isPKModeON = (sd && sd->status.karma) ? 1 : 0;
p.sex = vd->sex;
WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl));
p.xSize = p.ySize = (sd) ? 5 : 0;
@@ -965,14 +975,14 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
p.GEmblemVer = status->get_emblem_id(bl);
p.honor = (sd) ? sd->status.manner : 0;
p.virtue = (sc) ? sc->opt3 : 0;
- p.isPKModeON = (sd) ? sd->status.karma : 0;
+ p.isPKModeON = (sd && sd->status.karma) ? 1 : 0;
p.sex = vd->sex;
WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl));
p.xSize = p.ySize = (sd) ? 5 : 0;
p.state = vd->dead_sit;
p.clevel = clif_setlevel(bl);
#if PACKETVER >= 20080102
- p.font = (sd) ? sd->user_font : 0;
+ p.font = (sd) ? sd->status.font : 0;
#endif
#if PACKETVER >= 20140000 //actual 20120221
if( bl->type == BL_MOB ) {
@@ -1034,7 +1044,7 @@ void clif_spawn_unit2(struct block_list* bl, enum send_target target) {
p.headpalette = vd->hair_color;
p.bodypalette = vd->cloth_color;
p.headDir = (sd)? sd->head_dir : 0;
- p.isPKModeON = (sd) ? sd->status.karma : 0;
+ p.isPKModeON = (sd && sd->status.karma) ? 1 : 0;
p.sex = vd->sex;
WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl));
p.xSize = p.ySize = (sd) ? 5 : 0;
@@ -1094,13 +1104,13 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
p.GEmblemVer = status->get_emblem_id(bl);
p.honor = (sd) ? sd->status.manner : 0;
p.virtue = (sc) ? sc->opt3 : 0;
- p.isPKModeON = (sd) ? sd->status.karma : 0;
+ p.isPKModeON = (sd && sd->status.karma) ? 1 : 0;
p.sex = vd->sex;
WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl));
p.xSize = p.ySize = (sd) ? 5 : 0;
p.clevel = clif_setlevel(bl);
#if PACKETVER >= 20080102
- p.font = (sd) ? sd->user_font : 0;
+ p.font = (sd) ? sd->status.font : 0;
#endif
#if PACKETVER >= 20140000 //actual 20120221
if( bl->type == BL_MOB ) {
@@ -1156,7 +1166,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
p.head = vd->hair_style;
p.weapon = vd->weapon;
p.accessory = vd->head_bottom;
- p.moveStartTime = timer->gettick();
+ p.moveStartTime = (unsigned int)timer->gettick();
#if PACKETVER < 7
p.shield = vd->shield;
#endif
@@ -1172,13 +1182,13 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
p.GEmblemVer = status->get_emblem_id(bl);
p.honor = (sd) ? sd->status.manner : 0;
p.virtue = (sc) ? sc->opt3 : 0;
- p.isPKModeON = (sd) ? sd->status.karma : 0;
+ p.isPKModeON = (sd && sd->status.karma) ? 1 : 0;
p.sex = vd->sex;
WBUFPOS2(&p.MoveData[0],0,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
p.xSize = p.ySize = (sd) ? 5 : 0;
p.clevel = clif_setlevel(bl);
#if PACKETVER >= 20080102
- p.font = (sd) ? sd->user_font : 0;
+ p.font = (sd) ? sd->status.font : 0;
#endif
#if PACKETVER >= 20140000 //actual 20120221
if( bl->type == BL_MOB ) {
@@ -1526,13 +1536,17 @@ void clif_walkok(struct map_session_data *sd)
WFIFOHEAD(fd, packet_len(0x87));
WFIFOW(fd,0)=0x87;
- WFIFOL(fd,2)=timer->gettick();
+ WFIFOL(fd,2)=(unsigned int)timer->gettick();
WFIFOPOS2(fd,6,sd->bl.x,sd->bl.y,sd->ud.to_x,sd->ud.to_y,8,8);
WFIFOSET(fd,packet_len(0x87));
}
void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_data *ud) {
+ struct status_change *sc = NULL;
+
+ if( (sc = status->get_sc(bl)) && sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE|OPTION_CHASEWALK) )
+ clif->ally_only = true;
clif->set_unit_walking(bl,NULL,ud,AREA_WOS);
@@ -1564,6 +1578,8 @@ void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_data *u
clif->send_petdata(NULL, (TBL_PET*)bl, 3, vd->head_bottom);
break;
}
+
+ clif->ally_only = false;
}
@@ -1573,9 +1589,9 @@ void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_data *u
void clif_move(struct unit_data *ud)
{
unsigned char buf[16];
- struct view_data* vd;
- struct block_list* bl = ud->bl;
-
+ struct view_data *vd;
+ struct block_list *bl = ud->bl;
+ struct status_change *sc = NULL;
vd = status->get_viewdata(bl);
if (!vd || vd->class_ == INVISIBLE_CLASS)
return; //This performance check is needed to keep GM-hidden objects from being notified to bots.
@@ -1593,23 +1609,28 @@ void clif_move(struct unit_data *ud)
clif->move2(bl, vd, ud);
return;
}
+
+ if( (sc = status->get_sc(bl)) && sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE|OPTION_CHASEWALK) )
+ clif->ally_only = true;
WBUFW(buf,0)=0x86;
WBUFL(buf,2)=bl->id;
WBUFPOS2(buf,6,bl->x,bl->y,ud->to_x,ud->to_y,8,8);
- WBUFL(buf,12)=timer->gettick();
+ WBUFL(buf,12)=(unsigned int)timer->gettick();
clif->send(buf, packet_len(0x86), bl, AREA_WOS);
if (disguised(bl)) {
WBUFL(buf,2)=-bl->id;
clif->send(buf, packet_len(0x86), bl, SELF);
}
+
+ clif->ally_only = false;
}
/*==========================================
* Delays the map->quit of a player after they are disconnected. [Skotlex]
*------------------------------------------*/
-int clif_delayquit(int tid, unsigned int tick, int id, intptr_t data) {
+int clif_delayquit(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd = NULL;
//Remove player from map server
@@ -1680,11 +1701,11 @@ void clif_blown(struct block_list *bl)
/// isn't walkable, the char doesn't move at all. If the char is
/// sitting it will stand up (ZC_STOPMOVE).
/// 0088 <id>.L <x>.W <y>.W
-void clif_fixpos(struct block_list *bl)
-{
+void clif_fixpos(struct block_list *bl) {
unsigned char buf[10];
+
nullpo_retv(bl);
-
+
WBUFW(buf,0) = 0x88;
WBUFL(buf,2) = bl->id;
WBUFW(buf,6) = bl->x;
@@ -2198,8 +2219,8 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
else
p.nameid = sd->status.inventory[n].nameid;
- p.IsIdentified = sd->status.inventory[n].identify;
- p.IsDamaged = sd->status.inventory[n].attribute;
+ p.IsIdentified = sd->status.inventory[n].identify ? 1 : 0;
+ p.IsDamaged = sd->status.inventory[n].attribute ? 1 : 0;
p.refiningLevel =sd->status.inventory[n].refine;
clif->addcards2(&p.slot.card[0], &sd->status.inventory[n]);
p.location = pc->equippoint(sd,n);
@@ -2290,311 +2311,229 @@ void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data *
}
}
-//Unified inventory function which sends all of the inventory (requires two packets, one for equipable items and one for stackable ones. [Skotlex]
-void clif_inventorylist(struct map_session_data *sd) {
- int i,n,ne,arrow=-1;
- unsigned char *buf;
- unsigned char *bufe;
+void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *i, struct item_data *id, int eqp_pos) {
-#if PACKETVER < 5
- const int s = 10; //Entry size.
-#elif PACKETVER < 20080102
- const int s = 18;
-#else
- const int s = 22;
-#endif
-#if PACKETVER < 20071002
- const int se = 20;
-#elif PACKETVER < 20100629
- const int se = 26;
-#else
- const int se = 28;
-#endif
+ p->index = idx;
+
+ if (id->view_id > 0)
+ p->ITID = id->view_id;
+ else
+ p->ITID = i->nameid;
- buf = (unsigned char*)aMalloc(MAX_INVENTORY * s + 4);
- bufe = (unsigned char*)aMalloc(MAX_INVENTORY * se + 4);
+ p->type = itemtype(id->type);
- for( i = 0, n = 0, ne = 0; i < MAX_INVENTORY; i++ )
- {
- if( sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL )
- continue;
+#if PACKETVER < 20120925
+ p->IsIdentified = i->identify ? 1 : 0;
+#endif
+
+ p->location = eqp_pos;
+ p->WearState = i->equip;
+
+#if PACKETVER < 20120925
+ p->IsDamaged = i->attribute ? 1 : 0;
+#endif
+ p->RefiningLevel = i->refine;
+
+ clif->addcards2(&p->slot.card[0], i);
- if( !itemdb->isstackable2(sd->inventory_data[i]) )
- { //Non-stackable (Equippable)
- WBUFW(bufe,ne*se+4)=i+2;
- clif->item_sub(bufe, ne*se+6, &sd->status.inventory[i], sd->inventory_data[i], pc->equippoint(sd,i));
- clif->addcards(WBUFP(bufe, ne*se+16), &sd->status.inventory[i]);
#if PACKETVER >= 20071002
- WBUFL(bufe,ne*se+24)=sd->status.inventory[i].expire_time;
- WBUFW(bufe,ne*se+28)=0; //Unknown
+ p->HireExpireDate = i->expire_time;
#endif
+
+#if PACKETVER >= 20080102
+ p->bindOnEquipType = 0;
+#endif
+
#if PACKETVER >= 20100629
- if (sd->inventory_data[i]->equip&EQP_VISIBLE)
- WBUFW(bufe,ne*se+30)= sd->inventory_data[i]->look;
- else
- WBUFW(bufe,ne*se+30)=0;
+ p->wItemSpriteNumber = id->equip&EQP_VISIBLE ? id->look : 0;
#endif
- ne++;
- }
- else
- { //Stackable.
- WBUFW(buf,n*s+4)=i+2;
- clif->item_sub(buf, n*s+6, &sd->status.inventory[i], sd->inventory_data[i], -2);
- if( sd->inventory_data[i]->equip == EQP_AMMO && sd->status.inventory[i].equip )
- arrow=i;
+
+#if PACKETVER >= 20120925
+ p->Flag.IsIdentified = i->identify ? 1 : 0;
+ p->Flag.IsDamaged = i->attribute ? 1 : 0;
+ p->Flag.PlaceETCTab = i->favorite ? 1 : 0;
+ p->Flag.SpareBits = 0;
+#endif
+}
+void clif_item_normal(short idx, struct NORMALITEM_INFO *p, struct item *i, struct item_data *id) {
+ p->index = idx;
+
+ if (id->view_id > 0)
+ p->ITID = id->view_id;
+ else
+ p->ITID = i->nameid;
+
+ p->type = itemtype(id->type);
+
+#if PACKETVER < 20120925
+ p->IsIdentified = i->identify ? 1 : 0;
+#endif
+
+ p->count = i->amount;
+ p->WearState = id->equip;
+
#if PACKETVER >= 5
- clif->addcards(WBUFP(buf, n*s+14), &sd->status.inventory[i]);
+ clif->addcards2(&p->slot.card[0], i);
#endif
+
#if PACKETVER >= 20080102
- WBUFL(buf,n*s+22)=sd->status.inventory[i].expire_time;
+ p->HireExpireDate = i->expire_time;
#endif
- n++;
- }
- }
- if( n ) {
-#if PACKETVER < 5
- WBUFW(buf,0)=0xa3;
-#elif PACKETVER < 20080102
- WBUFW(buf,0)=0x1ee;
-#else
- WBUFW(buf,0)=0x2e8;
+
+#if PACKETVER >= 20120925
+ p->Flag.IsIdentified = i->identify ? 1 : 0;
+ p->Flag.PlaceETCTab = i->favorite ? 1 : 0;
+ p->Flag.SpareBits = 0;
#endif
- WBUFW(buf,2)=4+n*s;
- clif->send(buf, WBUFW(buf,2), &sd->bl, SELF);
+}
+void clif_inventorylist(struct map_session_data *sd) {
+ int i, normal = 0, equip = 0;
+
+ for( i = 0; i < MAX_INVENTORY; i++ ) {
+
+ if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL )
+ continue;
+ if( !itemdb->isstackable2(sd->inventory_data[i]) ) //Non-stackable (Equippable)
+ clif_item_equip(i+2,&itemlist_equip.list[equip++],&sd->status.inventory[i],sd->inventory_data[i],pc->equippoint(sd,i));
+ else //Stackable (Normal)
+ clif_item_normal(i+2,&itemlist_normal.list[normal++],&sd->status.inventory[i],sd->inventory_data[i]);
+ }
+
+ if( normal ) {
+ itemlist_normal.PacketType = inventorylistnormalType;
+ itemlist_normal.PacketLength = 4 + (sizeof(struct NORMALITEM_INFO) * normal);
+
+ clif->send(&itemlist_normal, itemlist_normal.PacketLength, &sd->bl, SELF);
}
- if( arrow >= 0 )
- clif->arrowequip(sd,arrow);
+
+ if( sd->equip_index[EQI_AMMO] >= 0 )
+ clif->arrowequip(sd,sd->equip_index[EQI_AMMO]);
+
+ if( equip ) {
+ itemlist_equip.PacketType = inventorylistequipType;
+ itemlist_equip.PacketLength = 4 + (sizeof(struct EQUIPITEM_INFO) * equip);
- if( ne ) {
-#if PACKETVER < 20071002
- WBUFW(bufe,0)=0xa4;
-#else
- WBUFW(bufe,0)=0x2d0;
-#endif
- WBUFW(bufe,2)=4+ne*se;
- clif->send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
+ clif->send(&itemlist_equip, itemlist_equip.PacketLength, &sd->bl, SELF);
}
-#if PACKETVER >= 20111122
+/* on 20120925 onwards this is a field on clif_item_equip/normal */
+#if PACKETVER >= 20111122 && PACKETVER < 20120925
for( i = 0; i < MAX_INVENTORY; i++ ) {
if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL )
continue;
-
+
if ( sd->status.inventory[i].favorite )
clif->favorite_item(sd, i);
}
#endif
-
- if( buf ) aFree(buf);
- if( bufe ) aFree(bufe);
}
//Required when items break/get-repaired. Only sends equippable item list.
-void clif_equiplist(struct map_session_data *sd)
-{
- int i,n,fd = sd->fd;
- unsigned char *buf;
-#if PACKETVER < 20071002
- const int cmd = 20;
-#elif PACKETVER < 20100629
- const int cmd = 26;
-#else
- const int cmd = 28;
-#endif
-
- WFIFOHEAD(fd, MAX_INVENTORY * cmd + 4);
- buf = WFIFOP(fd,0);
-
- for(i=0,n=0;i<MAX_INVENTORY;i++){
- if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL)
+void clif_equiplist(struct map_session_data *sd) {
+ int i, equip = 0;
+
+ for( i = 0; i < MAX_INVENTORY; i++ ) {
+
+ if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL )
continue;
-
- if(itemdb->isstackable2(sd->inventory_data[i]))
+ if( !itemdb->isstackable2(sd->inventory_data[i]) ) //Non-stackable (Equippable)
+ clif_item_equip(i+2,&itemlist_equip.list[equip++],&sd->status.inventory[i],sd->inventory_data[i],pc->equippoint(sd,i));
+ }
+
+ if( equip ) {
+ itemlist_equip.PacketType = inventorylistequipType;
+ itemlist_equip.PacketLength = 4 + (sizeof(struct EQUIPITEM_INFO) * equip);
+
+ clif->send(&itemlist_equip, itemlist_equip.PacketLength, &sd->bl, SELF);
+ }
+
+ /* on 20120925 onwards this is a field on clif_item_equip */
+#if PACKETVER >= 20111122 && PACKETVER < 20120925
+ for( i = 0; i < MAX_INVENTORY; i++ ) {
+ if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL )
continue;
- //Equippable
- WBUFW(buf,n*cmd+4)=i+2;
- clif->item_sub(buf, n*cmd+6, &sd->status.inventory[i], sd->inventory_data[i], pc->equippoint(sd,i));
- clif->addcards(WBUFP(buf, n*cmd+16), &sd->status.inventory[i]);
-#if PACKETVER >= 20071002
- WBUFL(buf,n*cmd+24)=sd->status.inventory[i].expire_time;
- WBUFW(buf,n*cmd+28)=0; //Unknown
-#endif
-#if PACKETVER >= 20100629
- if (sd->inventory_data[i]->equip&EQP_VISIBLE)
- WBUFW(buf,n*cmd+30)= sd->inventory_data[i]->look;
- else
- WBUFW(buf,n*cmd+30)=0;
-#endif
- n++;
+
+ if ( sd->status.inventory[i].favorite )
+ clif->favorite_item(sd, i);
}
- if (n) {
-#if PACKETVER < 20071002
- WBUFW(buf,0)=0xa4;
-#else
- WBUFW(buf,0)=0x2d0;
#endif
- WBUFW(buf,2)=4+n*cmd;
- WFIFOSET(fd,WFIFOW(fd,2));
- }
}
-void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length)
-{
+void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length) {
+ int i = 0;
struct item_data *id;
- int i,n,ne;
- unsigned char *buf;
- unsigned char *bufe;
-#if PACKETVER < 5
- const int s = 10; //Entry size.
-#elif PACKETVER < 20080102
- const int s = 18;
-#else
- const int s = 22;
-#endif
-#if PACKETVER < 20071002
- const int cmd = 20;
-#elif PACKETVER < 20100629
- const int cmd = 26;
-#else
- const int cmd = 28;
-#endif
-
- buf = (unsigned char*)aMalloc(items_length * s + 4);
- bufe = (unsigned char*)aMalloc(items_length * cmd + 4);
+
+ do {
+ int normal = 0, equip = 0, k = 0;
- for( i = 0, n = 0, ne = 0; i < items_length; i++ )
- {
- if( items[i].nameid <= 0 )
- continue;
- id = itemdb->search(items[i].nameid);
- if( !itemdb->isstackable2(id) )
- { //Equippable
- WBUFW(bufe,ne*cmd+4)=i+1;
- clif->item_sub(bufe, ne*cmd+6, &items[i], id, id->equip);
- clif->addcards(WBUFP(bufe, ne*cmd+16), &items[i]);
-#if PACKETVER >= 20071002
- WBUFL(bufe,ne*cmd+24)=items[i].expire_time;
- WBUFW(bufe,ne*cmd+28)=0; //Unknown
-#endif
- ne++;
+ for( ; i < items_length && k < 500; i++, k++ ) {
+
+ if( items[i].nameid <= 0 )
+ continue;
+
+ id = itemdb->search(items[i].nameid);
+
+ if( !itemdb->isstackable2(id) ) //Non-stackable (Equippable)
+ clif_item_equip(i+1,&storelist_equip.list[equip++],&items[i],id,id->equip);
+ else //Stackable (Normal)
+ clif_item_normal(i+1,&storelist_normal.list[normal++],&items[i],id);
}
- else
- { //Stackable
- WBUFW(buf,n*s+4)=i+1;
- clif->item_sub(buf, n*s+6, &items[i], id,-1);
-#if PACKETVER >= 5
- clif->addcards(WBUFP(buf,n*s+14), &items[i]);
-#endif
-#if PACKETVER >= 20080102
- WBUFL(buf,n*s+22)=items[i].expire_time;
+
+ if( normal ) {
+ storelist_normal.PacketType = storagelistnormalType;
+ storelist_normal.PacketLength = ( sizeof( storelist_normal ) - sizeof( storelist_normal.list ) ) + (sizeof(struct NORMALITEM_INFO) * normal);
+
+#if PACKETVER >= 20120925
+ safestrncpy(storelist_normal.name, "Storage", NAME_LENGTH);
#endif
- n++;
+
+ clif->send(&storelist_normal, storelist_normal.PacketLength, &sd->bl, SELF);
}
- }
- if( n )
- {
-#if PACKETVER < 5
- WBUFW(buf,0)=0xa5;
-#elif PACKETVER < 20080102
- WBUFW(buf,0)=0x1f0;
-#else
- WBUFW(buf,0)=0x2ea;
-#endif
- WBUFW(buf,2)=4+n*s;
- clif->send(buf, WBUFW(buf,2), &sd->bl, SELF);
- }
- if( ne )
- {
-#if PACKETVER < 20071002
- WBUFW(bufe,0)=0xa6;
-#else
- WBUFW(bufe,0)=0x2d1;
+
+ if( equip ) {
+ storelist_equip.PacketType = storagelistequipType;
+ storelist_equip.PacketLength = ( sizeof( storelist_equip ) - sizeof( storelist_equip.list ) ) + (sizeof(struct EQUIPITEM_INFO) * equip);
+
+#if PACKETVER >= 20120925
+ safestrncpy(storelist_equip.name, "Storage", NAME_LENGTH);
#endif
- WBUFW(bufe,2)=4+ne*cmd;
- clif->send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
- }
- if( buf ) aFree(buf);
- if( bufe ) aFree(bufe);
+ clif->send(&storelist_equip, storelist_equip.PacketLength, &sd->bl, SELF);
+ }
+
+ } while ( i < items_length );
+
}
-void clif_cartlist(struct map_session_data *sd)
-{
+void clif_cartlist(struct map_session_data *sd) {
+ int i, normal = 0, equip = 0;
struct item_data *id;
- int i,n,ne;
- unsigned char *buf;
- unsigned char *bufe;
-#if PACKETVER < 5
- const int s = 10; //Entry size.
-#elif PACKETVER < 20080102
- const int s = 18;
-#else
- const int s = 22;
-#endif
-#if PACKETVER < 20071002
- const int cmd = 20;
-#elif PACKETVER < 20100629
- const int cmd = 26;
-#else
- const int cmd = 28;
-#endif
-
- buf = (unsigned char*)aMalloc(MAX_CART * s + 4);
- bufe = (unsigned char*)aMalloc(MAX_CART * cmd + 4);
-
- for( i = 0, n = 0, ne = 0; i < MAX_CART; i++ )
- {
+
+ for( i = 0; i < MAX_CART; i++ ) {
+
if( sd->status.cart[i].nameid <= 0 )
continue;
+
id = itemdb->search(sd->status.cart[i].nameid);
- if( !itemdb->isstackable2(id) )
- { //Equippable
- WBUFW(bufe,ne*cmd+4)=i+2;
- clif->item_sub(bufe, ne*cmd+6, &sd->status.cart[i], id, id->equip);
- clif->addcards(WBUFP(bufe, ne*cmd+16), &sd->status.cart[i]);
-#if PACKETVER >= 20071002
- WBUFL(bufe,ne*cmd+24)=sd->status.cart[i].expire_time;
- WBUFW(bufe,ne*cmd+28)=0; //Unknown
-#endif
- ne++;
- }
- else
- { //Stackable
- WBUFW(buf,n*s+4)=i+2;
- clif->item_sub(buf, n*s+6, &sd->status.cart[i], id,-1);
-#if PACKETVER >= 5
- clif->addcards(WBUFP(buf,n*s+14), &sd->status.cart[i]);
-#endif
-#if PACKETVER >= 20080102
- WBUFL(buf,n*s+22)=sd->status.cart[i].expire_time;
-#endif
- n++;
- }
+
+ if( !itemdb->isstackable2(id) ) //Non-stackable (Equippable)
+ clif_item_equip(i+2,&itemlist_equip.list[equip++],&sd->status.cart[i],id,id->equip);
+ else //Stackable (Normal)
+ clif_item_normal(i+2,&itemlist_normal.list[normal++],&sd->status.cart[i],id);
}
- if( n )
- {
-#if PACKETVER < 5
- WBUFW(buf,0)=0x123;
-#elif PACKETVER < 20080102
- WBUFW(buf,0)=0x1ef;
-#else
- WBUFW(buf,0)=0x2e9;
-#endif
- WBUFW(buf,2)=4+n*s;
- clif->send(buf, WBUFW(buf,2), &sd->bl, SELF);
+
+ if( normal ) {
+ itemlist_normal.PacketType = cartlistnormalType;
+ itemlist_normal.PacketLength = 4 + (sizeof(struct NORMALITEM_INFO) * normal);
+
+ clif->send(&itemlist_normal, itemlist_normal.PacketLength, &sd->bl, SELF);
}
- if( ne )
- {
-#if PACKETVER < 20071002
- WBUFW(bufe,0)=0x122;
-#else
- WBUFW(bufe,0)=0x2d2;
-#endif
- WBUFW(bufe,2)=4+ne*cmd;
- clif->send(bufe, WBUFW(bufe,2), &sd->bl, SELF);
+
+ if( equip ) {
+ itemlist_equip.PacketType = cartlistequipType;
+ itemlist_equip.PacketLength = 4 + (sizeof(struct EQUIPITEM_INFO) * equip);
+
+ clif->send(&itemlist_equip, itemlist_equip.PacketLength, &sd->bl, SELF);
}
-
- if( buf ) aFree(buf);
- if( bufe ) aFree(bufe);
}
@@ -3001,7 +2940,8 @@ void clif_updatestatus(struct map_session_data *sd,int type)
case SP_HP:
WFIFOL(fd,4)=sd->battle_status.hp;
// TODO: Won't these overwrite the current packet?
- clif->hpmeter(sd);
+ if( map->list[sd->bl.m].hpmeter_visible )
+ clif->hpmeter(sd);
if( !battle_config.party_hp_mode && sd->status.party_id )
clif->party_hp(sd);
if( sd->bg_id )
@@ -3528,52 +3468,39 @@ void clif_statusupack(struct map_session_data *sd,int type,int ok,int val)
/// Notifies the client about the result of a request to equip an item (ZC_REQ_WEAR_EQUIP_ACK).
/// 00aa <index>.W <equip location>.W <result>.B
/// 00aa <index>.W <equip location>.W <view id>.W <result>.B (PACKETVER >= 20100629)
-/// result:
-/// 0 = failure
-/// 1 = success
-/// 2 = failure due to low level
-void clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok)
-{
- int fd;
+void clif_equipitemack(struct map_session_data *sd,int n,int pos,enum e_EQUIP_ITEM_ACK result) {
+ struct packet_equipitem_ack p;
nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xaa));
- WFIFOW(fd,0)=0xaa;
- WFIFOW(fd,2)=n+2;
- WFIFOW(fd,4)=pos;
-#if PACKETVER < 20100629
- WFIFOB(fd,6)=ok;
-#else
- if (ok && sd->inventory_data[n]->equip&EQP_VISIBLE)
- WFIFOW(fd,6)=sd->inventory_data[n]->look;
+ p.PacketType = equipitemackType;
+ p.index = n+2;
+ p.wearLocation = pos;
+#if PACKETVER >= 20100629
+ if (result == EIA_SUCCESS && sd->inventory_data[n]->equip&EQP_VISIBLE)
+ p.wItemSpriteNumber = sd->inventory_data[n]->look;
else
- WFIFOW(fd,6)=0;
- WFIFOB(fd,8)=ok;
+ p.wItemSpriteNumber = 0;
#endif
- WFIFOSET(fd,packet_len(0xaa));
+ p.result = (unsigned char)result;
+
+ clif->send(&p, sizeof(p), &sd->bl, SELF);
}
/// Notifies the client about the result of a request to take off an item (ZC_REQ_TAKEOFF_EQUIP_ACK).
/// 00ac <index>.W <equip location>.W <result>.B
-/// result:
-/// 0 = failure
-/// 1 = success
-void clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok)
-{
- int fd;
+void clif_unequipitemack(struct map_session_data *sd,int n,int pos,enum e_UNEQUIP_ITEM_ACK result) {
+ struct packet_unequipitem_ack p;
nullpo_retv(sd);
- fd=sd->fd;
- WFIFOHEAD(fd,packet_len(0xac));
- WFIFOW(fd,0)=0xac;
- WFIFOW(fd,2)=n+2;
- WFIFOW(fd,4)=pos;
- WFIFOB(fd,6)=ok;
- WFIFOSET(fd,packet_len(0xac));
+ p.PacketType = unequipitemackType;
+ p.index = n+2;
+ p.wearLocation = pos;
+ p.result = (unsigned char)result;
+
+ clif->send(&p, sizeof(p), &sd->bl, SELF);
}
@@ -4430,8 +4357,7 @@ int clif_calc_walkdelay(struct block_list *bl,int delay, int type, int damage, i
/// 10 = critical hit
/// 11 = lucky dodge
/// 12 = (touch skill?)
-int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int64 in_damage, int div, int type, int64 in_damage2)
-{
+int clif_damage(struct block_list* src, struct block_list* dst, int64 tick, int sdelay, int ddelay, int64 in_damage, int div, int type, int64 in_damage2) {
unsigned char buf[33];
struct status_change *sc;
int damage,damage2;
@@ -4459,7 +4385,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
WBUFW(buf,0)=cmd;
WBUFL(buf,2)=src->id;
WBUFL(buf,6)=dst->id;
- WBUFL(buf,10)=tick;
+ WBUFL(buf,10)=(uint32)tick;
WBUFL(buf,14)=sdelay;
WBUFL(buf,18)=ddelay;
#if PACKETVER < 20071113
@@ -4516,7 +4442,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
*------------------------------------------*/
void clif_takeitem(struct block_list* src, struct block_list* dst)
{
- //clif_damage(src,dst,0,0,0,0,0,1,0);
+ //clif->damage(src,dst,0,0,0,0,0,1,0);
unsigned char buf[32];
nullpo_retv(src);
@@ -4821,7 +4747,7 @@ int clif_insight(struct block_list *bl,va_list ap)
tsd = BL_CAST(BL_PC, tbl);
if (tsd && tsd->fd) { //Tell tsd that bl entered into his view
- switch(bl->type){
+ switch(bl->type) {
case BL_ITEM:
clif->getareachar_item(tsd,(struct flooritem_data*)bl);
break;
@@ -5097,7 +5023,7 @@ void clif_skill_fail(struct map_session_data *sd,uint16 skill_id,enum useskill_f
/// Skill cooldown display icon (ZC_SKILL_POSTDELAY).
/// 043d <skill ID>.W <tick>.L
-void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned int tick)
+void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned int duration)
{
#if PACKETVER>=20081112
int fd;
@@ -5108,7 +5034,7 @@ void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned
WFIFOHEAD(fd,packet_len(0x43d));
WFIFOW(fd,0) = 0x43d;
WFIFOW(fd,2) = skill_id;
- WFIFOL(fd,4) = tick;
+ WFIFOL(fd,4) = duration;
WFIFOSET(fd,packet_len(0x43d));
#endif
}
@@ -5117,7 +5043,7 @@ void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned
/// Skill attack effect and damage.
/// 0114 <skill id>.W <src id>.L <dst id>.L <tick>.L <src delay>.L <dst delay>.L <damage>.W <level>.W <div>.W <type>.B (ZC_NOTIFY_SKILL)
/// 01de <skill id>.W <src id>.L <dst id>.L <tick>.L <src delay>.L <dst delay>.L <damage>.L <level>.W <div>.W <type>.B (ZC_NOTIFY_SKILL2)
-int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int64 in_damage,int div,uint16 skill_id,uint16 skill_lv,int type) {
+int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 in_damage, int div, uint16 skill_id, uint16 skill_lv, int type) {
unsigned char buf[64];
struct status_change *sc;
int damage;
@@ -5138,7 +5064,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int
WBUFW(buf,2)=skill_id;
WBUFL(buf,4)=src->id;
WBUFL(buf,8)=dst->id;
- WBUFL(buf,12)=tick;
+ WBUFL(buf,12)=(uint32)tick;
WBUFL(buf,16)=sdelay;
WBUFL(buf,20)=ddelay;
if (battle_config.hide_woe_damage && map_flag_gvg2(src->m)) {
@@ -5169,7 +5095,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int
WBUFW(buf,2)=skill_id;
WBUFL(buf,4)=src->id;
WBUFL(buf,8)=dst->id;
- WBUFL(buf,12)=tick;
+ WBUFL(buf,12)=(uint32)tick;
WBUFL(buf,16)=sdelay;
WBUFL(buf,20)=ddelay;
if (battle_config.hide_woe_damage && map_flag_gvg2(src->m)) {
@@ -5205,7 +5131,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int
/// Ground skill attack effect and damage (ZC_NOTIFY_SKILL_POSITION).
/// 0115 <skill id>.W <src id>.L <dst id>.L <tick>.L <src delay>.L <dst delay>.L <x>.W <y>.W <damage>.W <level>.W <div>.W <type>.B
#if 0
-int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,uint16 skill_id,uint16 skill_lv,int type) {
+int clif_skill_damage2(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int damage, int div, uint16 skill_id, uint16 skill_lv, int type) {
unsigned char buf[64];
struct status_change *sc;
@@ -5225,7 +5151,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned in
WBUFW(buf,2)=skill_id;
WBUFL(buf,4)=src->id;
WBUFL(buf,8)=dst->id;
- WBUFL(buf,12)=tick;
+ WBUFL(buf,12)=(uint32)tick;
WBUFL(buf,16)=sdelay;
WBUFL(buf,20)=ddelay;
WBUFW(buf,24)=dst->x;
@@ -5295,8 +5221,7 @@ int clif_skill_nodamage(struct block_list *src,struct block_list *dst,uint16 ski
/// Non-damaging ground skill effect (ZC_NOTIFY_GROUNDSKILL).
/// 0117 <skill id>.W <src id>.L <level>.W <x>.W <y>.W <tick>.L
-void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,int y,int tick)
-{
+void clif_skill_poseffect(struct block_list *src, uint16 skill_id, int val, int x, int y, int64 tick) {
unsigned char buf[32];
nullpo_retv(src);
@@ -5307,7 +5232,7 @@ void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,i
WBUFW(buf,8)=val;
WBUFW(buf,10)=x;
WBUFW(buf,12)=y;
- WBUFL(buf,14)=tick;
+ WBUFL(buf,14)=(uint32)tick;
if(disguised(src)) {
clif->send(buf,packet_len(0x117),src,AREA_WOS);
WBUFL(buf,4)=-src->id;
@@ -8951,69 +8876,41 @@ void clif_equpcheckbox(struct map_session_data* sd)
/// 02d7 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE, PACKETVER >= 20100629)
/// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE2, PACKETVER >= 20101124)
/// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <robe>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE2, PACKETVER >= 20110111)
-void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd)
-{
- uint8* buf;
- int i, n, fd, offset = 0;
-#if PACKETVER < 20100629
- const int s = 26;
-#else
- const int s = 28;
-#endif
+void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd) {
+ int i, k, equip = 0;
+
nullpo_retv(sd);
nullpo_retv(tsd);
- fd = sd->fd;
-
- WFIFOHEAD(fd, MAX_INVENTORY * s + 43);
- buf = WFIFOP(fd,0);
+
+ for( i = 0; i < EQI_MAX; i++ ) {
+ if( (k = tsd->equip_index[i]) >= 0 ) {
+
+ if (tsd->status.inventory[k].nameid <= 0 || tsd->inventory_data[k] == NULL) // Item doesn't exist
+ continue;
+
+ clif_item_equip(k+2,&viewequip_list.list[equip++],&tsd->status.inventory[k],tsd->inventory_data[k],pc->equippoint(tsd,k));
-#if PACKETVER < 20101124
- WBUFW(buf, 0) = 0x2d7;
-#else
- WBUFW(buf, 0) = 0x859;
-#endif
- safestrncpy((char*)WBUFP(buf, 4), tsd->status.name, NAME_LENGTH);
- WBUFW(buf,28) = tsd->status.class_;
- WBUFW(buf,30) = tsd->vd.hair_style;
- WBUFW(buf,32) = tsd->vd.head_bottom;
- WBUFW(buf,34) = tsd->vd.head_mid;
- WBUFW(buf,36) = tsd->vd.head_top;
+ }
+ }
+
+ viewequip_list.PacketType = viewequipackType;
+ viewequip_list.PacketLength = ( sizeof( viewequip_list ) - sizeof( viewequip_list.list ) ) + ( sizeof(struct EQUIPITEM_INFO) * equip );
+
+ safestrncpy(viewequip_list.characterName, tsd->status.name, NAME_LENGTH);
+
+ viewequip_list.job = tsd->status.class_;
+ viewequip_list.head = tsd->vd.hair_style;
+ viewequip_list.accessory = tsd->vd.head_bottom;
+ viewequip_list.accessory2 = tsd->vd.head_mid;
+ viewequip_list.accessory3 = tsd->vd.head_top;
#if PACKETVER >= 20110111
- WBUFW(buf,38) = tsd->vd.robe;
- offset+= 2;
- buf = WBUFP(buf,2);
+ viewequip_list.robe = tsd->vd.robe;
#endif
- WBUFW(buf,38) = tsd->vd.hair_color;
- WBUFW(buf,40) = tsd->vd.cloth_color;
- WBUFB(buf,42) = tsd->vd.sex;
-
- for(i=0,n=0; i < MAX_INVENTORY; i++)
- {
- if (tsd->status.inventory[i].nameid <= 0 || tsd->inventory_data[i] == NULL) // Item doesn't exist
- continue;
- if (!itemdb->isequip2(tsd->inventory_data[i])) // Is not equippable
- continue;
-
- // Inventory position
- WBUFW(buf, n*s+43) = i + 2;
- // Add refine, identify flag, element, etc.
- clif->item_sub(WBUFP(buf,0), n*s+45, &tsd->status.inventory[i], tsd->inventory_data[i], pc->equippoint(tsd, i));
- // Add cards
- clif->addcards(WBUFP(buf, n*s+55), &tsd->status.inventory[i]);
- // Expiration date stuff, if all of those are set to 0 then the client doesn't show anything related (6 bytes)
- WBUFL(buf, n*s+63) = tsd->status.inventory[i].expire_time;
- WBUFW(buf, n*s+67) = 0;
-#if PACKETVER >= 20100629
- if (tsd->inventory_data[i]->equip&EQP_VISIBLE)
- WBUFW(buf, n*s+69) = tsd->inventory_data[i]->look;
- else
- WBUFW(buf, n*s+69) = 0;
-#endif
- n++;
- }
-
- WFIFOW(fd, 2) = 43+offset+n*s; // Set length
- WFIFOSET(fd, WFIFOW(fd, 2));
+ viewequip_list.headpalette = tsd->vd.hair_color;
+ viewequip_list.bodypalette = tsd->vd.cloth_color;
+ viewequip_list.sex = tsd->vd.sex;
+
+ clif->send(&viewequip_list, viewequip_list.PacketLength, &sd->bl, SELF);
}
@@ -9316,6 +9213,8 @@ void clif_hercules_chsys_mjoin(struct map_session_data *sd) {
/// Notification from the client, that it has finished map loading and is about to display player's character (CZ_NOTIFY_ACTORINIT).
/// 007d
void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
+ int i;
+
if(sd->bl.prev != NULL)
return;
@@ -9369,13 +9268,11 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
if( map->list[sd->bl.m].users++ == 0 && battle_config.dynamic_mobs )
map->spawnmobs(sd->bl.m);
+
if( !(sd->sc.option&OPTION_INVISIBLE) ) { // increment the number of pvp players on the map
map->list[sd->bl.m].users_pvp++;
}
- if( map->list[sd->bl.m].instance_id >= 0 ) {
- instance->list[map->list[sd->bl.m].instance_id].users++;
- instance->check_idle(map->list[sd->bl.m].instance_id);
- }
+
sd->state.debug_remove_map = 0; // temporary state to track double remove_map's [FlavioJS]
// reset the callshop flag if the player changes map
@@ -9429,7 +9326,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
clif->spawn(&sd->pd->bl);
clif->send_petdata(sd,sd->pd,0,0);
clif->send_petstatus(sd);
-// skill->unit_move(&sd->pd->bl,gettick(),1);
+// skill->unit_move(&sd->pd->bl,timer->gettick(),1);
}
}
@@ -9565,6 +9462,16 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
clif->broadcast(&sd->bl, output, strlen(output) + 1, BC_BLUE, SELF);
}
+ if( map->list[sd->bl.m].instance_id >= 0 ) {
+ instance->list[map->list[sd->bl.m].instance_id].users++;
+ instance->check_idle(map->list[sd->bl.m].instance_id);
+ }
+
+ if( pc->has_permission(sd,PC_PERM_VIEW_HPMETER) ) {
+ map->list[sd->bl.m].hpmeter_visible++;
+ sd->state.hpmeter_visible = 1;
+ }
+
map->iwall_get(sd); // Updates Walls Info on this Map to Client
status_calc_pc(sd, false);/* some conditions are map-dependent so we must recalculate */
sd->state.changemap = false;
@@ -9624,21 +9531,35 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
skill->usave_trigger(sd);
}
-// Trigger skill effects if you appear standing on them
+ // Trigger skill effects if you appear standing on them
if(!battle_config.pc_invincible_time)
skill->unit_move(&sd->bl,timer->gettick(),1);
+ // NPC Quest / Event Icon Check [Kisuka]
+#if PACKETVER >= 20090218
+ for(i = 0; i < map->list[sd->bl.m].qi_count; i++) {
+ struct questinfo *qi = &map->list[sd->bl.m].qi_data[i];
+ if( quest->check(sd, qi->quest_id, HAVEQUEST) == -1 ) {// Check if quest is not started
+ if( qi->hasJob ) { // Check if quest is job-specific, check is user is said job class.
+ if( sd->class_ == qi->job )
+ clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
+ } else {
+ clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
+ }
+ }
+ }
+#endif
}
/// Server's tick (ZC_NOTIFY_TIME).
/// 007f <time>.L
-void clif_notify_time(struct map_session_data* sd, unsigned long time) {
+void clif_notify_time(struct map_session_data* sd, int64 time) {
int fd = sd->fd;
WFIFOHEAD(fd,packet_len(0x7f));
WFIFOW(fd,0) = 0x7f;
- WFIFOL(fd,2) = time;
+ WFIFOL(fd,2) = (uint32)time;
WFIFOSET(fd,packet_len(0x7f));
}
@@ -9734,7 +9655,7 @@ void clif_parse_progressbar(int fd, struct map_session_data * sd)
if( timer->gettick() < sd->progressbar.timeout && sd->st )
sd->st->state = END;
- sd->state.workinprogress = sd->progressbar.npc_id = sd->progressbar.timeout = 0;
+ sd->progressbar.timeout = sd->state.workinprogress = sd->progressbar.npc_id = 0;
npc->scriptcont(sd, npc_id, false);
}
@@ -9767,7 +9688,8 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
RFIFOPOS(fd, packet_db[RFIFOW(fd,0)].pos[0], &x, &y, NULL);
//Set last idle time... [Skotlex]
- sd->idletime = last_tick;
+ if( battle_config.idletime_criteria & BCIDLE_WALK )
+ sd->idletime = last_tick;
unit->walktoxy(&sd->bl, x, y, 4);
}
@@ -9846,7 +9768,7 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) {
clif->charnameack(fd, bl);
}
-int clif_undisguise_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int clif_undisguise_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data * sd;
if( (sd = map->id2sd(id)) ) {
sd->fontcolor_tid = INVALID_TIMER;
@@ -9917,6 +9839,9 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
}
}
+ if( battle_config.idletime_criteria & BCIDLE_CHAT )
+ sd->idletime = last_tick;
+
if( sd->gcbind ) {
clif->chsys_send(sd->gcbind,sd,message);
return;
@@ -10077,6 +10002,9 @@ void clif_parse_Emotion(int fd, struct map_session_data *sd)
return;
}
sd->emotionlasttime = time(NULL);
+
+ if( battle_config.idletime_criteria & BCIDLE_EMOTION )
+ sd->idletime = last_tick;
if(battle_config.client_reshuffle_dice && emoticon>=E_DICE1 && emoticon<=E_DICE6) {// re-roll dice
emoticon = rnd()%6+E_DICE1;
@@ -10108,8 +10036,7 @@ void clif_parse_HowManyConnections(int fd, struct map_session_data *sd) {
}
-void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, unsigned int tick)
-{
+void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, int64 tick) {
if (pc_isdead(sd)) {
clif->clearunit_area(&sd->bl, CLR_DEAD);
return;
@@ -10151,7 +10078,8 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
}
pc->delinvincibletimer(sd);
- sd->idletime = last_tick;
+ if( battle_config.idletime_criteria & BCIDLE_ATTACK )
+ sd->idletime = last_tick;
unit->attack(&sd->bl, target_id, action_type != 0);
break;
case 0x02: // sitdown
@@ -10175,6 +10103,9 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
)) //No sitting during these states either.
break;
+ if( battle_config.idletime_criteria & BCIDLE_SIT )
+ sd->idletime = last_tick;
+
pc_setsit(sd);
skill->sit(sd,1);
clif->sitting(&sd->bl);
@@ -10185,6 +10116,10 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
clif->standing(&sd->bl);
return;
}
+
+ if( battle_config.idletime_criteria & BCIDLE_SIT )
+ sd->idletime = last_tick;
+
pc->setstand(sd);
skill->sit(sd,0);
clif->standing(&sd->bl);
@@ -10376,6 +10311,9 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay;
}
+ if( battle_config.idletime_criteria & BCIDLE_CHAT )
+ sd->idletime = last_tick;
+
// Chat logging type 'W' / Whisper
logs->chat(LOG_CHAT_WHISPER, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, target, message);
@@ -10594,6 +10532,9 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd)
if (!pc->dropitem(sd, item_index, item_amount))
break;
+ if( battle_config.idletime_criteria & BCIDLE_DROPITEM )
+ sd->idletime = last_tick;
+
return;
}
@@ -10619,7 +10560,8 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd)
return;
//Whether the item is used or not is irrelevant, the char ain't idle. [Skotlex]
- sd->idletime = last_tick;
+ if( battle_config.idletime_criteria & BCIDLE_USEITEM )
+ sd->idletime = last_tick;
n = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0])-2;
if(n <0 || n >= MAX_INVENTORY)
@@ -10631,18 +10573,19 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd)
/// Request to equip an item (CZ_REQ_WEAR_EQUIP).
/// 00a9 <index>.W <position>.W
-void clif_parse_EquipItem(int fd,struct map_session_data *sd)
-{
- int index;
+/// 0998 <index>.W <position>.L
+void clif_parse_EquipItem(int fd,struct map_session_data *sd) {
+ struct packet_equip_item *p = P2PTR(fd);
if(pc_isdead(sd)) {
clif->clearunit_area(&sd->bl,CLR_DEAD);
return;
}
- index = RFIFOW(fd,2)-2;
- if (index < 0 || index >= MAX_INVENTORY)
- return; //Out of bounds check.
+ p->index = p->index - 2;
+ if (p->index >= MAX_INVENTORY)
+ return; //Out of bounds check.
+
if( sd->npc_id ) {
if ( !sd->npc_item_flag )
return;
@@ -10651,24 +10594,27 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd)
else if ( pc_cant_act2(sd) || sd->state.prerefining )
return;
- if(!sd->status.inventory[index].identify) {
- clif->equipitemack(sd,index,0,0); // fail
+ if(!sd->status.inventory[p->index].identify) {
+ clif->equipitemack(sd,p->index,0,EIA_FAIL);// fail
return;
}
- if(!sd->inventory_data[index])
+ if(!sd->inventory_data[p->index])
return;
- if(sd->inventory_data[index]->type == IT_PETARMOR){
- pet->equipitem(sd,index);
+ if(sd->inventory_data[p->index]->type == IT_PETARMOR){
+ pet->equipitem(sd,p->index);
return;
}
+ if( battle_config.idletime_criteria & BCIDLE_USEITEM )
+ sd->idletime = last_tick;
+
//Client doesn't send the position for ammo.
- if(sd->inventory_data[index]->type == IT_AMMO)
- pc->equipitem(sd,index,EQP_AMMO);
+ if(sd->inventory_data[p->index]->type == IT_AMMO)
+ pc->equipitem(sd,p->index,EQP_AMMO);
else
- pc->equipitem(sd,index,RFIFOW(fd,4));
+ pc->equipitem(sd,p->index,p->wearLocation);
}
void clif_hercules_chsys_delete(struct hChSysCh *channel) {
@@ -10781,6 +10727,9 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd)
index = RFIFOW(fd,2)-2;
+ if( battle_config.idletime_criteria & BCIDLE_USEITEM )
+ sd->idletime = last_tick;
+
pc->unequipitem(sd,index,1);
}
@@ -11210,8 +11159,7 @@ void clif_parse_SkillUp(int fd,struct map_session_data *sd)
pc->skillup(sd,RFIFOW(fd,2));
}
-void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id)
-{
+void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, int target_id) {
int lv;
if( !hd )
@@ -11232,8 +11180,7 @@ void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_session_dat
unit->skilluse_id(&hd->bl, target_id, skill_id, skill_lv);
}
-void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo)
-{
+void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) {
int lv;
if( !hd )
return;
@@ -11253,8 +11200,7 @@ void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_da
unit->skilluse_pos(&hd->bl, x, y, skill_id, skill_lv);
}
-void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id)
-{
+void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, int target_id) {
int lv;
if( !md )
@@ -11275,8 +11221,7 @@ void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_ses
unit->skilluse_id(&md->bl, target_id, skill_id, skill_lv);
}
-void clif_parse_UseSkillToPos_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo)
-{
+void clif_parse_UseSkillToPos_mercenary(struct mercenary_data *md, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) {
int lv;
if( !md )
return;
@@ -11307,7 +11252,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
{
uint16 skill_id, skill_lv;
int tmp, target_id;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
skill_lv = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0]);
skill_id = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[1]);
@@ -11330,7 +11275,8 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
}
// Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
- sd->idletime = last_tick;
+ if( battle_config.idletime_criteria & BCIDLE_USESKILLTOID )
+ sd->idletime = last_tick;
if( sd->npc_id || sd->state.workinprogress&1 ){
#ifdef RENEWAL
@@ -11407,7 +11353,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
*------------------------------------------*/
void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 skill_lv, uint16 skill_id, short x, short y, int skillmoreinfo)
{
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
if( !(skill->get_inf(skill_id)&INF_GROUND_SKILL) )
return; //Using a target skill on the ground? WRONG.
@@ -11430,7 +11376,8 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 ski
#endif
//Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
- sd->idletime = last_tick;
+ if( battle_config.idletime_criteria & BCIDLE_USESKILLTOPOS )
+ sd->idletime = last_tick;
if( skill->not_ok(skill_id, sd) )
return;
@@ -12185,6 +12132,9 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd)
sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay;
}
+ if( battle_config.idletime_criteria & BCIDLE_CHAT )
+ sd->idletime = last_tick;
+
party->send_message(sd, text, textlen);
}
@@ -13140,6 +13090,9 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd)
sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay;
}
+ if( battle_config.idletime_criteria & BCIDLE_CHAT )
+ sd->idletime = last_tick;
+
if( sd->bg_id )
bg->send_message(sd, text, textlen);
else
@@ -15529,7 +15482,7 @@ void clif_bossmapinfo(int fd, struct mob_data *md, short flag)
unsigned int seconds;
int hours, minutes;
- seconds = DIFF_TICK(timer_data->tick, timer->gettick()) / 1000 + 60;
+ seconds = (unsigned int)(DIFF_TICK(timer_data->tick, timer->gettick()) / 1000 + 60);
hours = seconds / (60 * 60);
seconds = seconds - (60 * 60 * hours);
minutes = seconds / 60;
@@ -16077,6 +16030,9 @@ void clif_parse_BattleChat(int fd, struct map_session_data* sd)
sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay;
}
+ if( battle_config.idletime_criteria & BCIDLE_CHAT )
+ sd->idletime = last_tick;
+
bg->send_message(sd, text, textlen);
}
@@ -16145,7 +16101,7 @@ void clif_font(struct map_session_data *sd)
nullpo_retv(sd);
WBUFW(buf,0) = 0x2ef;
WBUFL(buf,2) = sd->bl.id;
- WBUFW(buf,6) = sd->user_font;
+ WBUFW(buf,6) = sd->status.font;
clif->send(buf, packet_len(0x2ef), &sd->bl, AREA);
#endif
}
@@ -17247,9 +17203,9 @@ void clif_parse_MoveItem(int fd, struct map_session_data *sd) {
/* [Ind/Hercules] */
void clif_cashshop_db(void) {
config_t cashshop_conf;
- config_setting_t *cashshop = NULL;
+ config_setting_t *cashshop = NULL, *cats = NULL;
const char *config_filename = "db/cashshop_db.conf"; // FIXME hardcoded name
- int i;
+ int i, item_count_t = 0;
for( i = 0; i < CASHSHOP_TAB_MAX; i++ ) {
CREATE(clif->cs.data[i], struct hCSData *, 1);
clif->cs.item_count[i] = 0;
@@ -17262,67 +17218,53 @@ void clif_cashshop_db(void) {
cashshop = config_lookup(&cashshop_conf, "cash_shop");
- if (cashshop != NULL) {
- config_setting_t *cats = config_setting_get_elem(cashshop, 0);
- config_setting_t *cat;
- int k, item_count_t = 0;
-
+ if( cashshop != NULL && (cats = config_setting_get_elem(cashshop, 0)) != NULL ) {
for(i = 0; i < CASHSHOP_TAB_MAX; i++) {
+ config_setting_t *cat;
char entry_name[10];
sprintf(entry_name,"cat_%d",i);
if( (cat = config_setting_get_member(cats, entry_name)) != NULL ) {
- int item_count = config_setting_length(cat);
+ int k, item_count = config_setting_length(cat);
- if( item_count == 0 ) {
- ShowWarning("cashshop_db: category '%s' is empty! adding dull apple!\n", entry_name);
- RECREATE(clif->cs.data[i], struct hCSData *, ++clif->cs.item_count[i]);
- CREATE(clif->cs.data[i][ clif->cs.item_count[i] - 1 ], struct hCSData , 1);
-
- clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->id = UNKNOWN_ITEM_ID;
- clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->price = 999;
- } else {
- for(k = 0; k < item_count; k++) {
- config_setting_t *entry = config_setting_get_elem(cat,k);
- const char *name = config_setting_name(entry);
- int price = config_setting_get_int(entry);
- struct item_data * data = NULL;
-
- if( price < 1 ) {
- ShowWarning("cashshop_db: unsupported price '%d' for entry named '%s' in category '%s'\n", price, name, entry_name);
+ for(k = 0; k < item_count; k++) {
+ config_setting_t *entry = config_setting_get_elem(cat,k);
+ const char *name = config_setting_name(entry);
+ int price = config_setting_get_int(entry);
+ struct item_data * data = NULL;
+
+ if( price < 1 ) {
+ ShowWarning("cashshop_db: unsupported price '%d' for entry named '%s' in category '%s'\n", price, name, entry_name);
+ continue;
+ }
+
+ if( name[0] == 'I' && name[1] == 'D' && strlen(name) <= 7 ) {
+ if( !( data = itemdb->exists(atoi(name+2))) ) {
+ ShowWarning("cashshop_db: unknown item id '%s' in category '%s'\n", name+2, entry_name);
continue;
}
-
- if( name[0] == 'I' && name[1] == 'D' && strlen(name) <= 7 ) {
- if( !( data = itemdb->exists(atoi(name+2))) ) {
- ShowWarning("cashshop_db: unknown item id '%s' in category '%s'\n", name+2, entry_name);
- continue;
- }
- } else {
- if( !( data = itemdb->search_name(name) ) ) {
- ShowWarning("cashshop_db: unknown item name '%s' in category '%s'\n", name, entry_name);
- continue;
- }
+ } else {
+ if( !( data = itemdb->search_name(name) ) ) {
+ ShowWarning("cashshop_db: unknown item name '%s' in category '%s'\n", name, entry_name);
+ continue;
}
-
-
- RECREATE(clif->cs.data[i], struct hCSData *, ++clif->cs.item_count[i]);
- CREATE(clif->cs.data[i][ clif->cs.item_count[i] - 1 ], struct hCSData , 1);
-
- clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->id = data->nameid;
- clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->price = price;
- item_count_t++;
}
+
+
+ RECREATE(clif->cs.data[i], struct hCSData *, ++clif->cs.item_count[i]);
+ CREATE(clif->cs.data[i][ clif->cs.item_count[i] - 1 ], struct hCSData , 1);
+
+ clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->id = data->nameid;
+ clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->price = price;
+ item_count_t++;
}
- } else {
- ShowError("cashshop_db: category '%s' (%d) not found!!\n",entry_name,i);
}
}
- ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", item_count_t, config_filename);
config_destroy(&cashshop_conf);
}
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", item_count_t, config_filename);
}
/// Items that are in favorite tab of inventory (ZC_ITEM_FAVORITE).
/// 0900 <index>.W <favorite>.B
@@ -17362,6 +17304,12 @@ void __attribute__ ((unused)) clif_parse_dull(int fd,struct map_session_data *sd
return;
}
void clif_parse_CashShopOpen(int fd, struct map_session_data *sd) {
+
+ if( map->list[sd->bl.m].flag.nocashshop ) {
+ clif->colormes(fd,COLOR_RED,msg_txt(1489)); //Cash Shop is disabled in this map
+ return;
+ }
+
WFIFOHEAD(fd, 10);
WFIFOW(fd, 0) = 0x845;
WFIFOL(fd, 2) = sd->cashPoints; //[Ryuuzaki] - switched positions to reflect proper values
@@ -17377,6 +17325,9 @@ void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) {
int i, j = 0;
for( i = 0; i < CASHSHOP_TAB_MAX; i++ ) {
+ if( clif->cs.item_count[i] == 0 )
+ continue; // Skip empty tabs, the client only expects filled ones
+
WFIFOHEAD(fd, 8 + ( clif->cs.item_count[i] * 6 ) );
WFIFOW(fd, 0) = 0x8ca;
WFIFOW(fd, 2) = 8 + ( clif->cs.item_count[i] * 6 );
@@ -17395,6 +17346,11 @@ void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) {
unsigned short limit = RFIFOW(fd, 4), i, j;
unsigned int kafra_pay = RFIFOL(fd, 6);// [Ryuuzaki] - These are free cash points (strangely #CASH = main cash curreny for us, confusing)
+ if( map->list[sd->bl.m].flag.nocashshop ) {
+ clif->colormes(fd,COLOR_RED,msg_txt(1489)); //Cash Shop is disabled in this map
+ return;
+ }
+
for(i = 0; i < limit; i++) {
int qty = RFIFOL(fd, 14 + ( i * 10 ));
int id = RFIFOL(fd, 10 + ( i * 10 ));
@@ -17478,7 +17434,7 @@ void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) {
short tab = RFIFOW(fd, 2);
int j;
- if( tab < 0 || tab > CASHSHOP_TAB_MAX )
+ if( tab < 0 || tab > CASHSHOP_TAB_MAX || clif->cs.item_count[tab] == 0 )
return;
WFIFOHEAD(fd, 10 + ( clif->cs.item_count[tab] * 6 ) );
@@ -17744,12 +17700,13 @@ void clif_skill_cooldown_list(int fd, struct skill_cd* cd) {
for( i = 0; i < cd->cursor; i++ ) {
if( cd->entry[i]->duration < 1 ) continue;
- WFIFOW(fd, 4 + (count*offset)) = cd->entry[i]->skill_id;
- WFIFOL(fd, 6 + (count*offset)) = cd->entry[i]->duration;
+ WFIFOW(fd, 4 + (count*offset)) = cd->entry[i]->skill_id;
#if PACKETVER >= 20120604
+ WFIFOL(fd, 6 + (count*offset)) = cd->entry[i]->total;
WFIFOL(fd, 10 + (count*offset)) = cd->entry[i]->duration;
+#else
+ WFIFOL(fd, 6 + (count*offset)) = cd->entry[i]->duration;
#endif
-
count++;
}
@@ -18158,6 +18115,7 @@ void clif_defaults(void) {
/* vars */
clif->bind_ip = INADDR_ANY;
clif->map_port = 5121;
+ clif->ally_only = false;
/* core */
clif->init = do_init_clif;
clif->final = do_final_clif;
diff --git a/src/map/clif.h b/src/map/clif.h
index 6d0fc0fc1..cbe3fa857 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -426,6 +426,29 @@ enum e_BANKING_WITHDRAW_ACK {
BWA_UNKNOWN_ERROR = 0x2,
};
+/* because the client devs were replaced by monkeys. */
+enum e_EQUIP_ITEM_ACK {
+#if PACKETVER >= 20120925
+ EIA_SUCCESS = 0x0,
+ EIA_FAIL_LV = 0x1,
+ EIA_FAIL = 0x2,
+#else
+ EIA_SUCCESS = 0x1,
+ EIA_FAIL_LV = 0x2,
+ EIA_FAIL = 0x0,
+#endif
+};
+
+/* and again. because the client devs were replaced by monkeys. */
+enum e_UNEQUIP_ITEM_ACK {
+#if PACKETVER >= 20120925
+ UIA_SUCCESS = 0x0,
+ UIA_FAIL = 0x1,
+#else
+ UIA_SUCCESS = 0x1,
+ UIA_FAIL = 0x0,
+#endif
+};
/**
* Structures
@@ -500,6 +523,8 @@ struct clif_interface {
} cs;
/* */
unsigned int cryptKey[3];
+ /* */
+ bool ally_only;
/* core */
int (*init) (void);
void (*final) (void);
@@ -529,8 +554,8 @@ struct clif_interface {
void (*use_card) (struct map_session_data *sd,int idx);
void (*cart_additem) (struct map_session_data *sd,int n,int amount,int fail);
void (*cart_delitem) (struct map_session_data *sd,int n,int amount);
- void (*equipitemack) (struct map_session_data *sd,int n,int pos,int ok);
- void (*unequipitemack) (struct map_session_data *sd,int n,int pos,int ok);
+ void (*equipitemack) (struct map_session_data *sd,int n,int pos,enum e_EQUIP_ITEM_ACK result);
+ void (*unequipitemack) (struct map_session_data *sd,int n,int pos,enum e_UNEQUIP_ITEM_ACK result);
void (*useitemack) (struct map_session_data *sd,int index,int amount,bool ok);
void (*addcards) (unsigned char* buf, struct item* item);
void (*addcards2) (unsigned short *cards, struct item* item);
@@ -542,7 +567,7 @@ struct clif_interface {
/* unit-related */
void (*clearunit_single) (int id, clr_type type, int fd);
void (*clearunit_area) (struct block_list* bl, clr_type type);
- void (*clearunit_delayed) (struct block_list* bl, clr_type type, unsigned int tick);
+ void (*clearunit_delayed) (struct block_list* bl, clr_type type, int64 tick);
void (*walkok) (struct map_session_data *sd);
void (*move) (struct unit_data *ud);
void (*move2) (struct block_list *bl, struct view_data *vd, struct unit_data *ud);
@@ -556,7 +581,7 @@ struct clif_interface {
void (*skill_setunit) (struct skill_unit *su);
void (*skill_delunit) (struct skill_unit *su);
void (*skillunit_update) (struct block_list* bl);
- int (*clearunit_delayed_sub) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*clearunit_delayed_sub) (int tid, int64 tick, int id, intptr_t data);
void (*set_unit_idle) (struct block_list* bl, struct map_session_data *tsd,enum send_target target);
void (*spawn_unit) (struct block_list* bl, enum send_target target);
void (*spawn_unit2) (struct block_list* bl, enum send_target target);
@@ -600,7 +625,7 @@ struct clif_interface {
void (*scriptclear) (struct map_session_data *sd, int npcid);
/* client-user-interface-related */
void (*viewpoint) (struct map_session_data *sd, int npc_id, int type, int x, int y, int id, int color);
- int (*damage) (struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int64 damage, int div, int type, int64 damage2);
+ int (*damage) (struct block_list* src, struct block_list* dst, int64 tick, int sdelay, int ddelay, int64 damage, int div, int type, int64 damage2);
void (*sitting) (struct block_list* bl);
void (*standing) (struct block_list* bl);
void (*arrow_create_list) (struct map_session_data *sd);
@@ -616,7 +641,7 @@ struct clif_interface {
int (*outsight) (struct block_list *bl,va_list ap);
void (*skillcastcancel) (struct block_list* bl);
void (*skill_fail) (struct map_session_data *sd,uint16 skill_id,enum useskill_fail_cause cause,int btype);
- void (*skill_cooldown) (struct map_session_data *sd, uint16 skill_id, unsigned int tick);
+ void (*skill_cooldown) (struct map_session_data *sd, uint16 skill_id, unsigned int duration);
void (*skill_memomessage) (struct map_session_data* sd, int type);
void (*skill_mapinfomessage) (struct map_session_data *sd, int type);
void (*skill_produce_mix_list) (struct map_session_data *sd, int skill_id, int trigger);
@@ -682,7 +707,7 @@ struct clif_interface {
void (*movetoattack) (struct map_session_data *sd,struct block_list *bl);
void (*solved_charname) (int fd, int charid, const char* name);
void (*charnameupdate) (struct map_session_data *ssd);
- int (*delayquit) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*delayquit) (int tid, int64 tick, int id, intptr_t data);
void (*getareachar_pc) (struct map_session_data* sd,struct map_session_data* dstsd);
void (*disconnect_ack) (struct map_session_data* sd, short result);
void (*PVPInfo) (struct map_session_data* sd);
@@ -700,9 +725,9 @@ struct clif_interface {
void (*wedding_effect) (struct block_list *bl);
void (*divorced) (struct map_session_data* sd, const char* name);
void (*callpartner) (struct map_session_data *sd);
- int (*skill_damage) (struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int64 damage,int div,uint16 skill_id,uint16 skill_lv,int type);
+ int (*skill_damage) (struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 damage, int div, uint16 skill_id, uint16 skill_lv, int type);
int (*skill_nodamage) (struct block_list *src,struct block_list *dst,uint16 skill_id,int heal,int fail);
- void (*skill_poseffect) (struct block_list *src,uint16 skill_id,int val,int x,int y,int tick);
+ void (*skill_poseffect) (struct block_list *src, uint16 skill_id, int val, int x, int y, int64 tick);
void (*skill_estimation) (struct map_session_data *sd,struct block_list *dst);
void (*skill_warppoint) (struct map_session_data* sd, uint16 skill_id, uint16 skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4);
void (*skillcasting) (struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, uint16 skill_id, int property, int casttime);
@@ -960,11 +985,11 @@ struct clif_interface {
void (*adopt_reply) (struct map_session_data *sd, int type);
void (*adopt_request) (struct map_session_data *sd, struct map_session_data *src, int p_id);
void (*readbook) (int fd, int book_id, int page);
- void (*notify_time) (struct map_session_data* sd, unsigned long time);
+ void (*notify_time) (struct map_session_data* sd, int64 time);
void (*user_count) (struct map_session_data* sd, int count);
void (*noask_sub) (struct map_session_data *src, struct map_session_data *target, int type);
void (*bc_ready) (void);
- int (*undisguise_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*undisguise_timer) (int tid, int64 tick, int id, intptr_t data);
/* Hercules Channel System */
void (*chsys_create) (struct hChSysCh *channel, char *name, char *pass, unsigned char color);
void (*chsys_msg) (struct hChSysCh *channel, struct map_session_data *sd, char *msg);
@@ -998,7 +1023,7 @@ struct clif_interface {
void (*pEmotion) (int fd, struct map_session_data *sd);
void (*pHowManyConnections) (int fd, struct map_session_data *sd);
void (*pActionRequest) (int fd, struct map_session_data *sd);
- void (*pActionRequest_sub) (struct map_session_data *sd, int action_type, int target_id, unsigned int tick);
+ void (*pActionRequest_sub) (struct map_session_data *sd, int action_type, int target_id, int64 tick);
void (*pRestart) (int fd, struct map_session_data *sd);
void (*pWisMessage) (int fd, struct map_session_data* sd);
void (*pBroadcast) (int fd, struct map_session_data* sd);
@@ -1032,12 +1057,12 @@ struct clif_interface {
void (*pStatusUp) (int fd,struct map_session_data *sd);
void (*pSkillUp) (int fd,struct map_session_data *sd);
void (*pUseSkillToId) (int fd, struct map_session_data *sd);
- void (*pUseSkillToId_homun) (struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id);
- void (*pUseSkillToId_mercenary) (struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id);
+ void (*pUseSkillToId_homun) (struct homun_data *hd, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, int target_id);
+ void (*pUseSkillToId_mercenary) (struct mercenary_data *md, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, int target_id);
void (*pUseSkillToPos) (int fd, struct map_session_data *sd);
void (*pUseSkillToPosSub) (int fd, struct map_session_data *sd, uint16 skill_lv, uint16 skill_id, short x, short y, int skillmoreinfo);
- void (*pUseSkillToPos_homun) (struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo);
- void (*pUseSkillToPos_mercenary) (struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo);
+ void (*pUseSkillToPos_homun) (struct homun_data *hd, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo);
+ void (*pUseSkillToPos_mercenary) (struct mercenary_data *md, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo);
void (*pUseSkillToPosMoreInfo) (int fd, struct map_session_data *sd);
void (*pUseSkillMap) (int fd, struct map_session_data* sd);
void (*pRequestMemo) (int fd,struct map_session_data *sd);
diff --git a/src/map/elemental.c b/src/map/elemental.c
index 3251ca992..f15b735b2 100644
--- a/src/map/elemental.c
+++ b/src/map/elemental.c
@@ -148,7 +148,7 @@ int elemental_get_lifetime(struct elemental_data *ed) {
return 0;
td = timer->get(ed->summon_timer);
- return (td != NULL) ? DIFF_TICK(td->tick, timer->gettick()) : 0;
+ return (td != NULL) ? DIFF_TICK32(td->tick, timer->gettick()) : 0;
}
int elemental_save(struct elemental_data *ed) {
@@ -169,7 +169,7 @@ int elemental_save(struct elemental_data *ed) {
return 1;
}
-int elemental_summon_end_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int elemental_summon_end_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd;
struct elemental_data *ed;
@@ -388,7 +388,7 @@ int elemental_clean_effect(struct elemental_data *ed) {
return 1;
}
-int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) {
+int elemental_action(struct elemental_data *ed, struct block_list *bl, int64 tick) {
struct skill_condition req;
uint16 skill_id, skill_lv;
int i;
@@ -636,7 +636,7 @@ int elemental_ai_sub_timer_activesearch(struct block_list *bl, va_list ap) {
return 0;
}
-int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, unsigned int tick) {
+int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, int64 tick) {
struct block_list *target = NULL;
int master_dist, view_range, mode;
@@ -723,7 +723,7 @@ int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *s
}
if( battle->check_range(&ed->bl,target,view_range) && rnd()%100 < 2 ) { // 2% chance to cast attack skill.
- if( elemental->action(ed,target,tick) )
+ if( elemental->action(ed,target,tick) )
return 1;
}
@@ -746,14 +746,14 @@ int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *s
}
int elemental_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) {
- unsigned int tick = va_arg(ap,unsigned int);
+ int64 tick = va_arg(ap,int64);
if(sd->status.ele_id && sd->ed)
elemental->ai_sub_timer(sd->ed,sd,tick);
return 0;
}
-int elemental_ai_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int elemental_ai_timer(int tid, int64 tick, int id, intptr_t data) {
map->foreachpc(elemental->ai_sub_foreachclient,tick);
return 0;
}
diff --git a/src/map/elemental.h b/src/map/elemental.h
index b42d5c0b7..3cd819d53 100644
--- a/src/map/elemental.h
+++ b/src/map/elemental.h
@@ -57,7 +57,7 @@ struct elemental_data {
int summon_timer;
int skill_timer;
- unsigned last_thinktime, last_linktime, last_spdrain_time;
+ int64 last_thinktime, last_linktime, last_spdrain_time;
short min_chase;
int target_id, attacked_id;
};
@@ -99,7 +99,7 @@ struct elemental_interface {
int (*set_target) (struct map_session_data *sd, struct block_list *bl);
int (*clean_single_effect) (struct elemental_data *ed, uint16 skill_id);
int (*clean_effect) (struct elemental_data *ed);
- int (*action) (struct elemental_data *ed, struct block_list *bl, unsigned int tick);
+ int (*action) (struct elemental_data *ed, struct block_list *bl, int64 tick);
struct skill_condition (*skill_get_requirements) (uint16 skill_id, uint16 skill_lv);
int (*read_skilldb) (void);
@@ -108,11 +108,11 @@ struct elemental_interface {
int (*search_index) (int class_);
void (*summon_init) (struct elemental_data *ed);
- int (*summon_end_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*summon_end_timer) (int tid, int64 tick, int id, intptr_t data);
int (*ai_sub_timer_activesearch) (struct block_list *bl, va_list ap);
- int (*ai_sub_timer) (struct elemental_data *ed, struct map_session_data *sd, unsigned int tick);
+ int (*ai_sub_timer) (struct elemental_data *ed, struct map_session_data *sd, int64 tick);
int (*ai_sub_foreachclient) (struct map_session_data *sd, va_list ap);
- int (*ai_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*ai_timer) (int tid, int64 tick, int id, intptr_t data);
int (*read_db) (void);
};
diff --git a/src/map/guild.c b/src/map/guild.c
index 30f989f58..0ae45bede 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -279,8 +279,7 @@ int guild_payexp_timer_sub(DBKey key, DBData *data, va_list ap) {
return 0;
}
-int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data)
-{
+int guild_payexp_timer(int tid, int64 tick, int id, intptr_t data) {
guild->expcache_db->clear(guild->expcache_db,guild->payexp_timer_sub);
return 0;
}
@@ -314,8 +313,7 @@ int guild_send_xy_timer_sub(DBKey key, DBData *data, va_list ap)
}
//Code from party_send_xy_timer [Skotlex]
-int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
-{
+int guild_send_xy_timer(int tid, int64 tick, int id, intptr_t data) {
guild->db->foreach(guild->db,guild->send_xy_timer_sub,tick);
return 0;
}
@@ -1365,7 +1363,7 @@ void guild_block_skill(struct map_session_data *sd, int time)
uint16 skill_id[] = { GD_BATTLEORDER, GD_REGENERATION, GD_RESTORE, GD_EMERGENCYCALL };
int i;
for (i = 0; i < 4; i++)
- skill->blockpc_start(sd, skill_id[i], time , true);
+ skill->blockpc_start(sd, skill_id[i], time);
}
/*====================================================
diff --git a/src/map/guild.h b/src/map/guild.h
index 566ca7ce4..348a6c7e4 100644
--- a/src/map/guild.h
+++ b/src/map/guild.h
@@ -148,13 +148,13 @@ struct guild_interface {
/* guild aura */
void (*aura_refresh) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
/* */
- int (*payexp_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*payexp_timer) (int tid, int64 tick, int id, intptr_t data);
TBL_PC* (*sd_check) (int guild_id, int account_id, int char_id);
bool (*read_guildskill_tree_db) (char* split[], int columns, int current);
bool (*read_castledb) (char* str[], int columns, int current);
int (*payexp_timer_sub) (DBKey key, DBData *data, va_list ap);
int (*send_xy_timer_sub) (DBKey key, DBData *data, va_list ap);
- int (*send_xy_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*send_xy_timer) (int tid, int64 tick, int id, intptr_t data);
DBData (*create_expcache) (DBKey key, va_list args);
int (*eventlist_db_final) (DBKey key, DBData *data, va_list ap);
int (*expcache_db_final) (DBKey key, DBData *data, va_list ap);
diff --git a/src/map/homunculus.c b/src/map/homunculus.c
index 1e47053fe..52f0572c0 100644
--- a/src/map/homunculus.c
+++ b/src/map/homunculus.c
@@ -615,7 +615,7 @@ bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) {
return true;
}
-int homunculus_hunger_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int homunculus_hunger_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd;
struct homun_data *hd;
diff --git a/src/map/homunculus.h b/src/map/homunculus.h
index 2cb558930..e3ec38f7b 100644
--- a/src/map/homunculus.h
+++ b/src/map/homunculus.h
@@ -117,7 +117,7 @@ struct homunculus_interface {
void (*save) (struct homun_data *hd);
unsigned char (*menu) (struct map_session_data *sd,unsigned char menu_num);
bool (*feed) (struct map_session_data *sd, struct homun_data *hd);
- int (*hunger_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*hunger_timer) (int tid, int64 tick, int id, intptr_t data);
void (*hunger_timer_delete) (struct homun_data *hd);
int (*change_name) (struct map_session_data *sd,char *name);
bool (*change_name_ack) (struct map_session_data *sd, char* name, int flag);
diff --git a/src/map/instance.c b/src/map/instance.c
index 6ae1d6141..6b96c3112 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -110,7 +110,10 @@ int instance_create(int owner_id, const char *name, enum instance_owner_type typ
instance->list[i].owner_id = owner_id;
instance->list[i].owner_type = type;
instance->list[i].vars = idb_alloc(DB_OPT_RELEASE_DATA);
-
+ instance->list[i].respawn.map = 0;
+ instance->list[i].respawn.y = 0;
+ instance->list[i].respawn.x = 0;
+
safestrncpy( instance->list[i].name, name, sizeof(instance->list[i].name) );
if( type != IOT_NONE ) {
@@ -239,9 +242,17 @@ int instance_add_map(const char *name, int instance_id, bool usebasename, const
}
}
+ //Mimic questinfo
+ if( map->list[m].qi_count ) {
+ map->list[im].qi_count = map->list[m].qi_count;
+ CREATE( map->list[im].qi_data, struct questinfo, map->list[im].qi_count );
+ memcpy( map->list[im].qi_data, map->list[m].qi_data, map->list[im].qi_count * sizeof(struct questinfo) );
+ }
+
map->list[im].m = im;
map->list[im].instance_id = instance_id;
map->list[im].instance_src_map = m;
+ map->list[im].flag.src4instance = 0; //clear
map->list[m].flag.src4instance = 1; // Flag this map as a src map for instances
RECREATE(instance->list[instance_id].map, unsigned short, ++instance->list[instance_id].num_map);
@@ -271,6 +282,21 @@ int instance_map2imap(int16 m, int instance_id) {
return -1;
}
+int instance_mapname2imap(const char *map_name, int instance_id) {
+ int i;
+
+ if( !instance->valid(instance_id) ) {
+ return -1;
+ }
+
+ for( i = 0; i < instance->list[instance_id].num_map; i++ ) {
+ if( instance->list[instance_id].map[i] && !strcmpi(map->list[map->list[instance->list[instance_id].map[i]].instance_src_map].name,map_name) )
+ return instance->list[instance_id].map[i];
+ }
+ return -1;
+}
+
+
/*--------------------------------------
* m : source map
* instance_id : where to search
@@ -291,7 +317,6 @@ int instance_mapid2imapid(int16 m, int instance_id) {
}
/*--------------------------------------
- * map_instance_map_npcsub
* Used on Init instance. Duplicates each script on source map
*--------------------------------------*/
int instance_map_npcsub(struct block_list* bl, va_list args) {
@@ -304,6 +329,19 @@ int instance_map_npcsub(struct block_list* bl, va_list args) {
return 1;
}
+int instance_init_npc(struct block_list* bl, va_list args) {
+ struct npc_data *nd = (struct npc_data*)bl;
+ struct event_data *ev;
+ char evname[EVENT_NAME_LENGTH];
+
+ snprintf(evname, EVENT_NAME_LENGTH, "%s::OnInstanceInit", nd->exname);
+
+ if( ( ev = strdb_get(npc->ev_db, evname) ) )
+ script->run(ev->nd->u.scr.script, ev->pos, 0, ev->nd->bl.id);
+
+ return 1;
+}
+
/*--------------------------------------
* Init all map on the instance. Npcs are created here
*--------------------------------------*/
@@ -314,8 +352,11 @@ void instance_init(int instance_id) {
return; // nothing to do
for( i = 0; i < instance->list[instance_id].num_map; i++ )
- map->foreachinmap(instance_map_npcsub, map->list[instance->list[instance_id].map[i]].instance_src_map, BL_NPC, instance->list[instance_id].map[i]);
+ map->foreachinmap(instance->map_npcsub, map->list[instance->list[instance_id].map[i]].instance_src_map, BL_NPC, instance->list[instance_id].map[i]);
+ /* cant be together with the previous because it will rely on all of them being up */
+ map->foreachininstance(instance->init_npc, instance_id, BL_NPC);
+
instance->list[instance_id].state = INSTANCE_BUSY;
}
@@ -409,6 +450,9 @@ void instance_del_map(int16 m) {
aFree(map->list[m].zone_mf);
}
+ if( map->list[m].qi_data )
+ aFree(map->list[m].qi_data);
+
// Remove from instance
for( i = 0; i < instance->list[map->list[m].instance_id].num_map; i++ ) {
if( instance->list[map->list[m].instance_id].map[i] == m ) {
@@ -436,7 +480,7 @@ void instance_del_map(int16 m) {
/*--------------------------------------
* Timer to destroy instance by process or idle
*--------------------------------------*/
-int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int instance_destroy_timer(int tid, int64 tick, int id, intptr_t data) {
instance->destroy(id);
return 0;
}
@@ -566,9 +610,11 @@ void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsign
if( progress_timeout ) {
instance->list[instance_id].progress_timeout = now + progress_timeout;
instance->list[instance_id].progress_timer = timer->add( timer->gettick() + progress_timeout * 1000, instance->destroy_timer, instance_id, 0);
+ instance->list[instance_id].original_progress_timeout = progress_timeout;
} else {
instance->list[instance_id].progress_timeout = 0;
instance->list[instance_id].progress_timer = INVALID_TIMER;
+ instance->list[instance_id].original_progress_timeout = 0;
}
if( idle_timeout ) {
@@ -600,6 +646,37 @@ void instance_check_kick(struct map_session_data *sd) {
}
}
+void do_reload_instance(void) {
+ struct s_mapiterator *iter;
+ struct map_session_data *sd;
+ int i, k;
+
+ for(i = 0; i < instance->instances; i++) {
+ for(k = 0; k < instance->list[i].num_map; k++) {
+ if( !map->list[map->list[instance->list[i].map[k]].instance_src_map].flag.src4instance )
+ break;
+ }
+
+ if( k != instance->list[i].num_map ) /* any (or all) of them were disabled, we destroy */
+ instance->destroy(i);
+ else {
+ /* populate the instance again */
+ instance->start(i);
+ /* restart timers */
+ instance->set_timeout(i,instance->list[i].original_progress_timeout,instance->list[i].idle_timeoutval);
+ }
+ }
+
+ iter = mapit_getallusers();
+ for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) {
+ if(sd && map->list[sd->bl.m].instance_id >= 0) {
+ pc->setpos(sd,instance->list[map->list[sd->bl.m].instance_id].respawn.map,instance->list[map->list[sd->bl.m].instance_id].respawn.x,instance->list[map->list[sd->bl.m].instance_id].respawn.y,CLR_TELEPORT);
+ }
+ }
+ mapit->free(iter);
+}
+
+
void do_final_instance(void) {
int i;
@@ -623,7 +700,7 @@ void instance_defaults(void) {
instance->init = do_init_instance;
instance->final = do_final_instance;
-
+ instance->reload = do_reload_instance;
/* start point */
instance->start_id = 0;
/* count */
@@ -636,6 +713,9 @@ void instance_defaults(void) {
instance->del_map = instance_del_map;
instance->map2imap = instance_map2imap;
instance->mapid2imapid = instance_mapid2imapid;
+ instance->mapname2imap = instance_mapname2imap;
+ instance->map_npcsub = instance_map_npcsub;
+ instance->init_npc = instance_init_npc;
instance->destroy = instance_destroy;
instance->start = instance_init;
instance->check_idle = instance_check_idle;
diff --git a/src/map/instance.h b/src/map/instance.h
index ba6d26d59..27a9401b4 100644
--- a/src/map/instance.h
+++ b/src/map/instance.h
@@ -40,11 +40,16 @@ struct instance_data {
int idle_timer;
unsigned int idle_timeout, idle_timeoutval;
+
+ unsigned int original_progress_timeout;
+
+ struct point respawn;/* reload spawn */
};
struct instance_interface {
void (*init) (void);
void (*final) (void);
+ void (*reload) (void);
/* start point */
unsigned short start_id;
unsigned short instances;/* count */
@@ -56,13 +61,16 @@ struct instance_interface {
void (*del_map) (int16 m);
int (*map2imap) (int16 m, int instance_id);
int (*mapid2imapid) (int16 m, int instance_id);
+ int (*mapname2imap) (const char *map_name, int instance_id);
+ int (*map_npcsub) (struct block_list* bl, va_list args);
+ int (*init_npc) (struct block_list* bl, va_list args);
void (*destroy) (int instance_id);
void (*start) (int instance_id);
void (*check_idle) (int instance_id);
void (*check_kick) (struct map_session_data *sd);
void (*set_timeout) (int instance_id, unsigned int progress_timeout, unsigned int idle_timeout);
bool (*valid) (int instance_id);
- int (*destroy_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*destroy_timer) (int tid, int64 tick, int id, intptr_t data);
};
struct instance_interface *instance;
diff --git a/src/map/irc-bot.c b/src/map/irc-bot.c
index 5225672af..f67446629 100644
--- a/src/map/irc-bot.c
+++ b/src/map/irc-bot.c
@@ -29,7 +29,7 @@ char send_string[IRC_MESSAGE_LENGTH];
* Timer callback to (re-)connect to an IRC server
* @see timer->do_timer
*/
-int irc_connect_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int irc_connect_timer(int tid, int64 tick, int id, intptr_t data) {
struct hSockOpt opt;
if( ircbot->isOn || ++ircbot->fails >= 3 )
return 0;
@@ -52,7 +52,7 @@ int irc_connect_timer(int tid, unsigned int tick, int id, intptr_t data) {
* Timer callback to send identification commands to an IRC server
* @see timer->do_timer
*/
-int irc_identify_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int irc_identify_timer(int tid, int64 tick, int id, intptr_t data) {
if( !ircbot->isOn )
return 0;
@@ -70,7 +70,7 @@ int irc_identify_timer(int tid, unsigned int tick, int id, intptr_t data) {
* Timer callback to join channels (and optionally send NickServ commands)
* @see timer->do_timer
*/
-int irc_join_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int irc_join_timer(int tid, int64 tick, int id, intptr_t data) {
if( !ircbot->isOn )
return 0;
diff --git a/src/map/irc-bot.h b/src/map/irc-bot.h
index aafbfccde..52ff0c9be 100644
--- a/src/map/irc-bot.h
+++ b/src/map/irc-bot.h
@@ -22,7 +22,7 @@ struct irc_func {
struct irc_bot_interface {
int fd;
bool isIn, isOn;
- unsigned int last_try;
+ int64 last_try;
unsigned char fails;
unsigned long ip;
unsigned short port;
@@ -43,9 +43,9 @@ struct irc_bot_interface {
/* */
struct irc_func* (*func_search) (char* function_name);
/* */
- int (*connect_timer) (int tid, unsigned int tick, int id, intptr_t data);
- int (*identify_timer) (int tid, unsigned int tick, int id, intptr_t data);
- int (*join_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*connect_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*identify_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*join_timer) (int tid, int64 tick, int id, intptr_t data);
/* */
void (*send)(char *str);
void (*relay) (char *name, const char *msg);
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 5c698b3c9..3fc8d526b 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -1027,7 +1027,10 @@ void itemdb_read_packages(void) {
if( itemdb->packages[count].random_qty ) {
CREATE(itemdb->packages[count].random_groups, struct item_package_rand_group, itemdb->packages[count].random_qty);
for( c = 0; c < itemdb->packages[count].random_qty; c++ ) {
- CREATE(itemdb->packages[count].random_groups[c].random_list, struct item_package_rand_entry, rgroups[ i - 1 ][c]);
+ if( !rgroups[ i - 1 ][c] )
+ ShowError("itemdb_read_packages: package '%s' missing 'Random' field %d! there must not be gaps!\n",config_setting_name(itg),c+1);
+ else
+ CREATE(itemdb->packages[count].random_groups[c].random_list, struct item_package_rand_entry, rgroups[ i - 1 ][c]);
itemdb->packages[count].random_groups[c].random_qty = 0;
}
}
@@ -1090,7 +1093,7 @@ void itemdb_read_packages(void) {
itemdb->packages[count].random_groups[gidx].random_list[r].id = data ? data->nameid : 0;
itemdb->packages[count].random_groups[gidx].random_list[r].qty = icount;
if( (itemdb->packages[count].random_groups[gidx].random_list[r].rate = rate) == 10000 ) {
- ShowWarning("itemdb_read_packages: item '%s' in '%s' has 100% drop rate!! set this item as 'Random: 0' or other items won't drop!!!\n",itname,config_setting_name(itg));
+ ShowWarning("itemdb_read_packages: item '%s' in '%s' has 100%% drop rate!! set this item as 'Random: 0' or other items won't drop!!!\n",itname,config_setting_name(itg));
}
itemdb->packages[count].random_groups[gidx].random_list[r].hours = expire;
itemdb->packages[count].random_groups[gidx].random_list[r].announce = announce == true ? 1 : 0;
@@ -1584,6 +1587,9 @@ int itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt)
if( nameid <= 0 ) {
ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source);
return 0;
+ } else if ( nameid >= MAX_ITEMDB ) {
+ ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", beyond MAX_ITEMDB, skipping.\n", nameid, line, source);
+ return 0;
}
//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index 0f46c1c01..2579d84ca 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -48,6 +48,15 @@ enum item_itemid {
ITEMID_TRAP_ALLOY = 7940,
ITEMID_ANCILLA = 12333,
ITEMID_REINS_OF_MOUNT = 12622,
+ ITEMID_LOVE_ANGEL = 12287,
+ ITEMID_SQUIRREL = 12288,
+ ITEMID_GOGO = 12289,
+ ITEMID_PICTURE_DIARY = 12304,
+ ITEMID_MINI_HEART = 12305,
+ ITEMID_NEWCOMER = 12306,
+ ITEMID_KID = 12307,
+ ITEMID_MAGIC_CASTLE = 12308,
+ ITEMID_BULGING_HEAD = 12309,
};
/**
diff --git a/src/map/map.c b/src/map/map.c
index d920875ee..2a2f98bdc 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -88,8 +88,12 @@ int map_usercount(void) {
*------------------------------------------*/
int map_freeblock (struct block_list *bl) {
nullpo_retr(map->block_free_lock, bl);
+
if (map->block_free_lock == 0 || map->block_free_count >= block_free_max) {
- aFree(bl);
+ if( bl->type == BL_ITEM )
+ ers_free(map->flooritem_ers, bl);
+ else
+ aFree(bl);
bl = NULL;
if (map->block_free_count >= block_free_max)
ShowWarning("map_freeblock: too many free block! %d %d\n", map->block_free_count, map->block_free_lock);
@@ -109,11 +113,14 @@ int map_freeblock_lock (void) {
* Remove the lock on map_bl
*------------------------------------------*/
int map_freeblock_unlock (void) {
+
if ((--map->block_free_lock) == 0) {
int i;
- for (i = 0; i < map->block_free_count; i++)
- {
- aFree(map->block_free[i]);
+ for (i = 0; i < map->block_free_count; i++) {
+ if( map->block_free[i]->type == BL_ITEM )
+ ers_free(map->flooritem_ers, map->block_free[i]);
+ else
+ aFree(map->block_free[i]);
map->block_free[i] = NULL;
}
map->block_free_count = 0;
@@ -127,7 +134,7 @@ int map_freeblock_unlock (void) {
// Timer function to check if there some remaining lock and remove them if so.
// Called each 1s
-int map_freeblock_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int map_freeblock_timer(int tid, int64 tick, int id, intptr_t data) {
if (map->block_free_lock > 0) {
ShowError("map_freeblock_timer: block_free_lock(%d) is invalid.\n", map->block_free_lock);
map->block_free_lock = 1;
@@ -259,8 +266,7 @@ int map_delblock(struct block_list* bl)
* Pass flag as 1 to prevent doing skill->unit_move checks
* (which are executed by default on BL_CHAR types)
*------------------------------------------*/
-int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
-{
+int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) {
int x0 = bl->x, y0 = bl->y;
struct status_change *sc = NULL;
int moveblock = ( x0/BLOCK_SIZE != x1/BLOCK_SIZE || y0/BLOCK_SIZE != y1/BLOCK_SIZE);
@@ -1305,7 +1311,7 @@ int map_get_new_object_id(void)
* Timered function to clear the floor (remove remaining item)
* Called each flooritem_lifetime ms
*------------------------------------------*/
-int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int map_clearflooritem_timer(int tid, int64 tick, int id, intptr_t data) {
struct flooritem_data* fitem = (struct flooritem_data*)idb_get(map->id_db, id);
if (fitem == NULL || fitem->bl.type != BL_ITEM || (fitem->cleartimer != tid)) {
@@ -1330,7 +1336,7 @@ int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data)
void map_clearflooritem(struct block_list *bl) {
struct flooritem_data* fitem = (struct flooritem_data*)bl;
- if( fitem->cleartimer )
+ if( fitem->cleartimer != INVALID_TIMER )
timer->delete(fitem->cleartimer,map->clearflooritem_timer);
clif->clearflooritem(fitem, 0);
@@ -1470,15 +1476,16 @@ int map_addflooritem(struct item *item_data,int amount,int16 m,int16 x,int16 y,i
return 0;
r=rnd();
- CREATE(fitem, struct flooritem_data, 1);
- fitem->bl.type=BL_ITEM;
+ fitem = ers_alloc(map->flooritem_ers, struct flooritem_data);
+
+ fitem->bl.type = BL_ITEM;
fitem->bl.prev = fitem->bl.next = NULL;
- fitem->bl.m=m;
- fitem->bl.x=x;
- fitem->bl.y=y;
+ fitem->bl.m = m;
+ fitem->bl.x = x;
+ fitem->bl.y = y;
fitem->bl.id = map->get_new_object_id();
if(fitem->bl.id==0){
- aFree(fitem);
+ ers_free(map->flooritem_ers, fitem);
return 0;
}
@@ -1715,8 +1722,6 @@ int map_quit(struct map_session_data *sd) {
if( sd->state.storage_flag == 1 ) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit.
- if (sd->state.permanent_speed == 1) sd->state.permanent_speed = 0; // Remove lock so speed is set back to normal at login.
-
if( sd->ed ) {
elemental->clean_effect(sd->ed);
unit->remove_map(&sd->ed->bl,CLR_TELEPORT,ALC_MARK);
@@ -2288,8 +2293,7 @@ int map_removemobs_sub(struct block_list *bl, va_list ap)
return 1;
}
-int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data)
-{
+int map_removemobs_timer(int tid, int64 tick, int id, intptr_t data) {
int count;
const int16 m = id;
@@ -3104,6 +3108,10 @@ void do_final_maps(void) {
if( map->list[i].channel )
clif->chsys_delete(map->list[i].channel);
+
+ if( map->list[i].qi_data )
+ aFree(map->list[i].qi_data);
+
}
map->zone_db_clear();
@@ -3169,6 +3177,12 @@ void map_flags_init(void) {
map->list[i].misc_damage_rate = 100;
map->list[i].short_damage_rate = 100;
map->list[i].long_damage_rate = 100;
+
+ if( map->list[i].qi_data )
+ aFree(map->list[i].qi_data);
+
+ map->list[i].qi_data = NULL;
+ map->list[i].qi_count = 0;
}
}
@@ -4380,7 +4394,17 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
map_zone_mf_cache_add(m,rflag);
}
}
+ } else if (!strcmpi(flag,"nocashshop")) {
+ if( state && map->list[m].flag.nocashshop )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nocashshop\toff");
+ else if( map->list[m].flag.nocashshop )
+ map_zone_mf_cache_add(m,"nocashshop");
+ }
}
+
return false;
}
void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const char* buffer, const char* filepath) {
@@ -4946,6 +4970,42 @@ void read_map_zone_db(void) {
}
}
+int map_get_new_bonus_id (void) {
+ return map->bonus_id++;
+}
+
+void map_add_questinfo(int m, struct questinfo *qi) {
+ unsigned short i;
+
+ /* duplicate, override */
+ for(i = 0; i < map->list[m].qi_count; i++) {
+ if( map->list[m].qi_data[i].nd == qi->nd )
+ break;
+ }
+
+ if( i == map->list[m].qi_count )
+ RECREATE(map->list[m].qi_data, struct questinfo, ++map->list[m].qi_count);
+
+ memcpy(&map->list[m].qi_data[i], qi, sizeof(struct questinfo));
+}
+
+bool map_remove_questinfo(int m, struct npc_data *nd) {
+ unsigned short i;
+
+ for(i = 0; i < map->list[m].qi_count; i++) {
+ struct questinfo *qi = &map->list[m].qi_data[i];
+ if( qi->nd == nd ) {
+ memset(&map->list[m].qi_data[i], 0, sizeof(struct questinfo));
+ if( i != --map->list[m].qi_count ) {
+ memmove(&map->list[m].qi_data[i],&map->list[m].qi_data[i+1],sizeof(struct questinfo)*(map->list[m].qi_count-i));
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
/**
* @see DBApply
*/
@@ -5075,6 +5135,8 @@ void do_final(void)
map->list_final();
vending->final();
+ HPM_map_do_final();
+
map->map_db->destroy(map->map_db, map->db_final);
mapindex_final();
@@ -5092,6 +5154,7 @@ void do_final(void)
map->sql_close();
ers_destroy(map->iterator_ers);
+ ers_destroy(map->flooritem_ers);
aFree(map->list);
@@ -5470,7 +5533,10 @@ int do_init(int argc, char *argv[])
map->zone_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAP_ZONE_NAME_LENGTH);
map->iterator_ers = ers_new(sizeof(struct s_mapiterator),"map.c::map_iterator_ers",ERS_OPT_NONE);
-
+
+ map->flooritem_ers = ers_new(sizeof(struct flooritem_data),"map.c::map_flooritem_ers",ERS_OPT_NONE);
+ ers_chunk_size(map->flooritem_ers, 100);
+
map->sql_init();
if (logs->config.sql_logs)
logs->sql_init();
@@ -5634,6 +5700,10 @@ void map_defaults(void) {
map->iterator_ers = NULL;
map->cache_buffer = NULL;
+
+ map->flooritem_ers = NULL;
+ /* */
+ map->bonus_id = SP_LAST_KNOWN;
/* funcs */
map->zone_init = map_zone_init;
map->zone_remove = map_zone_remove;
@@ -5800,7 +5870,12 @@ void map_defaults(void) {
map->addblcell = map_addblcell;
map->delblcell = map_delblcell;
-
+
+ map->get_new_bonus_id = map_get_new_bonus_id;
+
+ map->add_questinfo = map_add_questinfo;
+ map->remove_questinfo = map_remove_questinfo;
+
/**
* mapit interface
**/
diff --git a/src/map/map.h b/src/map/map.h
index 3a7990dcb..6b7d2a630 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -339,7 +339,7 @@ struct flooritem_data {
unsigned char subx,suby;
int cleartimer;
int first_get_charid,second_get_charid,third_get_charid;
- unsigned int first_get_tick,second_get_tick,third_get_tick;
+ int64 first_get_tick,second_get_tick,third_get_tick;
struct item item_data;
};
@@ -406,7 +406,11 @@ enum _sp {
SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE, SP_MAGIC_SP_GAIN_VALUE, SP_MAGIC_HP_GAIN_VALUE, SP_ADD_CLASS_DROP_ITEM, //2041-2045
SP_EMATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SKILL_USE_SP_RATE, //2046-2049
SP_SKILL_COOLDOWN,SP_SKILL_FIXEDCAST, SP_SKILL_VARIABLECAST, SP_FIXCASTRATE, SP_VARCASTRATE, //2050-2054
- SP_SKILL_USE_SP,SP_MAGIC_ATK_ELE, SP_ADD_FIXEDCAST, SP_ADD_VARIABLECAST //2055-2058
+ SP_SKILL_USE_SP,SP_MAGIC_ATK_ELE, SP_ADD_FIXEDCAST, SP_ADD_VARIABLECAST, //2055-2058
+
+
+ /* must be the last, plugins add bonuses from this value onwards */
+ SP_LAST_KNOWN,
};
enum _look {
@@ -553,6 +557,17 @@ struct map_drop_list {
int drop_per;
};
+
+struct questinfo {
+ struct npc_data *nd;
+ unsigned short icon;
+ unsigned char color;
+ int quest_id;
+ bool hasJob;
+ unsigned short job;/* perhaps a mapid mask would be most flexible? */
+};
+
+
struct map_data {
char name[MAP_NAME_LENGTH];
uint16 index; // The map index used by the mapindex* functions.
@@ -628,6 +643,7 @@ struct map_data {
unsigned chsysnolocalaj : 1;
unsigned noknockback : 1;
unsigned notomb : 1;
+ unsigned nocashshop : 1;
} flag;
struct point save;
struct npc_data *npc[MAX_NPC_PER_MAP];
@@ -686,6 +702,13 @@ struct map_data {
int (*getcellp)(struct map_data* m,int16 x,int16 y,cell_chk cellchk);
void (*setcell) (int16 m, int16 x, int16 y, cell_t cell, bool flag);
char *cellPos;
+
+ /* ShowEvent Data Cache */
+ struct questinfo *qi_data;
+ unsigned short qi_count;
+
+ /* speeds up clif_updatestatus processing by causing hpmeter to run only when someone with the permission can view it */
+ unsigned short hpmeter_visible;
};
/// Stores information about a remote map (for multi-mapserver setups).
@@ -854,6 +877,10 @@ struct map_interface {
/* [Ind/Hercules] */
struct eri *iterator_ers;
char *cache_buffer; // Has the uncompressed gat data of all maps, so just one allocation has to be made
+ /* */
+ struct eri *flooritem_ers;
+ /* */
+ int bonus_id;
/* funcs */
void (*zone_init) (void);
void (*zone_remove) (int m);
@@ -876,7 +903,7 @@ struct map_interface {
// blocklist manipulation
int (*addblock) (struct block_list* bl);
int (*delblock) (struct block_list* bl);
- int (*moveblock) (struct block_list *bl, int x1, int y1, unsigned int tick);
+ int (*moveblock) (struct block_list *bl, int x1, int y1, int64 tick);
//blocklist nb in one cell
int (*count_oncell) (int16 m,int16 x,int16 y,int type);
struct skill_unit * (*find_skill_unit_oncell) (struct block_list* target,int16 x,int16 y,uint16 skill_id,struct skill_unit* out_unit, int flag);
@@ -888,8 +915,8 @@ struct map_interface {
// npc
bool (*addnpc) (int16 m,struct npc_data *nd);
// map item
- int (*clearflooritem_timer) (int tid, unsigned int tick, int id, intptr_t data);
- int (*removemobs_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*clearflooritem_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*removemobs_timer) (int tid, int64 tick, int id, intptr_t data);
void (*clearflooritem) (struct block_list* bl);
int (*addflooritem) (struct item *item_data,int amount,int16 m,int16 x,int16 y,int first_charid,int second_charid,int third_charid,int flags);
// player to map session
@@ -977,7 +1004,7 @@ struct map_interface {
void (*do_shutdown) (void);
- int (*freeblock_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*freeblock_timer) (int tid, int64 tick, int id, intptr_t data);
int (*searchrandfreecell) (int16 m, int16 *x, int16 *y, int stack);
int (*count_sub) (struct block_list *bl, va_list ap);
DBData (*create_charid2nick) (DBKey key, va_list args);
@@ -1020,6 +1047,9 @@ struct map_interface {
bool (*arg_next_value) (const char *option, int i, int argc);
void (*addblcell) (struct block_list *bl);
void (*delblcell) (struct block_list *bl);
+ int (*get_new_bonus_id) (void);
+ void (*add_questinfo) (int m, struct questinfo *qi);
+ bool (*remove_questinfo) (int m, struct npc_data *nd);
};
struct map_interface *map;
diff --git a/src/map/mapreg.h b/src/map/mapreg.h
index 3c1d0ba0e..c8f229cef 100644
--- a/src/map/mapreg.h
+++ b/src/map/mapreg.h
@@ -34,7 +34,7 @@ struct mapreg_interface {
bool (*setregstr) (int uid, const char *str);
void (*load) (void);
void (*save) (void);
- int (*save_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*save_timer) (int tid, int64 tick, int id, intptr_t data);
void (*reload) (void);
bool (*config_read) (const char *w1, const char *w2);
};
diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c
index 902b7c39b..c94e42d5d 100644
--- a/src/map/mapreg_sql.c
+++ b/src/map/mapreg_sql.c
@@ -228,7 +228,7 @@ void script_save_mapreg(void) {
}
}
-int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr_t data) {
+int script_autosave_mapreg(int tid, int64 tick, int id, intptr_t data) {
mapreg->save();
return 0;
}
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index 8b8353f46..8c74a5e1e 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -94,7 +94,7 @@ int mercenary_get_lifetime(struct mercenary_data *md)
return 0;
td = timer->get(md->contract_timer);
- return (td != NULL) ? DIFF_TICK(td->tick, timer->gettick()) : 0;
+ return (td != NULL) ? DIFF_TICK32(td->tick, timer->gettick()) : 0;
}
int mercenary_get_guild(struct mercenary_data *md)
@@ -217,7 +217,7 @@ int mercenary_save(struct mercenary_data *md)
return 1;
}
-int merc_contract_end_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int merc_contract_end_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd;
struct mercenary_data *md;
diff --git a/src/map/mercenary.h b/src/map/mercenary.h
index 47f37ac66..3245606cf 100644
--- a/src/map/mercenary.h
+++ b/src/map/mercenary.h
@@ -43,7 +43,7 @@ struct mercenary_data {
int contract_timer;
unsigned devotion_flag : 1;
- unsigned int masterteleport_timer;
+ int64 masterteleport_timer;
};
/*=====================================
@@ -89,7 +89,7 @@ struct mercenary_interface {
int (*killbonus) (struct mercenary_data *md);
int (*search_index) (int class_);
- int (*contract_end_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*contract_end_timer) (int tid, int64 tick, int id, intptr_t data);
bool (*read_db_sub) (char* str[], int columns, int current);
bool (*read_skill_db_sub) (char* str[], int columns, int current);
};
diff --git a/src/map/mob.c b/src/map/mob.c
index 7023bcb9d..97f8ea6c1 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -332,8 +332,7 @@ int mob_get_random_id(int type, int flag, int lv)
/*==========================================
* Kill Steal Protection [Zephyrus]
*------------------------------------------*/
-bool mob_ksprotected (struct block_list *src, struct block_list *target)
-{
+bool mob_ksprotected(struct block_list *src, struct block_list *target) {
struct block_list *s_bl, *t_bl;
struct map_session_data
*sd, // Source
@@ -341,7 +340,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target)
*t_sd; // Mob Target
struct status_change_entry *sce;
struct mob_data *md;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
char output[128];
if( !battle_config.ksprotection )
@@ -559,8 +558,8 @@ int mob_once_spawn_area(struct map_session_data* sd, int16 m, int16 x0, int16 y0
/*==========================================
* Set a Guardian's guild data [Skotlex]
*------------------------------------------*/
-int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data)
-{ //Needed because the guild_data may not be available at guardian spawn time.
+int mob_spawn_guardian_sub(int tid, int64 tick, int id, intptr_t data) {
+ //Needed because the guild_data may not be available at guardian spawn time.
struct block_list* bl = map->id2bl(id);
struct mob_data* md;
struct guild* g;
@@ -779,18 +778,17 @@ int mob_can_reach(struct mob_data *md,struct block_list *bl,int range, int state
/*==========================================
* Links nearby mobs (supportive mobs)
*------------------------------------------*/
-int mob_linksearch(struct block_list *bl,va_list ap)
-{
+int mob_linksearch(struct block_list *bl,va_list ap) {
struct mob_data *md;
int class_;
struct block_list *target;
- unsigned int tick;
+ int64 tick;
nullpo_ret(bl);
md=(struct mob_data *)bl;
class_ = va_arg(ap, int);
target = va_arg(ap, struct block_list *);
- tick=va_arg(ap, unsigned int);
+ tick = va_arg(ap, int64);
if (md->class_ == class_ && DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME
&& !md->target_id)
@@ -809,7 +807,7 @@ int mob_linksearch(struct block_list *bl,va_list ap)
/*==========================================
* mob spawn with delay (timer function)
*------------------------------------------*/
-int mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data) {
+int mob_delayspawn(int tid, int64 tick, int id, intptr_t data) {
struct block_list* bl = map->id2bl(id);
struct mob_data* md = BL_CAST(BL_MOB, bl);
@@ -884,8 +882,8 @@ int mob_count_sub(struct block_list *bl, va_list ap) {
int mob_spawn (struct mob_data *md)
{
int i=0;
- unsigned int tick = timer->gettick();
- int c =0;
+ int64 tick = timer->gettick();
+ int64 c = 0;
md->last_thinktime = tick;
if (md->bl.prev != NULL)
@@ -1185,7 +1183,7 @@ int mob_warpchase_sub(struct block_list *bl,va_list ap) {
/*==========================================
* Processing of slave monsters
*------------------------------------------*/
-int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) {
+int mob_ai_sub_hard_slavemob(struct mob_data *md, int64 tick) {
struct block_list *bl;
bl=map->id2bl(md->master_id);
@@ -1268,8 +1266,7 @@ int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) {
* when trying to pick new targets when the current chosen target is
* unreachable.
*------------------------------------------*/
-int mob_unlocktarget(struct mob_data *md, unsigned int tick)
-{
+int mob_unlocktarget(struct mob_data *md, int64 tick) {
nullpo_ret(md);
switch (md->state.skillstate) {
@@ -1308,8 +1305,7 @@ int mob_unlocktarget(struct mob_data *md, unsigned int tick)
/*==========================================
* Random walk
*------------------------------------------*/
-int mob_randomwalk(struct mob_data *md,unsigned int tick)
-{
+int mob_randomwalk(struct mob_data *md, int64 tick) {
const int retrycount=20;
int i,x,y,c,d;
int speed;
@@ -1383,8 +1379,7 @@ int mob_warpchase(struct mob_data *md, struct block_list *target)
/*==========================================
* AI of MOB whose is near a Player
*------------------------------------------*/
-bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
-{
+bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
struct block_list *tbl = NULL, *abl = NULL;
int mode;
int view_range, can_move;
@@ -1645,10 +1640,9 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
return true;
}
-int mob_ai_sub_hard_timer(struct block_list *bl,va_list ap)
-{
+int mob_ai_sub_hard_timer(struct block_list *bl, va_list ap) {
struct mob_data *md = (struct mob_data*)bl;
- unsigned int tick = va_arg(ap, unsigned int);
+ int64 tick = va_arg(ap, int64);
if (mob->ai_sub_hard(md, tick))
{ //Hard AI triggered.
if(!md->state.spotted)
@@ -1661,9 +1655,9 @@ int mob_ai_sub_hard_timer(struct block_list *bl,va_list ap)
/*==========================================
* Serious processing for mob in PC field of view (foreachclient)
*------------------------------------------*/
-int mob_ai_sub_foreachclient(struct map_session_data *sd,va_list ap) {
- unsigned int tick;
- tick=va_arg(ap,unsigned int);
+int mob_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) {
+ int64 tick;
+ tick=va_arg(ap, int64);
map->foreachinrange(mob->ai_sub_hard_timer,&sd->bl, AREA_SIZE+ACTIVE_AI_RANGE, BL_MOB,tick);
return 0;
@@ -1672,16 +1666,15 @@ int mob_ai_sub_foreachclient(struct map_session_data *sd,va_list ap) {
/*==========================================
* Negligent mode MOB AI (PC is not in near)
*------------------------------------------*/
-int mob_ai_sub_lazy(struct mob_data *md, va_list args)
-{
- unsigned int tick;
+int mob_ai_sub_lazy(struct mob_data *md, va_list args) {
+ int64 tick;
nullpo_ret(md);
if(md->bl.prev == NULL)
return 0;
- tick = va_arg(args,unsigned int);
+ tick = va_arg(args, int64);
if (battle_config.mob_ai&0x20 && map->list[md->bl.m].users>0)
return (int)mob->ai_sub_hard(md, tick);
@@ -1715,7 +1708,7 @@ int mob_ai_sub_lazy(struct mob_data *md, va_list args)
md->last_thinktime=tick;
if (md->master_id) {
- mob->ai_sub_hard_slavemob (md,tick);
+ mob->ai_sub_hard_slavemob(md,tick);
return 0;
}
@@ -1740,7 +1733,7 @@ int mob_ai_sub_lazy(struct mob_data *md, va_list args)
/*==========================================
* Negligent processing for mob outside PC field of view (interval timer function)
*------------------------------------------*/
-int mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data) {
+int mob_ai_lazy(int tid, int64 tick, int id, intptr_t data) {
map->foreachmob(mob->ai_sub_lazy,tick);
return 0;
}
@@ -1748,7 +1741,7 @@ int mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data) {
/*==========================================
* Serious processing for mob in PC field of view (interval timer function)
*------------------------------------------*/
-int mob_ai_hard(int tid, unsigned int tick, int id, intptr_t data) {
+int mob_ai_hard(int tid, int64 tick, int id, intptr_t data) {
if (battle_config.mob_ai&0x20)
map->foreachmob(mob->ai_sub_lazy,tick);
@@ -1785,8 +1778,7 @@ struct item_drop* mob_setlootitem(struct item* item)
/*==========================================
* item drop with delay (timer function)
*------------------------------------------*/
-int mob_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data)
-{
+int mob_delay_item_drop(int tid, int64 tick, int id, intptr_t data) {
struct item_drop_list *list;
struct item_drop *ditem, *ditem_prev;
list=(struct item_drop_list *)data;
@@ -1840,7 +1832,7 @@ void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, struct ite
dlist->item = ditem;
}
-int mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data) {
+int mob_timer_delete(int tid, int64 tick, int id, intptr_t data) {
struct block_list* bl = map->id2bl(id);
struct mob_data* md = BL_CAST(BL_MOB, bl);
@@ -1885,7 +1877,7 @@ int mob_deleteslave(struct mob_data *md) {
return 0;
}
// Mob respawning through KAIZEL or NPC_REBIRTH [Skotlex]
-int mob_respawn(int tid, unsigned int tick, int id, intptr_t data) {
+int mob_respawn(int tid, int64 tick, int id, intptr_t data) {
struct block_list *bl = map->id2bl(id);
if(!bl) return 0;
@@ -2069,7 +2061,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
} pt[DAMAGELOG_SIZE];
int i, temp, count, m = md->bl.m, pnum = 0;
int dmgbltypes = 0; // bitfield of all bl types, that caused damage to the mob and are elligible for exp distribution
- unsigned int mvp_damage, tick = timer->gettick();
+ unsigned int mvp_damage;
+ int64 tick = timer->gettick();
bool rebirth, homkillonly;
mstatus = &md->status;
@@ -2610,7 +2603,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) {
void mob_revive(struct mob_data *md, unsigned int hp)
{
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
md->state.skillstate = MSS_IDLE;
md->last_thinktime = tick;
md->next_walktime = tick+rnd()%50+5000;
@@ -2695,8 +2688,8 @@ int mob_random_class (int *value, size_t count)
*------------------------------------------*/
int mob_class_change (struct mob_data *md, int class_)
{
- unsigned int tick = timer->gettick();
- int i, c, hp_rate;
+ int64 tick = timer->gettick(), c = 0;
+ int i, hp_rate;
nullpo_ret(md);
@@ -3032,8 +3025,7 @@ struct mob_data *mob_getfriendstatus(struct mob_data *md,int cond1,int cond2) {
/*==========================================
* Skill use judging
*------------------------------------------*/
-int mobskill_use(struct mob_data *md, unsigned int tick, int event)
-{
+int mobskill_use(struct mob_data *md, int64 tick, int event) {
struct mob_skill *ms;
struct block_list *fbl = NULL; //Friend bl, which can either be a BL_PC or BL_MOB depending on the situation. [Skotlex]
struct block_list *bl;
@@ -3249,8 +3241,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event)
/*==========================================
* Skill use event processing
*------------------------------------------*/
-int mobskill_event(struct mob_data *md, struct block_list *src, unsigned int tick, int flag)
-{
+int mobskill_event(struct mob_data *md, struct block_list *src, int64 tick, int flag) {
int target_id, res = 0;
if(md->bl.prev == NULL || md->status.hp <= 0)
@@ -3487,7 +3478,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons
{
if( md->deletetimer != INVALID_TIMER )
timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (timer->gettick() + duration, mob->timer_delete, md->bl.id, 0);
+ md->deletetimer = timer->add(timer->gettick() + duration, mob->timer_delete, md->bl.id, 0);
}
}
diff --git a/src/map/mob.h b/src/map/mob.h
index 210983675..2f425e285 100644
--- a/src/map/mob.h
+++ b/src/map/mob.h
@@ -166,7 +166,7 @@ struct mob_data {
int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs)
unsigned int bg_id; // BattleGround System
- unsigned int next_walktime,last_thinktime,last_linktime,last_pcneartime,dmgtick;
+ int64 next_walktime, last_thinktime, last_linktime, last_pcneartime, dmgtick;
short move_fail_count;
short lootitem_count;
short min_chase;
@@ -175,7 +175,7 @@ struct mob_data {
int master_id,master_dist;
int8 skill_idx;// key of array
- unsigned int skilldelay[MAX_MOBSKILL];
+ int64 skilldelay[MAX_MOBSKILL];
char npc_event[EVENT_NAME_LENGTH];
/**
* Did this monster summon something?
@@ -266,7 +266,7 @@ struct mob_interface {
struct mob_db* (*db) (int index);
struct mob_chat* (*chat) (short id);
int (*makedummymobdb) (int);
- int (*spawn_guardian_sub) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*spawn_guardian_sub) (int tid, int64 tick, int id, intptr_t data);
int (*skill_id2skill_idx) (int class_, uint16 skill_id);
int (*db_searchname) (const char *str);
int (*db_searchname_array_sub) (struct mob_db *mob, const char *str, int flag);
@@ -287,7 +287,7 @@ struct mob_interface {
int (*spawn_bg) (const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id);
int (*can_reach) (struct mob_data *md, struct block_list *bl, int range, int state);
int (*linksearch) (struct block_list *bl, va_list ap);
- int (*delayspawn) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*delayspawn) (int tid, int64 tick, int id, intptr_t data);
int (*setdelayspawn) (struct mob_data *md);
int (*count_sub) (struct block_list *bl, va_list ap);
int (*spawn) (struct mob_data *md);
@@ -298,24 +298,24 @@ struct mob_interface {
int (*ai_sub_hard_bg_ally) (struct block_list *bl, va_list ap);
int (*ai_sub_hard_lootsearch) (struct block_list *bl, va_list ap);
int (*warpchase_sub) (struct block_list *bl, va_list ap);
- int (*ai_sub_hard_slavemob) (struct mob_data *md, unsigned int tick);
- int (*unlocktarget) (struct mob_data *md, unsigned int tick);
- int (*randomwalk) (struct mob_data *md, unsigned int tick);
+ int (*ai_sub_hard_slavemob) (struct mob_data *md, int64 tick);
+ int (*unlocktarget) (struct mob_data *md, int64 tick);
+ int (*randomwalk) (struct mob_data *md, int64 tick);
int (*warpchase) (struct mob_data *md, struct block_list *target);
- bool (*ai_sub_hard) (struct mob_data *md, unsigned int tick);
+ bool (*ai_sub_hard) (struct mob_data *md, int64 tick);
int (*ai_sub_hard_timer) (struct block_list *bl, va_list ap);
int (*ai_sub_foreachclient) (struct map_session_data *sd, va_list ap);
int (*ai_sub_lazy) (struct mob_data *md, va_list args);
- int (*ai_lazy) (int tid, unsigned int tick, int id, intptr_t data);
- int (*ai_hard) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*ai_lazy) (int tid, int64 tick, int id, intptr_t data);
+ int (*ai_hard) (int tid, int64 tick, int id, intptr_t data);
struct item_drop* (*setdropitem) (int nameid, int qty, struct item_data *data);
struct item_drop* (*setlootitem) (struct item *item);
- int (*delay_item_drop) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*delay_item_drop) (int tid, int64 tick, int id, intptr_t data);
void (*item_drop) (struct mob_data *md, struct item_drop_list *dlist, struct item_drop *ditem, int loot, int drop_rate, unsigned short flag);
- int (*timer_delete) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*timer_delete) (int tid, int64 tick, int id, intptr_t data);
int (*deleteslave_sub) (struct block_list *bl, va_list ap);
int (*deleteslave) (struct mob_data *md);
- int (*respawn) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*respawn) (int tid, int64 tick, int id, intptr_t data);
void (*log_damage) (struct mob_data *md, struct block_list *src, int damage);
void (*damage) (struct mob_data *md, struct block_list *src, int damage);
int (*dead) (struct mob_data *md, struct block_list *src, int type);
@@ -334,8 +334,8 @@ struct mob_interface {
struct block_list* (*getmasterhpltmaxrate) (struct mob_data *md, int rate);
int (*getfriendstatus_sub) (struct block_list *bl, va_list ap);
struct mob_data* (*getfriendstatus) (struct mob_data *md, int cond1, int cond2);
- int (*skill_use) (struct mob_data *md, unsigned int tick, int event);
- int (*skill_event) (struct mob_data *md, struct block_list *src, unsigned int tick, int flag);
+ int (*skill_use) (struct mob_data *md, int64 tick, int event);
+ int (*skill_event) (struct mob_data *md, struct block_list *src, int64 tick, int flag);
int (*is_clone) (int class_);
int (*clone_spawn) (struct map_session_data *sd, int16 m, int16 x, int16 y, const char *event, int master_id, int mode, int flag, unsigned int duration);
int (*clone_delete) (struct mob_data *md);
diff --git a/src/map/npc.c b/src/map/npc.c
index c52dce325..f0bdd7bd0 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -215,7 +215,7 @@ struct npc_data* npc_name2id(const char* name)
/**
* Timer to check for idle time and timeout the dialog if necessary
**/
-int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int npc_rr_secure_timeout_timer(int tid, int64 tick, int id, intptr_t data) {
#ifdef SECURE_NPCTIMEOUT
struct map_session_data* sd = NULL;
unsigned int timeout = NPC_SECURE_TIMEOUT_NEXT;
@@ -394,8 +394,7 @@ int npc_event_doall(const char* name)
* Clock event execution
* OnMinute/OnClock/OnHour/OnDay/OnDDHHMM
*------------------------------------------*/
-int npc_event_do_clock(int tid, unsigned int tick, int id, intptr_t data)
-{
+int npc_event_do_clock(int tid, int64 tick, int id, intptr_t data) {
static struct tm ev_tm_b; // tracks previous execution time
time_t clock;
struct tm* t;
@@ -493,9 +492,9 @@ struct timer_event_data {
/*==========================================
* triger 'OnTimerXXXX' events
*------------------------------------------*/
-int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data) {
+int npc_timerevent(int tid, int64 tick, int id, intptr_t data) {
int old_rid, old_timer;
- unsigned int old_tick;
+ int64 old_tick;
struct npc_data* nd=(struct npc_data *)map->id2bl(id);
struct npc_timerevent_list *te;
struct timer_event_data *ted = (struct timer_event_data*)data;
@@ -529,8 +528,7 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data) {
ted->next++;
if( nd->u.scr.timeramount > ted->next )
{
- int next;
- next = nd->u.scr.timer_event[ ted->next ].timer - nd->u.scr.timer_event[ ted->next - 1 ].timer;
+ int next = nd->u.scr.timer_event[ ted->next ].timer - nd->u.scr.timer_event[ ted->next - 1 ].timer;
ted->time += next;
if( sd )
sd->npc_timer_id = timer->add(tick+next,npc->timerevent,id,(intptr_t)ted);
@@ -564,7 +562,7 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data) {
*------------------------------------------*/
int npc_timerevent_start(struct npc_data* nd, int rid) {
int j;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
struct map_session_data *sd = NULL; //Player to whom script is attached.
nullpo_ret(nd);
@@ -642,7 +640,7 @@ int npc_timerevent_stop(struct npc_data* nd)
if( !sd && nd->u.scr.timertick )
{
- nd->u.scr.timer += DIFF_TICK(timer->gettick(),nd->u.scr.timertick); // Set 'timer' to the time that has passed since the beginning of the timers
+ nd->u.scr.timer += DIFF_TICK32(timer->gettick(),nd->u.scr.timertick); // Set 'timer' to the time that has passed since the beginning of the timers
nd->u.scr.timertick = 0; // Set 'tick' to zero so that we know it's off.
}
@@ -688,7 +686,7 @@ void npc_timerevent_quit(struct map_session_data* sd)
if( ev )
{
int old_rid,old_timer;
- unsigned int old_tick;
+ int64 old_tick;
//Set timer related info.
old_rid = (nd->u.scr.rid == sd->bl.id ? 0 : nd->u.scr.rid); // Detach rid if the last attached player logged off.
@@ -715,9 +713,8 @@ void npc_timerevent_quit(struct map_session_data* sd)
* Get the tick value of an NPC timer
* If it's stopped, return stopped time
*------------------------------------------*/
-int npc_gettimerevent_tick(struct npc_data* nd)
-{
- int tick;
+int64 npc_gettimerevent_tick(struct npc_data* nd) {
+ int64 tick;
nullpo_ret(nd);
// TODO: Get player attached timer's tick. Now we can just get it by using 'getnpctimer' inside OnTimer event.
@@ -1790,6 +1787,9 @@ int npc_unload(struct npc_data* nd, bool single) {
aFree(nd->path);/* remove now that no other instances exist */
}
}
+
+ if( single && nd->bl.m != -1 )
+ map->remove_questinfo(nd->bl.m,nd);
if( (nd->subtype == SHOP || nd->subtype == CASHSHOP) && nd->src_id == 0) //src check for duplicate shops [Orcao]
aFree(nd->u.shop.shop_item);
@@ -2013,6 +2013,53 @@ void npc_parsename(struct npc_data* nd, const char* name, const char* start, con
}
}
+// Parse View
+// Support for using Constants in place of NPC View IDs.
+int npc_parseview(const char* w4, const char* start, const char* buffer, const char* filepath) {
+ int val = -1, i = 0;
+ char viewid[1024]; // Max size of name from const.txt, see script->read_constdb.
+
+ // Extract view ID / constant
+ while (w4[i] != '\0') {
+ if (isspace(w4[i]) || w4[i] == '/' || w4[i] == ',')
+ break;
+
+ i++;
+ }
+
+ safestrncpy(viewid, w4, i+=1);
+
+ // Check if view id is not an ID (only numbers).
+ if(!npc->viewisid(viewid))
+ {
+ // Check if constant exists and get its value.
+ if(!script->get_constant(viewid, &val)) {
+ ShowWarning("npc_parseview: Invalid NPC constant '%s' specified in file '%s', line'%d'. Defaulting to INVISIBLE_CLASS. \n", viewid, filepath, strline(buffer,start-buffer));
+ val = INVISIBLE_CLASS;
+ }
+ } else {
+ // NPC has an ID specified for view id.
+ val = atoi(w4);
+ }
+
+ return val;
+}
+
+// View is ID
+// Checks if given view is an ID or constant.
+bool npc_viewisid(const char * viewid)
+{
+ if(atoi(viewid) != -1)
+ {
+ // Loop through view, looking for non-numeric character.
+ while (*viewid) {
+ if (isdigit(*viewid++) == 0) return false;
+ }
+ }
+
+ return true;
+}
+
//Add then display an npc warp on map
struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y) {
int i, flag = 0;
@@ -2220,7 +2267,7 @@ const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* s
nd->bl.y = y;
nd->bl.id = npc->get_new_npc_id();
npc->parsename(nd, w3, start, buffer, filepath);
- nd->class_ = m==-1?-1:atoi(w4);
+ nd->class_ = m == -1 ? -1 : npc->parseview(w4, start, buffer, filepath);
nd->speed = 200;
++npc_shop;
@@ -2335,7 +2382,7 @@ const char* npc_skip_script(const char* start, const char* buffer, const char* f
/// <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,{<code>}
/// <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>,{<code>}
const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath, bool runOnInit) {
- int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov
+ int x, y, dir = 0, m, xs = 0, ys = 0; // [Valaris] thanks to fov
char mapname[32];
struct script_code *scriptroot;
int i;
@@ -2383,14 +2430,13 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char*
CREATE(nd, struct npc_data, 1);
- if( sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3 )
+ if( sscanf(w4, "%*[^,],%d,%d", &xs, &ys) == 2 )
{// OnTouch area defined
nd->u.scr.xs = xs;
nd->u.scr.ys = ys;
}
else
{// no OnTouch area
- class_ = atoi(w4);
nd->u.scr.xs = -1;
nd->u.scr.ys = -1;
}
@@ -2401,7 +2447,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char*
nd->bl.y = y;
npc->parsename(nd, w3, start, buffer, filepath);
nd->bl.id = npc->get_new_npc_id();
- nd->class_ = class_;
+ nd->class_ = m == -1 ? -1 : npc->parseview(w4, start, buffer, filepath);
nd->speed = 200;
nd->u.scr.script = scriptroot;
nd->u.scr.label_list = label_list;
@@ -2417,7 +2463,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char*
nd->dir = dir;
npc->setcells(nd);
map->addblock(&nd->bl);
- if( class_ >= 0 ) {
+ if( nd->class_ >= 0 ) {
status->set_viewdata(&nd->bl, nd->class_);
if( map->list[nd->bl.m].users )
clif->spawn(&nd->bl);
@@ -2465,7 +2511,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char*
/// npc: <map name>,<x>,<y>,<facing>%TAB%duplicate(<name of target>)%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>
const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
{
- int x, y, dir, m, xs = -1, ys = -1, class_ = 0;
+ int x, y, dir, m, xs = -1, ys = -1;
char mapname[32];
char srcname[128];
int i;
@@ -2515,9 +2561,8 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
}
if( type == WARP && sscanf(w4, "%d,%d", &xs, &ys) == 2 );// <spanx>,<spany>
- else if( type == SCRIPT && sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3);// <sprite id>,<triggerX>,<triggerY>
- else if( type != WARP ) class_ = atoi(w4);// <sprite id>
- else {
+ else if( type == SCRIPT && sscanf(w4, "%*d,%d,%d", &xs, &ys) == 2);// <sprite id>,<triggerX>,<triggerY>
+ else if( type == WARP ) {
ShowError("npc_parse_duplicate: Invalid span format for duplicate warp in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
return end;// next line, try to continue
}
@@ -2530,7 +2575,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
nd->bl.y = y;
npc->parsename(nd, w3, start, buffer, filepath);
nd->bl.id = npc->get_new_npc_id();
- nd->class_ = class_;
+ nd->class_ = m == -1 ? -1 : npc->parseview(w4, start, buffer, filepath);
nd->speed = 200;
nd->src_id = src_id;
nd->bl.type = BL_NPC;
@@ -2573,7 +2618,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
nd->dir = dir;
npc->setcells(nd);
map->addblock(&nd->bl);
- if( class_ >= 0 ) {
+ if( nd->class_ >= 0 ) {
status->set_viewdata(&nd->bl, nd->class_);
if( map->list[nd->bl.m].users )
clif->spawn(&nd->bl);
@@ -3439,6 +3484,10 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
map->list[m].short_damage_rate = (state) ? atoi(w4) : 100;
} else if ( !strcmpi(w3,"long_damage_rate") ) {
map->list[m].long_damage_rate = (state) ? atoi(w4) : 100;
+ } else if ( !strcmpi(w3,"src4instance") ) {
+ map->list[m].flag.src4instance = (state) ? 1 : 0;
+ } else if ( !strcmpi(w3,"nocashshop") ) {
+ map->list[m].flag.nocashshop = (state) ? 1 : 0;
} else
ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer));
@@ -3784,10 +3833,8 @@ int npc_reload(void) {
npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
itemdb->name_constants();
-
- for(i = 0; i < instance->instances; i++) {
- instance->destroy(i);
- }
+
+ instance->reload();
map->zone_init();
@@ -4043,6 +4090,8 @@ void npc_defaults(void) {
npc->addsrcfile = npc_addsrcfile;
npc->delsrcfile = npc_delsrcfile;
npc->parsename = npc_parsename;
+ npc->parseview = npc_parseview;
+ npc->viewisid = npc_viewisid;
npc->add_warp = npc_add_warp;
npc->parse_warp = npc_parse_warp;
npc->parse_shop = npc_parse_shop;
diff --git a/src/map/npc.h b/src/map/npc.h
index f809cb19c..5ec201e55 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -35,7 +35,7 @@ struct npc_data {
char exname[NAME_LENGTH+1];// unique npc name
int chat_id;
int touching_id;
- unsigned int next_walktime;
+ int64 next_walktime;
uint8 dir;
unsigned size : 2;
@@ -54,7 +54,7 @@ struct npc_data {
short xs,ys; // OnTouch area radius
int guild_id;
int timer,timerid,timeramount,rid;
- unsigned int timertick;
+ int64 timertick;
struct npc_timerevent_list *timer_event;
int label_list_num;
struct npc_label_list *label_list;
@@ -92,7 +92,7 @@ enum actor_classes {
#define MAX_NPC_CLASS 1000
// New NPC range
#define MAX_NPC_CLASS2_START 10000
-#define MAX_NPC_CLASS2_END 10049
+#define MAX_NPC_CLASS2_END 10070
//Checks if a given id is a valid npc id. [Skotlex]
//Since new npcs are added all the time, the max valid value is the one before the first mob (Scorpion = 1001)
@@ -160,14 +160,14 @@ struct npc_interface {
int (*event_do) (const char *name);
int (*event_doall_id) (const char *name, int rid);
int (*event_doall) (const char *name);
- int (*event_do_clock) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*event_do_clock) (int tid, int64 tick, int id, intptr_t data);
void (*event_do_oninit) (void);
int (*timerevent_export) (struct npc_data *nd, int i);
- int (*timerevent) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*timerevent) (int tid, int64 tick, int id, intptr_t data);
int (*timerevent_start) (struct npc_data *nd, int rid);
int (*timerevent_stop) (struct npc_data *nd);
void (*timerevent_quit) (struct map_session_data *sd);
- int (*gettimerevent_tick) (struct npc_data *nd);
+ int64 (*gettimerevent_tick) (struct npc_data *nd);
int (*settimerevent_tick) (struct npc_data *nd, int newtimer);
int (*event) (struct map_session_data *sd, const char *eventname, int ontouch);
int (*touch_areanpc_sub) (struct block_list *bl, va_list ap);
@@ -197,6 +197,8 @@ struct npc_interface {
void (*addsrcfile) (const char *name);
void (*delsrcfile) (const char *name);
void (*parsename) (struct npc_data *nd, const char *name, const char *start, const char *buffer, const char *filepath);
+ int (*parseview) (const char *w4, const char *start, const char *buffer, const char *filepath);
+ bool (*viewisid) (const char *viewid);
struct npc_data* (*add_warp) (char *name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y);
const char* (*parse_warp) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
const char* (*parse_shop) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
@@ -229,7 +231,7 @@ struct npc_interface {
/**
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
**/
- int (*secure_timeout_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*secure_timeout_timer) (int tid, int64 tick, int id, intptr_t data);
};
struct npc_interface *npc;
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 9d7282c92..813aebee0 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -9,12 +9,6 @@
#include "../common/mmo.h"
/**
- * structs for data
- */
-struct EQUIPSLOTINFO {
- unsigned short card[4];
-};
-/**
*
**/
enum packet_headers {
@@ -111,12 +105,161 @@ enum packet_headers {
#else
dropflooritemType = 0x9e,
#endif
+#if PACKETVER >= 20120925
+ inventorylistnormalType = 0x991,
+#elif PACKETVER >= 20080102
+ inventorylistnormalType = 0x2e8,
+#elif PACKETVER >= 20071002
+ inventorylistnormalType = 0x1ee,
+#else
+ inventorylistnormalType = 0xa3,
+#endif
+#if PACKETVER >= 20120925
+ inventorylistequipType = 0x992,
+#elif PACKETVER >= 20080102
+ inventorylistequipType = 0x2d0,
+#elif PACKETVER >= 20071002
+ inventorylistequipType = 0x295,
+#else
+ inventorylistequipType = 0xa4,
+#endif
+#if PACKETVER >= 20120925
+ storagelistnormalType = 0x995,
+#elif PACKETVER >= 20080102
+ storagelistnormalType = 0x2ea,
+#elif PACKETVER >= 20071002
+ storagelistnormalType = 0x295,
+#else
+ storagelistnormalType = 0xa5,
+#endif
+#if PACKETVER >= 20120925
+ storagelistequipType = 0x996,
+#elif PACKETVER >= 20080102
+ storagelistequipType = 0x2d1,
+#elif PACKETVER >= 20071002
+ storagelistequipType = 0x296,
+#else
+ storagelistequipType = 0xa6,
+#endif
+#if PACKETVER >= 20120925
+ cartlistnormalType = 0x993,
+#elif PACKETVER >= 20080102
+ cartlistnormalType = 0x2e9,
+#elif PACKETVER >= 20071002
+ cartlistnormalType = 0x1ef,
+#else
+ cartlistnormalType = 0x123,
+#endif
+#if PACKETVER >= 20120925
+ cartlistequipType = 0x994,
+#elif PACKETVER >= 20080102
+ cartlistequipType = 0x2d2,
+#elif PACKETVER >= 20071002
+ cartlistequipType = 0x297,
+#else
+ cartlistequipType = 0x122,
+#endif
+#if PACKETVER >= 20120925
+ equipitemType = 0x998,
+#else
+ equipitemType = 0xa9,
+#endif
+#if PACKETVER >= 20120925
+ equipitemackType = 0x999,
+#else
+ equipitemackType = 0xaa,
+#endif
+#if PACKETVER >= 20120925
+ unequipitemackType = 0x99a,
+#else
+ unequipitemackType = 0xac,
+#endif
+#if PACKETVER >= 20120925
+ viewequipackType = 0x997,
+#elif PACKETVER >= 20101124
+ viewequipackType = 0x859,
+#else
+ viewequipackType = 0x2d7,
+#endif
monsterhpType = 0x977,
maptypeproperty2Type = 0x99b,
};
#pragma pack(push, 1)
+/**
+ * structs for data
+ */
+struct EQUIPSLOTINFO {
+ unsigned short card[4];
+} __attribute__((packed));
+
+struct NORMALITEM_INFO {
+ short index;
+ unsigned short ITID;
+ unsigned char type;
+#if PACKETVER < 20120925
+ uint8 IsIdentified;
+#endif
+ short count;
+#if PACKETVER >= 20120925
+ unsigned int WearState;
+#else
+ unsigned short WearState;
+#endif
+#if PACKETVER >= 5
+ struct EQUIPSLOTINFO slot;
+#endif
+#if PACKETVER >= 20080102
+ int HireExpireDate;
+#endif
+#if PACKETVER >= 20120925
+ struct {
+ unsigned char IsIdentified : 1;
+ unsigned char PlaceETCTab : 1;
+ unsigned char SpareBits : 6;
+ } Flag;
+#endif
+} __attribute__((packed));
+
+struct EQUIPITEM_INFO {
+ short index;
+ unsigned short ITID;
+ unsigned char type;
+#if PACKETVER < 20120925
+ uint8 IsIdentified;
+#endif
+#if PACKETVER >= 20120925
+ unsigned int location;
+ unsigned int WearState;
+#else
+ unsigned short location;
+ unsigned short WearState;
+#endif
+#if PACKETVER < 20120925
+ uint8 IsDamaged;
+#endif
+ unsigned char RefiningLevel;
+ struct EQUIPSLOTINFO slot;
+#if PACKETVER >= 20071002
+ int HireExpireDate;
+#endif
+#if PACKETVER >= 20080102
+ unsigned short bindOnEquipType;
+#endif
+#if PACKETVER >= 20100629
+ unsigned short wItemSpriteNumber;
+#endif
+#if PACKETVER >= 20120925
+ struct {
+ unsigned char IsIdentified : 1;
+ unsigned char IsDamaged : 1;
+ unsigned char PlaceETCTab : 1;
+ unsigned char SpareBits : 5;
+ } Flag;
+#endif
+} __attribute__((packed));
+
struct packet_authok {
short PacketType;
unsigned int startTime;
@@ -147,8 +290,8 @@ struct packet_additem {
unsigned short Index;
unsigned short count;
unsigned short nameid;
- bool IsIdentified;
- bool IsDamaged;
+ uint8 IsIdentified;
+ uint8 IsDamaged;
unsigned char refiningLevel;
struct EQUIPSLOTINFO slot;
#if PACKETVER >= 20120925
@@ -173,7 +316,7 @@ struct packet_dropflooritem {
#if PACKETVER >= 20130000 /* not sure date */
unsigned short type;
#endif
- bool IsIdentified;
+ uint8 IsIdentified;
short xPos;
short yPos;
unsigned char subX;
@@ -205,7 +348,7 @@ struct packet_idle_unit2 {
short GEmblemVer;
short honor;
short virtue;
- bool isPKModeON;
+ uint8 isPKModeON;
unsigned char sex;
unsigned char PosDir[3];
unsigned char xSize;
@@ -233,7 +376,7 @@ struct packet_spawn_unit2 {
short headpalette;
short bodypalette;
short headDir;
- bool isPKModeON;
+ uint8 isPKModeON;
unsigned char sex;
unsigned char PosDir[3];
unsigned char xSize;
@@ -282,7 +425,7 @@ struct packet_spawn_unit {
#else
short virtue;
#endif
- bool isPKModeON;
+ uint8 isPKModeON;
unsigned char sex;
unsigned char PosDir[3];
unsigned char xSize;
@@ -343,7 +486,7 @@ struct packet_unit_walking {
#else
short virtue;
#endif
- bool isPKModeON;
+ uint8 isPKModeON;
unsigned char sex;
unsigned char MoveData[6];
unsigned char xSize;
@@ -401,7 +544,7 @@ struct packet_idle_unit {
#else
short virtue;
#endif
- bool isPKModeON;
+ uint8 isPKModeON;
unsigned char sex;
unsigned char PosDir[3];
unsigned char xSize;
@@ -578,6 +721,90 @@ struct packet_banking_withdraw_ack {
int Balance;
} __attribute__((packed));
+struct packet_itemlist_normal {
+ short PacketType;
+ short PacketLength;
+ struct NORMALITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct packet_itemlist_equip {
+ short PacketType;
+ short PacketLength;
+ struct EQUIPITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct packet_storelist_normal {
+ short PacketType;
+ short PacketLength;
+#if PACKETVER >= 20120925
+ char name[NAME_LENGTH];
+#endif
+ struct NORMALITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct packet_storelist_equip {
+ short PacketType;
+ short PacketLength;
+#if PACKETVER >= 20120925
+ char name[NAME_LENGTH];
+#endif
+ struct EQUIPITEM_INFO list[MAX_ITEMLIST];
+} __attribute__((packed));
+
+struct packet_equip_item {
+ short PacketType;
+ unsigned short index;
+#if PACKETVER >= 20120925
+ unsigned int wearLocation;
+#else
+ unsigned short wearLocation;
+#endif
+} __attribute__((packed));
+
+struct packet_equipitem_ack {
+ short PacketType;
+ unsigned short index;
+#if PACKETVER >= 20120925
+ unsigned int wearLocation;
+#else
+ unsigned short wearLocation;
+#endif
+#if PACKETVER >= 20100629
+ unsigned short wItemSpriteNumber;
+#endif
+ unsigned char result;
+} __attribute__((packed));
+
+struct packet_unequipitem_ack {
+ short PacketType;
+ unsigned short index;
+#if PACKETVER >= 20120925
+ unsigned int wearLocation;
+#else
+ unsigned short wearLocation;
+#endif
+ unsigned char result;
+} __attribute__((packed));
+
+struct packet_viewequip_ack {
+ short PacketType;
+ short PacketLength;
+ char characterName[NAME_LENGTH];
+ short job;
+ short head;
+ short accessory;
+ short accessory2;
+ short accessory3;
+#if PACKETVER >= 20101124
+ short robe;
+#endif
+ short headpalette;
+ short bodypalette;
+ unsigned char sex;
+ struct EQUIPITEM_INFO list[MAX_INVENTORY];
+} __attribute__((packed));
+
+
#pragma pack(pop)
#endif /* _PACKETS_STRUCT_H_ */
diff --git a/src/map/party.c b/src/map/party.c
index 904110452..ab05c23f7 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -831,8 +831,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id
return 0;
}
-int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data)
-{
+int party_send_xy_timer(int tid, int64 tick, int id, intptr_t data) {
struct party_data* p;
DBIterator *iter = db_iterator(party->db);
diff --git a/src/map/party.h b/src/map/party.h
index 208edb846..ab14d1a31 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -123,7 +123,7 @@ struct party_interface {
/* */
int (*vforeachsamemap) (int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range, va_list ap);
int (*foreachsamemap) (int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range,...);
- int (*send_xy_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*send_xy_timer) (int tid, int64 tick, int id, intptr_t data);
void (*fill_member) (struct party_member* member, struct map_session_data* sd, unsigned int leader);
TBL_PC* (*sd_check) (int party_id, int account_id, int char_id);
void (*check_state) (struct party_data *p);
diff --git a/src/map/pc.c b/src/map/pc.c
index 90a3db853..d98393739 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -117,7 +117,7 @@ bool pc_should_log_commands(struct map_session_data *sd)
return pc_group_should_log_commands(sd->group);
}
-int pc_invincible_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int pc_invincible_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd;
if( (sd=(struct map_session_data *)map->id2sd(id)) == NULL || sd->bl.type!=BL_PC )
@@ -155,7 +155,7 @@ void pc_delinvincibletimer(struct map_session_data* sd)
}
}
-int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int pc_spiritball_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd;
int i;
@@ -419,7 +419,7 @@ int pc_setrestartvalue(struct map_session_data *sd,int type) {
/*==========================================
Rental System
*------------------------------------------*/
-int pc_inventory_rental_end(int tid, unsigned int tick, int id, intptr_t data) {
+int pc_inventory_rental_end(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd = map->id2sd(id);
if( sd == NULL )
return 0;
@@ -443,11 +443,78 @@ int pc_inventory_rental_clear(struct map_session_data *sd)
return 1;
}
+/* assumes i is valid (from default areas where it is called, it is) */
+void pc_rental_expire(struct map_session_data *sd, int i) {
+ short nameid = sd->status.inventory[i].nameid;
+ /* Soon to be dropped, we got plans to integrate it with item db */
+ switch( nameid ) {
+ case ITEMID_REINS_OF_MOUNT:
+ status_change_end(&sd->bl,SC_ALL_RIDING,INVALID_TIMER);
+ break;
+ case ITEMID_LOVE_ANGEL:
+ if( sd->status.font == 1 ) {
+ sd->status.font = 0;
+ clif->font(sd);
+ }
+ break;
+ case ITEMID_SQUIRREL:
+ if( sd->status.font == 2 ) {
+ sd->status.font = 0;
+ clif->font(sd);
+ }
+ break;
+ case ITEMID_GOGO:
+ if( sd->status.font == 3 ) {
+ sd->status.font = 0;
+ clif->font(sd);
+ }
+ break;
+ case ITEMID_PICTURE_DIARY:
+ if( sd->status.font == 4 ) {
+ sd->status.font = 0;
+ clif->font(sd);
+ }
+ break;
+ case ITEMID_MINI_HEART:
+ if( sd->status.font == 5 ) {
+ sd->status.font = 0;
+ clif->font(sd);
+ }
+ break;
+ case ITEMID_NEWCOMER:
+ if( sd->status.font == 6 ) {
+ sd->status.font = 0;
+ clif->font(sd);
+ }
+ break;
+ case ITEMID_KID:
+ if( sd->status.font == 7 ) {
+ sd->status.font = 0;
+ clif->font(sd);
+ }
+ break;
+ case ITEMID_MAGIC_CASTLE:
+ if( sd->status.font == 8 ) {
+ sd->status.font = 0;
+ clif->font(sd);
+ }
+ break;
+ case ITEMID_BULGING_HEAD:
+ if( sd->status.font == 9 ) {
+ sd->status.font = 0;
+ clif->font(sd);
+ }
+ break;
+ }
+
+ clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
+ pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
+}
void pc_inventory_rentals(struct map_session_data *sd)
{
int i, c = 0;
- unsigned int expire_tick, next_tick = UINT_MAX;
+ int64 expire_tick, next_tick = INT64_MAX;
for( i = 0; i < MAX_INVENTORY; i++ )
{ // Check for Rentals on Inventory
@@ -457,14 +524,9 @@ void pc_inventory_rentals(struct map_session_data *sd)
continue;
if( sd->status.inventory[i].expire_time <= time(NULL) ) {
- if( sd->status.inventory[i].nameid == ITEMID_REINS_OF_MOUNT
- && sd->sc.data[SC_ALL_RIDING] ) {
- status_change_end(&sd->bl,SC_ALL_RIDING,INVALID_TIMER);
- }
- clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
- pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER);
+ pc->rental_expire(sd,i);
} else {
- expire_tick = (unsigned int)(sd->status.inventory[i].expire_time - time(NULL)) * 1000;
+ expire_tick = (int64)(sd->status.inventory[i].expire_time - time(NULL)) * 1000;
clif->rental_time(sd->fd, sd->status.inventory[i].nameid, (int)(expire_tick / 1000));
next_tick = min(expire_tick, next_tick);
c++;
@@ -611,6 +673,8 @@ int pc_equippoint(struct map_session_data *sd,int n)
if(ep == EQP_HAND_R && (pc->checkskill(sd,AS_LEFT) > 0 || (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN ||
(sd->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO))//Kagerou and Oboro can dual wield daggers. [Rytech]
return EQP_ARMS;
+ if( ep == EQP_SHADOW_SHIELD )/* are there conditions for those? */
+ return EQP_SHADOW_WEAPON|EQP_SHADOW_SHIELD;
}
return ep;
}
@@ -927,7 +991,7 @@ int pc_isequip(struct map_session_data *sd,int n)
*------------------------------------------*/
bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers) {
int i;
- unsigned long tick = timer->gettick();
+ int64 tick = timer->gettick();
uint32 ip = session[sd->fd]->client_addr;
sd->login_id2 = login_id2;
@@ -1267,8 +1331,6 @@ int pc_reg_received(struct map_session_data *sd)
clif->pLoadEndAck(sd->fd, sd);
}
- pc->inventory_rentals(sd);
-
if( sd->sc.option & OPTION_INVISIBLE ) {
sd->vd.class_ = INVISIBLE_CLASS;
clif->message(sd->fd, msg_txt(11)); // Invisible: On
@@ -1971,7 +2033,7 @@ int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus)
return 0;
}
-int pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data) {
+int pc_endautobonus(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd = map->id2sd(id);
struct s_autobonus *autobonus = (struct s_autobonus *)data;
@@ -3927,8 +3989,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
/* rental item check */
if( item_data->expire_time ) {
if( time(NULL) > item_data->expire_time ) {
- clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
- pc->delitem(sd, i, sd->status.inventory[i].amount, 1, 0, LOG_TYPE_OTHER);
+ pc->rental_expire(sd,i);
} else {
int seconds = (int)( item_data->expire_time - time(NULL) );
clif->rental_time(sd->fd, sd->status.inventory[i].nameid, seconds);
@@ -4026,7 +4087,7 @@ int pc_dropitem(struct map_session_data *sd,int n,int amount)
int pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem)
{
int flag=0;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
struct map_session_data *first_sd = NULL,*second_sd = NULL,*third_sd = NULL;
struct party_data *p=NULL;
@@ -4276,7 +4337,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
* 1 = success
*------------------------------------------*/
int pc_useitem(struct map_session_data *sd,int n) {
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
int amount, nameid, i;
struct script_code *item_script;
@@ -4343,7 +4404,7 @@ int pc_useitem(struct map_session_data *sd,int n) {
if( i < MAX_ITEMDELAYS ) {
if( sd->item_delay[i].nameid ) {// found
if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) {
- int e_tick = DIFF_TICK(sd->item_delay[i].tick, tick)/1000;
+ int e_tick = (int)(DIFF_TICK(sd->item_delay[i].tick, tick)/1000);
clif->msgtable_num(sd->fd, 0x746, e_tick + 1); // [%d] seconds left until you can use
return 0; // Delay has not expired yet
}
@@ -4791,6 +4852,14 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
stop = true;
}
}
+ /* we hit a instance, if empty we populate the spawn data */
+ if( map->list[m].instance_id >= 0 && instance->list[map->list[m].instance_id].respawn.map == 0 &&
+ instance->list[map->list[m].instance_id].respawn.x == 0 &&
+ instance->list[map->list[m].instance_id].respawn.y == 0) {
+ instance->list[map->list[m].instance_id].respawn.map = mapindex;
+ instance->list[map->list[m].instance_id].respawn.x = x;
+ instance->list[map->list[m].instance_id].respawn.y = y;
+ }
}
sd->state.changemap = (sd->mapindex != mapindex);
@@ -5634,7 +5703,7 @@ const char* job_name(int class_)
}
}
-int pc_follow_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int pc_follow_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd;
struct block_list *tbl;
@@ -6592,7 +6661,7 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype)
clif->resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
}
-int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int pc_respawn_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd = map->id2sd(id);
if( sd != NULL )
{
@@ -6639,7 +6708,7 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h
*------------------------------------------*/
int pc_dead(struct map_session_data *sd,struct block_list *src) {
int i=0,j=0,k=0;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
for(k = 0; k < 5; k++)
if (sd->devotion[k]){
@@ -8242,7 +8311,7 @@ int pc_setregistry_str(struct map_session_data *sd,const char *reg,const char *v
/*==========================================
* Exec eventtimer for player sd (retrieved from map_session (id))
*------------------------------------------*/
-int pc_eventtimer(int tid, unsigned int tick, int id, intptr_t data) {
+int pc_eventtimer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd=map->id2sd(id);
char *p = (char *)data;
int i;
@@ -8518,13 +8587,13 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
nullpo_ret(sd);
if( n < 0 || n >= MAX_INVENTORY ) {
- clif->equipitemack(sd,0,0,0);
+ clif->equipitemack(sd,0,0,EIA_FAIL);
return 0;
}
if( DIFF_TICK(sd->canequip_tick,timer->gettick()) > 0 )
{
- clif->equipitemack(sd,n,0,0);
+ clif->equipitemack(sd,n,0,EIA_FAIL);
return 0;
}
@@ -8535,13 +8604,13 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id?id->equip:0,req_pos);
if(!pc->isequip(sd,n) || !(pos&req_pos) || sd->status.inventory[n].equip != 0 || sd->status.inventory[n].attribute==1 ) { // [Valaris]
// FIXME: pc->isequip: equip level failure uses 2 instead of 0
- clif->equipitemack(sd,n,0,0); // fail
+ clif->equipitemack(sd,n,0,EIA_FAIL); // fail
return 0;
}
if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER])
{
- clif->equipitemack(sd,n,0,0); // fail
+ clif->equipitemack(sd,n,0,EIA_FAIL); // fail
return 0;
}
@@ -8581,7 +8650,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
clif->arrow_fail(sd,3);
}
else
- clif->equipitemack(sd,n,pos,1);
+ clif->equipitemack(sd,n,pos,EIA_SUCCESS);
sd->status.inventory[n].equip=pos;
@@ -8730,20 +8799,20 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
nullpo_ret(sd);
if( n < 0 || n >= MAX_INVENTORY ) {
- clif->unequipitemack(sd,0,0,0);
+ clif->unequipitemack(sd,0,0,UIA_FAIL);
return 0;
}
// if player is berserk then cannot unequip
if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER]))
{
- clif->unequipitemack(sd,n,0,0);
+ clif->unequipitemack(sd,n,0,UIA_FAIL);
return 0;
}
if( !(flag&2) && sd->sc.count && sd->sc.data[SC_KYOUGAKU] )
{
- clif->unequipitemack(sd,n,0,0);
+ clif->unequipitemack(sd,n,0,UIA_FAIL);
return 0;
}
@@ -8751,7 +8820,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
ShowInfo("unequip %d %x:%x\n",n,pc->equippoint(sd,n),sd->status.inventory[n].equip);
if(!sd->status.inventory[n].equip){ //Nothing to unequip
- clif->unequipitemack(sd,n,0,0);
+ clif->unequipitemack(sd,n,0,UIA_FAIL);
return 0;
}
for(i=0;i<EQI_MAX;i++) {
@@ -8813,7 +8882,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe);
}
- clif->unequipitemack(sd,n,sd->status.inventory[n].equip,1);
+ clif->unequipitemack(sd,n,sd->status.inventory[n].equip,UIA_SUCCESS);
if((sd->status.inventory[n].equip & EQP_ARMS) &&
sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_TK_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!)
@@ -9003,7 +9072,7 @@ int pc_calc_pvprank(struct map_session_data *sd) {
/*==========================================
* Calculate next sd ranking calculation from config
*------------------------------------------*/
-int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int pc_calc_pvprank_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd;
sd=map->id2sd(id);
@@ -9216,10 +9285,9 @@ int pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y)
}
/*==========================================
- * Save 1 player data at autosave intervalle
+ * Save 1 player data at autosave intervall
*------------------------------------------*/
-int pc_autosave(int tid, unsigned int tick, int id, intptr_t data)
-{
+int pc_autosave(int tid, int64 tick, int id, intptr_t data) {
int interval;
struct s_mapiterator* iter;
struct map_session_data* sd;
@@ -9270,7 +9338,7 @@ int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap) {
* timer to do the day [Yor]
* data: 0 = called by timer, 1 = gmcommand/script
*------------------------------------------------*/
-int map_day_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int map_day_timer(int tid, int64 tick, int id, intptr_t data) {
char tmp_soutput[1024];
if (data == 0 && battle_config.day_duration <= 0) // if we want a day
@@ -9290,7 +9358,7 @@ int map_day_timer(int tid, unsigned int tick, int id, intptr_t data) {
* timer to do the night [Yor]
* data: 0 = called by timer, 1 = gmcommand/script
*------------------------------------------------*/
-int map_night_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int map_night_timer(int tid, int64 tick, int id, intptr_t data) {
char tmp_soutput[1024];
if (data == 0 && battle_config.night_duration <= 0) // if we want a night
@@ -9368,7 +9436,7 @@ bool pc_can_use_command(struct map_session_data *sd, const char *command) {
return atcommand->can_use(sd,command);
}
-int pc_charm_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int pc_charm_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd;
int i, type;
@@ -10129,6 +10197,10 @@ void pc_bank_withdraw(struct map_session_data *sd, int money) {
clif->bank_withdraw(sd,BWA_SUCCESS);
}
}
+/* status change data arrived from char-server */
+void pc_scdata_received(struct map_session_data *sd) {
+ pc->inventory_rentals(sd);
+}
/*==========================================
* pc Init/Terminate
@@ -10191,7 +10263,7 @@ void pc_defaults(void) {
{ SG_MOON_ANGER, SG_MOON_BLESS, SG_MOON_COMFORT, "PC_FEEL_MOON", "PC_HATE_MOB_MOON", is_day_of_moon },
{ SG_STAR_ANGER, SG_STAR_BLESS, SG_STAR_COMFORT, "PC_FEEL_STAR", "PC_HATE_MOB_STAR", is_day_of_star }
};
- unsigned short equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARMENT,EQP_HEAD_LOW,EQP_HEAD_MID,EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_GARMENT,EQP_AMMO};
+ unsigned int equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARMENT,EQP_HEAD_LOW,EQP_HEAD_MID,EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_GARMENT,EQP_AMMO, EQP_SHADOW_ARMOR, EQP_SHADOW_WEAPON, EQP_SHADOW_SHIELD, EQP_SHADOW_SHOES, EQP_SHADOW_ACC_R, EQP_SHADOW_ACC_L };
pc = &pc_s;
@@ -10456,4 +10528,7 @@ void pc_defaults(void) {
pc->bank_withdraw = pc_bank_withdraw;
pc->bank_deposit = pc_bank_deposit;
+
+ pc->rental_expire = pc_rental_expire;
+ pc->scdata_received = pc_scdata_received;
}
diff --git a/src/map/pc.h b/src/map/pc.h
index bb7bff375..f1535941c 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -48,6 +48,12 @@ enum equip_index {
EQI_COSTUME_LOW,
EQI_COSTUME_GARMENT,
EQI_AMMO,
+ EQI_SHADOW_ARMOR,
+ EQI_SHADOW_WEAPON,
+ EQI_SHADOW_SHIELD,
+ EQI_SHADOW_SHOES,
+ EQI_SHADOW_ACC_R,
+ EQI_SHADOW_ACC_L,
EQI_MAX
};
struct weapon_data {
@@ -172,6 +178,7 @@ struct map_session_data {
unsigned int workinprogress : 3; // 1 = disable skill/item, 2 = disable npc interaction, 3 = disable both
unsigned int hold_recalc : 1;
unsigned int snovice_call_flag : 3; //Summon Angel (stage 1~3)
+ unsigned int hpmeter_visible : 1;
} state;
struct {
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
@@ -211,10 +218,10 @@ struct map_session_data {
char npc_str[CHATBOX_SIZE]; // for passing npc input box text to script engine
int npc_timer_id; //For player attached npc timers. [Skotlex]
unsigned int chatID;
- time_t idletime;
- struct{
+ int64 idletime;
+ struct {
int npc_id;
- unsigned int timeout;
+ int64 timeout;
} progressbar; //Progress Bar [Inkfish]
struct{
char name[NAME_LENGTH];
@@ -226,21 +233,21 @@ struct map_session_data {
uint16 skill_id_old,skill_lv_old;
uint16 skill_id_dance,skill_lv_dance;
short cook_mastery; // range: [0,1999] [Inkfish]
- unsigned char blockskill[MAX_SKILL];
+ bool blockskill[MAX_SKILL];
int cloneskill_id, reproduceskill_id;
int menuskill_id, menuskill_val, menuskill_val2;
int invincible_timer;
- unsigned int canlog_tick;
- unsigned int canuseitem_tick; // [Skotlex]
- unsigned int canusecashfood_tick;
- unsigned int canequip_tick; // [Inkfish]
- unsigned int cantalk_tick;
- unsigned int canskill_tick; // used to prevent abuse from no-delay ACT files
- unsigned int cansendmail_tick; // [Mail System Flood Protection]
- unsigned int ks_floodprotect_tick; // [Kill Steal Protection]
+ int64 canlog_tick;
+ int64 canuseitem_tick; // [Skotlex]
+ int64 canusecashfood_tick;
+ int64 canequip_tick; // [Inkfish]
+ int64 cantalk_tick;
+ int64 canskill_tick; /// used to prevent abuse from no-delay ACT files
+ int64 cansendmail_tick; /// Mail System Flood Protection
+ int64 ks_floodprotect_tick; /// [Kill Steal Protection]
struct {
short nameid;
- unsigned int tick;
+ int64 tick;
} item_delay[MAX_ITEMDELAYS]; // [Paradox924X]
short weapontype1,weapontype2;
short disguise; // [Valaris]
@@ -443,7 +450,6 @@ struct map_session_data {
const char* debug_func;
unsigned int bg_id;
- unsigned short user_font;
/**
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
@@ -461,7 +467,7 @@ struct map_session_data {
* @info
* - It is updated on every NPC iteration as mentioned above
**/
- unsigned int npc_idle_tick;
+ int64 npc_idle_tick;
/* */
enum npc_timeout_type npc_idle_type;
#endif
@@ -486,7 +492,7 @@ struct map_session_data {
bool stealth;
unsigned char fontcolor;
unsigned int fontcolor_tid;
- unsigned int hchsysch_tick;
+ int64 hchsysch_tick;
/* [Ind/Hercules] */
struct sc_display_entry **sc_display;
@@ -527,21 +533,28 @@ struct map_session_data {
//Equip position constants
enum equip_pos {
- EQP_HEAD_LOW = 0x0001,
- EQP_HEAD_MID = 0x0200, //512
- EQP_HEAD_TOP = 0x0100, //256
- EQP_HAND_R = 0x0002, //2
- EQP_HAND_L = 0x0020, //32
- EQP_ARMOR = 0x0010, //16
- EQP_SHOES = 0x0040, //64
- EQP_GARMENT = 0x0004, //4
- EQP_ACC_L = 0x0008, //8
- EQP_ACC_R = 0x0080, //128
- EQP_COSTUME_HEAD_TOP = 0x0400, //1024
- EQP_COSTUME_HEAD_MID = 0x0800, //2048
- EQP_COSTUME_HEAD_LOW = 0x1000, //4096
- EQP_COSTUME_GARMENT = 0x2000, //8192
- EQP_AMMO = 0x8000, //32768
+ EQP_HEAD_LOW = 0x000001,
+ EQP_HEAD_MID = 0x000200, //512
+ EQP_HEAD_TOP = 0x000100, //256
+ EQP_HAND_R = 0x000002, //2
+ EQP_HAND_L = 0x000020, //32
+ EQP_ARMOR = 0x000010, //16
+ EQP_SHOES = 0x000040, //64
+ EQP_GARMENT = 0x000004, //4
+ EQP_ACC_L = 0x000008, //8
+ EQP_ACC_R = 0x000080, //128
+ EQP_COSTUME_HEAD_TOP = 0x000400, //1024
+ EQP_COSTUME_HEAD_MID = 0x000800, //2048
+ EQP_COSTUME_HEAD_LOW = 0x001000, //4096
+ EQP_COSTUME_GARMENT = 0x002000, //8192
+ //UNUSED_COSTUME_FLOOR = 0x004000, //16384
+ EQP_AMMO = 0x008000, //32768
+ EQP_SHADOW_ARMOR = 0x010000, //65536
+ EQP_SHADOW_WEAPON = 0x020000, //131072
+ EQP_SHADOW_SHIELD = 0x040000, //262144
+ EQP_SHADOW_SHOES = 0x080000, //524288
+ EQP_SHADOW_ACC_R = 0x100000, //1048576
+ EQP_SHADOW_ACC_L = 0x200000, //2097152
};
#define EQP_WEAPON EQP_HAND_R
@@ -696,7 +709,7 @@ enum { ADDITEM_EXIST , ADDITEM_NEW , ADDITEM_OVERAMOUNT };
* All cooldowns are reset when server is restarted.
**/
struct item_cd {
- unsigned int tick[MAX_ITEMDELAYS];//tick
+ int64 tick[MAX_ITEMDELAYS];//tick
short nameid[MAX_ITEMDELAYS];//skill id
};
@@ -719,7 +732,7 @@ struct pc_interface {
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
unsigned int level_penalty[3][RC_MAX][MAX_LEVEL*2+1];
#endif
- unsigned short equip_pos[EQI_MAX];
+ unsigned int equip_pos[EQI_MAX];
/* */
struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE];
struct fame_list smith_fame_list[MAX_FAME_LIST];
@@ -797,7 +810,7 @@ struct pc_interface {
int (*addautobonus) (struct s_autobonus *bonus,char max,const char *bonus_script,short rate,unsigned int dur,short atk_type,const char *o_script,unsigned short pos,bool onskill);
int (*exeautobonus) (struct map_session_data* sd,struct s_autobonus *bonus);
- int (*endautobonus) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*endautobonus) (int tid, int64 tick, int id, intptr_t data);
int (*delautobonus) (struct map_session_data* sd,struct s_autobonus *bonus,char max,bool restore);
int (*bonus) (struct map_session_data *sd,int type,int val);
@@ -879,7 +892,7 @@ struct pc_interface {
int (*addeventtimercount) (struct map_session_data *sd,const char *name,int tick);
int (*calc_pvprank) (struct map_session_data *sd);
- int (*calc_pvprank_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*calc_pvprank_timer) (int tid, int64 tick, int id, intptr_t data);
int (*ismarried) (struct map_session_data *sd);
int (*marriage) (struct map_session_data *sd,struct map_session_data *dstsd);
@@ -910,8 +923,8 @@ struct pc_interface {
int (*set_hate_mob) (struct map_session_data *sd, int pos, struct block_list *bl);
int (*readdb) (void);
- int (*map_day_timer) (int tid, unsigned int tick, int id, intptr_t data); // by [yor]
- int (*map_night_timer) (int tid, unsigned int tick, int id, intptr_t data); // by [yor]
+ int (*map_day_timer) (int tid, int64 tick, int id, intptr_t data); // by [yor]
+ int (*map_night_timer) (int tid, int64 tick, int id, intptr_t data); // by [yor]
// Rental System
void (*inventory_rentals) (struct map_session_data *sd);
int (*inventory_rental_clear) (struct map_session_data *sd);
@@ -935,10 +948,10 @@ struct pc_interface {
int (*level_penalty_mod) (int diff, unsigned char race, unsigned short mode, int type);
int (*calc_skillpoint) (struct map_session_data* sd);
- int (*invincible_timer) (int tid, unsigned int tick, int id, intptr_t data);
- int (*spiritball_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*invincible_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*spiritball_timer) (int tid, int64 tick, int id, intptr_t data);
int (*check_banding) ( struct block_list *bl, va_list ap );
- int (*inventory_rental_end) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*inventory_rental_end) (int tid, int64 tick, int id, intptr_t data);
void (*check_skilltree) (struct map_session_data *sd, int skill_id);
int (*bonus_autospell) (struct s_autospell *spell, int max, short id, short lv, short rate, short flag, short card_id);
int (*bonus_autospell_onskill) (struct s_autospell *spell, int max, short src_skill, short id, short lv, short rate, short card_id);
@@ -946,16 +959,16 @@ struct pc_interface {
int (*bonus_addeff_onskill) (struct s_addeffectonskill* effect, int max, enum sc_type id, short rate, short skill_id, unsigned char target);
int (*bonus_item_drop) (struct s_add_drop *drop, const short max, short id, short group, int race, int rate);
void (*calcexp) (struct map_session_data *sd, unsigned int *base_exp, unsigned int *job_exp, struct block_list *src);
- int (*respawn_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*respawn_timer) (int tid, int64 tick, int id, intptr_t data);
int (*jobchange_killclone) (struct block_list *bl, va_list ap);
int (*getstat) (struct map_session_data* sd, int type);
int (*setstat) (struct map_session_data* sd, int type, int val);
- int (*eventtimer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*eventtimer) (int tid, int64 tick, int id, intptr_t data);
int (*daynight_timer_sub) (struct map_session_data *sd,va_list ap);
- int (*charm_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*charm_timer) (int tid, int64 tick, int id, intptr_t data);
bool (*readdb_levelpenalty) (char* fields[], int columns, int current);
- int (*autosave) (int tid, unsigned int tick, int id, intptr_t data);
- int (*follow_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*autosave) (int tid, int64 tick, int id, intptr_t data);
+ int (*follow_timer) (int tid, int64 tick, int id, intptr_t data);
void (*read_skill_tree) (void);
int (*isUseitem) (struct map_session_data *sd,int n);
int (*show_steal) (struct block_list *bl,va_list ap);
@@ -965,6 +978,9 @@ struct pc_interface {
void (*bank_deposit) (struct map_session_data *sd, int money);
void (*bank_withdraw) (struct map_session_data *sd, int money);
+
+ void (*rental_expire) (struct map_session_data *sd, int i);
+ void (*scdata_received) (struct map_session_data *sd);
};
struct pc_interface *pc;
diff --git a/src/map/pet.c b/src/map/pet.c
index 023059a6b..7dcf06c02 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -186,7 +186,7 @@ int pet_sc_check(struct map_session_data *sd, int type)
return 0;
}
-int pet_hungry(int tid, unsigned int tick, int id, intptr_t data) {
+int pet_hungry(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd;
struct pet_data *pd;
int interval;
@@ -656,7 +656,7 @@ int pet_equipitem(struct map_session_data *sd,int index) {
nameid = sd->status.inventory[index].nameid;
if(pd->petDB->AcceID == 0 || nameid != pd->petDB->AcceID || pd->pet.equip != 0) {
- clif->equipitemack(sd,0,0,0);
+ clif->equipitemack(sd,0,0,EIA_FAIL);
return 1;
}
@@ -666,7 +666,7 @@ int pet_equipitem(struct map_session_data *sd,int index) {
clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom);
if (battle_config.pet_equip_required) {
//Skotlex: start support timers if need
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
if (pd->s_skill && pd->s_skill->timer == INVALID_TIMER) {
if (pd->s_skill->id)
pd->s_skill->timer=timer->add(tick+pd->s_skill->delay*1000, pet->skill_support_timer, sd->bl.id, 0);
@@ -771,8 +771,7 @@ int pet_food(struct map_session_data *sd, struct pet_data *pd)
return 0;
}
-int pet_randomwalk(struct pet_data *pd,unsigned int tick)
-{
+int pet_randomwalk(struct pet_data *pd, int64 tick) {
nullpo_ret(pd);
Assert((pd->msd == 0) || (pd->msd->pd == pd));
@@ -812,8 +811,7 @@ int pet_randomwalk(struct pet_data *pd,unsigned int tick)
return 0;
}
-int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, unsigned int tick)
-{
+int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, int64 tick) {
struct block_list *target = NULL;
if(pd->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL)
@@ -924,16 +922,15 @@ int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, unsigned i
return 0;
}
-int pet_ai_sub_foreachclient(struct map_session_data *sd,va_list ap)
-{
- unsigned int tick = va_arg(ap,unsigned int);
+int pet_ai_sub_foreachclient(struct map_session_data *sd,va_list ap) {
+ int64 tick = va_arg(ap,int64);
if(sd->status.pet_id && sd->pd)
pet->ai_sub_hard(sd->pd,sd,tick);
return 0;
}
-int pet_ai_hard(int tid, unsigned int tick, int id, intptr_t data) {
+int pet_ai_hard(int tid, int64 tick, int id, intptr_t data) {
map->foreachpc(pet->ai_sub_foreachclient,tick);
return 0;
@@ -966,7 +963,7 @@ int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap)
return 0;
}
-int pet_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data) {
+int pet_delay_item_drop(int tid, int64 tick, int id, intptr_t data) {
struct item_drop_list *list;
struct item_drop *ditem, *ditem_prev;
list=(struct item_drop_list *)data;
@@ -1034,7 +1031,7 @@ int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd)
/*==========================================
* pet bonus giving skills [Valaris] / Rewritten by [Skotlex]
*------------------------------------------*/
-int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int pet_skill_bonus_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd=map->id2sd(id);
struct pet_data *pd;
int bonus;
@@ -1075,7 +1072,7 @@ int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data) {
/*==========================================
* pet recovery skills [Valaris] / Rewritten by [Skotlex]
*------------------------------------------*/
-int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int pet_recovery_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd=map->id2sd(id);
struct pet_data *pd;
@@ -1102,7 +1099,7 @@ int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data) {
return 0;
}
-int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int pet_heal_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd=map->id2sd(id);
struct status_data *st;
struct pet_data *pd;
@@ -1139,7 +1136,7 @@ int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data) {
/*==========================================
* pet support skills [Skotlex]
*------------------------------------------*/
-int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int pet_skill_support_timer(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd=map->id2sd(id);
struct pet_data *pd;
struct status_data *st;
diff --git a/src/map/pet.h b/src/map/pet.h
index 2f8e0b7c2..f95e860a2 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -86,7 +86,7 @@ struct pet_data {
unsigned skillbonus : 1;
} state;
int move_fail_count;
- unsigned int next_walktime,last_thinktime;
+ int64 next_walktime, last_thinktime;
short rate_fix; //Support rate as modified by intimacy (1000 = 100%) [Skotlex]
struct pet_recovery* recovery;
@@ -116,7 +116,7 @@ struct pet_interface {
int (*attackskill) (struct pet_data *pd, int target_id);
int (*target_check) (struct map_session_data *sd, struct block_list *bl, int type);
int (*sc_check) (struct map_session_data *sd, int type);
- int (*hungry) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*hungry) (int tid, int64 tick, int id, intptr_t data);
int (*search_petDB_index) (int key, int type);
int (*hungry_timer_delete) (struct pet_data *pd);
int (*performance) (struct map_session_data *sd, struct pet_data *pd);
@@ -135,16 +135,16 @@ struct pet_interface {
int (*change_name) (struct map_session_data *sd, char *name);
int (*change_name_ack) (struct map_session_data *sd, char *name, int flag);
int (*equipitem) (struct map_session_data *sd, int index);
- int (*randomwalk) (struct pet_data *pd, unsigned int tick);
- int (*ai_sub_hard) (struct pet_data *pd, struct map_session_data *sd, unsigned int tick);
+ int (*randomwalk) (struct pet_data *pd, int64 tick);
+ int (*ai_sub_hard) (struct pet_data *pd, struct map_session_data *sd, int64 tick);
int (*ai_sub_foreachclient) (struct map_session_data *sd, va_list ap);
- int (*ai_hard) (int tid, unsigned int tick, int id, intptr_t data);
- int (*delay_item_drop) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*ai_hard) (int tid, int64 tick, int id, intptr_t data);
+ int (*delay_item_drop) (int tid, int64 tick, int id, intptr_t data);
int (*lootitem_drop) (struct pet_data *pd, struct map_session_data *sd);
- int (*skill_bonus_timer) (int tid, unsigned int tick, int id, intptr_t data);
- int (*recovery_timer) (int tid, unsigned int tick, int id, intptr_t data);
- int (*heal_timer) (int tid, unsigned int tick, int id, intptr_t data);
- int (*skill_support_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*skill_bonus_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*recovery_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*heal_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*skill_support_timer) (int tid, int64 tick, int id, intptr_t data);
int (*read_db) ();
};
diff --git a/src/map/script.c b/src/map/script.c
index c74eff07b..944759f39 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -3184,7 +3184,7 @@ void script_stop_instances(struct script_code *code) {
/*==========================================
* Timer function for sleep
*------------------------------------------*/
-int run_script_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int run_script_timer(int tid, int64 tick, int id, intptr_t data) {
struct script_state *st = idb_get(script->st_db,(int)data);
if( st ) {
TBL_PC *sd = map->id2sd(st->rid);
@@ -5639,7 +5639,7 @@ BUILDIN(checkweight2)
int nb_it, nb_nb; //array size
TBL_PC *sd = script->rid2sd(st);
- nullpo_retr(1,sd);
+ nullpo_retr(false,sd);
data_it = script_getdata(st, 2);
data_nb = script_getdata(st, 3);
@@ -7993,7 +7993,7 @@ BUILDIN(gettimetick) { /* Asgard Version */
case 0:
default:
//type 0:(System Ticks)
- script_pushint(st,timer->gettick());
+ script_pushint(st,(int)timer->gettick()); // TODO: change this to int64 when we'll support 64 bit script values
break;
}
return true;
@@ -8821,7 +8821,7 @@ BUILDIN(getnpctimer) {
}
switch( type ) {
- case 0: val = npc->gettimerevent_tick(nd); break;
+ case 0: val = (int)npc->gettimerevent_tick(nd); break; // FIXME: change this to int64 when we'll support 64 bit script values
case 1:
if( nd->u.scr.rid ) {
sd = map->id2sd(nd->u.scr.rid);
@@ -8995,8 +8995,8 @@ BUILDIN(itemeffect) {
struct script_data *data;
struct item_data *item_data;
- nullpo_retr( 1, ( sd = script->rid2sd( st ) ) );
- nullpo_retr( 1, ( nd = (TBL_NPC *)map->id2bl( sd->npc_id ) ) );
+ nullpo_retr( false, ( sd = script->rid2sd( st ) ) );
+ nullpo_retr( false, ( nd = (TBL_NPC *)map->id2bl( sd->npc_id ) ) );
data = script_getdata( st, 2 );
script->get_val( st, data );
@@ -9505,7 +9505,7 @@ BUILDIN(getstatus)
if( td ) {
// return the amount of time remaining
- script_pushint(st, td->tick - timer->gettick());
+ script_pushint(st, (int)(td->tick - timer->gettick())); // TODO: change this to int64 when we'll support 64 bit script values
}
}
break;
@@ -10201,6 +10201,7 @@ BUILDIN(getmapflag)
case MF_BATTLEGROUND: script_pushint(st,map->list[m].flag.battleground); break;
case MF_RESET: script_pushint(st,map->list[m].flag.reset); break;
case MF_NOTOMB: script_pushint(st,map->list[m].flag.notomb); break;
+ case MF_NOCASHSHOP: script_pushint(st,map->list[m].flag.nocashshop); break;
}
}
@@ -10317,6 +10318,7 @@ BUILDIN(setmapflag) {
case MF_BATTLEGROUND: map->list[m].flag.battleground = (val <= 0 || val > 2) ? 1 : val; break;
case MF_RESET: map->list[m].flag.reset = 1; break;
case MF_NOTOMB: map->list[m].flag.notomb = 1; break;
+ case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 1; break;
}
}
@@ -10402,6 +10404,7 @@ BUILDIN(removemapflag) {
case MF_BATTLEGROUND: map->list[m].flag.battleground = 0; break;
case MF_RESET: map->list[m].flag.reset = 0; break;
case MF_NOTOMB: map->list[m].flag.notomb = 0; break;
+ case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 0; break;
}
}
@@ -12685,7 +12688,7 @@ BUILDIN(summon)
const char *str,*event="";
TBL_PC *sd;
struct mob_data *md;
- int tick = timer->gettick();
+ int64 tick = timer->gettick();
sd=script->rid2sd(st);
if (!sd) return true;
@@ -14012,7 +14015,7 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle)
if( SQL_ERROR == SQL->QueryStr(handle, query) ) {
Sql_ShowDebug(handle);
- script_pushint(st, 0);
+ st->state = END;
return false;
}
@@ -14540,7 +14543,7 @@ BUILDIN(checkidle) {
sd = script->rid2sd(st);
if (sd)
- script_pushint(st, DIFF_TICK(last_tick, sd->idletime));
+ script_pushint(st, DIFF_TICK32(last_tick, sd->idletime)); // TODO: change this to int64 when we'll support 64 bit script values
else
script_pushint(st, 0);
@@ -15453,19 +15456,89 @@ BUILDIN(readbook)
Questlog script commands
*******************/
+BUILDIN(questinfo)
+{
+ struct npc_data *nd = map->id2nd(st->oid);
+ int quest, icon, job, color = 0;
+ struct questinfo qi;
+
+ if( nd == NULL || nd->bl.m == -1 )
+ return true;
+
+ quest = script_getnum(st, 2);
+ icon = script_getnum(st, 3);
+
+ #if PACKETVER >= 20120410
+ if(icon < 0 || (icon > 8 && icon != 9999) || icon == 7)
+ icon = 9999; // Default to nothing if icon id is invalid.
+ #else
+ if(icon < 0 || icon > 7)
+ icon = 0;
+ else
+ icon = icon + 1;
+ #endif
+
+ qi.quest_id = quest;
+ qi.icon = (unsigned char)icon;
+ qi.nd = nd;
+
+ if( script_hasdata(st, 4) ) {
+ color = script_getnum(st, 4);
+ if( color < 0 || color > 3 ) {
+ ShowWarning("buildin_questinfo: invalid color '%d', changing to 0\n",color);
+ script->reportfunc(st);
+ color = 0;
+ }
+ qi.color = (unsigned char)color;
+ }
+
+ qi.hasJob = false;
+
+ if(script_hasdata(st, 5)) {
+ job = script_getnum(st, 5);
+
+ if (!pcdb_checkid(job))
+ ShowError("buildin_questinfo: Nonexistant Job Class.\n");
+ else {
+ qi.hasJob = true;
+ qi.job = (unsigned short)job;
+ }
+ }
+
+ map->add_questinfo(nd->bl.m,&qi);
+
+ return true;
+}
+
BUILDIN(setquest)
{
struct map_session_data *sd = script->rid2sd(st);
- nullpo_ret(sd);
+ unsigned short i;
+ if (!sd)
+ return false;
+
quest->add(sd, script_getnum(st, 2));
+
+ // If questinfo is set, remove quest bubble once quest is set.
+ for(i = 0; i < map->list[sd->bl.m].qi_count; i++) {
+ struct questinfo *qi = &map->list[sd->bl.m].qi_data[i];
+ if( qi->quest_id == script_getnum(st, 2) ) {
+#if PACKETVER >= 20120410
+ clif->quest_show_event(sd, &qi->nd->bl, 9999, 0);
+#else
+ clif->quest_show_event(sd, &qi->nd->bl, 0, 0);
+#endif
+ }
+ }
+
return true;
}
BUILDIN(erasequest)
{
struct map_session_data *sd = script->rid2sd(st);
- nullpo_ret(sd);
+ nullpo_retr(false,sd);
quest->delete(sd, script_getnum(st, 2));
return true;
@@ -15474,7 +15547,7 @@ BUILDIN(erasequest)
BUILDIN(completequest)
{
struct map_session_data *sd = script->rid2sd(st);
- nullpo_ret(sd);
+ nullpo_retr(false,sd);
quest->update_status(sd, script_getnum(st, 2), Q_COMPLETE);
return true;
@@ -15483,7 +15556,7 @@ BUILDIN(completequest)
BUILDIN(changequest)
{
struct map_session_data *sd = script->rid2sd(st);
- nullpo_ret(sd);
+ nullpo_retr(false,sd);
quest->change(sd, script_getnum(st, 2),script_getnum(st, 3));
return true;
@@ -15494,7 +15567,7 @@ BUILDIN(checkquest)
struct map_session_data *sd = script->rid2sd(st);
quest_check_type type = HAVEQUEST;
- nullpo_ret(sd);
+ nullpo_retr(false,sd);
if( script_hasdata(st, 3) )
type = (quest_check_type)script_getnum(st, 3);
@@ -15507,17 +15580,32 @@ BUILDIN(checkquest)
BUILDIN(showevent) {
TBL_PC *sd = script->rid2sd(st);
struct npc_data *nd = map->id2nd(st->oid);
- int state, color;
+ int icon, color = 0;
if( sd == NULL || nd == NULL )
return true;
- state = script_getnum(st, 2);
- color = script_getnum(st, 3);
-
- if( color < 0 || color > 3 )
- color = 0; // set default color
+
+ icon = script_getnum(st, 2);
+ if( script_hasdata(st, 3) ) {
+ color = script_getnum(st, 3);
+ if( color < 0 || color > 3 ) {
+ ShowWarning("buildin_showevent: invalid color '%d', changing to 0\n",color);
+ script->reportfunc(st);
+ color = 0;
+ }
+ }
+
+ #if PACKETVER >= 20120410
+ if(icon < 0 || (icon > 8 && icon != 9999) || icon == 7)
+ icon = 9999; // Default to nothing if icon id is invalid.
+ #else
+ if(icon < 0 || icon > 7)
+ icon = 0;
+ else
+ icon = icon + 1;
+ #endif
- clif->quest_show_event(sd, &nd->bl, state, color);
+ clif->quest_show_event(sd, &nd->bl, icon, color);
return true;
}
@@ -16141,10 +16229,10 @@ BUILDIN(setfont)
if( sd == NULL )
return true;
- if( sd->user_font != font )
- sd->user_font = font;
+ if( sd->status.font != font )
+ sd->status.font = font;
else
- sd->user_font = 0;
+ sd->status.font = 0;
clif->font(sd);
return true;
@@ -17455,6 +17543,74 @@ BUILDIN(bg_match_over) {
return true;
}
+
+BUILDIN(instance_mapname) {
+ const char *map_name;
+ int m;
+ short instance_id = -1;
+
+ map_name = script_getstr(st,2);
+
+ if( script_hasdata(st,3) )
+ instance_id = script_getnum(st,3);
+ else
+ instance_id = st->instance_id;
+
+ // Check that instance mapname is a valid map
+ if( instance_id == -1 || (m = instance->mapname2imap(map_name,instance_id)) == -1 )
+ script_pushconststr(st, "");
+ else
+ script_pushconststr(st, map->list[m].name);
+
+ return true;
+}
+/* modify an instances' reload-spawn point */
+/* instance_set_respawn <map_name>,<x>,<y>{,<instance_id>} */
+/* returns 1 when successful, 0 otherwise. */
+BUILDIN(instance_set_respawn) {
+ const char *map_name;
+ short instance_id = -1;
+ short mid;
+ short x,y;
+
+ map_name = script_getstr(st,2);
+ x = script_getnum(st, 3);
+ y = script_getnum(st, 4);
+
+ if( script_hasdata(st, 5) )
+ instance_id = script_getnum(st, 5);
+ else
+ instance_id = st->instance_id;
+
+ if( instance_id == -1 || !instance->valid(instance_id) )
+ script_pushint(st, 0);
+ else if( (mid = map->mapname2mapid(map_name)) == -1 ) {
+ ShowError("buildin_instance_set_respawn: unknown map '%s'\n",map_name);
+ script_pushint(st, 0);
+ } else {
+ int i;
+
+ for(i = 0; i < instance->list[instance_id].num_map; i++) {
+ if( map->list[instance->list[instance_id].map[i]].m == mid ) {
+ instance->list[instance_id].respawn.map = map_id2index(mid);
+ instance->list[instance_id].respawn.x = x;
+ instance->list[instance_id].respawn.y = y;
+ break;
+ }
+ }
+
+ if( i != instance->list[instance_id].num_map )
+ script_pushint(st, 1);
+ else {
+ ShowError("buildin_instance_set_respawn: map '%s' not part of instance '%s'\n",map_name,instance->list[instance_id].name);
+ script_pushint(st, 0);
+ }
+ }
+
+
+ return true;
+}
+
// declarations that were supposed to be exported from npc_chat.c
#ifdef PCRE_SUPPORT
BUILDIN(defpattern);
@@ -17920,6 +18076,9 @@ void script_parse_builtin(void) {
BUILDIN_DEF(has_instance,"s?"),
BUILDIN_DEF(instance_warpall,"sii?"),
BUILDIN_DEF(instance_check_party,"i???"),
+ BUILDIN_DEF(instance_mapname,"s?"),
+ BUILDIN_DEF(instance_set_respawn,"sii?"),
+
/**
* 3rd-related
**/
@@ -17952,12 +18111,13 @@ void script_parse_builtin(void) {
BUILDIN_DEF(useatcmd, "s"),
//Quest Log System [Inkfish]
+ BUILDIN_DEF(questinfo, "ii??"),
BUILDIN_DEF(setquest, "i"),
BUILDIN_DEF(erasequest, "i"),
BUILDIN_DEF(completequest, "i"),
BUILDIN_DEF(checkquest, "i?"),
BUILDIN_DEF(changequest, "ii"),
- BUILDIN_DEF(showevent, "ii"),
+ BUILDIN_DEF(showevent, "i?"),
/**
* hQueue [Ind/Hercules]
@@ -18050,7 +18210,7 @@ void script_label_add(int key, int pos) {
void script_defaults(void) {
// aegis->athena slot position conversion table
- unsigned int equip[SCRIPT_EQUIP_TABLE_SIZE] = {EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_GARMENT,EQP_SHOES,EQP_ACC_L,EQP_ACC_R,EQP_HEAD_MID,EQP_HEAD_LOW,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_GARMENT};
+ unsigned int equip[SCRIPT_EQUIP_TABLE_SIZE] = {EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_GARMENT,EQP_SHOES,EQP_ACC_L,EQP_ACC_R,EQP_HEAD_MID,EQP_HEAD_LOW,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_GARMENT,EQP_SHADOW_ARMOR, EQP_SHADOW_WEAPON, EQP_SHADOW_SHIELD, EQP_SHADOW_SHOES, EQP_SHADOW_ACC_R, EQP_SHADOW_ACC_L};
script = &script_s;
diff --git a/src/map/script.h b/src/map/script.h
index c00086ef9..a4d14c777 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -35,7 +35,7 @@ struct eri;
//#define SCRIPT_HASH_SDBM
#define SCRIPT_HASH_ELF
-#define SCRIPT_EQUIP_TABLE_SIZE 14
+#define SCRIPT_EQUIP_TABLE_SIZE 20
//#define SCRIPT_DEBUG_DISP
//#define SCRIPT_DEBUG_DISASM
@@ -287,7 +287,8 @@ enum {
MF_PVP_NOCALCRANK, //50
MF_BATTLEGROUND,
MF_RESET,
- MF_NOTOMB
+ MF_NOTOMB,
+ MF_NOCASHSHOP
};
/**
@@ -535,7 +536,7 @@ struct script_interface {
void (*label_add)(int key, int pos);
void (*run) (struct script_code *rootscript,int pos,int rid,int oid);
void (*run_main) (struct script_state *st);
- int (*run_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*run_timer) (int tid, int64 tick, int id, intptr_t data);
int (*set_var) (struct map_session_data *sd, char *name, void *val);
void (*stop_instances) (struct script_code *code);
void (*free_code) (struct script_code* code);
diff --git a/src/map/skill.c b/src/map/skill.c
index 9db10bbc7..b70e58c46 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -460,7 +460,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
return 1;
}
- if (sd->blockskill[idx] > 0) {
+ if (sd->blockskill[idx]) {
clif->skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0);
return 1;
}
@@ -639,7 +639,7 @@ struct s_skill_unit_layout* skill_get_unit_layout (uint16 skill_id, uint16 skill
/*==========================================
*
*------------------------------------------*/
-int skill_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int dmg_lv, unsigned int tick) {
+int skill_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int dmg_lv, int64 tick) {
struct map_session_data *sd, *dstsd;
struct mob_data *md, *dstmd;
struct status_data *sstatus, *tstatus;
@@ -1139,12 +1139,12 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
sc_start4(bl,SC_BURNING,100,skill_lv,0,src->id,0,skill->get_time2(skill_id,skill_lv));
break;
case WL_EARTHSTRAIN:
- {
- // lv 1 & 2 = Strip Helm, lv 3 = Strip Armor, lv 4 = Strip Weapon and lv 5 = Strip Accessory. [malufett]
- const int pos[5] = { EQP_HELM, EQP_HELM, EQP_ARMOR, EQP_WEAPON, EQP_ACC };
- skill->strip_equip(bl, pos[skill_lv], 6 * skill_lv + status->get_lv(src) / 4 + status_get_dex(src) / 10,
- skill_lv, skill->get_time2(skill_id,skill_lv));
- }
+ {
+ // lv 1 & 2 = Strip Helm, lv 3 = Strip Armor, lv 4 = Strip Weapon and lv 5 = Strip Accessory. [malufett]
+ const int pos[5] = { EQP_HELM, EQP_HELM, EQP_ARMOR, EQP_WEAPON, EQP_ACC };
+ skill->strip_equip(bl, pos[skill_lv-1], 6 * skill_lv + status->get_lv(src) / 4 + status_get_dex(src) / 10,
+ skill_lv, skill->get_time2(skill_id,skill_lv));
+ }
break;
case WL_JACKFROST:
sc_start(bl,SC_FREEZE,100,skill_lv,skill->get_time(skill_id,skill_lv));
@@ -1569,7 +1569,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
return 0;
}
-int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint16 skill_id, unsigned int tick) {
+int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint16 skill_id, int64 tick) {
int temp, skill_lv, i, type, notok;
struct block_list *tbl;
@@ -1667,7 +1667,7 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint1
* type of skills, so not every instance of skill->additional_effect needs a call
* to this one.
*/
-int skill_counter_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, unsigned int tick) {
+int skill_counter_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int64 tick) {
int rate;
struct map_session_data *sd=NULL;
struct map_session_data *dstsd=NULL;
@@ -2109,7 +2109,7 @@ int skill_magic_reflect(struct block_list* src, struct block_list* bl, int type)
* flag&0x2000 is used to signal that the skill_lv should be passed as -1 to the
* client (causes player characters to not scream skill name)
*-------------------------------------------------------------------------*/
-int skill_attack (int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) {
+int skill_attack(int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
struct Damage dmg;
struct status_data *sstatus, *tstatus;
struct status_change *sc;
@@ -2117,7 +2117,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
int type;
int64 damage;
int8 rmdamage=0;//magic reflected
- bool additional_effects = true;
+ bool additional_effects = true, shadow_flag = false;
if(skill_id > 0 && !skill_lv) return 0;
@@ -2357,7 +2357,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
break;
} //Switch End
if (flag) { //Possible to chain
- if ( (flag = DIFF_TICK(sd->ud.canact_tick, tick)) < 50 ) flag = 50;/* less is a waste. */
+ if ( (flag = DIFF_TICK32(sd->ud.canact_tick, tick)) < 50 ) flag = 50;/* less is a waste. */
sc_start2(src,SC_COMBOATTACK,100,skill_id,bl->id,flag);
clif->combo_delay(src, flag);
}
@@ -2574,10 +2574,12 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if (ud && DIFF_TICK(ud->attackabletime, tick + type) < 0)
ud->attackabletime = tick + type;
}
+
+ shadow_flag = skill->check_shadowform(bl, damage, dmg.div_);
if( !dmg.amotion ) {
//Instant damage
- if( !sc || (!sc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD) )
+ if( (!sc || (!sc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD)) && !shadow_flag)
status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo.
if( !status->isdead(bl) && additional_effects )
skill->additional_effect(src,bl,skill_id,skill_lv,dmg.flag,dmg.dmg_lv,tick);
@@ -2657,8 +2659,15 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
}
//Delayed damage must be dealt after the knockback (it needs to know actual position of target)
- if (dmg.amotion)
- battle->delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects);
+ if (dmg.amotion){
+ if( shadow_flag ){
+ if( !status->isdead(bl) && additional_effects )
+ skill->additional_effect(src,bl,skill_id,skill_lv,dmg.flag,dmg.dmg_lv,tick);
+ if( dmg.flag > ATK_BLOCK )
+ skill->counter_additional_effect(src,bl,skill_id,skill_lv,dmg.flag,tick);
+ }else
+ battle->delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects);
+ }
if( sc && sc->data[SC_DEVOTION] && skill_id != PA_PRESSURE ) {
struct status_change_entry *sce = sc->data[SC_DEVOTION];
@@ -2758,21 +2767,21 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
* Checking bl battle flag and display dammage
* then call func with source,target,skill_id,skill_lv,tick,flag
*------------------------------------------*/
-int skill_area_sub (struct block_list *bl, va_list ap) {
+int skill_area_sub(struct block_list *bl, va_list ap) {
struct block_list *src;
uint16 skill_id,skill_lv;
int flag;
- unsigned int tick;
+ int64 tick;
SkillFunc func;
nullpo_ret(bl);
- src=va_arg(ap,struct block_list *);
- skill_id=va_arg(ap,int);
- skill_lv=va_arg(ap,int);
- tick=va_arg(ap,unsigned int);
- flag=va_arg(ap,int);
- func=va_arg(ap,SkillFunc);
+ src = va_arg(ap,struct block_list *);
+ skill_id = va_arg(ap,int);
+ skill_lv = va_arg(ap,int);
+ tick = va_arg(ap,int64);
+ flag = va_arg(ap,int);
+ func = va_arg(ap,SkillFunc);
if(battle->check_target(src,bl,flag) > 0) {
// several splash skills need this initial dummy packet to display correctly
@@ -3027,14 +3036,14 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv,
/*==========================================
* what the hell it doesn't need to receive this many params, it doesn't do anything ~_~
*------------------------------------------*/
-int skill_area_sub_count (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) {
+int skill_area_sub_count(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
return 1;
}
/*==========================================
*
*------------------------------------------*/
-int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
+int skill_timerskill(int tid, int64 tick, int id, intptr_t data) {
struct block_list *src = map->id2bl(id),*target;
struct unit_data *ud = unit->bl2ud(src);
struct skill_timerskill *skl;
@@ -3059,8 +3068,23 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
break; // Target not on Map
if(src->m != target->m)
break; // Different Maps
- if(status->isdead(src))
- break; // Caster is Dead
+ if(status->isdead(src)){
+ // Exceptions
+ switch(skl->skill_id){
+ case WL_CHAINLIGHTNING_ATK:
+ case WL_TETRAVORTEX_FIRE:
+ case WL_TETRAVORTEX_WATER:
+ case WL_TETRAVORTEX_WIND:
+ case WL_TETRAVORTEX_GROUND:
+ case SR_FLASHCOMBO_ATK_STEP1:
+ case SR_FLASHCOMBO_ATK_STEP2:
+ case SR_FLASHCOMBO_ATK_STEP3:
+ case SR_FLASHCOMBO_ATK_STEP4:
+ break;
+ default:
+ continue; // Caster is Dead
+ }
+ }
if(status->isdead(target) && skl->skill_id != RG_INTIMIDATE && skl->skill_id != WZ_WATERBALL)
break;
@@ -3129,12 +3153,12 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
case WL_TETRAVORTEX_WIND:
case WL_TETRAVORTEX_GROUND:
clif->skill_nodamage(src, target, skl->skill_id, skl->skill_lv, 1);
- skill_attack(BF_MAGIC, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag);
+ skill->attack(BF_MAGIC, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag);
skill->toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify
if( skl->type == 4 ){
const enum sc_type scs[] = { SC_BURNING, SC_BLOODING, SC_FROSTMISTY, SC_STUN }; // status inflicts are depend on what summoned element is used.
int rate = skl->y, index = skl->x-1;
- sc_start2(target, scs[index], rate, skl->skill_lv, src->id, skill->get_time(WL_TETRAVORTEX,index));
+ sc_start2(target, scs[index], rate, skl->skill_lv, src->id, skill->get_time(WL_TETRAVORTEX,index+1));
}
break;
case WM_REVERBERATION_MELEE:
@@ -3245,8 +3269,7 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
/*==========================================
*
*------------------------------------------*/
-int skill_addtimerskill (struct block_list *src, unsigned int tick, int target, int x,int y, uint16 skill_id, uint16 skill_lv, int type, int flag)
-{
+int skill_addtimerskill(struct block_list *src, int64 tick, int target, int x,int y, uint16 skill_id, uint16 skill_lv, int type, int flag) {
int i;
struct unit_data *ud;
nullpo_retr(1, src);
@@ -3285,6 +3308,17 @@ int skill_cleartimerskill (struct block_list *src)
for(i=0;i<MAX_SKILLTIMERSKILL;i++) {
if(ud->skilltimerskill[i]) {
+ switch(ud->skilltimerskill[i]->skill_id){
+ case WL_TETRAVORTEX_FIRE:
+ case WL_TETRAVORTEX_WATER:
+ case WL_TETRAVORTEX_WIND:
+ case WL_TETRAVORTEX_GROUND:
+ case SR_FLASHCOMBO_ATK_STEP1:
+ case SR_FLASHCOMBO_ATK_STEP2:
+ case SR_FLASHCOMBO_ATK_STEP3:
+ case SR_FLASHCOMBO_ATK_STEP4:
+ continue;
+ }
timer->delete(ud->skilltimerskill[i]->timer, skill->timerskill);
ers_free(skill->timer_ers, ud->skilltimerskill[i]);
ud->skilltimerskill[i]=NULL;
@@ -3299,7 +3333,7 @@ int skill_activate_reverbetion( struct block_list *bl, va_list ap) {
return 0;
if( su->alive && (sg = su->group) && sg->skill_id == WM_REVERBERATION ) {
map->foreachinrange(skill->trap_splash, bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, timer->gettick());
- su->limit=DIFF_TICK(timer->gettick(),sg->tick);
+ su->limit=DIFF_TICK32(timer->gettick(),sg->tick);
sg->unit_id = UNT_USED_TRAPS;
}
return 0;
@@ -3320,7 +3354,7 @@ int skill_reveal_trap (struct block_list *bl, va_list ap) {
*
*
*------------------------------------------*/
-int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) {
+int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
struct map_session_data *sd = NULL;
struct status_data *tstatus;
struct status_change *sc;
@@ -4185,7 +4219,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
}
}
if(cooldown)
- skill->blockpc_start(sd, skill_id, cooldown, false);
+ skill->blockpc_start(sd, skill_id, cooldown);
}else if( sc ){ // Summon Balls
int i = SC_SUMMON5;
for(; i >= SC_SUMMON1; i--){
@@ -4522,8 +4556,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
/*==========================================
*
*------------------------------------------*/
-int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
-{
+int skill_castend_id(int tid, int64 tick, int id, intptr_t data) {
struct block_list *target, *src;
struct map_session_data *sd;
struct mob_data *md;
@@ -4734,7 +4767,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
}
}
if(cooldown)
- skill->blockpc_start(sd, ud->skill_id, cooldown, false);
+ skill->blockpc_start(sd, ud->skill_id, cooldown);
}
if( battle_config.display_status_timers && sd )
clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, ud->skill_id, ud->skill_lv), 0, 0, 0);
@@ -4785,7 +4818,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
sc->data[SC_SOULLINK]->val3 = 0; //Clear bounced spell check.
if( sc->data[SC_DANCING] && skill->get_inf2(ud->skill_id)&INF2_SONG_DANCE && sd )
- skill->blockpc_start(sd,BD_ADAPTATION,3000, false);
+ skill->blockpc_start(sd,BD_ADAPTATION,3000);
}
if( sd && ud->skill_id != SA_ABRACADABRA && ud->skill_id != WM_RANDOMIZESPELL ) // they just set the data so leave it as it is.[Inkfish]
@@ -4850,8 +4883,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
/*==========================================
*
*------------------------------------------*/
-int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag)
-{
+int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
struct map_session_data *sd, *dstsd;
struct mob_data *md, *dstmd;
struct homun_data *hd;
@@ -4930,11 +4962,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
- return skill->castend_damage_id (src, bl, skill_id, skill_lv, tick, flag);
+ return skill->castend_damage_id(src, bl, skill_id, skill_lv, tick, flag);
}
break;
case NPC_SMOKING: //Since it is a self skill, this one ends here rather than in damage_id. [Skotlex]
- return skill->castend_damage_id (src, bl, skill_id, skill_lv, tick, flag);
+ return skill->castend_damage_id(src, bl, skill_id, skill_lv, tick, flag);
case MH_STEINWAND: {
struct block_list *s_src = battle->get_master(src);
short ret = 0;
@@ -5406,7 +5438,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
// Initiate 10% of your damage becomes fire element.
sc_start4(src,SC_SUB_WEAPONPROPERTY,100,3,20,0,0,skill->get_time2(skill_id, skill_lv));
if( sd )
- skill->blockpc_start(sd, skill_id, skill->get_time(skill_id, skill_lv), false);
+ skill->blockpc_start(sd, skill_id, skill->get_time(skill_id, skill_lv));
else if( bl->type == BL_MER )
skill->blockmerc_start((TBL_MER*)bl, skill_id, skill->get_time(skill_id, skill_lv));
break;
@@ -5575,7 +5607,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif->skill_nodamage(src,bl,skill_id,skill_lv,
sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
if (sd)
- skill->blockpc_start (sd, skill_id, skill->get_time2(skill_id,skill_lv), false);
+ skill->blockpc_start (sd, skill_id, skill->get_time2(skill_id,skill_lv));
break;
case ALL_ANGEL_PROTECT:
@@ -7072,8 +7104,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case UNT_TALKIEBOX:
su->group->unit_id = UNT_USED_TRAPS;
clif->changetraplook(bl, UNT_USED_TRAPS);
- su->group->limit=DIFF_TICK(tick+1500,su->group->tick);
- su->limit=DIFF_TICK(tick+1500,su->group->tick);
+ su->group->limit=DIFF_TICK32(tick+1500,su->group->tick);
+ su->limit=DIFF_TICK32(tick+1500,su->group->tick);
}
}
}
@@ -7098,7 +7130,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif->skill_nodamage(src,bl,skill_id,skill_lv,
sc_start4(bl,type,100,skill_lv,skill_id,src->id,skill->get_time(skill_id,skill_lv),1000));
#ifndef RENEWAL
- if (sd) skill->blockpc_start (sd, skill_id, skill->get_time(skill_id, skill_lv)+3000, false);
+ if (sd) skill->blockpc_start (sd, skill_id, skill->get_time(skill_id, skill_lv)+3000);
#endif
break;
@@ -8873,7 +8905,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
duration = 9000;
break;
}
- skill->blockpc_start(sd, skill_id, duration, false);
+ skill->blockpc_start(sd, skill_id, duration);
}
break;
@@ -9084,7 +9116,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
md->special_state.ai = AI_ZANZOU;
if( md->deletetimer != INVALID_TIMER )
timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0);
+ md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0);
mob->spawn( md );
pc->setinvincibletimer(sd,500);// unlock target lock
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -9317,7 +9349,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
/*==========================================
*
*------------------------------------------*/
-int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) {
+int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) {
struct block_list* src = map->id2bl(id);
int maxcount;
struct map_session_data *sd;
@@ -9430,7 +9462,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) {
}
}
if(cooldown)
- skill->blockpc_start(sd, ud->skill_id, cooldown, false);
+ skill->blockpc_start(sd, ud->skill_id, cooldown);
}
if( battle_config.display_status_timers && sd )
clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, ud->skill_id, ud->skill_lv), 0, 0, 0);
@@ -9617,8 +9649,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
/*==========================================
*
*------------------------------------------*/
-int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag)
-{
+int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
struct map_session_data* sd;
struct status_change* sc;
struct status_change_entry *sce;
@@ -9908,7 +9939,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
clif->skill_poseffect(src,skill_id,skill_lv,src->x,src->y,tick);
#endif
if (sd)
- skill->blockpc_start (sd, MO_EXTREMITYFIST, 2000, false);
+ skill->blockpc_start (sd, MO_EXTREMITYFIST, 2000);
}
break;
case NJ_SHADOWJUMP:
@@ -9933,7 +9964,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
md->special_state.ai = (skill_id == AM_SPHEREMINE) ? AI_SPHERE : AI_FLORA;
if( md->deletetimer != INVALID_TIMER )
timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (timer->gettick() + skill->get_time(skill_id,skill_lv), mob->timer_delete, md->bl.id, 0);
+ md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id,skill_lv), mob->timer_delete, md->bl.id, 0);
mob->spawn (md); //Now it is ready for spawning.
}
}
@@ -10031,7 +10062,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
{
if( md->deletetimer != INVALID_TIMER )
timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (tick + i, mob->timer_delete, md->bl.id, 0);
+ md->deletetimer = timer->add(tick + i, mob->timer_delete, md->bl.id, 0);
}
mob->spawn (md);
}
@@ -10162,7 +10193,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
md->special_state.ai = AI_FLORA;
if( md->deletetimer != INVALID_TIMER )
timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0);
+ md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0);
mob->spawn( md );
}
}
@@ -10570,7 +10601,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
old_sg->skill_id == SA_VIOLENTGALE
) && old_sg->limit > 0)
{ //Use the previous limit (minus the elapsed time) [Skotlex]
- limit = old_sg->limit - DIFF_TICK(timer->gettick(), old_sg->tick);
+ limit = old_sg->limit - DIFF_TICK32(timer->gettick(), old_sg->tick);
if (limit < 0) //This can happen...
limit = skill->get_time(skill_id,skill_lv);
}
@@ -10927,7 +10958,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
/*==========================================
*
*------------------------------------------*/
-int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned int tick) {
+int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick) {
struct skill_unit_group *sg;
struct block_list *ss;
struct status_change *sc;
@@ -10967,14 +10998,14 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
if( status->change_start(bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,8) ) {
const struct TimerData* td = sc->data[type]?timer->get(sc->data[type]->timer):NULL;
if( td )
- sec = DIFF_TICK(td->tick, tick);
+ sec = DIFF_TICK32(td->tick, tick);
map->moveblock(bl, src->bl.x, src->bl.y, tick);
clif->fixpos(bl);
sg->val2 = bl->id;
}
else
sec = 3000; //Couldn't trap it?
- sg->limit = DIFF_TICK(tick,sg->tick)+sec;
+ sg->limit = DIFF_TICK32(tick,sg->tick)+sec;
}
break;
case UNT_SAFETYWALL:
@@ -11100,7 +11131,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
// case UNT_ICEWALL: //Destroy the cell. [Skotlex]
// src->val1 = 0;
// if(src->limit + sg->tick > tick + 700)
- // src->limit = DIFF_TICK(tick+700,sg->tick);
+ // src->limit = DIFF_TICK32(tick+700,sg->tick);
// break;
case UNT_MOONLIT:
@@ -11138,7 +11169,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
/*==========================================
*
*------------------------------------------*/
-int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, unsigned int tick) {
+int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int64 tick) {
struct skill_unit_group *sg;
struct block_list *ss;
TBL_PC* tsd;
@@ -11182,7 +11213,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if ((ts = skill->unitgrouptickset_search(bl,sg,tick))) {
//Not all have it, eg: Traps don't have it even though they can be hit by Heaven's Drive [Skotlex]
- diff = DIFF_TICK(tick,ts->tick);
+ diff = DIFF_TICK32(tick,ts->tick);
if (diff < 0)
return 0;
ts->tick = tick+sg->interval;
@@ -11282,7 +11313,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
status->charge(ss, 0, 8); //costs additional 8 SP if miss
} else { // mobs
//should end when out of sp.
- sg->limit = DIFF_TICK(tick,sg->tick);
+ sg->limit = DIFF_TICK32(tick,sg->tick);
break;
}
} while( x == bl->x && y == bl->y
@@ -11325,7 +11356,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
skill->blown(&src->bl,bl,skill->get_blewcount(sg->skill_id,sg->skill_lv),unit->getdir(bl),0);
sg->unit_id = UNT_USED_TRAPS;
clif->changetraplook(&src->bl, UNT_USED_TRAPS);
- sg->limit=DIFF_TICK(tick,sg->tick)+1500;
+ sg->limit=DIFF_TICK32(tick,sg->tick)+1500;
}
break;
@@ -11336,7 +11367,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if( status->change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, 8) ) {
const struct TimerData* td = tsc->data[type]?timer->get(tsc->data[type]->timer):NULL;
if( td )
- sec = DIFF_TICK(td->tick, tick);
+ sec = DIFF_TICK32(td->tick, tick);
if( sg->unit_id == UNT_MANHOLE || battle_config.skill_trap_type || !map_flag_gvg2(src->bl.m) ) {
unit->movepos(bl, src->bl.x, src->bl.y, 0, 0);
clif->fixpos(bl);
@@ -11353,7 +11384,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
**/
clif->changetraplook(&src->bl, UNT_ANKLESNARE);
}
- sg->limit = DIFF_TICK(tick,sg->tick)+sec;
+ sg->limit = DIFF_TICK32(tick,sg->tick)+sec;
sg->interval = -1;
src->range = 0;
}
@@ -11405,7 +11436,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
if (sg->unit_id != UNT_FIREPILLAR_ACTIVE)
clif->changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
- sg->limit=DIFF_TICK(tick,sg->tick)+1500 +
+ sg->limit=DIFF_TICK32(tick,sg->tick)+1500 +
(sg->unit_id== UNT_CLUSTERBOMB || sg->unit_id== UNT_ICEBOUNDTRAP?1000:0);// Cluster Bomb/Icebound has 1s to disappear once activated.
sg->unit_id = UNT_USED_TRAPS; //Changed ID so it does not invoke a for each in area again.
break;
@@ -11417,7 +11448,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
clif->talkiebox(&src->bl, sg->valstr);
sg->unit_id = UNT_USED_TRAPS;
clif->changetraplook(&src->bl, UNT_USED_TRAPS);
- sg->limit = DIFF_TICK(tick, sg->tick) + 5000;
+ sg->limit = DIFF_TICK32(tick, sg->tick) + 5000;
sg->val2 = -1;
}
break;
@@ -11594,7 +11625,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
&src->bl,tick);
sg->unit_id = UNT_USED_TRAPS;
//clif->changetraplook(&src->bl, UNT_FIREPILLAR_ACTIVE);
- sg->limit=DIFF_TICK(tick,sg->tick)+1500;
+ sg->limit=DIFF_TICK32(tick,sg->tick)+1500;
break;
/**
* 3rd stuff
@@ -11647,7 +11678,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_REVERBERATION:
clif->changetraplook(&src->bl,UNT_USED_TRAPS);
map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
- sg->limit = DIFF_TICK(tick,sg->tick)+1000;
+ sg->limit = DIFF_TICK32(tick,sg->tick)+1000;
sg->unit_id = UNT_USED_TRAPS;
break;
@@ -11659,7 +11690,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if( !(status_get_mode(bl)&MD_BOSS) && ss != bl && battle->check_target(&src->bl, bl, BCT_PARTY) > 0 ) {
if( !(tsc && tsc->data[type]) ){
sc_start(bl, type, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv));
- sg->limit = DIFF_TICK(tick,sg->tick);
+ sg->limit = DIFF_TICK32(tick,sg->tick);
sg->unit_id = UNT_USED_TRAPS;
}
}
@@ -11671,13 +11702,13 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if( sc_start(bl, type, 100, sg->skill_lv, sec) ) {
const struct TimerData* td = tsc->data[type]?timer->get(tsc->data[type]->timer):NULL;
if( td )
- sec = DIFF_TICK(td->tick, tick);
+ sec = DIFF_TICK32(td->tick, tick);
///map->moveblock(bl, src->bl.x, src->bl.y, tick); // in official server it doesn't behave like this. [malufett]
clif->fixpos(bl);
sg->val2 = bl->id;
} else
sec = 3000; // Couldn't trap it?
- sg->limit = DIFF_TICK(tick, sg->tick) + sec;
+ sg->limit = DIFF_TICK32(tick, sg->tick) + sec;
} else if( tsc->data[SC_THORNS_TRAP] && bl->id == sg->val2 )
skill->attack(skill->get_type(GN_THORNS_TRAP), ss, ss, bl, sg->skill_id, sg->skill_lv, tick, SD_LEVEL|SD_ANIMATION);
}
@@ -11715,7 +11746,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if( battle->check_target(&src->bl,bl,BCT_ENEMY) > 0 )
skill->attack(skill->get_type(GN_HELLS_PLANT_ATK), ss, &src->bl, bl, GN_HELLS_PLANT_ATK, sg->skill_lv, tick, 0);
if( ss != bl) //The caster is the only one who can step on the Plants, without destroying them
- sg->limit = DIFF_TICK(tick, sg->tick) + 100;
+ sg->limit = DIFF_TICK32(tick, sg->tick) + 100;
break;
case UNT_CLOUD_KILL:
@@ -11765,7 +11796,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_VACUUM_EXTREME:
{// TODO: official behavior in gvg area. [malufett]
- int sec = sg->limit - DIFF_TICK(tick, sg->tick);
+ int sec = sg->limit - DIFF_TICK32(tick, sg->tick);
int range = skill->get_unit_range(sg->skill_id, sg->skill_lv);
if( tsc && !tsc->data[type] &&
@@ -11828,7 +11859,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_LAVA_SLIDE:
skill->attack(BF_WEAPON, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
if(++sg->val1 > 4) //after 5 stop hit and destroy me
- sg->limit = DIFF_TICK(tick, sg->tick);
+ sg->limit = DIFF_TICK32(tick, sg->tick);
break;
case UNT_POISON_MIST:
@@ -11845,7 +11876,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
/*==========================================
* Triggered when a char steps out of a skill cell
*------------------------------------------*/
-int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned int tick) {
+int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick) {
struct skill_unit_group *sg;
struct status_change *sc;
struct status_change_entry *sce;
@@ -11888,7 +11919,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
if (target && target==bl) {
if (sce && sce->val3 == sg->group_id)
status_change_end(bl, type, INVALID_TIMER);
- sg->limit = DIFF_TICK(tick,sg->tick)+1000;
+ sg->limit = DIFF_TICK32(tick,sg->tick)+1000;
}
}
break;
@@ -11899,7 +11930,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
/*==========================================
* Triggered when a char steps out of a skill group (entirely) [Skotlex]
*------------------------------------------*/
-int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick) {
+int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) {
struct status_change *sc;
struct status_change_entry *sce;
enum sc_type type;
@@ -12005,10 +12036,10 @@ int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick
* flag&1: Invoke onplace function (otherwise invoke onout)
* flag&4: Invoke a onleft call (the unit might be scheduled for deletion)
*------------------------------------------*/
-int skill_unit_effect (struct block_list* bl, va_list ap) {
+int skill_unit_effect(struct block_list* bl, va_list ap) {
struct skill_unit* su = va_arg(ap,struct skill_unit*);
struct skill_unit_group* group = su->group;
- unsigned int tick = va_arg(ap,unsigned int);
+ int64 tick = va_arg(ap,int64);
unsigned int flag = va_arg(ap,unsigned int);
uint16 skill_id;
bool dissonance;
@@ -12044,8 +12075,7 @@ int skill_unit_effect (struct block_list* bl, va_list ap) {
/*==========================================
*
*------------------------------------------*/
-int skill_unit_ondamaged (struct skill_unit *src, struct block_list *bl, int64 damage, unsigned int tick)
-{
+int skill_unit_ondamaged(struct skill_unit *src, struct block_list *bl, int64 damage, int64 tick) {
struct skill_unit_group *sg;
nullpo_ret(src);
@@ -14152,8 +14182,7 @@ void skill_brandishspear_dir (struct square* tc, uint8 dir, int are) {
}
}
-void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag)
-{
+void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
int c,n=4;
uint8 dir = map->calc_dir(src,bl->x,bl->y);
struct square tc;
@@ -14490,10 +14519,10 @@ int skill_sit (struct map_session_data *sd, int type)
/*==========================================
*
*------------------------------------------*/
-int skill_frostjoke_scream (struct block_list *bl, va_list ap) {
+int skill_frostjoke_scream(struct block_list *bl, va_list ap) {
struct block_list *src;
uint16 skill_id,skill_lv;
- unsigned int tick;
+ int64 tick;
nullpo_ret(bl);
nullpo_ret(src=va_arg(ap,struct block_list*));
@@ -14501,7 +14530,7 @@ int skill_frostjoke_scream (struct block_list *bl, va_list ap) {
skill_id=va_arg(ap,int);
skill_lv=va_arg(ap,int);
if(!skill_lv) return 0;
- tick=va_arg(ap,unsigned int);
+ tick=va_arg(ap,int64);
if (src == bl || status->isdead(bl))
return 0;
@@ -14534,22 +14563,22 @@ void skill_unitsetmapcell (struct skill_unit *src, uint16 skill_id, uint16 skill
/*==========================================
*
*------------------------------------------*/
-int skill_attack_area (struct block_list *bl, va_list ap) {
+int skill_attack_area(struct block_list *bl, va_list ap) {
struct block_list *src,*dsrc;
int atk_type,skill_id,skill_lv,flag,type;
- unsigned int tick;
+ int64 tick;
if(status->isdead(bl))
return 0;
atk_type = va_arg(ap,int);
- src=va_arg(ap,struct block_list*);
- dsrc=va_arg(ap,struct block_list*);
- skill_id=va_arg(ap,int);
- skill_lv=va_arg(ap,int);
- tick=va_arg(ap,unsigned int);
- flag=va_arg(ap,int);
- type=va_arg(ap,int);
+ src = va_arg(ap,struct block_list*);
+ dsrc = va_arg(ap,struct block_list*);
+ skill_id = va_arg(ap,int);
+ skill_lv = va_arg(ap,int);
+ tick = va_arg(ap,int64);
+ flag = va_arg(ap,int);
+ type = va_arg(ap,int);
if (skill->area_temp[1] == bl->id) //This is the target of the skill, do a full attack and skip target checks.
@@ -14704,7 +14733,7 @@ int skill_detonator(struct block_list *bl, va_list ap) {
map->foreachinrange(skill->trap_splash,bl,skill->get_splash(su->group->skill_id,su->group->skill_lv),su->group->bl_flag,bl,su->group->tick);
}
clif->changetraplook(bl, UNT_USED_TRAPS);
- su->group->limit = DIFF_TICK(timer->gettick(),su->group->tick) +
+ su->group->limit = DIFF_TICK32(timer->gettick(),su->group->tick) +
(unit_id == UNT_TALKIEBOX ? 5000 : (unit_id == UNT_CLUSTERBOMB || unit_id == UNT_ICEBOUNDTRAP? 2500 : (unit_id == UNT_FIRINGTRAP ? 0 : 1500)) );
su->group->unit_id = UNT_USED_TRAPS;
break;
@@ -14841,15 +14870,15 @@ int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap)
/*==========================================
*
*------------------------------------------*/
-int skill_trap_splash (struct block_list *bl, va_list ap) {
+int skill_trap_splash(struct block_list *bl, va_list ap) {
struct block_list *src;
- int tick;
+ int64 tick;
struct skill_unit *su;
struct skill_unit_group *sg;
struct block_list *ss;
src = va_arg(ap,struct block_list *);
su = (struct skill_unit *)src;
- tick = va_arg(ap,int);
+ tick = va_arg(ap,int64);
if( !su->alive || bl->prev == NULL )
return 0;
@@ -14927,7 +14956,7 @@ int skill_trap_splash (struct block_list *bl, va_list ap) {
case UNT_FIRINGTRAP:
case UNT_ICEBOUNDTRAP:
clif->changetraplook(bl, UNT_USED_TRAPS);
- su->group->limit = DIFF_TICK(timer->gettick(),su->group->tick) + 1500;
+ su->group->limit = DIFF_TICK32(timer->gettick(),su->group->tick) + 1500;
su->group->unit_id = UNT_USED_TRAPS;
}
break;
@@ -15046,6 +15075,39 @@ bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *s
return wall;
}
+bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit){
+ struct status_change *sc;
+ struct block_list *src;
+
+ nullpo_retr(false, bl);
+
+ sc = status->get_sc(bl);
+
+ if( sc && sc->data[SC__SHADOWFORM] && damage ) {
+ src = map->id2bl(sc->data[SC__SHADOWFORM]->val2);
+
+ if( !src || src->m != bl->m ) {
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ return false;
+ }
+
+ if( src && (status->isdead(src) || !battle->check_target(bl,src,BCT_ENEMY)) ){
+ if( src->type == BL_PC )
+ ((TBL_PC*)src)->shadowform_id = 0;
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ return false;
+ }
+
+ status->damage(bl, src, damage, 0, clif->damage(src, src, timer->gettick(), 500, 500, damage, hit, (hit > 1 ? 8 : 0), 0), 0);
+ if( (--sc->data[SC__SHADOWFORM]->val3) <= 0 ) {
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ if( src->type == BL_PC )
+ ((TBL_PC*)src)->shadowform_id = 0;
+ }
+ return true;
+ }
+ return false;
+}
/*==========================================
*
*------------------------------------------*/
@@ -15220,11 +15282,11 @@ struct skill_unit_group* skill_initunitgroup (struct block_list* src, int count,
if(i == MAX_SKILLUNITGROUP) {
// array is full, make room by discarding oldest group
int j=0;
- unsigned maxdiff=0,x,tick=timer->gettick();
+ int64 maxdiff = 0, x, tick = timer->gettick();
for(i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i];i++)
- if((x=DIFF_TICK(tick,ud->skillunit[i]->tick))>maxdiff){
- maxdiff=x;
- j=i;
+ if( (x=DIFF_TICK(tick,ud->skillunit[i]->tick)) > maxdiff ) {
+ maxdiff = x;
+ j = i;
}
skill->del_unitgroup(ud->skillunit[j],ALC_MARK);
//Since elements must have shifted, we use the last slot.
@@ -15411,7 +15473,7 @@ int skill_clear_unitgroup (struct block_list *src)
/*==========================================
*
*------------------------------------------*/
-struct skill_unit_group_tickset *skill_unitgrouptickset_search (struct block_list *bl, struct skill_unit_group *group, int tick) {
+struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list *bl, struct skill_unit_group *group, int64 tick) {
int i,j=-1,k,s,id;
struct unit_data *ud;
struct skill_unit_group_tickset *set;
@@ -15451,10 +15513,10 @@ struct skill_unit_group_tickset *skill_unitgrouptickset_search (struct block_lis
/*==========================================
*
*------------------------------------------*/
-int skill_unit_timer_sub_onplace (struct block_list* bl, va_list ap) {
+int skill_unit_timer_sub_onplace(struct block_list* bl, va_list ap) {
struct skill_unit* su = va_arg(ap,struct skill_unit *);
struct skill_unit_group* group = su->group;
- unsigned int tick = va_arg(ap,unsigned int);
+ int64 tick = va_arg(ap,int64);
if( !su->alive || bl->prev == NULL )
return 0;
@@ -15478,7 +15540,7 @@ int skill_unit_timer_sub_onplace (struct block_list* bl, va_list ap) {
int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
struct skill_unit* su = DB->data2ptr(data);
struct skill_unit_group* group = su->group;
- unsigned int tick = va_arg(ap,unsigned int);
+ int64 tick = va_arg(ap,int64);
bool dissonance;
struct block_list* bl = &su->bl;
@@ -15502,8 +15564,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
case UNT_GROUNDDRIFT_FIRE:
group->unit_id = UNT_USED_TRAPS;
//clif->changetraplook(bl, UNT_FIREPILLAR_ACTIVE);
- group->limit=DIFF_TICK(tick+1500,group->tick);
- su->limit=DIFF_TICK(tick+1500,group->tick);
+ group->limit=DIFF_TICK32(tick+1500,group->tick);
+ su->limit=DIFF_TICK32(tick+1500,group->tick);
break;
case UNT_ANKLESNARE:
@@ -15582,8 +15644,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
}
clif->changetraplook(bl,UNT_USED_TRAPS);
map->foreachinrange(skill->trap_splash, bl, skill->get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick);
- group->limit = DIFF_TICK(tick,group->tick)+1000;
- su->limit = DIFF_TICK(tick,group->tick)+1000;
+ group->limit = DIFF_TICK32(tick,group->tick)+1000;
+ su->limit = DIFF_TICK32(tick,group->tick)+1000;
group->unit_id = UNT_USED_TRAPS;
break;
@@ -15604,8 +15666,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
break;
}
// This unit isn't removed while SC_BANDING is active.
- group->limit = DIFF_TICK(tick+group->interval,group->tick);
- su->limit = DIFF_TICK(tick+group->interval,group->tick);
+ group->limit = DIFF_TICK32(tick+group->interval,group->tick);
+ su->limit = DIFF_TICK32(tick+group->interval,group->tick);
}
break;
@@ -15618,7 +15680,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
// icewall loses 50 hp every second
su->val1 -= SKILLUNITTIMER_INTERVAL/20; // trap's hp
if( su->val1 <= 0 && su->limit + group->tick > tick + 700 )
- su->limit = DIFF_TICK(tick+700,group->tick);
+ su->limit = DIFF_TICK32(tick+700,group->tick);
break;
case UNT_BLASTMINE:
case UNT_SKIDTRAP:
@@ -15635,7 +15697,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
skill->delunit(su);
else {
clif->changetraplook(bl, group->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
- group->limit = DIFF_TICK(tick, group->tick) + 1500;
+ group->limit = DIFF_TICK32(tick, group->tick) + 1500;
group->unit_id = UNT_USED_TRAPS;
}
}
@@ -15644,15 +15706,15 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
if( su->val1 <= 0 ) {
clif->changetraplook(bl,UNT_USED_TRAPS);
map->foreachinrange(skill->trap_splash, bl, skill->get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick);
- group->limit = DIFF_TICK(tick,group->tick)+1000;
- su->limit = DIFF_TICK(tick,group->tick)+1000;
+ group->limit = DIFF_TICK32(tick,group->tick)+1000;
+ su->limit = DIFF_TICK32(tick,group->tick)+1000;
group->unit_id = UNT_USED_TRAPS;
}
break;
case UNT_WALLOFTHORN:
if( su->val1 <= 0 ) {
group->unit_id = UNT_USED_TRAPS;
- group->limit = DIFF_TICK(tick, group->tick) + 1500;
+ group->limit = DIFF_TICK32(tick, group->tick) + 1500;
}
break;
}
@@ -15689,7 +15751,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
/*==========================================
* Executes on all skill units every SKILLUNITTIMER_INTERVAL miliseconds.
*------------------------------------------*/
-int skill_unit_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int skill_unit_timer(int tid, int64 tick, int id, intptr_t data) {
map->freeblock_lock();
skill->unit_db->foreach(skill->unit_db, skill->unit_timer_sub, tick);
@@ -15702,12 +15764,12 @@ int skill_unit_timer(int tid, unsigned int tick, int id, intptr_t data) {
/*==========================================
*
*------------------------------------------*/
-int skill_unit_move_sub (struct block_list* bl, va_list ap) {
+int skill_unit_move_sub(struct block_list* bl, va_list ap) {
struct skill_unit* su = (struct skill_unit *)bl;
struct skill_unit_group* group = su->group;
struct block_list* target = va_arg(ap,struct block_list*);
- unsigned int tick = va_arg(ap,unsigned int);
+ int64 tick = va_arg(ap,int64);
int flag = va_arg(ap,int);
bool dissonance;
@@ -15799,7 +15861,7 @@ int skill_unit_move_sub (struct block_list* bl, va_list ap) {
* units to figure out when they have left a group.
* flag&4: Force a onleft event (triggered when the bl is killed, for example)
*------------------------------------------*/
-int skill_unit_move (struct block_list *bl, unsigned int tick, int flag) {
+int skill_unit_move(struct block_list *bl, int64 tick, int flag) {
nullpo_ret(bl);
if( bl->prev == NULL )
@@ -15824,10 +15886,9 @@ int skill_unit_move (struct block_list *bl, unsigned int tick, int flag) {
/*==========================================
*
*------------------------------------------*/
-int skill_unit_move_unit_group (struct skill_unit_group *group, int16 m, int16 dx, int16 dy)
-{
+int skill_unit_move_unit_group(struct skill_unit_group *group, int16 m, int16 dx, int16 dy) {
int i,j;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
int *m_flag;
struct skill_unit *su1;
struct skill_unit *su2;
@@ -16681,7 +16742,7 @@ int skill_magicdecoy(struct map_session_data *sd, int nameid) {
md->special_state.ai = AI_FLORA;
if( md->deletetimer != INVALID_TIMER )
timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (timer->gettick() + skill->get_time(NC_MAGICDECOY,skill_id), mob->timer_delete, md->bl.id, 0);
+ md->deletetimer = timer->add(timer->gettick() + skill->get_time(NC_MAGICDECOY,skill_id), mob->timer_delete, md->bl.id, 0);
mob->spawn(md);
md->status.matk_min = md->status.matk_max = 250 + (50 * skill_id);
}
@@ -16879,13 +16940,13 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite
/**
* for Royal Guard's LG_TRAMPLE
**/
-int skill_destroy_trap( struct block_list *bl, va_list ap ) {
+int skill_destroy_trap(struct block_list *bl, va_list ap) {
struct skill_unit *su = (struct skill_unit *)bl;
struct skill_unit_group *sg;
- unsigned int tick;
+ int64 tick;
nullpo_ret(su);
- tick = va_arg(ap, unsigned int);
+ tick = va_arg(ap, int64);
if (su->alive && (sg = su->group) && skill->get_inf2(sg->skill_id)&INF2_TRAP) {
switch( sg->unit_id ) {
@@ -16912,13 +16973,14 @@ int skill_destroy_trap( struct block_list *bl, va_list ap ) {
/*==========================================
*
*------------------------------------------*/
-int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) {
+int skill_blockpc_end(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd = map->id2sd(id);
struct skill_cd * cd = NULL;
if (data <= 0 || data >= MAX_SKILL)
return 0;
- if (!sd) return 0;
+ if (!sd || !sd->blockskill[data])
+ return 0;
if( ( cd = idb_get(skill->cd_db,sd->status.char_id) ) ) {
int i;
@@ -16952,22 +17014,21 @@ int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) {
}
}
- if (sd->blockskill[data] != (0x1|(tid&0xFE))) return 0;
-
- sd->blockskill[data] = 0;
+ sd->blockskill[data] = false;
return 1;
}
/**
* flags a singular skill as being blocked from persistent usage.
* @param sd the player the skill delay affects
- * @param skill_id the skill which should be delayed
+ * @param skill_id the skill which should be delayed
* @param tick the length of time the delay should last
- * @param load whether this assignment is being loaded upon player login
* @return 0 if successful, -1 otherwise
*/
-int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick, bool load) {
+int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick) {
+ struct skill_cd* cd = NULL;
uint16 idx = skill->get_index(skill_id);
+ int64 now = timer->gettick();
nullpo_retr (-1, sd);
@@ -16975,53 +17036,63 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick,
return -1;
if (tick < 1) {
- sd->blockskill[idx] = 0;
+ sd->blockskill[idx] = false;
return -1;
}
- if( !load && battle_config.display_status_timers )
+ if( battle_config.display_status_timers )
clif->skill_cooldown(sd, skill_id, tick);
-
- if( !load ) {// not being loaded initially so ensure the skill delay is recorded
- struct skill_cd* cd = NULL;
+
+ if( !(cd = idb_get(skill->cd_db,sd->status.char_id)) ) {// create a new skill cooldown object for map storage
+ cd = ers_alloc(skill->cd_ers, struct skill_cd);
+
+ cd->cursor = 0;
+ memset(cd->entry, 0, sizeof(cd->entry));
+
+ idb_put( skill->cd_db, sd->status.char_id, cd );
+ } else {
int i;
- if( !(cd = idb_get(skill->cd_db,sd->status.char_id)) ) {// create a new skill cooldown object for map storage
- cd = ers_alloc(skill->cd_ers, struct skill_cd);
-
- cd->cursor = 0;
- memset(cd->entry, 0, sizeof(cd->entry));
-
- idb_put( skill->cd_db, sd->status.char_id, cd );
- }
-
for(i = 0; i < MAX_SKILL_TREE; i++) {
- if( !cd->entry[i] )
+ if( cd->entry[i] && cd->entry[i]->skidx == idx )
break;
}
-
- if( i == MAX_SKILL_TREE ) {
- ShowError("skill_blockpc_start: '%s' got over '%d' skill cooldowns, no room to save!\n",sd->status.name,MAX_SKILL_TREE);
- } else {
- cd->entry[cd->cursor] = ers_alloc(skill->cd_entry_ers,struct skill_cd_entry);
-
- cd->entry[cd->cursor]->duration = tick;
+
+ if( i != MAX_SKILL_TREE ) {/* duplicate, update necessary */
+ cd->entry[i]->duration = tick;
#if PACKETVER >= 20120604
- cd->entry[cd->cursor]->total = tick;
+ cd->entry[i]->total = tick;
#endif
- cd->entry[cd->cursor]->skidx = idx;
- cd->entry[cd->cursor]->skill_id = skill_id;
- cd->entry[cd->cursor]->started = timer->gettick();
-
- cd->cursor++;
+ cd->entry[i]->started = now;
+ timer->settick(cd->entry[i]->timer,now+tick);
+ return 0;
}
+
}
+
+ if( cd->cursor == MAX_SKILL_TREE ) {
+ ShowError("skill_blockpc_start: '%s' got over '%d' skill cooldowns, no room to save!\n",sd->status.name,MAX_SKILL_TREE);
+ return -1;
+ }
+
+ cd->entry[cd->cursor] = ers_alloc(skill->cd_entry_ers,struct skill_cd_entry);
+
+ cd->entry[cd->cursor]->duration = tick;
+#if PACKETVER >= 20120604
+ cd->entry[cd->cursor]->total = tick;
+#endif
+ cd->entry[cd->cursor]->skidx = idx;
+ cd->entry[cd->cursor]->skill_id = skill_id;
+ cd->entry[cd->cursor]->started = now;
+ cd->entry[cd->cursor]->timer = timer->add(now+tick,skill->blockpc_end,sd->bl.id,idx);
+
+ cd->cursor++;
- sd->blockskill[idx] = 0x1|(0xFE&timer->add(timer->gettick()+tick,skill->blockpc_end,sd->bl.id,idx));
+ sd->blockskill[idx] = true;
return 0;
}
-int skill_blockhomun_end(int tid, unsigned int tick, int id, intptr_t data) { //[orn]
+int skill_blockhomun_end(int tid, int64 tick, int id, intptr_t data) { //[orn]
struct homun_data *hd = (TBL_HOM*)map->id2bl(id);
if (data <= 0 || data >= MAX_SKILL)
return 0;
@@ -17046,7 +17117,7 @@ int skill_blockhomun_start(struct homun_data *hd, uint16 skill_id, int tick) { /
return timer->add(timer->gettick() + tick, skill->blockhomun_end, hd->bl.id, idx);
}
-int skill_blockmerc_end(int tid, unsigned int tick, int id, intptr_t data) {//[orn]
+int skill_blockmerc_end(int tid, int64 tick, int id, intptr_t data) {//[orn]
struct mercenary_data *md = (TBL_MER*)map->id2bl(id);
if( data <= 0 || data >= MAX_SKILL )
return 0;
@@ -17514,7 +17585,7 @@ int skill_get_elemental_type( uint16 skill_id , uint16 skill_lv ) {
void skill_cooldown_save(struct map_session_data * sd) {
int i;
struct skill_cd* cd = NULL;
- unsigned int now = 0;
+ int64 now = 0;
// always check to make sure the session properly exists
nullpo_retv(sd);
@@ -17527,7 +17598,11 @@ void skill_cooldown_save(struct map_session_data * sd) {
// process each individual cooldown associated with the character
for( i = 0; i < cd->cursor; i++ ) {
- cd->entry[i]->duration = DIFF_TICK(cd->entry[i]->started+cd->entry[i]->duration,now);
+ cd->entry[i]->duration = DIFF_TICK32(cd->entry[i]->started+cd->entry[i]->duration,now);
+ if( cd->entry[i]->timer != INVALID_TIMER ) {
+ timer->delete(cd->entry[i]->timer,skill->blockpc_end);
+ cd->entry[i]->timer = INVALID_TIMER;
+ }
}
}
@@ -17538,7 +17613,7 @@ void skill_cooldown_save(struct map_session_data * sd) {
void skill_cooldown_load(struct map_session_data * sd) {
int i;
struct skill_cd* cd = NULL;
- unsigned int now = 0;
+ int64 now = 0;
// always check to make sure the session properly exists
nullpo_retv(sd);
@@ -17554,8 +17629,8 @@ void skill_cooldown_load(struct map_session_data * sd) {
// process each individual cooldown associated with the character
for( i = 0; i < cd->cursor; i++ ) {
cd->entry[i]->started = now;
- // block the skill from usage but ensure it is not recorded (load = true)
- skill->blockpc_start( sd, cd->entry[i]->skill_id, cd->entry[i]->duration, true );
+ cd->entry[i]->timer = timer->add(timer->gettick()+cd->entry[i]->duration,skill->blockpc_end,sd->bl.id,cd->entry[i]->skidx);
+ sd->blockskill[cd->entry[i]->skidx] = true;
}
}
@@ -17608,6 +17683,7 @@ bool skill_parse_row_skilldb(char* split[], int columns, int current) {
safestrncpy(skill->db[idx].name, trim(split[15]), sizeof(skill->db[idx].name));
safestrncpy(skill->db[idx].desc, trim(split[16]), sizeof(skill->db[idx].desc));
strdb_iput(skill->name2id_db, skill->db[idx].name, skill_id);
+ script->set_constant2(skill->db[idx].name,(int)skill_id,0);
return true;
}
@@ -18291,4 +18367,5 @@ void skill_defaults(void) {
skill->cooldown_save = skill_cooldown_save;
skill->maelstrom_suction = skill_maelstrom_suction;
skill->get_new_group_id = skill_get_new_group_id;
+ skill->check_shadowform = skill_check_shadowform;
}
diff --git a/src/map/skill.h b/src/map/skill.h
index 0f89cd3be..fca4952ef 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -909,7 +909,14 @@ enum e_skill {
NPC_VENOMFOG,
NPC_MILLENNIUMSHIELD,
NPC_COMET,
-
+ NPC_WIDEWEB,
+ NPC_WIDESUCK,
+ NPC_STORMGUST2,
+ NPC_FIRESTORM,
+ NPC_REVERBERATION,
+ NPC_REVERBERATION_ATK,
+ NPC_LEX_AETERNA,
+
KN_CHARGEATK = 1001,
CR_SHRINK,
AS_SONICACCEL,
@@ -1271,7 +1278,7 @@ enum e_skill {
RL_R_TRIP_PLUSATK,
RL_B_FLICKER_ATK,
RL_GLITTERING_GREED_ATK,
-
+
KO_YAMIKUMO = 3001,
KO_RIGHT,
KO_LEFT,
@@ -1679,7 +1686,7 @@ struct skill_unit_group {
int map;
int target_flag; //Holds BCT_* flag for battle_check_target
int bl_flag; //Holds BL_* flag for map_foreachin* functions
- unsigned int tick;
+ int64 tick;
int limit,interval;
uint16 skill_id,skill_lv;
@@ -1708,7 +1715,7 @@ struct skill_unit {
};
struct skill_unit_group_tickset {
- unsigned int tick;
+ int64 tick;
int id;
};
@@ -1740,10 +1747,11 @@ struct s_skill_magicmushroom_db {
struct skill_cd_entry {
int duration;//milliseconds
#if PACKETVER >= 20120604
- int total;
+ int total;/* used for display on newer clients */
#endif
short skidx;//the skill index entries belong to
- unsigned int started;
+ int64 started;/* gettick() of when it started, used vs duration to measure how much left upon logout */
+ int timer;/* timer id */
uint16 skill_id;//skill id
};
@@ -1783,7 +1791,7 @@ struct s_skill_spellbook_db {
int point;
};
-typedef int (*SkillFunc)(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag);
+typedef int (*SkillFunc)(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 tick, int flag);
/**
* Skill.c Interface
@@ -1875,13 +1883,13 @@ struct skill_interface {
int (*get_casttype2) (uint16 index);
int (*name2id) (const char* name);
int (*isammotype) (struct map_session_data *sd, int skill);
- int (*castend_id) (int tid, unsigned int tick, int id, intptr_t data);
- int (*castend_pos) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*castend_id) (int tid, int64 tick, int id, intptr_t data);
+ int (*castend_pos) (int tid, int64 tick, int id, intptr_t data);
int (*castend_map) ( struct map_session_data *sd,uint16 skill_id, const char *mapname);
int (*cleartimerskill) (struct block_list *src);
- int (*addtimerskill) (struct block_list *src,unsigned int tick,int target,int x,int y,uint16 skill_id,uint16 skill_lv,int type,int flag);
- int (*additional_effect) ( struct block_list* src, struct block_list *bl,uint16 skill_id,uint16 skill_lv,int attack_type,int dmg_lv,unsigned int tick);
- int (*counter_additional_effect) ( struct block_list* src, struct block_list *bl,uint16 skill_id,uint16 skill_lv,int attack_type,unsigned int tick);
+ int (*addtimerskill) (struct block_list *src, int64 tick, int target, int x, int y, uint16 skill_id, uint16 skill_lv, int type, int flag);
+ int (*additional_effect) (struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int dmg_lv, int64 tick);
+ int (*counter_additional_effect) (struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int64 tick);
int (*blown) (struct block_list* src, struct block_list* target, int count, int8 dir, int flag);
int (*break_equip) (struct block_list *bl, unsigned short where, int rate, int flag);
int (*strip_equip) (struct block_list *bl, unsigned short where, int rate, int lv, int time);
@@ -1893,8 +1901,8 @@ struct skill_interface {
int (*del_unitgroup) (struct skill_unit_group *group, const char* file, int line, const char* func);
int (*clear_unitgroup) (struct block_list *src);
int (*clear_group) (struct block_list *bl, int flag);
- int (*unit_onplace) (struct skill_unit *src, struct block_list *bl, unsigned int tick);
- int (*unit_ondamaged) (struct skill_unit *src,struct block_list *bl,int64 damage,unsigned int tick);
+ int (*unit_onplace) (struct skill_unit *src, struct block_list *bl, int64 tick);
+ int (*unit_ondamaged) (struct skill_unit *src, struct block_list *bl, int64 damage, int64 tick);
int (*cast_fix) ( struct block_list *bl, uint16 skill_id, uint16 skill_lv);
int (*cast_fix_sc) ( struct block_list *bl, int time);
int (*vf_cast_fix) ( struct block_list *bl, double time, uint16 skill_id, uint16 skill_lv);
@@ -1904,12 +1912,12 @@ struct skill_interface {
int (*consume_requirement) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type);
struct skill_condition (*get_requirement) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
int (*check_pc_partner) (struct map_session_data *sd, uint16 skill_id, uint16* skill_lv, int range, int cast_flag);
- int (*unit_move) (struct block_list *bl,unsigned int tick,int flag);
- int (*unit_onleft) (uint16 skill_id, struct block_list *bl,unsigned int tick);
- int (*unit_onout) (struct skill_unit *src, struct block_list *bl, unsigned int tick);
+ int (*unit_move) (struct block_list *bl, int64 tick, int flag);
+ int (*unit_onleft) (uint16 skill_id, struct block_list *bl, int64 tick);
+ int (*unit_onout) (struct skill_unit *src, struct block_list *bl, int64 tick);
int (*unit_move_unit_group) ( struct skill_unit_group *group, int16 m,int16 dx,int16 dy);
int (*sit) (struct map_session_data *sd, int type);
- void (*brandishspear) (struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag);
+ void (*brandishspear) (struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag);
void (*repairweapon) (struct map_session_data *sd, int idx);
void (*identify) (struct map_session_data *sd,int idx);
void (*weaponrefine) (struct map_session_data *sd,int idx);
@@ -1924,25 +1932,25 @@ struct skill_interface {
int (*can_produce_mix) ( struct map_session_data *sd, int nameid, int trigger, int qty);
int (*produce_mix) ( struct map_session_data *sd, uint16 skill_id, int nameid, int slot1, int slot2, int slot3, int qty );
int (*arrow_create) ( struct map_session_data *sd,int nameid);
- int (*castend_nodamage_id) ( struct block_list *src, struct block_list *bl,uint16 skill_id,uint16 skill_lv,unsigned int tick,int flag );
- int (*castend_damage_id) ( struct block_list* src, struct block_list *bl,uint16 skill_id,uint16 skill_lv,unsigned int tick,int flag );
- int (*castend_pos2) ( struct block_list *src, int x,int y,uint16 skill_id,uint16 skill_lv,unsigned int tick,int flag);
- int (*blockpc_start) (struct map_session_data *sd, uint16 skill_id, int tick, bool load);
+ int (*castend_nodamage_id) (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag);
+ int (*castend_damage_id) (struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick,int flag);
+ int (*castend_pos2) (struct block_list *src, int x, int y, uint16 skill_id, uint16 skill_lv, int64 tick, int flag);
+ int (*blockpc_start) (struct map_session_data *sd, uint16 skill_id, int tick);
int (*blockhomun_start) (struct homun_data *hd, uint16 skill_id, int tick);
int (*blockmerc_start) (struct mercenary_data *md, uint16 skill_id, int tick);
- int (*attack) ( int attack_type, struct block_list* src, struct block_list *dsrc,struct block_list *bl,uint16 skill_id,uint16 skill_lv,unsigned int tick,int flag );
+ int (*attack) (int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag);
int (*attack_area) (struct block_list *bl,va_list ap);
int (*area_sub) (struct block_list *bl, va_list ap);
- int (*area_sub_count) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag);
+ int (*area_sub_count) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 tick, int flag);
int (*check_unit_range) (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv);
int (*check_unit_range_sub) (struct block_list *bl, va_list ap);
int (*check_unit_range2) (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv);
int (*check_unit_range2_sub) (struct block_list *bl, va_list ap);
void (*toggle_magicpower) (struct block_list *bl, uint16 skill_id);
int (*magic_reflect) (struct block_list* src, struct block_list* bl, int type);
- int (*onskillusage) (struct map_session_data *sd, struct block_list *bl, uint16 skill_id, unsigned int tick);
+ int (*onskillusage) (struct map_session_data *sd, struct block_list *bl, uint16 skill_id, int64 tick);
int (*cell_overlap) (struct block_list *bl, va_list ap);
- int (*timerskill) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*timerskill) (int tid, int64 tick, int id, intptr_t data);
int (*trap_splash) (struct block_list *bl, va_list ap);
int (*check_condition_mercenary) (struct block_list *bl, int skill_id, int lv, int type);
struct skill_unit_group *(*locate_element_field) (struct block_list *bl);
@@ -1955,26 +1963,26 @@ struct skill_interface {
int (*greed) (struct block_list *bl, va_list ap);
int (*destroy_trap) ( struct block_list *bl, va_list ap );
int (*icewall_block) (struct block_list *bl,va_list ap);
- struct skill_unit_group_tickset *(*unitgrouptickset_search) (struct block_list *bl, struct skill_unit_group *group, int tick);
+ struct skill_unit_group_tickset *(*unitgrouptickset_search) (struct block_list *bl, struct skill_unit_group *group, int64 tick);
bool (*dance_switch) (struct skill_unit* su, int flag);
int (*check_condition_char_sub) (struct block_list *bl, va_list ap);
int (*check_condition_mob_master_sub) (struct block_list *bl, va_list ap);
void (*brandishspear_first) (struct square *tc, uint8 dir, int16 x, int16 y);
void (*brandishspear_dir) (struct square* tc, uint8 dir, int are);
- int (*get_fixed_cast) ( uint16 skill_id ,uint16 skill_lv );
+ int (*get_fixed_cast) ( uint16 skill_id ,uint16 skill_lv );
int (*sit_count) (struct block_list *bl, va_list ap);
int (*sit_in) (struct block_list *bl, va_list ap);
int (*sit_out) (struct block_list *bl, va_list ap);
void (*unitsetmapcell) (struct skill_unit *src, uint16 skill_id, uint16 skill_lv, cell_t cell, bool flag);
- int (*unit_onplace_timer) (struct skill_unit *src, struct block_list *bl, unsigned int tick);
+ int (*unit_onplace_timer) (struct skill_unit *src, struct block_list *bl, int64 tick);
int (*unit_effect) (struct block_list* bl, va_list ap);
int (*unit_timer_sub_onplace) (struct block_list* bl, va_list ap);
int (*unit_move_sub) (struct block_list* bl, va_list ap);
- int (*blockpc_end) (int tid, unsigned int tick, int id, intptr_t data);
- int (*blockhomun_end) (int tid, unsigned int tick, int id, intptr_t data);
- int (*blockmerc_end) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*blockpc_end) (int tid, int64 tick, int id, intptr_t data);
+ int (*blockhomun_end) (int tid, int64 tick, int id, intptr_t data);
+ int (*blockmerc_end) (int tid, int64 tick, int id, intptr_t data);
int (*split_atoi) (char *str, int *val);
- int (*unit_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*unit_timer) (int tid, int64 tick, int id, intptr_t data);
int (*unit_timer_sub) (DBKey key, DBData *data, va_list ap);
void (*init_unit_layout) (void);
bool (*parse_row_skilldb) (char* split[], int columns, int current);
@@ -2011,6 +2019,7 @@ struct skill_interface {
void (*cooldown_save) (struct map_session_data * sd);
int (*maelstrom_suction) (struct block_list *bl, va_list ap);
int (*get_new_group_id) (void);
+ bool (*check_shadowform) (struct block_list *bl, int64 damage, int hit);
};
struct skill_interface *skill;
diff --git a/src/map/status.c b/src/map/status.c
index 8a2ac7cd6..c06de4dfe 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -906,6 +906,8 @@ void initChangeTables(void) {
status->IconChangeTable[SC_REBOUND] = SI_REBOUND;
status->IconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING;
status->IconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM;
+ status->IconChangeTable[SC_MOONSTAR] = SI_MOONSTAR;
+ status->IconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR;
//Other SC which are not necessarily associated to skills.
status->ChangeFlagTable[SC_ATTHASTE_POTION1] = SCB_ASPD;
@@ -995,6 +997,9 @@ void initChangeTables(void) {
status->ChangeFlagTable[SC_MTF_MATK] = SCB_MATK;
status->ChangeFlagTable[SC_MTF_MLEATKED] |= SCB_ALL;
+ status->ChangeFlagTable[SC_MOONSTAR] |= SCB_NONE;
+ status->ChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE;
+
/* status->DisplayType Table [Ind/Hercules] */
status->DisplayType[SC_ALL_RIDING] = true;
status->DisplayType[SC_PUSH_CART] = true;
@@ -1019,6 +1024,8 @@ void initChangeTables(void) {
status->DisplayType[SC__SHADOWFORM] = true;
status->DisplayType[SC__MANHOLE] = true;
status->DisplayType[SC_MONSTER_TRANSFORM] = true;
+ status->DisplayType[SC_MOONSTAR] = true;
+ status->DisplayType[SC_SUPER_STAR] = true;
#ifdef RENEWAL_EDP
// renewal EDP increases your weapon atk
@@ -2382,11 +2389,17 @@ int status_calc_pc_(struct map_session_data* sd, bool first) {
clif->sc_end(&sd->bl,sd->bl.id,SELF,SI_CLAIRVOYANCE);
memset(&sd->special_state,0,sizeof(sd->special_state));
- memset(&bstatus->max_hp, 0, sizeof(struct status_data)-(sizeof(bstatus->hp)+sizeof(bstatus->sp)));
-
- //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
- if (!sd->state.permanent_speed)
+
+ if (!sd->state.permanent_speed) {
+ memset(&bstatus->max_hp, 0, sizeof(struct status_data)-(sizeof(bstatus->hp)+sizeof(bstatus->sp)));
bstatus->speed = DEFAULT_WALK_SPEED;
+ } else {
+ int pSpeed = bstatus->speed;
+ memset(&bstatus->max_hp, 0, sizeof(struct status_data)-(sizeof(bstatus->hp)+sizeof(bstatus->sp)));
+ bstatus->speed = pSpeed;
+ }
+
+ //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
//Give them all modes except these (useful for clones)
bstatus->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK);
@@ -3663,6 +3676,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
if(flag&SCB_SPEED) {
struct unit_data *ud = unit->bl2ud(bl);
+
st->speed = status->calc_speed(bl, sc, bst->speed);
//Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER
@@ -3671,13 +3685,11 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) {
if (ud)
ud->state.change_walk_target = ud->state.speed_changed = 1;
- if( bl->type&BL_PC && st->speed < battle_config.max_walk_speed )
+ if( bl->type&BL_PC && !(sd && sd->state.permanent_speed) && st->speed < battle_config.max_walk_speed )
st->speed = battle_config.max_walk_speed;
if( bl->type&BL_HOM && battle_config.hom_setting&0x8 && ((TBL_HOM*)bl)->master)
st->speed = status->get_speed(&((TBL_HOM*)bl)->master->bl);
-
-
}
if(flag&SCB_CRI && bst->cri) {
@@ -5038,11 +5050,8 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
TBL_PC* sd = BL_CAST(BL_PC, bl);
int speed_rate;
- if( sc == NULL )
- return cap_value(speed,10,USHRT_MAX);
-
- if (sd && sd->state.permanent_speed)
- return (short)cap_value(speed,10,USHRT_MAX);
+ if( sc == NULL || ( sd && sd->state.permanent_speed ) )
+ return (unsigned short)cap_value(speed,MIN_WALK_SPEED,MAX_WALK_SPEED);
if( sd && sd->ud.skilltimer != INVALID_TIMER && (pc->checkskill(sd,SA_FREECAST) > 0 || sd->ud.skill_id == LG_EXEEDBREAK) )
{
@@ -5215,7 +5224,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
}
- return (short)cap_value(speed,10,USHRT_MAX);
+ return (unsigned short)cap_value(speed,MIN_WALK_SPEED,MAX_WALK_SPEED);
}
// flag&1 - fixed value [malufett]
@@ -6497,46 +6506,46 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
return 0; // Immune to status ailements
switch( type ) {
- case SC_QUAGMIRE://Tester said it protects against this and decrease agi.
- case SC_DEC_AGI:
- case SC_BURNING:
- case SC_FROSTMISTY:
+ case SC_QUAGMIRE://Tester said it protects against this and decrease agi.
+ case SC_DEC_AGI:
+ case SC_BURNING:
+ case SC_FROSTMISTY:
//case SC_WHITEIMPRISON://Need confirm. Protected against this in the past. [Rytech]
- case SC_MARSHOFABYSS:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_DEATHHURT:
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
- case SC_COLD: ////08/31/2011 - Class Balance Changes
- case SC_DEEP_SLEEP:
- case SC_MANDRAGORA:
- return 0;
+ case SC_MARSHOFABYSS:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+ case SC_COLD: ////08/31/2011 - Class Balance Changes
+ case SC_DEEP_SLEEP:
+ case SC_MANDRAGORA:
+ return 0;
}
} else if( sc->data[SC_INSPIRATION] ) {
if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX )
return 0; // Immune to status ailements
switch( type ) {
- case SC_DEEP_SLEEP:
- case SC_SATURDAY_NIGHT_FEVER:
- case SC_PYREXIA:
- case SC_DEATHHURT:
- case SC_MAGICMUSHROOM:
- case SC_VENOMBLEED:
- case SC_TOXIN:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__LAZINESS:
- case SC__UNLUCKY:
- case SC__WEAKNESS:
- case SC__BODYPAINT:
- case SC__IGNORANCE:
- return 0;
+ case SC_DEEP_SLEEP:
+ case SC_SATURDAY_NIGHT_FEVER:
+ case SC_PYREXIA:
+ case SC_DEATHHURT:
+ case SC_MAGICMUSHROOM:
+ case SC_VENOMBLEED:
+ case SC_TOXIN:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+ case SC__ENERVATION:
+ case SC__GROOMY:
+ case SC__LAZINESS:
+ case SC__UNLUCKY:
+ case SC__WEAKNESS:
+ case SC__BODYPAINT:
+ case SC__IGNORANCE:
+ return 0;
}
}
@@ -6551,292 +6560,292 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
undead_flag = battle->check_undead(st->race,st->def_ele);
//Check for inmunities / sc fails
switch (type) {
- case SC_DRUMBATTLE:
- case SC_NIBELUNGEN:
- case SC_INTOABYSS:
- case SC_SIEGFRIED:
- if( bl->type == BL_PC) {
- struct map_session_data *sd = BL_CAST(BL_PC,bl);
- if (!sd->status.party_id) return 0;
- }
- break;
- case SC_ANGRIFFS_MODUS:
- case SC_GOLDENE_FERSE:
- if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS])
- || (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE])
- )
- return 0;
- case SC_STONE:
- if(sc->data[SC_POWER_OF_GAIA])
- return 0;
- case SC_FREEZE:
- //Undead are immune to Freeze/Stone
- if (undead_flag && !(flag&1))
- return 0;
- case SC_DEEP_SLEEP:
- case SC_SLEEP:
- case SC_STUN:
- case SC_FROSTMISTY:
- case SC_COLD:
- if (sc->opt1)
- return 0; //Cannot override other opt1 status changes. [Skotlex]
- if((type == SC_FREEZE || type == SC_FROSTMISTY || type == SC_COLD) && sc->data[SC_WARMER])
- return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
- break;
+ case SC_DRUMBATTLE:
+ case SC_NIBELUNGEN:
+ case SC_INTOABYSS:
+ case SC_SIEGFRIED:
+ if( bl->type == BL_PC) {
+ struct map_session_data *sd = BL_CAST(BL_PC,bl);
+ if (!sd->status.party_id) return 0;
+ }
+ break;
+ case SC_ANGRIFFS_MODUS:
+ case SC_GOLDENE_FERSE:
+ if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS])
+ || (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE])
+ )
+ return 0;
+ case SC_STONE:
+ if(sc->data[SC_POWER_OF_GAIA])
+ return 0;
+ case SC_FREEZE:
+ //Undead are immune to Freeze/Stone
+ if (undead_flag && !(flag&1))
+ return 0;
+ case SC_DEEP_SLEEP:
+ case SC_SLEEP:
+ case SC_STUN:
+ case SC_FROSTMISTY:
+ case SC_COLD:
+ if (sc->opt1)
+ return 0; //Cannot override other opt1 status changes. [Skotlex]
+ if((type == SC_FREEZE || type == SC_FROSTMISTY || type == SC_COLD) && sc->data[SC_WARMER])
+ return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
+ break;
- //There all like berserk, do not everlap each other
- case SC_BERSERK:
- if( sc->data[SC__BLOODYLUST] || sc->data[SC_SATURDAY_NIGHT_FEVER] )
- return 0;
- break;
+ //There all like berserk, do not everlap each other
+ case SC_BERSERK:
+ if( sc->data[SC__BLOODYLUST] || sc->data[SC_SATURDAY_NIGHT_FEVER] )
+ return 0;
+ break;
- case SC_BURNING:
- if(sc->opt1 || sc->data[SC_FROSTMISTY])
- return 0;
- break;
+ case SC_BURNING:
+ if(sc->opt1 || sc->data[SC_FROSTMISTY])
+ return 0;
+ break;
- case SC_CRUCIS:
- //Only affects demons and undead element (but not players)
- if((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC)
- return 0;
- break;
- case SC_LEXAETERNA:
- if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] )
- return 0;
- break;
- case SC_KYRIE:
- if (bl->type == BL_MOB)
- return 0;
- break;
- case SC_OVERTHRUST:
- if (sc->data[SC_OVERTHRUSTMAX])
- return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
- case SC_OVERTHRUSTMAX:
- if( sc->option&OPTION_MADOGEAR )
- return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
- break;
- case SC_ADRENALINE:
- if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE)))
- return 0;
- if (sc->data[SC_QUAGMIRE] ||
- sc->data[SC_DEC_AGI] ||
- sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind]
+ case SC_CRUCIS:
+ //Only affects demons and undead element (but not players)
+ if((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC)
+ return 0;
+ break;
+ case SC_LEXAETERNA:
+ if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] )
+ return 0;
+ break;
+ case SC_KYRIE:
+ if (bl->type == BL_MOB)
+ return 0;
+ break;
+ case SC_OVERTHRUST:
+ if (sc->data[SC_OVERTHRUSTMAX])
+ return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
+ case SC_OVERTHRUSTMAX:
+ if( sc->option&OPTION_MADOGEAR )
+ return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
+ break;
+ case SC_ADRENALINE:
+ if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE)))
+ return 0;
+ if (sc->data[SC_QUAGMIRE] ||
+ sc->data[SC_DEC_AGI] ||
+ sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind]
+ )
+ return 0;
+ break;
+ case SC_ADRENALINE2:
+ if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE2)))
+ return 0;
+ if (sc->data[SC_QUAGMIRE] ||
+ sc->data[SC_DEC_AGI]
)
- return 0;
- break;
- case SC_ADRENALINE2:
- if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE2)))
- return 0;
- if (sc->data[SC_QUAGMIRE] ||
- sc->data[SC_DEC_AGI]
- )
- return 0;
- break;
- case SC_MAGNIFICAT:
- if( sc->data[SC_OFFERTORIUM] || sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat
- return 0;
- break;
- case SC_ONEHANDQUICKEN:
- case SC_MER_QUICKEN:
- case SC_TWOHANDQUICKEN:
- if(sc->data[SC_DEC_AGI])
- return 0;
+ return 0;
+ break;
+ case SC_MAGNIFICAT:
+ if( sc->data[SC_OFFERTORIUM] || sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat
+ return 0;
+ break;
+ case SC_ONEHANDQUICKEN:
+ case SC_MER_QUICKEN:
+ case SC_TWOHANDQUICKEN:
+ if(sc->data[SC_DEC_AGI])
+ return 0;
- case SC_CONCENTRATION:
- case SC_SPEARQUICKEN:
- case SC_TRUESIGHT:
- case SC_WINDWALK:
- case SC_CARTBOOST:
- case SC_ASSNCROS:
- if(sc->option&OPTION_MADOGEAR)
- return 0;//Mado is immune to wind walk, cart boost, etc (others above) [Ind]
- case SC_INC_AGI:
- if (sc->data[SC_QUAGMIRE])
- return 0;
- break;
- case SC_CLOAKING:
- //Avoid cloaking with no wall and low skill level. [Skotlex]
- //Due to the cloaking card, we have to check the wall versus to known
- //skill level rather than the used one. [Skotlex]
- //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
- if( sd && pc->checkskill(sd, AS_CLOAKING) < 3 && !skill->check_cloaking(bl,NULL) )
- return 0;
- break;
- case SC_MODECHANGE:
- {
- int mode;
- struct status_data *bst = status->get_base_status(bl);
- if (!bst) return 0;
- if (sc->data[type]) {
- //Pile up with previous values.
- if(!val2) val2 = sc->data[type]->val2;
- val3 |= sc->data[type]->val3;
- val4 |= sc->data[type]->val4;
- }
- mode = val2 ? val2 : bst->mode; //Base mode
- if (val4) mode&=~val4; //Del mode
- if (val3) mode|= val3; //Add mode
- if (mode == bst->mode) { //No change.
- if (sc->data[type]) //Abort previous status
- return status_change_end(bl, type, INVALID_TIMER);
- return 0;
- }
- }
- break;
- //Strip skills, need to divest something or it fails.
- case SC_NOEQUIPWEAPON:
- if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data
- int i;
- opt_flag = 0; //Reuse to check success condition.
- if(sd->bonus.unstripable_equip&EQP_WEAPON)
+ case SC_CONCENTRATION:
+ case SC_SPEARQUICKEN:
+ case SC_TRUESIGHT:
+ case SC_WINDWALK:
+ case SC_CARTBOOST:
+ case SC_ASSNCROS:
+ if(sc->option&OPTION_MADOGEAR)
+ return 0;//Mado is immune to wind walk, cart boost, etc (others above) [Ind]
+ case SC_INC_AGI:
+ if (sc->data[SC_QUAGMIRE])
+ return 0;
+ break;
+ case SC_CLOAKING:
+ //Avoid cloaking with no wall and low skill level. [Skotlex]
+ //Due to the cloaking card, we have to check the wall versus to known
+ //skill level rather than the used one. [Skotlex]
+ //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL))
+ if( sd && pc->checkskill(sd, AS_CLOAKING) < 3 && !skill->check_cloaking(bl,NULL) )
return 0;
+ break;
+ case SC_MODECHANGE:
+ {
+ int mode;
+ struct status_data *bst = status->get_base_status(bl);
+ if (!bst) return 0;
+ if (sc->data[type]) {
+ //Pile up with previous values.
+ if(!val2) val2 = sc->data[type]->val2;
+ val3 |= sc->data[type]->val3;
+ val4 |= sc->data[type]->val4;
+ }
+ mode = val2 ? val2 : bst->mode; //Base mode
+ if (val4) mode&=~val4; //Del mode
+ if (val3) mode|= val3; //Add mode
+ if (mode == bst->mode) { //No change.
+ if (sc->data[type]) //Abort previous status
+ return status_change_end(bl, type, INVALID_TIMER);
+ return 0;
+ }
+ }
+ break;
+ //Strip skills, need to divest something or it fails.
+ case SC_NOEQUIPWEAPON:
+ if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data
+ int i;
+ opt_flag = 0; //Reuse to check success condition.
+ if(sd->bonus.unstripable_equip&EQP_WEAPON)
+ return 0;
- i = sd->equip_index[EQI_HAND_R];
- if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
- opt_flag|=2;
+ i = sd->equip_index[EQI_HAND_R];
+ if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) {
+ opt_flag|=2;
+ pc->unequipitem(sd,i,3);
+ }
+ if (!opt_flag) return 0;
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_NOEQUIPSHIELD:
+ if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off..
+ else
+ if (sd && !(flag&4)) {
+ int i;
+ if(sd->bonus.unstripable_equip&EQP_SHIELD)
+ return 0;
+ i = sd->equip_index[EQI_HAND_L];
+ if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR )
+ return 0;
+ pc->unequipitem(sd,i,3);
+ }
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_NOEQUIPARMOR:
+ if (sd && !(flag&4)) {
+ int i;
+ if(sd->bonus.unstripable_equip&EQP_ARMOR)
+ return 0;
+ i = sd->equip_index[EQI_ARMOR];
+ if ( i < 0 || !sd->inventory_data[i] )
+ return 0;
pc->unequipitem(sd,i,3);
}
- if (!opt_flag) return 0;
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_NOEQUIPSHIELD:
- if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off..
- else
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_NOEQUIPHELM:
if (sd && !(flag&4)) {
int i;
- if(sd->bonus.unstripable_equip&EQP_SHIELD)
+ if(sd->bonus.unstripable_equip&EQP_HELM)
return 0;
- i = sd->equip_index[EQI_HAND_L];
- if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR )
+ i = sd->equip_index[EQI_HEAD_TOP];
+ if ( i < 0 || !sd->inventory_data[i] )
return 0;
pc->unequipitem(sd,i,3);
}
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
- case SC_NOEQUIPARMOR:
- if (sd && !(flag&4)) {
- int i;
- if(sd->bonus.unstripable_equip&EQP_ARMOR)
+ case SC_MER_FLEE:
+ case SC_MER_ATK:
+ case SC_MER_HP:
+ case SC_MER_SP:
+ case SC_MER_HIT:
+ if( bl->type != BL_MER )
+ return 0; // Stats only for Mercenaries
+ break;
+ case SC_FOOD_STR:
+ if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1)
return 0;
- i = sd->equip_index[EQI_ARMOR];
- if ( i < 0 || !sd->inventory_data[i] )
+ break;
+ case SC_FOOD_AGI:
+ if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1)
return 0;
- pc->unequipitem(sd,i,3);
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_NOEQUIPHELM:
- if (sd && !(flag&4)) {
- int i;
- if(sd->bonus.unstripable_equip&EQP_HELM)
+ break;
+ case SC_FOOD_VIT:
+ if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1)
return 0;
- i = sd->equip_index[EQI_HEAD_TOP];
- if ( i < 0 || !sd->inventory_data[i] )
+ break;
+ case SC_FOOD_INT:
+ if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1)
return 0;
- pc->unequipitem(sd,i,3);
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_MER_FLEE:
- case SC_MER_ATK:
- case SC_MER_HP:
- case SC_MER_SP:
- case SC_MER_HIT:
- if( bl->type != BL_MER )
- return 0; // Stats only for Mercenaries
- break;
- case SC_FOOD_STR:
- if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_AGI:
- if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_VIT:
- if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_INT:
- if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_DEX:
- if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_LUK:
- if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_STR_CASH:
- if (sc->data[SC_FOOD_STR] && sc->data[SC_FOOD_STR]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_AGI_CASH:
- if (sc->data[SC_FOOD_AGI] && sc->data[SC_FOOD_AGI]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_VIT_CASH:
- if (sc->data[SC_FOOD_VIT] && sc->data[SC_FOOD_VIT]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_INT_CASH:
- if (sc->data[SC_FOOD_INT] && sc->data[SC_FOOD_INT]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_DEX_CASH:
- if (sc->data[SC_FOOD_DEX] && sc->data[SC_FOOD_DEX]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_LUK_CASH:
- if (sc->data[SC_FOOD_LUK] && sc->data[SC_FOOD_LUK]->val1 > val1)
- return 0;
- break;
- case SC_CAMOUFLAGE:
- if( sd && pc->checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill->check_camouflage(bl,NULL) )
- return 0;
- break;
- case SC__STRIPACCESSARY:
- if( sd ) {
- int i = -1;
- if( !(sd->bonus.unstripable_equip&EQP_ACC_L) ) {
- i = sd->equip_index[EQI_ACC_L];
- if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
- pc->unequipitem(sd,i,3); //L-Accessory
- } if( !(sd->bonus.unstripable_equip&EQP_ACC_R) ) {
- i = sd->equip_index[EQI_ACC_R];
- if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
- pc->unequipitem(sd,i,3); //R-Accessory
+ break;
+ case SC_FOOD_DEX:
+ if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_LUK:
+ if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_STR_CASH:
+ if (sc->data[SC_FOOD_STR] && sc->data[SC_FOOD_STR]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_AGI_CASH:
+ if (sc->data[SC_FOOD_AGI] && sc->data[SC_FOOD_AGI]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_VIT_CASH:
+ if (sc->data[SC_FOOD_VIT] && sc->data[SC_FOOD_VIT]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_INT_CASH:
+ if (sc->data[SC_FOOD_INT] && sc->data[SC_FOOD_INT]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_DEX_CASH:
+ if (sc->data[SC_FOOD_DEX] && sc->data[SC_FOOD_DEX]->val1 > val1)
+ return 0;
+ break;
+ case SC_FOOD_LUK_CASH:
+ if (sc->data[SC_FOOD_LUK] && sc->data[SC_FOOD_LUK]->val1 > val1)
+ return 0;
+ break;
+ case SC_CAMOUFLAGE:
+ if( sd && pc->checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill->check_camouflage(bl,NULL) )
+ return 0;
+ break;
+ case SC__STRIPACCESSARY:
+ if( sd ) {
+ int i = -1;
+ if( !(sd->bonus.unstripable_equip&EQP_ACC_L) ) {
+ i = sd->equip_index[EQI_ACC_L];
+ if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
+ pc->unequipitem(sd,i,3); //L-Accessory
+ } if( !(sd->bonus.unstripable_equip&EQP_ACC_R) ) {
+ i = sd->equip_index[EQI_ACC_R];
+ if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR )
+ pc->unequipitem(sd,i,3); //R-Accessory
+ }
+ if( i < 0 )
+ return 0;
}
- if( i < 0 )
+ if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
+ break;
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+ { // it doesn't stack or even renewed
+ int i = SC_TOXIN;
+ for(; i<= SC_LEECHESEND; i++)
+ if(sc->data[i]) return 0;
+ }
+ break;
+ case SC_SATURDAY_NIGHT_FEVER:
+ if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION])
return 0;
- }
- if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
- break;
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_DEATHHURT:
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
- { // it doesn't stack or even renewed
- int i = SC_TOXIN;
- for(; i<= SC_LEECHESEND; i++)
- if(sc->data[i]) return 0;
- }
- break;
- case SC_SATURDAY_NIGHT_FEVER:
- if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION])
- return 0;
- break;
- case SC_OFFERTORIUM:
- if (sc->data[SC_MAGNIFICAT])
- return 0;
- break;
+ break;
+ case SC_OFFERTORIUM:
+ if (sc->data[SC_MAGNIFICAT])
+ return 0;
+ break;
}
//Check for BOSS resistances
@@ -6844,1574 +6853,1891 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX)
return 0;
switch (type) {
- case SC_BLESSING:
- case SC_DEC_AGI:
- case SC_PROVOKE:
- case SC_COMA:
- case SC_GRAVITATION:
- case SC_NJ_SUITON:
- case SC_RICHMANKIM:
- case SC_ROKISWEIL:
- case SC_FOGWALL:
- case SC_FROSTMISTY:
- case SC_BURNING:
- case SC_MARSHOFABYSS:
- case SC_ADORAMUS:
- case SC_NEEDLE_OF_PARALYZE:
- case SC_DEEP_SLEEP:
- case SC_COLD:
+ case SC_BLESSING:
+ case SC_DEC_AGI:
+ case SC_PROVOKE:
+ case SC_COMA:
+ case SC_GRAVITATION:
+ case SC_NJ_SUITON:
+ case SC_RICHMANKIM:
+ case SC_ROKISWEIL:
+ case SC_FOGWALL:
+ case SC_FROSTMISTY:
+ case SC_BURNING:
+ case SC_MARSHOFABYSS:
+ case SC_ADORAMUS:
+ case SC_NEEDLE_OF_PARALYZE:
+ case SC_DEEP_SLEEP:
+ case SC_COLD:
+
+ // Exploit prevention - kRO Fix
+ case SC_PYREXIA:
+ case SC_DEATHHURT:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+
+ // Ranger Effects
+ case SC_WUGBITE:
+ case SC_ELECTRICSHOCKER:
+ case SC_MAGNETICFIELD:
+
+ // Masquerades
+ case SC__ENERVATION:
+ case SC__GROOMY:
+ case SC__LAZINESS:
+ case SC__UNLUCKY:
+ case SC__WEAKNESS:
+ case SC__IGNORANCE:
- // Exploit prevention - kRO Fix
- case SC_PYREXIA:
- case SC_DEATHHURT:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
-
- // Ranger Effects
- case SC_WUGBITE:
- case SC_ELECTRICSHOCKER:
- case SC_MAGNETICFIELD:
-
- // Masquerades
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__LAZINESS:
- case SC__UNLUCKY:
- case SC__WEAKNESS:
- case SC__IGNORANCE:
-
- return 0;
+ return 0;
}
}
//Before overlapping fail, one must check for status cured.
switch (type) {
- case SC_BLESSING:
- //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
- //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
- if ((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) {
- status_change_end(bl, SC_CURSE, INVALID_TIMER);
- if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- }
- break;
- case SC_INC_AGI:
- status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
- break;
- case SC_QUAGMIRE:
- status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
- status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
- status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- //Also blocks the ones below...
- case SC_DEC_AGI:
- status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
- //Also blocks the ones below...
- case SC_DONTFORGETME:
- status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
- status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
- break;
- case SC_ONEHANDQUICKEN:
- //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
- status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
- break;
- case SC_OVERTHRUSTMAX:
- //Cancels Normal Overthrust. [Skotlex]
- status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
- break;
- case SC_KYRIE:
- //Cancels Assumptio
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- break;
- case SC_DELUGE:
- if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- break;
- case SC_SILENCE:
- if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
- status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
- break;
- case SC_HIDING:
- status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
- status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
- break;
- case SC_BERSERK:
- if( val3 == SC__BLOODYLUST )
- break;
- if(battle_config.berserk_cancels_buffs) {
- status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
- status_change_end(bl, SC_PARRYING, INVALID_TIMER);
- status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
- status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
- }
-#ifdef RENEWAL
- else {
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- }
-#endif
- break;
- case SC_ASSUMPTIO:
- status_change_end(bl, SC_KYRIE, INVALID_TIMER);
- status_change_end(bl, SC_KAITE, INVALID_TIMER);
- break;
- case SC_KAITE:
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- break;
- case SC_CARTBOOST:
- if(sc->data[SC_DEC_AGI])
- { //Cancel Decrease Agi, but take no further effect [Skotlex]
- status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
- return 0;
- }
- break;
- case SC_FUSION:
- status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
- break;
- case SC_GS_ADJUSTMENT:
- status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER);
- break;
- case SC_GS_MADNESSCANCEL:
- status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER);
- break;
- //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
- case SC_PROPERTYUNDEAD:
- status_change_end(bl, SC_BLESSING, INVALID_TIMER);
- status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
- break;
- case SC_FOOD_STR:
- status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_AGI:
- status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_VIT:
- status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_INT:
- status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_DEX:
- status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_LUK:
- status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_STR_CASH:
- status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
- break;
- case SC_FOOD_AGI_CASH:
- status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
- break;
- case SC_FOOD_VIT_CASH:
- status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
- break;
- case SC_FOOD_INT_CASH:
- status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
- break;
- case SC_FOOD_DEX_CASH:
- status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
- break;
- case SC_FOOD_LUK_CASH:
- status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
- break;
- case SC_ENDURE:
- if( val4 )
- status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
- break;
- case SC_FIGHTINGSPIRIT:
- status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
- break;
- case SC_MARSHOFABYSS:
- status_change_end(bl, SC_INCAGI, INVALID_TIMER);
- status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
- break;
- case SC_SWING:
- case SC_SYMPHONY_LOVE:
- case SC_MOONLIT_SERENADE:
- case SC_RUSH_WINDMILL:
- case SC_ECHOSONG:
- case SC_HARMONIZE: //group A doesn't overlap
- if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER);
- if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
- if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
- if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
- if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
- if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
- break;
- case SC_SIREN:
- case SC_DEEP_SLEEP:
- case SC_GLOOMYDAY:
- case SC_SONG_OF_MANA:
- case SC_DANCE_WITH_WUG:
- case SC_SATURDAY_NIGHT_FEVER:
- case SC_LERADS_DEW:
- case SC_MELODYOFSINK:
- case SC_BEYOND_OF_WARCRY:
- case SC_UNLIMITED_HUMMING_VOICE: //group B
- if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER);
- if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
- if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
- if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
- if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
- if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
- if (type != SC_GLOOMYDAY) {
- status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
- status_change_end(bl, SC_GLOOMYDAY_SK, INVALID_TIMER);
- }
- if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
- if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
- if (type != SC_SATURDAY_NIGHT_FEVER) {
- if (sc->data[SC_SATURDAY_NIGHT_FEVER]) {
- sc->data[SC_SATURDAY_NIGHT_FEVER]->val2 = 0; //mark to not lose hp
- status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER);
+ case SC_BLESSING:
+ //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
+ //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
+ if ((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) {
+ status_change_end(bl, SC_CURSE, INVALID_TIMER);
+ if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
}
- }
- break;
- case SC_REFLECTSHIELD:
- status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
- break;
- case SC_LG_REFLECTDAMAGE:
- status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
- break;
- case SC_SHIELDSPELL_DEF:
- case SC_SHIELDSPELL_MDEF:
- case SC_SHIELDSPELL_REF:
- status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
- if( type != SC_SHIELDSPELL_DEF )
- status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
- if( type != SC_SHIELDSPELL_MDEF )
- status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
- if( type != SC_SHIELDSPELL_REF )
- status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
- break;
- case SC_GENTLETOUCH_ENERGYGAIN:
- case SC_GENTLETOUCH_CHANGE:
- case SC_GENTLETOUCH_REVITALIZE:
- if( type != SC_GENTLETOUCH_REVITALIZE )
- status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER);
- if( type != SC_GENTLETOUCH_ENERGYGAIN )
- status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER);
- if( type != SC_GENTLETOUCH_CHANGE )
- status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER);
- break;
- case SC_INVINCIBLE:
- status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
- break;
- case SC_INVINCIBLEOFF:
- status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
- break;
- case SC_MAGICPOWER:
- status_change_end(bl, type, INVALID_TIMER);
- break;
- }
-
- //Check for overlapping fails
- if( (sce = sc->data[type]) ) {
- switch( type ) {
- case SC_MER_FLEE:
- case SC_MER_ATK:
- case SC_MER_HP:
- case SC_MER_SP:
- case SC_MER_HIT:
- if( sce->val1 > val1 )
- val1 = sce->val1;
break;
- case SC_ADRENALINE:
- case SC_ADRENALINE2:
- case SC_WEAPONPERFECT:
- case SC_OVERTHRUST:
- if (sce->val2 > val2)
- return 0;
+ case SC_INC_AGI:
+ status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
break;
- case SC_S_LIFEPOTION:
- case SC_L_LIFEPOTION:
- case SC_CASH_BOSS_ALARM:
- case SC_STUN:
- case SC_SLEEP:
- case SC_POISON:
- case SC_CURSE:
- case SC_SILENCE:
- case SC_CONFUSION:
- case SC_BLIND:
- case SC_BLOODING:
- case SC_DPOISON:
- case SC_RG_CCONFINE_S: //Can't be re-closed in.
- case SC_MARIONETTE_MASTER:
- case SC_MARIONETTE:
- case SC_NOCHAT:
- case SC_HLIF_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation.
- case SC__INVISIBILITY:
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__IGNORANCE:
- case SC__LAZINESS:
- case SC__WEAKNESS:
- case SC__UNLUCKY:
- return 0;
- case SC_COMBOATTACK:
- case SC_DANCING:
- case SC_DEVOTION:
- case SC_ATTHASTE_POTION1:
- case SC_ATTHASTE_POTION2:
- case SC_ATTHASTE_POTION3:
- case SC_ATTHASTE_INFINITY:
- case SC_PLUSATTACKPOWER:
- case SC_PLUSMAGICPOWER:
- case SC_ENCHANTARMS:
- case SC_ARMORPROPERTY:
- case SC_ARMOR_RESIST:
- break;
- case SC_GOSPEL:
- //Must not override a casting gospel char.
- if(sce->val4 == BCT_SELF)
- return 0;
- if(sce->val1 > val1)
- return 1;
+ case SC_QUAGMIRE:
+ status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
+ //Also blocks the ones below...
+ case SC_DEC_AGI:
+ status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
+ //Also blocks the ones below...
+ case SC_DONTFORGETME:
+ status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
+ status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
break;
- case SC_ENDURE:
- if(sce->val4 && !val4)
- return 1; //Don't let you override infinite endure.
- if(sce->val1 > val1)
- return 1;
+ case SC_ONEHANDQUICKEN:
+ //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
+ status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
break;
- case SC_KAAHI:
- //Kaahi overwrites previous level regardless of existing level.
- //Delete timer if it exists.
- if (sce->val4 != INVALID_TIMER) {
- timer->delete(sce->val4,status->kaahi_heal_timer);
- sce->val4 = INVALID_TIMER;
- }
+ case SC_OVERTHRUSTMAX:
+ //Cancels Normal Overthrust. [Skotlex]
+ status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
break;
- case SC_JAILED:
- //When a player is already jailed, do not edit the jail data.
- val2 = sce->val2;
- val3 = sce->val3;
- val4 = sce->val4;
+ case SC_KYRIE:
+ //Cancels Assumptio
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
break;
- case SC_LERADS_DEW:
- if (sc && sc->data[SC_BERSERK])
- return 0;
- case SC_SHAPESHIFT:
- case SC_PROPERTYWALK:
+ case SC_DELUGE:
+ if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
break;
- case SC_LEADERSHIP:
- case SC_GLORYWOUNDS:
- case SC_SOULCOLD:
- case SC_HAWKEYES:
- if( sce->val4 && !val4 )//you cannot override master guild aura
- return 0;
+ case SC_SILENCE:
+ if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
+ status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
break;
- case SC_JOINTBEAT:
- val2 |= sce->val2; // stackable ailments
- default:
- if(sce->val1 > val1)
- return 1; //Return true to not mess up skill animations. [Skotlex]
- }
- }
-
- vd = status->get_viewdata(bl);
- calc_flag = status->ChangeFlagTable[type];
- if(!(flag&4)) { //&4 - Do not parse val settings when loading SCs
- switch(type) {
- case SC_DEC_AGI:
- case SC_INC_AGI:
- val2 = 2 + val1; //Agi change
+ case SC_HIDING:
+ status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
+ status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
break;
- case SC_ENDURE:
- val2 = 7; // Hit-count [Celest]
- if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground && !val4 ) {
- struct map_session_data *tsd;
- if( sd ) {
- int i;
- for( i = 0; i < 5; i++ ) {
- if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
- status->change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
- }
- } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
- status->change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
+ case SC_BERSERK:
+ if( val3 == SC__BLOODYLUST )
+ break;
+ if(battle_config.berserk_cancels_buffs) {
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_PARRYING, INVALID_TIMER);
+ status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
+ status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
}
- //val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
- if( val4 )
- tick = -1;
+ #ifdef RENEWAL
+ else {
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ }
+ #endif
break;
- case SC_AUTOBERSERK:
- if (st->hp < st->max_hp>>2 &&
- (!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
- sc_start4(bl,SC_PROVOKE,100,10,1,0,0,60000);
- tick = -1;
+ case SC_ASSUMPTIO:
+ status_change_end(bl, SC_KYRIE, INVALID_TIMER);
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
break;
- case SC_CRUCIS:
- val2 = 10 + 4*val1; //Def reduction
- tick = -1;
- clif->emotion(bl,E_SWT);
+ case SC_KAITE:
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
break;
- case SC_MAXIMIZEPOWER:
- tick_time = val2 = tick>0?tick:60000;
- tick = -1; // duration sent to the client should be infinite
+ case SC_CARTBOOST:
+ if(sc->data[SC_DEC_AGI])
+ { //Cancel Decrease Agi, but take no further effect [Skotlex]
+ status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
+ return 0;
+ }
break;
- case SC_EDP: // [Celest]
- val2 = val1 + 2; //Chance to Poison enemies.
- val3 = 50*(val1+1); //Damage increase (+50 +50*lv%)
-#ifdef RENEWAL_EDP
- val4 = 100 * ((val1 + 1)/2 + 2);
-#endif
- if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
- tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
+ case SC_FUSION:
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
break;
- case SC_POISONREACT:
- val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
- val3=50; // + 5*val1; //Chance to counter. [Skotlex]
+ case SC_GS_ADJUSTMENT:
+ status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER);
break;
- case SC_MAGICROD:
- val2 = val1*20; //SP gained
+ case SC_GS_MADNESSCANCEL:
+ status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER);
break;
- case SC_KYRIE:
- val2 = (int64)st->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb
- val3 = (val1 / 2 + 5); //Hits
+ //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
+ case SC_PROPERTYUNDEAD:
+ status_change_end(bl, SC_BLESSING, INVALID_TIMER);
+ status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
break;
- case SC_MAGICPOWER:
- //val1: Skill lv
- val2 = 1; //Lasts 1 invocation
- val3 = 5*val1; //Matk% increase
- val4 = 0; // 0 = ready to be used, 1 = activated and running
- break;
- case SC_SACRIFICE:
- val2 = 5; //Lasts 5 hits
- tick = -1;
- break;
- case SC_ENCHANTPOISON:
- val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate
- case SC_ASPERSIO:
- case SC_PROPERTYFIRE:
- case SC_PROPERTYWATER:
- case SC_PROPERTYWIND:
- case SC_PROPERTYGROUND:
- case SC_PROPERTYDARK:
- case SC_PROPERTYTELEKINESIS:
- skill->enchant_elemental_end(bl,type);
- break;
- case SC_ARMOR_PROPERTY:
- // val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4)
- // val2 : Element (When no element, random one is picked)
- // val3 : 0 = called by skill 1 = called by script (fixed level)
- if( !val2 ) val2 = rnd()%ELE_MAX;
-
- if( val1 == 1 && val3 == 0 )
- val1 = 1 + rnd()%4;
- else if( val1 > 4 )
- val1 = 4; // Max Level
- val3 = 0; // Not need to keep this info.
+ case SC_FOOD_STR:
+ status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
break;
- case SC_PROVIDENCE:
- val2=val1*5; //Race/Ele resist
+ case SC_FOOD_AGI:
+ status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
break;
- case SC_REFLECTSHIELD:
- val2=10+val1*3; // %Dmg reflected
- if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) ) {
- struct map_session_data *tsd;
- if( sd ) {
- int i;
- for( i = 0; i < 5; i++ ) {
- if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
- status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
- }
- } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
- status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
- }
+ case SC_FOOD_VIT:
+ status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
break;
- case SC_NOEQUIPWEAPON:
- if (!sd) //Watk reduction
- val2 = 25;
+ case SC_FOOD_INT:
+ status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
break;
- case SC_NOEQUIPSHIELD:
- if (!sd) //Def reduction
- val2 = 15;
+ case SC_FOOD_DEX:
+ status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
break;
- case SC_NOEQUIPARMOR:
- if (!sd) //Vit reduction
- val2 = 40;
+ case SC_FOOD_LUK:
+ status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
break;
- case SC_NOEQUIPHELM:
- if (!sd) //Int reduction
- val2 = 40;
+ case SC_FOOD_STR_CASH:
+ status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
break;
- case SC_AUTOSPELL:
- //Val1 Skill LV of Autospell
- //Val2 Skill ID to cast
- //Val3 Max Lv to cast
- val4 = 5 + val1*2; //Chance of casting
+ case SC_FOOD_AGI_CASH:
+ status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
break;
- case SC_VOLCANO:
- val2 = val1*10; //Watk increase
-#ifndef RENEWAL
- if (st->def_ele != ELE_FIRE)
- val2 = 0;
-#endif
+ case SC_FOOD_VIT_CASH:
+ status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
break;
- case SC_VIOLENTGALE:
- val2 = val1*3; //Flee increase
-#ifndef RENEWAL
- if (st->def_ele != ELE_WIND)
- val2 = 0;
-#endif
+ case SC_FOOD_INT_CASH:
+ status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
break;
- case SC_DELUGE:
- val2 = skill->deluge_eff[val1-1]; //HP increase
-#ifndef RENEWAL
- if(st->def_ele != ELE_WATER)
- val2 = 0;
-#endif
+ case SC_FOOD_DEX_CASH:
+ status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
break;
- case SC_NJ_SUITON:
- if (!val2 || (sd && (sd->class_&MAPID_BASEMASK) == MAPID_NINJA)) {
- //No penalties.
- val2 = 0; //Agi penalty
- val3 = 0; //Walk speed penalty
- break;
- }
- val3 = 50;
- val2 = 3*((val1+1)/3);
- if (val1 > 4) val2--;
- break;
- case SC_ONEHANDQUICKEN:
- case SC_TWOHANDQUICKEN:
- val2 = 300;
- if (val1 > 10) //For boss casted skills [Skotlex]
- val2 += 20*(val1-10);
- break;
- case SC_MER_QUICKEN:
- val2 = 300;
+ case SC_FOOD_LUK_CASH:
+ status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
break;
-#ifndef RENEWAL_ASPD
- case SC_SPEARQUICKEN:
- val2 = 200+10*val1;
- break;
-#endif
- case SC_DANCING:
- //val1 : Skill ID + LV
- //val2 : Skill Group of the Dance.
- //val3 : Brings the skill_lv (merged into val1 here)
- //val4 : Partner
- if (val1 == CG_MOONLIT)
- clif->status_change(bl,SI_MOON,1,tick,0, 0, 0);
- val1|= (val3<<16);
- val3 = tick/1000; //Tick duration
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_LONGING:
-#ifdef RENEWAL
- val2 = 50 + 10 * val1;
-#else
- val2 = 500-100*val1; //Aspd penalty.
-#endif
+ case SC_ENDURE:
+ if( val4 )
+ status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
break;
- case SC_EXPLOSIONSPIRITS:
- val2 = 75 + 25*val1; //Cri bonus
+ case SC_FIGHTINGSPIRIT:
+ status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
break;
-
- case SC_ATTHASTE_POTION1:
- case SC_ATTHASTE_POTION2:
- case SC_ATTHASTE_POTION3:
- case SC_ATTHASTE_INFINITY:
- val2 = 50*(2+type-SC_ATTHASTE_POTION1);
+ case SC_MARSHOFABYSS:
+ status_change_end(bl, SC_INCAGI, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
break;
-
- case SC_WEDDING:
- case SC_XMAS:
- case SC_SUMMER:
- case SC_HANBOK:
- if (!vd) return 0;
- //Store previous values as they could be removed.
- unit->stop_attack(bl);
+ case SC_SWING:
+ case SC_SYMPHONY_LOVE:
+ case SC_MOONLIT_SERENADE:
+ case SC_RUSH_WINDMILL:
+ case SC_ECHOSONG:
+ case SC_HARMONIZE: //group A doesn't overlap
+ if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER);
+ if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
+ if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
+ if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
+ if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
+ if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
break;
- case SC_NOCHAT:
- // [GodLesZ] FIXME: is this correct? a hardcoded interval of 60sec? what about configuration ?_?
- tick = 60000;
- val1 = battle_config.manner_system; //Mute filters.
- if (sd)
- {
- clif->changestatus(sd,SP_MANNER,sd->status.manner);
- clif->updatestatus(sd,SP_MANNER);
+ case SC_SIREN:
+ case SC_DEEP_SLEEP:
+ case SC_GLOOMYDAY:
+ case SC_SONG_OF_MANA:
+ case SC_DANCE_WITH_WUG:
+ case SC_SATURDAY_NIGHT_FEVER:
+ case SC_LERADS_DEW:
+ case SC_MELODYOFSINK:
+ case SC_BEYOND_OF_WARCRY:
+ case SC_UNLIMITED_HUMMING_VOICE: //group B
+ if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER);
+ if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
+ if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
+ if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
+ if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
+ if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
+ if (type != SC_GLOOMYDAY) {
+ status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
+ status_change_end(bl, SC_GLOOMYDAY_SK, INVALID_TIMER);
}
- break;
-
- case SC_STONE:
- val3 = tick/1000; //Petrified HP-damage iterations.
- if(val3 < 1) val3 = 1;
- tick = val4; //Petrifying time.
- if(val4 > 500) // not with WL_SIENNAEXECRATE
- tick = max(tick, 1000); //Min time
- calc_flag = 0; //Actual status changes take effect on petrified state.
- break;
-
- case SC_DPOISON:
- //Lose 10/15% of your life as long as it doesn't brings life below 25%
- if (st->hp > st->max_hp>>2) {
- int diff = st->max_hp*(bl->type==BL_PC?10:15)/100;
- if (st->hp - diff < st->max_hp>>2)
- diff = st->hp - (st->max_hp>>2);
- if( val2 && bl->type == BL_MOB ) {
- struct block_list* src = map->id2bl(val2);
- if( src )
- mob->log_damage((TBL_MOB*)bl,src,diff);
+ if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
+ if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
+ if (type != SC_SATURDAY_NIGHT_FEVER) {
+ if (sc->data[SC_SATURDAY_NIGHT_FEVER]) {
+ sc->data[SC_SATURDAY_NIGHT_FEVER]->val2 = 0; //mark to not lose hp
+ status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER);
}
- status_zap(bl, diff, 0);
}
- // fall through
- case SC_POISON:
- val3 = tick/1000; //Damage iterations
- if(val3 < 1) val3 = 1;
- tick_time = 1000; // [GodLesZ] tick time
- //val4: HP damage
- if (bl->type == BL_PC)
- val4 = (type == SC_DPOISON) ? 3 + st->max_hp/50 : 3 + st->max_hp*3/200;
- else
- val4 = (type == SC_DPOISON) ? 3 + st->max_hp/100 : 3 + st->max_hp/200;
-
- break;
- case SC_CONFUSION:
- clif->emotion(bl,E_WHAT);
break;
- case SC_BLOODING:
- val4 = tick/10000;
- if (!val4) val4 = 1;
- tick_time = 10000; // [GodLesZ] tick time
- break;
- case SC_S_LIFEPOTION:
- case SC_L_LIFEPOTION:
- if( val1 == 0 ) return 0;
- // val1 = heal percent/amout
- // val2 = seconds between heals
- // val4 = total of heals
- if( val2 < 1 ) val2 = 1;
- if( (val4 = tick/(val2 * 1000)) < 1 )
- val4 = 1;
- tick_time = val2 * 1000; // [GodLesZ] tick time
+ case SC_REFLECTSHIELD:
+ status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
break;
- case SC_CASH_BOSS_ALARM:
- if( sd != NULL ) {
- struct mob_data *boss_md = map->getmob_boss(bl->m); // Search for Boss on this Map
- if( boss_md == NULL || boss_md->bl.prev == NULL ) {
- // No MVP on this map - MVP is dead
- clif->bossmapinfo(sd->fd, boss_md, 1);
- return 0; // No need to start SC
- }
- val1 = boss_md->bl.id;
- if( (val4 = tick/1000) < 1 )
- val4 = 1;
- tick_time = 1000; // [GodLesZ] tick time
- }
+ case SC_LG_REFLECTDAMAGE:
+ status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
break;
- case SC_HIDING:
- val2 = tick/1000;
- tick_time = 1000; // [GodLesZ] tick time
- val3 = 0; // unused, previously speed adjustment
- val4 = val1+3; //Seconds before SP substraction happen.
+ case SC_SHIELDSPELL_DEF:
+ case SC_SHIELDSPELL_MDEF:
+ case SC_SHIELDSPELL_REF:
+ status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
+ if( type != SC_SHIELDSPELL_DEF )
+ status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
+ if( type != SC_SHIELDSPELL_MDEF )
+ status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
+ if( type != SC_SHIELDSPELL_REF )
+ status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
+ break;
+ case SC_GENTLETOUCH_ENERGYGAIN:
+ case SC_GENTLETOUCH_CHANGE:
+ case SC_GENTLETOUCH_REVITALIZE:
+ if( type != SC_GENTLETOUCH_REVITALIZE )
+ status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER);
+ if( type != SC_GENTLETOUCH_ENERGYGAIN )
+ status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER);
+ if( type != SC_GENTLETOUCH_CHANGE )
+ status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER);
break;
- case SC_CHASEWALK:
- val2 = tick>0?tick:10000; //Interval at which SP is drained.
- val3 = 35 - 5 * val1; //Speed adjustment.
- if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE)
- val3 -= 40;
- val4 = 10+val1*2; //SP cost.
- if (map_flag_gvg(bl->m) || map->list[bl->m].flag.battleground) val4 *= 5;
+ case SC_INVINCIBLE:
+ status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
break;
- case SC_CLOAKING:
- if (!sd) //Monsters should be able to walk with no penalties. [Skotlex]
- val1 = 10;
- tick_time = val2 = tick>0?tick:60000; //SP consumption rate.
- tick = -1; // duration sent to the client should be infinite
- val3 = 0; // unused, previously walk speed adjustment
- //val4&1 signals the presence of a wall.
- //val4&2 makes cloak not end on normal attacks [Skotlex]
- //val4&4 makes cloak not end on using skills
- if (bl->type == BL_PC || (bl->type == BL_MOB && ((TBL_MOB*)bl)->special_state.clone) ) //Standard cloaking.
- val4 |= battle_config.pc_cloak_check_type&7;
- else
- val4 |= battle_config.monster_cloak_check_type&7;
+ case SC_INVINCIBLEOFF:
+ status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
break;
- case SC_SIGHT: /* splash status */
- case SC_RUWACH:
- case SC_WZ_SIGHTBLASTER:
- val3 = skill->get_splash(val2, val1); //Val2 should bring the skill-id.
- val2 = tick/250;
- tick_time = 10; // [GodLesZ] tick time
+ case SC_MAGICPOWER:
+ status_change_end(bl, type, INVALID_TIMER);
break;
+ }
- //Permanent effects.
- case SC_LEXAETERNA:
- case SC_MODECHANGE:
- case SC_WEIGHTOVER50:
- case SC_WEIGHTOVER90:
- case SC_BROKENWEAPON:
- case SC_BROKENARMOR:
- case SC_STORMKICK_READY:
- case SC_DOWNKICK_READY:
- case SC_COUNTERKICK_READY:
- case SC_TURNKICK_READY:
- case SC_DODGE_READY:
- case SC_PUSH_CART:
- case SC_ALL_RIDING:
- tick = -1;
- break;
-
- case SC_AUTOGUARD:
- if( !(flag&1) ) {
- struct map_session_data *tsd;
- int i,t;
- for( i = val2 = 0; i < val1; i++) {
- t = 5-(i>>1);
- val2 += (t < 0)? 1:t;
+ //Check for overlapping fails
+ if( (sce = sc->data[type]) ) {
+ switch( type ) {
+ case SC_MER_FLEE:
+ case SC_MER_ATK:
+ case SC_MER_HP:
+ case SC_MER_SP:
+ case SC_MER_HIT:
+ if( sce->val1 > val1 )
+ val1 = sce->val1;
+ break;
+ case SC_ADRENALINE:
+ case SC_ADRENALINE2:
+ case SC_WEAPONPERFECT:
+ case SC_OVERTHRUST:
+ if (sce->val2 > val2)
+ return 0;
+ break;
+ case SC_S_LIFEPOTION:
+ case SC_L_LIFEPOTION:
+ case SC_CASH_BOSS_ALARM:
+ case SC_STUN:
+ case SC_SLEEP:
+ case SC_POISON:
+ case SC_CURSE:
+ case SC_SILENCE:
+ case SC_CONFUSION:
+ case SC_BLIND:
+ case SC_BLOODING:
+ case SC_DPOISON:
+ case SC_RG_CCONFINE_S: //Can't be re-closed in.
+ case SC_MARIONETTE_MASTER:
+ case SC_MARIONETTE:
+ case SC_NOCHAT:
+ case SC_HLIF_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation.
+ case SC__INVISIBILITY:
+ case SC__ENERVATION:
+ case SC__GROOMY:
+ case SC__IGNORANCE:
+ case SC__LAZINESS:
+ case SC__WEAKNESS:
+ case SC__UNLUCKY:
+ return 0;
+ case SC_COMBOATTACK:
+ case SC_DANCING:
+ case SC_DEVOTION:
+ case SC_ATTHASTE_POTION1:
+ case SC_ATTHASTE_POTION2:
+ case SC_ATTHASTE_POTION3:
+ case SC_ATTHASTE_INFINITY:
+ case SC_PLUSATTACKPOWER:
+ case SC_PLUSMAGICPOWER:
+ case SC_ENCHANTARMS:
+ case SC_ARMORPROPERTY:
+ case SC_ARMOR_RESIST:
+ break;
+ case SC_GOSPEL:
+ //Must not override a casting gospel char.
+ if(sce->val4 == BCT_SELF)
+ return 0;
+ if(sce->val1 > val1)
+ return 1;
+ break;
+ case SC_ENDURE:
+ if(sce->val4 && !val4)
+ return 1; //Don't let you override infinite endure.
+ if(sce->val1 > val1)
+ return 1;
+ break;
+ case SC_KAAHI:
+ //Kaahi overwrites previous level regardless of existing level.
+ //Delete timer if it exists.
+ if (sce->val4 != INVALID_TIMER) {
+ timer->delete(sce->val4,status->kaahi_heal_timer);
+ sce->val4 = INVALID_TIMER;
}
+ break;
+ case SC_JAILED:
+ //When a player is already jailed, do not edit the jail data.
+ val2 = sce->val2;
+ val3 = sce->val3;
+ val4 = sce->val4;
+ break;
+ case SC_LERADS_DEW:
+ if (sc && sc->data[SC_BERSERK])
+ return 0;
+ case SC_SHAPESHIFT:
+ case SC_PROPERTYWALK:
+ break;
+ case SC_LEADERSHIP:
+ case SC_GLORYWOUNDS:
+ case SC_SOULCOLD:
+ case SC_HAWKEYES:
+ if( sce->val4 && !val4 )//you cannot override master guild aura
+ return 0;
+ break;
+ case SC_JOINTBEAT:
+ val2 |= sce->val2; // stackable ailments
+ default:
+ if(sce->val1 > val1)
+ return 1; //Return true to not mess up skill animations. [Skotlex]
+ }
+ }
- if( bl->type&(BL_PC|BL_MER) ) {
+ vd = status->get_viewdata(bl);
+ calc_flag = status->ChangeFlagTable[type];
+ if(!(flag&4)) { //&4 - Do not parse val settings when loading SCs
+ switch(type) {
+ case SC_DEC_AGI:
+ case SC_INC_AGI:
+ val2 = 2 + val1; //Agi change
+ break;
+ case SC_ENDURE:
+ val2 = 7; // Hit-count [Celest]
+ if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground && !val4 ) {
+ struct map_session_data *tsd;
+ if( sd ) {
+ int i;
+ for( i = 0; i < 5; i++ ) {
+ if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
+ status->change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
+ }
+ } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
+ status->change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
+ }
+ //val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
+ if( val4 )
+ tick = -1;
+ break;
+ case SC_AUTOBERSERK:
+ if (st->hp < st->max_hp>>2 &&
+ (!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
+ sc_start4(bl,SC_PROVOKE,100,10,1,0,0,60000);
+ tick = -1;
+ break;
+ case SC_CRUCIS:
+ val2 = 10 + 4*val1; //Def reduction
+ tick = -1;
+ clif->emotion(bl,E_SWT);
+ break;
+ case SC_MAXIMIZEPOWER:
+ tick_time = val2 = tick>0?tick:60000;
+ tick = -1; // duration sent to the client should be infinite
+ break;
+ case SC_EDP: // [Celest]
+ val2 = val1 + 2; //Chance to Poison enemies.
+ val3 = 50*(val1+1); //Damage increase (+50 +50*lv%)
+ #ifdef RENEWAL_EDP
+ val4 = 100 * ((val1 + 1)/2 + 2);
+ #endif
+ if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
+ tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
+ break;
+ case SC_POISONREACT:
+ val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
+ val3=50; // + 5*val1; //Chance to counter. [Skotlex]
+ break;
+ case SC_MAGICROD:
+ val2 = val1*20; //SP gained
+ break;
+ case SC_KYRIE:
+ val2 = (int64)st->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb
+ val3 = (val1 / 2 + 5); //Hits
+ break;
+ case SC_MAGICPOWER:
+ //val1: Skill lv
+ val2 = 1; //Lasts 1 invocation
+ val3 = 5*val1; //Matk% increase
+ val4 = 0; // 0 = ready to be used, 1 = activated and running
+ break;
+ case SC_SACRIFICE:
+ val2 = 5; //Lasts 5 hits
+ tick = -1;
+ break;
+ case SC_ENCHANTPOISON:
+ val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate
+ case SC_ASPERSIO:
+ case SC_PROPERTYFIRE:
+ case SC_PROPERTYWATER:
+ case SC_PROPERTYWIND:
+ case SC_PROPERTYGROUND:
+ case SC_PROPERTYDARK:
+ case SC_PROPERTYTELEKINESIS:
+ skill->enchant_elemental_end(bl,type);
+ break;
+ case SC_ARMOR_PROPERTY:
+ // val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4)
+ // val2 : Element (When no element, random one is picked)
+ // val3 : 0 = called by skill 1 = called by script (fixed level)
+ if( !val2 ) val2 = rnd()%ELE_MAX;
+
+ if( val1 == 1 && val3 == 0 )
+ val1 = 1 + rnd()%4;
+ else if( val1 > 4 )
+ val1 = 4; // Max Level
+ val3 = 0; // Not need to keep this info.
+ break;
+ case SC_PROVIDENCE:
+ val2=val1*5; //Race/Ele resist
+ break;
+ case SC_REFLECTSHIELD:
+ val2=10+val1*3; // %Dmg reflected
+ if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) ) {
+ struct map_session_data *tsd;
if( sd ) {
+ int i;
for( i = 0; i < 5; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
}
- }
- else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
+ } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
}
- }
- break;
+ break;
+ case SC_NOEQUIPWEAPON:
+ if (!sd) //Watk reduction
+ val2 = 25;
+ break;
+ case SC_NOEQUIPSHIELD:
+ if (!sd) //Def reduction
+ val2 = 15;
+ break;
+ case SC_NOEQUIPARMOR:
+ if (!sd) //Vit reduction
+ val2 = 40;
+ break;
+ case SC_NOEQUIPHELM:
+ if (!sd) //Int reduction
+ val2 = 40;
+ break;
+ case SC_AUTOSPELL:
+ //Val1 Skill LV of Autospell
+ //Val2 Skill ID to cast
+ //Val3 Max Lv to cast
+ val4 = 5 + val1*2; //Chance of casting
+ break;
+ case SC_VOLCANO:
+ val2 = val1*10; //Watk increase
+ #ifndef RENEWAL
+ if (st->def_ele != ELE_FIRE)
+ val2 = 0;
+ #endif
+ break;
+ case SC_VIOLENTGALE:
+ val2 = val1*3; //Flee increase
+ #ifndef RENEWAL
+ if (st->def_ele != ELE_WIND)
+ val2 = 0;
+ #endif
+ break;
+ case SC_DELUGE:
+ val2 = skill->deluge_eff[val1-1]; //HP increase
+ #ifndef RENEWAL
+ if(st->def_ele != ELE_WATER)
+ val2 = 0;
+ #endif
+ break;
+ case SC_NJ_SUITON:
+ if (!val2 || (sd && (sd->class_&MAPID_BASEMASK) == MAPID_NINJA)) {
+ //No penalties.
+ val2 = 0; //Agi penalty
+ val3 = 0; //Walk speed penalty
+ break;
+ }
+ val3 = 50;
+ val2 = 3*((val1+1)/3);
+ if (val1 > 4) val2--;
+ break;
+ case SC_ONEHANDQUICKEN:
+ case SC_TWOHANDQUICKEN:
+ val2 = 300;
+ if (val1 > 10) //For boss casted skills [Skotlex]
+ val2 += 20*(val1-10);
+ break;
+ case SC_MER_QUICKEN:
+ val2 = 300;
+ break;
+ #ifndef RENEWAL_ASPD
+ case SC_SPEARQUICKEN:
+ val2 = 200+10*val1;
+ break;
+ #endif
+ case SC_DANCING:
+ //val1 : Skill ID + LV
+ //val2 : Skill Group of the Dance.
+ //val3 : Brings the skill_lv (merged into val1 here)
+ //val4 : Partner
+ if (val1 == CG_MOONLIT)
+ clif->status_change(bl,SI_MOON,1,tick,0, 0, 0);
+ val1|= (val3<<16);
+ val3 = tick/1000; //Tick duration
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_LONGING:
+ #ifdef RENEWAL
+ val2 = 50 + 10 * val1;
+ #else
+ val2 = 500-100*val1; //Aspd penalty.
+ #endif
+ break;
+ case SC_EXPLOSIONSPIRITS:
+ val2 = 75 + 25*val1; //Cri bonus
+ break;
+
+ case SC_ATTHASTE_POTION1:
+ case SC_ATTHASTE_POTION2:
+ case SC_ATTHASTE_POTION3:
+ case SC_ATTHASTE_INFINITY:
+ val2 = 50*(2+type-SC_ATTHASTE_POTION1);
+ break;
+
+ case SC_WEDDING:
+ case SC_XMAS:
+ case SC_SUMMER:
+ case SC_HANBOK:
+ if (!vd) return 0;
+ //Store previous values as they could be removed.
+ unit->stop_attack(bl);
+ break;
+ case SC_NOCHAT:
+ // [GodLesZ] FIXME: is this correct? a hardcoded interval of 60sec? what about configuration ?_?
+ tick = 60000;
+ val1 = battle_config.manner_system; //Mute filters.
+ if (sd)
+ {
+ clif->changestatus(sd,SP_MANNER,sd->status.manner);
+ clif->updatestatus(sd,SP_MANNER);
+ }
+ break;
+
+ case SC_STONE:
+ val3 = tick/1000; //Petrified HP-damage iterations.
+ if(val3 < 1) val3 = 1;
+ tick = val4; //Petrifying time.
+ if(val4 > 500) // not with WL_SIENNAEXECRATE
+ tick = max(tick, 1000); //Min time
+ calc_flag = 0; //Actual status changes take effect on petrified state.
+ break;
- case SC_DEFENDER:
- if (!(flag&1)) {
- val2 = 5 + 15*val1; //Damage reduction
+ case SC_DPOISON:
+ //Lose 10/15% of your life as long as it doesn't brings life below 25%
+ if (st->hp > st->max_hp>>2) {
+ int diff = st->max_hp*(bl->type==BL_PC?10:15)/100;
+ if (st->hp - diff < st->max_hp>>2)
+ diff = st->hp - (st->max_hp>>2);
+ if( val2 && bl->type == BL_MOB ) {
+ struct block_list* src = map->id2bl(val2);
+ if( src )
+ mob->log_damage((TBL_MOB*)bl,src,diff);
+ }
+ status_zap(bl, diff, 0);
+ }
+ // fall through
+ case SC_POISON:
+ val3 = tick/1000; //Damage iterations
+ if(val3 < 1) val3 = 1;
+ tick_time = 1000; // [GodLesZ] tick time
+ //val4: HP damage
+ if (bl->type == BL_PC)
+ val4 = (type == SC_DPOISON) ? 3 + st->max_hp/50 : 3 + st->max_hp*3/200;
+ else
+ val4 = (type == SC_DPOISON) ? 3 + st->max_hp/100 : 3 + st->max_hp/200;
+
+ break;
+ case SC_CONFUSION:
+ clif->emotion(bl,E_WHAT);
+ break;
+ case SC_BLOODING:
+ val4 = tick/10000;
+ if (!val4) val4 = 1;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_S_LIFEPOTION:
+ case SC_L_LIFEPOTION:
+ if( val1 == 0 ) return 0;
+ // val1 = heal percent/amout
+ // val2 = seconds between heals
+ // val4 = total of heals
+ if( val2 < 1 ) val2 = 1;
+ if( (val4 = tick/(val2 * 1000)) < 1 )
+ val4 = 1;
+ tick_time = val2 * 1000; // [GodLesZ] tick time
+ break;
+ case SC_CASH_BOSS_ALARM:
+ if( sd != NULL ) {
+ struct mob_data *boss_md = map->getmob_boss(bl->m); // Search for Boss on this Map
+ if( boss_md == NULL || boss_md->bl.prev == NULL ) {
+ // No MVP on this map - MVP is dead
+ clif->bossmapinfo(sd->fd, boss_md, 1);
+ return 0; // No need to start SC
+ }
+ val1 = boss_md->bl.id;
+ if( (val4 = tick/1000) < 1 )
+ val4 = 1;
+ tick_time = 1000; // [GodLesZ] tick time
+ }
+ break;
+ case SC_HIDING:
+ val2 = tick/1000;
+ tick_time = 1000; // [GodLesZ] tick time
val3 = 0; // unused, previously speed adjustment
- val4 = 250 - 50*val1; //Aspd adjustment
+ val4 = val1+3; //Seconds before SP substraction happen.
+ break;
+ case SC_CHASEWALK:
+ val2 = tick>0?tick:10000; //Interval at which SP is drained.
+ val3 = 35 - 5 * val1; //Speed adjustment.
+ if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE)
+ val3 -= 40;
+ val4 = 10+val1*2; //SP cost.
+ if (map_flag_gvg(bl->m) || map->list[bl->m].flag.battleground) val4 *= 5;
+ break;
+ case SC_CLOAKING:
+ if (!sd) //Monsters should be able to walk with no penalties. [Skotlex]
+ val1 = 10;
+ tick_time = val2 = tick>0?tick:60000; //SP consumption rate.
+ tick = -1; // duration sent to the client should be infinite
+ val3 = 0; // unused, previously walk speed adjustment
+ //val4&1 signals the presence of a wall.
+ //val4&2 makes cloak not end on normal attacks [Skotlex]
+ //val4&4 makes cloak not end on using skills
+ if (bl->type == BL_PC || (bl->type == BL_MOB && ((TBL_MOB*)bl)->special_state.clone) ) //Standard cloaking.
+ val4 |= battle_config.pc_cloak_check_type&7;
+ else
+ val4 |= battle_config.monster_cloak_check_type&7;
+ break;
+ case SC_SIGHT: /* splash status */
+ case SC_RUWACH:
+ case SC_WZ_SIGHTBLASTER:
+ val3 = skill->get_splash(val2, val1); //Val2 should bring the skill-id.
+ val2 = tick/250;
+ tick_time = 10; // [GodLesZ] tick time
+ break;
- if (sd) {
+ //Permanent effects.
+ case SC_LEXAETERNA:
+ case SC_MODECHANGE:
+ case SC_WEIGHTOVER50:
+ case SC_WEIGHTOVER90:
+ case SC_BROKENWEAPON:
+ case SC_BROKENARMOR:
+ case SC_STORMKICK_READY:
+ case SC_DOWNKICK_READY:
+ case SC_COUNTERKICK_READY:
+ case SC_TURNKICK_READY:
+ case SC_DODGE_READY:
+ case SC_PUSH_CART:
+ case SC_ALL_RIDING:
+ tick = -1;
+ break;
+
+ case SC_AUTOGUARD:
+ if( !(flag&1) ) {
struct map_session_data *tsd;
- int i;
- for (i = 0; i < 5; i++) {
- //See if there are devoted characters, and pass the status to them. [Skotlex]
- if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])))
- status->change_start(&tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1);
+ int i,t;
+ for( i = val2 = 0; i < val1; i++) {
+ t = 5-(i>>1);
+ val2 += (t < 0)? 1:t;
+ }
+
+ if( bl->type&(BL_PC|BL_MER) ) {
+ if( sd ) {
+ for( i = 0; i < 5; i++ ) {
+ if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
+ status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
+ }
+ }
+ else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
+ status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
}
}
- }
- break;
+ break;
- case SC_TENSIONRELAX:
- if (sd) {
- pc_setsit(sd);
- clif->sitting(&sd->bl);
- }
- val2 = 12; //SP cost
- val4 = 10000; //Decrease at 10secs intervals.
- val3 = tick/val4;
- tick = -1; // duration sent to the client should be infinite
- tick_time = val4; // [GodLesZ] tick time
- break;
- case SC_PARRYING:
- val2 = 20 + val1*3; //Block Chance
- break;
+ case SC_DEFENDER:
+ if (!(flag&1)) {
+ val2 = 5 + 15*val1; //Damage reduction
+ val3 = 0; // unused, previously speed adjustment
+ val4 = 250 - 50*val1; //Aspd adjustment
+
+ if (sd) {
+ struct map_session_data *tsd;
+ int i;
+ for (i = 0; i < 5; i++) {
+ //See if there are devoted characters, and pass the status to them. [Skotlex]
+ if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])))
+ status->change_start(&tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1);
+ }
+ }
+ }
+ break;
- case SC_WINDWALK:
- val2 = (val1+1)/2; // Flee bonus is 1/1/2/2/3/3/4/4/5/5
- break;
+ case SC_TENSIONRELAX:
+ if (sd) {
+ pc_setsit(sd);
+ clif->sitting(&sd->bl);
+ }
+ val2 = 12; //SP cost
+ val4 = 10000; //Decrease at 10secs intervals.
+ val3 = tick/val4;
+ tick = -1; // duration sent to the client should be infinite
+ tick_time = val4; // [GodLesZ] tick time
+ break;
+ case SC_PARRYING:
+ val2 = 20 + val1*3; //Block Chance
+ break;
- case SC_JOINTBEAT:
- if( val2&BREAK_NECK )
- sc_start2(bl,SC_BLOODING,100,val1,val3,skill->get_time2(status->sc2skill(type),val1));
- break;
+ case SC_WINDWALK:
+ val2 = (val1+1)/2; // Flee bonus is 1/1/2/2/3/3/4/4/5/5
+ break;
- case SC_BERSERK:
- if( val3 == SC__BLOODYLUST )
- sc_start(bl,(sc_type)val3,100,val1,tick);
- if( !val3 && !(!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4) )
- sc_start4(bl, SC_ENDURE, 100,10,0,0,2, tick);
- //HP healing is performing after the calc_status call.
- //Val2 holds HP penalty
- if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1);
- if (!val4) val4 = 10000; //Val4 holds damage interval
- val3 = tick/val4; //val3 holds skill duration
- tick_time = val4; // [GodLesZ] tick time
- break;
-
- case SC_GOSPEL:
- if(val4 == BCT_SELF) {
- // self effect
- val2 = tick/10000;
- tick_time = 10000; // [GodLesZ] tick time
- status->change_clear_buffs(bl,3); //Remove buffs/debuffs
- }
- break;
+ case SC_JOINTBEAT:
+ if( val2&BREAK_NECK )
+ sc_start2(bl,SC_BLOODING,100,val1,val3,skill->get_time2(status->sc2skill(type),val1));
+ break;
- case SC_MARIONETTE_MASTER:
- {
- int stat;
+ case SC_BERSERK:
+ if( val3 == SC__BLOODYLUST )
+ sc_start(bl,(sc_type)val3,100,val1,tick);
+ if( !val3 && !(!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4) )
+ sc_start4(bl, SC_ENDURE, 100,10,0,0,2, tick);
+ //HP healing is performing after the calc_status call.
+ //Val2 holds HP penalty
+ if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1);
+ if (!val4) val4 = 10000; //Val4 holds damage interval
+ val3 = tick/val4; //val3 holds skill duration
+ tick_time = val4; // [GodLesZ] tick time
+ break;
- val3 = 0;
- val4 = 0;
- stat = ( sd ? sd->status.str : status->get_base_status(bl)->str ) / 2; val3 |= cap_value(stat,0,0xFF)<<16;
- stat = ( sd ? sd->status.agi : status->get_base_status(bl)->agi ) / 2; val3 |= cap_value(stat,0,0xFF)<<8;
- stat = ( sd ? sd->status.vit : status->get_base_status(bl)->vit ) / 2; val3 |= cap_value(stat,0,0xFF);
- stat = ( sd ? sd->status.int_: status->get_base_status(bl)->int_) / 2; val4 |= cap_value(stat,0,0xFF)<<16;
- stat = ( sd ? sd->status.dex : status->get_base_status(bl)->dex ) / 2; val4 |= cap_value(stat,0,0xFF)<<8;
- stat = ( sd ? sd->status.luk : status->get_base_status(bl)->luk ) / 2; val4 |= cap_value(stat,0,0xFF);
- }
- break;
- case SC_MARIONETTE:
- {
- int stat,max_stat;
- // fetch caster information
- struct block_list *pbl = map->id2bl(val1);
- struct status_change *psc = pbl ? status->get_sc(pbl) : NULL;
- struct status_change_entry *psce = psc ? psc->data[SC_MARIONETTE_MASTER] : NULL;
- // fetch target's stats
- struct status_data* tst = status->get_status_data(bl); // battle status
-
- if (!psce)
- return 0;
+ case SC_GOSPEL:
+ if(val4 == BCT_SELF) {
+ // self effect
+ val2 = tick/10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ status->change_clear_buffs(bl,3); //Remove buffs/debuffs
+ }
+ break;
- val3 = 0;
- val4 = 0;
- max_stat = battle_config.max_parameter; //Cap to 99 (default)
- stat = (psce->val3 >>16)&0xFF; stat = min(stat, max_stat - tst->str ); val3 |= cap_value(stat,0,0xFF)<<16;
- stat = (psce->val3 >> 8)&0xFF; stat = min(stat, max_stat - tst->agi ); val3 |= cap_value(stat,0,0xFF)<<8;
- stat = (psce->val3 >> 0)&0xFF; stat = min(stat, max_stat - tst->vit ); val3 |= cap_value(stat,0,0xFF);
- stat = (psce->val4 >>16)&0xFF; stat = min(stat, max_stat - tst->int_); val4 |= cap_value(stat,0,0xFF)<<16;
- stat = (psce->val4 >> 8)&0xFF; stat = min(stat, max_stat - tst->dex ); val4 |= cap_value(stat,0,0xFF)<<8;
- stat = (psce->val4 >> 0)&0xFF; stat = min(stat, max_stat - tst->luk ); val4 |= cap_value(stat,0,0xFF);
- }
- break;
- case SC_SWORDREJECT:
- val2 = 15*val1; //Reflect chance
- val3 = 3; //Reflections
- tick = -1;
- break;
+ case SC_MARIONETTE_MASTER:
+ {
+ int stat;
+
+ val3 = 0;
+ val4 = 0;
+ stat = ( sd ? sd->status.str : status->get_base_status(bl)->str ) / 2; val3 |= cap_value(stat,0,0xFF)<<16;
+ stat = ( sd ? sd->status.agi : status->get_base_status(bl)->agi ) / 2; val3 |= cap_value(stat,0,0xFF)<<8;
+ stat = ( sd ? sd->status.vit : status->get_base_status(bl)->vit ) / 2; val3 |= cap_value(stat,0,0xFF);
+ stat = ( sd ? sd->status.int_: status->get_base_status(bl)->int_) / 2; val4 |= cap_value(stat,0,0xFF)<<16;
+ stat = ( sd ? sd->status.dex : status->get_base_status(bl)->dex ) / 2; val4 |= cap_value(stat,0,0xFF)<<8;
+ stat = ( sd ? sd->status.luk : status->get_base_status(bl)->luk ) / 2; val4 |= cap_value(stat,0,0xFF);
+ }
+ break;
+ case SC_MARIONETTE:
+ {
+ int stat,max_stat;
+ // fetch caster information
+ struct block_list *pbl = map->id2bl(val1);
+ struct status_change *psc = pbl ? status->get_sc(pbl) : NULL;
+ struct status_change_entry *psce = psc ? psc->data[SC_MARIONETTE_MASTER] : NULL;
+ // fetch target's stats
+ struct status_data* tst = status->get_status_data(bl); // battle status
+
+ if (!psce)
+ return 0;
- case SC_MEMORIZE:
- val2 = 5; //Memorized casts.
- tick = -1;
- break;
+ val3 = 0;
+ val4 = 0;
+ max_stat = battle_config.max_parameter; //Cap to 99 (default)
+ stat = (psce->val3 >>16)&0xFF; stat = min(stat, max_stat - tst->str ); val3 |= cap_value(stat,0,0xFF)<<16;
+ stat = (psce->val3 >> 8)&0xFF; stat = min(stat, max_stat - tst->agi ); val3 |= cap_value(stat,0,0xFF)<<8;
+ stat = (psce->val3 >> 0)&0xFF; stat = min(stat, max_stat - tst->vit ); val3 |= cap_value(stat,0,0xFF);
+ stat = (psce->val4 >>16)&0xFF; stat = min(stat, max_stat - tst->int_); val4 |= cap_value(stat,0,0xFF)<<16;
+ stat = (psce->val4 >> 8)&0xFF; stat = min(stat, max_stat - tst->dex ); val4 |= cap_value(stat,0,0xFF)<<8;
+ stat = (psce->val4 >> 0)&0xFF; stat = min(stat, max_stat - tst->luk ); val4 |= cap_value(stat,0,0xFF);
+ }
+ break;
+ case SC_SWORDREJECT:
+ val2 = 15*val1; //Reflect chance
+ val3 = 3; //Reflections
+ tick = -1;
+ break;
- case SC_GRAVITATION:
- val2 = 50*val1; //aspd reduction
- break;
+ case SC_MEMORIZE:
+ val2 = 5; //Memorized casts.
+ tick = -1;
+ break;
- case SC_GDSKILL_REGENERATION:
- if (val1 == 1)
- val2 = 2;
- else
- val2 = val1; //HP Regerenation rate: 200% 200% 300%
- val3 = val1; //SP Regeneration Rate: 100% 200% 300%
- //if val4 comes set, this blocks regen rather than increase it.
- break;
+ case SC_GRAVITATION:
+ val2 = 50*val1; //aspd reduction
+ break;
- case SC_DEVOTION:
- {
- struct block_list *d_bl;
- struct status_change *d_sc;
-
- if( (d_bl = map->id2bl(val1)) && (d_sc = status->get_sc(d_bl)) && d_sc->count ) {
- // Inherits Status From Source
- const enum sc_type types[] = { SC_AUTOGUARD, SC_DEFENDER, SC_REFLECTSHIELD, SC_ENDURE };
- enum sc_type type2;
- int i = (map_flag_gvg(bl->m) || map->list[bl->m].flag.battleground)?2:3;
- while( i >= 0 ) {
- type2 = types[i];
- if( d_sc->data[type2] )
- sc_start(bl, type2, 100, d_sc->data[type2]->val1, skill->get_time(status->sc2skill(type2),d_sc->data[type2]->val1));
- i--;
+ case SC_GDSKILL_REGENERATION:
+ if (val1 == 1)
+ val2 = 2;
+ else
+ val2 = val1; //HP Regerenation rate: 200% 200% 300%
+ val3 = val1; //SP Regeneration Rate: 100% 200% 300%
+ //if val4 comes set, this blocks regen rather than increase it.
+ break;
+
+ case SC_DEVOTION:
+ {
+ struct block_list *d_bl;
+ struct status_change *d_sc;
+
+ if( (d_bl = map->id2bl(val1)) && (d_sc = status->get_sc(d_bl)) && d_sc->count ) {
+ // Inherits Status From Source
+ const enum sc_type types[] = { SC_AUTOGUARD, SC_DEFENDER, SC_REFLECTSHIELD, SC_ENDURE };
+ enum sc_type type2;
+ int i = (map_flag_gvg(bl->m) || map->list[bl->m].flag.battleground)?2:3;
+ while( i >= 0 ) {
+ type2 = types[i];
+ if( d_sc->data[type2] )
+ sc_start(bl, type2, 100, d_sc->data[type2]->val1, skill->get_time(status->sc2skill(type2),d_sc->data[type2]->val1));
+ i--;
+ }
}
+ break;
}
- break;
- }
- case SC_COMA: //Coma. Sends a char to 1HP. If val2, do not zap sp
- if( val3 && bl->type == BL_MOB ) {
- struct block_list* src = map->id2bl(val3);
- if( src )
- mob->log_damage((TBL_MOB*)bl,src,st->hp - 1);
+ case SC_COMA: //Coma. Sends a char to 1HP. If val2, do not zap sp
+ if( val3 && bl->type == BL_MOB ) {
+ struct block_list* src = map->id2bl(val3);
+ if( src )
+ mob->log_damage((TBL_MOB*)bl,src,st->hp - 1);
+ }
+ status_zap(bl, st->hp-1, val2 ? 0 : st->sp);
+ return 1;
+ break;
+ case SC_RG_CCONFINE_S:
+ {
+ struct block_list *src = val2 ? map->id2bl(val2) : NULL;
+ struct status_change *sc2 = src ? status->get_sc(src) : NULL;
+ struct status_change_entry *sce2 = sc2 ? sc2->data[SC_RG_CCONFINE_M] : NULL;
+ if (src && sc2) {
+ if (!sce2) //Start lock on caster.
+ sc_start4(src,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000);
+ else { //Increase count of locked enemies and refresh time.
+ (sce2->val2)++;
+ timer->delete(sce2->timer, status->change_timer);
+ sce2->timer = timer->add(timer->gettick()+tick+1000, status->change_timer, src->id, SC_RG_CCONFINE_M);
+ }
+ } else //Status failed.
+ return 0;
}
- status_zap(bl, st->hp-1, val2 ? 0 : st->sp);
- return 1;
- break;
- case SC_RG_CCONFINE_S:
- {
- struct block_list *src = val2 ? map->id2bl(val2) : NULL;
- struct status_change *sc2 = src ? status->get_sc(src) : NULL;
- struct status_change_entry *sce2 = sc2 ? sc2->data[SC_RG_CCONFINE_M] : NULL;
- if (src && sc2) {
- if (!sce2) //Start lock on caster.
- sc_start4(src,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000);
- else { //Increase count of locked enemies and refresh time.
- (sce2->val2)++;
- timer->delete(sce2->timer, status->change_timer);
- sce2->timer = timer->add(timer->gettick()+tick+1000, status->change_timer, src->id, SC_RG_CCONFINE_M);
+ break;
+ case SC_KAITE:
+ val2 = 1+val1/5; //Number of bounces: 1 + skill_lv/5
+ break;
+ case SC_KAUPE:
+ switch (val1) {
+ case 3: //33*3 + 1 -> 100%
+ val2++;
+ case 1:
+ case 2: //33, 66%
+ val2 += 33*val1;
+ val3 = 1; //Dodge 1 attack total.
+ break;
+ default: //Custom. For high level mob usage, higher level means more blocks. [Skotlex]
+ val2 = 100;
+ val3 = val1-2;
+ break;
}
- } else //Status failed.
- return 0;
- }
- break;
- case SC_KAITE:
- val2 = 1+val1/5; //Number of bounces: 1 + skill_lv/5
- break;
- case SC_KAUPE:
- switch (val1) {
- case 3: //33*3 + 1 -> 100%
- val2++;
- case 1:
- case 2: //33, 66%
- val2 += 33*val1;
- val3 = 1; //Dodge 1 attack total.
break;
- default: //Custom. For high level mob usage, higher level means more blocks. [Skotlex]
- val2 = 100;
- val3 = val1-2;
+
+ case SC_COMBOATTACK: {
+ //val1: Skill ID
+ //val2: When given, target (for autotargetting skills)
+ //val3: When set, this combo time should NOT delay attack/movement
+ //val3: TK: Last used kick
+ //val4: TK: Combo time
+ struct unit_data *ud = unit->bl2ud(bl);
+ if (ud && !val3) {
+ tick += 300 * battle_config.combo_delay_rate/100;
+ ud->attackabletime = timer->gettick()+tick;
+ unit->set_walkdelay(bl, timer->gettick(), tick, 1);
+ }
+ val3 = 0;
+ val4 = tick;
+ }
+ break;
+ case SC_EARTHSCROLL:
+ val2 = 11-val1; //Chance to consume: 11-skill_lv%
break;
+ case SC_RUN:
+ {
+ //Store time at which you started running.
+ int64 currenttick = timer->gettick();
+ // Note: this int64 value is stored in two separate int32 variables (FIXME)
+ val3 = (int)(currenttick&0x00000000ffffffffLL);
+ val4 = (int)((currenttick&0xffffffff00000000LL)>>32);
}
- break;
+ tick = -1;
+ break;
+ case SC_KAAHI:
+ val2 = 200*val1; //HP heal
+ val3 = 5*val1; //SP cost
+ val4 = INVALID_TIMER; //Kaahi Timer.
+ break;
+ case SC_BLESSING:
+ if ((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC)
+ val2 = val1;
+ else
+ val2 = 0; //0 -> Half stat.
+ break;
+ case SC_TRICKDEAD:
+ if (vd) vd->dead_sit = 1;
+ tick = -1;
+ break;
+ case SC_CONCENTRATION:
+ val2 = 2 + val1;
+ if (sd) { //Store the card-bonus data that should not count in the %
+ val3 = sd->param_bonus[1]; //Agi
+ val4 = sd->param_bonus[4]; //Dex
+ } else {
+ val3 = val4 = 0;
+ }
+ break;
+ case SC_OVERTHRUSTMAX:
+ val2 = 20*val1; //Power increase
+ break;
+ case SC_OVERTHRUST:
+ //val2 holds if it was casted on self, or is bonus received from others
+ val3 = 5*val1; //Power increase
+ if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
+ tick += tick / 10;
+ break;
+ case SC_ADRENALINE2:
+ case SC_ADRENALINE:
+ val3 = (val2) ? 300 : 200; // aspd increase
+ case SC_WEAPONPERFECT:
+ if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
+ tick += tick / 10;
+ break;
+ case SC_LKCONCENTRATION:
+ val2 = 5*val1; //Batk/Watk Increase
+ val3 = 10*val1; //Hit Increase
+ val4 = 5*val1; //Def reduction
+ sc_start(bl, SC_ENDURE, 100, 1, tick); //Endure effect
+ break;
+ case SC_ANGELUS:
+ val2 = 5*val1; //def increase
+ break;
+ case SC_IMPOSITIO:
+ val2 = 5*val1; //watk increase
+ break;
+ case SC_MELTDOWN:
+ val2 = 100*val1; //Chance to break weapon
+ val3 = 70*val1; //Change to break armor
+ break;
+ case SC_TRUESIGHT:
+ val2 = 10*val1; //Critical increase
+ val3 = 3*val1; //Hit increase
+ break;
+ case SC_SUN_COMFORT:
+ val2 = (status->get_lv(bl) + st->dex + st->luk)/2; //def increase
+ break;
+ case SC_MOON_COMFORT:
+ val2 = (status->get_lv(bl) + st->dex + st->luk)/10; //flee increase
+ break;
+ case SC_STAR_COMFORT:
+ val2 = (status->get_lv(bl) + st->dex + st->luk); //Aspd increase
+ break;
+ case SC_QUAGMIRE:
+ val2 = (sd?5:10)*val1; //Agi/Dex decrease.
+ break;
- case SC_COMBOATTACK: {
- //val1: Skill ID
- //val2: When given, target (for autotargetting skills)
- //val3: When set, this combo time should NOT delay attack/movement
- //val3: TK: Last used kick
- //val4: TK: Combo time
- struct unit_data *ud = unit->bl2ud(bl);
- if (ud && !val3) {
- tick += 300 * battle_config.combo_delay_rate/100;
- ud->attackabletime = timer->gettick()+tick;
- unit->set_walkdelay(bl, timer->gettick(), tick, 1);
- }
- val3 = 0;
- val4 = tick;
- }
- break;
- case SC_EARTHSCROLL:
- val2 = 11-val1; //Chance to consume: 11-skill_lv%
- break;
- case SC_RUN:
- val4 = timer->gettick(); //Store time at which you started running.
- tick = -1;
- break;
- case SC_KAAHI:
- val2 = 200*val1; //HP heal
- val3 = 5*val1; //SP cost
- val4 = INVALID_TIMER; //Kaahi Timer.
- break;
- case SC_BLESSING:
- if ((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC)
- val2 = val1;
- else
- val2 = 0; //0 -> Half stat.
- break;
- case SC_TRICKDEAD:
- if (vd) vd->dead_sit = 1;
- tick = -1;
- break;
- case SC_CONCENTRATION:
- val2 = 2 + val1;
- if (sd) { //Store the card-bonus data that should not count in the %
- val3 = sd->param_bonus[1]; //Agi
- val4 = sd->param_bonus[4]; //Dex
- } else {
- val3 = val4 = 0;
- }
- break;
- case SC_OVERTHRUSTMAX:
- val2 = 20*val1; //Power increase
- break;
- case SC_OVERTHRUST:
- //val2 holds if it was casted on self, or is bonus received from others
- val3 = 5*val1; //Power increase
- if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
- tick += tick / 10;
- break;
- case SC_ADRENALINE2:
- case SC_ADRENALINE:
- val3 = (val2) ? 300 : 200; // aspd increase
- case SC_WEAPONPERFECT:
- if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
- tick += tick / 10;
- break;
- case SC_LKCONCENTRATION:
- val2 = 5*val1; //Batk/Watk Increase
- val3 = 10*val1; //Hit Increase
- val4 = 5*val1; //Def reduction
- sc_start(bl, SC_ENDURE, 100, 1, tick); //Endure effect
- break;
- case SC_ANGELUS:
- val2 = 5*val1; //def increase
- break;
- case SC_IMPOSITIO:
- val2 = 5*val1; //watk increase
- break;
- case SC_MELTDOWN:
- val2 = 100*val1; //Chance to break weapon
- val3 = 70*val1; //Change to break armor
- break;
- case SC_TRUESIGHT:
- val2 = 10*val1; //Critical increase
- val3 = 3*val1; //Hit increase
- break;
- case SC_SUN_COMFORT:
- val2 = (status->get_lv(bl) + st->dex + st->luk)/2; //def increase
- break;
- case SC_MOON_COMFORT:
- val2 = (status->get_lv(bl) + st->dex + st->luk)/10; //flee increase
- break;
- case SC_STAR_COMFORT:
- val2 = (status->get_lv(bl) + st->dex + st->luk); //Aspd increase
- break;
- case SC_QUAGMIRE:
- val2 = (sd?5:10)*val1; //Agi/Dex decrease.
- break;
+ // gs_something1 [Vicious]
+ case SC_GS_GATLINGFEVER:
+ val2 = 20*val1; //Aspd increase
+ val4 = 5*val1; //Flee decrease
+ #ifndef RENEWAL
+ val3 = 20+10*val1; //Batk increase
+ #endif
+ break;
- // gs_something1 [Vicious]
- case SC_GS_GATLINGFEVER:
- val2 = 20*val1; //Aspd increase
- val4 = 5*val1; //Flee decrease
-#ifndef RENEWAL
- val3 = 20+10*val1; //Batk increase
-#endif
- break;
+ case SC_FLING:
+ if (bl->type == BL_PC)
+ val2 = 0; //No armor reduction to players.
+ else
+ val2 = 5*val1; //Def reduction
+ val3 = 5*val1; //Def2 reduction
+ break;
+ case SC_PROVOKE:
+ //val2 signals autoprovoke.
+ val3 = 2+3*val1; //Atk increase
+ val4 = 5+5*val1; //Def reduction.
+ break;
+ case SC_HLIF_AVOID:
+ //val2 = 10*val1; //Speed change rate.
+ break;
+ case SC_HAMI_DEFENCE:
+ val2 = 2*val1; //Def bonus
+ break;
+ case SC_HAMI_BLOODLUST:
+ val2 = 20+10*val1; //Atk rate change.
+ val3 = 3*val1; //Leech chance
+ val4 = 20; //Leech percent
+ break;
+ case SC_HLIF_FLEET:
+ val2 = 30*val1; //Aspd change
+ val3 = 5+5*val1; //bAtk/wAtk rate change
+ break;
+ case SC_MINDBREAKER:
+ val2 = 20*val1; //matk increase.
+ val3 = 12*val1; //mdef2 reduction.
+ break;
+ case SC_SKA:
+ val2 = tick/1000;
+ val3 = rnd()%100; //Def changes randomly every second...
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_JAILED:
+ //Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
+ tick = val1>0?1000:250;
+ if (sd)
+ {
+ if (sd->mapindex != val2)
+ {
+ int pos = (bl->x&0xFFFF)|(bl->y<<16); /// Current Coordinates
+ int mapindex = sd->mapindex; /// Current Map
+ //1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y
+ pc->setpos(sd,(unsigned short)val2,val3,val4, CLR_TELEPORT);
+ //2. Set restore point (val3 -> return map, val4 return coords
+ val3 = mapindex;
+ val4 = pos;
+ } else if (!val3 || val3 == sd->mapindex) { //Use save point.
+ val3 = sd->status.save_point.map;
+ val4 = (sd->status.save_point.x&0xFFFF)
+ |(sd->status.save_point.y<<16);
+ }
+ }
+ break;
+ case SC_NJ_UTSUSEMI:
+ val2=(val1+1)/2; // number of hits blocked
+ val3=skill->get_blewcount(NJ_UTSUSEMI, val1); //knockback value.
+ break;
+ case SC_NJ_BUNSINJYUTSU:
+ val2=(val1+1)/2; // number of hits blocked
+ break;
+ case SC_HLIF_CHANGE:
+ val2= 30*val1; //Vit increase
+ val3= 20*val1; //Int increase
+ break;
+ case SC_SWOO:
+ if(st->mode&MD_BOSS)
+ tick /= 5; //TODO: Reduce skill's duration. But for how long?
+ break;
+ case SC_SPIDERWEB:
+ if( bl->type == BL_PC )
+ tick /= 2;
+ break;
+ case SC_ARMOR:
+ //NPC_DEFENDER:
+ val2 = 80; //Damage reduction
+ //Attack requirements to be blocked:
+ val3 = BF_LONG; //Range
+ val4 = BF_WEAPON|BF_MISC; //Type
+ break;
+ case SC_ENCHANTARMS:
+ //end previous enchants
+ skill->enchant_elemental_end(bl,type);
+ //Make sure the received element is valid.
+ if (val2 >= ELE_MAX)
+ val2 = val2%ELE_MAX;
+ else if (val2 < 0)
+ val2 = rnd()%ELE_MAX;
+ break;
+ case SC_CRITICALWOUND:
+ val2 = 20*val1; //Heal effectiveness decrease
+ break;
+ case SC_MAGICMIRROR:
+ case SC_SLOWCAST:
+ val2 = 20*val1; //Magic reflection/cast rate
+ break;
- case SC_FLING:
- if (bl->type == BL_PC)
- val2 = 0; //No armor reduction to players.
- else
- val2 = 5*val1; //Def reduction
- val3 = 5*val1; //Def2 reduction
- break;
- case SC_PROVOKE:
- //val2 signals autoprovoke.
- val3 = 2+3*val1; //Atk increase
- val4 = 5+5*val1; //Def reduction.
- break;
- case SC_HLIF_AVOID:
- //val2 = 10*val1; //Speed change rate.
- break;
- case SC_HAMI_DEFENCE:
- val2 = 2*val1; //Def bonus
- break;
- case SC_HAMI_BLOODLUST:
- val2 = 20+10*val1; //Atk rate change.
- val3 = 3*val1; //Leech chance
- val4 = 20; //Leech percent
- break;
- case SC_HLIF_FLEET:
- val2 = 30*val1; //Aspd change
- val3 = 5+5*val1; //bAtk/wAtk rate change
- break;
- case SC_MINDBREAKER:
- val2 = 20*val1; //matk increase.
- val3 = 12*val1; //mdef2 reduction.
- break;
- case SC_SKA:
- val2 = tick/1000;
- val3 = rnd()%100; //Def changes randomly every second...
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_JAILED:
- //Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
- tick = val1>0?1000:250;
- if (sd)
+ case SC_STONESKIN:
+ if (val2 == NPC_ANTIMAGIC)
+ { //Boost mdef
+ val2 =-20;
+ val3 = 20;
+ } else { //Boost def
+ val2 = 20;
+ val3 =-20;
+ }
+ val2*=val1; //20% per level
+ val3*=val1;
+ break;
+ case SC_CASH_PLUSEXP:
+ case SC_CASH_PLUSONLYJOBEXP:
+ if (val1 < 0)
+ val1 = 0;
+ break;
+ case SC_PLUSAVOIDVALUE:
+ case SC_CRITICALPERCENT:
+ val2 = val1*10; //Actual boost (since 100% = 1000)
+ break;
+ case SC_SUFFRAGIUM:
+ val2 = 15 * val1; //Speed cast decrease
+ break;
+ case SC_HEALPLUS:
+ if (val1 < 1)
+ val1 = 1;
+ break;
+ case SC_ILLUSION:
+ val2 = 5+val1; //Factor by which displayed damage is increased by
+ break;
+ case SC_DOUBLECASTING:
+ val2 = 30+10*val1; //Trigger rate
+ break;
+ case SC_KAIZEL:
+ val2 = 10*val1; //% of life to be revived with
+ break;
+ // case SC_ARMORPROPERTY:
+ // case SC_ARMOR_RESIST:
+ // Mod your resistance against elements:
+ // val1 = water | val2 = earth | val3 = fire | val4 = wind
+ // break;
+ //case ????:
+ //Place here SCs that have no SCB_* data, no skill associated, no ICON
+ //associated, and yet are not wrong/unknown. [Skotlex]
+ //break;
+
+ case SC_MER_FLEE:
+ case SC_MER_ATK:
+ case SC_MER_HIT:
+ val2 = 15 * val1;
+ break;
+ case SC_MER_HP:
+ case SC_MER_SP:
+ val2 = 5 * val1;
+ break;
+ case SC_REBIRTH:
+ val2 = 20*val1; //% of life to be revived with
+ break;
+
+ case SC_MANU_DEF:
+ case SC_MANU_ATK:
+ case SC_MANU_MATK:
+ val2 = 1; // Manuk group
+ break;
+ case SC_SPL_DEF:
+ case SC_SPL_ATK:
+ case SC_SPL_MATK:
+ val2 = 2; // Splendide group
+ break;
+ /**
+ * General
+ **/
+ case SC_FEAR:
+ val2 = 2;
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_BURNING:
+ val4 = tick / 3000; // Total Ticks to Burn!!
+ tick_time = 3000; // [GodLesZ] tick time
+ break;
+ /**
+ * Rune Knight
+ **/
+ case SC_DEATHBOUND:
+ val2 = 500 + 100 * val1;
+ break;
+ case SC_STONEHARDSKIN:
+ if( sd )
+ val1 = sd->status.job_level * pc->checkskill(sd, RK_RUNEMASTERY) / 4; //DEF/MDEF Increase
+ break;
+ case SC_ABUNDANCE:
+ val4 = tick / 10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ /**
+ * Arch Bishop
+ **/
+ case SC_RENOVATIO:
+ val4 = tick / 5000;
+ tick_time = 5000;
+ break;
+ case SC_SECRAMENT:
+ val2 = 10 * val1;
+ break;
+ case SC_VENOMIMPRESS:
+ val2 = 10 * val1;
+ break;
+ case SC_WEAPONBLOCKING:
+ val2 = 10 + 2 * val1; // Chance
+ val4 = tick / 3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ break;
+ case SC_TOXIN:
+ val4 = tick / 10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_MAGICMUSHROOM:
+ val4 = tick / 4000;
+ tick_time = 4000; // [GodLesZ] tick time
+ break;
+ case SC_PYREXIA:
+ status->change_start(bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds
+ val4 = tick / 3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ break;
+ case SC_LEECHESEND:
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_OBLIVIONCURSE:
+ val4 = tick / 3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ break;
+ case SC_CLOAKINGEXCEED:
+ val2 = ( val1 + 1 ) / 2; // Hits
+ val3 = 90 + val1 * 10; // Walk speed
+ if (bl->type == BL_PC)
+ val4 |= battle_config.pc_cloak_check_type&7;
+ else
+ val4 |= battle_config.monster_cloak_check_type&7;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_HALLUCINATIONWALK:
+ val2 = 50 * val1; // Evasion rate of physical attacks. Flee
+ val3 = 10 * val1; // Evasion rate of magical attacks.
+ break;
+ case SC_WHITEIMPRISON:
+ status_change_end(bl, SC_BURNING, INVALID_TIMER);
+ status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER);
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ break;
+ case SC_MARSHOFABYSS:
+ val2 = 6 * val1;
+ if( sd ) // half on players
+ val2 >>= 1;
+ break;
+ case SC_FROSTMISTY:
+ status_change_end(bl, SC_BURNING, INVALID_TIMER);
+ break;
+ case SC_READING_SB:
+ // val2 = sp reduction per second
+ tick_time = 5000; // [GodLesZ] tick time
+ break;
+ case SC_SUMMON1:
+ case SC_SUMMON2:
+ case SC_SUMMON3:
+ case SC_SUMMON4:
+ case SC_SUMMON5:
+ val4 = tick / 1000;
+ if( val4 < 1 )
+ val4 = 1;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_SHAPESHIFT:
+ switch( val1 )
+ {
+ case 1: val2 = ELE_FIRE; break;
+ case 2: val2 = ELE_EARTH; break;
+ case 3: val2 = ELE_WIND; break;
+ case 4: val2 = ELE_WATER; break;
+ }
+ break;
+ case SC_ELECTRICSHOCKER:
+ case SC_COLD:
+ case SC_MEIKYOUSISUI:
+ val4 = tick / 1000;
+ if( val4 < 1 )
+ val4 = 1;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_CAMOUFLAGE:
+ val4 = tick/1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_WUGDASH:
{
- if (sd->mapindex != val2)
+ //Store time at which you started running.
+ int64 currenttick = timer->gettick();
+ // Note: this int64 value is stored in two separate int32 variables (FIXME)
+ val3 = (int)(currenttick&0x00000000ffffffffLL);
+ val4 = (int)((currenttick&0xffffffff00000000LL)>>32);
+ }
+ tick = -1;
+ break;
+ case SC__SHADOWFORM: {
+ struct map_session_data * s_sd = map->id2sd(val2);
+ if( s_sd )
+ s_sd->shadowform_id = bl->id;
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ }
+ break;
+ case SC__STRIPACCESSARY:
+ if (!sd)
+ val2 = 20;
+ break;
+ case SC__INVISIBILITY:
+ val2 = 50 - 10 * val1; // ASPD
+ val3 = 20 * val1; // CRITICAL
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC__ENERVATION:
+ val2 = 20 + 10 * val1; // ATK Reduction
+ if( sd ) pc->delspiritball(sd,sd->spiritball,0);
+ break;
+ case SC__GROOMY:
+ val2 = 20 + 10 * val1; //ASPD. Need to confirm if Movement Speed reduction is the same. [Jobbie]
+ val3 = 20 * val1; //HIT
+ if( sd ) { // Removes Animals
+ if( pc_isriding(sd) ) pc->setriding(sd, 0);
+ if( pc_isridingdragon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_DRAGON);
+ if( pc_iswug(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_WUG);
+ if( pc_isridingwug(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
+ if( pc_isfalcon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_FALCON);
+ if( sd->status.pet_id > 0 ) pet->menu(sd, 3);
+ if( homun_alive(sd->hd) ) homun->vaporize(sd,HOM_ST_REST);
+ if( sd->md ) mercenary->delete(sd->md,3);
+ }
+ break;
+ case SC__LAZINESS:
+ val2 = 10 + 10 * val1; // Cast reduction
+ val3 = 10 * val1; // Flee Reduction
+ break;
+ case SC__UNLUCKY:
+ val2 = 10 * val1; // Crit and Flee2 Reduction
+ break;
+ case SC__WEAKNESS:
+ val2 = 10 * val1;
+ // bypasses coating protection and MADO
+ sc_start(bl,SC_NOEQUIPWEAPON,100,val1,tick);
+ sc_start(bl,SC_NOEQUIPSHIELD,100,val1,tick);
+ break;
+ case SC_GN_CARTBOOST:
+ if( val1 < 3 )
+ val2 = 50;
+ else if( val1 < 5 )
+ val2 = 75;
+ else
+ val2 = 100;
+ break;
+ case SC_PROPERTYWALK:
+ val3 = 0;
+ break;
+ case SC_WARMER:
+ status_change_end(bl, SC_FREEZE, INVALID_TIMER);
+ status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER);
+ status_change_end(bl, SC_COLD, INVALID_TIMER);
+ break;
+ case SC_STRIKING:
+ val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1)
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_BLOOD_SUCKER:
+ {
+ struct block_list *src = map->id2bl(val2);
+ val3 = 1;
+ if(src)
+ val3 = 200 + 100 * val1 + status_get_int(src);
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ }
+ break;
+ case SC_VACUUM_EXTREME:
+ tick -= (st->str / 20) * 1000;
+ val4 = val3 = tick / 100;
+ tick_time = 100; // [GodLesZ] tick time
+ break;
+ case SC_SWING:
+ val2 = 4 * val1; // Walk speed and aspd reduction.
+ break;
+ case SC_SYMPHONY_LOVE:
+ case SC_RUSH_WINDMILL:
+ case SC_ECHOSONG:
+ val2 = 6 * val1;
+ val2 += val3; //Adding 1% * Lesson Bonus
+ val2 += (int)(val4*2/10); //Adding 0.2% per JobLevel
+ break;
+ case SC_MOONLIT_SERENADE:
+ val2 = 10 * val1;
+ break;
+ case SC_HARMONIZE:
+ val2 = 5 + 5 * val1;
+ break;
+ case SC_SIREN:
+ val4 = tick / 2000;
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ case SC_DEEP_SLEEP:
+ val4 = tick / 2000;
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ case SC_SIRCLEOFNATURE:
+ val2 = 1 + val1; //SP consume
+ val3 = 40 * val1; //HP recovery
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_SONG_OF_MANA:
+ val3 = 10 + (2 * val2);
+ val4 = tick/3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ break;
+ case SC_SATURDAY_NIGHT_FEVER:
+ if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1);
+ if (!val4) val4 = 3000;
+ val3 = tick/val4;
+ tick_time = val4; // [GodLesZ] tick time
+ break;
+ case SC_GLOOMYDAY:
+ val2 = 20 + 5 * val1; // Flee reduction.
+ val3 = 15 + 5 * val1; // ASPD reduction.
+ if( sd && rand()%100 < val1 ){ // (Skill Lv) %
+ val4 = 1; // reduce walk speed by half.
+ if( pc_isriding(sd) ) pc->setriding(sd, 0);
+ if( pc_isridingdragon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_DRAGON);
+ }
+ break;
+ case SC_GLOOMYDAY_SK:
+ // Random number between [15 ~ (Voice Lesson Skill Level x 5) + (Skill Level x 10)] %.
+ val2 = 15 + rand()%( (sd?pc->checkskill(sd, WM_LESSON)*5:0) + val1*10 );
+ break;
+ case SC_SITDOWN_FORCE:
+ case SC_BANANA_BOMB_SITDOWN_POSTDELAY:
+ if( sd && !pc_issit(sd) )
{
- int pos = (bl->x&0xFFFF)|(bl->y<<16); /// Current Coordinates
- int mapindex = sd->mapindex; /// Current Map
- //1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y
- pc->setpos(sd,(unsigned short)val2,val3,val4, CLR_TELEPORT);
- //2. Set restore point (val3 -> return map, val4 return coords
- val3 = mapindex;
- val4 = pos;
- } else if (!val3 || val3 == sd->mapindex) { //Use save point.
- val3 = sd->status.save_point.map;
- val4 = (sd->status.save_point.x&0xFFFF)
- |(sd->status.save_point.y<<16);
+ pc_setsit(sd);
+ skill->sit(sd,1);
+ clif->sitting(bl);
+ }
+ break;
+ case SC_DANCE_WITH_WUG:
+ val3 = (5 * val1) + (1 * val2); //Still need official value.
+ break;
+ case SC_LERADS_DEW:
+ val3 = (5 * val1) + (1 * val2);
+ break;
+ case SC_MELODYOFSINK:
+ val3 = (5 * val1) + (1 * val2);
+ break;
+ case SC_BEYOND_OF_WARCRY:
+ val3 = (5 * val1) + (1 * val2);
+ break;
+ case SC_UNLIMITED_HUMMING_VOICE:
+ {
+ struct unit_data *ud = unit->bl2ud(bl);
+ if( ud == NULL ) return 0;
+ ud->state.skillcastcancel = 0;
+ val3 = 15 - (2 * val2);
+ }
+ break;
+ case SC_LG_REFLECTDAMAGE:
+ val2 = 15 + 5 * val1;
+ val3 = (val1==5)?20:(val1+4)*2; // SP consumption
+ val4 = tick/10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_FORCEOFVANGUARD: // This is not the official way to handle it but I think we should use it. [pakpil]
+ val2 = 20 + 12 * (val1 - 1); // Chance
+ val3 = 5 + (2 * val1); // Max rage counters
+ tick = -1; //endless duration in the client
+ tick_time = 6000; // [GodLesZ] tick time
+ break;
+ case SC_EXEEDBREAK:
+ val1 *= 150; // 150 * skill_lv
+ if( sd && sd->inventory_data[sd->equip_index[EQI_HAND_R]] ) { // Chars.
+ val1 += (sd->inventory_data[sd->equip_index[EQI_HAND_R]]->weight/10 * sd->inventory_data[sd->equip_index[EQI_HAND_R]]->wlv * status->get_lv(bl) / 100);
+ val1 += 15 * (sd ? sd->status.job_level:50) + 100;
+ } else // Mobs
+ val1 += (400 * status->get_lv(bl) / 100) + (15 * (status->get_lv(bl) / 2)); // About 1138% at mob_lvl 99. Is an aproximation to a standard weapon. [pakpil]
+ break;
+ case SC_PRESTIGE: // Based on suggested formula in iRO Wiki and some test, still need more test. [pakpil]
+ val2 = ((st->int_ + st->luk) / 6) + 5; // Chance to evade magic damage.
+ val1 *= 15; // Defence added
+ if( sd )
+ val1 += 10 * pc->checkskill(sd,CR_DEFENDER);
+ break;
+ case SC_BANDING:
+ tick_time = 5000; // [GodLesZ] tick time
+ break;
+ case SC_MAGNETICFIELD:
+ val3 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_INSPIRATION:
+ if( sd ) {
+ val2 = (40 * val1) + (3 * sd->status.job_level); // ATK bonus
+ val3 = (sd->status.job_level / 10) * 2 + 12; // All stat bonus
+ }
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ status->change_clear_buffs(bl,3); //Remove buffs/debuffs
+ break;
+ case SC_CRESCENTELBOW:
+ val2 = 94 + val1;
+ break;
+ case SC_LIGHTNINGWALK: // [(Job Level / 2) + (40 + 5 * Skill Level)] %
+ val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1;
+ break;
+ case SC_RAISINGDRAGON:
+ val3 = tick / 5000;
+ tick_time = 5000; // [GodLesZ] tick time
+ break;
+ case SC_GENTLETOUCH_CHANGE:
+ {// take note there is no def increase as skill desc says. [malufett]
+ struct block_list * src;
+ val3 = st->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] %
+ if( (src = map->id2bl(val2)) ){
+ val4 = ( 200/status_get_int(src) ) * val1;// MDEF decrease: MDEF [(200 / Caster INT) x Skill Level]
+ val2 = ( status_get_dex(src)/4 + status_get_str(src)/2 ) * val1 / 5; // ATK increase: ATK [{(Caster DEX / 4) + (Caster STR / 2)} x Skill Level / 5]
}
}
- break;
- case SC_NJ_UTSUSEMI:
- val2=(val1+1)/2; // number of hits blocked
- val3=skill->get_blewcount(NJ_UTSUSEMI, val1); //knockback value.
- break;
- case SC_NJ_BUNSINJYUTSU:
- val2=(val1+1)/2; // number of hits blocked
- break;
- case SC_HLIF_CHANGE:
- val2= 30*val1; //Vit increase
- val3= 20*val1; //Int increase
- break;
- case SC_SWOO:
- if(st->mode&MD_BOSS)
- tick /= 5; //TODO: Reduce skill's duration. But for how long?
- break;
- case SC_SPIDERWEB:
- if( bl->type == BL_PC )
- tick /= 2;
- break;
- case SC_ARMOR:
- //NPC_DEFENDER:
- val2 = 80; //Damage reduction
- //Attack requirements to be blocked:
- val3 = BF_LONG; //Range
- val4 = BF_WEAPON|BF_MISC; //Type
- break;
- case SC_ENCHANTARMS:
- //end previous enchants
- skill->enchant_elemental_end(bl,type);
- //Make sure the received element is valid.
- if (val2 >= ELE_MAX)
- val2 = val2%ELE_MAX;
- else if (val2 < 0)
- val2 = rnd()%ELE_MAX;
- break;
- case SC_CRITICALWOUND:
- val2 = 20*val1; //Heal effectiveness decrease
- break;
- case SC_MAGICMIRROR:
- case SC_SLOWCAST:
- val2 = 20*val1; //Magic reflection/cast rate
- break;
-
- case SC_STONESKIN:
- if (val2 == NPC_ANTIMAGIC)
- { //Boost mdef
- val2 =-20;
- val3 = 20;
- } else { //Boost def
- val2 = 20;
- val3 =-20;
+ break;
+ case SC_GENTLETOUCH_REVITALIZE:
+ {// take note there is no vit,aspd,speed increase as skill desc says. [malufett]
+ struct block_list * src;
+ val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] %
+ if( (src = map->id2bl(val2)) ) // the stat def is not shown in the status window and it is process differently
+ val4 = ( status_get_vit(src)/4 ) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level]
}
- val2*=val1; //20% per level
- val3*=val1;
- break;
- case SC_CASH_PLUSEXP:
- case SC_CASH_PLUSONLYJOBEXP:
- if (val1 < 0)
- val1 = 0;
- break;
- case SC_PLUSAVOIDVALUE:
- case SC_CRITICALPERCENT:
- val2 = val1*10; //Actual boost (since 100% = 1000)
- break;
- case SC_SUFFRAGIUM:
- val2 = 15 * val1; //Speed cast decrease
- break;
- case SC_HEALPLUS:
- if (val1 < 1)
- val1 = 1;
- break;
- case SC_ILLUSION:
- val2 = 5+val1; //Factor by which displayed damage is increased by
- break;
- case SC_DOUBLECASTING:
- val2 = 30+10*val1; //Trigger rate
- break;
- case SC_KAIZEL:
- val2 = 10*val1; //% of life to be revived with
- break;
- // case SC_ARMORPROPERTY:
- // case SC_ARMOR_RESIST:
- // Mod your resistance against elements:
- // val1 = water | val2 = earth | val3 = fire | val4 = wind
- // break;
- //case ????:
- //Place here SCs that have no SCB_* data, no skill associated, no ICON
- //associated, and yet are not wrong/unknown. [Skotlex]
- //break;
+ break;
+ case SC_HEATER_OPTION:
+ val2 = 120; // Watk. TODO: Renewal (Atk2)
+ val3 = 33; // % Increase effects.
+ val4 = 3; // Change into fire element.
+ break;
+ case SC_TROPIC_OPTION:
+ val2 = 180; // Watk. TODO: Renewal (Atk2)
+ val3 = MG_FIREBOLT;
+ break;
+ case SC_AQUAPLAY_OPTION:
+ val2 = 40;
+ break;
+ case SC_COOLER_OPTION:
+ val2 = 80; // % Freezing chance
+ val3 = 33; // % increased damage
+ val4 = 1; // Change into water elemet
+ break;
+ case SC_CHILLY_AIR_OPTION:
+ val2 = 120; // Matk. TODO: Renewal (Matk1)
+ val3 = MG_COLDBOLT;
+ break;
+ case SC_WIND_STEP_OPTION:
+ val2 = 50; // % Increase speed and flee.
+ break;
+ case SC_BLAST_OPTION:
+ val2 = 20;
+ val3 = ELE_WIND;
+ break;
+ case SC_WILD_STORM_OPTION:
+ val2 = MG_LIGHTNINGBOLT;
+ break;
+ case SC_PETROLOGY_OPTION:
+ val2 = 5;
+ val3 = 50;
+ break;
+ case SC_CURSED_SOIL_OPTION:
+ val2 = 10;
+ val3 = 33;
+ val4 = 2;
+ break;
+ case SC_UPHEAVAL_OPTION:
+ val2 = WZ_EARTHSPIKE;
+ break;
+ case SC_CIRCLE_OF_FIRE_OPTION:
+ val2 = 300;
+ break;
+ case SC_FIRE_CLOAK_OPTION:
+ case SC_WATER_DROP_OPTION:
+ case SC_WIND_CURTAIN_OPTION:
+ case SC_STONE_SHIELD_OPTION:
+ val2 = 20; // Elemental modifier. Not confirmed.
+ break;
+ case SC_CIRCLE_OF_FIRE:
+ case SC_FIRE_CLOAK:
+ case SC_WATER_DROP:
+ case SC_WATER_SCREEN:
+ case SC_WIND_CURTAIN:
+ case SC_WIND_STEP:
+ case SC_STONE_SHIELD:
+ case SC_SOLID_SKIN:
+ val2 = 10;
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ case SC_WATER_BARRIER:
+ val2 = 40; // Increasement. Mdef1 ???
+ val3 = 20; // Reductions. Atk2, Flee1, Matk1 ????
+ break;
+ case SC_ZEPHYR:
+ val2 = 22; // Flee.
+ break;
+ case SC_TIDAL_WEAPON:
+ val2 = 20; // Increase Elemental's attack.
+ break;
+ case SC_ROCK_CRUSHER:
+ case SC_ROCK_CRUSHER_ATK:
+ case SC_POWER_OF_GAIA:
+ val2 = 33;
+ break;
+ case SC_MELON_BOMB:
+ case SC_BANANA_BOMB:
+ val1 = 15;
+ break;
+ case SC_STOMACHACHE:
+ val2 = 8; // SP consume.
+ val4 = tick / 10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_KYOUGAKU:
+ val2 = 2*val1 + rand()%(3 * val1);
+ clif->status_change(bl, SI_ACTIVE_MONSTER_TRANSFORM, 1, 0, 1002, 0, 0); // Poring in disguise
+ break;
+ case SC_KAGEMUSYA:
+ val3 = val1 * 2;
+ case SC_IZAYOI:
+ val2 = tick/1000;
+ tick_time = 1000;
+ break;
+ case SC_ZANGETSU:
+ val2 = val4 = status->get_lv(bl) / 3 + 20 * val1;
+ val3 = status->get_lv(bl) / 2 + 30 * val1;
+ val2 = (!(status_get_hp(bl)%2) ? val2 : -val3);
+ val3 = (!(status_get_sp(bl)%2) ? val4 : -val3);
+ break;
+ case SC_GENSOU:
- case SC_MER_FLEE:
- case SC_MER_ATK:
- case SC_MER_HIT:
- val2 = 15 * val1;
- break;
- case SC_MER_HP:
- case SC_MER_SP:
- val2 = 5 * val1;
- break;
- case SC_REBIRTH:
- val2 = 20*val1; //% of life to be revived with
- break;
+ #define PER( a ) do { \
+ if( a <= 15 ) lv = 1; \
+ else if( a <= 30 ) lv = 2; \
+ else if( a <= 50 ) lv = 3; \
+ else if( a <= 75 ) lv = 4; \
+ } while(0)
- case SC_MANU_DEF:
- case SC_MANU_ATK:
- case SC_MANU_MATK:
- val2 = 1; // Manuk group
- break;
- case SC_SPL_DEF:
- case SC_SPL_ATK:
- case SC_SPL_MATK:
- val2 = 2; // Splendide group
- break;
- /**
- * General
- **/
- case SC_FEAR:
- val2 = 2;
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_BURNING:
- val4 = tick / 3000; // Total Ticks to Burn!!
- tick_time = 3000; // [GodLesZ] tick time
- break;
- /**
- * Rune Knight
- **/
- case SC_DEATHBOUND:
- val2 = 500 + 100 * val1;
- break;
- case SC_STONEHARDSKIN:
- if( sd )
- val1 = sd->status.job_level * pc->checkskill(sd, RK_RUNEMASTERY) / 4; //DEF/MDEF Increase
- break;
+ {
+ int hp = status_get_hp(bl), sp = status_get_sp(bl), lv = 5;
+
+ if( rand()%100 > (25 + 10 * val1) - status_get_int(bl) / 2)
+ return 0;
+
+ PER( 100 / (status_get_max_hp(bl) / hp) );
+ status->heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, 1);
+
+ PER( 100 / (status_get_max_sp(bl) / sp) );
+ status->heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), 1);
+ }
+ #undef PER
+ break;
+ case SC_ANGRIFFS_MODUS:
+ val2 = 50 + 20 * val1; //atk bonus
+ val3 = 40 + 20 * val1; // Flee reduction.
+ val4 = tick/1000; // hp/sp reduction timer
+ tick_time = 1000;
+ break;
+ case SC_NEUTRALBARRIER:
+ tick_time = tick;
+ tick = -1;
+ break;
+ case SC_GOLDENE_FERSE:
+ val2 = 10 + 10*val1; //max hp bonus
+ val3 = 6 + 4 * val1; // Aspd Bonus
+ val4 = 2 + 2 * val1; // Chance of holy attack
+ break;
+ case SC_OVERED_BOOST:
+ val2 = 300 + 40*val1; //flee bonus
+ val3 = 179 + 2*val1; //aspd bonus
+ break;
+ case SC_GRANITIC_ARMOR:
+ val2 = 2*val1; //dmg reduction
+ val3 = 6*val1; //dmg on status end
+ break;
+ case SC_MAGMA_FLOW:
+ val2 = 3*val1; //activation chance
+ break;
+ case SC_PYROCLASTIC:
+ val2 += 10*val1; //atk bonus
+ break;
+ case SC_NEEDLE_OF_PARALYZE: //[Lighta] need real info
+ val2 = 2*val1; //def reduction
+ val3 = 500*val1; //varcast augmentation
+ break;
+ case SC_PAIN_KILLER: //[Lighta] need real info
+ val2 = 2*val1; //aspd reduction %
+ val3 = 2*val1; //dmg reduction %
+ if(sc->data[SC_NEEDLE_OF_PARALYZE])
+ sc_start(bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
+ break;
+ case SC_STYLE_CHANGE: //[Lighta] need real info
+ tick = -1;
+ if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING;
+ else val2 = MH_MD_FIGHTING;
+ break;
+ case SC_FULL_THROTTLE:
+ status_percent_heal(bl,100,0);
+ val2 = 7 - val1;
+ tick_time = 1000;
+ val4 = tick / tick_time;
+ break;
+ case SC_KINGS_GRACE:
+ val2 = 3 + val1;
+ tick_time = 1000;
+ val4 = tick / tick_time;
+ break;
+ case SC_TELEKINESIS_INTENSE:
+ val2 = 10 * val1;
+ val3 = 40 * val1;
+ break;
+ case SC_OFFERTORIUM:
+ val2 = 30 * val1;
+ break;
+ case SC_FRIGG_SONG:
+ val2 = 5 * val1;
+ val3 = 1000 + 100 * val1;
+ tick_time = 10000;
+ val4 = tick / tick_time;
+ break;
+ case SC_MONSTER_TRANSFORM:
+ if( !mob->db_checkid(val1) )
+ val1 = 1002; // default poring
+ break;
+ default:
+ if( calc_flag == SCB_NONE && status->SkillChangeTable[type] == 0 && status->IconChangeTable[type] == 0 )
+ { //Status change with no calc, no icon, and no skill associated...?
+ ShowError("UnknownStatusChange [%d]\n", type);
+ return 0;
+ }
+ }
+ } else { //Special considerations when loading SC data.
+ switch( type ) {
+ case SC_WEDDING:
+ case SC_XMAS:
+ case SC_SUMMER:
+ case SC_HANBOK:
+ if( !vd ) break;
+ clif->changelook(bl,LOOK_BASE,vd->class_);
+ clif->changelook(bl,LOOK_WEAPON,0);
+ clif->changelook(bl,LOOK_SHIELD,0);
+ clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
+ break;
+ case SC_KAAHI:
+ val4 = INVALID_TIMER;
+ break;
+ case SC_KYOUGAKU:
+ clif->status_change(bl, SI_ACTIVE_MONSTER_TRANSFORM, 1, 0, 1002, 0, 0); // Poring in disguise
+ break;
+ }
+ }
+
+ /* values that must be set regardless of flag&4 e.g. val_flag */
+ switch(type) {
case SC_FIGHTINGSPIRIT:
val_flag |= 1|2;
break;
- case SC_ABUNDANCE:
- val4 = tick / 10000;
- tick_time = 10000; // [GodLesZ] tick time
- break;
- /**
- * Arch Bishop
- **/
- case SC_RENOVATIO:
- val4 = tick / 5000;
- tick_time = 5000;
- break;
- case SC_SECRAMENT:
- val2 = 10 * val1;
- break;
case SC_VENOMIMPRESS:
- val2 = 10 * val1;
val_flag |= 1|2;
break;
case SC_POISONINGWEAPON:
val_flag |= 1|2|4;
break;
case SC_WEAPONBLOCKING:
- val2 = 10 + 2 * val1; // Chance
- val4 = tick / 3000;
- tick_time = 3000; // [GodLesZ] tick time
val_flag |= 1|2;
break;
- case SC_TOXIN:
- val4 = tick / 10000;
- tick_time = 10000; // [GodLesZ] tick time
- break;
- case SC_MAGICMUSHROOM:
- val4 = tick / 4000;
- tick_time = 4000; // [GodLesZ] tick time
- break;
- case SC_PYREXIA:
- status->change_start(bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds
- val4 = tick / 3000;
- tick_time = 3000; // [GodLesZ] tick time
- break;
- case SC_LEECHESEND:
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_OBLIVIONCURSE:
- val4 = tick / 3000;
- tick_time = 3000; // [GodLesZ] tick time
- break;
case SC_ROLLINGCUTTER:
val_flag |= 1;
break;
case SC_CLOAKINGEXCEED:
- val2 = ( val1 + 1 ) / 2; // Hits
- val3 = 90 + val1 * 10; // Walk speed
val_flag |= 1|2|4;
- if (bl->type == BL_PC)
- val4 |= battle_config.pc_cloak_check_type&7;
- else
- val4 |= battle_config.monster_cloak_check_type&7;
- tick_time = 1000; // [GodLesZ] tick time
break;
case SC_HALLUCINATIONWALK:
- val2 = 50 * val1; // Evasion rate of physical attacks. Flee
- val3 = 10 * val1; // Evasion rate of magical attacks.
val_flag |= 1|2|4;
break;
- case SC_WHITEIMPRISON:
- status_change_end(bl, SC_BURNING, INVALID_TIMER);
- status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER);
- status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- break;
- case SC_MARSHOFABYSS:
- val2 = 6 * val1;
- if( sd ) // half on players
- val2 >>= 1;
- break;
- case SC_FROSTMISTY:
- status_change_end(bl, SC_BURNING, INVALID_TIMER);
- break;
- case SC_READING_SB:
- // val2 = sp reduction per second
- tick_time = 5000; // [GodLesZ] tick time
- break;
case SC_SUMMON1:
case SC_SUMMON2:
case SC_SUMMON3:
case SC_SUMMON4:
case SC_SUMMON5:
- val4 = tick / 1000;
- if( val4 < 1 )
- val4 = 1;
- tick_time = 1000; // [GodLesZ] tick time
val_flag |= 1;
break;
- case SC_SHAPESHIFT:
- switch( val1 )
- {
- case 1: val2 = ELE_FIRE; break;
- case 2: val2 = ELE_EARTH; break;
- case 3: val2 = ELE_WIND; break;
- case 4: val2 = ELE_WATER; break;
- }
- break;
- case SC_ELECTRICSHOCKER:
- case SC_COLD:
- case SC_MEIKYOUSISUI:
- val4 = tick / 1000;
- if( val4 < 1 )
- val4 = 1;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_CAMOUFLAGE:
- val4 = tick/1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_WUGDASH:
- val4 = timer->gettick(); //Store time at which you started running.
- tick = -1;
- break;
- case SC__SHADOWFORM: {
- struct map_session_data * s_sd = map->id2sd(val2);
- if( s_sd )
- s_sd->shadowform_id = bl->id;
- val4 = tick / 1000;
+ case SC__SHADOWFORM:
val_flag |= 1|2|4;
- tick_time = 1000; // [GodLesZ] tick time
- }
- break;
- case SC__STRIPACCESSARY:
- if (!sd)
- val2 = 20;
break;
case SC__INVISIBILITY:
- val2 = 50 - 10 * val1; // ASPD
- val3 = 20 * val1; // CRITICAL
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
val_flag |= 1|2;
break;
case SC__ENERVATION:
- val2 = 20 + 10 * val1; // ATK Reduction
val_flag |= 1|2;
- if( sd ) pc->delspiritball(sd,sd->spiritball,0);
break;
case SC__GROOMY:
- val2 = 20 + 10 * val1; //ASPD. Need to confirm if Movement Speed reduction is the same. [Jobbie]
- val3 = 20 * val1; //HIT
val_flag |= 1|2|4;
- if( sd ) { // Removes Animals
- if( pc_isriding(sd) ) pc->setriding(sd, 0);
- if( pc_isridingdragon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_DRAGON);
- if( pc_iswug(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_WUG);
- if( pc_isridingwug(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
- if( pc_isfalcon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_FALCON);
- if( sd->status.pet_id > 0 ) pet->menu(sd, 3);
- if( homun_alive(sd->hd) ) homun->vaporize(sd,HOM_ST_REST);
- if( sd->md ) mercenary->delete(sd->md,3);
- }
break;
case SC__LAZINESS:
- val2 = 10 + 10 * val1; // Cast reduction
- val3 = 10 * val1; // Flee Reduction
val_flag |= 1|2|4;
break;
case SC__UNLUCKY:
- val2 = 10 * val1; // Crit and Flee2 Reduction
val_flag |= 1|2|4;
break;
case SC__WEAKNESS:
- val2 = 10 * val1;
val_flag |= 1|2;
- // bypasses coating protection and MADO
- sc_start(bl,SC_NOEQUIPWEAPON,100,val1,tick);
- sc_start(bl,SC_NOEQUIPSHIELD,100,val1,tick);
- break;
- case SC_GN_CARTBOOST:
- if( val1 < 3 )
- val2 = 50;
- else if( val1 < 5 )
- val2 = 75;
- else
- val2 = 100;
break;
case SC_PROPERTYWALK:
val_flag |= 1|2;
- val3 = 0;
- break;
- case SC_WARMER:
- status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER);
- status_change_end(bl, SC_COLD, INVALID_TIMER);
- break;
- case SC_STRIKING:
- val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1)
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_BLOOD_SUCKER:
- {
- struct block_list *src = map->id2bl(val2);
- val3 = 1;
- if(src)
- val3 = 200 + 100 * val1 + status_get_int(src);
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- }
- break;
- case SC_VACUUM_EXTREME:
- tick -= (st->str / 20) * 1000;
- val4 = val3 = tick / 100;
- tick_time = 100; // [GodLesZ] tick time
- break;
- case SC_SWING:
- val2 = 4 * val1; // Walk speed and aspd reduction.
- break;
- case SC_SYMPHONY_LOVE:
- case SC_RUSH_WINDMILL:
- case SC_ECHOSONG:
- val2 = 6 * val1;
- val2 += val3; //Adding 1% * Lesson Bonus
- val2 += (int)(val4*2/10); //Adding 0.2% per JobLevel
- break;
- case SC_MOONLIT_SERENADE:
- val2 = 10 * val1;
- break;
- case SC_HARMONIZE:
- val2 = 5 + 5 * val1;
- break;
- case SC_SIREN:
- val4 = tick / 2000;
- tick_time = 2000; // [GodLesZ] tick time
- break;
- case SC_DEEP_SLEEP:
- val4 = tick / 2000;
- tick_time = 2000; // [GodLesZ] tick time
- break;
- case SC_SIRCLEOFNATURE:
- val2 = 1 + val1; //SP consume
- val3 = 40 * val1; //HP recovery
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_SONG_OF_MANA:
- val3 = 10 + (2 * val2);
- val4 = tick/3000;
- tick_time = 3000; // [GodLesZ] tick time
- break;
- case SC_SATURDAY_NIGHT_FEVER:
- if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1);
- if (!val4) val4 = 3000;
- val3 = tick/val4;
- tick_time = val4; // [GodLesZ] tick time
- break;
- case SC_GLOOMYDAY:
- val2 = 20 + 5 * val1; // Flee reduction.
- val3 = 15 + 5 * val1; // ASPD reduction.
- if( sd && rand()%100 < val1 ){ // (Skill Lv) %
- val4 = 1; // reduce walk speed by half.
- if( pc_isriding(sd) ) pc->setriding(sd, 0);
- if( pc_isridingdragon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_DRAGON);
- }
- break;
- case SC_GLOOMYDAY_SK:
- // Random number between [15 ~ (Voice Lesson Skill Level x 5) + (Skill Level x 10)] %.
- val2 = 15 + rand()%( (sd?pc->checkskill(sd, WM_LESSON)*5:0) + val1*10 );
- break;
- case SC_SITDOWN_FORCE:
- case SC_BANANA_BOMB_SITDOWN_POSTDELAY:
- if( sd && !pc_issit(sd) )
- {
- pc_setsit(sd);
- skill->sit(sd,1);
- clif->sitting(bl);
- }
- break;
- case SC_DANCE_WITH_WUG:
- val3 = (5 * val1) + (1 * val2); //Still need official value.
- break;
- case SC_LERADS_DEW:
- val3 = (5 * val1) + (1 * val2);
- break;
- case SC_MELODYOFSINK:
- val3 = (5 * val1) + (1 * val2);
break;
- case SC_BEYOND_OF_WARCRY:
- val3 = (5 * val1) + (1 * val2);
- break;
- case SC_UNLIMITED_HUMMING_VOICE:
- {
- struct unit_data *ud = unit->bl2ud(bl);
- if( ud == NULL ) return 0;
- ud->state.skillcastcancel = 0;
- val3 = 15 - (2 * val2);
- }
- break;
- case SC_LG_REFLECTDAMAGE:
- val2 = 15 + 5 * val1;
- val3 = (val1==5)?20:(val1+4)*2; // SP consumption
- val4 = tick/10000;
- tick_time = 10000; // [GodLesZ] tick time
- break;
- case SC_FORCEOFVANGUARD: // This is not the official way to handle it but I think we should use it. [pakpil]
- val2 = 20 + 12 * (val1 - 1); // Chance
- val3 = 5 + (2 * val1); // Max rage counters
- tick = -1; //endless duration in the client
- tick_time = 6000; // [GodLesZ] tick time
+ case SC_FORCEOFVANGUARD:
val_flag |= 1|2|4;
break;
- case SC_EXEEDBREAK:
- val1 *= 150; // 150 * skill_lv
- if( sd && sd->inventory_data[sd->equip_index[EQI_HAND_R]] ) { // Chars.
- val1 += (sd->inventory_data[sd->equip_index[EQI_HAND_R]]->weight/10 * sd->inventory_data[sd->equip_index[EQI_HAND_R]]->wlv * status->get_lv(bl) / 100);
- val1 += 15 * (sd ? sd->status.job_level:50) + 100;
- } else // Mobs
- val1 += (400 * status->get_lv(bl) / 100) + (15 * (status->get_lv(bl) / 2)); // About 1138% at mob_lvl 99. Is an aproximation to a standard weapon. [pakpil]
- break;
- case SC_PRESTIGE: // Based on suggested formula in iRO Wiki and some test, still need more test. [pakpil]
- val2 = ((st->int_ + st->luk) / 6) + 5; // Chance to evade magic damage.
- val1 *= 15; // Defence added
- if( sd )
- val1 += 10 * pc->checkskill(sd,CR_DEFENDER);
+ case SC_PRESTIGE:
val_flag |= 1|2;
break;
case SC_BANDING:
- tick_time = 5000; // [GodLesZ] tick time
val_flag |= 1;
break;
case SC_SHIELDSPELL_DEF:
@@ -8419,554 +8745,312 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_SHIELDSPELL_REF:
val_flag |= 1|2;
break;
- case SC_MAGNETICFIELD:
- val3 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- break;
- case SC_INSPIRATION:
- if( sd ) {
- val2 = (40 * val1) + (3 * sd->status.job_level); // ATK bonus
- val3 = (sd->status.job_level / 10) * 2 + 12; // All stat bonus
- }
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
- status->change_clear_buffs(bl,3); //Remove buffs/debuffs
- break;
case SC_SPELLFIST:
case SC_CURSEDCIRCLE_ATKER:
val_flag |= 1|2|4;
break;
case SC_CRESCENTELBOW:
- val2 = 94 + val1;
val_flag |= 1|2;
break;
- case SC_LIGHTNINGWALK: // [(Job Level / 2) + (40 + 5 * Skill Level)] %
- val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1;
+ case SC_LIGHTNINGWALK:
val_flag |= 1;
break;
- case SC_RAISINGDRAGON:
- val3 = tick / 5000;
- tick_time = 5000; // [GodLesZ] tick time
- break;
- case SC_GENTLETOUCH_CHANGE:
- {// take note there is no def increase as skill desc says. [malufett]
- struct block_list * src;
- val3 = st->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] %
- if( (src = map->id2bl(val2)) ){
- val4 = ( 200/status_get_int(src) ) * val1;// MDEF decrease: MDEF [(200 / Caster INT) x Skill Level]
- val2 = ( status_get_dex(src)/4 + status_get_str(src)/2 ) * val1 / 5; // ATK increase: ATK [{(Caster DEX / 4) + (Caster STR / 2)} x Skill Level / 5]
- }
- }
- break;
- case SC_GENTLETOUCH_REVITALIZE:
- {// take note there is no vit,aspd,speed increase as skill desc says. [malufett]
- struct block_list * src;
- val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] %
- if( (src = map->id2bl(val2)) ) // the stat def is not shown in the status window and it is process differently
- val4 = ( status_get_vit(src)/4 ) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level]
- }
- break;
case SC_PYROTECHNIC_OPTION:
val_flag |= 1|2|4;
break;
case SC_HEATER_OPTION:
- val2 = 120; // Watk. TODO: Renewal (Atk2)
- val3 = 33; // % Increase effects.
- val4 = 3; // Change into fire element.
val_flag |= 1|2|4;
break;
- case SC_TROPIC_OPTION:
- val2 = 180; // Watk. TODO: Renewal (Atk2)
- val3 = MG_FIREBOLT;
- break;
case SC_AQUAPLAY_OPTION:
- val2 = 40;
val_flag |= 1|2|4;
break;
case SC_COOLER_OPTION:
- val2 = 80; // % Freezing chance
- val3 = 33; // % increased damage
- val4 = 1; // Change into water elemet
val_flag |= 1|2|4;
break;
case SC_CHILLY_AIR_OPTION:
- val2 = 120; // Matk. TODO: Renewal (Matk1)
- val3 = MG_COLDBOLT;
val_flag |= 1|2;
break;
case SC_GUST_OPTION:
val_flag |= 1|2;
break;
- case SC_WIND_STEP_OPTION:
- val2 = 50; // % Increase speed and flee.
- break;
case SC_BLAST_OPTION:
- val2 = 20;
- val3 = ELE_WIND;
val_flag |= 1|2|4;
break;
case SC_WILD_STORM_OPTION:
- val2 = MG_LIGHTNINGBOLT;
val_flag |= 1|2;
break;
case SC_PETROLOGY_OPTION:
- val2 = 5;
- val3 = 50;
val_flag |= 1|2|4;
break;
case SC_CURSED_SOIL_OPTION:
- val2 = 10;
- val3 = 33;
- val4 = 2;
val_flag |= 1|2|4;
break;
case SC_UPHEAVAL_OPTION:
- val2 = WZ_EARTHSPIKE;
val_flag |= 1|2;
break;
case SC_CIRCLE_OF_FIRE_OPTION:
- val2 = 300;
val_flag |= 1|2;
break;
- case SC_FIRE_CLOAK_OPTION:
- case SC_WATER_DROP_OPTION:
- case SC_WIND_CURTAIN_OPTION:
- case SC_STONE_SHIELD_OPTION:
- val2 = 20; // Elemental modifier. Not confirmed.
- break;
- case SC_CIRCLE_OF_FIRE:
- case SC_FIRE_CLOAK:
- case SC_WATER_DROP:
- case SC_WATER_SCREEN:
- case SC_WIND_CURTAIN:
- case SC_WIND_STEP:
- case SC_STONE_SHIELD:
- case SC_SOLID_SKIN:
- val2 = 10;
- tick_time = 2000; // [GodLesZ] tick time
- break;
case SC_WATER_BARRIER:
- val2 = 40; // Increasement. Mdef1 ???
- val3 = 20; // Reductions. Atk2, Flee1, Matk1 ????
val_flag |= 1|2|4;
break;
- case SC_ZEPHYR:
- val2 = 22; // Flee.
- break;
- case SC_TIDAL_WEAPON:
- val2 = 20; // Increase Elemental's attack.
- break;
- case SC_ROCK_CRUSHER:
- case SC_ROCK_CRUSHER_ATK:
- case SC_POWER_OF_GAIA:
- val2 = 33;
- break;
- case SC_MELON_BOMB:
- case SC_BANANA_BOMB:
- val1 = 15;
- break;
- case SC_STOMACHACHE:
- val2 = 8; // SP consume.
- val4 = tick / 10000;
- tick_time = 10000; // [GodLesZ] tick time
- break;
- case SC_KYOUGAKU:
- val2 = 2*val1 + rand()%(3 * val1);
- clif->status_change(bl, SI_ACTIVE_MONSTER_TRANSFORM, 1, 0, 1002, 0, 0); // Poring in disguise
- break;
- case SC_KAGEMUSYA:
- val3 = val1 * 2;
- case SC_IZAYOI:
- val2 = tick/1000;
- tick_time = 1000;
- break;
- case SC_ZANGETSU:
- val2 = val4 = status->get_lv(bl) / 3 + 20 * val1;
- val3 = status->get_lv(bl) / 2 + 30 * val1;
- val2 = (!(status_get_hp(bl)%2) ? val2 : -val3);
- val3 = (!(status_get_sp(bl)%2) ? val4 : -val3);
- break;
- case SC_GENSOU:
-
-#define PER( a ) do { \
- if( a <= 15 ) lv = 1; \
- else if( a <= 30 ) lv = 2; \
- else if( a <= 50 ) lv = 3; \
- else if( a <= 75 ) lv = 4; \
-} while(0)
-
- {
- int hp = status_get_hp(bl), sp = status_get_sp(bl), lv = 5;
-
- if( rand()%100 > (25 + 10 * val1) - status_get_int(bl) / 2)
- return 0;
-
- PER( 100 / (status_get_max_hp(bl) / hp) );
- status->heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, 1);
-
- PER( 100 / (status_get_max_sp(bl) / sp) );
- status->heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), 1);
- }
-#undef PER
- break;
- case SC_ANGRIFFS_MODUS:
- val2 = 50 + 20 * val1; //atk bonus
- val3 = 40 + 20 * val1; // Flee reduction.
- val4 = tick/1000; // hp/sp reduction timer
- tick_time = 1000;
- break;
- case SC_NEUTRALBARRIER:
- tick_time = tick;
- tick = -1;
- break;
- case SC_GOLDENE_FERSE:
- val2 = 10 + 10*val1; //max hp bonus
- val3 = 6 + 4 * val1; // Aspd Bonus
- val4 = 2 + 2 * val1; // Chance of holy attack
- break;
- case SC_OVERED_BOOST:
- val2 = 300 + 40*val1; //flee bonus
- val3 = 179 + 2*val1; //aspd bonus
- break;
- case SC_GRANITIC_ARMOR:
- val2 = 2*val1; //dmg reduction
- val3 = 6*val1; //dmg on status end
- break;
- case SC_MAGMA_FLOW:
- val2 = 3*val1; //activation chance
- break;
- case SC_PYROCLASTIC:
- val2 += 10*val1; //atk bonus
- break;
- case SC_NEEDLE_OF_PARALYZE: //[Lighta] need real info
- val2 = 2*val1; //def reduction
- val3 = 500*val1; //varcast augmentation
- break;
- case SC_PAIN_KILLER: //[Lighta] need real info
- val2 = 2*val1; //aspd reduction %
- val3 = 2*val1; //dmg reduction %
- if(sc->data[SC_NEEDLE_OF_PARALYZE])
- sc_start(bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
- break;
- case SC_STYLE_CHANGE: //[Lighta] need real info
- tick = -1;
- if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING;
- else val2 = MH_MD_FIGHTING;
- break;
- case SC_FULL_THROTTLE:
- status_percent_heal(bl,100,0);
- val2 = 7 - val1;
- tick_time = 1000;
- val4 = tick / tick_time;
- break;
- case SC_KINGS_GRACE:
- val2 = 3 + val1;
- tick_time = 1000;
- val4 = tick / tick_time;
- break;
- case SC_TELEKINESIS_INTENSE:
- val2 = 10 * val1;
- val3 = 40 * val1;
- break;
- case SC_OFFERTORIUM:
- val2 = 30 * val1;
- break;
- case SC_FRIGG_SONG:
- val2 = 5 * val1;
- val3 = 1000 + 100 * val1;
- tick_time = 10000;
- val4 = tick / tick_time;
- break;
- case SC_MONSTER_TRANSFORM:
- if( !mob->db_checkid(val1) )
- val1 = 1002; // default poring
- val_flag |= 1;
- break;
- default:
- if( calc_flag == SCB_NONE && status->SkillChangeTable[type] == 0 && status->IconChangeTable[type] == 0 )
- { //Status change with no calc, no icon, and no skill associated...?
- ShowError("UnknownStatusChange [%d]\n", type);
- return 0;
- }
- }
- } else { //Special considerations when loading SC data.
- switch( type ) {
- case SC_WEDDING:
- case SC_XMAS:
- case SC_SUMMER:
- case SC_HANBOK:
- if( !vd ) break;
- clif->changelook(bl,LOOK_BASE,vd->class_);
- clif->changelook(bl,LOOK_WEAPON,0);
- clif->changelook(bl,LOOK_SHIELD,0);
- clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
- break;
- case SC_KAAHI:
- val4 = INVALID_TIMER;
- break;
- case SC_SUMMON1:
- case SC_SUMMON2:
- case SC_SUMMON3:
- case SC_SUMMON4:
- case SC_SUMMON5:
+ case SC_CASH_PLUSEXP:
+ case SC_CASH_PLUSONLYJOBEXP:
case SC_MONSTER_TRANSFORM:
+ case SC_CASH_RECEIVEITEM:
val_flag |= 1;
break;
- case SC_KYOUGAKU:
- clif->status_change(bl, SI_ACTIVE_MONSTER_TRANSFORM, 1, 0, 1002, 0, 0); // Poring in disguise
- break;
- }
}
-
+
/* [Ind/Hercules] */
if( sd && status->DisplayType[type] ) {
int dval1 = 0, dval2 = 0, dval3 = 0;
switch( type ) {
- case SC_ALL_RIDING:
- dval1 = 1;
- break;
- default: /* all others: just copy val1 */
- dval1 = val1;
- break;
+ case SC_ALL_RIDING:
+ dval1 = 1;
+ break;
+ default: /* all others: just copy val1 */
+ dval1 = val1;
+ break;
}
status->display_add(sd,type,dval1,dval2,dval3);
}
//Those that make you stop attacking/walking....
switch (type) {
- case SC_FREEZE:
- case SC_STUN:
- case SC_SLEEP:
- case SC_STONE:
- case SC_DEEP_SLEEP:
- if (sd && pc_issit(sd)) //Avoid sprite sync problems.
- pc->setstand(sd);
- case SC_TRICKDEAD:
- status_change_end(bl, SC_DANCING, INVALID_TIMER);
- // Cancel cast when get status [LuzZza]
- if (battle_config.sc_castcancel&bl->type)
- unit->skillcastcancel(bl, 0);
- case SC_WHITEIMPRISON:
- unit->stop_attack(bl);
- case SC_STOP:
- case SC_CONFUSION:
- case SC_RG_CCONFINE_M:
- case SC_RG_CCONFINE_S:
- case SC_SPIDERWEB:
- case SC_ELECTRICSHOCKER:
- case SC_WUGBITE:
- case SC_THORNS_TRAP:
- case SC__MANHOLE:
- case SC_COLD:
- case SC_CURSEDCIRCLE_ATKER:
- case SC_CURSEDCIRCLE_TARGET:
- case SC_FEAR:
- case SC_NETHERWORLD:
- case SC_MEIKYOUSISUI:
- case SC_KYOUGAKU:
- case SC_NEEDLE_OF_PARALYZE:
- case SC_DEATHBOUND:
- unit->stop_walking(bl,1);
- break;
- case SC_ANKLESNARE:
- if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) )
+ case SC_FREEZE:
+ case SC_STUN:
+ case SC_SLEEP:
+ case SC_STONE:
+ case SC_DEEP_SLEEP:
+ if (sd && pc_issit(sd)) //Avoid sprite sync problems.
+ pc->setstand(sd);
+ case SC_TRICKDEAD:
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
+ // Cancel cast when get status [LuzZza]
+ if (battle_config.sc_castcancel&bl->type)
+ unit->skillcastcancel(bl, 0);
+ case SC_WHITEIMPRISON:
+ unit->stop_attack(bl);
+ case SC_STOP:
+ case SC_CONFUSION:
+ case SC_RG_CCONFINE_M:
+ case SC_RG_CCONFINE_S:
+ case SC_SPIDERWEB:
+ case SC_ELECTRICSHOCKER:
+ case SC_WUGBITE:
+ case SC_THORNS_TRAP:
+ case SC__MANHOLE:
+ case SC_COLD:
+ case SC_CURSEDCIRCLE_ATKER:
+ case SC_CURSEDCIRCLE_TARGET:
+ case SC_FEAR:
+ case SC_NETHERWORLD:
+ case SC_MEIKYOUSISUI:
+ case SC_KYOUGAKU:
+ case SC_NEEDLE_OF_PARALYZE:
+ case SC_DEATHBOUND:
unit->stop_walking(bl,1);
- break;
- case SC_HIDING:
- case SC_CLOAKING:
- case SC_CLOAKINGEXCEED:
- case SC_CHASEWALK:
- case SC_WEIGHTOVER90:
- case SC_CAMOUFLAGE:
- case SC_SIREN:
- unit->stop_attack(bl);
- break;
- case SC_SILENCE:
- if (battle_config.sc_castcancel&bl->type)
- unit->skillcastcancel(bl, 0);
- break;
- /* */
- case SC_ITEMSCRIPT:
- if( sd ) {
- switch( val1 ) {
- //case 4121://Phree
- //case 4047://Ghostring
- case 4302://Gunka
- clif->status_change(bl,SI_MVPCARD_TAOGUNKA,1,tick,0,0,0);
- break;
- case 4132://Mistress
- clif->status_change(bl,SI_MVPCARD_MISTRESS,1,tick,0,0,0);
- break;
- case 4143://Orc Hero
- clif->status_change(bl,SI_MVPCARD_ORCHERO,1,tick,0,0,0);
- break;
- case 4135://Orc Lord
- clif->status_change(bl,SI_MVPCARD_ORCLORD,1,tick,0,0,0);
- break;
+ break;
+ case SC_ANKLESNARE:
+ if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) )
+ unit->stop_walking(bl,1);
+ break;
+ case SC_HIDING:
+ case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
+ case SC_CHASEWALK:
+ case SC_WEIGHTOVER90:
+ case SC_CAMOUFLAGE:
+ case SC_SIREN:
+ unit->stop_attack(bl);
+ break;
+ case SC_SILENCE:
+ if (battle_config.sc_castcancel&bl->type)
+ unit->skillcastcancel(bl, 0);
+ break;
+ /* */
+ case SC_ITEMSCRIPT:
+ if( sd ) {
+ switch( val1 ) {
+ //case 4121://Phree
+ //case 4047://Ghostring
+ case 4302://Gunka
+ clif->status_change(bl,SI_MVPCARD_TAOGUNKA,1,tick,0,0,0);
+ break;
+ case 4132://Mistress
+ clif->status_change(bl,SI_MVPCARD_MISTRESS,1,tick,0,0,0);
+ break;
+ case 4143://Orc Hero
+ clif->status_change(bl,SI_MVPCARD_ORCHERO,1,tick,0,0,0);
+ break;
+ case 4135://Orc Lord
+ clif->status_change(bl,SI_MVPCARD_ORCLORD,1,tick,0,0,0);
+ break;
+ }
}
- }
- break;
+ break;
}
// Set option as needed.
opt_flag = 1;
switch(type) {
//OPT1
- case SC_STONE: sc->opt1 = OPT1_STONEWAIT; break;
- case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break;
- case SC_STUN: sc->opt1 = OPT1_STUN; break;
- case SC_DEEP_SLEEP: opt_flag = 0;
- case SC_SLEEP: sc->opt1 = OPT1_SLEEP; break;
- case SC_BURNING: sc->opt1 = OPT1_BURNING; break; // Burning need this to be showed correctly. [pakpil]
- case SC_WHITEIMPRISON: sc->opt1 = OPT1_IMPRISON; break;
- case SC_COLD: sc->opt1 = OPT1_CRYSTALIZE; break;
+ case SC_STONE: sc->opt1 = OPT1_STONEWAIT; break;
+ case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break;
+ case SC_STUN: sc->opt1 = OPT1_STUN; break;
+ case SC_DEEP_SLEEP: opt_flag = 0;
+ case SC_SLEEP: sc->opt1 = OPT1_SLEEP; break;
+ case SC_BURNING: sc->opt1 = OPT1_BURNING; break; // Burning need this to be showed correctly. [pakpil]
+ case SC_WHITEIMPRISON: sc->opt1 = OPT1_IMPRISON; break;
+ case SC_COLD: sc->opt1 = OPT1_CRYSTALIZE; break;
//OPT2
- case SC_POISON: sc->opt2 |= OPT2_POISON; break;
- case SC_CURSE: sc->opt2 |= OPT2_CURSE; break;
- case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break;
+ case SC_POISON: sc->opt2 |= OPT2_POISON; break;
+ case SC_CURSE: sc->opt2 |= OPT2_CURSE; break;
+ case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break;
- case SC_CRUCIS:
- sc->opt2 |= OPT2_SIGNUMCRUCIS;
- break;
+ case SC_CRUCIS:
+ sc->opt2 |= OPT2_SIGNUMCRUCIS;
+ break;
- case SC_BLIND: sc->opt2 |= OPT2_BLIND; break;
- case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break;
- case SC_BLOODING: sc->opt2 |= OPT2_BLEEDING; break;
- case SC_DPOISON: sc->opt2 |= OPT2_DPOISON; break;
+ case SC_BLIND: sc->opt2 |= OPT2_BLIND; break;
+ case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break;
+ case SC_BLOODING: sc->opt2 |= OPT2_BLEEDING; break;
+ case SC_DPOISON: sc->opt2 |= OPT2_DPOISON; break;
//OPT3
- case SC_TWOHANDQUICKEN:
- case SC_ONEHANDQUICKEN:
- case SC_SPEARQUICKEN:
- case SC_LKCONCENTRATION:
- case SC_MER_QUICKEN:
- sc->opt3 |= OPT3_QUICKEN;
- opt_flag = 0;
- break;
- case SC_OVERTHRUSTMAX:
- case SC_OVERTHRUST:
- case SC_SWOO: //Why does it shares the same opt as Overthrust? Perhaps we'll never know...
- sc->opt3 |= OPT3_OVERTHRUST;
- opt_flag = 0;
- break;
- case SC_ENERGYCOAT:
- case SC_SKE:
- sc->opt3 |= OPT3_ENERGYCOAT;
- opt_flag = 0;
- break;
- case SC_INCATKRATE:
- //Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex]
- if (bl->type != BL_MOB) {
+ case SC_TWOHANDQUICKEN:
+ case SC_ONEHANDQUICKEN:
+ case SC_SPEARQUICKEN:
+ case SC_LKCONCENTRATION:
+ case SC_MER_QUICKEN:
+ sc->opt3 |= OPT3_QUICKEN;
opt_flag = 0;
break;
- }
- case SC_EXPLOSIONSPIRITS:
- sc->opt3 |= OPT3_EXPLOSIONSPIRITS;
- opt_flag = 0;
- break;
- case SC_STEELBODY:
- case SC_SKA:
- sc->opt3 |= OPT3_STEELBODY;
- opt_flag = 0;
- break;
- case SC_BLADESTOP:
- sc->opt3 |= OPT3_BLADESTOP;
- opt_flag = 0;
- break;
- case SC_AURABLADE:
- sc->opt3 |= OPT3_AURABLADE;
- opt_flag = 0;
- break;
- case SC_BERSERK:
- opt_flag = 0;
- sc->opt3 |= OPT3_BERSERK;
- break;
- // case ???: // doesn't seem to do anything
- // sc->opt3 |= OPT3_LIGHTBLADE;
- // opt_flag = 0;
- // break;
- case SC_DANCING:
- if ((val1&0xFFFF) == CG_MOONLIT)
- sc->opt3 |= OPT3_MOONLIT;
- opt_flag = 0;
- break;
- case SC_MARIONETTE_MASTER:
- case SC_MARIONETTE:
- sc->opt3 |= OPT3_MARIONETTE;
- opt_flag = 0;
- break;
- case SC_ASSUMPTIO:
- sc->opt3 |= OPT3_ASSUMPTIO;
- opt_flag = 0;
- break;
- case SC_WARM: //SG skills [Komurka]
- sc->opt3 |= OPT3_WARM;
- opt_flag = 0;
- break;
- case SC_KAITE:
- sc->opt3 |= OPT3_KAITE;
- opt_flag = 0;
- break;
- case SC_NJ_BUNSINJYUTSU:
- sc->opt3 |= OPT3_BUNSIN;
- opt_flag = 0;
- break;
- case SC_SOULLINK:
- sc->opt3 |= OPT3_SOULLINK;
- opt_flag = 0;
- break;
- case SC_PROPERTYUNDEAD:
- sc->opt3 |= OPT3_UNDEAD;
- opt_flag = 0;
- break;
- // case ???: // from DA_CONTRACT (looks like biolab mobs aura)
- // sc->opt3 |= OPT3_CONTRACT;
- // opt_flag = 0;
- // break;
+ case SC_OVERTHRUSTMAX:
+ case SC_OVERTHRUST:
+ case SC_SWOO: //Why does it shares the same opt as Overthrust? Perhaps we'll never know...
+ sc->opt3 |= OPT3_OVERTHRUST;
+ opt_flag = 0;
+ break;
+ case SC_ENERGYCOAT:
+ case SC_SKE:
+ sc->opt3 |= OPT3_ENERGYCOAT;
+ opt_flag = 0;
+ break;
+ case SC_INCATKRATE:
+ //Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex]
+ if (bl->type != BL_MOB) {
+ opt_flag = 0;
+ break;
+ }
+ case SC_EXPLOSIONSPIRITS:
+ sc->opt3 |= OPT3_EXPLOSIONSPIRITS;
+ opt_flag = 0;
+ break;
+ case SC_STEELBODY:
+ case SC_SKA:
+ sc->opt3 |= OPT3_STEELBODY;
+ opt_flag = 0;
+ break;
+ case SC_BLADESTOP:
+ sc->opt3 |= OPT3_BLADESTOP;
+ opt_flag = 0;
+ break;
+ case SC_AURABLADE:
+ sc->opt3 |= OPT3_AURABLADE;
+ opt_flag = 0;
+ break;
+ case SC_BERSERK:
+ opt_flag = 0;
+ sc->opt3 |= OPT3_BERSERK;
+ break;
+// case ???: // doesn't seem to do anything
+// sc->opt3 |= OPT3_LIGHTBLADE;
+// opt_flag = 0;
+// break;
+ case SC_DANCING:
+ if ((val1&0xFFFF) == CG_MOONLIT)
+ sc->opt3 |= OPT3_MOONLIT;
+ opt_flag = 0;
+ break;
+ case SC_MARIONETTE_MASTER:
+ case SC_MARIONETTE:
+ sc->opt3 |= OPT3_MARIONETTE;
+ opt_flag = 0;
+ break;
+ case SC_ASSUMPTIO:
+ sc->opt3 |= OPT3_ASSUMPTIO;
+ opt_flag = 0;
+ break;
+ case SC_WARM: //SG skills [Komurka]
+ sc->opt3 |= OPT3_WARM;
+ opt_flag = 0;
+ break;
+ case SC_KAITE:
+ sc->opt3 |= OPT3_KAITE;
+ opt_flag = 0;
+ break;
+ case SC_NJ_BUNSINJYUTSU:
+ sc->opt3 |= OPT3_BUNSIN;
+ opt_flag = 0;
+ break;
+ case SC_SOULLINK:
+ sc->opt3 |= OPT3_SOULLINK;
+ opt_flag = 0;
+ break;
+ case SC_PROPERTYUNDEAD:
+ sc->opt3 |= OPT3_UNDEAD;
+ opt_flag = 0;
+ break;
+// case ???: // from DA_CONTRACT (looks like biolab mobs aura)
+// sc->opt3 |= OPT3_CONTRACT;
+// opt_flag = 0;
+// break;
//OPTION
- case SC_HIDING:
- sc->option |= OPTION_HIDE;
- opt_flag = 2;
- break;
- case SC_CLOAKING:
- case SC_CLOAKINGEXCEED:
- case SC__INVISIBILITY:
- sc->option |= OPTION_CLOAK;
- opt_flag = 2;
- break;
- case SC_CHASEWALK:
- sc->option |= OPTION_CHASEWALK|OPTION_CLOAK;
- opt_flag = 2;
- break;
- case SC_SIGHT:
- sc->option |= OPTION_SIGHT;
- break;
- case SC_RUWACH:
- sc->option |= OPTION_RUWACH;
- break;
- case SC_WEDDING:
- sc->option |= OPTION_WEDDING;
- opt_flag |= 0x4;
- break;
- case SC_XMAS:
- sc->option |= OPTION_XMAS;
- opt_flag |= 0x4;
- break;
- case SC_SUMMER:
- sc->option |= OPTION_SUMMER;
- opt_flag |= 0x4;
- break;
- case SC_HANBOK:
- sc->option |= OPTION_HANBOK;
- opt_flag |= 0x4;
- break;
- case SC_ORCISH:
- sc->option |= OPTION_ORCISH;
- break;
- case SC_FUSION:
- sc->option |= OPTION_FLYING;
- break;
- default:
- opt_flag = 0;
+ case SC_HIDING:
+ sc->option |= OPTION_HIDE;
+ opt_flag = 2;
+ break;
+ case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
+ case SC__INVISIBILITY:
+ sc->option |= OPTION_CLOAK;
+ opt_flag = 2;
+ break;
+ case SC_CHASEWALK:
+ sc->option |= OPTION_CHASEWALK|OPTION_CLOAK;
+ opt_flag = 2;
+ break;
+ case SC_SIGHT:
+ sc->option |= OPTION_SIGHT;
+ break;
+ case SC_RUWACH:
+ sc->option |= OPTION_RUWACH;
+ break;
+ case SC_WEDDING:
+ sc->option |= OPTION_WEDDING;
+ opt_flag |= 0x4;
+ break;
+ case SC_XMAS:
+ sc->option |= OPTION_XMAS;
+ opt_flag |= 0x4;
+ break;
+ case SC_SUMMER:
+ sc->option |= OPTION_SUMMER;
+ opt_flag |= 0x4;
+ break;
+ case SC_HANBOK:
+ sc->option |= OPTION_HANBOK;
+ opt_flag |= 0x4;
+ break;
+ case SC_ORCISH:
+ sc->option |= OPTION_ORCISH;
+ break;
+ case SC_FUSION:
+ sc->option |= OPTION_FLYING;
+ break;
+ default:
+ opt_flag = 0;
}
//On Aegis, when turning on a status change, first goes the option packet, then the sc packet.
@@ -9020,81 +9104,81 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
pet->sc_check(sd, type); //Skotlex: Pet Status Effect Healing
switch (type) {
- case SC_BERSERK:
- if (!(sce->val2)) { //don't heal if already set
- status->heal(bl, st->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
- status->set_sp(bl, 0, 0); //Damage all SP
- }
- sce->val2 = 5 * st->max_hp / 100;
- break;
- case SC_HLIF_CHANGE:
- status_percent_heal(bl, 100, 100);
- break;
- case SC_RUN:
- {
- struct unit_data *ud = unit->bl2ud(bl);
- if( ud )
- ud->state.running = unit->run(bl);
- }
- break;
- case SC_CASH_BOSS_ALARM:
- clif->bossmapinfo(sd->fd, map->id2boss(sce->val1), 0); // First Message
- break;
- case SC_MER_HP:
- status_percent_heal(bl, 100, 0); // Recover Full HP
- break;
- case SC_MER_SP:
- status_percent_heal(bl, 0, 100); // Recover Full SP
- break;
- /**
- * Ranger
- **/
- case SC_WUGDASH:
- {
- struct unit_data *ud = unit->bl2ud(bl);
- if( ud )
- ud->state.running = unit->wugdash(bl, sd);
- }
- break;
- case SC_COMBOATTACK:
- switch (sce->val1) {
- case TK_STORMKICK:
- clif->skill_nodamage(bl,bl,TK_READYSTORM,1,1);
+ case SC_BERSERK:
+ if (!(sce->val2)) { //don't heal if already set
+ status->heal(bl, st->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
+ status->set_sp(bl, 0, 0); //Damage all SP
+ }
+ sce->val2 = 5 * st->max_hp / 100;
break;
- case TK_DOWNKICK:
- clif->skill_nodamage(bl,bl,TK_READYDOWN,1,1);
+ case SC_HLIF_CHANGE:
+ status_percent_heal(bl, 100, 100);
break;
- case TK_TURNKICK:
- clif->skill_nodamage(bl,bl,TK_READYTURN,1,1);
+ case SC_RUN:
+ {
+ struct unit_data *ud = unit->bl2ud(bl);
+ if( ud )
+ ud->state.running = unit->run(bl);
+ }
break;
- case TK_COUNTER:
- clif->skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
+ case SC_CASH_BOSS_ALARM:
+ clif->bossmapinfo(sd->fd, map->id2boss(sce->val1), 0); // First Message
break;
- case MO_COMBOFINISH:
- case CH_TIGERFIST:
- case CH_CHAINCRUSH:
- if (sd)
- clif->skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
+ case SC_MER_HP:
+ status_percent_heal(bl, 100, 0); // Recover Full HP
break;
- case TK_JUMPKICK:
- if (sd)
- clif->skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
+ case SC_MER_SP:
+ status_percent_heal(bl, 0, 100); // Recover Full SP
break;
- case MO_TRIPLEATTACK:
- if (sd && pc->checkskill(sd, SR_DRAGONCOMBO) > 0)
- clif->skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL);
+ /**
+ * Ranger
+ **/
+ case SC_WUGDASH:
+ {
+ struct unit_data *ud = unit->bl2ud(bl);
+ if( ud )
+ ud->state.running = unit->wugdash(bl, sd);
+ }
break;
- case SR_FALLENEMPIRE:
- if (sd){
- clif->skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL);
- clif->skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL);
+ case SC_COMBOATTACK:
+ switch (sce->val1) {
+ case TK_STORMKICK:
+ clif->skill_nodamage(bl,bl,TK_READYSTORM,1,1);
+ break;
+ case TK_DOWNKICK:
+ clif->skill_nodamage(bl,bl,TK_READYDOWN,1,1);
+ break;
+ case TK_TURNKICK:
+ clif->skill_nodamage(bl,bl,TK_READYTURN,1,1);
+ break;
+ case TK_COUNTER:
+ clif->skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
+ break;
+ case MO_COMBOFINISH:
+ case CH_TIGERFIST:
+ case CH_CHAINCRUSH:
+ if (sd)
+ clif->skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
+ break;
+ case TK_JUMPKICK:
+ if (sd)
+ clif->skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
+ break;
+ case MO_TRIPLEATTACK:
+ if (sd && pc->checkskill(sd, SR_DRAGONCOMBO) > 0)
+ clif->skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL);
+ break;
+ case SR_FALLENEMPIRE:
+ if (sd){
+ clif->skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL);
+ clif->skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL);
+ }
+ break;
}
break;
- }
- break;
- case SC_RAISINGDRAGON:
- sce->val2 = st->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie]
- break;
+ case SC_RAISINGDRAGON:
+ sce->val2 = st->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie]
+ break;
}
if( opt_flag&2 && sd && sd->touching_id )
@@ -9252,6 +9336,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
{
struct unit_data *ud = unit->bl2ud(bl);
bool begin_spurt = true;
+ // Note: this int64 value is stored in two separate int32 variables (FIXME)
+ int64 starttick = (int64)sce->val3&0x00000000ffffffffLL;
+ starttick |= ((int64)sce->val4<<32)&0xffffffff00000000LL;
+
if (ud) {
if(!ud->state.running)
begin_spurt = false;
@@ -9260,7 +9348,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
unit->stop_walking(bl,1);
}
if (begin_spurt && sce->val1 >= 7
- && DIFF_TICK(timer->gettick(), sce->val4) <= 1000
+ && DIFF_TICK(timer->gettick(), starttick) <= 1000
&& (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
)
sc_start(bl,SC_STRUP,100,sce->val1,skill->get_time2(status->sc2skill(type), sce->val1));
@@ -9869,7 +9957,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
return 1;
}
-int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data) {
struct block_list *bl;
struct status_change *sc;
struct status_change_entry *sce;
@@ -9907,7 +9995,7 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data) {
* For recusive status, like for each 5s we drop sp etc.
* Reseting the end timer.
*------------------------------------------*/
-int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
enum sc_type type = (sc_type)data;
struct block_list *bl;
struct map_session_data *sd;
@@ -10291,7 +10379,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) {
if (sd && !pc_issit(sd)) { //can't cast if sit
int mushroom_skill_id = 0, i;
unit->stop_attack(bl);
- unit->skillcastcancel(bl,1);
+ unit->skillcastcancel(bl,0);
do {
i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB;
mushroom_skill_id = skill->magicmushroom_db[i].skill_id;
@@ -10299,15 +10387,15 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) {
while( mushroom_skill_id == 0 );
switch( skill->get_casttype(mushroom_skill_id) ) { // Magic Mushroom skills are buffs or area damage
- case CAST_GROUND:
- skill->castend_pos2(bl,bl->x,bl->y,mushroom_skill_id,1,tick,0);
- break;
- case CAST_NODAMAGE:
- skill->castend_nodamage_id(bl,bl,mushroom_skill_id,1,tick,0);
- break;
- case CAST_DAMAGE:
- skill->castend_damage_id(bl,bl,mushroom_skill_id,1,tick,0);
- break;
+ case CAST_GROUND:
+ skill->castend_pos2(bl,bl->x,bl->y,mushroom_skill_id,1,tick,0);
+ break;
+ case CAST_NODAMAGE:
+ skill->castend_nodamage_id(bl,bl,mushroom_skill_id,1,tick,0);
+ break;
+ case CAST_DAMAGE:
+ skill->castend_damage_id(bl,bl,mushroom_skill_id,1,tick,0);
+ break;
}
}
@@ -10723,7 +10811,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap) {
struct block_list* src = va_arg(ap,struct block_list*);
struct status_change_entry* sce = va_arg(ap,struct status_change_entry*);
enum sc_type type = (sc_type)va_arg(ap,int); //gcc: enum args get promoted to int
- unsigned int tick = va_arg(ap,unsigned int);
+ int64 tick = va_arg(ap, int64);
if (status->isdead(bl))
return 0;
@@ -10977,7 +11065,7 @@ int status_change_clear_buffs (struct block_list* bl, int type) {
int status_change_spread( struct block_list *src, struct block_list *bl ) {
int i, flag = 0;
struct status_change *sc = status->get_sc(src);
- unsigned int tick;
+ int64 tick;
struct status_change_data data;
if( !sc || !sc->count )
@@ -11019,7 +11107,7 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) {
const struct TimerData *td = timer->get(sc->data[i]->timer);
if (td == NULL || td->func != status->change_timer || DIFF_TICK(td->tick,tick) < 0)
continue;
- data.tick = DIFF_TICK(td->tick,tick);
+ data.tick = DIFF_TICK32(td->tick,tick);
} else
data.tick = INVALID_TIMER;
break;
@@ -11247,8 +11335,9 @@ int status_natural_heal(struct block_list* bl, va_list args) {
}
//Natural heal main timer.
-int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_t data) {
- status->natural_heal_diff_tick = DIFF_TICK(tick,status->natural_heal_prev_tick);
+int status_natural_heal_timer(int tid, int64 tick, int id, intptr_t data) {
+ // This difference is always positive and lower than UINT_MAX (~24 days)
+ status->natural_heal_diff_tick = (unsigned int)cap_value(DIFF_TICK(tick,status->natural_heal_prev_tick), 0, UINT_MAX);
map->foreachregen(status->natural_heal);
status->natural_heal_prev_tick = tick;
return 0;
diff --git a/src/map/status.h b/src/map/status.h
index 9b1721d1a..254f3bfab 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -677,6 +677,9 @@ typedef enum sc_type {
SC_MTF_MLEATKED,
SC_MTF_CRIDAMAGE,
+ SC_MOONSTAR,
+ SC_SUPER_STAR,
+
SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
} sc_type;
// Official status change ids, used to display status icons on the client.
@@ -1858,7 +1861,8 @@ struct status_interface {
sc_conf_type sc_conf[SC_MAX];
struct eri *data_ers; //For sc_data entries
struct status_data dummy;
- unsigned int natural_heal_prev_tick,natural_heal_diff_tick;
+ int64 natural_heal_prev_tick;
+ unsigned int natural_heal_diff_tick;
/* */
int (*init) (void);
void (*final) (void);
@@ -1902,8 +1906,8 @@ struct status_interface {
int (*get_sc_def) (struct block_list *bl, enum sc_type type, int rate, int tick, int flag);
int (*change_start) (struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag);
int (*change_end_) (struct block_list* bl, enum sc_type type, int tid, const char* file, int line);
- int (*kaahi_heal_timer) (int tid, unsigned int tick, int id, intptr_t data);
- int (*change_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*kaahi_heal_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*change_timer) (int tid, int64 tick, int id, intptr_t data);
int (*change_timer_sub) (struct block_list* bl, va_list ap);
int (*change_clear) (struct block_list* bl, int type);
int (*change_clear_buffs) (struct block_list* bl, int type);
@@ -1967,7 +1971,7 @@ struct status_interface {
void (*display_add) (struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3);
void (*display_remove) (struct map_session_data *sd, enum sc_type type);
int (*natural_heal) (struct block_list *bl, va_list args);
- int (*natural_heal_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*natural_heal_timer) (int tid, int64 tick, int id, intptr_t data);
bool (*readdb_job1) (char *fields[], int columns, int current);
bool (*readdb_job2) (char *fields[], int columns, int current);
bool (*readdb_sizefix) (char *fields[], int columns, int current);
diff --git a/src/map/unit.c b/src/map/unit.c
index a7aca10b9..c7ba2f6f9 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -82,9 +82,6 @@ struct unit_data* unit_bl2ud2(struct block_list *bl) {
return unit->bl2ud(bl);
}
-int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data);
-int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data);
-
int unit_walktoxy_sub(struct block_list *bl)
{
int i;
@@ -137,7 +134,7 @@ int unit_walktoxy_sub(struct block_list *bl)
return 1;
}
-int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) {
int i;
int x,y,dx,dy;
uint8 dir;
@@ -322,7 +319,7 @@ int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) {
return 0;
}
-int unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int unit_delay_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) {
struct block_list *bl = map->id2bl(id);
if (!bl || bl->prev == NULL)
@@ -402,7 +399,7 @@ static inline void set_mobstate(struct block_list* bl, int flag)
md->state.skillstate = md->state.aggressive ? MSS_FOLLOW : MSS_RUSH;
}
-int unit_walktobl_sub(int tid, unsigned int tick, int id, intptr_t data) {
+int unit_walktobl_sub(int tid, int64 tick, int id, intptr_t data) {
struct block_list *bl = map->id2bl(id);
struct unit_data *ud = bl?unit->bl2ud(bl):NULL;
@@ -854,7 +851,7 @@ int unit_stop_walking(struct block_list *bl,int type)
{
struct unit_data *ud;
const struct TimerData* td;
- unsigned int tick;
+ int64 tick;
nullpo_ret(bl);
ud = unit->bl2ud(bl);
@@ -1001,7 +998,7 @@ int unit_can_move(struct block_list *bl) {
* Resume running after a walk delay
*------------------------------------------*/
-int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) {
+int unit_resume_running(int tid, int64 tick, int id, intptr_t data) {
struct unit_data *ud = (struct unit_data *)data;
TBL_PC * sd = map->id2sd(id);
@@ -1025,8 +1022,7 @@ int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) {
* if type is 0, this is a damage induced delay: if previous delay is active, do not change it.
* if type is 1, this is a skill induced delay: walk-delay may only be increased, not decreased.
*------------------------------------------*/
-int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type)
-{
+int unit_set_walkdelay(struct block_list *bl, int64 tick, int delay, int type) {
struct unit_data *ud = unit->bl2ud(bl);
if (delay <= 0 || !ud) return 0;
@@ -1073,7 +1069,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
struct status_change *sc;
struct map_session_data *sd = NULL;
struct block_list * target = NULL;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
int temp = 0, range;
nullpo_ret(src);
@@ -1437,7 +1433,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
struct unit_data *ud = NULL;
struct status_change *sc;
struct block_list bl;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
int range;
nullpo_ret(src);
@@ -1795,8 +1791,7 @@ int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir)
/*==========================================
* Continuous Attack (function timer)
*------------------------------------------*/
-int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int tick)
-{
+int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick) {
struct block_list *target;
struct unit_data *ud;
struct status_data *sstatus;
@@ -1915,7 +1910,7 @@ int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int tick)
}
if(ud->state.attack_continue) {
- if( src->type == BL_PC )
+ if( src->type == BL_PC && battle_config.idletime_criteria & BCIDLE_ATTACK )
((TBL_PC*)src)->idletime = last_tick;
ud->attacktimer = timer->add(ud->attackabletime,unit->attack_timer,src->id,0);
}
@@ -1923,7 +1918,7 @@ int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int tick)
return 1;
}
-int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int unit_attack_timer(int tid, int64 tick, int id, intptr_t data) {
struct block_list *bl;
bl = map->id2bl(id);
if(bl && unit->attack_timer_sub(bl, tid, tick) == 0)
@@ -1940,7 +1935,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
{
struct map_session_data *sd = NULL;
struct unit_data *ud = unit->bl2ud( bl);
- unsigned int tick=timer->gettick();
+ int64 tick = timer->gettick();
int ret=0, skill_id;
nullpo_ret(bl);
@@ -1971,7 +1966,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
else
ret = timer->delete( ud->skilltimer, skill->castend_id );
if( ret < 0 )
- ShowError("delete timer error : skill_id : %d\n",ret);
+ ShowError("delete timer error %d : skill %d (%s)\n",ret,skill_id,skill->get_name(skill_id));
ud->skilltimer = INVALID_TIMER;
@@ -2021,8 +2016,7 @@ int unit_counttargeted(struct block_list* bl)
/*==========================================
*
*------------------------------------------*/
-int unit_fixdamage(struct block_list *src,struct block_list *target,unsigned int tick,int sdelay,int ddelay,int64 damage,int div,int type,int64 damage2)
-{
+int unit_fixdamage(struct block_list *src, struct block_list *target, int64 tick, int sdelay, int ddelay, int64 damage, int div, int type, int64 damage2) {
nullpo_ret(target);
if(damage+damage2 <= 0)
@@ -2200,6 +2194,10 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i
instance->list[map->list[bl->m].instance_id].users--;
instance->check_idle(map->list[bl->m].instance_id);
}
+ if( sd->state.hpmeter_visible ) {
+ map->list[bl->m].hpmeter_visible--;
+ sd->state.hpmeter_visible = 0;
+ }
sd->state.debug_remove_map = 1; // temporary state to track double remove_map's [FlavioJS]
sd->debug_file = file;
sd->debug_line = line;
diff --git a/src/map/unit.h b/src/map/unit.h
index be7b789d9..0567688a1 100644
--- a/src/map/unit.h
+++ b/src/map/unit.h
@@ -30,10 +30,10 @@ struct unit_data {
int target_to;
int attacktimer;
int walktimer;
- int chaserange;
- unsigned int attackabletime;
- unsigned int canact_tick;
- unsigned int canmove_tick;
+ int chaserange;
+ int64 attackabletime;
+ int64 canact_tick;
+ int64 canmove_tick;
uint8 dir;
unsigned char walk_count;
unsigned char target_count;
@@ -77,12 +77,12 @@ struct unit_interface {
/* */
struct unit_data* (*bl2ud) (struct block_list *bl);
struct unit_data* (*bl2ud2) (struct block_list *bl);
- int (*attack_timer) (int tid, unsigned int tick, int id, intptr_t data);
- int (*walktoxy_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*attack_timer) (int tid, int64 tick, int id, intptr_t data);
+ int (*walktoxy_timer) (int tid, int64 tick, int id, intptr_t data);
int (*walktoxy_sub) (struct block_list *bl);
- int (*delay_walktoxy_timer) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*delay_walktoxy_timer) (int tid, int64 tick, int id, intptr_t data);
int (*walktoxy) (struct block_list *bl, short x, short y, int flag);
- int (*walktobl_sub) (int tid, unsigned int tick, int id, intptr_t data);
+ int (*walktobl_sub) (int tid, int64 tick, int id, intptr_t data);
int (*walktobl) (struct block_list *bl, struct block_list *tbl, int range, int flag);
int (*run) (struct block_list *bl);
int (*wugdash) (struct block_list *bl, struct map_session_data *sd);
@@ -96,8 +96,8 @@ struct unit_interface {
int (*skilluse_id) (struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv);
int (*is_walking) (struct block_list *bl);
int (*can_move) (struct block_list *bl);
- int (*resume_running) (int tid, unsigned int tick, int id, intptr_t data);
- int (*set_walkdelay) (struct block_list *bl, unsigned int tick, int delay, int type);
+ int (*resume_running) (int tid, int64 tick, int id, intptr_t data);
+ int (*set_walkdelay) (struct block_list *bl, int64 tick, int delay, int type);
int (*skilluse_id2) (struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel);
int (*skilluse_pos) (struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv);
int (*skilluse_pos2) (struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel);
@@ -109,11 +109,11 @@ struct unit_interface {
bool (*can_reach_pos) (struct block_list *bl, int x, int y, int easy);
bool (*can_reach_bl) (struct block_list *bl, struct block_list *tbl, int range, int easy, short *x, short *y);
int (*calc_pos) (struct block_list *bl, int tx, int ty, uint8 dir);
- int (*attack_timer_sub) (struct block_list *src, int tid, unsigned int tick);
+ int (*attack_timer_sub) (struct block_list *src, int tid, int64 tick);
int (*skillcastcancel) (struct block_list *bl, int type);
void (*dataset) (struct block_list *bl);
int (*counttargeted) (struct block_list *bl);
- int (*fixdamage) (struct block_list *src, struct block_list *target, unsigned int tick, int sdelay, int ddelay, int64 damage, int div, int type, int64 damage2);
+ int (*fixdamage) (struct block_list *src, struct block_list *target, int64 tick, int sdelay, int ddelay, int64 damage, int div, int type, int64 damage2);
int (*changeviewsize) (struct block_list *bl, short size);
int (*remove_map) (struct block_list *bl, clr_type clrtype, const char *file, int line, const char *func);
void (*remove_map_pc) (struct map_session_data *sd, clr_type clrtype);