浏览代码

- Modified set_reg so that it returns whether it succeeded or not in setting the requested variable.
- Externalized battle skill range and blewcount bonus into their own static functions (battle_range_type & battle_blewcount_bonus).
- Sped up the skill range flag setting code.
- Added automatic support of damagesplit. This means that if a skill's nk value includes damage split among targets, it will do a divide by the number of targets (whereas before the list of skills where this worked was hardcoded)


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

skotlex 18 年之前
父节点
当前提交
4dd0c95c58
共有 5 个文件被更改,包括 93 次插入109 次删除
  1. 1 1
      src/char/char.c
  2. 1 1
      src/char_sql/char.c
  3. 56 75
      src/map/battle.c
  4. 15 15
      src/map/pc.c
  5. 20 17
      src/map/script.c

+ 1 - 1
src/char/char.c

@@ -2031,7 +2031,7 @@ int parse_tologin(int fd) {
 				return 0;
 			for(i = 0; i < fd_max && !(
 				session[i] &&
-			 	(sd = (struct char_session_data*)session[i]->session_data) &&
+				(sd = (struct char_session_data*)session[i]->session_data) &&
 				sd->account_id == RFIFOL(fd,2))
 				; i++);
 			if (i < fd_max) {

+ 1 - 1
src/char_sql/char.c

@@ -1898,7 +1898,7 @@ int parse_tologin(int fd) {
 			for(i = 0; i < fd_max && !(
 				session[i] &&
 				(sd = (struct char_session_data*)session[i]->session_data) &&
-			 	sd->account_id == RFIFOL(fd,2))
+				sd->account_id == RFIFOL(fd,2))
 				; i++);
 
 			if (i < fd_max) {

+ 56 - 75
src/map/battle.c

@@ -805,6 +805,36 @@ void battle_consume_ammo(TBL_PC*sd, int skill, int lv)
 		pc_delitem(sd,sd->equip_index[EQI_AMMO],qty,0);
 }
 
+static int battle_range_type(
+	struct block_list *src, struct block_list *target,
+	int skill_num, int skill_lv)
+{	//Skill Range Criteria
+	if (battle_config.skillrange_by_distance &&
+		(src->type&battle_config.skillrange_by_distance)
+	) { //based on distance between src/target [Skotlex]
+		if (check_distance_bl(src, target, 5))
+			return BF_SHORT;
+		return BF_LONG;
+	}
+	//based on used skill's range
+	if (skill_get_range2(src, skill_num, skill_lv) < 5)
+		return BF_SHORT;
+	return BF_LONG;
+}
+
+static int battle_blewcount_bonus(struct map_session_data *sd, int skill_num)
+{
+	int i;
+	if (!sd->skillblown[0].id)
+		return 0;
+	//Apply the bonus blewcount. [Skotlex]
+	for (i = 0; i < MAX_PC_BONUS && sd->skillblown[i].id; i++) {
+		if (sd->skillblown[i].id == skill_num)
+			return sd->skillblown[i].val;
+	}
+	return 0;
+}
+
 struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag);
 struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag);
 
