From 354a5439cd4f7b4e1454cb37637ce07af279466c Mon Sep 17 00:00:00 2001 From: skotlex Date: Tue, 11 Apr 2006 18:45:43 +0000 Subject: - Implemented use of ers for skill_unit_groups to reduce memory usage. NEEDS TESTING git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5991 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/battle.c | 4 +- src/map/map.c | 1 + src/map/map.h | 2 +- src/map/pc.c | 2 +- src/map/skill.c | 173 +++++++++++++++++++++++++++++-------------------------- src/map/skill.h | 4 +- src/map/status.c | 4 +- 7 files changed, 101 insertions(+), 89 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index fdbcffa07..cb84d3044 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -223,7 +223,7 @@ int battle_damage(struct block_list *src,struct block_list *target,int damage, i sc->data[SC_GRAVITATION].val3 == BCT_SELF) { struct skill_unit_group *sg = (struct skill_unit_group *)sc->data[SC_GRAVITATION].val4; if (sg) { - skill_delunitgroup(sg); + skill_delunitgroup(target,sg); sc->data[SC_GRAVITATION].val4 = 0; status_change_end(target, SC_GRAVITATION, -1); } @@ -404,7 +404,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i struct skill_unit_group *group = (struct skill_unit_group *)sc->data[SC_SAFETYWALL].val3; if (group) { if (--group->val2<=0) - skill_delunitgroup(group); + skill_delunitgroup(NULL,group); return 0; } else { status_change_end(bl,SC_SAFETYWALL,-1); diff --git a/src/map/map.c b/src/map/map.c index aac3bea46..bfe0f777f 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -3659,6 +3659,7 @@ void do_final(void) { do_final_pet(); do_final_mob(); do_final_msg(); + do_final_skill(); do_final_unit(); if(use_irc) do_final_irc(); diff --git a/src/map/map.h b/src/map/map.h index 50f8693b7..9e13c3985 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -349,7 +349,7 @@ struct unit_data { struct block_list *bl; struct walkpath_data walkpath; struct skill_timerskill skilltimerskill[MAX_SKILLTIMERSKILL]; - struct skill_unit_group skillunit[MAX_SKILLUNITGROUP]; + struct skill_unit_group *skillunit[MAX_SKILLUNITGROUP]; struct skill_unit_group_tickset skillunittick[MAX_SKILLUNITGROUPTICKSET]; short attacktarget_lv; short to_x,to_y; diff --git a/src/map/pc.c b/src/map/pc.c index 8502b5ce8..f752f3a5e 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4679,7 +4679,7 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) { //Remove Gospel [Skotlex] struct skill_unit_group *sg = (struct skill_unit_group *)sd->sc.data[SC_GOSPEL].val3; if (sg) - skill_delunitgroup(sg); + skill_delunitgroup(&sd->bl, sg); } clif_clearchar_area(&sd->bl,1); diff --git a/src/map/skill.c b/src/map/skill.c index f0964ec01..e60bea290 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -12,6 +12,7 @@ #include "../common/malloc.h" #include "../common/showmsg.h" #include "../common/grfio.h" +#include "../common/ers.h" #include "skill.h" #include "map.h" @@ -35,7 +36,6 @@ //Guild Skills are shifted to these to make them stick into the skill array. #define GD_SKILLRANGEMIN 900 #define GD_SKILLRANGEMAX GD_SKILLRANGEMIN+MAX_GUILDSKILL -#define swap(x,y) { int t; t = x; x = y; y = t; } int skill_names_id[MAX_SKILL_DB]; const struct skill_name_db skill_names[] = { @@ -610,6 +610,8 @@ const struct skill_name_db skill_names[] = { static const int dirx[8]={0,-1,-1,-1,0,1,1,1}; static const int diry[8]={1,1,0,-1,-1,-1,0,1}; + +static struct eri *skill_unit_ers = NULL; //For handling skill_unit's [Skotlex] /* ƒXƒLƒ‹ƒf?ƒ^ƒx?ƒX */ struct skill_db skill_db[MAX_SKILL_DB]; @@ -5803,8 +5805,8 @@ int skill_castend_pos( int tid, unsigned int tick, int id,int data ) (maxcount = skill_get_maxcount(ud->skillid)) > 0 ) { int i; - for(i=0;iskillunit[i].alive_count > 0 && ud->skillunit[i].skill_id == ud->skillid) + for(i=0;iskillunit[i] && maxcount;i++) { + if(ud->skillunit[i]->skill_id == ud->skillid) maxcount--; } if(!maxcount) @@ -6229,8 +6231,8 @@ int skill_castend_map( struct map_session_data *sd,int skill_num, const char *ma p[3] = &sd->status.memo_point[2]; if((maxcount = skill_get_maxcount(skill_num)) > 0) { - for(i=0;iud.skillunit[i].alive_count > 0 && sd->ud.skillunit[i].skill_id == skill_num) + for(i=0;iud.skillunit[i] && maxcount;i++) { + if(sd->ud.skillunit[i]->skill_id == skill_num) maxcount--; } if(!maxcount) { @@ -6598,7 +6600,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int struct skill_unit_group *sg; struct block_list *ss; struct status_change *sc; - int type; + int type,skillid; nullpo_retr(0, src); nullpo_retr(0, bl); @@ -6622,7 +6624,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int return 0; //Hidden characters are inmune to AoE skills except Heaven's Drive. [Skotlex] type = SkillStatusChangeTable[sg->skill_id]; - + skillid = sg->skill_id; //In case the group is deleted, we need to return the correct skill id, still. switch (sg->unit_id) { case UNT_SAFETYWALL: //TODO: Find a more reliable way to handle the link to sg, this could cause dangling pointers. [Skotlex] @@ -6637,7 +6639,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int && sd->ud.to_x == src->bl.x && sd->ud.to_y == src->bl.y) { if (pc_setpos(sd,sg->val3,sg->val2>>16,sg->val2&0xffff,3) == 0) { if (--sg->val1<=0 || sg->src_id == bl->id) - skill_delunitgroup(sg); + skill_delunitgroup(NULL, sg); } } } else if(battle_config.mob_warpportal && bl->type != BL_PET) @@ -6686,12 +6688,12 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int if (sc && sc->data[type].timer==-1) sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit); break; - +/* Basilica does not knocks back... case UNT_BASILICA: if (!(status_get_mode(bl)&MD_BOSS) && battle_check_target(&src->bl,bl,BCT_ENEMY)>0) skill_blown(&src->bl,bl,1); break; - +*/ case UNT_FOGWALL: if (sc && sc->data[type].timer==-1) { @@ -6713,7 +6715,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int break; } - return sg->skill_id; + return skillid; } /*========================================== @@ -6728,7 +6730,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign int splash_count=0; struct status_change *tsc, *sc; struct skill_unit_group_tickset *ts; - int type; + int type, skillid; int diff=0; nullpo_retr(0, src); @@ -6743,6 +6745,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign sc = status_get_sc(ss); //For magic power. tsc = status_get_sc(bl); type = SkillStatusChangeTable[sg->skill_id]; + skillid = sg->skill_id; if (sg->interval == -1) { switch (sg->unit_id) { @@ -6765,7 +6768,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign ts->tick = tick+sg->interval; // GX‚Í?d‚È‚Á‚Ä‚¢‚½‚ç3HIT‚µ‚È‚¢ - if ((sg->skill_id==CR_GRANDCROSS || sg->skill_id==NPC_GRANDDARKNESS) && !battle_config.gx_allhit) + if ((skillid==CR_GRANDCROSS || skillid==NPC_GRANDDARKNESS) && !battle_config.gx_allhit) ts->tick += sg->interval*(map_count_oncell(bl->m,bl->x,bl->y,0)-1); } //Temporarily set magic power to have it take effect. [Skotlex] @@ -6817,7 +6820,7 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign sg->val1--; // ?V‹K‚É“ü‚Á‚½ƒ†ƒjƒbƒg‚¾‚¯ƒJƒEƒ“ƒg } if (sg->val1 <= 0) - skill_delunitgroup(sg); + skill_delunitgroup(NULL,sg); break; } @@ -6835,8 +6838,8 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign break; case UNT_FIREPILLAR_WAITING: - skill_delunit(src); skill_unitsetting(ss,sg->skill_id,sg->skill_lv,src->bl.x,src->bl.y,1); + skill_delunit(src); break; case UNT_FIREPILLAR_ACTIVE: @@ -7066,13 +7069,13 @@ int skill_unit_onplace_timer(struct skill_unit *src,struct block_list *bl,unsign int target = md->target_id; if (ss->type == BL_PC) md->target_id = ss->id; - mobskill_use(md, tick, MSC_SKILLUSED|(sg->skill_id << 16)); + mobskill_use(md, tick, MSC_SKILLUSED|(skillid << 16)); md->target_id = target; } else - mobskill_use(md, tick, MSC_SKILLUSED|(sg->skill_id << 16)); + mobskill_use(md, tick, MSC_SKILLUSED|(skillid << 16)); } - return sg->skill_id; + return skillid; } /*========================================== * ƒXƒLƒ‹ƒ†ƒjƒbƒg‚©‚ç—£?‚·‚é(‚à‚µ‚­‚Í‚µ‚Ä‚¢‚é)?ê?‡ @@ -7321,7 +7324,7 @@ int skill_unit_ondamaged(struct skill_unit *src,struct block_list *bl, nullpo_retr(0, sg=src->group); if (skill_get_inf2(sg->skill_id)&INF2_TRAP && damage > 0) - skill_delunitgroup(sg); + skill_delunitgroup(NULL,sg); else switch(sg->unit_id){ case UNT_ICEWALL: @@ -8926,14 +8929,14 @@ int skill_clear_element_field(struct block_list *bl) nullpo_retr(0, bl); if (!ud) return 0; - for (i=0;iskillunit[i].skill_id) { + for (i=0;iskillunit[i];i++) { + switch (ud->skillunit[i]->skill_id) { case SA_DELUGE: case SA_VOLCANO: case SA_VIOLENTGALE: case SA_LANDPROTECTOR: case NJ_SUITON: - skill_delunitgroup(&ud->skillunit[i]); + skill_delunitgroup(bl, ud->skillunit[i]); } } return 1; @@ -8950,14 +8953,14 @@ struct skill_unit_group *skill_locate_element_field(struct block_list *bl) nullpo_retr(0, bl); if (!ud) return NULL; - for (i=0;iskillunit[i].skill_id) { + for (i=0;iskillunit[i];i++) { + switch (ud->skillunit[i]->skill_id) { case SA_DELUGE: case SA_VOLCANO: case SA_VIOLENTGALE: case SA_LANDPROTECTOR: case NJ_SUITON: - return &ud->skillunit[i]; + return ud->skillunit[i]; } } return NULL; @@ -9058,7 +9061,7 @@ int skill_ganbatein(struct block_list *bl, va_list ap ) if (unit->group->skill_id == SA_LANDPROTECTOR) skill_delunit(unit); - else skill_delunitgroup(unit->group); + else skill_delunitgroup(NULL, unit->group); return 1; } @@ -9246,7 +9249,7 @@ void skill_stop_dancing(struct block_list *src) } if (group) - skill_delunitgroup(group); + skill_delunitgroup(NULL, group); if (dsd) { @@ -9348,7 +9351,7 @@ int skill_delunit(struct skill_unit *unit) unit->alive=0; map_delobjectnofree(unit->bl.id); if(--group->alive_count==0) - skill_delunitgroup(group); + skill_delunitgroup(NULL, group); return 0; } @@ -9369,30 +9372,23 @@ struct skill_unit_group *skill_initunitgroup(struct block_list *src, nullpo_retr(NULL, src); nullpo_retr(NULL, ud); - if(ud->skillunit){ - for(i=0;iskillunit[i].group_id==0){ - group=&ud->skillunit[i]; - break; - } - - if(group==NULL){ /* ‹ó‚¢‚ĂȂ¢‚̂Ō¢‚à‚Ì??õ */ - int j=0; - unsigned maxdiff=0,x,tick=gettick(); - for(i=0;iskillunit[i].tick))>maxdiff){ - maxdiff=x; - j=i; - } - skill_delunitgroup(&ud->skillunit[j]); - group=&ud->skillunit[j]; - } - } - - if(group==NULL){ - ShowFatalError("skill_initunitgroup: error unit group !\n"); - exit(1); - } + for(i=0;iskillunit[i]; i++); + + if(i == MAX_SKILLUNITGROUP) { + int j=0; + unsigned maxdiff=0,x,tick=gettick(); + for(i=0;iskillunit[i];i++) + if((x=DIFF_TICK(tick,ud->skillunit[i]->tick))>maxdiff){ + maxdiff=x; + j=i; + } + skill_delunitgroup(src, ud->skillunit[j]); + //Since elements must have shifted, we use the last slot. + i = MAX_SKILLUNITGROUP-1; + } + if (!ud->skillunit[i]) + ud->skillunit[i] = ers_alloc(skill_unit_ers, struct skill_unit_group); + group=ud->skillunit[i]; group->src_id=src->id; group->party_id=status_get_party_id(src); @@ -9439,34 +9435,36 @@ struct skill_unit_group *skill_initunitgroup(struct block_list *src, * ƒXƒLƒ‹ƒ†ƒjƒbƒgƒOƒ‹?ƒv?í?œ *------------------------------------------ */ -int skill_delunitgroup(struct skill_unit_group *group) +int skill_delunitgroup(struct block_list *src, struct skill_unit_group *group) { - struct block_list *src; - int i; + struct unit_data *ud; + int i,j; nullpo_retr(0, group); if(group->unit_count<=0) return 0; - src=map_id2bl(group->src_id); - //ƒ_ƒ“ƒXƒXƒLƒ‹‚̓_ƒ“ƒX?ó‘Ô‚ð‰ð?œ‚·‚é - if(src) { - if (skill_get_unit_flag(group->skill_id)&UF_DANCE) + if (!src) src=map_id2bl(group->src_id); + ud = unit_bl2ud(src); + if(!src || !ud) { + ShowError("skill_delunitgroup: Group's source not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id); + return 0; + } + if (skill_get_unit_flag(group->skill_id)&UF_DANCE) + { + struct status_change* sc = status_get_sc(src); + if (sc && sc->data[SC_DANCING].timer != -1) { - struct status_change* sc = status_get_sc(src); - if (sc && sc->data[SC_DANCING].timer != -1) - { - sc->data[SC_DANCING].val2 = 0 ; //This prevents status_change_end attempting to redelete the group. [Skotlex] - status_change_end(src,SC_DANCING,-1); - } + sc->data[SC_DANCING].val2 = 0 ; //This prevents status_change_end attempting to redelete the group. [Skotlex] + status_change_end(src,SC_DANCING,-1); } + } - if (group->unit_id == UNT_GOSPEL) { //Clear Gospel [Skotlex] - struct status_change *sc = status_get_sc(src); - if(sc && sc->data[SC_GOSPEL].timer != -1) { - sc->data[SC_GOSPEL].val3 = 0; //Remove reference to this group. [Skotlex] - status_change_end(src,SC_GOSPEL,-1); - } + if (group->unit_id == UNT_GOSPEL) { //Clear Gospel [Skotlex] + struct status_change *sc = status_get_sc(src); + if(sc && sc->data[SC_GOSPEL].timer != -1) { + sc->data[SC_GOSPEL].val3 = 0; //Remove reference to this group. [Skotlex] + status_change_end(src,SC_GOSPEL,-1); } } @@ -9484,10 +9482,20 @@ int skill_delunitgroup(struct skill_unit_group *group) map_freeblock((struct block_list*)group->unit); /* aFree()‚̑ւí‚è */ group->unit=NULL; - group->src_id=0; group->group_id=0; group->unit_count=0; - return 0; + + //Locate and clear this unit from the array. + for (i=0; iskillunit[i]!=group; i++); + for (j=i; jskillunit[j]; j++); + j--; + if (iskillunit[i] = ud->skillunit[j]; + ud->skillunit[j] = NULL; + ers_free(skill_unit_ers, group); + } else + ShowError("skill_delunitgroup: Group not found! (src_id: %d skill_id: %d)\n", group->src_id, group->skill_id); + return 1; } /*========================================== @@ -9497,16 +9505,11 @@ int skill_delunitgroup(struct skill_unit_group *group) int skill_clear_unitgroup(struct block_list *src) { struct unit_data *ud = unit_bl2ud(src); - int i; - nullpo_retr(0, src); nullpo_retr(0, ud); - if(!ud) return 0; - - for(i=0;iskillunit[i].group_id>0 && ud->skillunit[i].src_id == src->id) - skill_delunitgroup(&ud->skillunit[i]); + while (ud->skillunit[0]) + skill_delunitgroup(src, ud->skillunit[0]); return 1; } @@ -9744,6 +9747,7 @@ int skill_unit_move_sub( struct block_list *bl, va_list ap ) } if (flag&4) skill_unit_onleft(skill_id,target,tick); + return 1; } @@ -11060,7 +11064,9 @@ void skill_reload(void) int do_init_skill(void) { skill_readdb(); - + + skill_unit_ers = ers_new((uint32)sizeof(struct skill_unit_group)); + if (battle_config.skill_sp_override_grffile) skill_read_skillspamount(); @@ -11074,3 +11080,8 @@ int do_init_skill(void) return 0; } + +int do_final_skill(void) { + ers_destroy(skill_unit_ers); + return 0; +} diff --git a/src/map/skill.h b/src/map/skill.h index 42069c29c..2ba25b937 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -130,7 +130,7 @@ struct skill_unit; struct skill_unit_group; int do_init_skill(void); - +int do_final_skill(void); //Returns the cast type of the skill: ground cast, castend damage, castend no damage enum { CAST_GROUND, CAST_DAMAGE, CAST_NODAMAGE }; @@ -187,7 +187,7 @@ struct skill_unit *skill_initunit(struct skill_unit_group *group,int idx,int x,i int skill_delunit(struct skill_unit *unit); struct skill_unit_group *skill_initunitgroup(struct block_list *src, int count,int skillid,int skilllv,int unit_id, int limit, int interval); -int skill_delunitgroup(struct skill_unit_group *group); +int skill_delunitgroup(struct block_list *src, struct skill_unit_group *group); int skill_clear_unitgroup(struct block_list *src); int skill_clear_element_field(struct block_list *bl); diff --git a/src/map/status.c b/src/map/status.c index d708a921c..ffba6e1e5 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -5021,7 +5021,7 @@ int status_change_end( struct block_list* bl , int type,int tid ) struct status_change *dsc; if(sc->data[type].val2) { - skill_delunitgroup((struct skill_unit_group *)sc->data[type].val2); + skill_delunitgroup(bl, (struct skill_unit_group *)sc->data[type].val2); sc->data[type].val2 = 0; } if(sc->data[type].val4 && sc->data[type].val4 != BCT_SELF && (dsd=map_id2sd(sc->data[type].val4))){ @@ -5131,7 +5131,7 @@ int status_change_end( struct block_list* bl , int type,int tid ) else if (sc->data[type].val3) { //Clear the group. struct skill_unit_group *group = (struct skill_unit_group *)sc->data[type].val3; sc->data[type].val3 = 0; - skill_delunitgroup(group); + skill_delunitgroup(bl, group); } break; case SC_HERMODE: -- cgit v1.2.3-70-g09d2