Browse Source

Song and Dance timers now correctly update in the instance of Dissonance/Ugly Dance cell switches - Fixes bugreport:6606
Adding display enabled language in @langtype
Speed up language check and ignore case

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

akinari1087 12 years ago
parent
commit
bc7f63b3b5
7 changed files with 93 additions and 31 deletions
  1. 1 0
      conf/msg_conf/map_msg.conf
  2. 25 11
      src/common/msg_conf.c
  3. 1 0
      src/common/msg_conf.h
  4. 9 0
      src/map/atcommand.c
  5. 1 1
      src/map/battle.c
  6. 52 15
      src/map/skill.c
  7. 4 4
      src/map/unit.c

+ 1 - 0
conf/msg_conf/map_msg.conf

@@ -448,6 +448,7 @@
 461: Langtype is now = %s=>%d
 461: Langtype is now = %s=>%d
 462: The choosen langage is currently disable please choose another
 462: The choosen langage is currently disable please choose another
 463: Msg_conf have been reloaded
 463: Msg_conf have been reloaded
+464: Available langages:
 
 
 // Messages of others (not for GM commands)
 // Messages of others (not for GM commands)
 // ----------------------------------------
 // ----------------------------------------

+ 25 - 11
src/common/msg_conf.c

@@ -77,18 +77,32 @@ void _do_final_msg(int size, char ** msg_table){
  */
  */
 int msg_langstr2langtype(char * langtype){
 int msg_langstr2langtype(char * langtype){
 	int lang=-1;
 	int lang=-1;
-	if(!strncmp(langtype, "eng",2)) lang=0;
-	else if (!strncmp(langtype, "rus",2)) lang = 1;
-	else if (!strncmp(langtype, "spn",2)) lang = 2;
-	else if (!strncmp(langtype, "grm",2)) lang = 3;
-	else if (!strncmp(langtype, "chn",2)) lang = 4;
-	else if (!strncmp(langtype, "mal",2)) lang = 5;
-	else if (!strncmp(langtype, "idn",2)) lang = 6;
-	else if (!strncmp(langtype, "frn",2)) lang = 7;
+	if(!strncmpi(langtype, "eng",2)) lang=0;
+	else if (!strncmpi(langtype, "rus",2)) lang = 1;
+	else if (!strncmpi(langtype, "spn",2)) lang = 2;
+	else if (!strncmpi(langtype, "grm",2)) lang = 3;
+	else if (!strncmpi(langtype, "chn",2)) lang = 4;
+	else if (!strncmpi(langtype, "mal",2)) lang = 5;
+	else if (!strncmpi(langtype, "idn",2)) lang = 6;
+	else if (!strncmpi(langtype, "frn",2)) lang = 7;
 
 
 	return lang;
 	return lang;
 }
 }
 
 
+const char* msg_langtype2langstr(int langtype){
+	switch(langtype){
+		case 0: return "English (ENG)";
+		case 1: return "Russian (RUS)";
+		case 2: return "Spanish (SPN)";
+		case 3: return "German (GRM)";
+		case 4: return "Chinese (CHN)";
+		case 5: return "Malasian (MAL)";
+		case 6: return "Indonesian (IDN)";
+		case 7: return "French (FRN)";
+		default: return "??";
+	}
+}
+
 /*
 /*
  * verify that the choosen langtype is enable
  * verify that the choosen langtype is enable
  * return
  * return
@@ -97,10 +111,10 @@ int msg_langstr2langtype(char * langtype){
  * -2 : disable
  * -2 : disable
  */
  */
 int msg_checklangtype(int lang, bool display){
 int msg_checklangtype(int lang, bool display){
-	uint16 test=1;
+	uint16 test= (1<<(lang-1));
 	if(!lang) return 1; //default english
 	if(!lang) return 1; //default english
-	else if(lang < 0 && (test<<(lang-1)) > LANG_MAX ) return -1; //false range
-	else if (LANG_ENABLE&(test<<(lang-1)) ) return 1;
+	else if(lang < 0 || test > LANG_MAX) return -1; //false range
+	else if (LANG_ENABLE&test) return 1;
 	else if(display) {
 	else if(display) {
 		ShowDebug("Unsuported langtype=%d\n",lang);
 		ShowDebug("Unsuported langtype=%d\n",lang);
 	}
 	}

+ 1 - 0
src/common/msg_conf.h

@@ -26,6 +26,7 @@ const char* _msg_txt(int msg_number,int size, char ** msg_table);
 int _msg_config_read(const char* cfgName,int size, char ** msg_table);
 int _msg_config_read(const char* cfgName,int size, char ** msg_table);
 void _do_final_msg(int size, char ** msg_table);
 void _do_final_msg(int size, char ** msg_table);
 int msg_langstr2langtype(char * langtype);
 int msg_langstr2langtype(char * langtype);
+const char* msg_langtype2langstr(int langtype);
 //verify that the choosen langtype is enable
 //verify that the choosen langtype is enable
 int msg_checklangtype(int lang, bool display);
 int msg_checklangtype(int lang, bool display);
 
 

+ 9 - 0
src/map/atcommand.c

@@ -9088,7 +9088,16 @@ ACMD_FUNC(langtype){
 		clif_displaymessage(fd,output); //"English is now set as default language"
 		clif_displaymessage(fd,output); //"English is now set as default language"
 	}
 	}
 	else {
 	else {
+		int i=0, test=0; char output[512]; //shoud be fine for 50 lang
 		clif_displaymessage(fd,msg_txt(sd,462));
 		clif_displaymessage(fd,msg_txt(sd,462));
+		clif_displaymessage(fd,msg_txt(sd,464));
+		while(test!=-1){ //out of range
+			test = msg_checklangtype(i,false);
+			if(test == 1)
+				sprintf(output,"%s%s => %d\n",output,msg_langtype2langstr(i),i);
+			i++;
+		}
+		clif_displaymessage(fd,output);
 	}
 	}
 
 
 	return 0;
 	return 0;

+ 1 - 1
src/map/battle.c

@@ -1200,7 +1200,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
 	}
 	}
 
 
 	if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && map[bl->m].flag.pvp)
 	if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && map[bl->m].flag.pvp)
