Преглед изворни кода

- Added function skill_dance_switch which handles converting overlapping song/dances to dissonance/ugly dance. It should make the overlapping area now behave completely like the mentioned song/dances (taking into account interval and target type changes).

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@8876 54d463be-8e91-2dee-dedb-b68131a5f0ec
skotlex пре 18 година
родитељ
комит
faa1896447
2 измењених фајлова са 93 додато и 73 уклоњено
  1. 4 0
      Changelog-Trunk.txt
  2. 89 73
      src/map/skill.c

+ 4 - 0
Changelog-Trunk.txt

@@ -4,6 +4,10 @@ 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/09/26
+	* Added function skill_dance_switch which handles converting overlapping
+	  song/dances to dissonance/ugly dance. It should make the overlapping area
+	  now behave completely like the mentioned song/dances (taking into account
+	  interval and target type changes). [Skotlex]
 	* Updated battle_check_target so that non-offensive skills cannot be used
 	  on a homun except for the homun and it's master. [Skotlex]
 	* Steal zeny won't work on treasure chests now. [Skotlex]

+ 89 - 73
src/map/skill.c

@@ -6441,6 +6441,55 @@ int skill_dance_overlap(struct skill_unit *unit, int flag)
 		unit->bl.m,unit->bl.x,unit->bl.y,BL_SKILL,unit,flag);
 }
 
