Skip to content

Commit

Permalink
Add support body style implementation
Browse files Browse the repository at this point in the history
* This feature require the client support before 2015-05-13 or newer
   Make sure you data&lub support for this

  note : read info to https://rathena.org/board/topic/104205-2015-client-support/

  Special Thanks you to Rytech, @aleos89
  • Loading branch information
icxbb-xx committed Jan 11, 2016
1 parent 3f26c3d commit d70b173
Show file tree
Hide file tree
Showing 18 changed files with 305 additions and 103 deletions.
7 changes: 7 additions & 0 deletions conf/battle/client.conf
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ min_hair_color: 0
max_hair_color: 8
min_cloth_color: 0
max_cloth_color: 4
min_body_style: 0
max_body_style: 1

// When set to yes, the damage field in packets sent from woe maps will be set
// to -1, making it impossible for GMs, Bots and Hexed clients to know the
Expand Down Expand Up @@ -120,6 +122,11 @@ wedding_modifydisplay: no
// Save Clothes color. (This will degrade performance) (Note 1)
save_clothcolor: yes

// Save body styles. (Note 1)
// Note: Don't turn this on unless you know what your doing.
// Sprites are not released officially.
save_body_style: no

// Do not display cloth colors for the wedding class?
// Note: Both save_clothcolor and wedding_modifydisplay have to be enabled
// for this option to take effect. Set this to yes if your cloth palettes
Expand Down
8 changes: 6 additions & 2 deletions conf/msg_conf/map_msg.conf
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,11 @@
737: '%s' (%d) cannot be cloned, limit (%d).
738: Clone '%s' is done.

//739-899 free
// @bodystyle
739: Please enter a body style (usage: @bodystyle <body ID: %d-%d>).
740: This job has no alternate body styles.

//741-899 free

//------------------------------------
// More atcommands message
Expand Down Expand Up @@ -1112,7 +1116,7 @@

// @changelook
1177: Usage: @changelook {<position>} <view id>
1178: Position: 1-Top 2-Middle 3-Bottom 4-Weapon 5-Shield 6-Shoes 7-Robe
1178: Position: 1-Top 2-Middle 3-Bottom 4-Weapon 5-Shield 6-Shoes 7-Robe 8-Body

// @autotrade
1179: Autotrade is not allowed on this map.
Expand Down
22 changes: 22 additions & 0 deletions doc/script_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8998,5 +8998,27 @@ The command returns 1 upon success, and these values upon failure:

---------------------------------------

*opendressroom({<char_id>});

This will open the Dress Room window on the client connected to the invoking character.

mes "Close this window to open the Dress Room window.";
close2;
opendressroom;
end;

---------------------------------------

*closedressroom({<char_id>});

This will close an open Dress Room window on the client connected to the invoking character.

mes "Close this window to close the Dress Room window.";
close2;
closedressroom;
end;

---------------------------------------