-  	{
+	{
 		if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex]
 		if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex]
 			if (flag&BF_WEAPON)
 			if (flag&BF_WEAPON)
 				DAMAGE_RATE(battle_config.pk_weapon_damage_rate)
 				DAMAGE_RATE(battle_config.pk_weapon_damage_rate)

+ 52 - 15
src/map/skill.c

@@ -252,7 +252,7 @@ static int skill_cell_overlap(struct block_list *bl, va_list ap);
 static int skill_trap_splash(struct block_list *bl, va_list ap);
 static int skill_trap_splash(struct block_list *bl, va_list ap);
 struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list *bl,struct skill_unit_group *sg,int tick);
 struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list *bl,struct skill_unit_group *sg,int tick);
 static int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int tick);
 static int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int tick);
-static int skill_unit_onleft(uint16 skill_id, struct block_list *bl,unsigned int tick);
+int skill_unit_onleft(uint16 skill_id, struct block_list *bl,unsigned int tick);
 static int skill_unit_effect(struct block_list *bl,va_list ap);
 static int skill_unit_effect(struct block_list *bl,va_list ap);
 
 
 int enchant_eff[5] = { 10, 14, 17, 19, 20 };
 int enchant_eff[5] = { 10, 14, 17, 19, 20 };
@@ -1045,7 +1045,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
 		if(sd && (skill=pc_checkskill(sd,DC_DANCINGLESSON)))
 		if(sd && (skill=pc_checkskill(sd,DC_DANCINGLESSON)))
 		    rate += 5+skill;
 		    rate += 5+skill;
 		status_zap(bl, 0, rate);
 		status_zap(bl, 0, rate);
-  		break;
+		break;
 	case SL_STUN:
 	case SL_STUN:
 		if (tstatus->size==SZ_MEDIUM) //Only stuns mid-sized mobs.
 		if (tstatus->size==SZ_MEDIUM) //Only stuns mid-sized mobs.
 			sc_start(src,bl,SC_STUN,(30+10*skill_lv),skill_lv,skill_get_time(skill_id,skill_lv));
 			sc_start(src,bl,SC_STUN,(30+10*skill_lv),skill_lv,skill_get_time(skill_id,skill_lv));
@@ -10640,6 +10640,9 @@ int skill_dance_overlap(struct skill_unit* unit, int flag)
 /*==========================================
 /*==========================================
  * Converts this group information so that it is handled as a Dissonance or Ugly Dance cell.
  * Converts this group information so that it is handled as a Dissonance or Ugly Dance cell.
  * Flag: 0 - Convert, 1 - Revert.
  * Flag: 0 - Convert, 1 - Revert.
+ * TODO: This should be completely removed later and rewritten
+ * 	 The entire execution of the overlapping songs instances is dirty and hacked together
+ *	 Overlapping cells should be checked on unit entry, not infinitely loop checked causing 1000's of executions a song/dance
  *------------------------------------------*/
  *------------------------------------------*/
 static bool skill_dance_switch(struct skill_unit* unit, int flag)
 static bool skill_dance_switch(struct skill_unit* unit, int flag)
 {
 {
@@ -10859,10 +10862,6 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
 		break;
 		break;
 	}
 	}
 
 
