Przeglądaj źródła

* Follow ups of:
-- 51074a0: Moved the 'group' check when make 'must' item also as random item
-- 96443cd: Leftover, fixed @allstats issue
-- 7083ecf: https://github.com/rathena/rathena/commit/7083ecf079436f8813a4c19205018ccd5be2c12a#commitcomment-4952745
-- 744195a
* Added 'get_githash' script command.
* Fixed overflowed parameters calculation will gives 32767 stat effect instead 1 (ex. overflowed LUK will gives crit 32767)

Signed-off-by: Cydh Ramdh <house.bad@gmail.com>

Cydh Ramdh 11 lat temu
rodzic
commit
12007fef7e
11 zmienionych plików z 399 dodań i 386 usunięć
  1. 1 1
      db/magicmushroom_db.txt
  2. 10 1
      doc/script_commands.txt
  3. 46 53
      src/map/atcommand.c
  4. 9 8
      src/map/chrif.c
  5. 46 44
      src/map/itemdb.c
  6. 8 8
      src/map/itemdb.h
  7. 2 2
      src/map/mob.h
  8. 152 189
      src/map/pc.c
  9. 50 56
      src/map/pc.h
  10. 18 5
      src/map/script.c
  11. 57 19
      src/map/status.c

+ 1 - 1
db/magicmushroom_db.txt

@@ -1,4 +1,4 @@
-// Magic Mushroom DB
+// Magic Mushroom Database
 // List of skills that are randomly used through Magic Mushroom status change.
 //
 // Structure of Database:

+ 10 - 1
doc/script_commands.txt

@@ -4092,7 +4092,16 @@ This command will return the SVN revision number that the server is
 currently running on.
 
     if ( get_revision() >= 15000 )
-        mes "Welcome rAthena!";
+        mes "Welcome to rAthena!";
+
+---------------------------------------
+
+*get_githash()
+
+This command will return the Git Hash that the server is currently running on.
+
+	set .@gitHash$,get_githash();
+	mes "Welcome to rAthena! Git Hash: "+.@gitHash$;
 
 ---------------------------------------
 \\

+ 46 - 53
src/map/atcommand.c

