소스 검색

-Upd mob_count to read a 10 modib list to chk if present or not
-Add UNLIMITED_HUMMING implementation, now increase sp requirement and make cast unbreakable
-Upd Group dance overlaping A and B, previous chk wasn't ending other properly (if fail was skipping other)
-Upd OdinPower effect

-Fix Cursed-Circle, shoudn't be able to cast near Emp,Stones bugreport:6457
-Fix Cursed-Circle wasn't remove when caster was being warped

-Small docs upd

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16918 54d463be-8e91-2dee-dedb-b68131a5f0ec

glighta 12 년 전
부모
커밋
33b2b02c5a
8개의 변경된 파일77개의 추가작업 그리고 53개의 파일을 삭제
  1. 0 1
      src/map/map.h
  2. 9 3
      src/map/mob.c
  3. 1 0
      src/map/mob.h
  4. 1 1
      src/map/npc.c
  5. 11 12
      src/map/pc.c
  6. 11 0
      src/map/skill.c
  7. 40 34
      src/map/status.c
  8. 4 2
      src/map/unit.c

+ 0 - 1
src/map/map.h

@@ -717,7 +717,6 @@ bool                    mapit_exists(struct s_mapiterator* mapit);
 #define mapit_geteachnpc()  mapit_alloc(MAPIT_NORMAL,BL_NPC)
 #define mapit_geteachiddb() mapit_alloc(MAPIT_NORMAL,BL_ALL)
 
-// ���̑�
 int map_check_dir(int s_dir,int t_dir);
 unsigned char map_calc_dir( struct block_list *src,int x,int y);
 int map_random_dir(struct block_list *bl, short *x, short *y); // [Skotlex]

+ 9 - 3
src/map/mob.c

@@ -881,9 +881,15 @@ int mob_setdelayspawn(struct mob_data *md)
 	return 0;
 }
 
