Added Support for BodyStyle

Closes #974 as merged
This commit is contained in:
Dastgir 2015-12-17 16:10:19 +05:30 committed by Haru
parent 987b90508e
commit 0c458a4976
18 changed files with 201 additions and 55 deletions

View file

@ -26,6 +26,8 @@ min_hair_color: 0
max_hair_color: 8
min_cloth_color: 0
max_cloth_color: 4
min_body_style: 0
max_body_style: 4
// 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
@ -75,6 +77,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 costume?
// 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

View file

@ -1035,7 +1035,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 in this map.

View file

@ -633,6 +633,7 @@ LOOK_SHOES 9
LOOK_BODY 10
LOOK_FLOOR 11
LOOK_ROBE 12
LOOK_BODY2 13
Eff_Stone 0
Eff_Freeze 1

View file

@ -169,6 +169,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',
@ -821,6 +822,7 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1414975503); -- 2014-11-0
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1435860840); -- 2015-07-02--18-14.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1436360978); -- 2015-07-08--13-08.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1440688342); -- 2015-08-27--20-42.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1450367880); -- 2015-12-17--15-58.sql
--
-- Table structure for table `storage`

View file

@ -0,0 +1,22 @@
#1450367880
-- This file is part of Hercules.
-- http://herc.ws - http://github.com/HerculesWS/Hercules
--
-- Copyright (C) 2015 Hercules Dev Team
--
-- Hercules is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
ALTER TABLE `char` ADD `body` smallint(5) unsigned NOT NULL default '0' AFTER `clothes_color`;
INSERT INTO `sql_updates` (`timestamp`) VALUES (1450367880);

View file

@ -27,4 +27,5 @@
2014-11-03--00-45.sql
2015-07-02--18-14.sql
2015-07-08--13-08.sql
2015-08-27--20-42.sql
2015-08-27--20-42.sql
2015-12-17--15-58.sql

View file

@ -508,7 +508,8 @@ int char_mmo_char_tosql(int 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->hair != cp->hair) || (p->hair_color != cp->hair_color) ||
(p->clothes_color != cp->clothes_color) || (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) ||
@ -517,12 +518,12 @@ int char_mmo_char_tosql(int char_id, struct mmo_charstatus* p)
)
{
if( SQL_ERROR == SQL->Query(inter->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`='%d', `father`='%d', `mother`='%d', `child`='%d',"
"`karma`='%d',`manner`='%d', `fame`='%d'"
"`karma`='%d', `manner`='%d', `fame`='%d'"
" WHERE `account_id`='%d' AND `char_id` = '%d'",
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) )
@ -1070,7 +1071,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`,`slotchange`,`unban_time`,`sex`"
" FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", char_db, sd->account_id, MAX_CHARS)
|| SQL_ERROR == SQL->StmtExecute(stmt)
@ -1101,18 +1102,19 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 24, SQLDT_SHORT, &p.hair, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 25, SQLDT_SHORT, &p.hair_color, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 26, SQLDT_SHORT, &p.clothes_color, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 27, SQLDT_SHORT, &p.weapon, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 28, SQLDT_SHORT, &p.shield, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 29, SQLDT_SHORT, &p.head_top, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 30, SQLDT_SHORT, &p.head_mid, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 31, SQLDT_SHORT, &p.head_bottom, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 32, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 33, SQLDT_USHORT, &p.rename, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 34, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 35, SQLDT_SHORT, &p.robe, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 36, SQLDT_USHORT, &p.slotchange, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 37, SQLDT_LONG, &unban_time, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 38, SQLDT_ENUM, &sex, sizeof(sex), NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 27, SQLDT_SHORT, &p.body, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 28, SQLDT_SHORT, &p.weapon, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 29, SQLDT_SHORT, &p.shield, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 30, SQLDT_SHORT, &p.head_top, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 31, SQLDT_SHORT, &p.head_mid, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 32, SQLDT_SHORT, &p.head_bottom, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 33, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 34, SQLDT_USHORT, &p.rename, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 35, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 36, SQLDT_SHORT, &p.robe, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 37, SQLDT_USHORT, &p.slotchange, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 38, SQLDT_LONG, &unban_time, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 39, SQLDT_ENUM, &sex, sizeof(sex), NULL, NULL)
) {
SqlStmt_ShowDebug(stmt);
SQL->StmtFree(stmt);
@ -1176,7 +1178,7 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every
"`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`,`slotchange`,"
"`char_opt`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`"
" FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
@ -1215,31 +1217,32 @@ int char_mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_every
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 30, SQLDT_SHORT, &p->hair, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 31, SQLDT_SHORT, &p->hair_color, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 32, SQLDT_SHORT, &p->clothes_color, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 33, SQLDT_SHORT, &p->weapon, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 34, SQLDT_SHORT, &p->shield, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 35, SQLDT_SHORT, &p->head_top, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 36, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 37, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 38, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 39, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 40, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 41, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 42, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 43, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 44, SQLDT_INT, &p->partner_id, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 45, SQLDT_INT, &p->father, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 46, SQLDT_INT, &p->mother, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 47, SQLDT_INT, &p->child, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 48, SQLDT_INT, &p->fame, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 49, SQLDT_USHORT, &p->rename, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 50, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 51, SQLDT_SHORT, &p->robe, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 52, SQLDT_USHORT, &p->slotchange, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 53, SQLDT_UINT, &opt, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 54, SQLDT_UCHAR, &p->font, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 55, SQLDT_UINT, &p->uniqueitem_counter, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 56, SQLDT_ENUM, &sex, sizeof(sex), NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 57, SQLDT_UCHAR, &p->hotkey_rowshift, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 33, SQLDT_SHORT, &p->body, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 34, SQLDT_SHORT, &p->weapon, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 35, SQLDT_SHORT, &p->shield, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 36, SQLDT_SHORT, &p->head_top, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 37, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 38, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 39, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 40, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 41, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 42, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 43, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 44, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 45, SQLDT_INT, &p->partner_id, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 46, SQLDT_INT, &p->father, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 47, SQLDT_INT, &p->mother, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 48, SQLDT_INT, &p->child, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 49, SQLDT_INT, &p->fame, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 50, SQLDT_USHORT, &p->rename, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 51, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 52, SQLDT_SHORT, &p->robe, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 53, SQLDT_USHORT, &p->slotchange, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 54, SQLDT_UINT, &opt, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 55, SQLDT_UCHAR, &p->font, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 56, SQLDT_UINT, &p->uniqueitem_counter, 0, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 57, SQLDT_ENUM, &sex, sizeof(sex), NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 58, SQLDT_UCHAR, &p->hotkey_rowshift, 0, NULL, NULL)
) {
SqlStmt_ShowDebug(stmt);
SQL->StmtFree(stmt);
@ -1998,12 +2001,11 @@ 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!?

View file

@ -501,7 +501,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;

View file

@ -1702,6 +1702,32 @@ ACMD(model)
return true;
}
/*==========================================
* @bodystyle [Rytech]
*------------------------------------------*/
ACMD(bodystyle)
{
int body_style = 0;
memset(atcmd_output, '\0', sizeof(atcmd_output));
if (!*message || sscanf(message, "%d", &body_style) < 1) {
sprintf(atcmd_output, "Please, enter a body style (usage: @bodystyle <body ID: %d-%d>).", MIN_BODY_STYLE, MAX_BODY_STYLE);
clif->message(fd, atcmd_output);
return false;
}
if (body_style >= MIN_BODY_STYLE && body_style <= MAX_BODY_STYLE) {
pc->changelook(sd, LOOK_BODY2, body_style);
clif->message(fd, msg_txt(36)); // Appearence changed.
} else {
clif->message(fd, msg_txt(37)); // An invalid number was specified.
return false;
}
return true;
}
/*==========================================
* @dye && @ccolor
*------------------------------------------*/
@ -5484,7 +5510,7 @@ ACMD(divorce)
ACMD(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, "%12d %12d", &j, &k)) < 1) {
clif->message(fd, msg_fd(fd,1177)); // Usage: @changelook {<position>} <view id>
@ -9648,6 +9674,7 @@ void atcommand_basecommands(void) {
ACMD_DEF(skdebug),
ACMD_DEF(cddebug),
ACMD_DEF(lang),
ACMD_DEF(bodystyle),
};
int i;

View file

@ -7196,6 +7196,9 @@ static const struct battle_data {
{ "costume_refine_def", &battle_config.costume_refine_def, 1, 0, 1, },
{ "shadow_refine_def", &battle_config.shadow_refine_def, 1, 0, 1, },
{ "shadow_refine_atk", &battle_config.shadow_refine_atk, 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
/**

View file

@ -43,6 +43,8 @@ struct status_data;
#define MAX_HAIR_COLOR (battle->bc->max_hair_color)
#define MIN_CLOTH_COLOR (battle->bc->min_cloth_color)
#define MAX_CLOTH_COLOR (battle->bc->max_cloth_color)
#define MIN_BODY_STYLE (battle->bc->min_body_style)
#define MAX_BODY_STYLE (battle->bc->max_body_style)
#define is_boss(bl) (status_get_mode(bl)&MD_BOSS) // Can refine later [Aru]
@ -529,9 +531,14 @@ struct Battle_Config {
int show_monster_hp_bar; // [Frost]
int fix_warp_hit_delay_abuse;
// Refine Def/Atk
int costume_refine_def, shadow_refine_def;
int shadow_refine_atk;
// BodyStyle
int min_body_style, max_body_style;
int save_body_style;
};
/* criteria for battle_config.idletime_critera */

View file

@ -1059,7 +1059,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu
}
#endif
#if PACKETVER >= 20150513
p.body = 0;
p.body = vd->body_style;
#endif
clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target);
@ -1198,7 +1198,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) {
}
#endif
#if PACKETVER >= 20150513
p.body = 0;
p.body = vd->body_style;
#endif
if( disguised(bl) ) {
nullpo_retv(sd);
@ -1288,7 +1288,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd,
}
#endif
#if PACKETVER >= 20150513
p.body = 0;
p.body = vd->body_style;
#endif
clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target);
@ -1417,6 +1417,8 @@ bool clif_spawn(struct block_list *bl)
if (vd->cloth_color)
clif->refreshlook(bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,AREA_WOS);
if (vd->body_style)
clif->refreshlook(bl,bl->id,LOOK_BODY2,vd->body_style,AREA_WOS);
switch (bl->type) {
case BL_PC:
@ -1681,6 +1683,8 @@ void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_data *u
if(vd->cloth_color)
clif->refreshlook(bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,AREA_WOS);
if (vd->body_style)
clif->refreshlook(bl,bl->id,LOOK_BODY2,vd->body_style,AREA_WOS);
switch(bl->type) {
case BL_PC:
@ -3120,6 +3124,11 @@ void clif_changelook(struct block_list *bl,int type,int val)
vd->cloth_color = 0;
if (sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */)
vd->cloth_color = 0;
if (vd->body_style && (
sd->sc.option&OPTION_WEDDING || sd->sc.option&OPTION_XMAS ||
sd->sc.option&OPTION_SUMMER || sd->sc.option&OPTION_HANBOK ||
sd->sc.option&OPTION_OKTOBERFEST))
vd->body_style = 0;
break;
case LOOK_HAIR:
vd->hair_style = val;
@ -3177,6 +3186,14 @@ void clif_changelook(struct block_list *bl,int type,int val)
vd->robe = val;
#endif
break;
case LOOK_BODY2:
if (val && (
sd->sc.option&OPTION_WEDDING || sd->sc.option&OPTION_XMAS ||
sd->sc.option&OPTION_SUMMER || sd->sc.option&OPTION_HANBOK ||
sd->sc.option&OPTION_OKTOBERFEST))
val = 0;
vd->body_style = val;
break;
}
// prevent leaking the presence of GM-hidden objects
@ -4160,6 +4177,9 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) {
if (vd->cloth_color)
clif->refreshlook(&sd->bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,SELF);
if (vd->body_style)
clif->refreshlook(&sd->bl,bl->id,LOOK_BODY2,vd->body_style,SELF);
switch (bl->type) {
case BL_PC:
{
@ -8281,6 +8301,8 @@ void clif_refresh(struct map_session_data *sd)
if (sd->vd.cloth_color)
clif->refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
if (sd->vd.body_style)
clif->refreshlook(&sd->bl,sd->bl.id,LOOK_BODY2,sd->vd.body_style,SELF);
if(homun_alive(sd->hd))
clif->send_homdata(sd,SP_ACK,0);
if( sd->md ) {
@ -9124,6 +9146,8 @@ void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) {
if(sd->vd.cloth_color)
clif->refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
if (sd->vd.body_style)
clif->refreshlook(&sd->bl,sd->bl.id,LOOK_BODY2,sd->vd.body_style,SELF);
// item
clif->inventorylist(sd); // inventory list first, otherwise deleted items in pc->checkitem show up as 'unknown item'
pc->checkitem(sd);

View file

@ -486,6 +486,7 @@ enum look {
LOOK_BODY,
LOOK_FLOOR,
LOOK_ROBE,
LOOK_BODY2,
};
// used by map_setcell()

View file

@ -596,6 +596,10 @@ int pc_makesavestatus(struct map_session_data *sd)
if(!battle_config.save_clothcolor)
sd->status.clothes_color=0;
if (!battle_config.save_body_style)
sd->status.body = 0;
//Only copy the Cart/Peco/Falcon options, the rest are handled via
//status change load/saving. [Skotlex]
#ifdef NEW_CARTS
@ -1067,6 +1071,9 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
if( sd->status.clothes_color < MIN_CLOTH_COLOR || sd->status.clothes_color > MAX_CLOTH_COLOR ) {
sd->status.clothes_color = MIN_CLOTH_COLOR;
}
if (sd->status.body < MIN_BODY_STYLE || sd->status.body > MAX_BODY_STYLE) {
sd->status.body = MIN_BODY_STYLE;
}
//Initializations to null/0 unneeded since map_session_data was filled with 0 upon allocation.
if(!sd->status.hp) pc_setdead(sd);
@ -8450,6 +8457,8 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
clif->changelook(&sd->bl,LOOK_BASE,sd->vd.class_); // move sprite update to prevent client crashes with incompatible equipment [Valaris]
if(sd->vd.cloth_color)
clif->changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
if (sd->vd.body_style)
clif->changelook(&sd->bl,LOOK_BODY2,sd->vd.body_style);
//Update skill tree.
pc->calc_skilltree(sd);
@ -8546,6 +8555,8 @@ int pc_changelook(struct map_session_data *sd,int type,int val)
clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
if (sd->vd.cloth_color)
clif->changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
if (sd->vd.body_style)
clif->changelook(&sd->bl,LOOK_BODY2,sd->vd.body_style);
clif->skillinfoblock(sd);
return 0;
break;
@ -8594,6 +8605,10 @@ int pc_changelook(struct map_session_data *sd,int type,int val)
case LOOK_ROBE:
sd->status.robe = val;
break;
case LOOK_BODY2:
val = cap_value(val, MIN_BODY_STYLE, MAX_BODY_STYLE);
sd->status.body=val;
break;
}
clif->changelook(&sd->bl,type,val);
return 0;
@ -8690,6 +8705,8 @@ int pc_setoption(struct map_session_data *sd,int type)
clif->changelook(&sd->bl,LOOK_BASE,new_look);
if (sd->vd.cloth_color)
clif->changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
if( sd->vd.body_style )
clif->changelook(&sd->bl,LOOK_BODY2,sd->vd.body_style);
clif->skillinfoblock(sd); // Skill list needs to be updated after base change.
return 0;

View file

@ -14109,6 +14109,7 @@ BUILDIN(getlook)
case LOOK_SHIELD: val = sd->status.shield; break; //8
case LOOK_SHOES: break; //9
case LOOK_ROBE: val = sd->status.robe; break; //12
case LOOK_BODY2: val=sd->status.body; break; //13
}
script_pushint(st,val);

View file

@ -6525,6 +6525,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
sd->vd.hair_color = cap_value(sd->status.hair_color,0,battle_config.max_hair_color);
sd->vd.cloth_color = cap_value(sd->status.clothes_color,0,battle_config.max_cloth_color);
sd->vd.robe = sd->status.robe;
sd->vd.body_style = sd->status.body;
sd->vd.sex = sd->status.sex;
if ( sd->vd.cloth_color ) {
@ -6539,6 +6540,11 @@ void status_set_viewdata(struct block_list *bl, int class_)
if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ )
sd->vd.cloth_color = 0;
}
if ( sd->vd.body_style && (
sd->sc.option&OPTION_WEDDING || sd->sc.option&OPTION_XMAS ||
sd->sc.option&OPTION_SUMMER || sd->sc.option&OPTION_HANBOK ||
sd->sc.option&OPTION_OKTOBERFEST))
sd->vd.body_style = 0;
} else if (vd)
memcpy(&sd->vd, vd, sizeof(struct view_data));
else
@ -9464,6 +9470,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
clif->changelook(bl,LOOK_WEAPON,0);
clif->changelook(bl,LOOK_SHIELD,0);
clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
clif->changelook(bl,LOOK_BODY2,0);
break;
case SC_KAAHI:
val4 = INVALID_TIMER;
@ -9869,6 +9876,17 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
calc_flag&=~SCB_DYE;
}
#if 0 //Currently No SC's use this
if (calc_flag&SCB_BODY) {
//Reset Body Style
if (vd && vd->body_style) {
val4 = vd->body_style;
clif->changelook(bl,LOOK_BODY2,0);
}
calc_flag&=~SCB_BODY;
}
#endif
if(!(flag&SCFLAG_NOICON) && !(flag&SCFLAG_LOADED && status->dbs->DisplayType[type]))
clif->status_change(bl,status->dbs->IconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
@ -10752,6 +10770,14 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
calc_flag&=~SCB_DYE;
}
#if 0 // Currently No SC's use this
if (calc_flag&SCB_BODY) { // Restore Body color
if (vd && !vd->body_style && sce->val4)
clif->changelook(bl,LOOK_BODY2,sce->val4);
calc_flag&=~SCB_BODY;
}
#endif
//On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
clif->sc_end(bl,bl->id,AREA,status->dbs->IconChangeTable[type]);
@ -10765,6 +10791,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
clif->changelook(bl,LOOK_WEAPON,sd->vd.weapon);
clif->changelook(bl,LOOK_SHIELD,sd->vd.shield);
clif->changelook(bl,LOOK_CLOTHES_COLOR,cap_value(sd->status.clothes_color,0,battle_config.max_cloth_color));
clif->changelook(bl,LOOK_BODY2,cap_value(sd->status.body,0,battle_config.max_body_style));
}
}

View file

@ -1923,6 +1923,9 @@ enum scb_flag
SCB_RANGE = 0x10000000,
SCB_REGEN = 0x20000000,
SCB_DYE = 0x40000000, // force cloth-dye change to 0 to avoid client crashes.
#if 0 // Currently No SC use it. Also, when this will be implemented, there will be need to change to 64bit variable
SCB_BODY = 0x80000000, // Force bodysStyle change to 0
#endif
SCB_BATTLE = 0x3FFFFFFE,
SCB_ALL = 0x3FFFFFFF

View file

@ -93,7 +93,8 @@ struct view_data {
head_bottom,
hair_style,
hair_color,
cloth_color;
cloth_color,
body_style;
char sex;
unsigned dead_sit : 2;
};