소스 검색

Bug Fixes
* Fixed #274 Castling (HAMI_CASTLE) makes a whole area attack you!
* Changed `skill_changetarget` to `unit_changetarget`, also fixed the validation before switching the `bl`'s attacking target from current `src` to new `target`.

Signed-off-by: Cydh Ramdh <cydh@pservero.com>

Cydh Ramdh 10 년 전
부모
커밋
82d43fe894
4개의 변경된 파일53개의 추가작업 그리고 28개의 파일을 삭제
  1. 16 26
      src/map/skill.c
  2. 0 2
      src/map/skill.h
  3. 36 0
      src/map/unit.c
  4. 1 0
      src/map/unit.h

+ 16 - 26
src/map/skill.c

@@ -5569,9 +5569,15 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 	return 0;
 	return 0;
 }
 }
 
 
-/*==========================================
- *
- *------------------------------------------*/
+/**
+ * Use no-damage skill from 'src' to 'bl
+ * @param src Caster
+ * @param bl Target of the skill, bl maybe same with src for self skill
+ * @param skill_id
+ * @param skill_lv
+ * @param tick
+ * @param flag Various value, &1: Recursive effect
+ **/
 int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag)
 int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag)
 {
 {
 	struct map_session_data *sd, *dstsd;
 	struct map_session_data *sd, *dstsd;
@@ -8352,22 +8358,24 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 		break;
 
 
 	case HAMI_CASTLE:	//[orn]
 	case HAMI_CASTLE:	//[orn]
-		if (rnd()%100 < 20 * skill_lv && src != bl) {
+		if (src != bl && rnd()%100 < 20 * skill_lv) {
 			int x = src->x, y = src->y;
 			int x = src->x, y = src->y;
 
 
 			if (hd)
 			if (hd)
 				skill_blockhomun_start(hd,skill_id,skill_get_time2(skill_id,skill_lv));
 				skill_blockhomun_start(hd,skill_id,skill_get_time2(skill_id,skill_lv));
+			// Move source
 			if (unit_movepos(src,bl->x,bl->y,0,0)) {
 			if (unit_movepos(src,bl->x,bl->y,0,0)) {
 				clif_skill_nodamage(src,src,skill_id,skill_lv,1); // Homunc
 				clif_skill_nodamage(src,src,skill_id,skill_lv,1); // Homunc
 				clif_blown(src);
 				clif_blown(src);
+				// Move target
 				if (unit_movepos(bl,x,y,0,0)) {
 				if (unit_movepos(bl,x,y,0,0)) {
-					clif_skill_nodamage(bl,bl,skill_id,skill_lv,1); // Master
+					clif_skill_nodamage(bl,bl,skill_id,skill_lv,1);
 					clif_blown(bl);
 					clif_blown(bl);
 				}
 				}
-				//TODO: Make casted skill also change its target
-				map_foreachinrange(skill_changetarget,src,AREA_SIZE,BL_CHAR,bl,src);
+				map_foreachinrange(unit_changetarget,src,AREA_SIZE,BL_MOB,bl,src);
 			}
 			}
-		} else if (hd && hd->master) // Failed
+		}
+		else if (hd && hd->master) // Failed
 			clif_skill_fail(hd->master, skill_id, USESKILL_FAIL_LEVEL, 0);
 			clif_skill_fail(hd->master, skill_id, USESKILL_FAIL_LEVEL, 0);
 		else if (sd)
 		else if (sd)
 			clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
 			clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
@@ -16688,24 +16696,6 @@ static int skill_cell_overlap(struct block_list *bl, va_list ap)
 	return 0;
 	return 0;
 }
 }
 
 
