Skip to content

Commit

Permalink
Fixed issue: 7939
Browse files Browse the repository at this point in the history
http://hercules.ws/board/tracker/issue-7939-change-sex/
Also cleaned a bit the change sex process
  • Loading branch information
panikon committed Apr 10, 2014
1 parent 7a5f7db commit 6a27692
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 97 deletions.
117 changes: 64 additions & 53 deletions src/char/char.c
Original file line number Diff line number Diff line change
Expand Up @@ -2423,71 +2423,82 @@ int parse_fromlogin(int fd) {
{
unsigned char buf[7];

int char_id[MAX_CHARS];
int class_[MAX_CHARS];
int guild_id[MAX_CHARS];
int num;
int i;
char* data;
struct auth_node* node;

int acc = RFIFOL(fd,2);
int sex = RFIFOB(fd,6);

RFIFOSKIP(fd,7);

if( acc > 0 )
{// TODO: Is this even possible?
int char_id[MAX_CHARS];
int class_[MAX_CHARS];
int guild_id[MAX_CHARS];
int num;
int i;
char* data;
// This should _never_ happen
if( acc <= 0 ) {
ShowError("Received invalid account id from login server! (aid: %d)\n", acc);
return 0;
}

struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc);
if( node != NULL )
node->sex = sex;
node = (struct auth_node*)idb_get(auth_db, acc);
if( node != NULL )
node->sex = sex;

// get characters
if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", char_db, acc) )
Sql_ShowDebug(sql_handle);
for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i )
// get characters
if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", char_db, acc) )
Sql_ShowDebug(sql_handle);
for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i )
{
SQL->GetData(sql_handle, 0, &data, NULL); char_id[i] = atoi(data);
SQL->GetData(sql_handle, 1, &data, NULL); class_[i] = atoi(data);
SQL->GetData(sql_handle, 2, &data, NULL); guild_id[i] = atoi(data);
}
num = i;
for( i = 0; i < num; ++i )
{
if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER ||
class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ||
class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ||
class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ||
class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ||
class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ||
class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
{
SQL->GetData(sql_handle, 0, &data, NULL); char_id[i] = atoi(data);
SQL->GetData(sql_handle, 1, &data, NULL); class_[i] = atoi(data);
SQL->GetData(sql_handle, 2, &data, NULL); guild_id[i] = atoi(data);
// job modification
if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER )
class_[i] = (sex ? JOB_BARD : JOB_DANCER);
else if( class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY )
class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY);
else if( class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER )
class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER);
else if( class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER )
class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER);
else if( class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T )
class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T);
else if( class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER )
class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER);
else if( class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO);
}
num = i;
for( i = 0; i < num; ++i )
{
if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER ||
class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ||
class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ||
class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ||
class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ||
class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ||
class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
{
// job modification
if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER )
class_[i] = (sex ? JOB_BARD : JOB_DANCER);
else if( class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY )
class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY);
else if( class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER )
class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER);
else if( class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER )
class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER);
else if( class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T )
class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T);
else if( class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER )
class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER);
else if( class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO);
}

if( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', `head_bottom`='0' WHERE `char_id`='%d'", char_db, class_[i], char_id[i]) )
Sql_ShowDebug(sql_handle);
if( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `equip`='0' WHERE `char_id`='%d'", inventory_db, char_id[i]) )
Sql_ShowDebug(sql_handle);

if( guild_id[i] )// If there is a guild, update the guild_member data [Skotlex]
inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex);
}
SQL->FreeResult(sql_handle);
if( SQL_ERROR == SQL->Query(sql_handle,
"UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', "
"`head_bottom`='0' WHERE `char_id`='%d'",
char_db, class_[i], char_id[i]) )
Sql_ShowDebug(sql_handle);

// disconnect player if online on char-server
disconnect_player(acc);
if( guild_id[i] )// If there is a guild, update the guild_member data [Skotlex]
inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex);
}
SQL->FreeResult(sql_handle);

// disconnect player if online on char-server
disconnect_player(acc);

// notify all mapservers about this change
WBUFW(buf,0) = 0x2b0d;
Expand Down
51 changes: 7 additions & 44 deletions src/map/chrif.c
Original file line number Diff line number Diff line change
Expand Up @@ -842,56 +842,19 @@ bool chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, u
*------------------------------------------*/
void chrif_changedsex(int fd) {
int acc, sex;
struct map_session_data *sd;

acc = RFIFOL(fd,2);
sex = RFIFOL(fd,6);

if ( battle_config.etc_log )
ShowNotice("chrif_changedsex %d.\n", acc);

sd = map->id2sd(acc);
if ( sd ) { //Normally there should not be a char logged on right now!
if ( sd->status.sex == sex )
return; //Do nothing? Likely safe.
sd->status.sex = !sd->status.sex;

// reset skill of some job
if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
int i, idx = 0;
// remove specifical skills of Bard classes
for(i = 315; i <= 322; i++) {
idx = skill->get_index(i);
if (sd->status.skill[idx].id > 0 && sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[idx].lv;
sd->status.skill[idx].id = 0;
sd->status.skill[idx].lv = 0;
}
}
// remove specifical skills of Dancer classes
for(i = 323; i <= 330; i++) {
idx = skill->get_index(i);
if (sd->status.skill[idx].id > 0 && sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) {
sd->status.skill_point += sd->status.skill[idx].lv;
sd->status.skill[idx].id = 0;
sd->status.skill[idx].lv = 0;
}
}
clif->updatestatus(sd, SP_SKILLPOINT);
// change job if necessary
if (sd->status.sex) //Changed from Dancer
sd->status.class_ -= 1;
else //Changed from Bard
sd->status.class_ += 1;
//sd->class_ needs not be updated as both Dancer/Bard are the same.
}
// save character
sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
// do same modify in login-server for the account, but no in char-server (it ask again login_id1 to login, and don't remember it)
clif->message(sd->fd, msg_txt(409)); //"Your sex has been changed (disconnection required to complete the process)..."
set_eof(sd->fd); // forced to disconnect for the change
map->quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X]
}

// Path to activate this response:
// Map(start) (0x2b0e) -> Char(0x2727) -> Login
// Login(0x2723) [ALL] -> Char (0x2b0d)[ALL] -> Map (HERE)
// Char will usually be "logged in" despite being forced to log-out in the begining
// of this process, but there's no need to perform map-server specific response
// as everything should've been changed through char-server [Panikon]
}
/*==========================================
* Request Char Server to Divorce Players
Expand Down

0 comments on commit 6a27692

Please sign in to comment.