/*========================================== * Saves character data. * Flag = 1: Character is quitting * Flag = 2: Character is changing map-servers *------------------------------------------*/ int chrif_save(struct map_session_data *sd, int flag) { nullpo_retr(-1, sd); pc_makesavestatus(sd); if (flag && sd->state.active) //Store player data which is quitting. { //FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex] if (chrif_isconnected()) chrif_save_scdata(sd); if (!chrif_auth_logout(sd, flag==1?ST_LOGOUT:ST_MAPCHANGE)) ShowError("chrif_save: Falha em configurar personagem %d:%d para sair adequadamente!\n", sd->status.account_id, sd->status.char_id); } if(!chrif_isconnected()) return -1; //Character is saved on reconnect. //For data sync if (sd->state.storage_flag == 2) storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag); if (flag) sd->state.storage_flag = 0; //Force close it. //Saving of registry values. if (sd->state.reg_dirty&4) intif_saveregistry(sd, 3); //Save char regs if (sd->state.reg_dirty&2) intif_saveregistry(sd, 2); //Save account regs if (sd->state.reg_dirty&1) intif_saveregistry(sd, 1); //Save account2 regs WFIFOHEAD(char_fd, sizeof(sd->status) + 13); WFIFOW(char_fd,0) = 0x2b01; WFIFOW(char_fd,2) = sizeof(sd->status) + 13; WFIFOL(char_fd,4) = sd->status.account_id; WFIFOL(char_fd,8) = sd->status.char_id; WFIFOB(char_fd,12) = (flag==1)?1:0; //Flag to tell char-server this character is quitting. memcpy(WFIFOP(char_fd,13), &sd->status, sizeof(sd->status)); WFIFOSET(char_fd, WFIFOW(char_fd,2)); if( sd->status.pet_id > 0 && sd->pd ) intif_save_petdata(sd->status.account_id,&sd->pd->pet); if( sd->hd && merc_is_hom_active(sd->hd) ) merc_save(sd->hd); if( sd->md && mercenary_get_lifetime(sd->md) > 0 ) mercenary_save(sd->md); #ifndef TXT_ONLY if( sd->save_quest ) intif_quest_save(sd); #endif return 0; }
/*========================================== * Saves character data. * Flag = 1: Character is quitting * Flag = 2: Character is changing map-servers *------------------------------------------*/ int chrif_save(struct map_session_data *sd, int flag) { nullpo_retr(-1, sd); if (!flag) //The flag check is needed to prevent 'nosave' taking effect when a jailed player logs out. pc_makesavestatus(sd); if (flag && sd->state.active) //Store player data which is quitting. { //FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex] if (chrif_isconnected()) chrif_save_scdata(sd); if (!chrif_auth_logout(sd, flag==1?ST_LOGOUT:ST_MAPCHANGE)) ShowError("chrif_save: Failed to set up player %d:%d for proper quitting!\n", sd->status.account_id, sd->status.char_id); } if(!chrif_isconnected()) return -1; //Character is saved on reconnect. //For data sync if (sd->state.storage_flag == 1) storage_storage_save(sd->status.account_id, flag); else if (sd->state.storage_flag == 2) storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag); if (flag) sd->state.storage_flag = 0; //Force close it. //Saving of registry values. if (sd->state.reg_dirty&4) intif_saveregistry(sd, 3); //Save char regs if (sd->state.reg_dirty&2) intif_saveregistry(sd, 2); //Save account regs if (sd->state.reg_dirty&1) intif_saveregistry(sd, 1); //Save account2 regs WFIFOHEAD(char_fd, sizeof(sd->status) + 13); WFIFOW(char_fd,0) = 0x2b01; WFIFOW(char_fd,2) = sizeof(sd->status) + 13; WFIFOL(char_fd,4) = sd->status.account_id; WFIFOL(char_fd,8) = sd->status.char_id; WFIFOB(char_fd,12) = (flag==1)?1:0; //Flag to tell char-server this character is quitting. memcpy(WFIFOP(char_fd,13), &sd->status, sizeof(sd->status)); WFIFOSET(char_fd, WFIFOW(char_fd,2)); if(sd->status.pet_id > 0 && sd->pd) intif_save_petdata(sd->status.account_id,&sd->pd->pet); if (sd->hd && merc_is_hom_active(sd->hd)) merc_save(sd->hd); return 0; }
int merc_hom_change_name_ack(struct map_session_data *sd, char* name, int flag) { struct homun_data *hd = sd->hd; if (!merc_is_hom_active(hd)) return 0; if (!flag) { clif_displaymessage(sd->fd, msg_txt(280)); // You cannot use this name return 0; } strncpy(hd->homunculus.name,name,NAME_LENGTH); clif_charnameack (0,&hd->bl); hd->homunculus.rename_flag = 1; clif_hominfo(sd,hd,0); return 1; }
int merc_hom_shuffle(struct homun_data *hd) { struct map_session_data *sd; int lv, i, skillpts; unsigned int exp; struct s_skill b_skill[MAX_HOMUNSKILL]; if (!merc_is_hom_active(hd)) return 0; sd = hd->master; lv = hd->homunculus.level; exp = hd->homunculus.exp; memcpy(&b_skill, &hd->homunculus.hskill, sizeof(b_skill)); skillpts = hd->homunculus.skillpts; //Reset values to level 1. merc_reset_stats(hd); //Level it back up for (i = 1; i < lv && hd->exp_next; i++){ hd->homunculus.exp += hd->exp_next; // Should never happen, but who knows if( !merc_hom_levelup(hd) ){ break; } } if(hd->homunculus.class_ == hd->homunculusDB->evo_class) { //Evolved bonuses struct s_homunculus *hom = &hd->homunculus; struct h_stats *max = &hd->homunculusDB->emax, *min = &hd->homunculusDB->emin; hom->max_hp += rnd_value(min->HP, max->HP); hom->max_sp += rnd_value(min->SP, max->SP); hom->str += 10*rnd_value(min->str, max->str); hom->agi += 10*rnd_value(min->agi, max->agi); hom->vit += 10*rnd_value(min->vit, max->vit); hom->int_+= 10*rnd_value(min->int_,max->int_); hom->dex += 10*rnd_value(min->dex, max->dex); hom->luk += 10*rnd_value(min->luk, max->luk); } hd->homunculus.exp = exp; memcpy(&hd->homunculus.hskill, &b_skill, sizeof(b_skill)); hd->homunculus.skillpts = skillpts; clif_homskillinfoblock(sd); status_calc_homunculus(hd,0); status_percent_heal(&hd->bl, 100, 100); clif_specialeffect(&hd->bl,568,AREA); return 1; }
/*========================================== * Saves character data. * Flag = 1: Character is quitting * Flag = 2: Character is changing map-servers *------------------------------------------*/ int chrif_save(struct map_session_data *sd, int flag) { nullpo_retr(-1, sd); if (!flag) //The flag check is needed to prevent 'nosave' taking effect when a jailed player logs out. pc_makesavestatus(sd); if(!chrif_isconnected()) { if (flag) sd->state.finalsave = 1; //Will save character on reconnect. return -1; } if (sd->state.finalsave) return -1; //Refuse to save a char already tagged for final saving. [Skotlex] //For data sync if (sd->state.storage_flag == 1) storage_storage_save(sd->status.account_id, flag); else if (sd->state.storage_flag == 2) storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag); if (flag) sd->state.storage_flag = 0; //Force close it. //Saving of registry values. if (sd->state.reg_dirty&4) intif_saveregistry(sd, 3); //Save char regs if (sd->state.reg_dirty&2) intif_saveregistry(sd, 2); //Save account regs if (sd->state.reg_dirty&1) intif_saveregistry(sd, 1); //Save account2 regs WFIFOHEAD(char_fd, sizeof(sd->status) + 13); WFIFOW(char_fd,0) = 0x2b01; WFIFOW(char_fd,2) = sizeof(sd->status) + 13; WFIFOL(char_fd,4) = sd->status.account_id; WFIFOL(char_fd,8) = sd->status.char_id; WFIFOB(char_fd,12) = (flag==1)?1:0; //Flag to tell char-server this character is quitting. memcpy(WFIFOP(char_fd,13), &sd->status, sizeof(sd->status)); WFIFOSET(char_fd, WFIFOW(char_fd,2)); if (sd->hd && merc_is_hom_active(sd->hd)) merc_save(sd->hd); if (flag) sd->state.finalsave = 1; //Mark the last save as done. return 0; }
int merc_hom_change_name(struct map_session_data *sd,char *name) { int i; struct homun_data *hd; nullpo_retr(1, sd); hd = sd->hd; if (!merc_is_hom_active(hd)) return 1; if(hd->homunculus.rename_flag && !battle_config.hom_rename) return 1; for(i=0;i<NAME_LENGTH && name[i];i++){ if( !(name[i]&0xe0) || name[i]==0x7f) return 1; } return intif_rename_hom(sd, name); }
/*========================================== * Saves character data. * Flag = 1: Character is quitting * Flag = 2: Character is changing map-servers *------------------------------------------*/ int chrif_save(struct map_session_data *sd, int flag) { nullpo_retr(-1, sd); pc_makesavestatus(sd); if (flag && sd->state.active) { //Store player data which is quitting //FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex] if ( chrif_isconnected() ) chrif_save_scdata(sd); if ( !chrif_auth_logout(sd,flag == 1 ? ST_LOGOUT : ST_MAPCHANGE) ) ShowError("chrif_save: Failed to set up player %d:%d for proper quitting!\n", sd->status.account_id, sd->status.char_id); } chrif_check(-1); //Character is saved on reconnect. //For data sync if (sd->state.storage_flag == 2) storage_guild_storagesave(sd->status.account_id, sd->status.guild_id, flag); if (flag) sd->state.storage_flag = 0; //Force close it. //Saving of registry values. if (sd->state.reg_dirty&4) intif_saveregistry(sd, 3); //Save char regs if (sd->state.reg_dirty&2) intif_saveregistry(sd, 2); //Save account regs if (sd->state.reg_dirty&1) intif_saveregistry(sd, 1); //Save account2 regs WFIFOHEAD(char_fd, sizeof(sd->status) + 13); WFIFOW(char_fd,0) = 0x2b01; WFIFOW(char_fd,2) = sizeof(sd->status) + 13; WFIFOL(char_fd,4) = sd->status.account_id; WFIFOL(char_fd,8) = sd->status.char_id; WFIFOB(char_fd,12) = (flag==1)?1:0; //Flag to tell char-server this character is quitting. // If the user is on a instance map, we have to fake his current position if( map[sd->bl.m].instance_id ){ struct mmo_charstatus status; // Copy the whole status memcpy( &status, &sd->status, sizeof( struct mmo_charstatus ) ); // Change his current position to his savepoint memcpy( &status.last_point, &status.save_point, sizeof( struct point ) ); // Copy the copied status into the packet memcpy( WFIFOP( char_fd, 13 ), &status, sizeof( struct mmo_charstatus ) ); } else { // Copy the whole status into the packet memcpy( WFIFOP( char_fd, 13 ), &sd->status, sizeof( struct mmo_charstatus ) ); } WFIFOSET(char_fd, WFIFOW(char_fd,2)); if( sd->status.pet_id > 0 && sd->pd ) intif_save_petdata(sd->status.account_id,&sd->pd->pet); if( sd->hd && merc_is_hom_active(sd->hd) ) merc_save(sd->hd); if( sd->md && mercenary_get_lifetime(sd->md) > 0 ) mercenary_save(sd->md); if( sd->ed && elemental_get_lifetime(sd->ed) > 0 ) elemental_save(sd->ed); if( sd->save_quest ) intif_quest_save(sd); return 0; }