-/*==========================================
- *
- *------------------------------------------*/
-int skill_changetarget(struct block_list *bl, va_list ap)
-{
-	struct mob_data *md = (struct mob_data *)bl;
-	struct unit_data *ud = unit_bl2ud(bl);
-	struct block_list *from_bl = va_arg(ap,struct block_list *);
-	struct block_list *to_bl = va_arg(ap,struct block_list *);
-
-	if(ud && ud->target == from_bl->id)
-		ud->target = to_bl->id;
-
-	if(md->bl.type == BL_MOB && md->target_id == from_bl->id)
-		md->target_id = to_bl->id;
-	return 0;
-}
-
 /*==========================================
 /*==========================================
  * Splash effect for skill unit 'trap type'.
  * Splash effect for skill unit 'trap type'.
  * Chance triggered when damaged, timeout, or char step on it.
  * Chance triggered when damaged, timeout, or char step on it.

+ 0 - 2
src/map/skill.h

@@ -484,8 +484,6 @@ bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md);
 
 
 bool skill_isNotOk_npcRange(struct block_list *src, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y);
 bool skill_isNotOk_npcRange(struct block_list *src, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y);
 
 
-int skill_changetarget(struct block_list *bl,va_list ap);
-
 // Item creation
 // Item creation
 short skill_can_produce_mix( struct map_session_data *sd, unsigned short nameid, int trigger, int qty);
 short skill_can_produce_mix( struct map_session_data *sd, unsigned short nameid, int trigger, int qty);
 bool skill_produce_mix( struct map_session_data *sd, uint16 skill_id, unsigned short nameid, int slot1, int slot2, int slot3, int qty );
 bool skill_produce_mix( struct map_session_data *sd, uint16 skill_id, unsigned short nameid, int slot1, int slot2, int slot3, int qty );

+ 36 - 0
src/map/unit.c

@@ -2758,6 +2758,42 @@ int unit_changeviewsize(struct block_list *bl,short size)
 	return 0;
 	return 0;
 }
 }
 
 
+/**
+ * Makes 'bl' that attacking 'src' switch to 'target'
+ * @param bl
+ * @param ap
+ * @param src Current target
+ * @param target New target
+ * @param flag 0x1 Force to attack although 'bl' is idle
+ *             0x2 Force to attack although 'bl' has different target (not targetting 'src')
+ **/
+int unit_changetarget(struct block_list *bl, va_list ap) {
+	struct unit_data *ud = unit_bl2ud(bl);
+	struct block_list *src = va_arg(ap,struct block_list *);
+	struct block_list *target = va_arg(ap,struct block_list *);
+	int flag = va_arg(ap,int);
+
+	if (!ud || !target || ud->target == target->id)
+		return 1;
+	if (!(flag&0x1) && !ud->target && !ud->target_to)
+		return 1;
+	if (!(flag&0x2) && ud->target != src->id && ud->target_to != src->id)
+		return 1;
+
+	if (bl->type == BL_MOB)
+		(BL_CAST(BL_MOB,bl))->target_id = target->id;
+	if (ud->target_to)
+		ud->target_to = target->id;
+	else
+		ud->target_to = 0;
+	if (ud->skilltarget)
+		ud->skilltarget = target->id;
+	unit_set_target(ud, target->id);
+
+	//unit_attack(bl, target->id, ud->state.attack_continue);
+	return 0;
+}
+
 /**
 /**
  * Removes a bl/ud from the map
  * Removes a bl/ud from the map
  * On kill specifics are not performed here, check status_damage()
  * On kill specifics are not performed here, check status_damage()

+ 1 - 0
src/map/unit.h

@@ -140,6 +140,7 @@ void unit_free_pc(struct map_session_data *sd);
 int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, int line, const char* func);
 int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, int line, const char* func);
 int unit_free(struct block_list *bl, clr_type clrtype);
 int unit_free(struct block_list *bl, clr_type clrtype);
 int unit_changeviewsize(struct block_list *bl,short size);
 int unit_changeviewsize(struct block_list *bl,short size);
+int unit_changetarget(struct block_list *bl,va_list ap);
 
 
 void do_init_unit(void);
 void do_init_unit(void);
 void do_final_unit(void);
 void do_final_unit(void);