Implemented new adoption methods

* Implemented atcommand adopt.
* Implemented script command adopt.
* Circumvents adoption issues with 2013-08+ clients (Related to #768).
* Suggested from https://rathena.org/board/topic/104014-suggestion-add-adopt-or-etc/
This commit is contained in:
aleos89 2016-03-11 13:45:17 -05:00
parent ac1db5de02
commit 0f5b6db813
9 changed files with 214 additions and 29 deletions

View File

@ -785,7 +785,15 @@
741: Gained
742: Lost
743: Experience %s Base:%ld (%0.2f%%) Job:%ld (%0.2f%%)
//744-899 free
// @adopt
744: Baby already adopted or is in the process of being adopted.
745: You need to be married and in a party with your partner and the Baby to adopt.
746: Both parents need to have their wedding rings equipped.
747: The Baby is not a Novice.
748: A parent or Baby was not found.
//749-899 free
//------------------------------------
// More atcommands message

View File

@ -5536,6 +5536,26 @@ current SVN, which prevents the cases of multi-spouse problems). It will return
This function will also destroy both wedding rings and send a message to both
players, telling them they are now divorced.
---------------------------------------
*adopt("<parent_name>","<baby_name>");
*adopt(<parent_id>,<baby_id>);
This function will send the client adoption request to the specified baby
character. The parent value can be either parent. Both parents and the baby
need to be online in order for adoption to work.
Return values:
ADOPT_ALLOWED - Sent message to Baby to accept or deny.
ADOPT_ALREADY_ADOPTED - Character is already adopted.
ADOPT_MARRIED_AND_PARTY - Parents need to be married and in a party with the baby.
ADOPT_EQUIP_RINGS - Parents need wedding rings equipped.
ADOPT_NOT_NOVICE - Baby is not a Novice.
ADOPT_CHARACTER_NOT_FOUND - A parent or Baby was not found.
ADOPT_MORE_CHILDREN - You cannot adopt more than 1 child. (client message)
ADOPT_LEVEL_70 - Parents need to be at least level 70 in order to adopt someone. (client message)
ADOPT_MARRIED - You cannot adopt a married person. (client message)
---------------------------------------
//
4,3.- End of marriage-related commands

View File