@@ -2410,10 +2410,10 @@ ACMD_FUNC(zeny)
  *------------------------------------------*/
 ACMD_FUNC(param)
 {
-	int i, value = 0, new_value;
+	uint8 i;
+	int value = 0;
 	const char* param[] = { "str", "agi", "vit", "int", "dex", "luk" };
-	short* status[6];
-	short max_status[6];
+	short new_value, *status[6], max_status[6];
  	//we don't use direct initialization because it isn't part of the c standard.
 	nullpo_retr(-1, sd);
 
@@ -2438,30 +2438,23 @@ ACMD_FUNC(param)
 	status[4] = &sd->status.dex;
 	status[5] = &sd->status.luk;
 
-	if( battle_config.atcommand_max_stat_bypass ){
-		max_status[0] = SHRT_MAX;
-		max_status[1] = SHRT_MAX;
-		max_status[2] = SHRT_MAX;
-		max_status[3] = SHRT_MAX;
-		max_status[4] = SHRT_MAX;
-		max_status[5] = SHRT_MAX;
-	}
+	if( battle_config.atcommand_max_stat_bypass )
+		max_status[0] = max_status[1] = max_status[2] = max_status[3] = max_status[4] = max_status[5] = SHRT_MAX;
 	else {
-		max_status[0] = pc_maxparameter(sd->class_,sd->status.sex,PARAM_STR);
-		max_status[1] = pc_maxparameter(sd->class_,sd->status.sex,PARAM_AGI);
-		max_status[2] = pc_maxparameter(sd->class_,sd->status.sex,PARAM_VIT);
-		max_status[3] = pc_maxparameter(sd->class_,sd->status.sex,PARAM_INT);
-		max_status[4] = pc_maxparameter(sd->class_,sd->status.sex,PARAM_DEX);
-		max_status[5] = pc_maxparameter(sd->class_,sd->status.sex,PARAM_LUK);
+		max_status[0] = pc_maxparameter(sd,PARAM_STR);
+		max_status[1] = pc_maxparameter(sd,PARAM_AGI);
+		max_status[2] = pc_maxparameter(sd,PARAM_VIT);
+		max_status[3] = pc_maxparameter(sd,PARAM_INT);
+		max_status[4] = pc_maxparameter(sd,PARAM_DEX);
+		max_status[5] = pc_maxparameter(sd,PARAM_LUK);
 	}
 
-	if(value < 0 && *status[i] <= -value) {
-		new_value = 1;
-	} else if(max_status[i] - *status[i] < value) {
+	if(value > 0  && *status[i] + value >= max_status[i])
 		new_value = max_status[i];
-	} else {
+	else if(value < 0 && *status[i] <= -value)
+		new_value = 1;
+	else
 		new_value = *status[i] + value;
-	}
 
 	if (new_value != *status[i]) {
 		*status[i] = new_value;
@@ -2485,10 +2478,9 @@ ACMD_FUNC(param)
  *------------------------------------------*/
 ACMD_FUNC(stat_all)
 {
-	int index, count, value, new_value;
-	short* status[PARAM_MAX];
-	short max_status[PARAM_MAX];
-	short values[PARAM_MAX];
+	int value = 0;
+	uint8 count, i;
+	short *status[PARAM_MAX], max_status[PARAM_MAX];
  	//we don't use direct initialization because it isn't part of the c standard.
 	nullpo_retr(-1, sd);
 
@@ -2500,39 +2492,40 @@ ACMD_FUNC(stat_all)
 	status[5] = &sd->status.luk;
 
 	if (!message || !*message || sscanf(message, "%d", &value) < 1 || value == 0) {
-		uint8 i;
-		for (i  = 0; i < PARAM_MAX; i++) {
-			values[i] = pc_maxparameter(sd->class_,sd->status.sex,(enum e_params)i);
-			max_status[i] = pc_maxparameter(sd->class_,sd->status.sex,(enum e_params)i);
-		}
+		max_status[0] = pc_maxparameter(sd,PARAM_STR);
+		max_status[1] = pc_maxparameter(sd,PARAM_AGI);
+		max_status[2] = pc_maxparameter(sd,PARAM_VIT);
+		max_status[3] = pc_maxparameter(sd,PARAM_INT);
+		max_status[4] = pc_maxparameter(sd,PARAM_DEX);
+		max_status[5] = pc_maxparameter(sd,PARAM_LUK);
+		value = SHRT_MAX;
 	} else {
-		uint8 i;
-		for (i  = 0; i < PARAM_MAX; i++)
-			values[i] = value;
-
-		if( battle_config.atcommand_max_stat_bypass ) {
-			for (i  = 0; i < PARAM_MAX; i++)
-				max_status[i] = SHRT_MAX;
-		}
+		if( battle_config.atcommand_max_stat_bypass )
+			max_status[0] = max_status[1] = max_status[2] = max_status[3] = max_status[4] = max_status[5] = SHRT_MAX;
 		else {
-			for (i  = 0; i < PARAM_MAX; i++)
-				max_status[i] = pc_maxparameter(sd->class_,sd->status.sex,(enum e_params)i);
+			max_status[0] = pc_maxparameter(sd,PARAM_STR);
+			max_status[1] = pc_maxparameter(sd,PARAM_AGI);
+			max_status[2] = pc_maxparameter(sd,PARAM_VIT);
+			max_status[3] = pc_maxparameter(sd,PARAM_INT);
+			max_status[4] = pc_maxparameter(sd,PARAM_DEX);
+			max_status[5] = pc_maxparameter(sd,PARAM_LUK);
 		}
 	}
 	
 	count = 0;
-	for (index = 0; index < ARRAYLENGTH(status); index++) {
-		if (values[index] > 0 && *status[index] > max_status[index] - values[index])
-			new_value = max_status[index];
-		else if (values[index] < 0 && *status[index] <= -values[index])
+	for (i = 0; i < ARRAYLENGTH(status); i++) {
+		short new_value;
+		if (value > 0 && *status[i] + value >= max_status[i])
+			new_value = max_status[i];
+		else if (value < 0 && *status[i] <= -value)
 			new_value = 1;
 		else
-			new_value = *status[index] +values[index];
+			new_value = *status[i] + value;
 
-		if (new_value != (int)*status[index]) {
-			*status[index] = new_value;
-			clif_updatestatus(sd, SP_STR + index);
-			clif_updatestatus(sd, SP_USTR + index);
+		if (new_value != *status[i]) {
+			*status[i] = new_value;
+			clif_updatestatus(sd, SP_STR + i);
+			clif_updatestatus(sd, SP_USTR + i);
 			count++;
 		}
 	}
@@ -5580,7 +5573,7 @@ ACMD_FUNC(marry)
 		return -1;
 	}
 
-	if (pc_marriage(sd, pl_sd) == 0) {
+	if (pc_marriage(sd, pl_sd)) {
 		clif_displaymessage(fd, msg_txt(sd,1173)); // They are married... wish them well.
 		clif_wedding_effect(&pl_sd->bl); //wedding effect and music [Lupus]
 		getring(sd); // Auto-give named rings (Aru)
@@ -5600,7 +5593,7 @@ ACMD_FUNC(divorce)
 {
 	nullpo_retr(-1, sd);
 
-	if (pc_divorce(sd) != 0) {
+	if (!pc_divorce(sd)) {
 		sprintf(atcmd_output, msg_txt(sd,1175), sd->status.name); // '%s' is not married.
 		clif_displaymessage(fd, atcmd_output);
 		return -1;
@@ -8955,7 +8948,7 @@ ACMD_FUNC(cart) {
 		MC_CART_MDFY(1);
 	}
 
-	if( pc_setcart(sd, val) ) {
+	if( !pc_setcart(sd, val) ) {
 		if( need_skill ) {
 			MC_CART_MDFY(0);
 		}

+ 9 - 8
src/map/chrif.c

@@ -1779,7 +1779,8 @@ int chrif_bsdata_request(int char_id) {
 * @param sd
 */
 int chrif_save_bsdata(struct map_session_data *sd) {
-	int i, count=0;
+	int i;
+	uint8 count = 0;
 	unsigned int tick;
 	struct bonus_script_data bs;
 	const struct TimerData *timer;
@@ -1801,7 +1802,7 @@ int chrif_save_bsdata(struct map_session_data *sd) {
 	pc_bonus_script_clear(sd,i);
 
 	for (i = 0; i < MAX_PC_BONUS_SCRIPT; i++) {
-		if (!(&sd->bonus_script[i]) || !sd->bonus_script[i].script || strlen(sd->bonus_script[i].script_str) == 0)
+		if (!(&sd->bonus_script[i]) || !sd->bonus_script[i].script || sd->bonus_script[i].script_str == '\0')
 			continue;
 
 		timer = get_timer(sd->bonus_script[i].tid);
@@ -1835,9 +1836,9 @@ int chrif_save_bsdata(struct map_session_data *sd) {
 */
 int chrif_load_bsdata(int fd) {
 	struct map_session_data *sd;
-	struct bonus_script_data *bs;
 	int cid, count;
-	uint8 i, count_ = 0;
+	uint8 i;
+	bool calc = false;
 
 	cid = RFIFOL(fd,4);
 	sd = map_charid2sd(cid);
@@ -1856,9 +1857,9 @@ int chrif_load_bsdata(int fd) {
 
 	for (i = 0; i < count; i++) {
 		struct script_code *script;
-		bs = (struct bonus_script_data*)RFIFOP(fd,10 + i*sizeof(struct bonus_script_data));
+		struct bonus_script_data *bs = (struct bonus_script_data*)RFIFOP(fd,10 + i*sizeof(struct bonus_script_data));
 
-		if (!(script = parse_script(bs->script,"chrif_load_bsdata",1,1)))
+		if (bs->script == '\0' || !(script = parse_script(bs->script,"chrif_load_bsdata",1,1)))
 			continue;
 
 		memcpy(sd->bonus_script[i].script_str,bs->script,strlen(bs->script));
@@ -1869,9 +1870,9 @@ int chrif_load_bsdata(int fd) {
 		sd->bonus_script[i].icon = bs->icon;
 		if (bs->icon != SI_BLANK) //Gives status icon if exist
 			clif_status_change(&sd->bl,sd->bonus_script[i].icon,1,bs->tick,1,0,0);
-		count_++;
+		calc = true;
 	}
-	if (count_)
+	if (calc)
 		status_calc_pc(sd,false);
 	return 0;
 }

+ 46 - 44
src/map/itemdb.c

@@ -148,7 +148,7 @@ int itemdb_searchname_array(struct item_data** data, int size, const char *str)
 * @param sub_group: Default is 1
 * @return nameid
 */
-int itemdb_searchrandomid(int group_id, uint8 sub_group)
+unsigned short itemdb_searchrandomid(int group_id, uint8 sub_group)
 {
 	if (sub_group)
 		sub_group -= 1;
@@ -197,10 +197,9 @@ uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, uint16 n
 * Gives item(s) to the player based on item group
 * @param sd: Player that obtains item from item group
 * @param group_id: The group ID of item that obtained by player
-* @param nameid_from: The item that trigger this item group
 * @param *group: struct s_item_group from itemgroup_db[group_id].random[idx] or itemgroup_db[group_id].must[sub_group][idx]
 */
-void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, uint16 group_id, uint16 nameid_from, struct s_item_group *group) {
+static void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, uint16 group_id, struct s_item_group *group) {
 	uint16 i;
 	struct item tmp;
 
@@ -226,7 +225,7 @@ void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, uint16 group_id, u
 			clif_additem(sd,0,0,flag);
 		else if (!flag && group->isAnnounced) { ///TODO: Move this broadcast to proper behavior (it should on at different packet)
 			char output[CHAT_SIZE_MAX];
-			sprintf(output,msg_txt(NULL,717),sd->status.name,itemdb_jname(group->nameid),itemdb_jname(nameid_from));
+			sprintf(output,msg_txt(NULL,717),sd->status.name,itemdb_jname(group->nameid),itemdb_jname(sd->itemid));
 			clif_broadcast(&sd->bl,output,strlen(output),0,ALL_CLIENT);
 			//clif_broadcast_obtain_special_item();
 		}
@@ -239,10 +238,9 @@ void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, uint16 group_id, u
 * Find item(s) that will be obtained by player based on Item Group
 * @param group_id: The group ID that will be gained by player
 * @param nameid: The item that trigger this item group
-* @param sd: Player that obtains item from item group
 * @return val: 0:success, 1:no sd, 2:invalid item group
 */
-uint8 itemdb_pc_get_itemgroup(uint16 group_id, uint16 nameid, struct map_session_data *sd) {
+char itemdb_pc_get_itemgroup(uint16 group_id, struct map_session_data *sd) {
 	uint16 i = 0;
 
 	nullpo_retr(1,sd);
@@ -255,7 +253,7 @@ uint8 itemdb_pc_get_itemgroup(uint16 group_id, uint16 nameid, struct map_session
 	//Get the 'must' item(s)
 	for (i = 0; i < itemgroup_db[group_id].must_qty; i++) {
 		if (&itemgroup_db[group_id].must[i] && itemdb_exists(itemgroup_db[group_id].must[i].nameid))
-			itemdb_pc_get_itemgroup_sub(sd,group_id,nameid,&itemgroup_db[group_id].must[i]);
+			itemdb_pc_get_itemgroup_sub(sd,group_id,&itemgroup_db[group_id].must[i]);
 	}
 
 	//Get the 'random' item each random group
@@ -269,7 +267,7 @@ uint8 itemdb_pc_get_itemgroup(uint16 group_id, uint16 nameid, struct map_session
 			continue;
 		}
 		if (itemdb_exists(itemgroup_db[group_id].random[i][rand].nameid))
-			itemdb_pc_get_itemgroup_sub(sd,group_id,nameid,&itemgroup_db[group_id].random[i][rand]);
+			itemdb_pc_get_itemgroup_sub(sd,group_id,&itemgroup_db[group_id].random[i][rand]);
 	}
 
 	return 0;
@@ -307,7 +305,7 @@ struct item_data* itemdb_exists(int nameid)
 
 /// Returns human readable name for given item type.
 /// @param type Type id to retrieve name for ( IT_* ).
-const char* itemdb_typename(int type)
+const char* itemdb_typename(enum item_types type)
 {
 	switch(type)
 	{
@@ -469,7 +467,7 @@ struct item_data* itemdb_search(int nameid)
 /*==========================================
  * Returns if given item is a player-equippable piece.
  *------------------------------------------*/
-int itemdb_isequip(int nameid)
+bool itemdb_isequip(int nameid)
 {
 	int type=itemdb_type(nameid);
 	switch (type) {
@@ -477,16 +475,16 @@ int itemdb_isequip(int nameid)
 		case IT_ARMOR:
 		case IT_AMMO:
 		case IT_SHADOWGEAR:
-			return 1;
+			return true;
 		default:
-			return 0;
+			return false;
 	}
 }
 
 /*==========================================
  * Alternate version of itemdb_isequip
  *------------------------------------------*/
-int itemdb_isequip2(struct item_data *data)
+bool itemdb_isequip2(struct item_data *data)
 {
 	nullpo_ret(data);
 	switch(data->type) {
@@ -494,34 +492,34 @@ int itemdb_isequip2(struct item_data *data)
 		case IT_ARMOR:
 		case IT_AMMO:
 		case IT_SHADOWGEAR:
-			return 1;
+			return true;
 		default:
-			return 0;
+			return false;
 	}
 }
 
 /*==========================================
  * Returns if given item's type is stackable.
  *------------------------------------------*/
-int itemdb_isstackable(int nameid)
+bool itemdb_isstackable(uint16 nameid)
 {
-  int type=itemdb_type(nameid);
+  uint8 type = itemdb_type(nameid);
   switch(type) {
 	  case IT_WEAPON:
 	  case IT_ARMOR:
 	  case IT_PETEGG:
 	  case IT_PETARMOR:
 	  case IT_SHADOWGEAR:
-		  return 0;
+		  return false;
 	  default:
-		  return 1;
+		  return true;
   }
 }
 
 /*==========================================
  * Alternate version of itemdb_isstackable
  *------------------------------------------*/
-int itemdb_isstackable2(struct item_data *data)
+bool itemdb_isstackable2(struct item_data *data)
 {
   nullpo_ret(data);
   switch(data->type) {
@@ -530,9 +528,9 @@ int itemdb_isstackable2(struct item_data *data)
 	  case IT_PETEGG:
 	  case IT_PETARMOR:
 	  case IT_SHADOWGEAR:
-		  return 0;
+		  return false;
 	  default:
-		  return 1;
+		  return true;
   }
 }
 
@@ -576,29 +574,29 @@ int itemdb_canauction_sub(struct item_data* item, int gmlv, int unused) {
 	return (item && (!(item->flag.trade_restriction&256) || gmlv >= item->gm_lv_trade_override));
 }
 
-int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int))
+bool itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int))
 {
 	struct item_data* item_data = itemdb_search(item->nameid);
 	int i;
 
 	if (!func(item_data, gmlv, gmlv2))
-		return 0;
+		return false;
 
 	if(item_data->slot == 0 || itemdb_isspecial(item->card[0]))
-		return 1;
+		return true;
 
 	for(i = 0; i < item_data->slot; i++) {
 		if (!item->card[i]) continue;
 		if (!func(itemdb_search(item->card[i]), gmlv, gmlv2))
-			return 0;
+			return false;
 	}
-	return 1;
+	return true;
 }
 
 /*==========================================
  *	Specifies if item-type should drop unidentified.
  *------------------------------------------*/
-int itemdb_isidentified(int nameid)
+char itemdb_isidentified(int nameid)
 {
 	int type=itemdb_type(nameid);
 	switch (type) {
@@ -693,10 +691,10 @@ static void itemdb_read_itemgroup_sub(const char* filename)
 		}
 
 		//Checking group_id
-		if (!atoi(str[0])) //Try reads group id by const
-			script_get_constant(trim(str[0]),&group_id);
-		else
+		if (atoi(str[0]))
 			group_id = atoi(str[0]);
+		else //Try reads group id by const
+			script_get_constant(trim(str[0]),&group_id);
 		if (!group_id || group_id >= MAX_ITEMGROUP) {
 			ShowWarning("itemdb_read_itemgroup: Invalid group id '%s' in %s:%d\n", str[0], filename, ln);
 			continue;
@@ -709,12 +707,12 @@ static void itemdb_read_itemgroup_sub(const char* filename)
 		}
 
 		//Checking item
-		if (!atoi(str[1]) && itemdb_searchname(str[1])) {
+		if ((nameid = atoi(str[1])) && itemdb_exists(nameid))
+			found = true;
+		else if (itemdb_searchname(str[1])) {
 			found = true;
 			nameid = itemdb_searchname(str[1])->nameid;
 		}
-		else if ((nameid = atoi(str[1])) && itemdb_exists(nameid))
-			found = true;
 		if (!found) {
 			ShowWarning("itemdb_read_itemgroup: Non-existant item '%s' in %s:%d\n", str[1], filename, ln);
 			continue;
@@ -741,10 +739,16 @@ static void itemdb_read_itemgroup_sub(const char* filename)
 			itemgroup_db[group_id].must[idx].isNamed = named;
 			itemgroup_db[group_id].must[idx].bound = bound;
 			itemgroup_db[group_id].must_qty++;
+			group = 1;
 		}
+		prob = max(prob,0);
+		if (!prob) {
+			entries++;
+			continue;
+		}
+		group -= 1;
 		for (j = 0; j < prob; j++) {
 			uint16 idx;
-			if (group > 0) group -= 1;
 			idx = itemgroup_db[group_id].random_qty[group];
 			itemgroup_db[group_id].random[group][idx].nameid = nameid;
 			itemgroup_db[group_id].random[group][idx].amount = amt;
@@ -950,7 +954,7 @@ static bool itemdb_read_nouse(char* fields[], int columns, int current)
 /**
  * @return: amount of retrieved entries.
  **/
-int itemdb_combo_split_atoi (char *str, int *val) {
+static int itemdb_combo_split_atoi (char *str, int *val) {
 	int i;
 
 	for (i=0; i<MAX_ITEMS_PER_COMBO; i++) {
@@ -972,7 +976,7 @@ int itemdb_combo_split_atoi (char *str, int *val) {
 /**
  * <combo{:combo{:combo:{..}}}>,<{ script }>
  **/
-void itemdb_read_combos() {
+static void itemdb_read_combos() {
 	uint32 lines = 0, count = 0;
 	char line[1024];
 
@@ -1115,7 +1119,7 @@ void itemdb_read_combos() {
 /*======================================
  * Applies gender restrictions according to settings. [Skotlex]
  *======================================*/
-static int itemdb_gendercheck(struct item_data *id)
+static char itemdb_gendercheck(struct item_data *id)
 {
 	if (id->nameid == WEDDING_RING_M) //Grom Ring
 		return 1;
@@ -1133,7 +1137,7 @@ static int itemdb_gendercheck(struct item_data *id)
  * For backwards compatibility, in Renewal mode, MATK from weapons comes from the atk slot
  * We use a ':' delimiter which, if not found, assumes the weapon does not provide any matk.
  **/
-void itemdb_re_split_atoi(char *str, int *atk, int *matk) {
+static void itemdb_re_split_atoi(char *str, int *atk, int *matk) {
 	int i, val[2];
 
 	for (i=0; i<2; i++) {
@@ -1477,7 +1481,7 @@ static int itemdb_read_sqldb(void) {
 * 2 set new value bypassing anything
 * 3/other return last value
 *------------------------------------------*/
-uint64 itemdb_unique_id(int8 flag, int64 value) {
+static uint64 itemdb_unique_id(int8 flag, int64 value) {
 	static uint64 item_uid = 0;
 
 	if(flag)
@@ -1493,7 +1497,7 @@ uint64 itemdb_unique_id(int8 flag, int64 value) {
 
 	return ++item_uid;
 }
-int itemdb_uid_load(){
+static void itemdb_uid_load(){
 
 	char * uid;
 	if (SQL_ERROR == Sql_Query(mmysql_handle, "SELECT `value` FROM `interreg` WHERE `varname`='unique_id'"))
@@ -1503,14 +1507,12 @@ int itemdb_uid_load(){
 	{
 		ShowError("itemdb_uid_load: Unable to fetch unique_id data\n");
 		Sql_FreeResult(mmysql_handle);
-		return -1;
+		return;
 	}
 
 	Sql_GetData(mmysql_handle, 0, &uid, NULL);
 	itemdb_unique_id(1, (uint64)strtoull(uid, NULL, 10));
 	Sql_FreeResult(mmysql_handle);
-
-	return 0;
 }
 
 /*==========================================

+ 8 - 8
src/map/itemdb.h

@@ -223,7 +223,7 @@ struct item_data* itemdb_exists(int nameid);
 const char* itemdb_typename(int type);
 
 int itemdb_group_bonus(struct map_session_data* sd, int itemid);
-int itemdb_searchrandomid(int group_id, uint8 sub_group);
+unsigned short itemdb_searchrandomid(int group_id, uint8 sub_group);
 
 #define itemdb_value_buy(n) itemdb_search(n)->value_buy
 #define itemdb_value_sell(n) itemdb_search(n)->value_sell
@@ -238,7 +238,7 @@ int itemdb_canstore_sub(struct item_data*, int, int);
 int itemdb_canguildstore_sub(struct item_data*, int, int);
 int itemdb_canmail_sub(struct item_data*, int, int);
 int itemdb_canauction_sub(struct item_data*, int, int);
-int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int));
+bool itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int));
 #define itemdb_isdropable(item, gmlv) itemdb_isrestricted(item, gmlv, 0, itemdb_isdropable_sub)
 #define itemdb_cantrade(item, gmlv, gmlv2) itemdb_isrestricted(item, gmlv, gmlv2, itemdb_cantrade_sub)
 #define itemdb_canpartnertrade(item, gmlv, gmlv2) itemdb_isrestricted(item, gmlv, gmlv2, itemdb_canpartnertrade_sub)
@@ -249,15 +249,15 @@ int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(stru
 #define itemdb_canmail(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canmail_sub)
 #define itemdb_canauction(item, gmlv) itemdb_isrestricted(item , gmlv, 0, itemdb_canauction_sub)
 
-int itemdb_isequip(int);
-int itemdb_isequip2(struct item_data *);
-int itemdb_isidentified(int);
-int itemdb_isstackable(int);
-int itemdb_isstackable2(struct item_data *);
+bool itemdb_isequip(int);
+bool itemdb_isequip2(struct item_data *);
+char itemdb_isidentified(int);
+bool itemdb_isstackable(uint16 nameid);
+bool itemdb_isstackable2(struct item_data *data);
 uint64 itemdb_unique_id(int8 flag, int64 value); // Unique Item ID
 bool itemdb_isNoEquip(struct item_data *id, uint16 m);
 
-uint8 itemdb_pc_get_itemgroup(uint16 group_id, uint16 nameid, struct map_session_data *sd);
+char itemdb_pc_get_itemgroup(uint16 group_id, struct map_session_data *sd);
 uint16 itemdb_get_randgroupitem_count(uint16 group_id, uint8 sub_group, uint16 nameid);
 
 DBMap * itemdb_get_combodb();

+ 2 - 2
src/map/mob.h

@@ -139,8 +139,8 @@ struct mob_data {
 		int provoke_flag; // Celest
 	} state;
 	struct guardian_data* guardian_data;
-	struct {
-		int id;
+	struct s_dmglog {
+		int id; //char id
 		unsigned int dmg;
 		unsigned int flag : 2; //0: Normal. 1: Homunc exp. 2: Pet exp
 	} dmglog[DAMAGELOG_SIZE];

Plik diff jest za duży
+ 152 - 189
src/map/pc.c


+ 50 - 56
src/map/pc.h

@@ -128,10 +128,10 @@ struct skill_cooldown_entry {
 };
 
 #ifdef VIP_ENABLE
-	struct vip_info {
-		unsigned int enabled : 1;
-		time_t time;
-	};
+struct vip_info {
+	unsigned int enabled : 1;
+	time_t time;
+};
 #endif
 
 enum npc_timeout_type {
@@ -150,7 +150,7 @@ struct map_session_data {
 	struct regen_data_sub sregen, ssregen;
 	//NOTE: When deciding to add a flag to state or special_state, take into consideration that state is preserved in
 	//status_calc_pc, while special_state is recalculated in each call. [Skotlex]
-	struct {
+	struct s_state {
 		unsigned int active : 1; //Marks active player (not active is logging in/out, or changing map servers)
 		unsigned int menu_or_input : 1;// if a script is waiting for feedback from the player
 		unsigned int dead_sit : 2;
@@ -242,12 +242,12 @@ struct map_session_data {
 	unsigned int chatID;
 	time_t idletime;
 
-	struct{
+	struct s_progressbar {
 		int npc_id;
 		unsigned int timeout;
 	} progressbar; //Progress Bar [Inkfish]
 
-	struct{
+	struct s_ignore {
 		char name[NAME_LENGTH];
 	} ignore[MAX_IGNORE_LIST];
 
@@ -274,7 +274,7 @@ struct map_session_data {
 	unsigned int cansendmail_tick; // [Mail System Flood Protection]
 	unsigned int ks_floodprotect_tick; // [Kill Steal Protection]
 
-	struct {
+	struct s_item_delay {
 		short nameid;
 		unsigned int tick;
 	} item_delay[MAX_ITEMDELAYS]; // [Paradox924X]
@@ -316,11 +316,11 @@ struct map_session_data {
 	struct s_addeffect addeff[MAX_PC_BONUS], addeff2[MAX_PC_BONUS];
 	struct s_addeffectonskill addeff3[MAX_PC_BONUS];
 
-	struct { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills.
+	struct s_skill_bonus { //skillatk raises bonus dmg% of skills, skillheal increases heal%, skillblown increases bonus blewcount for some skills.
 		unsigned short id;
 		short val;
 	} skillatk[MAX_PC_BONUS], skillusesprate[MAX_PC_BONUS], skillusesp[MAX_PC_BONUS], skillheal[5], skillheal2[5], skillblown[MAX_PC_BONUS], skillcast[MAX_PC_BONUS], skillcooldown[MAX_PC_BONUS], skillfixcast[MAX_PC_BONUS], skillvarcast[MAX_PC_BONUS], skillfixcastrate[MAX_PC_BONUS];
-	struct {
+	struct s_regen {
 		short value;
 		int rate;
 		int tick;
@@ -329,11 +329,11 @@ struct map_session_data {
 		short class_, rate;
 	}	add_def[MAX_PC_BONUS], add_mdef[MAX_PC_BONUS], add_mdmg[MAX_PC_BONUS];
 	struct s_add_drop add_drop[MAX_PC_BONUS];
-	struct {
+	struct s_healrate {
 		int nameid;
 		int rate;
 	} itemhealrate[MAX_PC_BONUS];
-	struct {
+	struct s_subele2 {
 		short flag, rate;
 		unsigned char ele;
 	} subele2[MAX_PC_BONUS];
@@ -346,7 +346,7 @@ struct map_session_data {
 	struct s_autobonus autobonus[MAX_PC_BONUS], autobonus2[MAX_PC_BONUS], autobonus3[MAX_PC_BONUS]; //Auto script on attack, when attacked, on skill usage
 	// manually zeroed structures end here.
 	// zeroed vars start here.
-	struct {
+	struct s_bonus {
 		int hp, sp;
 		int atk_rate;
 		int arrow_atk,arrow_ele,arrow_cri,arrow_hit;
@@ -415,8 +415,8 @@ struct map_session_data {
 	struct script_regstr *regstr;
 
 	int trade_partner;
-	struct {
-		struct {
+	struct s_deal {
+		struct s_item {
 			short index, amount;
 		} item[10];
 		int zeny, weight;
@@ -450,10 +450,10 @@ struct map_session_data {
 	struct mercenary_data *md;
 	struct elemental_data *ed;
 
-	struct{
+	struct s_hate_mob {
 		int  m; //-1 - none, other: map index corresponding to map name.
 		unsigned short index; //map index
-	}feel_map[3];// 0 - Sun; 1 - Moon; 2 - Stars
+	} feel_map[3];// 0 - Sun; 1 - Moon; 2 - Stars
 	short hate_mob[3];
 
 	int pvp_timer;
@@ -479,12 +479,12 @@ struct map_session_data {
 	int rental_timer;
 
 	// Auction System [Zephyrus]
-	struct {
+	struct s_auction{
 		int index, amount;
 	} auction;
 
 	// Mail System [Zephyrus]
-	struct {
+	struct s_mail {
 		short nameid;
 		int index, amount, zeny;
 		struct mail_data inbox;
@@ -524,7 +524,7 @@ struct map_session_data {
 	enum npc_timeout_type npc_idle_type;
 #endif
 
-	struct {
+	struct s_combos {
 		struct script_code **bonus;/* the script */
 		unsigned short *id;/* array of combo ids */
 		unsigned char count;
@@ -549,9 +549,7 @@ struct map_session_data {
 	const char* delunit_prevfile;
 	int delunit_prevline;
 
-	struct {
-		int id;
-	} dmglog[DAMAGELOG_SIZE_PC];
+	uint16 dmglog[DAMAGELOG_SIZE_PC]; ///target ids
 
 	struct s_crimson_marker { ///Store target that marked by Crimson Marker [Cydh]
 		int target[MAX_SKILL_CRIMSON_MARKER]; //Target id storage
@@ -724,7 +722,7 @@ enum e_params {
 	PARAM_LUK,
 	PARAM_MAX
 };
-short pc_maxparameter(int class_, int sex, enum e_params param);
+short pc_maxparameter(struct map_session_data *sd, enum e_params param);
 
 /**
  * Ranger
@@ -813,19 +811,18 @@ int pc_equippoint(struct map_session_data *sd,int n);
 int pc_setinventorydata(struct map_session_data *sd);
 
 int pc_checkskill(struct map_session_data *sd,uint16 skill_id);
-int pc_checkallowskill(struct map_session_data *sd);
-int pc_checkequip(struct map_session_data *sd,int pos);
-int pc_checkequip2(struct map_session_data *sd,int nameid,int min, int max);
+short pc_checkequip(struct map_session_data *sd,int pos);
+bool pc_checkequip2(struct map_session_data *sd,int nameid,int min, int max);
 
 int pc_calc_skilltree(struct map_session_data *sd);
 int pc_calc_skilltree_normalize_job(struct map_session_data *sd);
-int pc_clean_skilltree(struct map_session_data *sd);
+void pc_clean_skilltree(struct map_session_data *sd);
 
 #define pc_checkoverhp(sd) ((sd)->battle_status.hp == (sd)->battle_status.max_hp)
 #define pc_checkoversp(sd) ((sd)->battle_status.sp == (sd)->battle_status.max_sp)
 
 int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype);
-int pc_setsavepoint(struct map_session_data*,short,int,int);
+void pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y);
 int pc_randomwarp(struct map_session_data *sd,clr_type type);
 int pc_memo(struct map_session_data* sd, int pos);
 
@@ -902,10 +899,10 @@ int pc_resetstate(struct map_session_data*);
 int pc_resetskill(struct map_session_data*, int);
 int pc_resetfeel(struct map_session_data*);
 int pc_resethate(struct map_session_data*);
-int pc_equipitem(struct map_session_data*,int,int);
-int pc_unequipitem(struct map_session_data*,int,int);
-int pc_checkitem(struct map_session_data*);
-int pc_check_available_item(struct map_session_data *sd);
+bool pc_equipitem(struct map_session_data*,int,int);
+bool pc_unequipitem(struct map_session_data*,int,int);
+void pc_checkitem(struct map_session_data*);
+void pc_check_available_item(struct map_session_data *sd);
 int pc_useitem(struct map_session_data*,int);
 
 int pc_skillatk_bonus(struct map_session_data *sd, uint16 skill_id);
@@ -919,20 +916,20 @@ void pc_heal(struct map_session_data *sd,unsigned int hp,unsigned int sp, int ty
 int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp);
 int pc_percentheal(struct map_session_data *sd,int,int);
 int pc_jobchange(struct map_session_data *,int, int);
-int pc_setoption(struct map_session_data *,int);
-int pc_setcart(struct map_session_data* sd, int type);
-int pc_setfalcon(struct map_session_data* sd, int flag);
-int pc_setriding(struct map_session_data* sd, int flag);
-int pc_setmadogear(struct map_session_data* sd, int flag);
-int pc_changelook(struct map_session_data *,int,int);
-int pc_equiplookall(struct map_session_data *sd);
+void pc_setoption(struct map_session_data *,int);
+bool pc_setcart(struct map_session_data* sd, int type);
+void pc_setfalcon(struct map_session_data* sd, int flag);
+void pc_setriding(struct map_session_data* sd, int flag);
+void pc_setmadogear(struct map_session_data* sd, int flag);
+void pc_changelook(struct map_session_data *,int,int);
+void pc_equiplookall(struct map_session_data *sd);
 
 int pc_readparam(struct map_session_data*,int);
-int pc_setparam(struct map_session_data*,int,int);
+bool pc_setparam(struct map_session_data*,int,int);
 int pc_readreg(struct map_session_data*,int);
-int pc_setreg(struct map_session_data*,int,int);
+bool pc_setreg(struct map_session_data*,int,int);
 char *pc_readregstr(struct map_session_data *sd,int reg);
-int pc_setregstr(struct map_session_data *sd,int reg,const char *str);
+bool pc_setregstr(struct map_session_data *sd,int reg,const char *str);
 
 #define pc_readglobalreg(sd,reg) pc_readregistry(sd,reg,3)
 #define pc_setglobalreg(sd,reg,val) pc_setregistry(sd,reg,val,3)
@@ -947,21 +944,21 @@ int pc_setregstr(struct map_session_data *sd,int reg,const char *str);
 #define pc_readaccountreg2str(sd,reg) pc_readregistry_str(sd,reg,1)
 #define pc_setaccountreg2str(sd,reg,val) pc_setregistry_str(sd,reg,val,1)
 int pc_readregistry(struct map_session_data*,const char*,int);
-int pc_setregistry(struct map_session_data*,const char*,int,int);
+bool pc_setregistry(struct map_session_data*,const char*,int,int);
 char *pc_readregistry_str(struct map_session_data*,const char*,int);
-int pc_setregistry_str(struct map_session_data*,const char*,const char*,int);
+bool pc_setregistry_str(struct map_session_data*,const char*,const char*,int);
 
-int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name);
-int pc_deleventtimer(struct map_session_data *sd,const char *name);
-int pc_cleareventtimer(struct map_session_data *sd);
-int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick);
+bool pc_addeventtimer(struct map_session_data *sd,int tick,const char *name);
+bool pc_deleventtimer(struct map_session_data *sd,const char *name);
+void pc_cleareventtimer(struct map_session_data *sd);
+void pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick);
 
 int pc_calc_pvprank(struct map_session_data *sd);
 int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr_t data);
 
 int pc_ismarried(struct map_session_data *sd);
-int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd);
-int pc_divorce(struct map_session_data *sd);
+bool pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd);
+bool pc_divorce(struct map_session_data *sd);
 struct map_session_data *pc_get_partner(struct map_session_data *sd);
 struct map_session_data *pc_get_father(struct map_session_data *sd);
 struct map_session_data *pc_get_mother(struct map_session_data *sd);
@@ -971,7 +968,7 @@ void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick);
 void pc_regen (struct map_session_data *sd, unsigned int diff_tick);
 
 void pc_setstand(struct map_session_data *sd);
-int pc_candrop(struct map_session_data *sd,struct item *item);
+bool pc_candrop(struct map_session_data *sd,struct item *item);
 
 int pc_jobid2mapid(unsigned short b_class);	// Skotlex
 int pc_mapid2jobid(unsigned short class_, int sex);	// Skotlex
@@ -1006,7 +1003,7 @@ int pc_addspiritball(struct map_session_data *sd,int,int);
 int pc_delspiritball(struct map_session_data *sd,int,int);
 void pc_addfame(struct map_session_data *sd,int count);
 unsigned char pc_famerank(int char_id, int job);
-int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl);
+bool pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl);
 
 extern struct fame_list smith_fame_list[MAX_FAME_LIST];
 extern struct fame_list chemist_fame_list[MAX_FAME_LIST];
@@ -1070,9 +1067,6 @@ void pc_bonus_script_clear(struct map_session_data *sd, uint16 flag);
 
 void pc_cell_basilica(struct map_session_data *sd);
 
-unsigned int pc_get_maxhp(uint16 level, uint16 class_, uint16 vit, int bonus, int bonus_rate);
-unsigned int pc_get_maxsp(uint16 level, uint16 class_, uint16 int_, int bonus, int bonus_rate);
-
 #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
 int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_race, uint32 mob_mode, int type);
 #endif

+ 18 - 5
src/map/script.c

@@ -11779,7 +11779,7 @@ BUILDIN_FUNC(marriage)
 	TBL_PC *sd=script_rid2sd(st);
 	TBL_PC *p_sd=map_nick2sd(partner);
 
-	if(sd==NULL || p_sd==NULL || pc_marriage(sd,p_sd) < 0){
+	if(!sd || !p_sd || !pc_marriage(sd,p_sd)){
 		script_pushint(st,0);
 		return 0;
 	}
@@ -11803,7 +11803,7 @@ BUILDIN_FUNC(wedding_effect)
 BUILDIN_FUNC(divorce)
 {
 	TBL_PC *sd=script_rid2sd(st);
-	if(sd==NULL || pc_divorce(sd) < 0){
+	if(!sd || !pc_divorce(sd)){
 		script_pushint(st,0);
 		return 0;
 	}
@@ -17345,6 +17345,18 @@ BUILDIN_FUNC(get_revision) {
 		script_pushint(st,-1); //unknown
 	return SCRIPT_CMD_SUCCESS;
 }
+/* get_hash() -> retrieves the current git hash (if available)*/
+BUILDIN_FUNC(get_githash) {
+	const char* git = get_git_hash();
+	char buf[CHAT_SIZE_MAX];
+	safestrncpy(buf,git,strlen(git)+1);
+
+	if ( git[0] != UNKNOWN_VERSION )
+		script_pushstr(st,buf);
+	else
+		script_pushstr(st,"Unknown"); //unknown
+	return SCRIPT_CMD_SUCCESS;
+}
 /**
  * freeloop(<toggle>) -> toggles this script instance's looping-check ability
  **/
@@ -17568,7 +17580,7 @@ BUILDIN_FUNC(getgroupitem) {
 	if (!(sd = script_rid2sd(st)))
 		return SCRIPT_CMD_SUCCESS;
 	
-	if (itemdb_pc_get_itemgroup(group_id,sd->itemid,sd)) {
+	if (itemdb_pc_get_itemgroup(group_id,sd)) {
 		ShowError("getgroupitem: Invalid group id '%d' specified.",group_id);
 		return SCRIPT_CMD_FAILURE;
 	}
@@ -18224,7 +18236,7 @@ BUILDIN_FUNC(bonus_script) {
 	uint32 dur;
 	char type = 0;
 	TBL_PC* sd;
-	const char *script_str = NULL;
+	const char *script_str = '\0';
 	struct script_code *script = NULL;
 
 	if (script_hasdata(st,7))
@@ -18241,7 +18253,7 @@ BUILDIN_FUNC(bonus_script) {
 	FETCH(5,type);
 	FETCH(6,icon);
 
-	if (!strlen(script_str) || !dur) {
+	if (script_str == '\0' || !dur) {
 		//ShowWarning("buildin_bonus_script: Invalid value(s). Skipping...\n");
 		return 0;
 	}
@@ -18719,6 +18731,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(getcharip,"?"),
 	BUILDIN_DEF(is_function,"s"),
 	BUILDIN_DEF(get_revision,""),
+	BUILDIN_DEF(get_githash,""),
 	BUILDIN_DEF(freeloop,"i"),
 	BUILDIN_DEF(getrandgroupitem,"ii?"),
 	BUILDIN_DEF(cleanmap,"s"),

+ 57 - 19
src/map/status.c

@@ -2074,6 +2074,7 @@ unsigned short status_base_matk(const struct status_data* status, int level) { r
 **/
 void status_calc_misc(struct block_list *bl, struct status_data *status, int level)
 {
+	int stat;
 	// Non players get the value set, players need to stack with previous bonuses.
 	if( bl->type != BL_PC )
 		status->batk =
@@ -2083,34 +2084,71 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
 
 #ifdef RENEWAL // Renewal formulas
 	if (bl->type == BL_MOB) {
-		status->hit += level + status->dex + 175;
-		status->flee += level + status->agi + 100;
+		//Hit
+		stat = status->hit;
+		stat += level + status->dex + 175;
+		status->hit = cap_value(stat,1,SHRT_MAX);
+		//Flee
+		stat = status->flee;
+		stat += level + status->agi + 100;
+		status->flee = cap_value(stat,1,SHRT_MAX);
 	} else if (bl->type == BL_HOM) {
-		status->hit = level + status->dex + 150; // base level + dex + 150
-		status->flee = level + status->agi + level/10; // base level + agi + base level/10
+		status->hit = cap_value(level + status->dex + 150,1,SHRT_MAX); // base level + dex + 150
+		status->flee = cap_value(level + status->agi + level/10,1,SHRT_MAX); // base level + agi + base level/10
 	} else {
-		status->hit += level + status->dex + status->luk/3 + 175; // base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
-		status->flee += level + status->agi + status->luk/5 + 100; // base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
+		//Hit
+		stat = status->hit;
+		stat += level + status->dex + status->luk/3 + 175; // base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
+		status->hit = cap_value(stat,1,SHRT_MAX);
+		//Flee
+		stat = status->flee;
+		stat += level + status->agi + status->luk/5 + 100; // base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
+		status->flee = cap_value(stat,1,SHRT_MAX);
 	}
 	status->matk_min = status->matk_max = status_base_matk(status, level);
-	status->def2 += (int)(((float)level + status->vit)/2 + ((float)status->agi/5)); // base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
-	status->mdef2 += (int)(status->int_ + ((float)level/4) + ((float)status->dex/5) + ((float)status->vit/5)); // (every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
+	//Def2
+	stat = status->def2;
+	stat += (int)(((float)level + status->vit)/2 + ((float)status->agi/5)); // base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
+	status->def2 = cap_value(stat,0,SHRT_MAX);
+	//MDef2
+	stat = status->mdef2;
+	stat += (int)(status->int_ + ((float)level/4) + ((float)status->dex/5) + ((float)status->vit/5)); // (every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
+	status->mdef2 = cap_value(stat,0,SHRT_MAX);
 #else
 	status->matk_min = status_base_matk_min(status);
 	status->matk_max = status_base_matk_max(status);
-	status->hit += level + status->dex;
-	status->flee += level + status->agi;
-	status->def2 += status->vit;
-	status->mdef2 += status->int_ + (status->vit>>1);
+	//Hit
+	stat = status->hit;
+	stat += level + status->dex;
+	status->hit = cap_value(stat,1,SHRT_MAX);
+	//Flee
+	stat = status->flee;
+	stat += level + status->agi;
+	status->flee = cap_value(stat,1,SHRT_MAX);
+	//Def2
+	stat = status->def2;
+	stat += status->vit;
+	status->def2 = cap_value(stat,0,SHRT_MAX);
+	//MDef2
+	stat = status->mdef2;
+	stat += status->int_ + (status->vit>>1);
+	status->mdef2 = cap_value(stat,0,SHRT_MAX);
 #endif
 
-	if( bl->type&battle_config.enable_critical )
-		status->cri += 10 + (status->luk*10/3); // (every 1 luk = +0.3 critical)
+	//Critical
+	if( bl->type&battle_config.enable_critical ) {
+		stat = status->cri;
+		stat += 10 + (status->luk*10/3); // (every 1 luk = +0.3 critical)
+		status->cri = cap_value(stat,1,SHRT_MAX);
+	}
 	else
 		status->cri = 0;
 
-	if (bl->type&battle_config.enable_perfect_flee)
-		status->flee2 += status->luk + 10; // (every 10 luk = +1 perfect flee)
+	if (bl->type&battle_config.enable_perfect_flee) {
+		stat = status->flee2;
+		stat += status->luk + 10; // (every 10 luk = +1 perfect flee)
+		status->flee2 = cap_value(stat,0,SHRT_MAX);
+	}
 	else
 		status->flee2 = 0;
 
@@ -2123,7 +2161,7 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
 	switch (bl->type) {
 	case BL_MOB:
 		if(battle_config.mob_critical_rate != 100)
-			status->cri = status->cri*battle_config.mob_critical_rate/100;
+			status->cri = cap_value(status->cri*battle_config.mob_critical_rate/100,1,SHRT_MAX);
 		if(!status->cri && battle_config.mob_critical_rate)
 		  	status->cri = 10;
 		break;
@@ -2132,7 +2170,7 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
 		break;
 	default:
 		if(battle_config.critical_rate != 100)
-			status->cri = status->cri*battle_config.critical_rate/100;
+			status->cri = cap_value(status->cri*battle_config.critical_rate/100,1,SHRT_MAX);
 		if (!status->cri && battle_config.critical_rate)
 			status->cri = 10;
 	}
@@ -3184,7 +3222,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
 	if(sd->critical_rate < 0)
 		sd->critical_rate = 0;
 	if(sd->critical_rate != 100)
-		status->cri = status->cri * sd->critical_rate/100;
+		status->cri = cap_value(status->cri * sd->critical_rate/100,SHRT_MIN,SHRT_MAX);
 
 	if(sd->flee2_rate < 0)
 		sd->flee2_rate = 0;

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików