diff --git a/conf/channels.conf b/conf/channels.conf index a6e33cbd2c..c0a76fd506 100644 --- a/conf/channels.conf +++ b/conf/channels.conf @@ -25,8 +25,8 @@ chsys: ( /* Add as many colors as you'd like. */ } - /* Allow users to create their own (private) channels through @channels command? */ - /* (must also allow players to use @channels in groups.conf) */ + /* Allow users to create their own (private) channels through @channel command? */ + /* (must also allow players to use @channel in groups.conf) */ allow_user_channel_creation: true /* "map_local_channel" is an instanced channel unique to each map. */ diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c index 8a472d1b55..a53aee3e25 100644 --- a/src/map/buyingstore.c +++ b/src/map/buyingstore.c @@ -41,7 +41,7 @@ static const short buyingstore_blankslots[MAX_SLOTS] = { 0 }; // used when chec /// Returns unique buying store id static unsigned int buyingstore_getuid(void) { - return buyingstore_nextid++; + return ++buyingstore_nextid; } diff --git a/src/map/clif.c b/src/map/clif.c index 4df9c358be..561fca4f6f 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9611,6 +9611,7 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd) (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) ) { set_eof(fd); + pc_damage_log_clear(sd,0); clif_disconnect_ack(sd, 0); } else { clif_disconnect_ack(sd, 1); @@ -9980,6 +9981,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) ) { //Send to char-server for character selection. + pc_damage_log_clear(sd,0); chrif_charselectreq(sd, session[fd]->client_addr); } else { clif_disconnect_ack(sd, 1); diff --git a/src/map/map.c b/src/map/map.c index 53fa002d9a..5d42619b0c 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1724,6 +1724,7 @@ int map_quit(struct map_session_data *sd) { } } + pc_damage_log_clear(sd,0); party_booking_delete(sd); // Party Booking [Spiria] pc_makesavestatus(sd); pc_clean_skilltree(sd); diff --git a/src/map/mob.c b/src/map/mob.c index bfc5c122a7..7a3a276c8e 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2019,6 +2019,9 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage) if(md->dmglog[i].id==0) { //Store data in first empty slot. md->dmglog[i].id = char_id; md->dmglog[i].flag= flag; + + if(md->db->mexp) + pc_damage_log_add(map_charid2sd(char_id),md->bl.id); break; } if(md->dmglog[i].dmgdmglog[minpos].id = char_id; md->dmglog[minpos].flag= flag; md->dmglog[minpos].dmg = damage; + + if(md->db->mexp) + pc_damage_log_add(map_charid2sd(char_id),md->bl.id); } } return; @@ -2160,6 +2166,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) case MDLF_HOMUN: dmgbltypes|= BL_HOM; break; case MDLF_PET: dmgbltypes|= BL_PET; break; } + if( md->db->mexp ) + pc_damage_log_clear(tsd,md->bl.id); } // determines, if the monster was killed by homunculus' damage only diff --git a/src/map/pc.c b/src/map/pc.c index e864ff7c8f..d7982120fd 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -9962,6 +9962,64 @@ void pc_itemcd_do(struct map_session_data *sd, bool load) { return; } +void pc_clear_log_damage_sub(int char_id, struct mob_data *md) +{ + int i; + ARR_FIND(0,DAMAGELOG_SIZE,i,md->dmglog[i].id == char_id); + if( i < DAMAGELOG_SIZE ) + { + md->dmglog[i].id=0; + md->dmglog[i].dmg=0; + md->dmglog[i].flag=0; + } +} + +void pc_damage_log_add(struct map_session_data *sd, int id) +{ + int i = 0; + + if( !sd ) + return; + + for(i = 0; i < DAMAGELOG_SIZE_PC && sd->dmglog[i].id != id; i++) + if( !sd->dmglog[i].id ) + { + sd->dmglog[i].id = id; + break; + } + return; +} + +void pc_damage_log_clear(struct map_session_data *sd, int id) +{ + int i; + struct mob_data *md = NULL; + if( !sd ) + return; + + if( !id ) + { + for(i = 0; i < DAMAGELOG_SIZE_PC; i++) // track every id + { + if( !sd->dmglog[i].id ) //skip the empty value + continue; + + if( (md = map_id2md(sd->dmglog[i].id)) ) + pc_clear_log_damage_sub(sd->status.char_id,md); + } + memset(sd->dmglog,0,sizeof(sd->dmglog)); // clear all + } + else + { + if( (md = map_id2md(id)) ) + pc_clear_log_damage_sub(sd->status.char_id,md); + + ARR_FIND(0,DAMAGELOG_SIZE_PC,i,sd->dmglog[i].id == id); // find the id position + if( i < DAMAGELOG_SIZE_PC ) + sd->dmglog[i].id = 0; + } +} + /*========================================== * pc Init/Terminate *------------------------------------------*/ diff --git a/src/map/pc.h b/src/map/pc.h index 7aabcda2cd..744a6f46b9 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -23,6 +23,7 @@ #define MAX_PC_BONUS 10 #define MAX_PC_SKILL_REQUIRE 5 #define MAX_PC_FEELHATE 3 +#define DAMAGELOG_SIZE_PC 100 // Any idea for this value? //Equip indexes constants. (eg: sd->equip_index[EQI_AMMO] returns the index //where the arrows are equipped) @@ -515,6 +516,10 @@ struct map_session_data { const char* delunit_prevfile; int delunit_prevline; + struct { + int id; + } dmglog[DAMAGELOG_SIZE_PC]; + }; //Update this max as necessary. 55 is the value needed for Super Baby currently @@ -965,6 +970,9 @@ int pc_del_talisman(struct map_session_data *sd,int count,int type); void pc_baselevelchanged(struct map_session_data *sd); +void pc_damage_log_add(struct map_session_data *sd, int id); +void pc_damage_log_clear(struct map_session_data *sd, int id); + #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_race, uint32 mob_mode, int type); #endif diff --git a/src/map/unit.c b/src/map/unit.c index aa0482ace1..9e1dd8f81e 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1421,6 +1421,9 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui } else skill_castend_id(ud->skilltimer,tick,src->id,0); + if( sd ) + sd->canlog_tick = gettick(); + return 1; } @@ -1554,6 +1557,9 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui ud->skilltimer = INVALID_TIMER; skill_castend_pos(ud->skilltimer,tick,src->id,0); } + + if( sd ) + sd->canlog_tick = gettick(); return 1; } @@ -1920,6 +1926,9 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t if(ud->state.attack_continue) ud->attacktimer = add_timer(ud->attackabletime,unit_attack_timer,src->id,0); + if( sd ) + sd->canlog_tick = gettick(); + return 1; } diff --git a/src/map/vending.c b/src/map/vending.c index a7931d6cc0..5c346e5e9e 100644 --- a/src/map/vending.c +++ b/src/map/vending.c @@ -29,7 +29,7 @@ DBMap * vending_getdb(){ /// Returns an unique vending shop id. static int vending_getuid(void) { - return vending_nextid++; + return ++vending_nextid; } /*==========================================