-	case BA_DISSONANCE:
-	case DC_UGLYDANCE:
-		val1 = 10;	//FIXME: This value is not used anywhere, what is it for? [Skotlex]
-		break;
 	case BA_WHISTLE:
 	case BA_WHISTLE:
 		val1 = skill_lv +status->agi/10; // Flee increase
 		val1 = skill_lv +status->agi/10; // Flee increase
 		val2 = ((skill_lv+1)/2)+status->luk/10; // Perfect dodge increase
 		val2 = ((skill_lv+1)/2)+status->luk/10; // Perfect dodge increase
@@ -12180,6 +12179,19 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
 			}
 			}
 			break;
 			break;
 		}
 		}
+	case UNT_DISSONANCE:
+	case UNT_UGLYDANCE: //Used for updating timers in song overlap instances
+		{
+			short i;
+			for(i = BA_WHISTLE; i <= DC_SERVICEFORYOU; i++){
+				if(skill_get_inf2(i)&(INF2_SONG_DANCE)){
+					type = status_skill2sc(i);
+					sce = (sc && type != -1)?sc->data[type]:NULL;
+					if(sce)
+						return i;
+				}
+			}
+		}
 	}
 	}
 	return sg->skill_id;
 	return sg->skill_id;
 }
 }
@@ -12187,7 +12199,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
 /*==========================================
 /*==========================================
  * Triggered when a char steps out of a skill group (entirely) [Skotlex]
  * Triggered when a char steps out of a skill group (entirely) [Skotlex]
  *------------------------------------------*/
  *------------------------------------------*/
-static int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick)
+int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick)
 {
 {
 	struct status_change *sc;
 	struct status_change *sc;
 	struct status_change_entry *sce;
 	struct status_change_entry *sce;
@@ -12252,7 +12264,23 @@ static int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned i
 				status_set_sp(bl, 0, 0); //set sp to 0 when quitting zone
 				status_set_sp(bl, 0, 0); //set sp to 0 when quitting zone
 			}
 			}
 			break;
 			break;
-
+		case BA_DISSONANCE:
+		case DC_UGLYDANCE: //Used for updating song timers in overlap instances
+			{
+				short i;
+				for(i = BA_WHISTLE; i <= DC_SERVICEFORYOU; i++){
+					if(skill_get_inf2(i)&(INF2_SONG_DANCE)){
+						type = status_skill2sc(i);
+						sce = (sc && type != -1)?sc->data[type]:NULL;
+						if(sce && !sce->val4){ //We don't want dissonance updating this anymore
+							delete_timer(sce->timer, status_change_timer);
+							sce->val4 = 1; //Store the fact that this is a "reduced" duration effect.
+							sce->timer = add_timer(tick+skill_get_time2(i,1), status_change_timer, bl->id, type);
+						}
+					}
+				}
+			}
+			break;
 		case BA_POEMBRAGI:
 		case BA_POEMBRAGI:
 		case BA_WHISTLE:
 		case BA_WHISTLE:
 		case BA_ASSASSINCROSS:
 		case BA_ASSASSINCROSS:
@@ -12302,6 +12330,7 @@ static int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned i
  * flag values:
  * flag values:
  * flag&1: Invoke onplace function (otherwise invoke onout)
  * flag&1: Invoke onplace function (otherwise invoke onout)
  * flag&4: Invoke a onleft call (the unit might be scheduled for deletion)
  * flag&4: Invoke a onleft call (the unit might be scheduled for deletion)