@ -9783,6 +9783,49 @@ ACMD_FUNC(clonestat) {
return 0;
}
/**
* Adopt a character.
* Usage: @adopt <char name>
* https://rathena.org/board/topic/104014-suggestion-add-adopt-or-etc/
*/
ACMD_FUNC(adopt)
{
TBL_PC *b_sd;
enum adopt_responses response;
nullpo_retr(-1, sd);
memset(atcmd_output, '\0', sizeof(atcmd_output));
memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) {
sprintf(atcmd_output, msg_txt(sd, 435), command); // Please enter a player name (usage: %s <char name>).
clif_displaymessage(fd, atcmd_output);
return -1;
}
if ((b_sd = map_nick2sd((char *)atcmd_player_name)) == NULL) {
clif_displaymessage(fd, msg_txt(sd, 3)); // Character not found.
return -1;
}
response = pc_try_adopt(sd, map_charid2sd(sd->status.partner_id), b_sd);
if (response == ADOPT_ALLOWED) {
TBL_PC *p_sd = map_charid2sd(sd->status.partner_id);
b_sd->adopt_invite = sd->status.account_id;
clif_Adopt_request(b_sd, sd, p_sd->status.account_id);
return 0;
}
if (response < ADOPT_MORE_CHILDREN) { // No displaymessage for client-type responses
sprintf(atcmd_output, msg_txt(sd, 744 + response - 1));
clif_displaymessage(fd, atcmd_output);
}
return -1;
}
#include "../custom/atcommand.inc"
/**
@ -10075,6 +10118,7 @@ void atcommand_basecommands(void) {
ACMD_DEF(cloneequip),
ACMD_DEF(clonestat),
ACMD_DEF(bodystyle),
ACMD_DEF(adopt),
};
AtCommandInfo* atcommand;
int i;

View File

@ -15755,9 +15755,9 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd){
/// Adoption message (ZC_BABYMSG).
/// 0216 <msg>.L
/// msg:
/// 0 = "You cannot adopt more than 1 child."
/// 1 = "You must be at least character level 70 in order to adopt someone."
/// 2 = "You cannot adopt a married person."
/// ADOPT_REPLY_MORE_CHILDREN = "You cannot adopt more than 1 child."
/// ADOPT_REPLY_LEVEL_70 = "You must be at least character level 70 in order to adopt someone."
/// ADOPT_REPLY_MARRIED = "You cannot adopt a married person."
void clif_Adopt_reply(struct map_session_data *sd, int type)
{
int fd = sd->fd;
@ -15791,7 +15791,7 @@ void clif_parse_Adopt_request(int fd, struct map_session_data *sd)
TBL_PC *tsd = map_id2sd(RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]));
TBL_PC *p_sd = map_charid2sd(sd->status.partner_id);
if( pc_can_Adopt(sd, p_sd, tsd) )
if( pc_try_adopt(sd, p_sd, tsd) == ADOPT_ALLOWED )
{
tsd->adopt_invite = sd->status.account_id;
clif_Adopt_request(tsd, sd, p_sd->status.account_id);

View File

@ -136,6 +136,12 @@ enum BROADCASTING_SPECIAL_ITEM_OBTAIN {
ITEMOBTAIN_TYPE_NPC = 0x2,
};
enum e_adopt_reply {
ADOPT_REPLY_MORE_CHILDREN = 0,
ADOPT_REPLY_LEVEL_70,
ADOPT_REPLY_MARRIED,
};
// packet_db[SERVER] is reserved for server use
#define SERVER 0
#define packet_len(cmd) packet_db[SERVER][cmd].len
@ -855,6 +861,7 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd);
// ADOPTION
void clif_Adopt_reply(struct map_session_data *sd, int type);
void clif_Adopt_request(struct map_session_data *sd, struct map_session_data *src, int p_id);
// MERCENARIES
void clif_mercenary_info(struct map_session_data *sd);

View File

@ -868,57 +868,66 @@ bool pc_isequipped(struct map_session_data *sd, unsigned short nameid)
return false;
}
/** Check adopt rule
* @param p1_sd Player 1
* @param p2_sd Player 2
* @param b_sd Player that will be adopted
* @return True - if can be adopted, False otherwise
*/
bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd )
/**
* Check adoption rules
* @param p1_sd: Player 1
* @param p2_sd: Player 2
* @param b_sd: Player that will be adopted
* @return ADOPT_ALLOWED - Sent message to Baby to accept or deny
* ADOPT_ALREADY_ADOPTED - Already adopted
* ADOPT_MARRIED_AND_PARTY - Need to be married and in the same party
* ADOPT_EQUIP_RINGS - Need wedding rings equipped
* ADOPT_NOT_NOVICE - Adoptee is not a Novice
* ADOPT_CHARACTER_NOT_FOUND - Parent or Baby not found
* ADOPT_MORE_CHILDREN - Cannot adopt more than 1 Baby (client message)
* ADOPT_LEVEL_70 - Parents need to be level 70+ (client message)
* ADOPT_MARRIED - Cannot adopt a married person (client message)
*/
enum adopt_responses pc_try_adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd)
{
if( !p1_sd || !p2_sd || !b_sd )
return false;
return ADOPT_CHARACTER_NOT_FOUND;
if( b_sd->status.father || b_sd->status.mother || b_sd->adopt_invite )
return false; // already adopted baby / in adopt request
return ADOPT_ALREADY_ADOPTED; // already adopted baby / in adopt request
if( !p1_sd->status.partner_id || !p1_sd->status.party_id || p1_sd->status.party_id != b_sd->status.party_id )
return false; // You need to be married and in party with baby to adopt
return ADOPT_MARRIED_AND_PARTY; // You need to be married and in party with baby to adopt
if( p1_sd->status.partner_id != p2_sd->status.char_id || p2_sd->status.partner_id != p1_sd->status.char_id )
return false; // Not married, wrong married
return ADOPT_MARRIED_AND_PARTY; // Not married, wrong married
if( p2_sd->status.party_id != p1_sd->status.party_id )
return false; // Both parents need to be in the same party
return ADOPT_MARRIED_AND_PARTY; // Both parents need to be in the same party
// Parents need to have their ring equipped
if( !pc_isequipped(p1_sd, WEDDING_RING_M) && !pc_isequipped(p1_sd, WEDDING_RING_F) )
return false;
return ADOPT_EQUIP_RINGS;
if( !pc_isequipped(p2_sd, WEDDING_RING_M) && !pc_isequipped(p2_sd, WEDDING_RING_F) )
return false;
return ADOPT_EQUIP_RINGS;
// Already adopted a baby
if( p1_sd->status.child || p2_sd->status.child ) {
clif_Adopt_reply(p1_sd, 0);
return false;
clif_Adopt_reply(p1_sd, ADOPT_REPLY_MORE_CHILDREN);
return ADOPT_MORE_CHILDREN;
}
// Parents need at least lvl 70 to adopt
if( p1_sd->status.base_level < 70 || p2_sd->status.base_level < 70 ) {
clif_Adopt_reply(p1_sd, 1);
return false;
clif_Adopt_reply(p1_sd, ADOPT_REPLY_LEVEL_70);
return ADOPT_LEVEL_70;
}
if( b_sd->status.partner_id ) {
clif_Adopt_reply(p1_sd, 2);
return false;
clif_Adopt_reply(p1_sd, ADOPT_REPLY_MARRIED);
return ADOPT_MARRIED;
}
if( !( ( b_sd->status.class_ >= JOB_NOVICE && b_sd->status.class_ <= JOB_THIEF ) || b_sd->status.class_ == JOB_SUPER_NOVICE || b_sd->status.class_ == JOB_SUPER_NOVICE_E ) )
return false;
return ADOPT_NOT_NOVICE;
return true;
return ADOPT_ALLOWED;
}
/*==========================================
@ -929,7 +938,7 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd,
int job, joblevel;
unsigned int jobexp;
if( !pc_can_Adopt(p1_sd, p2_sd, b_sd) )
if( pc_try_adopt(p1_sd, p2_sd, b_sd) != ADOPT_ALLOWED )
return false;
// Preserve current job levels and progress

View File

@ -749,6 +749,18 @@ enum idletime_option {
IDLE_ATCOMMAND = 0x200,
};
enum adopt_responses {
ADOPT_ALLOWED = 0,
ADOPT_ALREADY_ADOPTED,
ADOPT_MARRIED_AND_PARTY,
ADOPT_EQUIP_RINGS,
ADOPT_NOT_NOVICE,
ADOPT_CHARACTER_NOT_FOUND,
ADOPT_MORE_CHILDREN,
ADOPT_LEVEL_70,
ADOPT_MARRIED,
};
struct {
unsigned int base_hp[MAX_LEVEL], base_sp[MAX_LEVEL]; //Storage for the first calculation with hp/sp factor and multiplicator
int hp_factor, hp_multiplicator, sp_factor;
@ -966,7 +978,7 @@ bool pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem);
bool pc_dropitem(struct map_session_data *sd,int n,int amount);
bool pc_isequipped(struct map_session_data *sd, unsigned short nameid);
bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd );
enum adopt_responses pc_try_adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd);
bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd);
void pc_updateweightstatus(struct map_session_data *sd);

View File

@ -21095,6 +21095,80 @@ BUILDIN_FUNC(navigateto){
#endif
}
/**
* adopt("<parent_name>","<baby_name>");
* adopt(<parent_id>,<baby_id>);
* https://rathena.org/board/topic/104014-suggestion-add-adopt-or-etc/
*/
BUILDIN_FUNC(adopt)
{
TBL_PC *sd, *b_sd;
struct script_data *data;
enum adopt_responses response;
data = script_getdata(st, 2);
get_val(st, data);
if (data_isstring(data)) {
const char *name = conv_str(st, data);
sd = map_nick2sd(name);
if (sd == NULL) {
ShowError("buildin_adopt: Non-existant parent character %s requested.\n", name);
return SCRIPT_CMD_FAILURE;
}
} else if (data_isint(data)) {
uint32 char_id = conv_num(st, data);
sd = map_charid2sd(char_id);
if (sd == NULL) {
ShowError("buildin_adopt: Non-existant parent character %d requested.\n", char_id);
return SCRIPT_CMD_FAILURE;
}
} else {
ShowError("buildin_adopt: Invalid data type for argument #1 (%d).", data->type);
return SCRIPT_CMD_FAILURE;
}
data = script_getdata(st, 3);
get_val(st, data);
if (data_isstring(data)) {
const char *name = conv_str(st, data);
b_sd = map_nick2sd(name);
if (b_sd == NULL) {
ShowError("buildin_adopt: Non-existant baby character %s requested.\n", name);
return SCRIPT_CMD_FAILURE;
}
} else if (data_isint(data)) {
uint32 char_id = conv_num(st, data);
b_sd = map_charid2sd(char_id);
if (b_sd == NULL) {
ShowError("buildin_adopt: Non-existant baby character %d requested.\n", char_id);
return SCRIPT_CMD_FAILURE;
}
} else {
ShowError("buildin_adopt: Invalid data type for argument #2 (%d).", data->type);
return SCRIPT_CMD_FAILURE;
}
response = pc_try_adopt(sd, map_charid2sd(sd->status.partner_id), b_sd);
if (response == ADOPT_ALLOWED) {
TBL_PC *p_sd = map_charid2sd(sd->status.partner_id);
b_sd->adopt_invite = sd->status.account_id;
clif_Adopt_request(b_sd, sd, p_sd->status.account_id);
script_pushint(st, ADOPT_ALLOWED);
return SCRIPT_CMD_SUCCESS;
}
script_pushint(st, response);
return SCRIPT_CMD_FAILURE;
}
#include "../custom/script.inc"
// declarations that were supposed to be exported from npc_chat.c
@ -21662,6 +21736,7 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(setquestinfo_job,"ii*"),
BUILDIN_DEF(opendressroom,"i?"),
BUILDIN_DEF(navigateto,"s???????"),
BUILDIN_DEF(adopt,"vv"),
#include "../custom/script_def.inc"

View File

@ -3004,6 +3004,16 @@
export_constant(NAV_KAFRA_AND_SCROLL);
export_constant(NAV_ALL);
export_constant(ADOPT_ALLOWED);
export_constant(ADOPT_ALREADY_ADOPTED);
export_constant(ADOPT_MARRIED_AND_PARTY);
export_constant(ADOPT_EQUIP_RINGS);
export_constant(ADOPT_NOT_NOVICE);
export_constant(ADOPT_CHARACTER_NOT_FOUND);
export_constant(ADOPT_MORE_CHILDREN);
export_constant(ADOPT_LEVEL_70);
export_constant(ADOPT_MARRIED);
#undef export_constant
#endif /* _SCRIPT_CONSTANTS_H_ */