-static int mob_count_sub(struct block_list *bl,va_list ap)
-{
-	return 1;
+int mob_count_sub(struct block_list *bl, va_list ap) {
+    int mobid[10], i;
+    ARR_FIND(0, 10, i, (mobid[i] = va_arg(ap, int)) == 0); //fetch till 0
+    if (mobid[0]) { //if there one let's check it otherwise go backward
+        TBL_MOB *md = BL_CAST(BL_MOB, bl);
+        ARR_FIND(0, 10, i, md->class_ == mobid[i]);
+        return (i < 10) ? 1 : 0;
+    }
+    return 1; //backward compatibility
 }
 
 /*==========================================

+ 1 - 0
src/map/mob.h

@@ -304,6 +304,7 @@ int mobskill_castend_id( int tid, unsigned int tick, int id,int data );
 int mobskill_castend_pos( int tid, unsigned int tick, int id,int data );
 int mob_summonslave(struct mob_data *md2,int *value,int amount,int skill_id);
 int mob_countslave(struct block_list *bl);
+int mob_count_sub(struct block_list *bl, va_list ap);
 
 int mob_is_clone(int class_);
 

+ 1 - 1
src/map/npc.c

@@ -2229,7 +2229,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
 }
 
 /**
- * NPCのラベルデータコンバート
+ * NPC other label
  * Not sure, seem to add label in a chainlink
  * @see DBApply
  */

+ 11 - 12
src/map/pc.c

@@ -2613,7 +2613,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
 }
 
 /*==========================================
- * ? ???i????\????~{??i?X???
+ * Player bonus (type) with args type2 and val, called trough bonus2 (npc)
  *------------------------------------------*/
 int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
 {
@@ -4864,13 +4864,10 @@ int pc_checkskill(struct map_session_data *sd,int skill_id)
 }
 
 /*==========================================
- * ??????X????X?L???????`?F?b?N
- * ????F
- *   struct map_session_data *sd	?Z?b?V?????f??^
- *   int nameid						????iID
- * ???l?F
- *   0		??X???
- *   -1		?X?L????????
+ * Chk if we still have the correct weapon to continue the skill (actually status)
+ * If not ending it
+ * Return
+ *	0 - No status found or all done
  *------------------------------------------*/
 int pc_checkallowskill(struct map_session_data *sd)
 {
@@ -4921,7 +4918,9 @@ int pc_checkallowskill(struct map_session_data *sd)
 
 /*==========================================
  * Return equiped itemid? on player sd at pos
- * if -1 mean nothing equiped
+ * Return
+ * -1 : mean nothing equiped
+ * idx : (this index could be used in inventory to found item_data)
  *------------------------------------------*/
 int pc_checkequip(struct map_session_data *sd,int pos)
 {
@@ -7497,7 +7496,7 @@ int pc_setcart(struct map_session_data *sd,int type) {
 int pc_setfalcon(TBL_PC* sd, int flag)
 {
 	if( flag ){
-		if( pc_checkskill(sd,HT_FALCON)>0 )	// ?t?@???R???}?X?^????X?L??????
+		if( pc_checkskill(sd,HT_FALCON)>0 )	// add falcon if he have the skill
 			pc_setoption(sd,sd->sc.option|OPTION_FALCON);
 	} else if( pc_isfalcon(sd) ){
 		pc_setoption(sd,sd->sc.option&~OPTION_FALCON); // remove falcon
@@ -7512,7 +7511,7 @@ int pc_setfalcon(TBL_PC* sd, int flag)
 int pc_setriding(TBL_PC* sd, int flag)
 {
 	if( flag ){
-		if( pc_checkskill(sd,KN_RIDING) > 0 ) // ???C?f?B???O?X?L??????
+		if( pc_checkskill(sd,KN_RIDING) > 0 ) // add peco
 			pc_setoption(sd, sd->sc.option|OPTION_RIDING);
 	} else if( pc_isriding(sd) ){
 			pc_setoption(sd, sd->sc.option&~OPTION_RIDING);
@@ -8949,7 +8948,7 @@ void pc_setstand(struct map_session_data *sd){
 	nullpo_retv(sd);
 
 	status_change_end(&sd->bl, SC_TENSIONRELAX, INVALID_TIMER);
-        clif_status_load(&sd->bl,SI_SIT,0);
+	clif_status_load(&sd->bl,SI_SIT,0);
 	//Reset sitting tick.
 	sd->ssregen.tick.hp = sd->ssregen.tick.sp = 0;
 	sd->state.dead_sit = sd->vd.dead_sit = 0;

+ 11 - 0
src/map/skill.c

@@ -12847,6 +12847,15 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
 			}
 			break;
 		case SR_CURSEDCIRCLE:
+			if (map_flag_gvg(sd->bl.m)) {
+			    if (map_foreachinrange(mob_count_sub, &sd->bl, skill_get_splash(skill, lv), BL_MOB,
+				    MOBID_EMPERIUM, MOBID_GUARIDAN_STONE1, MOBID_GUARIDAN_STONE2)) {
+				char output[128];
+				sprintf(output, "You're too close to a stone or emperium to do this skill");
+				clif_colormes(sd, COLOR_RED, output);
+				return 0;
+			    }
+			}
 			if( sd->spiritball > 0 )
 				sd->spiritball_old = require.spiritball = sd->spiritball;
 			else {
@@ -13374,6 +13383,8 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
 	if( sc ) {
 		if( sc->data[SC__LAZINESS] )
 			req.sp += req.sp + sc->data[SC__LAZINESS]->val1 * 10;
+		if (sc->data[SC_UNLIMITEDHUMMINGVOICE])
+			req.sp += req.sp * sc->data[SC_UNLIMITEDHUMMINGVOICE]->val2 / 100;
 		if( sc->data[SC_RECOGNIZEDSPELL] )
 			req.sp += req.sp / 4;
 	}

+ 40 - 34
src/map/status.c

@@ -4561,7 +4561,7 @@ static unsigned short status_calc_matk(struct block_list *bl, struct status_chan
 	if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
 		matk += 50;
 	if(sc->data[SC_ODINS_POWER])
-		matk += 70;
+		matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; //70 lvl1, 100lvl2
 	if(sc->data[SC_IZAYOI])
 		matk += 50 * sc->data[SC_IZAYOI]->val1;
 	if( sc->data[SC_ZANGETSU] )
@@ -4923,10 +4923,10 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
 		mdef -= mdef * sc->data[SC_GT_CHANGE]->val4 / 100;
 	if(sc->data[SC_WATER_BARRIER])
 		mdef += sc->data[SC_WATER_BARRIER]->val2;
+	if (sc->data[SC_ODINS_POWER])
+		mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
 	if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
 		mdef += 50;
-	if(sc->data[SC_ODINS_POWER])
-		mdef -= 20;
 
 	return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
 }
@@ -6868,37 +6868,43 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 	case SC_MOONLITSERENADE:
 	case SC_RUSHWINDMILL:
 	case SC_ECHOSONG:
-	case SC_HARMONIZE:
-	case SC_VOICEOFSIREN:
-	case SC_DEEPSLEEP:
-	case SC_SIRCLEOFNATURE:
-		if( sc->data[type] ) // Don't remove same sc.
-			break;
-		status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
-		status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
-		status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
-		status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
-		status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
-		status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
-		status_change_end(bl, SC_VOICEOFSIREN, INVALID_TIMER);
-		status_change_end(bl, SC_DEEPSLEEP, INVALID_TIMER);
-		status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
-			break;
-	case SC_SONGOFMANA:
-	case SC_DANCEWITHWUG:
-	case SC_LERADSDEW:
-	case SC_MELODYOFSINK:
-	case SC_BEYONDOFWARCRY:
-	case SC_UNLIMITEDHUMMINGVOICE:
-		if( sc->data[type] ) // Don't remove same sc.
-			break; //FIXME this is wrong as it'll prevent other being remove as well
-		status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
-		status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
-		status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
-		status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
-		status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
-		status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
-		break;
+        case SC_HARMONIZE: //group A doesn't overlap
+            if (type != SC_SWINGDANCE) status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
+            if (type != SC_SYMPHONYOFLOVER) status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
+            if (type != SC_MOONLITSERENADE) status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
+            if (type != SC_RUSHWINDMILL) status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
+            if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
+            if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+            break;
+        case SC_VOICEOFSIREN:
+        case SC_DEEPSLEEP:
+        case SC_GLOOMYDAY:
+        case SC_SONGOFMANA:
+        case SC_DANCEWITHWUG:
+        case SC_SATURDAYNIGHTFEVER:
+        case SC_LERADSDEW:
+        case SC_MELODYOFSINK:
+        case SC_BEYONDOFWARCRY:
+        case SC_UNLIMITEDHUMMINGVOICE: //group B
+            if (type != SC_VOICEOFSIREN) status_change_end(bl, SC_VOICEOFSIREN, INVALID_TIMER);
+            if (type != SC_DEEPSLEEP) status_change_end(bl, SC_DEEPSLEEP, INVALID_TIMER);
+            if (type != SC_LERADSDEW) status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
+            if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
+            if (type != SC_BEYONDOFWARCRY) status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
+            if (type != SC_UNLIMITEDHUMMINGVOICE) status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
+            if (type != SC_GLOOMYDAY) {
+                status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
+                status_change_end(bl, SC_GLOOMYDAY_SK, INVALID_TIMER);
+            }
+            if (type != SC_SONGOFMANA) status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
+            if (type != SC_DANCEWITHWUG) status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
+            if (type != SC_SATURDAYNIGHTFEVER) {
+                if (sc->data[SC_SATURDAYNIGHTFEVER]) {
+                    sc->data[SC_SATURDAYNIGHTFEVER]->val2 = 0; //mark to not lose hp
+                    status_change_end(bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
+                }
+            }
+            break;
 	case SC_REFLECTSHIELD:
 		status_change_end(bl, SC_REFLECTDAMAGE, INVALID_TIMER);
 		break;

+ 4 - 2
src/map/unit.c

@@ -1869,7 +1869,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
 			return 0;
 
 		if (sd && (sd->special_state.no_castcancel2 ||
-			(sd->special_state.no_castcancel && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89]
+                ((sd->sc.data[SC_UNLIMITEDHUMMINGVOICE] || sd->special_state.no_castcancel) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89]
 			return 0;
 	}
 
@@ -2024,9 +2024,11 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
 		status_change_end(bl, SC_CHANGE, INVALID_TIMER);
 		status_change_end(bl, SC_STOP, INVALID_TIMER);
 		status_change_end(bl, SC_WUGDASH, INVALID_TIMER);
+		status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
 		status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
 		status_change_end(bl, SC__MANHOLE, INVALID_TIMER);
-
+		status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER);
+		status_change_end(bl, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER); //callme before warp
 	}
 
 	if (bl->type&(BL_CHAR|BL_PET)) {