summaryrefslogtreecommitdiff
path: root/src/map/pc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/pc.c')
-rw-r--r--src/map/pc.c237
1 files changed, 134 insertions, 103 deletions
diff --git a/src/map/pc.c b/src/map/pc.c
index 5416fbec2..5eccfbaf6 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -565,72 +565,8 @@ static int pc_inventory_rental_clear(struct map_session_data *sd)
/* assumes i is valid (from default areas where it is called, it is) */
static void pc_rental_expire(struct map_session_data *sd, int i)
{
- int nameid;
-
nullpo_retv(sd);
Assert_retv(i >= 0 && i < sd->status.inventorySize);
- nameid = sd->status.inventory[i].nameid;
-
- /* Soon to be dropped, we got plans to integrate it with item db */
- switch( nameid ) {
- case ITEMID_BOARDING_HALTER:
- status_change_end(&sd->bl,SC_ALL_RIDING,INVALID_TIMER);
- break;
- case ITEMID_LOVE_ANGEL:
- if( sd->status.font == 1 ) {
- sd->status.font = 0;
- clif->font(sd);
- }
- break;
- case ITEMID_SQUIRREL:
- if( sd->status.font == 2 ) {
- sd->status.font = 0;
- clif->font(sd);
- }
- break;
- case ITEMID_GOGO:
- if( sd->status.font == 3 ) {
- sd->status.font = 0;
- clif->font(sd);
- }
- break;
- case ITEMID_PICTURE_DIARY:
- if( sd->status.font == 4 ) {
- sd->status.font = 0;
- clif->font(sd);
- }
- break;
- case ITEMID_MINI_HEART:
- if( sd->status.font == 5 ) {
- sd->status.font = 0;
- clif->font(sd);
- }
- break;
- case ITEMID_NEWCOMER:
- if( sd->status.font == 6 ) {
- sd->status.font = 0;
- clif->font(sd);
- }
- break;
- case ITEMID_KID:
- if( sd->status.font == 7 ) {
- sd->status.font = 0;
- clif->font(sd);
- }
- break;
- case ITEMID_MAGIC_CASTLE:
- if( sd->status.font == 8 ) {
- sd->status.font = 0;
- clif->font(sd);
- }
- break;
- case ITEMID_BULGING_HEAD:
- if( sd->status.font == 9 ) {
- sd->status.font = 0;
- clif->font(sd);
- }
- break;
- }
clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid);
pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_RENTAL);
@@ -1536,17 +1472,16 @@ static int pc_reg_received(struct map_session_data *sd)
if (sd->status.guild_id)
guild->member_joined(sd);
- // pet
- if (sd->status.pet_id > 0)
- intif->request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id);
-
- // Homunculus [albator]
- if( sd->status.hom_id > 0 )
- intif->homunculus_requestload(sd->status.account_id, sd->status.hom_id);
- if( sd->status.mer_id > 0 )
- intif->mercenary_request(sd->status.mer_id, sd->status.char_id);
- if( sd->status.ele_id > 0 )
- intif->elemental_request(sd->status.ele_id, sd->status.char_id);
+ if (sd->state.standalone == 0 && sd->state.autotrade == 0) { // prevents loading pets, homunculi, mercenaries or elementals if the character doesn't have a client attached
+ if (sd->status.pet_id != 0)
+ intif->request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id);
+ if (sd->status.hom_id != 0)
+ intif->homunculus_requestload(sd->status.account_id, sd->status.hom_id);
+ if (sd->status.mer_id != 0)
+ intif->mercenary_request(sd->status.mer_id, sd->status.char_id);
+ if (sd->status.ele_id != 0)
+ intif->elemental_request(sd->status.ele_id, sd->status.char_id);
+ }
map->addiddb(&sd->bl);
map->delnickdb(sd->status.char_id, sd->status.name);
@@ -2268,7 +2203,7 @@ static int pc_bonus_item_drop(struct s_add_drop *drop, const short max, int id,
return 1;
}
-static int pc_addautobonus(struct s_autobonus *bonus, char max, const char *bonus_script, short rate, unsigned int dur, short flag, const char *other_script, unsigned short pos, bool onskill)
+static int pc_addautobonus(struct s_autobonus *bonus, char max, const char *bonus_script, short rate, unsigned int dur, short flag, const char *other_script, unsigned int pos, bool onskill)
{
int i;
@@ -4506,7 +4441,7 @@ static int pc_payzeny(struct map_session_data *sd, int zeny, enum e_log_pick_typ
if (sd->state.showzeny) {
char output[255];
- sprintf(output, "Removed %dz.", zeny);
+ sprintf(output, msg_sd(sd, 885), zeny); // Removed %dz.
clif_disp_onlyself(sd, output);
}
}
@@ -4645,7 +4580,7 @@ static int pc_getzeny(struct map_session_data *sd, int zeny, enum e_log_pick_typ
if (sd->state.showzeny) {
char output[255];
- sprintf(output, "Gained %dz.", zeny);
+ sprintf(output, msg_sd(sd, 886), zeny); // Gained %dz.
clif_disp_onlyself(sd, output);
}
}
@@ -4778,18 +4713,27 @@ static int pc_additem(struct map_session_data *sd, const struct item *item_data,
sd->weight += w;
clif->updatestatus(sd,SP_WEIGHT);
+
+ // auto-favorite
+ if (data->flag.auto_favorite > 0) {
+ sd->status.inventory[i].favorite = 1;
+ clif->favorite_item(sd, i);
+ }
+
//Auto-equip
if(data->flag.autoequip)
pc->equipitem(sd, i, data->equip);
/* rental item check */
- if( item_data->expire_time ) {
- if( time(NULL) > item_data->expire_time ) {
- pc->rental_expire(sd,i);
+ if (item_data->expire_time > 0) {
+ if (time(NULL) > item_data->expire_time) {
+ pc->rental_expire(sd, i);
} else {
- int seconds = (int)( item_data->expire_time - time(NULL) );
+ int seconds = (int)(item_data->expire_time - time(NULL));
clif->rental_time(sd->fd, sd->status.inventory[i].nameid, seconds);
pc->inventory_rental_add(sd, seconds);
+ if (data->rental_start_script != NULL)
+ script->run_item_rental_start_script(sd, data, 0);
}
}
quest->questinfo_refresh(sd);
@@ -4820,12 +4764,21 @@ static int pc_delitem(struct map_session_data *sd, int n, int amount, int type,
sd->status.inventory[n].amount -= amount;
sd->weight -= sd->inventory_data[n]->weight*amount ;
+
+ // It's here because the data would most likely get zeroed in following if [Hemagx]
+ struct item_data *itd = sd->inventory_data[n];
+ bool is_rental = (sd->status.inventory[n].expire_time > 0) ? true : false;
+
if( sd->status.inventory[n].amount <= 0 ){
if(sd->status.inventory[n].equip)
pc->unequipitem(sd, n, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
memset(&sd->status.inventory[n],0,sizeof(sd->status.inventory[0]));
sd->inventory_data[n] = NULL;
}
+
+ if (is_rental && itd->rental_end_script != NULL)
+ script->run_item_rental_end_script(sd, itd, 0);
+
if(!(type&1))
clif->delitem(sd,n,amount,reason);
if(!(type&2))
@@ -5582,9 +5535,9 @@ static int pc_show_steal(struct block_list *bl, va_list ap)
nullpo_ret(sd);
if((item=itemdb->exists(itemid))==NULL)
- sprintf(output,"%s stole an Unknown Item (id: %i).",sd->status.name, itemid);
+ sprintf(output, msg_sd(sd, 887), sd->status.name, itemid); // %s stole an Unknown Item (id: %i).
else
- sprintf(output,"%s stole %s.",sd->status.name,item->jname);
+ sprintf(output, msg_sd(sd, 888), sd->status.name, item->jname); // %s stole %s.
clif->message(tsd->fd, output);
return 0;
@@ -7131,11 +7084,16 @@ static bool pc_gainexp(struct map_session_data *sd, struct block_list *src, uint
if(sd->state.showexp) {
char output[256];
sprintf(output,
- "Experience Gained Base:%"PRIu64" (%.2f%%) Job:%"PRIu64" (%.2f%%)",
+ msg_sd(sd, 889), // Experience Gained Base:%"PRIu64" (%.2f%%) Job:%"PRIu64" (%.2f%%)
base_exp, nextbp * (float)100, job_exp, nextjp * (float)100);
clif_disp_onlyself(sd, output);
}
+ // Share master EXP to homunculus
+ if (sd->hd != NULL && battle_config.hom_bonus_exp_from_master > 0) {
+ homun->gainexp(sd->hd, apply_percentrate((int)base_exp, battle_config.hom_bonus_exp_from_master, 100));
+ }
+
return true;
}
@@ -7352,34 +7310,33 @@ static int pc_maxparameterincrease(struct map_session_data *sd, int type)
*/
static bool pc_statusup(struct map_session_data *sd, int type, int increase)
{
- int max_increase = 0, current = 0, needed_points = 0, final_value = 0;
-
nullpo_ret(sd);
+ int realIncrease = increase;
// check conditions
- if (type < SP_STR || type > SP_LUK || increase <= 0) {
- clif->statusupack(sd, type, 0, 0);
+ if (type < SP_STR || type > SP_LUK || realIncrease <= 0) {
+ clif->statusupack(sd, type, 0, increase);
return false;
}
// check limits
- current = pc->getstat(sd, type);
- max_increase = pc->maxparameterincrease(sd, type);
- increase = cap_value(increase, 0, max_increase); // cap to the maximum status points available
- if (increase <= 0 || current + increase > pc_maxparameter(sd)) {
- clif->statusupack(sd, type, 0, 0);
+ int current = pc->getstat(sd, type);
+ int max_increase = pc->maxparameterincrease(sd, type);
+ realIncrease = cap_value(realIncrease, 0, max_increase); // cap to the maximum status points available
+ if (realIncrease <= 0 || current + realIncrease > pc_maxparameter(sd)) {
+ clif->statusupack(sd, type, 0, increase);
return false;
}
// check status points
- needed_points = pc->need_status_point(sd, type, increase);
+ int needed_points = pc->need_status_point(sd, type, realIncrease);
if (needed_points < 0 || needed_points > sd->status.status_point) { // Sanity check
- clif->statusupack(sd, type, 0, 0);
+ clif->statusupack(sd, type, 0, increase);
return false;
}
// set new values
- final_value = pc->setstat(sd, type, current + increase);
+ int final_value = pc->setstat(sd, type, current + realIncrease);
sd->status.status_point -= needed_points;
status_calc_pc(sd, SCO_NONE);
@@ -7754,7 +7711,7 @@ static int pc_resetskill(struct map_session_data *sd, int flag)
pc->setoption(sd, i);
if( homun_alive(sd->hd) && pc->checkskill(sd, AM_CALLHOMUN) )
- homun->vaporize(sd, HOM_ST_REST);
+ homun->vaporize(sd, HOM_ST_REST, true);
if ((sd->sc.data[SC_SPRITEMABLE] && pc->checkskill(sd, SU_SPRITEMABLE)))
status_change_end(&sd->bl, SC_SPRITEMABLE, INVALID_TIMER);
@@ -7995,7 +7952,7 @@ static void pc_damage(struct map_session_data *sd, struct block_list *src, unsig
if( sd->status.pet_id > 0 && sd->pd && battle_config.pet_damage_support )
pet->target_check(sd,src,1);
- if( sd->status.ele_id > 0 )
+ if (sd->status.ele_id != 0 && sd->ed != NULL)
elemental->set_target(sd,src);
if (battle_config.prevent_logout_trigger & PLT_DAMAGE)
@@ -8043,7 +8000,7 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src)
if (sd->status.hom_id > 0){
if(battle_config.homunculus_auto_vapor && sd->hd)
- homun->vaporize(sd, HOM_ST_REST);
+ homun->vaporize(sd, HOM_ST_REST, true);
}
if( sd->md )
@@ -9058,7 +9015,7 @@ static int pc_jobchange(struct map_session_data *sd, int class, int upper)
pc->setoption(sd, i);
if(homun_alive(sd->hd) && !pc->checkskill(sd, AM_CALLHOMUN))
- homun->vaporize(sd, HOM_ST_REST);
+ homun->vaporize(sd, HOM_ST_REST, true);
if ((sd->sc.data[SC_SPRITEMABLE] && pc->checkskill(sd, SU_SPRITEMABLE)))
status_change_end(&sd->bl, SC_SPRITEMABLE, INVALID_TIMER);
@@ -10979,7 +10936,7 @@ static int map_day_timer(int tid, int64 tick, int id, intptr_t data)
map->night_flag = 0; // 0=day, 1=night [Yor]
map->foreachpc(pc->daynight_timer_sub);
safestrncpy(tmp_soutput, (data == 0) ? msg_txt(502) : msg_txt(60), sizeof(tmp_soutput)); // The day has arrived!
- intif->broadcast(tmp_soutput, (int)strlen(tmp_soutput) + 1, BC_DEFAULT);
+ clif->broadcast(NULL, tmp_soutput, (int)strlen(tmp_soutput) + 1, BC_DEFAULT, ALL_CLIENT);
return 0;
}
@@ -11000,7 +10957,7 @@ static int map_night_timer(int tid, int64 tick, int id, intptr_t data)
map->night_flag = 1; // 0=day, 1=night [Yor]
map->foreachpc(pc->daynight_timer_sub);
safestrncpy(tmp_soutput, (data == 0) ? msg_txt(503) : msg_txt(59), sizeof(tmp_soutput)); // The night has fallen...
- intif->broadcast(tmp_soutput, (int)strlen(tmp_soutput) + 1, BC_DEFAULT);
+ clif->broadcast(NULL, tmp_soutput, (int)strlen(tmp_soutput) + 1, BC_DEFAULT, ALL_CLIENT);
return 0;
}
@@ -12204,6 +12161,29 @@ static int pc_have_magnifier(struct map_session_data *sd)
}
/**
+ * checks if player have any item that listed in item chain
+ * @param sd map_session_data of Player
+ * @param chain_id unsigned short of item chain id
+ * @return index of inventory, INDEX_NOT_FOUND if it is not found
+ */
+static int pc_have_item_chain(struct map_session_data *sd, unsigned short chain_id)
+{
+ if (chain_id >= itemdb->chain_count) {
+ ShowError("itemdb_chain_item: unknown chain id %d\n", chain_id);
+ return INDEX_NOT_FOUND;
+ }
+
+ for (int n = 0; n < itemdb->chains[chain_id].qty; n++) {
+ struct item_chain_entry *entry = &itemdb->chains[chain_id].items[n];
+ int index = pc->search_inventory(sd, entry->id);
+ if (index != INDEX_NOT_FOUND)
+ return index;
+ }
+
+ return INDEX_NOT_FOUND;
+}
+
+/**
* Checks if player have basic skills learned.
* @param sd Player Data
* @param level Required Level of Novice Skill
@@ -12300,6 +12280,54 @@ static void pc_check_supernovice_call(struct map_session_data *sd, const char *m
}
}
+/**
+ * Sends a message t all online GMs having the specified permission.
+ *
+ * @param sender_name Sender character name.
+ * @param permission The required permission to receive this message.
+ * @param message The message body.
+ *
+ * @return The amount of characters the message was delivered to.
+ */
+// The transmission of GM only Wisp/Page from server to inter-server
+static int pc_wis_message_to_gm(const char *sender_name, int permission, const char *message)
+{
+ nullpo_ret(sender_name);
+ nullpo_ret(message);
+ int mes_len = (int)strlen(message) + 1; // + null
+ int count = 0;
+
+ // information is sent to all online GM
+ map->foreachpc(pc->wis_message_to_gm_sub, permission, sender_name, message, mes_len, &count);
+
+ return count;
+}
+
+/**
+ * Helper function for pc_wis_message_to_gm().
+ */
+static int pc_wis_message_to_gm_sub(struct map_session_data *sd, va_list va)
+{
+ nullpo_ret(sd);
+
+ int permission = va_arg(va, int);
+ if (!pc_has_permission(sd, permission))
+ return 0;
+
+ const char *sender_name = va_arg(va, const char *);
+ const char *message = va_arg(va, const char *);
+ int len = va_arg(va, int);
+ int *count = va_arg(va, int *);
+
+ nullpo_ret(sender_name);
+ nullpo_ret(message);
+ nullpo_ret(count);
+
+ clif->wis_message(sd->fd, sender_name, message, len);
+ ++*count;
+ return 1;
+}
+
static void pc_update_job_and_level(struct map_session_data *sd)
{
nullpo_retv(sd);
@@ -12747,6 +12775,8 @@ void pc_defaults(void)
pc->check_supernovice_call = pc_check_supernovice_call;
pc->process_chat_message = pc_process_chat_message;
+ pc->wis_message_to_gm = pc_wis_message_to_gm;
+ pc->wis_message_to_gm_sub = pc_wis_message_to_gm_sub;
/**
* Autotrade persistency [Ind/Hercules <3]
@@ -12762,6 +12792,7 @@ void pc_defaults(void)
pc->update_idle_time = pc_update_idle_time;
pc->have_magnifier = pc_have_magnifier;
+ pc->have_item_chain = pc_have_item_chain;
pc->check_basicskill = pc_check_basicskill;