diff options
-rw-r--r-- | Changelog-Trunk.txt | 3 | ||||
-rw-r--r-- | db/Changelog.txt | 2 | ||||
-rw-r--r-- | db/skill_unit_db.txt | 29 | ||||
-rw-r--r-- | src/map/clif.c | 12 | ||||
-rw-r--r-- | src/map/map.h | 1 | ||||
-rw-r--r-- | src/map/skill.c | 104 | ||||
-rw-r--r-- | src/map/skill.h | 7 |
7 files changed, 121 insertions, 37 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index f9f05ed27..cefb47895 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,9 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/05/30
+ * Added UF_SONG (0x400) to differentiate songs from dances. [Skotlex]
+ * Added preliminar support for making a Song+Dance turn into BA_DISSONANCE
+ cells. Beware of potential bugs as it's untested. [Skotlex]
* Added mapflag "nochat" to prevent chatting rooms from being created.
[Skotlex]
* Corrected some of the sleep checks when the char id does not matches with
diff --git a/db/Changelog.txt b/db/Changelog.txt index 0202fbc52..9974ca0c8 100644 --- a/db/Changelog.txt +++ b/db/Changelog.txt @@ -25,6 +25,8 @@ =========================
06/30
+ * Updated skill_unit_db to use the correct values of
+ UF_ENSEMBLE/UF_DANCE/UF_SONG as applicable. [Skotlex]
* Added the new X.4 headgears [Playtester]
* Fixed various items and sorted the item_db [Playtester]
* Reverted back Vulcan Arrow. It's fine now. Player can move after the attack animation end [Lupus]
diff --git a/db/skill_unit_db.txt b/db/skill_unit_db.txt index 7873ae907..ed8368190 100644 --- a/db/skill_unit_db.txt +++ b/db/skill_unit_db.txt @@ -12,6 +12,7 @@ // 0x080(UF_SKILL) Spell CAN affect skills.
// 0x100(UF_DANCE) Dance skill
// 0x200(UF_ENSEMBLE) Ensemble skill
+// 0x400(UF_SONG) Song skill
// 0x800(UF_DUALMODE) Spell has effects both at an interval and when you step in/out
// Example: 0x006 = 0x002+0x004 -> Cannot be stacked nor cast near targets
//
@@ -56,24 +57,24 @@ 286,0x9b, , 3, 0, -1,all, 0x000 //SA_DELUGE#デリュージ
287,0x9c, , 3, 0, -1,all, 0x000 //SA_VIOLENTGALE#バイオレントゲイル
288,0x9d,,3:3:4:4:5,0, -1,all, 0x000 //SA_LANDPROTECTOR#ランドプロテクター
-306,0x9e, , 4, 0,6000,all, 0x300 //BD_LULLABY#子守歌
-307,0x9f, , 4, 0, -1,enemy, 0x310 //BD_RICHMANKIM#ニヨルドの宴
-308,0xa0, , 4, 0, -1,enemy, 0x300 //BD_ETERNALCHAOS#永遠の混沌
-309,0xa1, , 4, 0, -1,party, 0x300 //BD_DRUMBATTLEFIELD#戦太鼓の響き
-310,0xa2, , 4, 0, -1,party, 0x300 //BD_RINGNIBELUNGEN#ニーベルングの指輪
-311,0xa3, , 4, 0, -1,all, 0x300 //BD_ROKISWEIL#ロキの叫び
-312,0xa4, , 4, 0, -1,party, 0x320 //BD_INTOABYSS#深淵の中に
-313,0xa5, , 4, 0, -1,party, 0x300 //BD_SIEGFRIED#不死身のジークフリード
+306,0x9e, , 4, 0,6000,all, 0x200 //BD_LULLABY#子守歌
+307,0x9f, , 4, 0, -1,enemy, 0x210 //BD_RICHMANKIM#ニヨルドの宴
+308,0xa0, , 4, 0, -1,enemy, 0x200 //BD_ETERNALCHAOS#永遠の混沌
+309,0xa1, , 4, 0, -1,party, 0x200 //BD_DRUMBATTLEFIELD#戦太鼓の響き
+310,0xa2, , 4, 0, -1,party, 0x200 //BD_RINGNIBELUNGEN#ニーベルングの指輪
+311,0xa3, , 4, 0, -1,all, 0x200 //BD_ROKISWEIL#ロキの叫び
+312,0xa4, , 4, 0, -1,party, 0x220 //BD_INTOABYSS#深淵の中に
+313,0xa5, , 4, 0, -1,party, 0x200 //BD_SIEGFRIED#不死身のジークフリード
317,0xa6, , 3, 0,3000,enemy, 0x100 //BA_DISSONANCE#不協和音
319,0xa7, , 3, 0, -1,all, 0x120 //BA_WHISTLE#口笛
320,0xa8, , 3, 0, -1,all, 0x120 //BA_ASSASSINCROSS#夕陽のアサシンクロス
321,0xa9, , 3, 0, -1,all, 0x120 //BA_POEMBRAGI#ブラギの詩
322,0xaa, , 3, 0,6000,all, 0x920 //BA_APPLEIDUN#イドゥンの林檎
-325,0xab, , 3, 0,3000,enemy, 0x100 //DC_UGLYDANCE#自分勝手なダンス
-327,0xac, , 3, 0, -1,all, 0x120 //DC_HUMMING#ハミング
-328,0xad, , 3, 0, -1,enemy, 0x100 //DC_DONTFORGETME#私を忘れないで…
-329,0xae, , 3, 0, -1,all, 0x120 //DC_FORTUNEKISS#幸運のキス
-330,0xaf, , 3, 0, -1,party, 0x100 //DC_SERVICEFORYOU#サービスフォーユー
+325,0xab, , 3, 0,3000,enemy, 0x400 //DC_UGLYDANCE#自分勝手なダンス
+327,0xac, , 3, 0, -1,all, 0x420 //DC_HUMMING#ハミング
+328,0xad, , 3, 0, -1,enemy, 0x400 //DC_DONTFORGETME#私を忘れないで…
+329,0xae, , 3, 0, -1,all, 0x420 //DC_FORTUNEKISS#幸運のキス
+330,0xaf, , 3, 0, -1,party, 0x400 //DC_SERVICEFORYOU#サービスフォーユー
336,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARTNER#あなたに逢いたい
339,0x86, , -1, 0, 400,enemy, 0x000 //NPC_DARKGRANDCROSS#闇グランドクロス
362,0xb4, , 0, 3, -1,all, 0x000 //HP_BASILICA#バジリカ
@@ -87,7 +88,7 @@ 429,0x86, , 0, 1, 500,enemy, 0x000 //SG_MOON_WARM
430,0x86, , 0, 1, 500,enemy, 0x000 //SG_STAR_WARM
484,0xb8, , 2, 0,1000,enemy, 0x808 //HW_GRAVITATION
-488,0xb9, , 3, 0, -1,all, 0x100 //CG_HERMODE
+488,0xb9, , 3, 0, -1,all, 0x200 //CG_HERMODE
535,0x86, , 0, 2,2000,enemy,0x008,NJ_KAENSIN#火炎陣#
536,0x86, , 0, 2, 300,enemy,0x008,NJ_BAKUENRYU#爆炎龍#
538,0xbb,,1:1:1:2:2:2:3:3:3:4,0, -1,all,0x010,NJ_SUITON#水遁#
diff --git a/src/map/clif.c b/src/map/clif.c index 30e0c1cd1..e9821bcd5 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -4653,7 +4653,11 @@ int clif_skill_setunit(struct skill_unit *unit) WBUFL(buf, 6)=unit->group->src_id;
WBUFW(buf,10)=unit->bl.x;
WBUFW(buf,12)=unit->bl.y;
- WBUFB(buf,14)=unit->group->unit_id;
+ if (unit->group->state.song_dance && unit->val1 == BA_DISSONANCE) {
+ WBUFB(buf,14)=UNT_DISSONANCE;
+ } else {
+ WBUFB(buf,14)=unit->group->unit_id;
+ }
WBUFB(buf,15)=1;
WBUFB(buf,16)=1;
memcpy(WBUFP(buf,17),unit->group->valstr,MESSAGE_SIZE);
@@ -4667,7 +4671,11 @@ int clif_skill_setunit(struct skill_unit *unit) WBUFL(buf, 6)=unit->group->src_id;
WBUFW(buf,10)=unit->bl.x;
WBUFW(buf,12)=unit->bl.y;
- WBUFB(buf,14)=unit->group->unit_id;
+ if (unit->group->state.song_dance && unit->val1 == BA_DISSONANCE) {
+ WBUFB(buf,14)=UNT_DISSONANCE;
+ } else {
+ WBUFB(buf,14)=unit->group->unit_id;
+ }
WBUFB(buf,15)=0;
clif_send(buf,packet_len_table[0x11f],&unit->bl,AREA);
return 0;
diff --git a/src/map/map.h b/src/map/map.h index 20fe52b45..9d8a6f254 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -317,6 +317,7 @@ struct skill_unit_group { unsigned ammo_consume : 1;
unsigned magic_power : 1;
unsigned into_abyss : 1;
+ unsigned song_dance : 1;
} state;
};
struct skill_unit_group_tickset {
diff --git a/src/map/skill.c b/src/map/skill.c index b43112109..250ef1d3c 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -3306,10 +3306,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in do { abra_skillid = rand() % MAX_SKILL_ABRA_DB; if (skill_abra_db[abra_skillid].req_lv > skilllv || - rand()%10000 >= skill_abra_db[abra_skillid].per || //db縺ォ蝓コ縺・縺上Ξ繝吶Ν繝サ遒コ邇蛻、螳 - (abra_skillid >= NPC_PIERCINGATT && abra_skillid <= NPC_SUMMONMONSTER) || //NPC繝サ邨仙ゥ壹サ鬢雁ュ舌サ繧「繧、繝繝繧ケ繧ュ繝ォ縺ッ繝繝。 - skill_get_unit_flag(abra_skillid) & UF_DANCE) //貍泌・上せ繧ュ繝ォ縺ッ繝繝。 - abra_skillid = 0; // reset to get a new id + rand()%10000 >= skill_abra_db[abra_skillid].per || + skill_get_inf2(abra_skillid)&INF2_NPC_SKILL || + skill_get_unit_flag(abra_skillid) &(UF_DANCE|UF_ENSEMBLE|UF_SONG) + ) + abra_skillid = 0; // reset to get a new id } while (abra_skillid == 0); abra_skilllv = skill_get_max(abra_skillid) > skilllv ? skilllv : skill_get_max(abra_skillid); clif_skill_nodamage (src, bl, skillid, skilllv, 1); @@ -6155,6 +6156,44 @@ int skill_castend_map (struct map_session_data *sd, int skill_num, const char *m #undef skill_failed } +static int skill_dance_overlap_sub(struct block_list *bl, va_list ap) +{ + struct skill_unit *target = (struct skill_unit*)bl, + *src = va_arg(ap, struct skill_unit*); + int flag = va_arg(ap, int); + if (!target || !target->group || !target->group->state.song_dance) + return 0; + if (!(target->val2 & src->val2 & ~UF_ENSEMBLE)) //They don't match (song + dance) is valid. + return 0; + if (flag) { //Set dissonance + target->val1 = src->val1 = BA_DISSONANCE; + target->val2 |= UF_ENSEMBLE; //Add ensemble to signal this unit is overlapping. + } else { //Remove dissonance + target->val1 = target->group->skill_id; //Restore skill id + target->val2 &= ~UF_ENSEMBLE; + } + clif_skill_setunit(target); //Update look of affected cell. + return 1; +} + +//Does the song/dance overlapping -> dissonance check. [Skotlex] +//When flag is 0, this unit is about to be removed, cancel the dissonance effect +//When 1, this unit has been positioned, so start the cancel effect. +int skill_dance_overlap(struct skill_unit *unit, int flag) +{ + if (!unit || !unit->group || !unit->group->state.song_dance) + return 0; + if (!flag && !(unit->val2&UF_ENSEMBLE)) + return 0; //Nothing to remove, this unit is not overlapped. + if (unit->val1 != unit->group->skill_id) + { //Reset state + unit->val1 = unit->group->skill_id; + unit->val2 &= ~UF_ENSEMBLE; + } + return map_foreachincell(skill_dance_overlap_sub, + unit->bl.m,unit->bl.x,unit->bl.y,BL_SKILL,unit,flag); +} + /*========================================== * Initializes and sets a ground skill. * flag&1 is used to determine when the skill 'morphs' (Warp portal becomes active, or Fire Pillar becomes active) @@ -6377,6 +6416,7 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid, group->state.into_abyss = (sc && sc->data[SC_INTOABYSS].timer != -1); //Store into abyss state, to know it shouldn't give traps back. [Skotlex] group->state.magic_power = (flag&2 || (sc && sc->data[SC_MAGICPOWER].timer != -1)); //Store the magic power flag. [Skotlex] group->state.ammo_consume = (sd && sd->state.arrow_atk); //Store if this skill needs to consume ammo. + group->state.song_dance = (unit_flag&(UF_DANCE|UF_SONG)); //Signals if this is a song/dance (does not counts duets) if(skillid==HT_TALKIEBOX || skillid==RG_GRAFFITI){ @@ -6413,6 +6453,12 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid, ux+=(i%5-2); uy+=(i/5-2); break; + default: + if (group->state.song_dance) { + val1 = skillid; //Holds SKILL id to use. + val2 = unit_flag&(UF_DANCE|UF_SONG); //Store whether this is a song/dance + } + break; } //逶エ荳翫せ繧ュ繝ォ縺ョ蝣エ蜷郁ィュ鄂ョ蠎ァ讓吩ク翫↓繝ゥ繝ウ繝峨励Ο繝繧ッ繧ソ繝シ縺後↑縺縺九メ繧ァ繝繧ッ if(range<=0) @@ -6440,12 +6486,10 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid, } if(alive){ - nullpo_retr(NULL, unit=skill_initunit(group,i,ux,uy)); - unit->val1=val1; - unit->val2=val2; + nullpo_retr(NULL, unit=skill_initunit(group,i,ux,uy,val1,val2)); unit->limit=limit; unit->range=range; - + if (range==0 && active_flag) map_foreachincell(skill_unit_effect,unit->bl.m, unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),1); @@ -6620,6 +6664,13 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns } type = SkillStatusChangeTable(sg->skill_id); skillid = sg->skill_id; + if (sg->state.song_dance && src->val2&UF_ENSEMBLE) + { //Treat this group as if it were BA_DISSONANCE. + //Values will be restored on proper switch case. + src->val1 = sg->unit_id; + sg->unit_id = UNT_DISSONANCE; + sg->skill_id = BA_DISSONANCE; + } if (sg->interval == -1) { switch (sg->unit_id) { @@ -6654,7 +6705,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns sstatus->matk_min = sc->data[SC_MAGICPOWER].val3; sstatus->matk_min = sc->data[SC_MAGICPOWER].val4; } - + switch (sg->unit_id) { case UNT_FIREWALL: { @@ -6829,6 +6880,12 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns case UNT_DISSONANCE: skill_attack(BF_MISC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0); + if (sg->state.song_dance && src->val2&UF_ENSEMBLE) + { //Restore values. + sg->skill_id = skillid; + sg->unit_id = src->val1; + src->val1 = BA_DISSONANCE; + } break; case UNT_APPLEIDUN: //Apple of Idun [Skotlex] @@ -9115,7 +9172,7 @@ void skill_stop_dancing (struct block_list *src) * 繧ケ繧ュ繝ォ繝ヲ繝九ャ繝亥晄悄蛹 *------------------------------------------ */ -struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int x, int y) +struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int x, int y, int val1, int val2) { struct skill_unit *unit; @@ -9131,11 +9188,11 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int unit->bl.x=x; unit->bl.y=y; unit->group=group; - unit->val1=unit->val2=0; unit->alive=1; + unit->val1=val1; + unit->val2=val2; map_addblock(&unit->bl); - clif_skill_setunit(unit); switch (group->skill_id) { case AL_PNEUMA: @@ -9153,7 +9210,12 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int case WZ_ICEWALL: skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_SETICEWALL); break; + default: + if (group->state.song_dance) //Check for dissonance. + skill_dance_overlap(unit, 1); + break; } + clif_skill_setunit(unit); return unit; } @@ -9173,6 +9235,9 @@ int skill_delunit (struct skill_unit *unit) /* onlimit繧、繝吶Φ繝亥他縺ウ蜃コ縺 */ skill_unit_onlimit( unit,gettick() ); + if (group->state.song_dance) //Restore dissonance effect. + skill_dance_overlap(unit, 0); + /* ondelete繧、繝吶Φ繝亥他縺ウ蜃コ縺 */ if (!unit->range) { map_foreachincell(skill_unit_effect,unit->bl.m, @@ -9265,7 +9330,7 @@ struct skill_unit_group *skill_initunitgroup (struct block_list *src, int count, group->valstr=NULL; i = skill_get_unit_flag(skillid); //Reuse for faster access from here on. [Skotlex] - if (i&UF_DANCE) { + if (i&(UF_DANCE|UF_SONG|UF_ENSEMBLE)) { struct map_session_data *sd = NULL; if(src->type==BL_PC && (sd=(struct map_session_data *)src) ){ sd->skillid_dance=skillid; @@ -9300,7 +9365,7 @@ int skill_delunitgroup (struct block_list *src, struct skill_unit_group *group) 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) + if (skill_get_unit_flag(group->skill_id)&(UF_DANCE|UF_SONG|UF_ENSEMBLE)) { struct status_change* sc = status_get_sc(src); if (sc && sc->data[SC_DANCING].timer != -1) @@ -9666,7 +9731,7 @@ int skill_unit_move_unit_group (struct skill_unit_group *group, int m, int dx, i return 0; m_flag = (int *) aMalloc(sizeof(int)*group->unit_count); - memset(m_flag,0,sizeof(int)*group->unit_count);// 遘サ蜍輔ヵ繝ゥ繧ー + memset(m_flag,0,sizeof(int)*group->unit_count); // m_flag // 0: Neither of the following (skill_unit_onplace & skill_unit_onout are needed) // 1: Unit will move to a slot that had another unit of the same group (skill_unit_onplace not needed) @@ -9694,6 +9759,8 @@ int skill_unit_move_unit_group (struct skill_unit_group *group, int m, int dx, i if (!unit1->alive) continue; if (!(m_flag[i]&0x2)) { + if (group->state.song_dance) //Restore dissonance effect. + skill_dance_overlap(unit1, 0); map_foreachincell(skill_unit_effect,unit1->bl.m, unit1->bl.x,unit1->bl.y,group->bl_flag,&unit1->bl,tick,4); } @@ -9703,7 +9770,6 @@ int skill_unit_move_unit_group (struct skill_unit_group *group, int m, int dx, i case 0: //Cell moves independently, safely move it. map_moveblock(&unit1->bl, unit1->bl.x+dx, unit1->bl.y+dy, tick); - clif_skill_setunit(unit1); break; case 1: //Cell moves unto another cell, look for a replacement cell that won't collide @@ -9715,7 +9781,6 @@ int skill_unit_move_unit_group (struct skill_unit_group *group, int m, int dx, i //Move to where this cell would had moved. unit2 = &group->unit[j]; map_moveblock(&unit1->bl, unit2->bl.x+dx, unit2->bl.y+dy, tick); - clif_skill_setunit(unit1); j++; //Skip this cell as we have used it. break; } @@ -9724,7 +9789,10 @@ int skill_unit_move_unit_group (struct skill_unit_group *group, int m, int dx, i case 3: break; //Don't move the cell as a cell will end on this tile anyway. } - if (!(m_flag[i]&2)) { //We only moved the cell in 0-1 + if (!(m_flag[i]&0x2)) { //We only moved the cell in 0-1 + if (group->state.song_dance) //Check for dissonance effect. + skill_dance_overlap(unit1, 1); + clif_skill_setunit(unit1); map_foreachincell(skill_unit_effect,unit1->bl.m, unit1->bl.x,unit1->bl.y,group->bl_flag,&unit1->bl,tick,1); } diff --git a/src/map/skill.h b/src/map/skill.h index 650fb6ae7..704fd4f57 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -95,8 +95,9 @@ enum { UF_NOPC = 0x0010, //May not target players
UF_NOMOB = 0x0020, //May not target mobs
UF_SKILL = 0x0080, //May target skills
- UF_DANCE = 0x0100, // ダンススキル
- UF_ENSEMBLE = 0x0200, // 合奏スキル
+ UF_DANCE = 0x0100, //Dance
+ UF_ENSEMBLE = 0x0200, //Duet
+ UF_SONG = 0x0400, //Song
UF_DUALMODE = 0x0800, //Spells should trigger both ontimer and onplace/onout/onleft effects.
};
@@ -188,7 +189,7 @@ int skill_blown( struct block_list *src, struct block_list *target,int count); int skill_break_equip(struct block_list *bl, unsigned short where, int rate, int flag);
// ユニットスキル
struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,int skilllv,int x,int y,int flag);
-struct skill_unit *skill_initunit(struct skill_unit_group *group,int idx,int x,int y);
+struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int x, int y, int val1, int val2);
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);
|