+/*==========================================
+ * Converts this group information so that it is handled
+ * as a Dissonance or Ugly Dance cell.
+ * Flag: 0 - Convert, 1 - Revert, 2 - Initialize.
+ *------------------------------------------
+ */
+#define skill_dance_switch(unit, group, flag) ((group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE)?skill_dance_switch_sub(unit, group, flag):0)
+static int skill_dance_switch_sub(struct skill_unit *unit, struct skill_unit_group *group, int flag)
+{
+	static struct skill_unit_group original, dissonance, uglydance, *group2;
+
+	if (flag&2) { //initialize
+		memset(&dissonance, 0, sizeof(dissonance));
+		memset(&uglydance, 0, sizeof(uglydance));
+		group2 = &dissonance;
+		group2->skill_id = BA_DISSONANCE;
+		group2->unit_id = skill_get_unit_id(group2->skill_id,0);
+		group2->target_flag = skill_get_unit_target(group2->skill_id);
+		group2->bl_flag= skill_get_unit_bl_target(group2->skill_id);
+		group2->interval = skill_get_unit_interval(group2->skill_id);
+
+		group2 = &uglydance;
+		group2->skill_id = DC_UGLYDANCE;
+		group2->unit_id = skill_get_unit_id(group2->skill_id,0);
+		group2->target_flag = skill_get_unit_target(group2->skill_id);
+		group2->bl_flag= skill_get_unit_bl_target(group2->skill_id);
+		group2->interval = skill_get_unit_interval(group2->skill_id);
+		return 0;
+	}
+
+	if (!flag)
+	{	//Transform
+		memcpy(&original, group, sizeof(struct skill_unit_group)); //Backup
+		group2 = unit->val2&UF_SONG?&dissonance:&uglydance;
+		group->skill_id = group2->skill_id;
+		group->unit_id = group2->unit_id;
+		group->target_flag = group2->target_flag;
+		group->bl_flag= group2->bl_flag;
+		group->interval = group2->interval;
+	} else { //Restore only relevant values (should the backup be 5 ints rather than the whole structure?)
+		group->skill_id = original.skill_id;
+		group->unit_id = original.unit_id;
+		group->target_flag = original.target_flag;
+		group->bl_flag = original.bl_flag;
+		group->interval = original.interval;
+	}
+	return 1;
+}
+
 /*==========================================
  * 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)
@@ -6746,10 +6795,8 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid,
 			uy+=(i/5-2);
 			break;
 		default:
-			if (group->state.song_dance&0x1) {
-				val1 = skillid; //Holds SKILL id to use.
+			if (group->state.song_dance&0x1)
 				val2 = unit_flag&(UF_DANCE|UF_SONG); //Store whether this is a song/dance
-			}
 			break;
 		}
 		if(range<=0)
@@ -7485,7 +7532,7 @@ int skill_unit_effect (struct block_list *bl, va_list ap)
 {
 	struct skill_unit *unit;
 	struct skill_unit_group *group;
-	int flag,unit_id=0,skill_id;
+	int flag,skill_id;
 	unsigned int tick;
 
 	unit=va_arg(ap,struct skill_unit*);
@@ -7497,6 +7544,9 @@ int skill_unit_effect (struct block_list *bl, va_list ap)
 
 	nullpo_retr(0, group=unit->group);
   	
+	if (skill_dance_switch(unit, group, 0))
+		flag|=64; //Converted cell, remember to restore it.
+
 	//Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
 	skill_id = group->skill_id;
 
@@ -7505,39 +7555,21 @@ int skill_unit_effect (struct block_list *bl, va_list ap)
 	{
 		if (flag&4 && group->src_id == bl->id && group->state.song_dance&0x2)
 			skill_unit_onleft(skill_id, bl, tick);//Ensemble check to terminate it.
+		if (flag&64)
+			skill_dance_switch(unit, group, 1);
 		return 0;
 	}
 
-	if (group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE)
-  	{	//Treat this group as if it were BA_DISSONANCE/DC_UGLYDANCE.
-		//Values will be restored on proper switch case.
-		flag|=64; //Signal to remember to restore it.
-		unit_id = group->unit_id;
-		unit->val1 = group->skill_id;
-		if (unit->val2&UF_SONG) {
-			group->unit_id = UNT_DISSONANCE;
-			group->skill_id = BA_DISSONANCE;
-		} else {
-			group->unit_id = UNT_UGLYDANCE;
-			group->skill_id = DC_UGLYDANCE;
-		}
-	}
-
 	if (flag&1)
 		skill_unit_onplace(unit,bl,tick);
 	else
 		skill_unit_onout(unit,bl,tick);
 
-	if (flag&64)
-	{	//TODO: Normally, this is dangerous since the unit and group could be freed
-		//inside the onout/onplace functions. Currently it is safe because we know song/dance
-		//cells do not get deleted within them. [Skotlex]
-		skill_id = group->skill_id;
-		group->unit_id = unit_id;
-		group->skill_id = unit->val1;
-	}
+	if (flag&4)
+	  	skill_unit_onleft(skill_id, bl, tick);
 
-	if (flag&4) skill_unit_onleft(skill_id, bl, tick);
+	if (flag&64)
+		skill_dance_switch(unit, group, 1);
 	return 0;
 }
 
@@ -9856,25 +9888,8 @@ int skill_unit_timer_sub_onplace (struct block_list *bl, va_list ap)
 	if (battle_check_target(&unit->bl,bl,group->target_flag)<=0)
 		return 0;
 
-	if (group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE)
-  	{	//Treat this group as if it were BA_DISSONANCE/DC_UGLYDANCE.
-		//Values will be restored on proper switch case.
-		int id = group->unit_id;
-		unit->val1 = group->skill_id;
-		if (unit->val2&UF_SONG) {
-			group->unit_id = UNT_DISSONANCE;
-			group->skill_id = BA_DISSONANCE;
-		} else {
-			group->unit_id = UNT_UGLYDANCE;
-			group->skill_id = DC_UGLYDANCE;
-		}
-		skill_unit_onplace_timer(unit,bl,tick);
-		group->unit_id = id;
-		group->skill_id = unit->val1;
-	} else
-		skill_unit_onplace_timer(unit,bl,tick);
-
-	return 0;
+	skill_unit_onplace_timer(unit,bl,tick);
+	return 1;
 }
 
 /*==========================================
@@ -9886,6 +9901,7 @@ int skill_unit_timer_sub (struct block_list *bl, va_list ap)
 	struct skill_unit *unit;
 	struct skill_unit_group *group;
 	unsigned int tick;
+  	int flag;
 
 	unit=(struct skill_unit *)bl;
 	tick=va_arg(ap,unsigned int);
@@ -9896,6 +9912,7 @@ int skill_unit_timer_sub (struct block_list *bl, va_list ap)
 
 	nullpo_retr(0, group);
 
+	flag = skill_dance_switch(unit, group, 0);
 	if (unit->range>=0 && group->interval!=-1) {
 		if (battle_config.skill_wall_check)
 			map_foreachinshootrange(skill_unit_timer_sub_onplace, bl, unit->range,
@@ -9904,8 +9921,14 @@ int skill_unit_timer_sub (struct block_list *bl, va_list ap)
 			map_foreachinrange(skill_unit_timer_sub_onplace, bl, unit->range,
 				group->bl_flag,bl,tick);
 		if (!unit->alive)
+		{
+			if (flag)
+				skill_dance_switch(unit, group, 1);
 			return 0;
+		}
 	}
+  	if (flag)
+		skill_dance_switch(unit, group, 1);
 
 	if((DIFF_TICK(tick,group->tick)>=group->limit || DIFF_TICK(tick,group->tick)>=unit->limit)){
 		switch(group->unit_id){
@@ -9996,7 +10019,7 @@ int skill_unit_move_sub (struct block_list *bl, va_list ap)
 	struct skill_unit_group *group;
 	struct block_list *target;
 	unsigned int tick,flag,result;
-	int skill_id,unit_id=0; //Set to 0 to shut-up compiler warnings.
+	int skill_id;
 
 	target=va_arg(ap,struct block_list*);
 	tick = va_arg(ap,unsigned int);
@@ -10007,12 +10030,20 @@ int skill_unit_move_sub (struct block_list *bl, va_list ap)
 	if (!unit->alive || target->prev==NULL)
 		return 0;
 
-  	//Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
-	skill_id = unit->group->skill_id;
 	
+	if (skill_dance_switch(unit, group, 0))
+		flag|=64; //Signal to remember to restore it.
+
+	//Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
+	skill_id = unit->group->skill_id;
+
 	if (unit->group->interval!=-1 && 
-		!(skill_get_unit_flag(skill_id)&UF_DUALMODE)) //Skills in dual mode have to trigger both. [Skotlex]
+		!(skill_get_unit_flag(skill_id)&UF_DUALMODE))
+	{	//Skills in dual mode have to trigger both. [Skotlex]
+		if (flag&64)
+			skill_dance_switch(unit, group, 1);
 		return 0;
+	}
 
 	//Target-type check.
 	if(!(group->bl_flag&target->type && battle_check_target(&unit->bl,target,group->target_flag)>0))
@@ -10037,24 +10068,11 @@ int skill_unit_move_sub (struct block_list *bl, va_list ap)
 			if (flag&4)
 				skill_unit_onleft(skill_id,target,tick);
 		}
+		if (flag&64)
+			skill_dance_switch(unit, group, 1);
 		return 0;
 	}
 	
-	if (group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE)
-  	{	//Treat this group as if it were BA_DISSONANCE/DC_UGLYDANCE.
-		//Values will be restored on proper switch case.
-		flag|=64; //Signal to remember to restore it.
-		unit_id = group->unit_id;
-		unit->val1 = group->skill_id;
-		if (unit->val2&UF_SONG) {
-			group->unit_id = UNT_DISSONANCE;
-			group->skill_id = BA_DISSONANCE;
-		} else {
-			group->unit_id = UNT_UGLYDANCE;
-			group->skill_id = DC_UGLYDANCE;
-		}
-	}
-
 	if (flag&1)
 	{
 		result = skill_unit_onplace(unit,target,tick);
@@ -10073,14 +10091,11 @@ int skill_unit_move_sub (struct block_list *bl, va_list ap)
 			skill_unit_temp[skill_unit_index++] = result;
 	}
 
+	//TODO: Normally, this is dangerous since the unit and group could be freed
+	//inside the onout/onplace functions. Currently it is safe because we know song/dance
+	//cells do not get deleted within them. [Skotlex]
 	if (flag&64)
-	{	//TODO: Normally, this is dangerous since the unit and group could be freed
-		//inside the onout/onplace functions. Currently it is safe because we know song/dance
-		//cells do not get deleted within them. [Skotlex]
-		skill_id = group->skill_id;
-		group->unit_id = unit_id;
-		group->skill_id = unit->val1;
-	}
+		skill_dance_switch(unit, group, 1);
 		
 	if (flag&4)
 		skill_unit_onleft(skill_id,target,tick);
@@ -11494,6 +11509,7 @@ void skill_reload (void)
 int do_init_skill (void)
 {
 	skill_readdb();
+	skill_dance_switch_sub(NULL, NULL, 2); //Initialize Song/Dance overlap switch code.
 	
 	skill_unit_ers = ers_new((uint32)sizeof(struct skill_unit_group));
 	skill_timer_ers  = ers_new((uint32)sizeof(struct skill_timerskill));