summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map/clif.c70
-rw-r--r--src/map/clif.h3
-rw-r--r--src/map/packets_struct.h12
-rw-r--r--src/map/pc.c23
-rw-r--r--src/map/pc.h7
-rw-r--r--src/map/status.c131
-rw-r--r--src/map/status.h16
-rw-r--r--src/map/unit.c13
8 files changed, 192 insertions, 83 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 2210c3072..5626122cb 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1354,18 +1354,13 @@ int clif_spawn(struct block_list *bl)
clif->specialeffect(bl,421,AREA);
if( sd->bg_id && map[sd->bl.m].flag.battleground )
clif->sendbgemblem_area(sd);
- if( sd->sc.data[SC_ALL_RIDING] ) {
- //New Mounts are not complaint to the original method, so we gotta tell this guy that he is mounting.
- clif->sc_notick(&sd->bl,SI_ALL_RIDING,2,1,0,0);
+ for( i = 0; i < sd->sc_display_count; i++ ) {
+ clif->sc_load(&sd->bl, sd->bl.id,AREA,StatusIconChangeTable[sd->sc_display[i]->type],sd->sc_display[i]->val1,sd->sc_display[i]->val2,sd->sc_display[i]->val3);
}
for(i = 1; i < 5; i++){
if( sd->talisman[i] > 0 )
clif->talisman(sd, i);
}
- #ifdef NEW_CARTS
- if( sd->sc.data[SC_PUSH_CART] )
- clif->sc_notick(&sd->bl, SI_ON_PUSH_CART, 2, sd->sc.data[SC_PUSH_CART]->val1, 0, 0);
- #endif
if (sd->status.robe)
clif->refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA);
}
@@ -4306,14 +4301,9 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds
if( dstsd->talisman[i] > 0 )
clif->talisman_single(sd->fd, dstsd, i);
}
- if( dstsd->sc.data[SC_ALL_RIDING] ) {
- //New Mounts are not complaint to the original method, so we gotta tell this guy that I'm mounting.
- clif->sc_single(sd->fd,dstsd->bl.id,SI_ALL_RIDING,2,1,0,0);
+ for( i = 0; i < dstsd->sc_display_count; i++ ) {
+ clif->sc_load(&sd->bl,dstsd->bl.id,SELF,StatusIconChangeTable[dstsd->sc_display[i]->type],dstsd->sc_display[i]->val1,dstsd->sc_display[i]->val2,dstsd->sc_display[i]->val3);
}
-#ifdef NEW_CARTS
- if( dstsd->sc.data[SC_PUSH_CART] )
- clif->sc_single(sd->fd, dstsd->bl.id, SI_ON_PUSH_CART, 2, dstsd->sc.data[SC_PUSH_CART]->val1, 0, 0);
-#endif
if( (sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting.
(sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround
pc_has_permission(sd, PC_PERM_VIEW_HPMETER)
@@ -16455,40 +16445,6 @@ int clif_skill_itemlistwindow( struct map_session_data *sd, uint16 skill_id, uin
return 1;
}
-/**
- * Sends a new status without a tick (currently used by the new mounts)
- **/
-int clif_status_load_notick(struct block_list *bl,int type,int flag,int val1, int val2, int val3) {
- unsigned char buf[32];
-
- nullpo_ret(bl);
-
- WBUFW(buf,0)=0x043f;
- WBUFW(buf,2)=type;
- WBUFL(buf,4)=bl->id;
- WBUFB(buf,8)=flag;
- WBUFL(buf,9) = 0;
- WBUFL(buf,13) = val1;
- WBUFL(buf,17) = val2;
- WBUFL(buf,21) = val3;
-
- clif->send(buf,packet_len(0x043f),bl,AREA);
- return 0;
-}
-//Notifies FD of ID's type
-int clif_status_load_single(int fd, int id,int type,int flag,int val1, int val2, int val3) {
- WFIFOHEAD(fd, packet_len(0x043f));
- WFIFOW(fd,0)=0x043f;
- WFIFOW(fd,2)=type;
- WFIFOL(fd,4)=id;
- WFIFOB(fd,8)=flag;
- WFIFOL(fd,9) = 0;
- WFIFOL(fd,13) = val1;
- WFIFOL(fd,17) = val2;
- WFIFOL(fd,21) = val3;
- WFIFOSET(fd, packet_len(0x043f));
- return 0;
-}
// msgstringtable.txt
// 0x291 <line>.W
void clif_msgtable(int fd, int line) {
@@ -16818,6 +16774,21 @@ void clif_maptypeproperty2(struct block_list *bl,enum send_target t) {
#endif
}
+void clif_status_change2(struct block_list *bl, int tid, enum send_target target, int type, int val1, int val2, int val3) {
+ struct packet_status_change2 p;
+
+ p.PacketType = status_change2Type;
+ p.index = type;
+ p.AID = tid;
+ p.state = 1;
+ p.Left = -1;// officially its 9999 but -1 is a explicit "no-duration" which behaves best [Ind/Hercules]
+ p.val1 = val1;
+ p.val2 = val2;
+ p.val3 = val3;
+
+ clif->send(&p,sizeof(p), bl, target);
+}
+
void clif_partytickack(struct map_session_data* sd, bool flag) {
WFIFOHEAD(sd->fd, packet_len(0x2c9));
@@ -17227,8 +17198,7 @@ void clif_defaults(void) {
clif->poison_list = clif_poison_list;
clif->autoshadowspell_list = clif_autoshadowspell_list;
clif->skill_itemlistwindow = clif_skill_itemlistwindow;
- clif->sc_notick = clif_status_load_notick;
- clif->sc_single = clif_status_load_single;
+ clif->sc_load = clif_status_change2;
clif->initialstatus = clif_initialstatus;
/* player-unit-specific-related */
clif->updatestatus = clif_updatestatus;
diff --git a/src/map/clif.h b/src/map/clif.h
index b981cc535..e8882d4f9 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -596,8 +596,7 @@ struct clif_interface {
int (*poison_list) (struct map_session_data *sd, uint16 skill_lv);
int (*autoshadowspell_list) (struct map_session_data *sd);
int (*skill_itemlistwindow) ( struct map_session_data *sd, uint16 skill_id, uint16 skill_lv );
- int (*sc_notick) (struct block_list *bl,int type,int flag,int val1, int val2, int val3);
- int (*sc_single) (int fd, int id,int type,int flag,int val1, int val2, int val3);
+ void (*sc_load) (struct block_list *bl, int tid, enum send_target target, int type, int val1, int val2, int val3);
void (*initialstatus) (struct map_session_data *sd);
/* player-unit-specific-related */
void (*updatestatus) (struct map_session_data *sd,int type);
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 94450facb..1ab296d40 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -50,6 +50,7 @@ enum packet_headers {
#else
status_changeType = sc_notickType,/* 0x196 */
#endif
+ status_change2Type = 0x43f,
#if PACKETVER < 4
spawn_unitType = 0x79,
#elif PACKETVER < 7
@@ -352,6 +353,17 @@ struct packet_status_change {
#endif
} __attribute__((packed));
+struct packet_status_change2 {
+ short PacketType;
+ short index;
+ unsigned int AID;
+ unsigned char state;
+ unsigned int Left;
+ int val1;
+ int val2;
+ int val3;
+} __attribute__((packed));
+
struct packet_maptypeproperty2 {
short PacketType;
short type;
diff --git a/src/map/pc.c b/src/map/pc.c
index 59b1c7443..d5d5efb3b 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1096,7 +1096,11 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
* Check if player have any item cooldowns on
**/
pc_itemcd_do(sd,true);
-
+
+ /* [Ind/Hercules] */
+ sd->sc_display = NULL;
+ sd->sc_display_count = 0;
+
// Request all registries (auth is considered completed whence they arrive)
intif_request_registry(sd,7);
return true;
@@ -1572,16 +1576,11 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
pc_setglobalreg (sd, "jobchange_level", sd->change_level_2nd);
}
- if (skill_point < novice_skills + (sd->change_level_2nd - 1))
- {
+ if (skill_point < novice_skills + (sd->change_level_2nd - 1)) {
c &= MAPID_BASEMASK;
- }
- // limit 3rd class to 2nd class/trans job levels
- else if(sd->class_&JOBL_THIRD)
- {
+ } else if(sd->class_&JOBL_THIRD) { // limit 3rd class to 2nd class/trans job levels
// regenerate change_level_3rd
- if (!sd->change_level_3rd)
- {
+ if (!sd->change_level_3rd) {
sd->change_level_3rd = 1 + skill_point + sd->status.skill_point
- (sd->status.job_level - 1)
- (sd->change_level_2nd - 1)
@@ -7718,7 +7717,7 @@ int pc_setcart(struct map_session_data *sd,int type) {
clif->cartlist(sd);
clif->updatestatus(sd, SP_CARTINFO);
sc_start(&sd->bl, SC_PUSH_CART, 100, type, 0);
- clif->sc_notick(&sd->bl, SI_ON_PUSH_CART, 2 , type, 0, 0);
+ clif->sc_load(&sd->bl, sd->bl.id, AREA, SI_ON_PUSH_CART, type, 0, 0);
if( sd->sc.data[SC_PUSH_CART] )/* forcefully update */
sd->sc.data[SC_PUSH_CART]->val1 = type;
break;
@@ -9822,6 +9821,8 @@ void do_final_pc(void) {
db_destroy(itemcd_db);
do_final_pc_groups();
+
+ ers_destroy(pc_sc_display_ers);
return;
}
@@ -9859,6 +9860,8 @@ int do_init_pc(void) {
}
do_init_pc_groups();
+
+ pc_sc_display_ers = ers_new(sizeof(struct sc_display_entry), "pc.c:pc_sc_display_ers", ERS_OPT_NONE);
return 0;
}
diff --git a/src/map/pc.h b/src/map/pc.h
index 4f421f7c2..10891f6b4 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -6,6 +6,7 @@
#define _PC_H_
#include "../common/mmo.h" // JOB_*, MAX_FAME_LIST, struct fame_list, struct mmo_charstatus
+#include "../common/ers.h"
#include "../common/timer.h" // INVALID_TIMER
#include "atcommand.h" // AtCommandType
#include "battle.h" // battle_config
@@ -513,12 +514,18 @@ struct map_session_data {
unsigned char fontcolor;
unsigned int hchsysch_tick;
+ /* [Ind/Hercules] */
+ struct sc_display_entry **sc_display;
+ unsigned char sc_display_count;
+
// temporary debugging of bug #3504
const char* delunit_prevfile;
int delunit_prevline;
};
+struct eri *pc_sc_display_ers;
+
//Update this max as necessary. 55 is the value needed for Super Baby currently
//Raised to 84 since Expanded Super Novice needs it.
#define MAX_SKILL_TREE 84
diff --git a/src/map/status.c b/src/map/status.c
index fec23cb55..3524430e5 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -55,9 +55,9 @@ static int hp_coefficient2[CLASS_COUNT];
static int hp_sigma_val[CLASS_COUNT][MAX_LEVEL+1];
static int sp_coefficient[CLASS_COUNT];
#ifdef RENEWAL_ASPD
-static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE+1];
+ static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE+1];
#else
-static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE]; //[blackhole89]
+ static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE]; //[blackhole89]
#endif
// bonus values and upgrade chances for refining equipment
@@ -78,13 +78,6 @@ int current_equip_card_id; //To prevent card-stacking (from jA) [Skotlex]
//we need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only
//to avoid cards exploits
-static sc_type SkillStatusChangeTable[MAX_SKILL]; // skill -> status
-static int StatusIconChangeTable[SC_MAX]; // status -> "icon" (icon is a bit of a misnomer, since there exist values with no icon associated)
-static unsigned int StatusChangeFlagTable[SC_MAX]; // status -> flags
-static int StatusSkillChangeTable[SC_MAX]; // status -> skill
-static int StatusRelevantBLTypes[SI_MAX]; // "icon" -> enum bl_type (for clif->status_change to identify for which bl types to send packets)
-
-
/**
* Returns the status change associated with a skill.
* @param skill The skill to look up
@@ -184,7 +177,7 @@ void initChangeTables(void) {
memset(StatusSkillChangeTable, 0, sizeof(StatusSkillChangeTable));
memset(StatusChangeFlagTable, 0, sizeof(StatusChangeFlagTable));
-
+ memset(StatusDisplayType, 0, sizeof(StatusDisplayType));
//First we define the skill for common ailments. These are used in skill_additional_effect through sc cards. [Skotlex]
set_sc( NPC_PETRIFYATTACK , SC_STONE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF );
@@ -988,6 +981,30 @@ void initChangeTables(void) {
StatusChangeFlagTable[SC_ALL_RIDING] = SCB_SPEED;
+ /* StatusDisplayType Table [Ind/Hercules] */
+ StatusDisplayType[SC_ALL_RIDING] = true;
+ StatusDisplayType[SC_PUSH_CART] = true;
+ StatusDisplayType[SC_SPHERE_1] = true;
+ StatusDisplayType[SC_SPHERE_2] = true;
+ StatusDisplayType[SC_SPHERE_3] = true;
+ StatusDisplayType[SC_SPHERE_4] = true;
+ StatusDisplayType[SC_SPHERE_5] = true;
+ StatusDisplayType[SC_CAMOUFLAGE] = true;
+ StatusDisplayType[SC_DUPLELIGHT] = true;
+ StatusDisplayType[SC_ORATIO] = true;
+ StatusDisplayType[SC_FREEZING] = true;
+ StatusDisplayType[SC_VENOMIMPRESS] = true;
+ StatusDisplayType[SC_HALLUCINATIONWALK] = true;
+ StatusDisplayType[SC_ROLLINGCUTTER] = true;
+ StatusDisplayType[SC_BANDING] = true;
+ StatusDisplayType[SC_CRYSTALIZE] = true;
+ StatusDisplayType[SC_DEEPSLEEP] = true;
+ StatusDisplayType[SC_CURSEDCIRCLE_ATKER]= true;
+ StatusDisplayType[SC_CURSEDCIRCLE_TARGET]= true;
+ StatusDisplayType[SC_BLOODSUCKER] = true;
+ StatusDisplayType[SC__SHADOWFORM] = true;
+ StatusDisplayType[SC__MANHOLE] = true;
+
#ifdef RENEWAL_EDP
// renewal EDP increases your weapon atk
StatusChangeFlagTable[SC_EDP] |= SCB_WATK;
@@ -6350,7 +6367,50 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
return tick;
}
-
+/* [Ind/Hercules] fast-checkin sc-display array */
+void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3) {
+ struct sc_display_entry *entry = ers_alloc(pc_sc_display_ers, struct sc_display_entry);
+
+ entry->type = type;
+ entry->val1 = dval1;
+ entry->val2 = dval2;
+ entry->val3 = dval3;
+
+ RECREATE(sd->sc_display, struct sc_display_entry *, ++sd->sc_display_count);
+ sd->sc_display[ sd->sc_display_count - 1 ] = entry;
+}
+void status_display_remove(struct map_session_data *sd, enum sc_type type) {
+ int i;
+
+ for( i = 0; i < sd->sc_display_count; i++ ) {
+ if( sd->sc_display[i]->type == type )
+ break;
+ }
+
+ if( i != sd->sc_display_count ) {
+ int cursor;
+
+ ers_free(pc_sc_display_ers, sd->sc_display[i]);
+ sd->sc_display[i] = NULL;
+
+ /* the all-mighty compact-o-matic */
+ for( i = 0, cursor = 0; i < sd->sc_display_count; i++ ) {
+ if( sd->sc_display[i] == NULL )
+ continue;
+
+ if( i != cursor ) {
+ sd->sc_display[cursor] = sd->sc_display[i];
+ }
+
+ cursor++;
+ }
+
+ if( !(sd->sc_display_count = cursor) ) {
+ aFree(sd->sc_display);
+ sd->sc_display = NULL;
+ }
+ }
+}
/*==========================================
* Starts a status change.
* 'type' = type, 'val1~4' depend on the type.
@@ -6362,8 +6422,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
* &4: sc_data loaded, no value has to be altered.
* &8: rate should not be reduced
*------------------------------------------*/
-int status_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 status_change_start(struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag) {
struct map_session_data *sd = NULL;
struct status_change* sc;
struct status_change_entry* sce;
@@ -8562,6 +8621,42 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
}
}
+
+ /* [Ind/Hercules] */
+ if( sd && StatusDisplayType[type] ) {
+ int dval1 = 0, dval2 = 0, dval3 = 0;
+ switch( type ) {
+ case SC_ALL_RIDING:
+ dval1 = 1;
+ break;
+ case SC_SPHERE_1:
+ case SC_SPHERE_2:
+ case SC_SPHERE_3:
+ case SC_SPHERE_4:
+ case SC_SPHERE_5:
+ case SC_PUSH_CART:
+ case SC_CAMOUFLAGE:
+ case SC_DUPLELIGHT:
+ case SC_ORATIO:
+ case SC_FREEZING:
+ case SC_VENOMIMPRESS:
+ case SC_HALLUCINATIONWALK:
+ case SC_ROLLINGCUTTER:
+ case SC_BANDING:
+ case SC_CRYSTALIZE:
+ case SC_DEEPSLEEP:
+ case SC_CURSEDCIRCLE_ATKER:
+ case SC_CURSEDCIRCLE_TARGET:
+ case SC_BLOODSUCKER:
+ case SC__SHADOWFORM:
+ case SC__MANHOLE:
+ dval1 = val1;
+ break;
+ /* handle */
+ default: break;
+ }
+ status_display_add(sd,type,dval1,dval2,dval3);
+ }
//Those that make you stop attacking/walking....
switch (type) {
@@ -8797,7 +8892,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
calc_flag&=~SCB_DYE;
}
- clif->status_change(bl,StatusIconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
+ if( !(flag&4 && StatusDisplayType[type]) )
+ clif->status_change(bl,StatusIconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
/**
* used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
@@ -9025,8 +9121,7 @@ int status_change_clear(struct block_list* bl, int type) {
/*==========================================
* Special condition we want to effectuate, check before ending a status.
*------------------------------------------*/
-int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line)
-{
+int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line) {
struct map_session_data *sd;
struct status_change *sc;
struct status_change_entry *sce;
@@ -9078,6 +9173,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
sc->data[type] = NULL;
+ if( sd && StatusDisplayType[type] ) {
+ status_display_remove(sd,type);
+ }
+
vd = status_get_viewdata(bl);
calc_flag = StatusChangeFlagTable[type];
switch(type){
diff --git a/src/map/status.h b/src/map/status.h
index eeac01e70..4a7af884e 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -16,9 +16,9 @@ struct status_change;
* Changing this limit requires edits to refine_db.txt
**/
#ifdef RENEWAL
-# define MAX_REFINE 20
+ #define MAX_REFINE 20
#else
-# define MAX_REFINE 10
+ #define MAX_REFINE 10
#endif
enum refine_type {
@@ -1563,6 +1563,13 @@ struct weapon_atk {
#endif
};
+sc_type SkillStatusChangeTable[MAX_SKILL]; // skill -> status
+int StatusIconChangeTable[SC_MAX]; // status -> "icon" (icon is a bit of a misnomer, since there exist values with no icon associated)
+unsigned int StatusChangeFlagTable[SC_MAX]; // status -> flags
+int StatusSkillChangeTable[SC_MAX]; // status -> skill
+int StatusRelevantBLTypes[SI_MAX]; // "icon" -> enum bl_type (for clif->status_change to identify for which bl types to send packets)
+bool StatusDisplayType[SC_MAX];
+
//For holding basic status (which can be modified by status changes)
struct status_data {
@@ -1639,6 +1646,11 @@ struct regen_data {
struct regen_data_sub *sregen, *ssregen;
};
+struct sc_display_entry {
+ enum sc_type type;
+ int val1,val2,val3;
+};
+
struct status_change_entry {
int timer;
int val1,val2,val3,val4;
diff --git a/src/map/unit.c b/src/map/unit.c
index 952b1a20e..f614d2fa0 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -2294,8 +2294,7 @@ int unit_free(struct block_list *bl, clr_type clrtype)
if( bl->prev ) //Players are supposed to logout with a "warp" effect.
unit_remove_map(bl, clrtype);
- switch( bl->type )
- {
+ switch( bl->type ) {
case BL_PC:
{
struct map_session_data *sd = (struct map_session_data*)bl;
@@ -2331,7 +2330,6 @@ int unit_free(struct block_list *bl, clr_type clrtype)
sd->reg_num = 0;
}
if( sd->regstr ) {
- int i;
for( i = 0; i < sd->regstr_num; ++i )
if( sd->regstr[i].data )
aFree(sd->regstr[i].data);
@@ -2349,6 +2347,15 @@ int unit_free(struct block_list *bl, clr_type clrtype)
aFree(sd->combos.id);
sd->combos.count = 0;
}
+ /* [Ind/Hercules] */
+ if( sd->sc_display_count ) {
+ for(i = 0; i < sd->sc_display_count; i++) {
+ ers_free(pc_sc_display_ers, sd->sc_display[i]);
+ }
+ sd->sc_display_count = 0;
+ aFree(sd->sc_display);
+ sd->sc_display = NULL;
+ }
break;
}
case BL_PET: