summaryrefslogtreecommitdiff
path: root/src/map/clif.c
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-11-28 13:20:02 -0200
committershennetsind <ind@henn.et>2013-11-28 13:20:02 -0200
commitae13db97ea770e37450e4e2c1a7919ce98d705a8 (patch)
tree193e3c349f022e2d76df2a0bc462476e29a91cb1 /src/map/clif.c
parent2761bb0af9ddfa8bd14cefa9b6e1b33b2940e7be (diff)
downloadhercules-ae13db97ea770e37450e4e2c1a7919ce98d705a8.tar.gz
hercules-ae13db97ea770e37450e4e2c1a7919ce98d705a8.tar.bz2
hercules-ae13db97ea770e37450e4e2c1a7919ce98d705a8.tar.xz
hercules-ae13db97ea770e37450e4e2c1a7919ce98d705a8.zip
Follow up fdb6de1aa34086fd4d22ae127437727f556cea3c
Modified reflect code so that each reflection source can judge whether to apply or not, necessary for mechanics such as item-bonus reflect triggers even on autoguard while reflect shield does not. Re-added that "reflect shield" overhead display which I mistakenly removed in fdb6de1aa34086fd4d22ae127437727f556cea3c. Added code to refrain damage numbers from overlapping in the client, which would render them illegible. Special Thanks to kyeme, Yommy. http://hercules.ws/board/tracker/issue-7792-safety-wall-reflect-bug-body-relocation-error/ Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src/map/clif.c')
-rw-r--r--src/map/clif.c197
1 files changed, 139 insertions, 58 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 6550af5b9..a383617b5 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -45,7 +45,6 @@
#include "clif.h"
#include "mail.h"
#include "quest.h"
-#include "packets_struct.h"
#include "irc-bot.h"
#include <stdio.h>
@@ -4363,78 +4362,68 @@ 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, int64 tick, int sdelay, int ddelay, int64 in_damage, int div, int type, int64 in_damage2) {
- unsigned char buf[33];
+int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type, int64 in_damage2) {
+ struct packet_damage p;
struct status_change *sc;
- int damage,damage2;
#if PACKETVER < 20071113
- const int cmd = 0x8a;
+ short damage,damage2;
#else
- const int cmd = 0x2e1;
+ int damage,damage2;
#endif
nullpo_ret(src);
nullpo_ret(dst);
-
- damage = (int)cap_value(in_damage,INT_MIN,INT_MAX);
- damage2 = (int)cap_value(in_damage2,INT_MIN,INT_MAX);
-
- type = clif_calc_delay(type,div,damage+damage2,ddelay);
+
sc = status->get_sc(dst);
- if(sc && sc->count) {
- if(sc->data[SC_ILLUSION]) {
- if(damage) damage = damage*(sc->data[SC_ILLUSION]->val2) + rnd()%100;
- if(damage2) damage2 = damage2*(sc->data[SC_ILLUSION]->val2) + rnd()%100;
- }
+
+ if(sc && sc->count && sc->data[SC_ILLUSION]) {
+ if(in_damage) in_damage = in_damage*(sc->data[SC_ILLUSION]->val2) + rnd()%100;
+ if(in_damage2) in_damage2 = in_damage2*(sc->data[SC_ILLUSION]->val2) + rnd()%100;
}
-
- WBUFW(buf,0)=cmd;
- WBUFL(buf,2)=src->id;
- WBUFL(buf,6)=dst->id;
- WBUFL(buf,10)=(uint32)tick;
- WBUFL(buf,14)=sdelay;
- WBUFL(buf,18)=ddelay;
+
#if PACKETVER < 20071113
- if (battle_config.hide_woe_damage && map_flag_gvg2(src->m)) {
- WBUFW(buf,22)=damage?div:0;
- WBUFW(buf,27)=damage2?div:0;
- } else {
- WBUFW(buf,22)=min(damage, INT16_MAX);
- WBUFW(buf,27)=damage2;
- }
- WBUFW(buf,24)=div;
- WBUFB(buf,26)=type;
+ damage = (short)min(in_damage,INT16_MAX);
+ damage2 = (short)min(in_damage2,INT16_MAX);
#else
- if (battle_config.hide_woe_damage && map_flag_gvg2(src->m)) {
- WBUFL(buf,22)=damage?div:0;
- WBUFL(buf,29)=damage2?div:0;
- } else {
- WBUFL(buf,22)=damage;
- WBUFL(buf,29)=damage2;
- }
- WBUFW(buf,26)=div;
- WBUFB(buf,28)=type;
+ damage = (int)min(in_damage,INT_MAX);
+ damage2 = (int)min(in_damage2,INT_MAX);
#endif
+ type = clif_calc_delay(type,div,damage+damage2,ddelay);
+
+ p.PacketType = damageType;
+ p.GID = src->id;
+ p.targetGID = dst->id;
+ p.startTime = (uint32)timer->gettick();
+ p.attackMT = sdelay;
+ p.attackedMT = ddelay;
+ p.count = div;
+ p.action = type;
+
+ if( battle_config.hide_woe_damage && map_flag_gvg2(src->m) ) {
+ p.damage = damage?div:0;
+ p.leftDamage = damage2?div:0;
+ } else {
+ p.damage = damage;
+ p.leftDamage = damage2;
+ }
+
if(disguised(dst)) {
- clif->send(buf,packet_len(cmd),dst,AREA_WOS);
- WBUFL(buf,6) = -dst->id;
- clif->send(buf,packet_len(cmd),dst,SELF);
+ clif->send(&p,sizeof(p),dst,AREA_WOS);
+ p.targetGID = -dst->id;
+ clif->send(&p,sizeof(p),dst,SELF);
} else
- clif->send(buf,packet_len(cmd),dst,AREA);
+ clif->send(&p,sizeof(p),dst,AREA);
if(disguised(src)) {
- WBUFL(buf,2) = -src->id;
+ p.GID = -src->id;
if (disguised(dst))
- WBUFL(buf,6) = dst->id;
-#if PACKETVER < 20071113
- if(damage > 0) WBUFW(buf,22) = -1;
- if(damage2 > 0) WBUFW(buf,27) = -1;
-#else
- if(damage > 0) WBUFL(buf,22) = -1;
- if(damage2 > 0) WBUFL(buf,29) = -1;
-#endif
- clif->send(buf,packet_len(cmd),src,SELF);
+ p.targetGID = dst->id;
+
+ if(damage > 0) p.damage = -1;
+ if(damage2 > 0) p.leftDamage = -1;
+
+ clif->send(&p,sizeof(p),src,SELF);
}
if(src == dst) {
@@ -4450,7 +4439,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, int64 tick, int
*------------------------------------------*/
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,1,0);
unsigned char buf[32];
nullpo_retv(src);
@@ -17932,7 +17921,9 @@ void clif_notify_bounditem(struct map_session_data *sd, unsigned short index) {
clif->send(&p,sizeof(p), &sd->bl, SELF);
}
-/* (GM) right click -> 'remove all equipment' */
+/**
+ * Parses the (GM) right click option 'remove all equipment'
+ **/
void clif_parse_GMFullStrip(int fd, struct map_session_data *sd) {
struct map_session_data *tsd = map->id2sd(RFIFOL(fd,2));
int i;
@@ -17946,6 +17937,90 @@ void clif_parse_GMFullStrip(int fd, struct map_session_data *sd) {
pc->unequipitem( tsd , tsd->equip_index[ i ] , 2 );
}
}
+/**
+ * clif_delay_damage timer, sends the stored data and clears the memory afterwards
+ **/
+int clif_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) {
+ struct cdelayed_damage *dd = (struct cdelayed_damage *)data;
+
+ clif->send(&dd->p,sizeof(struct packet_damage),&dd->bl,AREA_WOS);
+
+ ers_free(clif->delayed_damage_ers,dd);
+
+ return 0;
+}
+/**
+ * Delays sending a damage packet in order to avoid the visual display to overlap
+ *
+ * @param tick when to trigger the timer (e.g. timer->gettick() + 500)
+ * @param src block_list pointer of the src
+ * @param dst block_list pointer of the damage source
+ * @param sdelay attack motion usually status_get_amotion()
+ * @param ddelay damage motion usually status_get_dmotion()
+ * @param in_damage total damage to be sent
+ * @param div amount of hits
+ * @param type action type
+ *
+ * @return clif->calc_walkdelay used in further processing
+ **/
+int clif_delay_damage(int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type) {
+ struct cdelayed_damage *dd;
+ struct status_change *sc;
+#if PACKETVER < 20071113
+ short damage;
+#else
+ int damage;
+#endif
+
+ nullpo_ret(src);
+ nullpo_ret(dst);
+
+ sc = status->get_sc(dst);
+
+ if(sc && sc->count && sc->data[SC_ILLUSION]) {
+ if(in_damage) in_damage = in_damage*(sc->data[SC_ILLUSION]->val2) + rnd()%100;
+ }
+
+#if PACKETVER < 20071113
+ damage = (short)min(in_damage,INT16_MAX);
+#else
+ damage = (int)min(in_damage,INT_MAX);
+#endif
+
+ type = clif_calc_delay(type,div,damage,ddelay);
+
+ dd = ers_alloc(clif->delayed_damage_ers, struct cdelayed_damage);
+
+ dd->p.PacketType = damageType;
+ dd->p.GID = src->id;
+ dd->p.targetGID = dst->id;
+ dd->p.startTime = (uint32)timer->gettick();
+ dd->p.attackMT = sdelay;
+ dd->p.attackedMT = ddelay;
+ dd->p.count = div;
+ dd->p.action = type;
+ dd->p.leftDamage = 0;
+
+ if( battle_config.hide_woe_damage && map_flag_gvg2(src->m) )
+ dd->p.damage = damage?div:0;
+ else
+ dd->p.damage = damage;
+
+ dd->bl.m = dst->m;
+ dd->bl.x = dst->x;
+ dd->bl.y = dst->y;
+ dd->bl.type = BL_NUL;
+
+ if( tick > timer->gettick() )
+ timer->add(tick,clif->delay_damage_sub,0,(intptr_t)dd);
+ else {
+ clif->send(&dd->p,sizeof(struct packet_damage),&dd->bl,AREA_WOS);
+
+ ers_free(clif->delayed_damage_ers,dd);
+ }
+
+ return clif->calc_walkdelay(dst,ddelay,type,damage,div);
+}
/* */
unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
@@ -18221,7 +18296,8 @@ int do_init_clif(bool minimal) {
timer->add_func_list(clif->delayquit, "clif_delayquit");
clif->delay_clearunit_ers = ers_new(sizeof(struct block_list),"clif.c::delay_clearunit_ers",ERS_OPT_CLEAR);
-
+ clif->delayed_damage_ers = ers_new(sizeof(struct cdelayed_damage),"clif.c::delayed_damage_ers",ERS_OPT_CLEAR);
+
clif->channel_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, HCHSYS_NAME_LENGTH);
hChSys.ally = hChSys.local = hChSys.irc = hChSys.ally_autojoin = hChSys.local_autojoin = false;
clif->chann_config_read();
@@ -18251,6 +18327,7 @@ void do_final_clif(void) {
db_destroy(clif->channel_db);
ers_destroy(clif->delay_clearunit_ers);
+ ers_destroy(clif->delayed_damage_ers);
for(i = 0; i < CASHSHOP_TAB_MAX; i++) {
int k;
@@ -18267,6 +18344,7 @@ void clif_defaults(void) {
clif->bind_ip = INADDR_ANY;
clif->map_port = 5121;
clif->ally_only = false;
+ clif->delayed_damage_ers = NULL;
/* core */
clif->init = do_init_clif;
clif->final = do_final_clif;
@@ -18754,6 +18832,9 @@ void clif_defaults(void) {
clif->show_modifiers = clif_show_modifiers;
/* */
clif->notify_bounditem = clif_notify_bounditem;
+ /* */
+ clif->delay_damage = clif_delay_damage;
+ clif->delay_damage_sub = clif_delay_damage_sub;
/*------------------------
*- Parse Incoming Packet
*------------------------*/