+ * flag&8: Recursive
  *------------------------------------------*/
  *------------------------------------------*/
 static int skill_unit_effect (struct block_list* bl, va_list ap)
 static int skill_unit_effect (struct block_list* bl, va_list ap)
 {
 {
@@ -12310,7 +12339,7 @@ static int skill_unit_effect (struct block_list* bl, va_list ap)
 	unsigned int tick = va_arg(ap,unsigned int);
 	unsigned int tick = va_arg(ap,unsigned int);
 	unsigned int flag = va_arg(ap,unsigned int);
 	unsigned int flag = va_arg(ap,unsigned int);
 	uint16 skill_id;
 	uint16 skill_id;
-	bool dissonance;
+	bool dissonance = false;
 	bool isTarget = false;
 	bool isTarget = false;
 
 
 	if( (!unit->alive && !(flag&4)) || bl->prev == NULL )
 	if( (!unit->alive && !(flag&4)) || bl->prev == NULL )
@@ -12318,12 +12347,14 @@ static int skill_unit_effect (struct block_list* bl, va_list ap)
 
 
 	nullpo_ret(group);
 	nullpo_ret(group);
 
 
-	dissonance = skill_dance_switch(unit, 0);
+	if( !(flag&8) ) {
+		dissonance = skill_dance_switch(unit, 0);
+		//Target-type check.
+		isTarget = group->bl_flag & bl->type && battle_check_target( &unit->bl, bl, group->target_flag ) > 0;
+	}
 
 
 	//Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
 	//Necessary in case the group is deleted after calling on_place/on_out [Skotlex]
 	skill_id = group->skill_id;
 	skill_id = group->skill_id;
-	//Target-type check.
-	isTarget = group->bl_flag & bl->type && battle_check_target( &unit->bl, bl, group->target_flag ) > 0;
 	if( isTarget ){
 	if( isTarget ){
 		if( flag&1 )
 		if( flag&1 )
 			skill_unit_onplace(unit,bl,tick);
 			skill_unit_onplace(unit,bl,tick);
@@ -12336,8 +12367,11 @@ static int skill_unit_effect (struct block_list* bl, va_list ap)
 		skill_unit_onleft(skill_id, bl, tick);//Ensemble check to terminate it.
 		skill_unit_onleft(skill_id, bl, tick);//Ensemble check to terminate it.
 	}
 	}
 
 
-	if( dissonance )
+	if( dissonance ) {
 		skill_dance_switch(unit, 1);
 		skill_dance_switch(unit, 1);
+		//we placed a dissonance, let's update
+		map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),4|8);
+	}
 
 
 	return 0;
 	return 0;
 }
 }
@@ -15666,7 +15700,7 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap)
 			{
 			{
 				struct map_session_data *sd = NULL;
 				struct map_session_data *sd = NULL;
 				if(group->val1) {
 				if(group->val1) {
-		  			sd = map_charid2sd(group->val1);
+					sd = map_charid2sd(group->val1);
 					group->val1 = 0;
 					group->val1 = 0;
 					if (sd && !map[sd->bl.m].flag.nowarp)
 					if (sd && !map[sd->bl.m].flag.nowarp)
 						pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT);
 						pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT);
@@ -15841,7 +15875,10 @@ int skill_unit_move_sub (struct block_list* bl, va_list ap) {
 
 
 	if( unit->group->interval != -1 && !(skill_get_unit_flag(skill_id)&UF_DUALMODE) && skill_id != BD_LULLABY ) //Lullaby is the exception, bugreport:411
 	if( unit->group->interval != -1 && !(skill_get_unit_flag(skill_id)&UF_DUALMODE) && skill_id != BD_LULLABY ) //Lullaby is the exception, bugreport:411
 	{	//Non-dualmode unit skills with a timer don't trigger when walking, so just return
 	{	//Non-dualmode unit skills with a timer don't trigger when walking, so just return
-		if( dissonance ) skill_dance_switch(unit, 1);
+		if( dissonance ) {
+			skill_dance_switch(unit, 1);
+			skill_unit_onleft(skill_unit_onout(unit,target,tick),target,tick); //we placed a dissonance, let's update
+		}
 		return 0;
 		return 0;
 	}
 	}
 
 

+ 4 - 4
src/map/unit.c

@@ -924,10 +924,10 @@ int unit_can_move(struct block_list *bl) {
 			|| (sc->data[SC_FEAR] && sc->data[SC_FEAR]->val2 > 0)
 			|| (sc->data[SC_FEAR] && sc->data[SC_FEAR]->val2 > 0)
 			|| (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
 			|| (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
 			|| (sc->data[SC_DANCING] && sc->data[SC_DANCING]->val4 && (
 			|| (sc->data[SC_DANCING] && sc->data[SC_DANCING]->val4 && (
-																	!sc->data[SC_LONGING] ||
-																	(sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT ||
-																	(sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE
-																	) )
+				!sc->data[SC_LONGING] ||
+				(sc->data[SC_DANCING]->val1&0xFFFF) == CG_MOONLIT ||
+				(sc->data[SC_DANCING]->val1&0xFFFF) == CG_HERMODE
+				) )
 			|| (sc->data[SC_CLOAKING] && //Need wall at level 1-2
 			|| (sc->data[SC_CLOAKING] && //Need wall at level 1-2
 				sc->data[SC_CLOAKING]->val1 < 3 && !(sc->data[SC_CLOAKING]->val4&1))
 				sc->data[SC_CLOAKING]->val1 < 3 && !(sc->data[SC_CLOAKING]->val4&1))
 			)
 			)