Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Costume #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions conf/battle/battle.conf
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,9 @@ warg_can_falcon: no
// Should the target be able of dodging damage by snapping away to the edge of the screen?
// Official behavior is "no"
snap_dodge: no

// ****************************************
// Reserved Costume ID's
// ****************************************
// Reserved Char ID for costume converted items.
reserved_costume_id: 999998
19 changes: 19 additions & 0 deletions doc/script_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10079,6 +10079,25 @@ solution rather than sending the map and the monster_id.

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

*costume <equipment position>;

Converts equipment in <equipment position> to costume version that has no stats.

Applicable positions are:
EQI_HEAD_TOP - Top Headgear
EQI_HEAD_MID - Middle Headgear
EQI_HEAD_LOW - Lower Headgear
EQI_GARMENT - Garment

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

*getcostumeitem <item id>;
*getcostumeitem <"item name">;

Spawn a costume version of an <item id> or <"item name"> in attached player's inventory.

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

*hateffect(<Hat Effect ID>,<State>);

This will set a Hat Effect onto the player. The state field allows you to
Expand Down
29 changes: 28 additions & 1 deletion src/map/atcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1255,7 +1255,7 @@ ACMD_FUNC(heal)
ACMD_FUNC(item)
{
char item_name[100];
int number = 0, bound = BOUND_NONE;
int number = 0, bound = BOUND_NONE, costume = 0;
char flag = 0;
struct item item_tmp;
struct item_data *item_data[10];
Expand Down Expand Up @@ -1304,6 +1304,27 @@ ACMD_FUNC(item)

for(j--; j>=0; j--){ //produce items in list
unsigned short item_id = item_data[j]->nameid;
if (!strcmpi(command + 1, "costumeitem"))
{
if (!battle_config.reserved_costume_id)
{
clif_displaymessage(fd, "Costume convertion is disable. Set a value for reserved_cosutme_id on your battle.conf file.");
return -1;
}
if (!(item_data[j]->equip&EQP_HEAD_LOW) &&
!(item_data[j]->equip&EQP_HEAD_MID) &&
!(item_data[j]->equip&EQP_HEAD_TOP) &&
!(item_data[j]->equip&EQP_COSTUME_HEAD_LOW) &&
!(item_data[j]->equip&EQP_COSTUME_HEAD_MID) &&
!(item_data[j]->equip&EQP_COSTUME_HEAD_TOP) &&
!(item_data[j]->equip&EQP_GARMENT) &&
!(item_data[j]->equip&EQP_COSTUME_GARMENT))
{
clif_displaymessage(fd, "You cannot costume this item. Costume only work for headgears.");
return -1;
}
costume = 1;
}
//Check if it's stackable.
if (!itemdb_isstackable2(item_data[j]))
get_count = 1;
Expand All @@ -1314,6 +1335,11 @@ ACMD_FUNC(item)
memset(&item_tmp, 0, sizeof(item_tmp));
item_tmp.nameid = item_id;
item_tmp.identify = 1;
if (costume == 1) { // Costume item
item_tmp.card[0] = CARD0_CREATE;
item_tmp.card[2] = GetWord(battle_config.reserved_costume_id, 0);
item_tmp.card[3] = GetWord(battle_config.reserved_costume_id, 1);
}
item_tmp.bound = bound;
if ((flag = pc_additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND)))
clif_additem(sd, 0, 0, flag);
Expand Down Expand Up @@ -10348,6 +10374,7 @@ void atcommand_basecommands(void) {
ACMD_DEF(clonestat),
ACMD_DEF(bodystyle),
ACMD_DEF(adopt),
ACMD_DEF2("costumeitem", item),
ACMD_DEF(agitstart3),
ACMD_DEF(agitend3),
ACMD_DEFR(limitedsale, ATCMD_NOCONSOLE|ATCMD_NOAUTOTRADE),
Expand Down
1 change: 1 addition & 0 deletions src/map/battle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8485,6 +8485,7 @@ static const struct _battle_data {
{ "exp_cost_inspiration", &battle_config.exp_cost_inspiration, 1, 0, 100, },
{ "mvp_exp_reward_message", &battle_config.mvp_exp_reward_message, 0, 0, 1, },
{ "can_damage_skill", &battle_config.can_damage_skill, 1, 0, BL_ALL, },
{ "reserved_costume_id", &battle_config.reserved_costume_id, 999998, 0, INT_MAX, },
{ "atcommand_levelup_events", &battle_config.atcommand_levelup_events, 0, 0, 1, },
{ "atcommand_disable_npc", &battle_config.atcommand_disable_npc, 1, 0, 1, },
{ "block_account_in_same_party", &battle_config.block_account_in_same_party, 1, 0, 1, },
Expand Down
1 change: 1 addition & 0 deletions src/map/battle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ struct Battle_Config
int exp_cost_inspiration;
int mvp_exp_reward_message;
int can_damage_skill; //Which BL types can damage traps
int reserved_costume_id;
int atcommand_levelup_events;
int atcommand_disable_npc;
int block_account_in_same_party;
Expand Down
6 changes: 6 additions & 0 deletions src/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,12 @@ void map_reqnickdb(struct map_session_data * sd, int charid)

nullpo_retv(sd);

if (battle_config.reserved_costume_id && battle_config.reserved_costume_id == charid)
{
clif_solved_charname(sd->fd, charid, "Costume");
return;
}

tsd = map_charid2sd(charid);
if( tsd )
{
Expand Down
14 changes: 13 additions & 1 deletion src/map/pc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,7 @@ int pc_equippoint_sub(struct map_session_data *sd,struct item_data* id){
return EQP_SHADOW_ARMS;
}
}

return ep;
}

Expand All @@ -891,7 +892,18 @@ int pc_equippoint_sub(struct map_session_data *sd,struct item_data* id){
int pc_equippoint(struct map_session_data *sd,int n){
nullpo_ret(sd);

return pc_equippoint_sub(sd,sd->inventory_data[n]);
int ep = pc_equippoint_sub(sd, sd->inventory_data[n]);

if (battle_config.reserved_costume_id &&
sd->inventory.u.items_inventory[n].card[0] == CARD0_CREATE &&
MakeDWord(sd->inventory.u.items_inventory[n].card[2], sd->inventory.u.items_inventory[n].card[3]) == battle_config.reserved_costume_id)
{ // Costume Item - Converted
if (ep&EQP_HEAD_TOP) { ep &= ~EQP_HEAD_TOP; ep |= EQP_COSTUME_HEAD_TOP; }
if (ep&EQP_HEAD_LOW) { ep &= ~EQP_HEAD_LOW; ep |= EQP_COSTUME_HEAD_LOW; }
if (ep&EQP_HEAD_MID) { ep &= ~EQP_HEAD_MID; ep |= EQP_COSTUME_HEAD_MID; }
if (ep&EQP_GARMENT) { ep &= ~EQP_GARMENT; ep |= EQP_COSTUME_GARMENT; }
}
return ep;
}

/**
Expand Down
110 changes: 110 additions & 0 deletions src/map/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22821,6 +22821,114 @@ BUILDIN_FUNC(getexp2) {
return SCRIPT_CMD_SUCCESS;
}

/*==========================================
* Costume Items
*------------------------------------------*/
BUILDIN_FUNC(costume)
{
int i = -1, num, ep;
TBL_PC *sd;

num = script_getnum(st, 2); // Equip Slot

if (!script_rid2sd(sd))
return SCRIPT_CMD_FAILURE;

if (equip_index_check(num))
i = pc_checkequip(sd, equip_bitmask[num]);
if (i < 0)
return SCRIPT_CMD_FAILURE;

ep = sd->inventory.u.items_inventory[i].equip;
if (!(ep&EQP_HEAD_LOW) && !(ep&EQP_HEAD_MID) && !(ep&EQP_HEAD_TOP) && !(ep&EQP_GARMENT)) {
ShowError("buildin_costume: Attempted to convert non-cosmetic item to costume.");
return SCRIPT_CMD_FAILURE;
}
log_pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->inventory.u.items_inventory[i]);
pc_unequipitem(sd, i, 2);
clif_delitem(sd, i, 1, 3);
// --------------------------------------------------------------------
sd->inventory.u.items_inventory[i].refine = 0;
sd->inventory.u.items_inventory[i].attribute = 0;
sd->inventory.u.items_inventory[i].card[0] = CARD0_CREATE;
sd->inventory.u.items_inventory[i].card[1] = 0;
sd->inventory.u.items_inventory[i].card[2] = GetWord(battle_config.reserved_costume_id, 0);
sd->inventory.u.items_inventory[i].card[3] = GetWord(battle_config.reserved_costume_id, 1);

if (ep&EQP_HEAD_TOP) { ep &= ~EQP_HEAD_TOP; ep |= EQP_COSTUME_HEAD_TOP; }
if (ep&EQP_HEAD_LOW) { ep &= ~EQP_HEAD_LOW; ep |= EQP_COSTUME_HEAD_LOW; }
if (ep&EQP_HEAD_MID) { ep &= ~EQP_HEAD_MID; ep |= EQP_COSTUME_HEAD_MID; }
if (ep&EQP_GARMENT) { ep &= EQP_GARMENT; ep |= EQP_COSTUME_GARMENT; }
// --------------------------------------------------------------------
log_pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->inventory.u.items_inventory[i]);

clif_additem(sd, i, 1, 0);
pc_equipitem(sd, i, ep);
clif_misceffect(&sd->bl, 3);

return SCRIPT_CMD_SUCCESS;
}

/*===============================
* getcostumeitem <item id>;
* getcostumeitem <"item name">;
*===============================*/
BUILDIN_FUNC(getcostumeitem)
{
unsigned short nameid;
struct item item_tmp;
TBL_PC *sd;
struct script_data *data;

if (!script_rid2sd(sd))
{ // No player attached.
script_pushint(st, 0);
return SCRIPT_CMD_SUCCESS;
}

data = script_getdata(st, 2);
get_val(st, data);
if (data_isstring(data)) {
int ep;
const char *name = conv_str(st, data);
struct item_data *item_data = itemdb_searchname(name);
if (item_data == NULL)
{ //Failed
script_pushint(st, 0);
return SCRIPT_CMD_SUCCESS;
}
ep = item_data->equip;
if (!(ep&EQP_HEAD_LOW) && !(ep&EQP_HEAD_MID) && !(ep&EQP_HEAD_TOP) && !(ep&EQP_GARMENT)){
ShowError("buildin_getcostumeitem: Attempted to convert non-cosmetic item to costume.");
return SCRIPT_CMD_FAILURE;
}
nameid = item_data->nameid;
}
else
nameid = conv_num(st, data);

if (!itemdb_exists(nameid))
{ // Item does not exist.
script_pushint(st, 0);
return SCRIPT_CMD_SUCCESS;
}

memset(&item_tmp, 0, sizeof(item_tmp));
item_tmp.nameid = nameid;
item_tmp.amount = 1;
item_tmp.identify = 1;
item_tmp.card[0] = CARD0_CREATE;
item_tmp.card[2] = GetWord(battle_config.reserved_costume_id, 0);
item_tmp.card[3] = GetWord(battle_config.reserved_costume_id, 1);
if (pc_additem(sd, &item_tmp, 1, LOG_TYPE_SCRIPT)) {
script_pushint(st, 0);
return SCRIPT_CMD_SUCCESS; //Failed to add item, we will not drop if they don't fit
}

script_pushint(st, 1);
return SCRIPT_CMD_SUCCESS;
}

/**
* Force stat recalculation of sd
* recalculatestat;
Expand Down Expand Up @@ -25071,6 +25179,8 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(getguildalliance,"ii"),
BUILDIN_DEF(adopt,"vv"),
BUILDIN_DEF(getexp2,"ii?"),
BUILDIN_DEF(costume, "i"),
BUILDIN_DEF(getcostumeitem, "v"),
BUILDIN_DEF(recalculatestat,""),
BUILDIN_DEF(hateffect,"ii"),
BUILDIN_DEF(getrandomoptinfo, "i"),
Expand Down
2 changes: 2 additions & 0 deletions src/map/status.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3596,6 +3596,8 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt)
continue;
if (!sd->inventory_data[index])
continue;
if (sd->inventory.u.items_inventory[current_equip_item_index].card[0] == CARD0_CREATE && MakeDWord(sd->inventory.u.items_inventory[current_equip_item_index].card[2], sd->inventory.u.items_inventory[current_equip_item_index].card[3]) == battle_config.reserved_costume_id)
continue;

base_status->def += sd->inventory_data[index]->def;

Expand Down