@@ -863,7 +893,8 @@ static struct Damage battle_calc_weapon_attack(
 		wd.amotion >>= 1;
 	wd.dmotion=tstatus->dmotion;
 	wd.blewcount=skill_get_blewcount(skill_num,skill_lv);
-	wd.flag=BF_SHORT|BF_WEAPON|BF_NORMAL; //Initial Flag
+	wd.flag = BF_WEAPON; //Initial Flag
+	wd.flag|= skill_num?BF_SKILL:BF_NORMAL;
 	wd.dmg_lv=ATK_DEF;	//This assumption simplifies the assignation later
 	nk = skill_get_nk(skill_num);
 	flag.hit	= nk&NK_IGNORE_FLEE?1:0;
@@ -877,14 +908,8 @@ static struct Damage battle_calc_weapon_attack(
 	BL_CAST(BL_PC, src, sd);
 	BL_CAST(BL_PC, target, tsd);
 
-	if(sd) {
-		if (sd->skillblown[0].id != 0)
-		{	//Apply the bonus blewcount. [Skotlex]
-			for (i = 0; i < 5 && sd->skillblown[i].id != 0 && sd->skillblown[i].id != skill_num; i++);
-			if (i < 5 && sd->skillblown[i].id == skill_num)
-				 wd.blewcount += sd->skillblown[i].val;
-		}
-	}
+	if(sd)
+		wd.blewcount += battle_blewcount_bonus(sd, skill_num);
 
 	//Set miscellaneous data that needs be filled regardless of hit/miss
 	if(
@@ -894,7 +919,7 @@ static struct Damage battle_calc_weapon_attack(
 		flag.arrow = 1;
 	
 	if(skill_num){
-		wd.flag=(wd.flag&~BF_SKILLMASK)|BF_SKILL;
+		wd.flag |= battle_range_type(src, target, skill_num, skill_lv);
 		switch(skill_num)
 		{
 			case MO_FINGEROFFENSIVE:
@@ -940,23 +965,8 @@ static struct Damage battle_calc_weapon_attack(
 				flag.cri = 1; //Always critical skill.
 				break;
 		}
-
-		//Skill Range Criteria
-		if (battle_config.skillrange_by_distance &&
-			(src->type&battle_config.skillrange_by_distance)
-		) { //based on distance between src/target [Skotlex]
-			if (check_distance_bl(src, target, 5))
-				wd.flag=(wd.flag&~BF_RANGEMASK)|BF_SHORT;
-			else
-				wd.flag=(wd.flag&~BF_RANGEMASK)|BF_LONG;
-		} else { //based on used skill's range
-			if (skill_get_range2(src, skill_num, skill_lv) < 5)
-				wd.flag=(wd.flag&~BF_RANGEMASK)|BF_SHORT;
-			else
-				wd.flag=(wd.flag&~BF_RANGEMASK)|BF_LONG;
-		}
-	} else if (flag.arrow) //Make the normal attack ranged.
-		wd.flag=(wd.flag&~BF_RANGEMASK)|BF_LONG;
+	} else //Range for normal attacks.
+		wd.flag |= flag.arrow?BF_LONG:BF_SHORT;
 	
 	if (!skill_num && tstatus->flee2 && rand()%1000 < tstatus->flee2)
 	{	//Check for Lucky Dodge
@@ -1238,14 +1248,13 @@ static struct Damage battle_calc_weapon_attack(
 				if (flag.lh)
 					wd.damage2 = battle_calc_base_damage(sstatus, sstatus->lhw, sc, tstatus->size, sd, i);
 
-				// Added split damage for Huuma
-				if (skill_num == NJ_HUUMA)
-				{	// Divide ATK in case of multiple targets skill
+				if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets
 					if(wflag>0)
 						wd.damage/= wflag;
 					else if(battle_config.error_log)
-						ShowError("0 enemies targeted by Throw Huuma, divide per 0 avoided!\n");
+						ShowError("0 enemies targeted by %s, divide per 0 avoided!\n", skill_get_name(skill_num));
 				}
+
 				//Add any bonuses that modify the base baseatk+watk (pre-skills)
 				if(sd)
 				{
@@ -2139,29 +2148,11 @@ struct Damage battle_calc_magic_attack(
 	//Set miscellaneous data that needs be filled
 	if(sd) {
 		sd->state.arrow_atk = 0;
-		if (sd->skillblown[0].id != 0)
-		{	//Apply the bonus blewcount. [Skotlex]
-			for (i = 0; i < MAX_PC_BONUS && sd->skillblown[i].id != 0 && sd->skillblown[i].id != skill_num; i++);
-			if (i < MAX_PC_BONUS && sd->skillblown[i].id == skill_num)
-				ad.blewcount += sd->skillblown[i].val;
-		}
+		ad.blewcount += battle_blewcount_bonus(sd, skill_num);
 	}
 
 	//Skill Range Criteria
-	if (battle_config.skillrange_by_distance &&
-		(src->type&battle_config.skillrange_by_distance)
-	)	{ //based on distance between src/target [Skotlex]
-		if (check_distance_bl(src, target, 5))
-			ad.flag=(ad.flag&~BF_RANGEMASK)|BF_SHORT;
-		else
-			ad.flag=(ad.flag&~BF_RANGEMASK)|BF_LONG;
-	} else { //based on used skill's range
-		if (skill_get_range2(src, skill_num, skill_lv) < 5)
-			ad.flag=(ad.flag&~BF_RANGEMASK)|BF_SHORT;
-		else
-			ad.flag=(ad.flag&~BF_RANGEMASK)|BF_LONG;
-	}
-
+	ad.flag |= battle_range_type(src, target, skill_num, skill_lv);
 	flag.infdef=(tstatus->mode&MD_PLANT?1:0);
 		
 	switch(skill_num)
@@ -2229,11 +2220,11 @@ struct Damage battle_calc_magic_attack(
 					MATK_ADD(sstatus->matk_min);
 				}
 
-				if(skill_num == MG_NAPALMBEAT || skill_num == HW_NAPALMVULCAN){ // Divide MATK in case of multiple targets skill
+				if(nk&NK_SPLASHSPLIT){ // Divide MATK in case of multiple targets skill
 					if(mflag>0)
 						ad.damage/= mflag;
 					else if(battle_config.error_log)
-						ShowError("0 enemies targeted by Napalm Beat/Vulcan, divide per 0 avoided!\n");
+						ShowError("0 enemies targeted by %s, divide per 0 avoided!\n", skill_get_name(skill_num));
 				}
 
 				switch(skill_num){
@@ -2467,12 +2458,7 @@ struct Damage  battle_calc_misc_attack(
 	
 	if(sd) {
 		sd->state.arrow_atk = 0;
-		if (sd->skillblown[0].id != 0)
-		{	//Apply the bonus blewcount. [Skotlex]
-			for (i = 0; i < MAX_PC_BONUS && sd->skillblown[i].id != 0 && sd->skillblown[i].id != skill_num; i++);
-			if (i < MAX_PC_BONUS && sd->skillblown[i].id == skill_num)
-				md.blewcount += sd->skillblown[i].val;
-		}
+		md.blewcount += battle_blewcount_bonus(sd, skill_num);
 	}
 
 	s_ele = skill_get_pl(skill_num);
@@ -2480,19 +2466,7 @@ struct Damage  battle_calc_misc_attack(
 		s_ele = ELE_NEUTRAL;
 
 	//Skill Range Criteria
-	if (battle_config.skillrange_by_distance &&
-		(src->type&battle_config.skillrange_by_distance)
-	) { //based on distance between src/target [Skotlex]
-		if (check_distance_bl(src, target, 5))
-			md.flag=(md.flag&~BF_RANGEMASK)|BF_SHORT;
-		else
-			md.flag=(md.flag&~BF_RANGEMASK)|BF_LONG;
-	} else { //based on used skill's range
-		if (skill_get_range2(src, skill_num, skill_lv) < 5)
-			md.flag=(md.flag&~BF_RANGEMASK)|BF_SHORT;
-		else
-			md.flag=(md.flag&~BF_RANGEMASK)|BF_LONG;
-	}
+	md.flag |= battle_range_type(src, target, skill_num, skill_lv);
 
 	switch(skill_num){
 	case HT_LANDMINE:
@@ -2510,8 +2484,8 @@ struct Damage  battle_calc_misc_attack(
 		if(!sd || (skill = pc_checkskill(sd,HT_STEELCROW)) <= 0)
 			skill=0;
 		md.damage=(sstatus->dex/10+sstatus->int_/2+skill*3+40)*2;
-		if(mflag > 1)
-			md.damage /= mflag;
+		if(mflag > 1) //Autocasted Blitz.
+			nk|=NK_SPLASHSPLIT;
 		
 		if (skill_num == HT_BLITZBEAT)
 			break;
@@ -2574,7 +2548,14 @@ struct Damage  battle_calc_misc_attack(
 		nk|=NK_IGNORE_FLEE; //Only Breaker's Misc part always hits.
 		break;
 	}
-	
+
+	if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets
+		if(mflag>0)
+			md.damage/= mflag;
+		else if(battle_config.error_log)
+			ShowError("0 enemies targeted by %s, divide per 0 avoided!\n", skill_get_name(skill_num));
+	}
+
 	damage_div_fix(md.damage, md.div_);
 	
 	if (!(nk&NK_IGNORE_FLEE))

+ 15 - 15
src/map/pc.c

@@ -5434,7 +5434,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
 	}
 	clif_updatestatus(sd,type);
 
-	return 0;
+	return 1;
 }
 
 /*==========================================
@@ -5910,7 +5910,7 @@ int pc_setreg(struct map_session_data *sd,int reg,int val)
 	for (i = 0; i < sd->reg_num; i++) {
 		if (sd->reg[i].index == reg){
 			sd->reg[i].data = val;
-			return 0;
+			return 1;
 		}
 	}
 	sd->reg_num++;
@@ -5919,7 +5919,7 @@ int pc_setreg(struct map_session_data *sd,int reg,int val)
 	sd->reg[i].index = reg;
 	sd->reg[i].data = val;
 
-	return 0;
+	return 1;
 }
 
 /*==========================================
@@ -5956,7 +5956,7 @@ int pc_setregstr(struct map_session_data *sd,int reg,char *str)
 	for(i=0;i<sd->regstr_num;i++)
 		if(sd->regstr[i].index==reg){
 			strcpy(sd->regstr[i].data,str);
-			return 0;
+			return 1;
 		}
 
 	sd->regstr_num++;
@@ -5969,7 +5969,7 @@ int pc_setregstr(struct map_session_data *sd,int reg,char *str)
 	sd->regstr[i].index = reg;
 	strcpy(sd->regstr[i].data, str);
 
-	return 0;
+	return 1;
 }
 
 int pc_readregistry(struct map_session_data *sd,const char *reg,int type) {
@@ -6099,14 +6099,14 @@ int pc_setregistry(struct map_session_data *sd,const char *reg,int val,int type)
 				break;
 			}
 		}
-		return 0;
+		return 1;
 	}
 	// change value if found
 	for(i = 0; i < *max; i++) {
 		if (strcmp(sd_reg[i].str, reg) == 0) {
 			sprintf(sd_reg[i].value, "%d", val); 
 			sd->state.reg_dirty |= 1<<(type-1);
-			return 0;
+			return 1;
 		}
 	}
 
@@ -6117,13 +6117,13 @@ int pc_setregistry(struct map_session_data *sd,const char *reg,int val,int type)
 		sprintf(sd_reg[i].value, "%d", val); 
 		(*max)++;
 		sd->state.reg_dirty |= 1<<(type-1);
-		return 0;
+		return 1;
 	}
 
 	if(battle_config.error_log)
 		ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax);
 
-	return 1;
+	return 0;
 }
 
 int pc_setregistry_str(struct map_session_data *sd,char *reg,char *val,int type) {
@@ -6134,7 +6134,7 @@ int pc_setregistry_str(struct map_session_data *sd,char *reg,char *val,int type)
 	if (reg[strlen(reg)-1] != '$') {
 		if(battle_config.error_log)
 			ShowError("pc_setregistry_str : reg %s must be string (end in '$') to use this!\n", reg);
-		return 1;
+		return 0;
 	}
 
 	switch (type) {
@@ -6159,7 +6159,7 @@ int pc_setregistry_str(struct map_session_data *sd,char *reg,char *val,int type)
 	if (*max == -1) {
 		if(battle_config.error_log)
 			ShowError("pc_setregistry_str : refusing to set %s (type %d) until vars are received.\n", reg, type);
-		return 1;
+		return 0;
 	}
 	
 	// delete reg
@@ -6175,7 +6175,7 @@ int pc_setregistry_str(struct map_session_data *sd,char *reg,char *val,int type)
 				break;
 			}
 		}
-		return 0;
+		return 1;
 	}
 	// change value if found
 	for(i = 0; i < *max; i++) {
@@ -6183,7 +6183,7 @@ int pc_setregistry_str(struct map_session_data *sd,char *reg,char *val,int type)
 			strncpy(sd_reg[i].value, val, 256);
 			sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
 			if (type!=3) intif_saveregistry(sd,type);
-			return 0;
+			return 1;
 		}
 	}
 
@@ -6195,13 +6195,13 @@ int pc_setregistry_str(struct map_session_data *sd,char *reg,char *val,int type)
 		(*max)++;
 		sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved"
 		if (type!=3) intif_saveregistry(sd,type);
-		return 0;
+		return 1;
 	}
 
 	if(battle_config.error_log)
 		ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax);
 
-	return 1;
+	return 0;
 }
 
 /*==========================================

+ 20 - 17
src/map/script.c

@@ -2039,6 +2039,7 @@ void* get_val2(struct script_state* st, int num, struct linkdb_node** ref)
 
 /*==========================================
  * Stores the value of a script variable
+ * Return value is 0 on fail, 1 on success.
  *------------------------------------------*/
 static int set_reg(struct script_state* st, struct map_session_data* sd, int num, char* name, void* value, struct linkdb_node** ref)
 {
@@ -2049,11 +2050,13 @@ static int set_reg(struct script_state* st, struct map_session_data* sd, int num
 		char* str = (char*)value;
 		switch (prefix) {
 		case '@':
-			pc_setregstr(sd, num, str); break;
+			return pc_setregstr(sd, num, str);
 		case '$':
-			mapreg_setregstr(num, str); break;
+			return mapreg_setregstr(num, str);
 		case '#':
-			(name[1] == '#') ? pc_setaccountreg2str(sd, name, str) : pc_setaccountregstr(sd, name, str); break;
+			return (name[1] == '#') ?
+				pc_setaccountreg2str(sd, name, str) :
+				pc_setaccountregstr(sd, name, str);
 		case '.': {
 			char* p;
 			struct linkdb_node** n;
@@ -2065,24 +2068,26 @@ static int set_reg(struct script_state* st, struct map_session_data* sd, int num
 			}
 			if (str[0]) linkdb_insert(n, (void*)num, aStrdup(str));
 			}
-			break;
+			return 1;
 		default:
-			pc_setglobalreg_str(sd, name, str); break;
+			return pc_setglobalreg_str(sd, name, str);
 		}
 
 	} else { // integer variable
 
 		int val = (int)value;
 		if(str_data[num&0x00ffffff].type == C_PARAM)
-			pc_setparam(sd, str_data[num&0x00ffffff].val, val);
-		else
+			return pc_setparam(sd, str_data[num&0x00ffffff].val, val);
+
 		switch (prefix) {
 		case '@':
-			pc_setreg(sd, num, val); break;
+			return pc_setreg(sd, num, val);
 		case '$':
-			mapreg_setreg(num, val); break;
+			return mapreg_setreg(num, val);
 		case '#':
-			(name[1] == '#') ? pc_setaccountreg2(sd, name, val) : pc_setaccountreg(sd, name, val); break;
+			return (name[1] == '#') ?
+				pc_setaccountreg2(sd, name, val) :
+				pc_setaccountreg(sd, name, val);
 		case '.': {
 			struct linkdb_node** n;
 			n = (ref) ? ref : (name[1] == '@') ? st->stack->var_function : &st->script->script_vars;
@@ -2091,13 +2096,11 @@ static int set_reg(struct script_state* st, struct map_session_data* sd, int num
 			else 
 				linkdb_replace(n, (void*)num, (void*)val);
 			}
-			break;
+			return 1;
 		default:
-			pc_setglobalreg(sd, name, val); break;
+			return pc_setglobalreg(sd, name, val);
 		}
 	}
-
-	return 0;
 }
 
 int set_var(struct map_session_data* sd, char* name, void* val)
@@ -3036,7 +3039,7 @@ int mapreg_setreg(int num,int val)
 	}
 
 	mapreg_dirty=1;
-	return 0;
+	return 1;
 }
 /*==========================================
  * 文字列型マップ変数の変更
@@ -3064,7 +3067,7 @@ int mapreg_setregstr(int num,const char *str)
 #endif
 		idb_remove(mapregstr_db,num);
 		mapreg_dirty=1;
-		return 0;
+		return 1;
 	}
 	p=(char *)aMallocA((strlen(str)+1)*sizeof(char));
 	strcpy(p,str);
@@ -3082,7 +3085,7 @@ int mapreg_setregstr(int num,const char *str)
 	}
 #endif
 	mapreg_dirty=1;
-	return 0;
+	return 1;
 }
 
 /*==========================================