Whew.
That's about all of them.
3 changes: 2 additions & 1 deletion sql-files/main.sql
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ CREATE TABLE IF NOT EXISTS `char` (
`hair` tinyint(4) unsigned NOT NULL default '0',
`hair_color` smallint(5) unsigned NOT NULL default '0',
`clothes_color` smallint(5) unsigned NOT NULL default '0',
`body` smallint(5) unsigned NOT NULL default '0',
`weapon` smallint(6) unsigned NOT NULL default '0',
`shield` smallint(6) unsigned NOT NULL default '0',
`head_top` smallint(6) unsigned NOT NULL default '0',
Expand All @@ -197,7 +198,7 @@ CREATE TABLE IF NOT EXISTS `char` (
`font` tinyint(3) unsigned NOT NULL default '0',
`uniqueitem_counter` int(11) unsigned NOT NULL default '0',
`sex` ENUM('M','F','U') NOT NULL default 'U',
`hotkey_rowshift` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
`hotkey_rowshift` tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (`char_id`),
UNIQUE KEY `name_key` (`name`),
KEY `account_id` (`account_id`),
Expand Down
1 change: 1 addition & 0 deletions sql-files/upgrades/upgrade_20160112.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE `char` ADD `body`smallint(5) unsigned NOT NULL default '0' AFTER `clothes_color`;
100 changes: 51 additions & 49 deletions src/char/char.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y,
mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
(unsigned long)p->delete_date, // FIXME: platform-dependent size
p->robe,p->character_moves,p->font, p->uniqueitem_counter,
p->robe, p->character_moves, p->font, p->uniqueitem_counter,
p->hotkey_rowshift,
p->account_id, p->char_id) )
{
Expand All @@ -364,20 +364,20 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
//Values that will seldom change (to speed up saving)
if (
(p->hair != cp->hair) || (p->hair_color != cp->hair_color) || (p->clothes_color != cp->clothes_color) ||
(p->class_ != cp->class_) ||
(p->body != cp->body) || (p->class_ != cp->class_) ||
(p->partner_id != cp->partner_id) || (p->father != cp->father) ||
(p->mother != cp->mother) || (p->child != cp->child) ||
(p->karma != cp->karma) || (p->manner != cp->manner) ||
(p->fame != cp->fame)
)
{
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `class`='%d',"
"`hair`='%d',`hair_color`='%d',`clothes_color`='%d',"
"`hair`='%d', `hair_color`='%d', `clothes_color`='%d', `body`='%d',"
"`partner_id`='%u', `father`='%u', `mother`='%u', `child`='%u',"
"`karma`='%d',`manner`='%d', `fame`='%d'"
" WHERE `account_id`='%d' AND `char_id` = '%d'",
schema_config.char_db, p->class_,
p->hair, p->hair_color, p->clothes_color,
p->hair, p->hair_color, p->clothes_color, p->body,
p->partner_id, p->father, p->mother, p->child,
p->karma, p->manner, p->fame,
p->account_id, p->char_id) )
Expand Down Expand Up @@ -921,7 +921,7 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) {
"`char_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`,"
"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,"
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`hair`,`hair_color`,"
"`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`,"
"`clothes_color`,`body`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`,"
"`robe`,`moves`,`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`"
" FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", schema_config.char_db, sd->account_id, MAX_CHARS)
|| SQL_ERROR == SqlStmt_Execute(stmt)
Expand Down Expand Up @@ -952,21 +952,22 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) {
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 24, SQLDT_SHORT, &p.hair, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 25, SQLDT_SHORT, &p.hair_color, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 26, SQLDT_SHORT, &p.clothes_color, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 27, SQLDT_SHORT, &p.weapon, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 28, SQLDT_SHORT, &p.shield, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_SHORT, &p.head_top, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p.head_mid, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p.head_bottom, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p.rename, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p.robe, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_UINT, &p.character_moves, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_LONG, &p.unban_time, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_UCHAR, &p.font, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_UINT, &p.uniqueitem_counter, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_ENUM, &sex, sizeof(sex), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_UCHAR, &p.hotkey_rowshift, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 27, SQLDT_SHORT, &p.body, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 28, SQLDT_SHORT, &p.weapon, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_SHORT, &p.shield, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p.head_top, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p.head_mid, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT, &p.head_bottom, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT, &p.rename, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p.robe, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_UINT, &p.character_moves, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_LONG, &p.unban_time, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_UCHAR, &p.font, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_UINT, &p.uniqueitem_counter, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_ENUM, &sex, sizeof(sex), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_UCHAR, &p.hotkey_rowshift, 0, NULL, NULL)
)
{
SqlStmt_ShowDebug(stmt);
Expand Down Expand Up @@ -1030,7 +1031,7 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
"`char_id`,`account_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`,"
"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,"
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,"
"`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
"`hair_color`,`clothes_color`,`body`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`, `moves`,"
"`unban_time`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`"
" FROM `%s` WHERE `char_id`=? LIMIT 1", schema_config.char_db)
Expand Down Expand Up @@ -1069,31 +1070,32 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p->hair, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p->hair_color, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT, &p->clothes_color, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p->weapon, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT, &p->shield, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p->head_top, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_UINT32, &p->partner_id, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_UINT32, &p->father, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 46, SQLDT_UINT32, &p->mother, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_UINT32, &p->child, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 48, SQLDT_INT, &p->fame, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 49, SQLDT_SHORT, &p->rename, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 50, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 51, SQLDT_SHORT, &p->robe, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 52, SQLDT_UINT32, &p->character_moves, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 53, SQLDT_LONG, &p->unban_time, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 54, SQLDT_UCHAR, &p->font, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 55, SQLDT_UINT, &p->uniqueitem_counter, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 56, SQLDT_ENUM, &sex, sizeof(sex), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 57, SQLDT_UCHAR, &p->hotkey_rowshift, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p->body, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT, &p->weapon, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p->shield, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p->head_top, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_UINT32, &p->partner_id, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 46, SQLDT_UINT32, &p->father, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_UINT32, &p->mother, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 48, SQLDT_UINT32, &p->child, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 49, SQLDT_INT, &p->fame, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 50, SQLDT_SHORT, &p->rename, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 51, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 52, SQLDT_SHORT, &p->robe, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 53, SQLDT_UINT32, &p->character_moves, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 54, SQLDT_LONG, &p->unban_time, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 55, SQLDT_UCHAR, &p->font, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 56, SQLDT_UINT, &p->uniqueitem_counter, 0, NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 57, SQLDT_ENUM, &sex, sizeof(sex), NULL, NULL)
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 58, SQLDT_UCHAR, &p->hotkey_rowshift, 0, NULL, NULL)
)
{
SqlStmt_ShowDebug(stmt);
Expand Down Expand Up @@ -1733,12 +1735,12 @@ int char_mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
WBUFW(buf,48) = min(p->max_sp, INT16_MAX);
WBUFW(buf,50) = DEFAULT_WALK_SPEED; // p->speed;
WBUFW(buf,52) = p->class_;
WBUFW(buf,54) = p->hair;

#if PACKETVER >= 20141022
WBUFL(buf,54) = p->hair;
WBUFW(buf,56) = p->body;
offset+=2;
buf = WBUFP(buffer,offset);
#else
WBUFW(buf,54) = p->hair;
#endif

//When the weapon is sent and your option is riding, the client crashes on login!?
Expand Down
4 changes: 2 additions & 2 deletions src/common/mmo.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
// see conf/battle/client.conf for other version

#ifndef PACKETVER
#define PACKETVER 20130807
#define PACKETVER 20150513
//#define PACKETVER 20120410
#endif

Expand Down Expand Up @@ -390,7 +390,7 @@ struct mmo_charstatus {
unsigned int option;
short manner; // Defines how many minutes a char will be muted, each negative point is equivalent to a minute.
unsigned char karma;
short hair,hair_color,clothes_color;
short hair,hair_color,clothes_color,body;
int party_id,guild_id,pet_id,hom_id,mer_id,ele_id;
int fame;

Expand Down
40 changes: 37 additions & 3 deletions src/map/atcommand.c
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,39 @@ ACMD_FUNC(model)
return 0;
}

/*==========================================
* @bodystyle [Rytech]
*------------------------------------------*/
ACMD_FUNC(bodystyle)
{
int body_style = 0;
nullpo_retr(-1, sd);

memset(atcmd_output, '\0', sizeof(atcmd_output));

// Limit body styles to certain jobs since not all of them are released yet.
if (!((sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS || (sd->class_&MAPID_THIRDMASK) == MAPID_GENETIC)) {
clif_displaymessage(fd, msg_txt(sd,770)); // This job has no alternate body styles.
return -1;
}

if (!message || !*message || sscanf(message, "%d", &body_style) < 1) {
sprintf(atcmd_output, msg_txt(sd,739), MIN_BODY_STYLE, MAX_BODY_STYLE); // Please enter a body style (usage: @bodystyle <body ID: %d-%d>).
clif_displaymessage(fd, atcmd_output);
return -1;
}

if (body_style >= MIN_BODY_STYLE && body_style <= MAX_BODY_STYLE) {
pc_changelook(sd, LOOK_BODY2, body_style);
clif_displaymessage(fd, msg_txt(sd,36)); // Appearence changed.
} else {
clif_displaymessage(fd, msg_txt(sd,37)); // An invalid number was specified.
return -1;
}

return 0;
}

/*==========================================
* @dye && @ccolor
*------------------------------------------*/
Expand Down Expand Up @@ -5736,14 +5769,14 @@ ACMD_FUNC(divorce)
ACMD_FUNC(changelook)
{
int i, j = 0, k = 0;
int pos[7] = { LOOK_HEAD_TOP,LOOK_HEAD_MID,LOOK_HEAD_BOTTOM,LOOK_WEAPON,LOOK_SHIELD,LOOK_SHOES,LOOK_ROBE };
int pos[8] = { LOOK_HEAD_TOP,LOOK_HEAD_MID,LOOK_HEAD_BOTTOM,LOOK_WEAPON,LOOK_SHIELD,LOOK_SHOES,LOOK_ROBE, LOOK_BODY2 };

if((i = sscanf(message, "%11d %11d", &j, &k)) < 1) {
clif_displaymessage(fd, msg_txt(sd,1177)); // Usage: @changelook {<position>} <view id>
clif_displaymessage(fd, msg_txt(sd,1178)); // Position: 1-Top 2-Middle 3-Bottom 4-Weapon 5-Shield 6-Shoes 7-Robe
clif_displaymessage(fd, msg_txt(sd,1178)); // Position: 1-Top 2-Middle 3-Bottom 4-Weapon 5-Shield 6-Shoes 7-Robe 8-Body
return -1;
} else if ( i == 2 ) {
if (j < 1 || j > 7)
if (j < 1 || j > 8)
j = 1;
j = pos[j - 1];
} else if( i == 1 ) { // position not defined, use HEAD_TOP as default
Expand Down Expand Up @@ -10036,6 +10069,7 @@ void atcommand_basecommands(void) {
ACMD_DEF(costume),
ACMD_DEF(cloneequip),
ACMD_DEF(clonestat),
ACMD_DEF(bodystyle),
};
AtCommandInfo* atcommand;
int i;
Expand Down
3 changes: 3 additions & 0 deletions src/map/battle.c
Original file line number Diff line number Diff line change
Expand Up @@ -8171,6 +8171,9 @@ static const struct _battle_data {
{ "monster_loot_search_type", &battle_config.monster_loot_search_type, 1, 0, 1, },
{ "feature.roulette", &battle_config.feature_roulette, 1, 0, 1, },
{ "monster_hp_bars_info", &battle_config.monster_hp_bars_info, 1, 0, 1, },
{ "min_body_style", &battle_config.min_body_style, 0, 0, SHRT_MAX, },
{ "max_body_style", &battle_config.max_body_style, 4, 0, SHRT_MAX, },
{ "save_body_style", &battle_config.save_body_style, 0, 0, 1, },
};

#ifndef STATS_OPT_OUT
Expand Down
5 changes: 5 additions & 0 deletions src/map/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ bool is_infinite_defense(struct block_list *target, int flag);
#define MAX_HAIR_COLOR battle_config.max_hair_color
#define MIN_CLOTH_COLOR battle_config.min_cloth_color
#define MAX_CLOTH_COLOR battle_config.max_cloth_color
#define MIN_BODY_STYLE battle_config.min_body_style
#define MAX_BODY_STYLE battle_config.max_body_style

extern struct Battle_Config
{
Expand Down Expand Up @@ -592,6 +594,9 @@ extern struct Battle_Config
int monster_loot_search_type;
int feature_roulette;
int monster_hp_bars_info;
int min_body_style;
int max_body_style;
int save_body_style;
} battle_config;

void do_init_battle(void);
Expand Down

2 comments on commit d70b173

@renniw
Copy link

@renniw renniw commented on d70b173 Jan 11, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Ja.

@julia40124009
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow , good !
thanks

Please sign in to comment.