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.c2480
1 files changed, 1500 insertions, 980 deletions
diff --git a/src/map/pc.c b/src/map/pc.c
index 9ef7d084f..5410ae96a 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -2,7 +2,7 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2016 Hercules Dev Team
+ * Copyright (C) 2012-2018 Hercules Dev Team
* Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
@@ -29,6 +29,7 @@
#include "map/channel.h"
#include "map/chat.h"
#include "map/chrif.h"
+#include "map/clan.h"
#include "map/clif.h"
#include "map/date.h" // is_day_of_*()
#include "map/duel.h"
@@ -42,6 +43,7 @@
#include "map/mail.h"
#include "map/map.h"
#include "map/mercenary.h"
+#include "map/messages.h"
#include "map/mob.h" // struct mob_data
#include "map/npc.h" // fake_nd
#include "map/party.h" // party-"search()
@@ -53,6 +55,7 @@
#include "map/skill.h"
#include "map/status.h" // struct status_data
#include "map/storage.h"
+#include "map/achievement.h"
#include "common/cbasetypes.h"
#include "common/conf.h"
#include "common/core.h" // get_svn_revision()
@@ -74,13 +77,15 @@
#include <string.h>
#include <time.h>
-struct pc_interface pc_s;
+static struct pc_interface pc_s;
struct pc_interface *pc;
+static struct class_exp_tables exptables;
+
//Converts a class to its array index for CLASS_COUNT defined arrays.
//Note that it does not do a validity check for speed purposes, where parsing
//player input make sure to use a pc->db_checkid first!
-int pc_class2idx(int class)
+static int pc_class2idx(int class)
{
if (class >= JOB_NOVICE_HIGH) {
class += - JOB_NOVICE_HIGH + JOB_MAX_BASIC;
@@ -95,7 +100,7 @@ int pc_class2idx(int class)
* required to provide a session.
* Caller must release dummy on its own when it's no longer needed.
*/
-struct map_session_data* pc_get_dummy_sd(void)
+static struct map_session_data *pc_get_dummy_sd(void)
{
struct map_session_data *dummy_sd;
CREATE(dummy_sd, struct map_session_data, 1);
@@ -109,7 +114,7 @@ struct map_session_data* pc_get_dummy_sd(void)
* @param group_id Group ID
* @return 1 on error, 0 on success
*/
-int pc_set_group(struct map_session_data *sd, int group_id)
+static int pc_set_group(struct map_session_data *sd, int group_id)
{
GroupSettings *group = pcg->id2group(group_id);
nullpo_retr(1, sd);
@@ -123,13 +128,13 @@ int pc_set_group(struct map_session_data *sd, int group_id)
/**
* Checks if commands used by player should be logged.
*/
-bool pc_should_log_commands(struct map_session_data *sd)
+static bool pc_should_log_commands(struct map_session_data *sd)
{
nullpo_retr(true, sd);
return pcg->should_log_commands(sd->group);
}
-int pc_invincible_timer(int tid, int64 tick, int id, intptr_t data)
+static int pc_invincible_timer(int tid, int64 tick, int id, intptr_t data)
{
struct map_session_data *sd = map->id2sd(id);
@@ -146,7 +151,7 @@ int pc_invincible_timer(int tid, int64 tick, int id, intptr_t data)
return 0;
}
-void pc_setinvincibletimer(struct map_session_data* sd, int val)
+static void pc_setinvincibletimer(struct map_session_data *sd, int val)
{
nullpo_retv(sd);
@@ -157,7 +162,7 @@ void pc_setinvincibletimer(struct map_session_data* sd, int val)
sd->invincible_timer = timer->add(timer->gettick()+val,pc->invincible_timer,sd->bl.id,0);
}
-void pc_delinvincibletimer(struct map_session_data* sd)
+static void pc_delinvincibletimer(struct map_session_data *sd)
{
nullpo_retv(sd);
@@ -169,7 +174,8 @@ void pc_delinvincibletimer(struct map_session_data* sd)
}
}
-int pc_spiritball_timer(int tid, int64 tick, int id, intptr_t data) {
+static int pc_spiritball_timer(int tid, int64 tick, int id, intptr_t data)
+{
struct map_session_data *sd = map->id2sd(id);
int i;
@@ -201,12 +207,13 @@ int pc_spiritball_timer(int tid, int64 tick, int id, intptr_t data) {
}
/**
-* Get the possible number of spiritball that a player can call.
-* @param sd the affected player structure
-* @param min the minimum number of spiritball regardless the level of MO_CALLSPIRITS
-* @retval total number of spiritball
-**/
-int pc_getmaxspiritball(struct map_session_data *sd, int min) {
+ * Get the possible number of spiritball that a player can call.
+ * @param sd the affected player structure
+ * @param min the minimum number of spiritball regardless the level of MO_CALLSPIRITS
+ * @retval total number of spiritball
+ */
+static int pc_getmaxspiritball(struct map_session_data *sd, int min)
+{
int result;
nullpo_ret(sd);
@@ -222,7 +229,7 @@ int pc_getmaxspiritball(struct map_session_data *sd, int min) {
return result;
}
-int pc_addspiritball(struct map_session_data *sd,int interval,int max)
+static int pc_addspiritball(struct map_session_data *sd, int interval, int max)
{
int tid, i;
@@ -248,15 +255,22 @@ int pc_addspiritball(struct map_session_data *sd,int interval,int max)
memmove(sd->spirit_timer+i+1, sd->spirit_timer+i, (sd->spiritball-i)*sizeof(int));
sd->spirit_timer[i] = tid;
sd->spiritball++;
+ pc->addspiritball_sub(sd);
+
+ return 0;
+}
+
+static int pc_addspiritball_sub(struct map_session_data *sd)
+{
+ nullpo_ret(sd);
if ((sd->job & MAPID_THIRDMASK) == MAPID_ROYAL_GUARD)
clif->millenniumshield(&sd->bl,sd->spiritball);
else
clif->spiritball(&sd->bl);
-
return 0;
}
-int pc_delspiritball(struct map_session_data *sd,int count,int type)
+static int pc_delspiritball(struct map_session_data *sd, int count, int type)
{
int i;
@@ -286,15 +300,23 @@ int pc_delspiritball(struct map_session_data *sd,int count,int type)
sd->spirit_timer[i] = INVALID_TIMER;
}
- if(!type) {
- if ((sd->job & MAPID_THIRDMASK) == MAPID_ROYAL_GUARD)
- clif->millenniumshield(&sd->bl,sd->spiritball);
- else
- clif->spiritball(&sd->bl);
+ if (!type) {
+ pc->delspiritball_sub(sd);
}
return 0;
}
-int pc_check_banding(struct block_list *bl, va_list ap)
+
+static int pc_delspiritball_sub(struct map_session_data *sd)
+{
+ nullpo_ret(sd);
+ if ((sd->job & MAPID_THIRDMASK) == MAPID_ROYAL_GUARD)
+ clif->millenniumshield(&sd->bl,sd->spiritball);
+ else
+ clif->spiritball(&sd->bl);
+ return 0;
+}
+
+static int pc_check_banding(struct block_list *bl, va_list ap)
{
int *c, *b_sd;
struct block_list *src;
@@ -322,7 +344,8 @@ int pc_check_banding(struct block_list *bl, va_list ap)
return 0;
}
-int pc_banding(struct map_session_data *sd, uint16 skill_lv) {
+static int pc_banding(struct map_session_data *sd, uint16 skill_lv)
+{
int c;
int b_sd[MAX_PARTY]; // In case of a full Royal Guard party.
int i, j, hp, extra_hp = 0, tmp_qty = 0;
@@ -376,7 +399,7 @@ int pc_banding(struct map_session_data *sd, uint16 skill_lv) {
for( j = 0; j < i; j++ ) {
bsd = map->id2sd(b_sd[j]);
if( bsd != NULL ) {
- status->set_hp(&bsd->bl,hp,0); // Set hp
+ status->set_hp(&bsd->bl, hp, STATUS_HEAL_DEFAULT); // Set hp
if( (sc = status->get_sc(&bsd->bl)) != NULL && sc->data[SC_BANDING] ) {
sc->data[SC_BANDING]->val2 = c; // Set the counter. It doesn't count your self.
status_calc_bl(&bsd->bl, status->sc2scb_flag(SC_BANDING)); // Set atk and def.
@@ -397,7 +420,7 @@ int pc_banding(struct map_session_data *sd, uint16 skill_lv) {
* @param type The fame list type (@see enum fame_list_type).
* @param count The amount of points to add.
*/
-void pc_addfame(struct map_session_data *sd, int ranktype, int count)
+static void pc_addfame(struct map_session_data *sd, int ranktype, int count)
{
nullpo_retv(sd);
@@ -437,7 +460,7 @@ void pc_addfame(struct map_session_data *sd, int ranktype, int count)
* @return The rank position (1-based index)
* @retval 0 if the character isn't in the specified list.
*/
-int pc_fame_rank(int char_id, int ranktype)
+static int pc_fame_rank(int char_id, int ranktype)
{
int i;
@@ -476,7 +499,8 @@ int pc_fame_rank(int char_id, int ranktype)
* @return the appropriate fame list type (@see enum fame_list_type).
* @retval RANKTYPE_UNKNOWN if no appropriate type exists.
*/
-int pc_famelist_type(uint16 job_mapid) {
+static int pc_famelist_type(uint16 job_mapid)
+{
switch (job_mapid & MAPID_UPPERMASK) {
case MAPID_BLACKSMITH:
return RANKTYPE_BLACKSMITH;
@@ -489,7 +513,8 @@ int pc_famelist_type(uint16 job_mapid) {
}
}
-int pc_setrestartvalue(struct map_session_data *sd,int type) {
+static int pc_setrestartvalue(struct map_session_data *sd, int type)
+{
struct status_data *st, *bst;
nullpo_ret(sd);
@@ -498,10 +523,9 @@ int pc_setrestartvalue(struct map_session_data *sd,int type) {
if (type&1) {
//Normal resurrection
- st->hp = 1; //Otherwise status->heal may fail if dead.
- status->heal(&sd->bl, bst->hp, 0, 1);
+ status->heal(&sd->bl, bst->hp, 0, STATUS_HEAL_FORCED | STATUS_HEAL_ALLOWREVIVE);
if( st->sp < bst->sp )
- status->set_sp(&sd->bl, bst->sp, 1);
+ status->set_sp(&sd->bl, bst->sp, STATUS_HEAL_FORCED);
} else { //Just for saving on the char-server (with values as if respawned)
sd->status.hp = bst->hp;
sd->status.sp = (st->sp < bst->sp) ? bst->sp : st->sp;
@@ -512,7 +536,8 @@ int pc_setrestartvalue(struct map_session_data *sd,int type) {
/*==========================================
Rental System
*------------------------------------------*/
-int pc_inventory_rental_end(int tid, int64 tick, int id, intptr_t data) {
+static int pc_inventory_rental_end(int tid, int64 tick, int id, intptr_t data)
+{
struct map_session_data *sd = map->id2sd(id);
if( sd == NULL )
return 0;
@@ -526,7 +551,7 @@ int pc_inventory_rental_end(int tid, int64 tick, int id, intptr_t data) {
return 1;
}
-int pc_inventory_rental_clear(struct map_session_data *sd)
+static int pc_inventory_rental_clear(struct map_session_data *sd)
{
nullpo_ret(sd);
if( sd->rental_timer != INVALID_TIMER )
@@ -538,11 +563,12 @@ int pc_inventory_rental_clear(struct map_session_data *sd)
return 1;
}
/* assumes i is valid (from default areas where it is called, it is) */
-void pc_rental_expire(struct map_session_data *sd, int i) {
- short nameid;
+static void pc_rental_expire(struct map_session_data *sd, int i)
+{
+ int nameid;
nullpo_retv(sd);
- Assert_retv(i >= 0 && i < MAX_INVENTORY);
+ 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 */
@@ -609,13 +635,13 @@ void pc_rental_expire(struct map_session_data *sd, int i) {
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);
}
-void pc_inventory_rentals(struct map_session_data *sd)
+static void pc_inventory_rentals(struct map_session_data *sd)
{
- int i, c = 0;
+ int c = 0;
int64 expire_tick, next_tick = INT64_MAX;
nullpo_retv(sd);
- for( i = 0; i < MAX_INVENTORY; i++ )
+ for (int i = 0; i < sd->status.inventorySize; i++ )
{ // Check for Rentals on Inventory
if( sd->status.inventory[i].nameid == 0 )
continue; // Nothing here
@@ -638,7 +664,7 @@ void pc_inventory_rentals(struct map_session_data *sd)
sd->rental_timer = INVALID_TIMER;
}
-void pc_inventory_rental_add(struct map_session_data *sd, int seconds)
+static void pc_inventory_rental_add(struct map_session_data *sd, int seconds)
{
int tick = seconds * 1000;
@@ -662,7 +688,7 @@ void pc_inventory_rental_add(struct map_session_data *sd, int seconds)
/*==========================================
* prepares character for saving.
*------------------------------------------*/
-int pc_makesavestatus(struct map_session_data *sd)
+static int pc_makesavestatus(struct map_session_data *sd)
{
nullpo_ret(sd);
@@ -728,7 +754,7 @@ int pc_makesavestatus(struct map_session_data *sd)
/*==========================================
* Off init ? Connection?
*------------------------------------------*/
-int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int login_id1, unsigned int client_tick, int sex, int fd)
+static int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int login_id1, unsigned int client_tick, int sex, int fd)
{
nullpo_ret(sd);
@@ -741,7 +767,8 @@ int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int lo
sd->client_tick = client_tick;
sd->state.active = 0; //to be set to 1 after player is fully authed and loaded.
sd->bl.type = BL_PC;
- sd->canlog_tick = timer->gettick();
+ if (battle_config.prevent_logout_trigger & PLT_LOGIN)
+ sd->canlog_tick = timer->gettick();
//Required to prevent homunculus copuing a base speed of 0.
sd->battle_status.speed = sd->base_status.speed = DEFAULT_WALK_SPEED;
sd->state.warp_clean = 1;
@@ -749,12 +776,13 @@ int pc_setnewpc(struct map_session_data *sd, int account_id, int char_id, int lo
return 0;
}
-int pc_equippoint(struct map_session_data *sd,int n)
+// [4144] probably pc_equippoint should be replaced to pc_item_equippoint
+static int pc_equippoint(struct map_session_data *sd, int n)
{
int ep = 0;
nullpo_ret(sd);
- Assert_ret(n >= 0 && n < MAX_INVENTORY);
+ Assert_ret(n >= 0 && n < sd->status.inventorySize);
if(!sd->inventory_data[n])
return 0;
@@ -763,9 +791,9 @@ int pc_equippoint(struct map_session_data *sd,int n)
return 0; //Not equippable by players.
ep = sd->inventory_data[n]->equip;
- if (sd->inventory_data[n]->look == W_DAGGER
- || sd->inventory_data[n]->look == W_1HSWORD
- || sd->inventory_data[n]->look == W_1HAXE
+ if (sd->inventory_data[n]->subtype == W_DAGGER
+ || sd->inventory_data[n]->subtype == W_1HSWORD
+ || sd->inventory_data[n]->subtype == W_1HAXE
) {
if (pc->checkskill(sd,AS_LEFT) > 0
|| (sd->job & MAPID_UPPERMASK) == MAPID_ASSASSIN
@@ -781,64 +809,89 @@ int pc_equippoint(struct map_session_data *sd,int n)
return ep;
}
-int pc_setinventorydata(struct map_session_data *sd)
+static int pc_item_equippoint(struct map_session_data *sd, struct item_data *id)
{
- int i;
+ int ep = 0;
+
+ nullpo_ret(sd);
+ nullpo_ret(id);
+
+ if (!itemdb->isequip2(id))
+ return 0; //Not equippable by players.
+
+ ep = id->equip;
+ if (id->subtype == W_DAGGER ||
+ id->subtype == W_1HSWORD ||
+ id->subtype == W_1HAXE) {
+ if (pc->checkskill(sd, AS_LEFT) > 0 ||
+ (sd->job & MAPID_UPPERMASK) == MAPID_ASSASSIN ||
+ (sd->job & MAPID_UPPERMASK) == MAPID_KAGEROUOBORO) {
+ // Kagerou and Oboro can dual wield daggers. [Rytech]
+ if (ep == EQP_HAND_R)
+ return EQP_ARMS;
+ if (ep == EQP_SHADOW_WEAPON)
+ return EQP_SHADOW_ARMS;
+ }
+ }
+ return ep;
+}
+static int pc_setinventorydata(struct map_session_data *sd)
+{
nullpo_ret(sd);
- for (i = 0; i < MAX_INVENTORY; i++) {
+ for (int i = 0; i < sd->status.inventorySize; i++) {
int id = sd->status.inventory[i].nameid;
sd->inventory_data[i] = id?itemdb->search(id):NULL;
}
return 0;
}
-int pc_calcweapontype(struct map_session_data *sd)
+static int pc_calcweapontype(struct map_session_data *sd)
{
nullpo_ret(sd);
// single-hand
if(sd->weapontype2 == W_FIST) {
- sd->status.weapon = sd->weapontype1;
+ sd->weapontype = sd->weapontype1;
return 1;
}
if(sd->weapontype1 == W_FIST) {
- sd->status.weapon = sd->weapontype2;
+ sd->weapontype = sd->weapontype2;
return 1;
}
// dual-wield
- sd->status.weapon = 0;
+ sd->weapontype = W_FIST;
switch (sd->weapontype1){
case W_DAGGER:
switch (sd->weapontype2) {
- case W_DAGGER: sd->status.weapon = W_DOUBLE_DD; break;
- case W_1HSWORD: sd->status.weapon = W_DOUBLE_DS; break;
- case W_1HAXE: sd->status.weapon = W_DOUBLE_DA; break;
+ case W_DAGGER: sd->weapontype = W_DOUBLE_DD; break;
+ case W_1HSWORD: sd->weapontype = W_DOUBLE_DS; break;
+ case W_1HAXE: sd->weapontype = W_DOUBLE_DA; break;
}
break;
case W_1HSWORD:
switch (sd->weapontype2) {
- case W_DAGGER: sd->status.weapon = W_DOUBLE_DS; break;
- case W_1HSWORD: sd->status.weapon = W_DOUBLE_SS; break;
- case W_1HAXE: sd->status.weapon = W_DOUBLE_SA; break;
+ case W_DAGGER: sd->weapontype = W_DOUBLE_DS; break;
+ case W_1HSWORD: sd->weapontype = W_DOUBLE_SS; break;
+ case W_1HAXE: sd->weapontype = W_DOUBLE_SA; break;
}
break;
case W_1HAXE:
switch (sd->weapontype2) {
- case W_DAGGER: sd->status.weapon = W_DOUBLE_DA; break;
- case W_1HSWORD: sd->status.weapon = W_DOUBLE_SA; break;
- case W_1HAXE: sd->status.weapon = W_DOUBLE_AA; break;
+ case W_DAGGER: sd->weapontype = W_DOUBLE_DA; break;
+ case W_1HSWORD: sd->weapontype = W_DOUBLE_SA; break;
+ case W_1HAXE: sd->weapontype = W_DOUBLE_AA; break;
}
}
// unknown, default to right hand type
- if (!sd->status.weapon)
- sd->status.weapon = sd->weapontype1;
+ if (sd->weapontype == W_FIST)
+ sd->weapontype = sd->weapontype1;
return 2;
}
-int pc_setequipindex(struct map_session_data *sd)
+static int pc_setequipindex(struct map_session_data *sd)
{
int i,j;
@@ -847,7 +900,7 @@ int pc_setequipindex(struct map_session_data *sd)
for(i=0;i<EQI_MAX;i++)
sd->equip_index[i] = -1;
- for(i=0;i<MAX_INVENTORY;i++) {
+ for (i = 0; i < sd->status.inventorySize; i++) {
if(sd->status.inventory[i].nameid <= 0)
continue;
if(sd->status.inventory[i].equip) {
@@ -855,20 +908,30 @@ int pc_setequipindex(struct map_session_data *sd)
if(sd->status.inventory[i].equip & pc->equip_pos[j])
sd->equip_index[j] = i;
- if(sd->status.inventory[i].equip & EQP_HAND_R)
- {
- if(sd->inventory_data[i])
- sd->weapontype1 = sd->inventory_data[i]->look;
- else
- sd->weapontype1 = 0;
+ if (sd->status.inventory[i].equip & EQP_HAND_R) {
+ if (sd->inventory_data[i]) {
+ sd->weapontype1 = sd->inventory_data[i]->subtype;
+ sd->status.look.weapon = sd->inventory_data[i]->view_sprite;
+ } else {
+ sd->weapontype1 = W_FIST;
+ sd->status.look.weapon = 0;
+ }
}
- if( sd->status.inventory[i].equip & EQP_HAND_L )
- {
- if( sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON )
- sd->weapontype2 = sd->inventory_data[i]->look;
- else
- sd->weapontype2 = 0;
+ if (sd->status.inventory[i].equip & EQP_HAND_L) {
+ if (sd->inventory_data[i] != NULL) {
+ if (sd->inventory_data[i]->type == IT_WEAPON)
+ sd->weapontype2 = sd->inventory_data[i]->subtype;
+ else
+ sd->weapontype2 = W_FIST;
+ if (sd->inventory_data[i]->type == IT_ARMOR)
+ sd->has_shield = true;
+ else
+ sd->has_shield = false;
+ } else {
+ sd->weapontype2 = W_FIST;
+ sd->has_shield = false;
+ }
}
}
}
@@ -877,7 +940,7 @@ int pc_setequipindex(struct map_session_data *sd)
return 0;
}
-bool pc_isequipped(struct map_session_data *sd, int nameid)
+static bool pc_isequipped(struct map_session_data *sd, int nameid)
{
int i, j;
@@ -903,7 +966,7 @@ bool pc_isequipped(struct map_session_data *sd, int nameid)
return false;
}
-bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd )
+static bool pc_can_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;
@@ -953,10 +1016,10 @@ bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd
/*==========================================
* Adoption Process
*------------------------------------------*/
-bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd)
+static bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd)
{
int class, joblevel;
- unsigned int jobexp;
+ uint64 jobexp;
if( !pc->can_Adopt(p1_sd, p2_sd, b_sd) )
return false;
@@ -988,6 +1051,11 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd,
pc->skill(p1_sd, WE_CALLBABY, 1, SKILL_GRANT_PERMANENT);
pc->skill(p2_sd, WE_CALLBABY, 1, SKILL_GRANT_PERMANENT);
+ // Achievements [Smokexyz/Hercules]
+ achievement->validate_adopt(p1_sd, true); // Parent 1
+ achievement->validate_adopt(p2_sd, true); // Parent 2
+ achievement->validate_adopt(b_sd, false); // Baby
+
return true;
}
@@ -998,11 +1066,12 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd,
* Checks if the player can equip the item at index n in inventory.
* Returns 0 (no) or 1 (yes).
*------------------------------------------------*/
-int pc_isequip(struct map_session_data *sd,int n)
+static int pc_isequip(struct map_session_data *sd, int n)
{
struct item_data *item;
nullpo_ret(sd);
+ Assert_ret(n >= 0 && n < sd->status.inventorySize);
item = sd->inventory_data[n];
@@ -1018,11 +1087,15 @@ int pc_isequip(struct map_session_data *sd,int n)
return 1;
if (item->elv && sd->status.base_level < item->elv) {
- clif->msgtable(sd, MSG_ITEM_CANT_EQUIP_LVL);
+#if PACKETVER >= 20100525
+ clif->msgtable(sd, MSG_CANNOT_EQUIP_ITEM_LEVEL);
+#endif
return 0;
}
if (item->elvmax && sd->status.base_level > item->elvmax) {
- clif->msgtable(sd, MSG_ITEM_CANT_EQUIP_LVL);
+#if PACKETVER >= 20100525
+ clif->msgtable(sd, MSG_CANNOT_EQUIP_ITEM_LEVEL);
+#endif
return 0;
}
if(item->sex != 2 && sd->status.sex != item->sex)
@@ -1030,11 +1103,15 @@ int pc_isequip(struct map_session_data *sd,int n)
if ( item->equip & EQP_AMMO ) {
if (sd->state.active && !pc_iscarton(sd) && (sd->job & MAPID_THIRDMASK) == MAPID_GENETIC) { // check if sc data is already loaded.
- clif->msgtable(sd, MSG_ITEM_NEED_CART);
+#if PACKETVER_RE_NUM >= 20090529 || PACKETVER_MAIN_NUM >= 20090603 || defined(PACKETVER_ZERO)
+ clif->msgtable(sd, MSG_USESKILL_FAIL_CART);
+#endif
return 0;
}
if (!pc_ismadogear(sd) && (sd->job & MAPID_THIRDMASK) == MAPID_MECHANIC) {
- clif->msgtable(sd, MSG_ITEM_NEED_MADO);
+#if PACKETVER_RE_NUM >= 20090226 || PACKETVER_MAIN_NUM >= 20090304 || defined(PACKETVER_ZERO)
+ clif->msgtable(sd, MSG_USESKILL_FAIL_MADOGEAR);
+#endif
return 0;
}
}
@@ -1059,13 +1136,13 @@ int pc_isequip(struct map_session_data *sd,int n)
return 1; //Can equip all helms
if (sd->status.base_level > 96 && item->equip & EQP_ARMS && item->type == IT_WEAPON)
- switch(item->look) { //In weapons, the look determines type of weapon.
- case W_DAGGER: //Level 4 Knives are equippable.. this means all knives, I'd guess?
- case W_1HSWORD: //All 1H swords
- case W_1HAXE: //All 1H Axes
- case W_MACE: //All 1H Maces
- case W_STAFF: //All 1H Staves
- return 1;
+ switch (item->subtype) { //In weapons, the look determines type of weapon.
+ case W_DAGGER: //Level 4 Knives are equippable.. this means all knives, I'd guess?
+ case W_1HSWORD: //All 1H swords
+ case W_1HAXE: //All 1H Axes
+ case W_MACE: //All 1H Maces
+ case W_STAFF: //All 1H Staves
+ return 1;
}
}
}
@@ -1117,7 +1194,7 @@ int pc_isequip(struct map_session_data *sd,int n)
* No problem with the session id
* set the status that has been sent from char server
*------------------------------------------*/
-bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, const struct mmo_charstatus *st, bool changing_mapservers)
+static bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, const struct mmo_charstatus *st, bool changing_mapservers)
{
int i;
int64 tick = timer->gettick();
@@ -1136,6 +1213,8 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
}
memcpy(&sd->status, st, sizeof(*st));
+ memset(&sd->rodex, 0x0, sizeof(sd->rodex));
+ VECTOR_INIT(sd->rodex.messages);
if (st->sex != sd->status.sex) {
clif->authfail_fd(sd->fd, 0);
@@ -1249,14 +1328,18 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
sd->bg_queue.client_has_bg_data = 0;
sd->bg_queue.type = 0;
+ VECTOR_INIT(sd->channels);
VECTOR_INIT(sd->script_queues);
+ VECTOR_INIT(sd->achievement); // Achievements [Smokexyz/Hercules]
+ VECTOR_INIT(sd->storage.item); // initialize storage item vector.
+ VECTOR_INIT(sd->hatEffectId);
sd->state.dialog = 0;
sd->delayed_damage = 0;
- if( battle_config.item_check )
- sd->state.itemcheck = 1;
+ if (battle->bc->item_check != PCCHECKITEM_NONE) // Check and flag items for inspection.
+ sd->itemcheck = (enum pc_checkitem_types) battle->bc->item_check;
// Event Timers
for( i = 0; i < MAX_EVENTTIMER; i++ )
@@ -1295,6 +1378,8 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
pc->setpos(sd,sd->status.last_point.map,0,0,CLR_OUTSIGHT);
}
+ clif->inventoryExpansionInfo(sd);
+ clif->overweight_percent(sd);
clif->authok(sd);
//Prevent S. Novices from getting the no-death bonus just yet. [Skotlex]
@@ -1307,6 +1392,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
" Group '"CL_WHITE"%d"CL_RESET"').\n",
sd->status.name, sd->status.account_id, sd->status.char_id,
CONVIP(ip), sd->group_id);
+
// Send friends list
clif->friendslist_send(sd);
@@ -1328,16 +1414,6 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
clif->changemap(sd,sd->bl.m,sd->bl.x,sd->bl.y);
}
- /**
- * Check if player have any cool downs on
- **/
- skill->cooldown_load(sd);
-
- /**
- * Check if player have any item cooldowns on
- **/
- pc->itemcd_do(sd,true);
-
#ifdef GP_BOUND_ITEMS
if( sd->status.party_id == 0 )
pc->bound_clear(sd,IBT_PARTY);
@@ -1355,7 +1431,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
/*==========================================
* Closes a connection because it failed to be authenticated from the char server.
*------------------------------------------*/
-void pc_authfail(struct map_session_data *sd)
+static void pc_authfail(struct map_session_data *sd)
{
nullpo_retv(sd);
clif->authfail_fd(sd->fd, 0);
@@ -1363,7 +1439,7 @@ void pc_authfail(struct map_session_data *sd)
}
//Attempts to set a mob.
-int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl)
+static int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl)
{
int class_;
if (!sd || !bl || pos < 0 || pos >= MAX_PC_FEELHATE)
@@ -1383,7 +1459,7 @@ int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl)
return 0; //Wrong size
}
sd->hate_mob[pos] = class_;
- pc_setglobalreg(sd,script->add_str(pc->sg_info[pos].hate_var),class_+1);
+ pc_setglobalreg(sd,script->add_variable(pc->sg_info[pos].hate_var),class_+1);
clif->hate_info(sd, pos, class_, 1);
return 1;
}
@@ -1391,34 +1467,34 @@ int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl)
/*==========================================
* Invoked once after the char/account/account2 registry variables are received. [Skotlex]
*------------------------------------------*/
-int pc_reg_received(struct map_session_data *sd)
+static int pc_reg_received(struct map_session_data *sd)
{
int i, idx = 0;
nullpo_ret(sd);
sd->vars_ok = true;
- sd->change_level_2nd = pc_readglobalreg(sd,script->add_str("jobchange_level"));
- sd->change_level_3rd = pc_readglobalreg(sd,script->add_str("jobchange_level_3rd"));
- sd->die_counter = pc_readglobalreg(sd,script->add_str("PC_DIE_COUNTER"));
+ sd->change_level_2nd = pc_readglobalreg(sd,script->add_variable("jobchange_level"));
+ sd->change_level_3rd = pc_readglobalreg(sd,script->add_variable("jobchange_level_3rd"));
+ sd->die_counter = pc_readglobalreg(sd,script->add_variable("PC_DIE_COUNTER"));
// Cash shop
- sd->cashPoints = pc_readaccountreg(sd,script->add_str("#CASHPOINTS"));
- sd->kafraPoints = pc_readaccountreg(sd,script->add_str("#KAFRAPOINTS"));
+ sd->cashPoints = pc_readaccountreg(sd,script->add_variable("#CASHPOINTS"));
+ sd->kafraPoints = pc_readaccountreg(sd,script->add_variable("#KAFRAPOINTS"));
// Cooking Exp
- sd->cook_mastery = pc_readglobalreg(sd,script->add_str("COOK_MASTERY"));
+ sd->cook_mastery = pc_readglobalreg(sd,script->add_variable("COOK_MASTERY"));
if ((sd->job & MAPID_BASEMASK) == MAPID_TAEKWON) {
// Better check for class rather than skill to prevent "skill resets" from unsetting this
- sd->mission_mobid = pc_readglobalreg(sd,script->add_str("TK_MISSION_ID"));
- sd->mission_count = pc_readglobalreg(sd,script->add_str("TK_MISSION_COUNT"));
+ sd->mission_mobid = pc_readglobalreg(sd,script->add_variable("TK_MISSION_ID"));
+ sd->mission_count = pc_readglobalreg(sd,script->add_variable("TK_MISSION_COUNT"));
}
//SG map and mob read [Komurka]
for (i = 0; i < MAX_PC_FEELHATE; i++) {
//for now - someone need to make reading from txt/sql
- int j = pc_readglobalreg(sd,script->add_str(pc->sg_info[i].feel_var));
+ int j = pc_readglobalreg(sd,script->add_variable(pc->sg_info[i].feel_var));
if (j != 0) {
sd->feel_map[i].index = j;
sd->feel_map[i].m = map->mapindex2mapid(j);
@@ -1426,24 +1502,24 @@ int pc_reg_received(struct map_session_data *sd)
sd->feel_map[i].index = 0;
sd->feel_map[i].m = -1;
}
- sd->hate_mob[i] = pc_readglobalreg(sd,script->add_str(pc->sg_info[i].hate_var))-1;
+ sd->hate_mob[i] = pc_readglobalreg(sd,script->add_variable(pc->sg_info[i].hate_var))-1;
}
if ((i = pc->checkskill(sd,RG_PLAGIARISM)) > 0) {
- sd->cloneskill_id = pc_readglobalreg(sd,script->add_str("CLONE_SKILL"));
+ sd->cloneskill_id = pc_readglobalreg(sd,script->add_variable("CLONE_SKILL"));
if (sd->cloneskill_id > 0 && (idx = skill->get_index(sd->cloneskill_id)) > 0) {
sd->status.skill[idx].id = sd->cloneskill_id;
- sd->status.skill[idx].lv = pc_readglobalreg(sd,script->add_str("CLONE_SKILL_LV"));
+ sd->status.skill[idx].lv = pc_readglobalreg(sd,script->add_variable("CLONE_SKILL_LV"));
if (sd->status.skill[idx].lv > i)
sd->status.skill[idx].lv = i;
sd->status.skill[idx].flag = SKILL_FLAG_PLAGIARIZED;
}
}
if ((i = pc->checkskill(sd,SC_REPRODUCE)) > 0) {
- sd->reproduceskill_id = pc_readglobalreg(sd,script->add_str("REPRODUCE_SKILL"));
+ sd->reproduceskill_id = pc_readglobalreg(sd,script->add_variable("REPRODUCE_SKILL"));
if( sd->reproduceskill_id > 0 && (idx = skill->get_index(sd->reproduceskill_id)) > 0) {
sd->status.skill[idx].id = sd->reproduceskill_id;
- sd->status.skill[idx].lv = pc_readglobalreg(sd,script->add_str("REPRODUCE_SKILL_LV"));
+ sd->status.skill[idx].lv = pc_readglobalreg(sd,script->add_variable("REPRODUCE_SKILL_LV"));
if( i < sd->status.skill[idx].lv)
sd->status.skill[idx].lv = i;
sd->status.skill[idx].flag = SKILL_FLAG_PLAGIARIZED;
@@ -1477,13 +1553,27 @@ int pc_reg_received(struct map_session_data *sd)
if (!chrif->auth_finished(sd))
ShowError("pc_reg_received: Failed to properly remove player %d:%d from logging db!\n", sd->status.account_id, sd->status.char_id);
+ // Restore any cooldowns
+ skill->cooldown_load(sd);
+ pc->itemcd_do(sd, true);
+
pc->load_combo(sd);
status_calc_pc(sd,SCO_FIRST|SCO_FORCE);
chrif->scdata_request(sd->status.account_id, sd->status.char_id);
+ if (sd->status.clan_id)
+ clan->member_online(sd, true);
+
+ //Auth is fully okay, update last_login
+ sd->status.last_login = time(NULL);
+
+ // Storage Request
+ intif->request_account_storage(sd);
+
intif->Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
intif->request_questlog(sd);
+ intif->rodex_checkhasnew(sd);
if (sd->state.connect_new == 0 && sd->fd) { //Character already loaded map! Gotta trigger LoadEndAck manually.
sd->state.connect_new = 1;
@@ -1506,15 +1596,19 @@ int pc_reg_received(struct map_session_data *sd)
if( npc->motd ) /* [Ind/Hercules] */
script->run(npc->motd->u.scr.script, 0, sd->bl.id, npc->fake_nd->bl.id);
+ // Achievements [Smokexyz/Hercules]
+ intif->achievements_request(sd);
+
return 1;
}
-int pc_calc_skillpoint(struct map_session_data* sd) {
+static int pc_calc_skillpoint(struct map_session_data *sd)
+{
int i,inf2,skill_point=0;
nullpo_ret(sd);
- for (i = 1; i < MAX_SKILL; i++) {
+ for (i = 1; i < MAX_SKILL_DB; i++) {
int skill_lv = pc->checkskill2(sd,i);
if (skill_lv > 0) {
inf2 = skill->dbs->db[i].inf2;
@@ -1532,10 +1626,34 @@ int pc_calc_skillpoint(struct map_session_data* sd) {
return skill_point;
}
+static void pc_calc_skilltree_clear(struct map_session_data *sd)
+{
+ int i;
+
+ nullpo_retv(sd);
+
+ for (i = 0; i < MAX_SKILL_DB; i++) {
+ if (sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED) //Don't touch these
+ sd->status.skill[i].id = 0; //First clear skills.
+ /* permanent skills that must be re-checked */
+ if (sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) {
+ switch (skill->dbs->db[i].nameid) {
+ case NV_TRICKDEAD:
+ if ((sd->job & MAPID_UPPERMASK) != MAPID_NOVICE) {
+ sd->status.skill[i].id = 0;
+ sd->status.skill[i].lv = 0;
+ sd->status.skill[i].flag = 0;
+ }
+ break;
+ }
+ }
+ }
+}
+
/*==========================================
* Calculation of skill level.
*------------------------------------------*/
-int pc_calc_skilltree(struct map_session_data *sd)
+static int pc_calc_skilltree(struct map_session_data *sd)
{
int i,id=0,flag;
int class = 0, classidx = 0;
@@ -1550,24 +1668,9 @@ int pc_calc_skilltree(struct map_session_data *sd)
}
classidx = pc->class2idx(class);
- for( i = 0; i < MAX_SKILL; i++ ) {
- if( sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED ) //Don't touch these
- sd->status.skill[i].id = 0; //First clear skills.
- /* permanent skills that must be re-checked */
- if( sd->status.skill[i].flag == SKILL_FLAG_PERMANENT ) {
- switch( skill->dbs->db[i].nameid ) {
- case NV_TRICKDEAD:
- if ((sd->job & MAPID_UPPERMASK) != MAPID_NOVICE) {
- sd->status.skill[i].id = 0;
- sd->status.skill[i].lv = 0;
- sd->status.skill[i].flag = 0;
- }
- break;
- }
- }
- }
+ pc->calc_skilltree_clear(sd);
- for( i = 0; i < MAX_SKILL; i++ ) {
+ for (i = 0; i < MAX_SKILL_DB; i++) {
if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED )
{ // Restore original level of skills after deleting earned skills.
sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
@@ -1576,18 +1679,25 @@ int pc_calc_skilltree(struct map_session_data *sd)
if( sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER && skill->dbs->db[i].nameid >= DC_HUMMING && skill->dbs->db[i].nameid <= DC_SERVICEFORYOU )
{ //Enable Bard/Dancer spirit linked skills.
- if( sd->status.sex )
- { //Link dancer skills to bard.
- // i can be < 8?
- if( sd->status.skill[i-8].lv < 10 )
+ if (sd->status.sex) {
+ // Link dancer skills to bard.
+ if (i < 8) {
+ Assert_report(i >= 8);
+ continue;
+ }
+ if (sd->status.skill[i-8].lv < 10)
continue;
sd->status.skill[i].id = skill->dbs->db[i].nameid;
sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill
sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
- } else { //Link bard skills to dancer.
- if( sd->status.skill[i].lv < 10 )
+ } else {
+ // Link bard skills to dancer.
+ if (i < 8) {
+ Assert_report(i >= 8);
+ continue;
+ }
+ if (sd->status.skill[i].lv < 10)
continue;
- // i can be < 8?
sd->status.skill[i-8].id = skill->dbs->db[i-8].nameid;
sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill
sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill
@@ -1596,7 +1706,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
}
if( pc_has_permission(sd, PC_PERM_ALL_SKILL) ) {
- for( i = 0; i < MAX_SKILL; i++ ) {
+ for (i = 0; i < MAX_SKILL_DB; i++) {
switch(skill->dbs->db[i].nameid) {
/**
* Dummy skills must be added here otherwise they'll be displayed in the,
@@ -1685,6 +1795,19 @@ int pc_calc_skilltree(struct map_session_data *sd)
}
} while(flag);
+ pc->calc_skilltree_bonus(sd, classidx);
+
+ return 0;
+}
+
+static void pc_calc_skilltree_bonus(struct map_session_data *sd, int classidx)
+{
+ int i;
+ int id = 0;
+
+ nullpo_retv(sd);
+ Assert_retv(classidx >= 0 && classidx < CLASS_COUNT);
+
//
if (classidx > 0 && (sd->job & MAPID_UPPERMASK) == MAPID_TAEKWON
&& sd->status.base_level >= 90 && sd->status.skill_point == 0
@@ -1710,12 +1833,10 @@ int pc_calc_skilltree(struct map_session_data *sd)
sd->status.skill[idx].lv = skill->tree_get_max(id, sd->status.class);
}
}
-
- return 0;
}
//Checks if you can learn a new skill after having leveled up a skill.
-void pc_check_skilltree(struct map_session_data *sd, int skill_id)
+static void pc_check_skilltree(struct map_session_data *sd, int skill_id)
{
int i,id=0,flag;
int c=0;
@@ -1786,11 +1907,11 @@ void pc_check_skilltree(struct map_session_data *sd, int skill_id)
// Make sure all the skills are in the correct condition
// before persisting to the backend.. [MouseJstr]
-int pc_clean_skilltree(struct map_session_data *sd)
+static int pc_clean_skilltree(struct map_session_data *sd)
{
int i;
nullpo_ret(sd);
- for (i = 0; i < MAX_SKILL; i++){
+ for (i = 0; i < MAX_SKILL_DB; i++) {
if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED) {
sd->status.skill[i].id = 0;
sd->status.skill[i].lv = 0;
@@ -1804,7 +1925,7 @@ int pc_clean_skilltree(struct map_session_data *sd)
return 0;
}
-int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
+static int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
{
int skill_point, novice_skills;
uint16 job;
@@ -1816,7 +1937,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
skill_point = pc->calc_skillpoint(sd);
- novice_skills = pc->max_level[pc->class2idx(JOB_NOVICE)][1] - 1;
+ novice_skills = pc->dbs->class_exp_table[pc->class2idx(JOB_NOVICE)][CLASS_EXP_TABLE_JOB]->max_level - 1;
sd->sktree.second = sd->sktree.third = 0;
@@ -1830,7 +1951,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
if ((sd->job & JOBL_THIRD) != 0) {
// if neither 2nd nor 3rd jobchange levels are known, we have to assume a default for 2nd
if (sd->change_level_3rd == 0) {
- sd->change_level_2nd = pc->max_level[pc->class2idx(pc->mapid2jobid(sd->job & MAPID_UPPERMASK, sd->status.sex))][1];
+ sd->change_level_2nd = pc->dbs->class_exp_table[pc->class2idx(pc->mapid2jobid(sd->job & MAPID_UPPERMASK, sd->status.sex))][CLASS_EXP_TABLE_JOB]->max_level;
} else {
sd->change_level_2nd = 1 + skill_point + sd->status.skill_point
- (sd->status.job_level - 1)
@@ -1844,7 +1965,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
}
- pc_setglobalreg(sd, script->add_str("jobchange_level"), sd->change_level_2nd);
+ pc_setglobalreg(sd, script->add_variable("jobchange_level"), sd->change_level_2nd);
}
if (skill_point < novice_skills + (sd->change_level_2nd - 1)) {
@@ -1857,7 +1978,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
- (sd->status.job_level - 1)
- (sd->change_level_2nd - 1)
- novice_skills;
- pc_setglobalreg(sd, script->add_str("jobchange_level_3rd"), sd->change_level_3rd);
+ pc_setglobalreg(sd, script->add_variable("jobchange_level_3rd"), sd->change_level_3rd);
}
if (skill_point < novice_skills + (sd->change_level_2nd - 1) + (sd->change_level_3rd - 1)) {
@@ -1880,7 +2001,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
* 2: overweight 90%
* It's assumed that SC_WEIGHTOVER50 and SC_WEIGHTOVER90 are only started/stopped here.
*/
-int pc_updateweightstatus(struct map_session_data *sd)
+static int pc_updateweightstatus(struct map_session_data *sd)
{
int old_overweight;
int new_overweight;
@@ -1911,7 +2032,7 @@ int pc_updateweightstatus(struct map_session_data *sd)
return 0;
}
-int pc_disguise(struct map_session_data *sd, int class)
+static int pc_disguise(struct map_session_data *sd, int class)
{
nullpo_ret(sd);
if (class == -1 && sd->disguise == -1)
@@ -1954,7 +2075,7 @@ int pc_disguise(struct map_session_data *sd, int class)
clif->spawn(&sd->bl);
if (class == sd->status.class && pc_iscarton(sd)) {
//It seems the cart info is lost on undisguise.
- clif->cartlist(sd);
+ clif->cartList(sd);
clif->updatestatus(sd,SP_CARTINFO);
}
if (sd->chat_id != 0) {
@@ -1967,7 +2088,7 @@ int pc_disguise(struct map_session_data *sd, int class)
return 1;
}
-int pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, short rate, short flag, short card_id)
+static int pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, short rate, short flag, int card_id)
{
int i;
@@ -2005,7 +2126,7 @@ int pc_bonus_autospell(struct s_autospell *spell, int max, short id, short lv, s
return 1;
}
-int pc_bonus_autospell_onskill(struct s_autospell *spell, int max, short src_skill, short id, short lv, short rate, short card_id)
+static int pc_bonus_autospell_onskill(struct s_autospell *spell, int max, short src_skill, short id, short lv, short rate, int card_id)
{
int i;
@@ -2046,7 +2167,7 @@ int pc_bonus_autospell_onskill(struct s_autospell *spell, int max, short src_ski
* @retval 1 on success.
* @retval 0 on failure.
*/
-int pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, int16 rate, int16 arrow_rate, uint8 flag, uint16 duration)
+static int pc_bonus_addeff(struct s_addeffect *effect, int max, enum sc_type id, int16 rate, int16 arrow_rate, uint8 flag, uint16 duration)
{
int i;
@@ -2078,7 +2199,8 @@ int pc_bonus_addeff(struct s_addeffect* effect, int max, enum sc_type id, int16
return 1;
}
-int pc_bonus_addeff_onskill(struct s_addeffectonskill* effect, int max, enum sc_type id, short rate, short skill_id, unsigned char target) {
+static int pc_bonus_addeff_onskill(struct s_addeffectonskill *effect, int max, enum sc_type id, short rate, short skill_id, unsigned char target)
+{
int i;
nullpo_ret(effect);
@@ -2099,10 +2221,12 @@ int pc_bonus_addeff_onskill(struct s_addeffectonskill* effect, int max, enum sc_
return 1;
}
-int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id, short group, int race_mask, int rate) {
+static int pc_bonus_item_drop(struct s_add_drop *drop, const short max, int id, bool is_group, int race_mask, int rate)
+{
int i;
nullpo_ret(drop);
+ Assert_ret(is_group || id > 0);
//Apply config rate adjustment settings.
if (rate >= 0) { //Absolute drop.
if (battle_config.item_rate_adddrop != 100)
@@ -2117,17 +2241,14 @@ int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id, short
if (rate > -1)
rate = -1;
}
- for(i = 0; i < max && (drop[i].id || drop[i].group); i++) {
- if (((id && drop[i].id == id) || (group && drop[i].group == group))
- && race_mask != RCMASK_NONE
- ) {
+ for (i = 0; i < max && (drop[i].id != 0 || drop[i].is_group); i++) {
+ if (drop[i].id == id && race_mask != RCMASK_NONE) {
drop[i].race |= race_mask;
if (drop[i].rate > 0 && rate > 0) {
//Both are absolute rates.
if (drop[i].rate < rate)
drop[i].rate = rate;
- } else
- if(drop[i].rate < 0 && rate < 0) {
+ } else if (drop[i].rate < 0 && rate < 0) {
//Both are relative rates.
if (drop[i].rate > rate)
drop[i].rate = rate;
@@ -2141,13 +2262,14 @@ int pc_bonus_item_drop(struct s_add_drop *drop, const short max, short id, short
return 0;
}
drop[i].id = id;
- drop[i].group = group;
+ drop[i].is_group = is_group;
drop[i].race |= race_mask;
drop[i].rate = rate;
return 1;
}
-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 short pos, bool onskill)
+{
int i;
nullpo_ret(bonus);
@@ -2184,7 +2306,7 @@ int pc_addautobonus(struct s_autobonus *bonus,char max,const char *bonus_script,
return 1;
}
-int pc_delautobonus(struct map_session_data* sd, struct s_autobonus *autobonus,char max,bool restore)
+static int pc_delautobonus(struct map_session_data *sd, struct s_autobonus *autobonus, char max, bool restore)
{
int i;
nullpo_ret(sd);
@@ -2222,7 +2344,7 @@ int pc_delautobonus(struct map_session_data* sd, struct s_autobonus *autobonus,c
return 0;
}
-int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus)
+static int pc_exeautobonus(struct map_session_data *sd, struct s_autobonus *autobonus)
{
nullpo_ret(sd);
nullpo_ret(autobonus);
@@ -2242,7 +2364,8 @@ int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus)
return 0;
}
-int pc_endautobonus(int tid, int64 tick, int id, intptr_t data) {
+static int pc_endautobonus(int tid, int64 tick, int id, intptr_t data)
+{
struct map_session_data *sd = map->id2sd(id);
struct s_autobonus *autobonus = (struct s_autobonus *)data;
@@ -2255,7 +2378,7 @@ int pc_endautobonus(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
-int pc_bonus_addele(struct map_session_data* sd, unsigned char ele, short rate, short flag)
+static int pc_bonus_addele(struct map_session_data *sd, unsigned char ele, short rate, short flag)
{
int i;
struct weapon_data* wd;
@@ -2290,7 +2413,7 @@ int pc_bonus_addele(struct map_session_data* sd, unsigned char ele, short rate,
return 0;
}
-int pc_bonus_subele(struct map_session_data* sd, unsigned char ele, short rate, short flag)
+static int pc_bonus_subele(struct map_session_data *sd, unsigned char ele, short rate, short flag)
{
int i;
@@ -2336,7 +2459,8 @@ int pc_bonus_subele(struct map_session_data* sd, unsigned char ele, short rate,
/*==========================================
* Add a bonus(type) to player sd
*------------------------------------------*/
-int pc_bonus(struct map_session_data *sd,int type,int val) {
+static int pc_bonus(struct map_session_data *sd, int type, int val)
+{
struct status_data *bst;
int bonus;
int i;
@@ -2452,7 +2576,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val) {
}
switch (sd->state.lr_flag) {
case 2:
- switch (sd->status.weapon) {
+ switch (sd->weapontype) {
case W_BOW:
case W_REVOLVER:
case W_RIFLE:
@@ -2519,7 +2643,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val) {
case SP_ATTACKRANGE:
switch (sd->state.lr_flag) {
case 2:
- switch (sd->status.weapon) {
+ switch (sd->weapontype) {
case W_BOW:
case W_REVOLVER:
case W_RIFLE:
@@ -2985,7 +3109,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val) {
#endif
case SP_ADD_MONSTER_DROP_CHAINITEM:
if (sd->state.lr_flag != 2)
- pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, val, map->race_id2mask(RC_ALL), 10000);
+ pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), val, true, map->race_id2mask(RC_ALL), 10000);
break;
case SP_ADDMAXWEIGHT:
if (sd->state.lr_flag != 2)
@@ -3002,7 +3126,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val) {
/*==========================================
* Player bonus (type) with args type2 and val, called trough bonus2 (npc)
*------------------------------------------*/
-int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
+static int pc_bonus2(struct map_session_data *sd, int type, int type2, int val)
{
int i;
@@ -3560,7 +3684,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
case SP_ADD_MONSTER_DROP_ITEM:
if (sd->state.lr_flag != 2)
- pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, map->race_id2mask(RC_ALL), val);
+ pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, false, map->race_id2mask(RC_ALL), val);
break;
case SP_SP_LOSS_RATE:
if(sd->state.lr_flag != 2) {
@@ -3766,7 +3890,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
}
if (sd->state.lr_flag != 2)
- pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), 0, type2, race_mask, 10000);
+ pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, true, race_mask, 10000);
}
break;
#ifdef RENEWAL
@@ -3792,7 +3916,7 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
return 0;
}
-int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
+static int pc_bonus3(struct map_session_data *sd, int type, int type2, int type3, int val)
{
int i;
nullpo_ret(sd);
@@ -3806,12 +3930,12 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
break;
}
if (sd->state.lr_flag != 2)
- pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, race_mask, val);
+ pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, false, race_mask, val);
}
break;
case SP_ADD_CLASS_DROP_ITEM:
if(sd->state.lr_flag != 2)
- pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, 0, -type3, val);
+ pc->bonus_item_drop(sd->add_drop, ARRAYLENGTH(sd->add_drop), type2, false, -type3, val);
break;
case SP_AUTOSPELL:
if(sd->state.lr_flag != 2)
@@ -3966,7 +4090,8 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
return 0;
}
-int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4,int val) {
+static int pc_bonus4(struct map_session_data *sd, int type, int type2, int type3, int type4, int val)
+{
int i;
nullpo_ret(sd);
@@ -4061,7 +4186,8 @@ int pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type4
return 0;
}
-int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4,int type5,int val) {
+static int pc_bonus5(struct map_session_data *sd, int type, int type2, int type3, int type4, int type5, int val)
+{
nullpo_ret(sd);
switch(type){
@@ -4095,9 +4221,9 @@ int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4
* Grants a player a given skill.
* Flag values: @see enum pc_skill_flag
*------------------------------------------*/
-int pc_skill(struct map_session_data *sd, int id, int level, int flag)
+static int pc_skill(struct map_session_data *sd, int id, int level, int flag)
{
- uint16 index = 0;
+ int index = 0;
nullpo_ret(sd);
if (!(index = skill->get_index(id))) {
@@ -4174,13 +4300,13 @@ int pc_skill(struct map_session_data *sd, int id, int level, int flag)
* @param idx_equip The target equipment's inventory index.
* @retval true if the card can be inserted.
*/
-bool pc_can_insert_card_into(struct map_session_data* sd, int idx_card, int idx_equip)
+static bool pc_can_insert_card_into(struct map_session_data *sd, int idx_card, int idx_equip)
{
int i;
nullpo_ret(sd);
- if (idx_equip < 0 || idx_equip >= MAX_INVENTORY || sd->inventory_data[idx_equip] == NULL)
+ if (idx_equip < 0 || idx_equip >= sd->status.inventorySize || sd->inventory_data[idx_equip] == NULL)
return false; //Invalid item index.
if (sd->status.inventory[idx_equip].nameid <= 0 || sd->status.inventory[idx_equip].amount < 1)
return false; // target item missing
@@ -4210,11 +4336,11 @@ bool pc_can_insert_card_into(struct map_session_data* sd, int idx_card, int idx_
* @param idx_card The card's inventory index.
* @retval true if the card can be inserted.
*/
-bool pc_can_insert_card(struct map_session_data* sd, int idx_card)
+static bool pc_can_insert_card(struct map_session_data *sd, int idx_card)
{
nullpo_ret(sd);
- if (idx_card < 0 || idx_card >= MAX_INVENTORY || sd->inventory_data[idx_card] == NULL)
+ if (idx_card < 0 || idx_card >= sd->status.inventorySize || sd->inventory_data[idx_card] == NULL)
return false; //Invalid card index.
if (sd->status.inventory[idx_card].nameid <= 0 || sd->status.inventory[idx_card].amount < 1)
return false; // target card missing
@@ -4229,7 +4355,7 @@ bool pc_can_insert_card(struct map_session_data* sd, int idx_card)
* 0 = fail
* 1 = success
*------------------------------------------*/
-int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
+static int pc_insert_card(struct map_session_data *sd, int idx_card, int idx_equip)
{
int nameid;
@@ -4271,11 +4397,9 @@ int pc_insert_card(struct map_session_data* sd, int idx_card, int idx_equip)
/*==========================================
* Update buying value by skills
*------------------------------------------*/
-int pc_modifybuyvalue(struct map_session_data *sd, int orig_value)
+static int pc_modifybuyvalue(struct map_session_data *sd, int orig_value)
{
int skill_lv, rate1 = 0, rate2 = 0;
- if (orig_value <= 0)
- return 0;
if ((skill_lv=pc->checkskill(sd,MC_DISCOUNT)) > 0) // merchant discount
rate1 = 5+skill_lv*2-((skill_lv==10)? 1:0);
if ((skill_lv=pc->checkskill(sd,RG_COMPULSION)) > 0) // rogue discount
@@ -4284,25 +4408,25 @@ int pc_modifybuyvalue(struct map_session_data *sd, int orig_value)
rate1 = rate2;
if (rate1 != 0)
orig_value = apply_percentrate(orig_value, 100-rate1, 100);
- if (orig_value < 1)
- orig_value = 1;
+
+ if (orig_value < battle_config.min_item_buy_price)
+ orig_value = battle_config.min_item_buy_price;
return orig_value;
}
/*==========================================
* Update selling value by skills
*------------------------------------------*/
-int pc_modifysellvalue(struct map_session_data *sd, int orig_value)
+static int pc_modifysellvalue(struct map_session_data *sd, int orig_value)
{
int skill_lv, rate = 0;
- if (orig_value <= 0)
- return 0;
if ((skill_lv=pc->checkskill(sd,MC_OVERCHARGE)) > 0) //OverCharge
rate = 5+skill_lv*2-((skill_lv==10)? 1:0);
if (rate != 0)
orig_value = apply_percentrate(orig_value, 100+rate, 100);
- if (orig_value < 1)
- orig_value = 1;
+
+ if (orig_value < battle_config.min_item_sell_price)
+ orig_value = battle_config.min_item_sell_price;
return orig_value;
}
@@ -4310,9 +4434,8 @@ int pc_modifysellvalue(struct map_session_data *sd, int orig_value)
* Checking if we have enough place on inventory for new item
* Make sure to take 30k as limit (for client I guess)
*------------------------------------------*/
-int pc_checkadditem(struct map_session_data *sd,int nameid,int amount)
+static int pc_checkadditem(struct map_session_data *sd, int nameid, int amount)
{
- int i;
struct item_data* data;
nullpo_ret(sd);
@@ -4328,7 +4451,7 @@ int pc_checkadditem(struct map_session_data *sd,int nameid,int amount)
if( data->stack.inventory && amount > data->stack.amount )
return ADDITEM_OVERAMOUNT;
- for(i=0;i<MAX_INVENTORY;i++){
+ for(int i = 0; i < sd->status.inventorySize; i++) {
// FIXME: This does not consider the checked item's cards, thus could check a wrong slot for stackability.
if(sd->status.inventory[i].nameid==nameid){
if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) )
@@ -4344,13 +4467,12 @@ int pc_checkadditem(struct map_session_data *sd,int nameid,int amount)
* Return number of available place in inventory
* Each non stackable item will reduce place by 1
*------------------------------------------*/
-int pc_inventoryblank(struct map_session_data *sd)
+static int pc_inventoryblank(struct map_session_data *sd)
{
- int i,b;
-
nullpo_ret(sd);
+ int b = 0;
- for(i=0,b=0;i<MAX_INVENTORY;i++){
+ for (int i = 0; i < sd->status.inventorySize; i++) {
if(sd->status.inventory[i].nameid==0)
b++;
}
@@ -4361,7 +4483,7 @@ int pc_inventoryblank(struct map_session_data *sd)
/*==========================================
* attempts to remove zeny from player (sd)
*------------------------------------------*/
-int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, struct map_session_data *tsd)
+static int pc_payzeny(struct map_session_data *sd, int zeny, enum e_log_pick_type type, struct map_session_data *tsd)
{
nullpo_retr(-1,sd);
@@ -4378,59 +4500,70 @@ int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
sd->status.zeny -= zeny;
clif->updatestatus(sd,SP_ZENY);
- if(!tsd) tsd = sd;
- logs->zeny(sd, type, tsd, -zeny);
- if( zeny > 0 && sd->state.showzeny ) {
- char output[255];
- sprintf(output, "Removed %dz.", zeny);
- clif_disp_onlyself(sd, output);
+ if (zeny > 0) {
+ achievement->validate_zeny(sd, -zeny); // Achievements [Smokexyz/Hercules]
+ logs->zeny(sd, type, tsd ? tsd : sd, -zeny);
+
+ if (sd->state.showzeny) {
+ char output[255];
+ sprintf(output, "Removed %dz.", zeny);
+ clif_disp_onlyself(sd, output);
+ }
}
return 0;
}
-/*==========================================
- * Cash Shop
- *------------------------------------------*/
-int pc_paycash(struct map_session_data *sd, int price, int points)
+/**
+ * Calculates leftover cashpoints and kafrapoints when buying an item from cashshop
+ *
+ * @param price Price of the item.
+ * @param points Provided kafra points.
+ *
+ * @return points Leftover kafra points.
+ */
+//Changed Kafrapoints calculation. [Normynator]
+static int pc_paycash(struct map_session_data *sd, int price, int points)
{
int cash;
- nullpo_retr(-1,sd);
+ int mempoints;
+ nullpo_retr(-1, sd);
- points = cap_value(points,-MAX_ZENY,MAX_ZENY); //prevent command UB
- if( price < 0 || points < 0 )
- {
+ points = cap_value(points, -MAX_ZENY, MAX_ZENY); //prevent command UB
+ if (price < 0 || points < 0) {
ShowError("pc_paycash: Paying negative points (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
return -2;
}
- if( points > price )
- {
+ if (points > price) {
ShowWarning("pc_paycash: More kafra points provided than needed (price=%d, points=%d, account_id=%d, char_id=%d).\n", price, points, sd->status.account_id, sd->status.char_id);
- points = price;
+ points = points - price;
+ mempoints = price;
+ cash = 0;
+ } else {
+ cash = price - points;
+ mempoints = points;
+ points = 0;
}
- cash = price-points;
-
- if( sd->cashPoints < cash || sd->kafraPoints < points )
- {
+ if (sd->cashPoints < cash || sd->kafraPoints < mempoints) {
ShowError("pc_paycash: Not enough points (cash=%d, kafra=%d) to cover the price (cash=%d, kafra=%d) (account_id=%d, char_id=%d).\n", sd->cashPoints, sd->kafraPoints, cash, points, sd->status.account_id, sd->status.char_id);
return -1;
}
- pc_setaccountreg(sd, script->add_str("#CASHPOINTS"), sd->cashPoints-cash);
- pc_setaccountreg(sd, script->add_str("#KAFRAPOINTS"), sd->kafraPoints-points);
+ pc_setaccountreg(sd, script->add_variable("#CASHPOINTS"), sd->cashPoints - cash);
+ pc_setaccountreg(sd, script->add_variable("#KAFRAPOINTS"), sd->kafraPoints - mempoints);
- if( battle_config.cashshop_show_points )
- {
+ if (battle_config.cashshop_show_points) {
char output[128];
sprintf(output, msg_sd(sd,504), points, cash, sd->kafraPoints, sd->cashPoints);
clif_disp_onlyself(sd, output);
}
- return cash+points;
+
+ return points;
}
-int pc_getcash(struct map_session_data *sd, int cash, int points)
+static int pc_getcash(struct map_session_data *sd, int cash, int points)
{
char output[128];
nullpo_retr(-1,sd);
@@ -4445,7 +4578,7 @@ int pc_getcash(struct map_session_data *sd, int cash, int points)
cash = MAX_ZENY-sd->cashPoints;
}
- pc_setaccountreg(sd, script->add_str("#CASHPOINTS"), sd->cashPoints+cash);
+ pc_setaccountreg(sd, script->add_variable("#CASHPOINTS"), sd->cashPoints+cash);
if( battle_config.cashshop_show_points )
{
@@ -4468,7 +4601,7 @@ int pc_getcash(struct map_session_data *sd, int cash, int points)
points = MAX_ZENY-sd->kafraPoints;
}
- pc_setaccountreg(sd, script->add_str("#KAFRAPOINTS"), sd->kafraPoints+points);
+ pc_setaccountreg(sd, script->add_variable("#KAFRAPOINTS"), sd->kafraPoints+points);
if( battle_config.cashshop_show_points )
{
@@ -4489,7 +4622,7 @@ int pc_getcash(struct map_session_data *sd, int cash, int points)
* Attempts to give zeny to player (sd)
* tsd (optional) from who for log (if null take sd)
*------------------------------------------*/
-int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, struct map_session_data *tsd)
+static int pc_getzeny(struct map_session_data *sd, int zeny, enum e_log_pick_type type, struct map_session_data *tsd)
{
nullpo_retr(-1,sd);
@@ -4506,12 +4639,15 @@ int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
sd->status.zeny += zeny;
clif->updatestatus(sd,SP_ZENY);
- if(!tsd) tsd = sd;
- logs->zeny(sd, type, tsd, zeny);
- if( zeny > 0 && sd->state.showzeny ) {
- char output[255];
- sprintf(output, "Gained %dz.", zeny);
- clif_disp_onlyself(sd, output);
+ if (zeny > 0) {
+ achievement->validate_zeny(sd, zeny); // Achievements [Smokexyz/Hercules]
+ logs->zeny(sd, type, tsd ? tsd : sd, zeny);
+
+ if (sd->state.showzeny) {
+ char output[255];
+ sprintf(output, "Gained %dz.", zeny);
+ clif_disp_onlyself(sd, output);
+ }
}
return 0;
@@ -4528,12 +4664,13 @@ int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
* @return the inventory index of the first instance of the requested item.
* @retval INDEX_NOT_FOUND if the item wasn't found.
*/
-int pc_search_inventory(struct map_session_data *sd, int item_id) {
+static int pc_search_inventory(struct map_session_data *sd, int item_id)
+{
int i;
nullpo_retr(INDEX_NOT_FOUND, sd);
- ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == item_id && (sd->status.inventory[i].amount > 0 || item_id == 0) );
- return ( i < MAX_INVENTORY ) ? i : INDEX_NOT_FOUND;
+ ARR_FIND(0, sd->status.inventorySize, i, sd->status.inventory[i].nameid == item_id && (sd->status.inventory[i].amount > 0 || item_id == 0));
+ return (i < sd->status.inventorySize) ? i : INDEX_NOT_FOUND;
}
/*==========================================
@@ -4548,7 +4685,7 @@ int pc_search_inventory(struct map_session_data *sd, int item_id) {
* 6 = ?
* 7 = stack limitation
*------------------------------------------*/
-int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type)
+static int pc_additem(struct map_session_data *sd, const struct item *item_data, int amount, e_log_pick_type log_type)
{
struct item_data *data;
int i;
@@ -4595,11 +4732,11 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
}
}
- i = MAX_INVENTORY;
+ i = sd->status.inventorySize;
// Stackable | Non Rental
if( itemdb->isstackable2(data) && item_data->expire_time == 0 ) {
- for( i = 0; i < MAX_INVENTORY; i++ ) {
+ for (i = 0; i < sd->status.inventorySize; i++) {
if( sd->status.inventory[i].nameid == item_data->nameid &&
sd->status.inventory[i].bound == item_data->bound &&
sd->status.inventory[i].expire_time == 0 &&
@@ -4614,7 +4751,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
}
}
- if ( i >= MAX_INVENTORY ) {
+ if (i >= sd->status.inventorySize) {
i = pc->search_inventory(sd,0);
if (i == INDEX_NOT_FOUND)
return 4;
@@ -4629,6 +4766,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
sd->status.inventory[i].amount = amount;
sd->inventory_data[i] = data;
clif->additem(sd,i,amount,0);
+
}
if( ( !itemdb->isstackable2(data) || data->flag.force_serial || data->type == IT_CASH) && !item_data->unique_id )
@@ -4636,6 +4774,8 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
logs->pick_pc(sd, log_type, amount, &sd->status.inventory[i],sd->inventory_data[i]);
+ achievement->validate_item_get(sd, sd->status.inventory[i].nameid, sd->status.inventory[i].amount); // Achievements [Smokexyz/Hercules]
+
sd->weight += w;
clif->updatestatus(sd,SP_WEIGHT);
//Auto-equip
@@ -4652,6 +4792,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
pc->inventory_rental_add(sd, seconds);
}
}
+ quest->questinfo_refresh(sd);
return 0;
}
@@ -4667,10 +4808,10 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l
* 0 = success
* 1 = invalid itemid or negative amount
*------------------------------------------*/
-int pc_delitem(struct map_session_data *sd,int n,int amount,int type, short reason, e_log_pick_type log_type)
+static int pc_delitem(struct map_session_data *sd, int n, int amount, int type, short reason, e_log_pick_type log_type)
{
nullpo_retr(1, sd);
- Assert_retr(1, n >= 0 && n < MAX_INVENTORY);
+ Assert_retr(1, n >= 0 && n < sd->status.inventorySize);
if(sd->status.inventory[n].nameid==0 || amount <= 0 || sd->status.inventory[n].amount<amount || sd->inventory_data[n] == NULL)
return 1;
@@ -4689,6 +4830,7 @@ int pc_delitem(struct map_session_data *sd,int n,int amount,int type, short reas
clif->delitem(sd,n,amount,reason);
if(!(type&2))
clif->updatestatus(sd,SP_WEIGHT);
+ quest->questinfo_refresh(sd);
return 0;
}
@@ -4699,11 +4841,11 @@ int pc_delitem(struct map_session_data *sd,int n,int amount,int type, short reas
* 0 = fail
* 1 = success
*------------------------------------------*/
-int pc_dropitem(struct map_session_data *sd,int n,int amount)
+static int pc_dropitem(struct map_session_data *sd, int n, int amount)
{
nullpo_retr(1, sd);
- if(n < 0 || n >= MAX_INVENTORY)
+ if(n < 0 || n >= sd->status.inventorySize)
return 0;
if(amount <= 0)
@@ -4728,7 +4870,7 @@ int pc_dropitem(struct map_session_data *sd,int n,int amount)
return 0;
}
- if (!map->addflooritem(&sd->bl, &sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 2))
+ if (!map->addflooritem(&sd->bl, &sd->status.inventory[n], amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 2, false))
return 0;
pc->delitem(sd, n, amount, 1, DELITEM_NORMAL, LOG_TYPE_PICKDROP_PLAYER);
@@ -4742,7 +4884,7 @@ int pc_dropitem(struct map_session_data *sd,int n,int amount)
* 0 = fail
* 1 = success
*------------------------------------------*/
-int pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem)
+static int pc_takeitem(struct map_session_data *sd, struct flooritem_data *fitem)
{
int flag=0;
int64 tick = timer->gettick();
@@ -4808,13 +4950,13 @@ int pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem)
* 0 = no
* 1 = yes
*------------------------------------------*/
-int pc_isUseitem(struct map_session_data *sd,int n)
+static int pc_isUseitem(struct map_session_data *sd, int n)
{
struct item_data *item;
int nameid;
nullpo_ret(sd);
- Assert_ret(n >= 0 && n < MAX_INVENTORY);
+ Assert_ret(n >= 0 && n < sd->status.inventorySize);
item = sd->inventory_data[n];
nameid = sd->status.inventory[n].nameid;
@@ -4828,33 +4970,73 @@ int pc_isUseitem(struct map_session_data *sd,int n)
return 0;
if ((item->item_usage.flag&INR_SITTING) && (pc_issit(sd) == 1) && (pc_get_group_level(sd) < item->item_usage.override)) {
- clif->msgtable(sd, MSG_ITEM_NEED_STANDING);
+ clif->msgtable(sd, MSG_CANT_USE_WHEN_SITDOWN);
//clif->messagecolor_self(sd->fd, COLOR_WHITE, msg_txt(1474));
return 0; // You cannot use this item while sitting.
}
- if (sd->state.storage_flag != STORAGE_FLAG_CLOSED && item->type != IT_CASH) {
- clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd,1475));
- return 0; // You cannot use this item while storage is open.
- }
-
switch( nameid ) { // TODO: Is there no better way to handle this, other than hardcoding item IDs?
case ITEMID_ANODYNE:
- if( map_flag_gvg2(sd->bl.m) )
- return 0;
- /* Fall through */
- case ITEMID_ALOEBERA:
- if( pc_issit(sd) )
+ if (map_flag_gvg2(sd->bl.m)) {
+#if PACKETVER >= 20080311
+ clif->skill_mapinfomessage(sd, 3);
+#else
+ clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 51));
+#endif
return 0;
+ }
break;
+
+ case ITEMID_GIANT_FLY_WING: {
+ struct party_data *p;
+
+ if (!sd->status.party_id) {
+#if PACKETVER >= 20061030
+ clif->msgtable(sd, MSG_CANNOT_PARTYCALL);
+#endif
+ break;
+ }
+
+ if ((p = party->search(sd->status.party_id)) != NULL) {
+ int i;
+ int16 m;
+
+ ARR_FIND(0, MAX_PARTY, i, p->data[i].sd == sd);
+
+ if (i == MAX_PARTY || !p->party.member[i].leader) {
+#if PACKETVER >= 20061030
+ clif->msgtable(sd, MSG_CANNOT_PARTYCALL);
+#endif
+ break;
+ }
+
+ m = sd->bl.m;
+
+ ARR_FIND(0, MAX_PARTY, i, p->data[i].sd && p->data[i].sd != sd && p->data[i].sd->bl.m == m);
+
+ if (i == MAX_PARTY || pc_isdead(p->data[i].sd)) {
+#if PACKETVER >= 20061030
+ clif->msgtable(sd, MSG_NO_PARTYMEM_ON_THISMAP);
+#endif
+ break;
+ }
+ }
+ }
+ FALLTHROUGH
case ITEMID_WING_OF_FLY:
- case ITEMID_GIANT_FLY_WING:
- if( map->list[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m) ) {
- clif->skill_mapinfomessage(sd,0);
+ case ITEMID_N_FLY_WING:
+ case ITEMID_C_WING_OF_FLY:
+ if (map->list[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m)) {
+#if PACKETVER >= 20080311
+ clif->skill_mapinfomessage(sd, 0);
+#else
+ clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd, 49));
+#endif
return 0;
}
/* Fall through */
case ITEMID_WING_OF_BUTTERFLY:
+ case ITEMID_N_BUTTERFLY_WING:
case ITEMID_DUN_TELE_SCROLL1:
case ITEMID_DUN_TELE_SCROLL2:
case ITEMID_WOB_RUNE: // Yellow Butterfly Wing
@@ -4866,34 +5048,27 @@ int pc_isUseitem(struct map_session_data *sd,int n)
clif->message(sd->fd, msg_sd(sd,863)); // "Duel: Can't use this item in duel."
return 0;
}
- if( nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && map->list[sd->bl.m].flag.noreturn )
+ if (nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && map->list[sd->bl.m].flag.noreturn) {
+#if PACKETVER >= 20080311
+ clif->skill_mapinfomessage(sd, 0);
+#else
+ clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd, 49));
+#endif
return 0;
+ }
break;
case ITEMID_BRANCH_OF_DEAD_TREE:
case ITEMID_RED_POUCH_OF_SURPRISE:
case ITEMID_BLOODY_DEAD_BRANCH:
case ITEMID_PORING_BOX:
- if( map->list[sd->bl.m].flag.nobranch || map_flag_gvg2(sd->bl.m) )
- return 0;
- break;
- case ITEMID_BUBBLE_GUM:
- case ITEMID_COMP_BUBBLE_GUM:
- if( sd->sc.data[SC_CASH_RECEIVEITEM] )
- return 0;
- break;
- case ITEMID_BATTLE_MANUAL:
- case ITEMID_COMP_BATTLE_MANUAL:
- case ITEMID_THICK_MANUAL50:
- case ITEMID_NOBLE_NAMEPLATE:
- case ITEMID_BATTLE_MANUAL25:
- case ITEMID_BATTLE_MANUAL100:
- case ITEMID_BATTLE_MANUAL_X3:
- if( sd->sc.data[SC_CASH_PLUSEXP] )
- return 0;
- break;
- case ITEMID_JOB_MANUAL50:
- if( sd->sc.data[SC_CASH_PLUSONLYJOBEXP] )
+ if (map->list[sd->bl.m].flag.nobranch || map_flag_gvg2(sd->bl.m)) {
+#if PACKETVER >= 20080311
+ clif->skill_mapinfomessage(sd, 3);
+#else
+ clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 51));
+#endif
return 0;
+ }
break;
// Mercenary Items
@@ -4913,28 +5088,23 @@ int pc_isUseitem(struct map_session_data *sd,int n)
break;
case ITEMID_NEURALIZER:
- if( !map->list[sd->bl.m].flag.reset )
+ if (!map->list[sd->bl.m].flag.reset) {
+#if PACKETVER >= 20080311
+ clif->skill_mapinfomessage(sd, 3);
+#else
+ clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 51));
+#endif
return 0;
+ }
break;
}
if( nameid >= ITEMID_BOW_MERCENARY_SCROLL1 && nameid <= ITEMID_SPEARMERCENARY_SCROLL10 && sd->md != NULL ) // Mercenary Scrolls
return 0;
- /**
- * Only Rune Knights may use runes
- **/
- if (itemdb_is_rune(nameid) && (sd->job & MAPID_THIRDMASK) != MAPID_RUNE_KNIGHT)
- return 0;
- /**
- * Only GCross may use poisons
- **/
- else if (itemdb_is_poison(nameid) && (sd->job & MAPID_THIRDMASK) != MAPID_GUILLOTINE_CROSS)
- return 0;
-
if( item->package || item->group ) {
if (pc_is90overweight(sd)) {
- clif->msgtable(sd, MSG_ITEM_CANT_OBTAIN_WEIGHT);
+ clif->msgtable(sd, MSG_CANT_GET_ITEM_BECAUSE_WEIGHT);
return 0;
}
if (!pc->inventoryblank(sd)) {
@@ -4948,12 +5118,16 @@ int pc_isUseitem(struct map_session_data *sd,int n)
return 0;
//Required level check
if (item->elv && sd->status.base_level < item->elv) {
- clif->msgtable(sd, MSG_ITEM_CANT_USE_LVL);
+#if PACKETVER >= 20100525
+ clif->msgtable(sd, MSG_CANNOT_USE_ITEM_LEVEL);
+#endif
return 0;
}
if (item->elvmax && sd->status.base_level > item->elvmax) {
- clif->msgtable(sd, MSG_ITEM_CANT_USE_LVL);
+#if PACKETVER >= 20100525
+ clif->msgtable(sd, MSG_CANNOT_USE_ITEM_LEVEL);
+#endif
return 0;
}
@@ -4990,7 +5164,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
break;
}
// Upper third classes
- if ((item->class_upper & ITEMUPPER_THURDUPPER) != 0) {
+ if ((item->class_upper & ITEMUPPER_THIRDUPPER) != 0) {
if ((sd->job & JOBL_THIRD) != 0 && (sd->job & JOBL_UPPER) != 0)
break;
}
@@ -5011,25 +5185,35 @@ int pc_isUseitem(struct map_session_data *sd,int n)
* 0 = fail
* 1 = success
*------------------------------------------*/
-int pc_useitem(struct map_session_data *sd,int n) {
+static int pc_useitem(struct map_session_data *sd, int n)
+{
int64 tick = timer->gettick();
int amount, nameid, i;
bool removeItem = false;
nullpo_ret(sd);
- Assert_ret(n >= 0 && n < MAX_INVENTORY);
+ Assert_ret(n >= 0 && n < sd->status.inventorySize);
- if( sd->npc_id || sd->state.workinprogress&1 ){
- /* TODO: add to clif->messages enum */
-#ifdef RENEWAL
- clif->msgtable(sd, MSG_NPC_WORK_IN_PROGRESS); // TODO look for the client date that has this message.
+ if (sd->npc_id || sd->state.workinprogress & 1) {
+#if PACKETVER >= 20110308
+ clif->msgtable(sd, MSG_BUSY);
+#else
+ clif->messagecolor_self(sd->fd, COLOR_WHITE, msg_sd(sd, 48));
#endif
return 0;
}
+ if (battle_config.storage_use_item == 1 && sd->state.storage_flag != STORAGE_FLAG_CLOSED) {
+ clif->messagecolor_self(sd->fd, COLOR_RED, msg_sd(sd, 1475));
+ return 0; // You cannot use this item while storage is open.
+ }
+
if( sd->status.inventory[n].nameid <= 0 || sd->status.inventory[n].amount <= 0 )
return 0;
+ if (sd->block_action.useitem) // *pcblock script command
+ return 0;
+
if( !pc->isUseitem(sd,n) )
return 0;
@@ -5058,10 +5242,8 @@ int pc_useitem(struct map_session_data *sd,int n) {
))
return 0;
- //Prevent mass item usage. [Skotlex]
- if( DIFF_TICK(sd->canuseitem_tick, tick) > 0 ||
- (itemdb_iscashfood(nameid) && DIFF_TICK(sd->canusecashfood_tick, tick) > 0)
- )
+ // Prevent mass item usage. [Skotlex]
+ if (DIFF_TICK(sd->canuseitem_tick, tick) > 0)
return 0;
/* Items with delayed consume are not meant to work while in mounts except reins of mount(12622) */
@@ -5078,15 +5260,21 @@ int pc_useitem(struct map_session_data *sd,int n) {
if( sd->inventory_data[n]->flag.delay_consume && ( sd->ud.skilltimer != INVALID_TIMER /*|| !status->check_skilluse(&sd->bl, &sd->bl, ALL_RESURRECTION, 0)*/ ) )
return 0;
- if( sd->inventory_data[n]->delay > 0 ) {
- ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid );
- if( i == MAX_ITEMDELAYS ) /* item not found. try first empty now */
- ARR_FIND(0, MAX_ITEMDELAYS, i, !sd->item_delay[i].nameid );
- if( i < MAX_ITEMDELAYS ) {
- if( sd->item_delay[i].nameid ) {// found
- if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) {
- int e_tick = (int)(DIFF_TICK(sd->item_delay[i].tick, tick)/1000);
- clif->msgtable_num(sd, MSG_SECONDS_UNTIL_USE, e_tick + 1); // [%d] seconds left until you can use
+ if (sd->inventory_data[n]->delay > 0) {
+ ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid);
+ if (i == MAX_ITEMDELAYS) /* item not found. try first empty now */
+ ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == 0);
+ if (i < MAX_ITEMDELAYS) {
+ if (sd->item_delay[i].nameid != 0) {// found
+ if (DIFF_TICK(sd->item_delay[i].tick, tick) > 0) {
+ int delay_tick = (int)(DIFF_TICK(sd->item_delay[i].tick, tick) / 1000);
+#if PACKETVER >= 20101123
+ clif->msgtable_num(sd, MSG_ITEM_REUSE_LIMIT_SECOND, delay_tick + 1); // [%d] seconds left until you can use
+#else
+ char delay_msg[100];
+ sprintf(delay_msg, msg_sd(sd, 26), delay_tick + 1);
+ clif->messagecolor_self(sd->fd, COLOR_YELLOW, delay_msg); // [%d] seconds left until you can use
+#endif
return 0; // Delay has not expired yet
}
} else {// not yet used item (all slots are initially empty)
@@ -5109,7 +5297,11 @@ int pc_useitem(struct map_session_data *sd,int n) {
/* on restricted maps the item is consumed but the effect is not used */
for(i = 0; i < map->list[sd->bl.m].zone->disabled_items_count; i++) {
if( map->list[sd->bl.m].zone->disabled_items[i] == nameid ) {
- clif->msgtable(sd, MSG_ITEM_CANT_USE_AREA); // This item cannot be used within this area
+#if PACKETVER >= 20080311
+ clif->skill_mapinfomessage(sd, 3);
+#else
+ clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 50));
+#endif
if( battle_config.item_restricted_consumption_type && sd->status.inventory[n].expire_time == 0 ) {
clif->useitemack(sd,n,sd->status.inventory[n].amount-1,true);
pc->delitem(sd, n, 1, 1, DELITEM_NORMAL, LOG_TYPE_CONSUME);
@@ -5127,6 +5319,10 @@ int pc_useitem(struct map_session_data *sd,int n) {
if(sd->catch_target_class != -1) //Abort pet catching.
sd->catch_target_class = -1;
+ // Removes abracadabra/randomize spell flag for delayed consume items or item doesn't get consumed
+ if (sd->inventory_data[n]->flag.delay_consume)
+ sd->state.abra_flag = 0;
+
amount = sd->status.inventory[n].amount;
//Check if the item is to be consumed immediately [Skotlex]
if (sd->inventory_data[n]->flag.delay_consume || sd->inventory_data[n]->flag.keepafteruse)
@@ -5147,10 +5343,8 @@ int pc_useitem(struct map_session_data *sd,int n) {
script->potion_flag = 3; //Even more effective potions.
}
- //Update item use time.
+ // Update item use time.
sd->canuseitem_tick = tick + battle_config.item_use_interval;
- if( itemdb_iscashfood(nameid) )
- sd->canusecashfood_tick = tick + battle_config.cashfood_use_interval;
script->run_use_script(sd, sd->inventory_data[n], npc->fake_nd->bl.id);
script->potion_flag = 0;
@@ -5166,7 +5360,7 @@ int pc_useitem(struct map_session_data *sd,int n) {
* 0 = success
* 1 = fail
*------------------------------------------*/
-int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type)
+static int pc_cart_additem(struct map_session_data *sd, struct item *item_data, int amount, e_log_pick_type log_type)
{
struct item_data *data;
int i,w;
@@ -5235,10 +5429,11 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun
* 0 = success
* 1 = fail
*------------------------------------------*/
-int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type,e_log_pick_type log_type) {
+static int pc_cart_delitem(struct map_session_data *sd, int n, int amount, int type, e_log_pick_type log_type)
+{
struct item_data * data;
nullpo_retr(1, sd);
- Assert_retr(1, n >= 0 && n < MAX_INVENTORY);
+ Assert_retr(1, n >= 0 && n < MAX_CART);
if( sd->status.cart[n].nameid == 0 || sd->status.cart[n].amount < amount || !(data = itemdb->exists(sd->status.cart[n].nameid)) )
return 1;
@@ -5265,14 +5460,14 @@ int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type,e_log_
* 0 = fail
* 1 = succes
*------------------------------------------*/
-int pc_putitemtocart(struct map_session_data *sd,int idx,int amount)
+static int pc_putitemtocart(struct map_session_data *sd, int idx, int amount)
{
struct item *item_data;
int flag;
nullpo_ret(sd);
- if (idx < 0 || idx >= MAX_INVENTORY) //Invalid index check [Skotlex]
+ if (idx < 0 || idx >= sd->status.inventorySize) //Invalid index check [Skotlex]
return 1;
item_data = &sd->status.inventory[idx];
@@ -5292,7 +5487,7 @@ int pc_putitemtocart(struct map_session_data *sd,int idx,int amount)
* -1 = itemid not found or no amount found
* x = remaining itemid on cart after get
*------------------------------------------*/
-int pc_cartitem_amount(struct map_session_data* sd, int idx, int amount)
+static int pc_cartitem_amount(struct map_session_data *sd, int idx, int amount)
{
struct item* item_data;
@@ -5312,7 +5507,7 @@ int pc_cartitem_amount(struct map_session_data* sd, int idx, int amount)
* 0 = player not found or (FIXME) succes (from pc->cart_delitem)
* 1 = failure
*------------------------------------------*/
-int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
+static int pc_getitemfromcart(struct map_session_data *sd, int idx, int amount)
{
struct item *item_data;
int flag;
@@ -5333,7 +5528,7 @@ int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount)
return flag;
}
-void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type)
+static void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type)
{
int i;
@@ -5342,7 +5537,7 @@ void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type)
/* both restricted to inventory */
case IBT_PARTY:
case IBT_CHARACTER:
- for( i = 0; i < MAX_INVENTORY; i++ ){
+ for (i = 0; i < sd->status.inventorySize; i++ ) {
if( sd->status.inventory[i].bound == type ) {
pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_SKILLUSE, LOG_TYPE_OTHER); // FIXME: is this the correct reason flag?
}
@@ -5354,7 +5549,7 @@ void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type)
case IBT_GUILD: {
struct guild_storage *gstor = idb_get(gstorage->db,sd->status.guild_id);
- for( i = 0; i < MAX_INVENTORY; i++ ){
+ for (i = 0; i < sd->status.inventorySize; i++ ) {
if(sd->status.inventory[i].bound == type) {
if( gstor )
gstorage->additem(sd,gstor,&sd->status.inventory[i],sd->status.inventory[i].amount);
@@ -5370,7 +5565,7 @@ void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type)
/*==========================================
* Display item stolen msg to player sd
*------------------------------------------*/
-int pc_show_steal(struct block_list *bl,va_list ap)
+static int pc_show_steal(struct block_list *bl, va_list ap)
{
struct map_session_data *sd = NULL, *tsd = NULL;
int itemid;
@@ -5400,7 +5595,7 @@ int pc_show_steal(struct block_list *bl,va_list ap)
* 0 = fail
* 1 = succes
*------------------------------------------*/
-int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skill_lv)
+static int pc_steal_item(struct map_session_data *sd, struct block_list *bl, uint16 skill_lv)
{
int i,itemid,flag;
int rate;
@@ -5467,13 +5662,6 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil
//Logs items, Stolen from mobs [Lupus]
logs->pick_mob(md, LOG_TYPE_STEAL, -1, &tmp_item, data);
- //A Rare Steal Global Announce by Lupus
- if(md->db->dropitem[i].p<=battle_config.rare_drop_announce) {
- char message[128];
- sprintf (message, msg_txt(542), sd->status.name, md->db->jname, data->jname, (float)md->db->dropitem[i].p / 100);
- //MSG: "'%s' stole %s's %s (chance: %0.02f%%)"
- intif->broadcast(message, (int)strlen(message)+1, BC_DEFAULT);
- }
return 1;
}
@@ -5486,7 +5674,7 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil
*
* @return Amount of stolen zeny (0 in case of failure)
*/
-int pc_steal_coin(struct map_session_data *sd, struct block_list *target, uint16 skill_lv)
+static int pc_steal_coin(struct map_session_data *sd, struct block_list *target, uint16 skill_lv)
{
int rate;
struct mob_data *md = BL_CAST(BL_MOB, target);
@@ -5518,7 +5706,8 @@ int pc_steal_coin(struct map_session_data *sd, struct block_list *target, uint16
* 1 - Invalid map index.
* 2 - Map not in this map-server, and failed to locate alternate map-server.
*------------------------------------------*/
-int pc_setpos(struct map_session_data* sd, unsigned short map_index, int x, int y, clr_type clrtype) {
+static int pc_setpos(struct map_session_data *sd, unsigned short map_index, int x, int y, enum clr_type clrtype)
+{
int16 m;
nullpo_ret(sd);
@@ -5601,7 +5790,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short map_index, int x, int
for (i = 0; i < VECTOR_LENGTH(sd->script_queues); i++) {
struct script_queue *queue = script->queue(VECTOR_INDEX(sd->script_queues, i));
if (queue && queue->event_mapchange[0] != '\0') {
- pc->setregstr(sd, script->add_str("@Queue_Destination_Map$"), map->list[m].name);
+ pc->setregstr(sd, script->add_variable("@Queue_Destination_Map$"), map->list[m].name);
npc->event(sd, queue->event_mapchange, 0);
}
}
@@ -5649,8 +5838,11 @@ int pc_setpos(struct map_session_data* sd, unsigned short map_index, int x, int
vending->close(sd);
}
- if (map->list[sd->bl.m].channel) {
- channel->leave(map->list[sd->bl.m].channel,sd);
+ if (sd->mapindex != 0) {
+ // Only if the character is already on a map
+ if (map->list[sd->bl.m].channel) {
+ channel->leave(map->list[sd->bl.m].channel,sd);
+ }
}
}
@@ -5754,7 +5946,8 @@ int pc_setpos(struct map_session_data* sd, unsigned short map_index, int x, int
* 0 = fail or FIXME success (from pc->setpos)
* x(1|2) = fail
*------------------------------------------*/
-int pc_randomwarp(struct map_session_data *sd, clr_type type) {
+static int pc_randomwarp(struct map_session_data *sd, enum clr_type type)
+{
int x,y,i=0;
int16 m;
@@ -5780,7 +5973,8 @@ int pc_randomwarp(struct map_session_data *sd, clr_type type) {
* Records a memo point at sd's current position
* pos - entry to replace, (-1: shift oldest entry out)
*------------------------------------------*/
-int pc_memo(struct map_session_data* sd, int pos) {
+static int pc_memo(struct map_session_data *sd, int pos)
+{
int skill_lv;
nullpo_ret(sd);
@@ -5830,8 +6024,9 @@ int pc_memo(struct map_session_data* sd, int pos) {
/*==========================================
* Return player sd skill_lv learned for given skill
*------------------------------------------*/
-int pc_checkskill(struct map_session_data *sd,uint16 skill_id) {
- uint16 index = 0;
+static int pc_checkskill(struct map_session_data *sd, uint16 skill_id)
+{
+ int index = 0;
if(sd == NULL) return 0;
if( skill_id >= GD_SKILLBASE && skill_id < GD_MAX ) {
struct guild *g;
@@ -5849,9 +6044,11 @@ int pc_checkskill(struct map_session_data *sd,uint16 skill_id) {
return 0;
}
-int pc_checkskill2(struct map_session_data *sd,uint16 index) {
- if(sd == NULL) return 0;
- if(index >= ARRAYLENGTH(sd->status.skill) ) {
+static int pc_checkskill2(struct map_session_data *sd, uint16 index)
+{
+ if (sd == NULL)
+ return 0;
+ if (index >= MAX_SKILL_DB) {
ShowError("pc_checkskill: Invalid skill index %d (char_id=%d).\n", index, sd->status.char_id);
return 0;
}
@@ -5874,7 +6071,7 @@ int pc_checkskill2(struct map_session_data *sd,uint16 index) {
* Return
* 0 - No status found or all done
*------------------------------------------*/
-int pc_checkallowskill(struct map_session_data *sd)
+static int pc_checkallowskill(struct map_session_data *sd)
{
const enum sc_type scw_list[] = {
SC_TWOHANDQUICKEN,
@@ -5914,11 +6111,11 @@ int pc_checkallowskill(struct map_session_data *sd)
status_change_end(&sd->bl, scw_list[i], INVALID_TIMER);
}
- if(sd->sc.data[SC_STRUP] && sd->status.weapon)
+ if(sd->sc.data[SC_STRUP] && sd->weapontype != W_FIST)
// Spurt requires bare hands (feet, in fact xD)
status_change_end(&sd->bl, SC_STRUP, INVALID_TIMER);
- if(sd->status.shield <= 0) { // Skills requiring a shield
+ if (!sd->has_shield) { // Skills requiring a shield
for (i = 0; i < ARRAYLENGTH(scs_list); i++)
if(sd->sc.data[scs_list[i]])
status_change_end(&sd->bl, scs_list[i], INVALID_TIMER);
@@ -5932,7 +6129,7 @@ int pc_checkallowskill(struct map_session_data *sd)
* -1 : mean nothing equiped
* idx : (this index could be used in inventory to found item_data)
*------------------------------------------*/
-int pc_checkequip(struct map_session_data *sd,int pos)
+static int pc_checkequip(struct map_session_data *sd, int pos)
{
int i;
@@ -5950,7 +6147,7 @@ int pc_checkequip(struct map_session_data *sd,int pos)
* Convert's from the client's lame Job ID system
* to the map server's 'makes sense' system. [Skotlex]
*------------------------------------------*/
-int pc_jobid2mapid(int16 class)
+static int pc_jobid2mapid(int16 class)
{
switch (class) {
//Novice And 1-1 Jobs
@@ -6092,7 +6289,7 @@ int pc_jobid2mapid(int16 class)
}
//Reverts the map-style class id to the client-style one.
-int pc_mapid2jobid(uint16 job, int sex)
+static int pc_mapid2jobid(uint16 job, int sex)
{
switch (job) {
//Novice And 1-1 Jobs
@@ -6229,7 +6426,7 @@ int pc_mapid2jobid(uint16 job, int sex)
/*====================================================
* This function return the name of the job (by [Yor])
*----------------------------------------------------*/
-const char *job_name(int class)
+static const char *job_name(int class)
{
switch (class) {
case JOB_NOVICE: // 550
@@ -6458,7 +6655,8 @@ const char *job_name(int class)
}
}
-int pc_check_job_name(const char *name) {
+static int pc_check_job_name(const char *name)
+{
int i, len;
struct {
const char *name;
@@ -6592,7 +6790,8 @@ int pc_check_job_name(const char *name) {
return names[i].id;
}
-int pc_follow_timer(int tid, int64 tick, int id, intptr_t data) {
+static int pc_follow_timer(int tid, int64 tick, int id, intptr_t data)
+{
struct map_session_data *sd;
struct block_list *tbl;
@@ -6630,7 +6829,7 @@ int pc_follow_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
-int pc_stop_following (struct map_session_data *sd)
+static int pc_stop_following(struct map_session_data *sd)
{
nullpo_ret(sd);
@@ -6646,7 +6845,8 @@ int pc_stop_following (struct map_session_data *sd)
return 0;
}
-int pc_follow(struct map_session_data *sd,int target_id) {
+static int pc_follow(struct map_session_data *sd, int target_id)
+{
struct block_list *bl = map->id2bl(target_id);
nullpo_retr(1, sd);
if (bl == NULL /*|| bl->type != BL_PC*/)
@@ -6660,8 +6860,9 @@ int pc_follow(struct map_session_data *sd,int target_id) {
return 0;
}
-int pc_checkbaselevelup(struct map_session_data *sd) {
- unsigned int next = pc->nextbaseexp(sd);
+static int pc_checkbaselevelup(struct map_session_data *sd)
+{
+ uint64 next = pc->nextbaseexp(sd);
nullpo_ret(sd);
if (!next || sd->status.base_exp < next)
@@ -6690,29 +6891,42 @@ int pc_checkbaselevelup(struct map_session_data *sd) {
status_calc_pc(sd,SCO_FORCE);
status_percent_heal(&sd->bl,100,100);
- if ((sd->job & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) {
- sc_start(NULL,&sd->bl,status->skill2sc(PR_KYRIE),100,1,skill->get_time(PR_KYRIE,1));
- sc_start(NULL,&sd->bl,status->skill2sc(PR_IMPOSITIO),100,1,skill->get_time(PR_IMPOSITIO,1));
- sc_start(NULL,&sd->bl,status->skill2sc(PR_MAGNIFICAT),100,1,skill->get_time(PR_MAGNIFICAT,1));
- sc_start(NULL,&sd->bl,status->skill2sc(PR_GLORIA),100,1,skill->get_time(PR_GLORIA,1));
- sc_start(NULL,&sd->bl,status->skill2sc(PR_SUFFRAGIUM),100,1,skill->get_time(PR_SUFFRAGIUM,1));
- if (sd->state.snovice_dead_flag)
- sd->state.snovice_dead_flag = 0; //Reenable steelbody resurrection on dead.
- } else if ((sd->job & MAPID_BASEMASK) == MAPID_TAEKWON) {
- sc_start(NULL,&sd->bl,status->skill2sc(AL_INCAGI),100,10,600000);
- sc_start(NULL,&sd->bl,status->skill2sc(AL_BLESSING),100,10,600000);
- }
+ pc->checkbaselevelup_sc(sd);
clif->misceffect(&sd->bl,0);
npc->script_event(sd, NPCE_BASELVUP); //LORDALFA - LVLUPEVENT
- if(sd->status.party_id)
+ if (sd->status.party_id)
party->send_levelup(sd);
pc->baselevelchanged(sd);
+
+ quest->questinfo_refresh(sd);
+
+ achievement->validate_stats(sd, SP_BASELEVEL, sd->status.base_level);
+
return 1;
}
-void pc_baselevelchanged(struct map_session_data *sd) {
+static void pc_checkbaselevelup_sc(struct map_session_data *sd)
+{
+ nullpo_retv(sd);
+
+ if ((sd->job & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) {
+ sc_start(NULL, &sd->bl, status->skill2sc(PR_KYRIE), 100, 1, skill->get_time(PR_KYRIE, 1));
+ sc_start(NULL, &sd->bl, status->skill2sc(PR_IMPOSITIO), 100, 1, skill->get_time(PR_IMPOSITIO, 1));
+ sc_start(NULL, &sd->bl, status->skill2sc(PR_MAGNIFICAT), 100, 1, skill->get_time(PR_MAGNIFICAT, 1));
+ sc_start(NULL, &sd->bl, status->skill2sc(PR_GLORIA), 100, 1, skill->get_time(PR_GLORIA, 1));
+ sc_start(NULL, &sd->bl, status->skill2sc(PR_SUFFRAGIUM), 100, 1, skill->get_time(PR_SUFFRAGIUM, 1));
+ if (sd->state.snovice_dead_flag)
+ sd->state.snovice_dead_flag = 0; //Reenable steelbody resurrection on dead.
+ } else if ((sd->job & MAPID_BASEMASK) == MAPID_TAEKWON) {
+ sc_start(NULL, &sd->bl, status->skill2sc(AL_INCAGI), 100, 10, 600000);
+ sc_start(NULL, &sd->bl, status->skill2sc(AL_BLESSING), 100, 10, 600000);
+ }
+}
+
+static void pc_baselevelchanged(struct map_session_data *sd)
+{
int i;
nullpo_retv(sd);
for( i = 0; i < EQI_MAX; i++ ) {
@@ -6723,9 +6937,9 @@ void pc_baselevelchanged(struct map_session_data *sd) {
}
}
-int pc_checkjoblevelup(struct map_session_data *sd)
+static int pc_checkjoblevelup(struct map_session_data *sd)
{
- unsigned int next = pc->nextjobexp(sd);
+ uint64 next = pc->nextjobexp(sd);
nullpo_ret(sd);
if(!next || sd->status.job_exp < next)
@@ -6752,13 +6966,19 @@ int pc_checkjoblevelup(struct map_session_data *sd)
clif->status_change(&sd->bl,SI_DEVIL1, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL.
npc->script_event(sd, NPCE_JOBLVUP);
+
+ quest->questinfo_refresh(sd);
+
+ achievement->validate_stats(sd, SP_BASELEVEL, sd->status.job_level);
+
return 1;
}
/**
* Alters EXP based on self bonuses that do not get shared with the party
**/
-void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned int *job_exp, struct block_list *src) {
+static void pc_calcexp(struct map_session_data *sd, uint64 *base_exp, uint64 *job_exp, struct block_list *src)
+{
int buff_ratio = 0, buff_job_ratio = 0, race_ratio = 0, pk_ratio = 0;
int64 jexp, bexp;
@@ -6823,8 +7043,8 @@ void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned in
bexp += apply_percentrate64(bexp, buff_ratio, 100);
jexp += apply_percentrate64(jexp, buff_ratio + buff_job_ratio, 100);
- *job_exp = (unsigned int)cap_value(jexp, 1, UINT_MAX);
- *base_exp = (unsigned int)cap_value(bexp, 1, UINT_MAX);
+ *job_exp = cap_value(jexp, 1, UINT64_MAX);
+ *base_exp = cap_value(bexp, 1, UINT64_MAX);
}
/**
@@ -6833,9 +7053,10 @@ void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned in
* @param is_quest Used to let client know that the EXP was from a quest (clif->displayexp) PACKETVER >= 20091027
* @retval true success
**/
-bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int base_exp,unsigned int job_exp,bool is_quest) {
- float nextbp=0, nextjp=0;
- unsigned int nextb=0, nextj=0;
+static bool pc_gainexp(struct map_session_data *sd, struct block_list *src, uint64 base_exp, uint64 job_exp, bool is_quest)
+{
+ float nextbp = 0, nextjp = 0;
+ uint64 nextb = 0, nextj = 0;
nullpo_ret(sd);
if (sd->bl.prev == NULL || pc_isdead(sd))
@@ -6851,7 +7072,7 @@ bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in
pc->calcexp(sd, &base_exp, &job_exp, src);
if (sd->status.guild_id > 0)
- base_exp -= guild->payexp(sd,base_exp);
+ base_exp -= guild->payexp(sd, base_exp);
nextb = pc->nextbaseexp(sd);
nextj = pc->nextjobexp(sd);
@@ -6862,16 +7083,16 @@ bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in
if (nextj > 0)
nextjp = (float) job_exp / (float) nextj;
- if(battle_config.max_exp_gain_rate) {
+ if (battle_config.max_exp_gain_rate) {
if (nextbp > battle_config.max_exp_gain_rate/1000.) {
//Note that this value should never be greater than the original
//base_exp, therefore no overflow checks are needed. [Skotlex]
- base_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextb);
+ base_exp = (uint64)(battle_config.max_exp_gain_rate / 1000. * nextb);
if (sd->state.showexp)
nextbp = (float) base_exp / (float) nextb;
}
if (nextjp > battle_config.max_exp_gain_rate/1000.) {
- job_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextj);
+ job_exp = (uint64)(battle_config.max_exp_gain_rate / 1000. * nextj);
if (sd->state.showexp)
nextjp = (float) job_exp / (float) nextj;
}
@@ -6881,23 +7102,23 @@ bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in
// Cap exp to the level up requirement of the previous level when you are at max level,
// otherwise cap at UINT_MAX (this is required for some S. Novice bonuses). [Skotlex]
if (base_exp) {
- nextb = nextb?UINT_MAX:pc->thisbaseexp(sd);
- if(sd->status.base_exp > nextb - base_exp)
+ nextb = nextb ? UINT64_MAX : pc->thisbaseexp(sd);
+ if (sd->status.base_exp > nextb - base_exp)
sd->status.base_exp = nextb;
else
sd->status.base_exp += base_exp;
pc->checkbaselevelup(sd);
- clif->updatestatus(sd,SP_BASEEXP);
+ clif->updatestatus(sd, SP_BASEEXP);
}
if (job_exp) {
- nextj = nextj?UINT_MAX:pc->thisjobexp(sd);
- if(sd->status.job_exp > nextj - job_exp)
+ nextj = nextj ? UINT64_MAX : pc->thisjobexp(sd);
+ if (sd->status.job_exp > nextj - job_exp)
sd->status.job_exp = nextj;
else
sd->status.job_exp += job_exp;
pc->checkjoblevelup(sd);
- clif->updatestatus(sd,SP_JOBEXP);
+ clif->updatestatus(sd, SP_JOBEXP);
}
#if PACKETVER >= 20091027
@@ -6910,7 +7131,8 @@ bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in
if(sd->state.showexp) {
char output[256];
sprintf(output,
- "Experience Gained Base:%u (%.2f%%) Job:%u (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100);
+ "Experience Gained Base:%"PRIu64" (%.2f%%) Job:%"PRIu64" (%.2f%%)",
+ base_exp, nextbp * (float)100, job_exp, nextjp * (float)100);
clif_disp_onlyself(sd, output);
}
@@ -6920,14 +7142,18 @@ bool pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in
/*==========================================
* Returns max level for this character.
*------------------------------------------*/
-int pc_maxbaselv(const struct map_session_data *sd)
+static int pc_maxbaselv(const struct map_session_data *sd)
{
- return pc->max_level[pc->class2idx(sd->status.class)][0];
+ nullpo_ret(sd);
+
+ return pc->dbs->class_exp_table[pc->class2idx(sd->status.class)][CLASS_EXP_TABLE_BASE]->max_level;
}
-int pc_maxjoblv(const struct map_session_data *sd)
+static int pc_maxjoblv(const struct map_session_data *sd)
{
- return pc->max_level[pc->class2idx(sd->status.class)][1];
+ nullpo_ret(sd);
+
+ return pc->dbs->class_exp_table[pc->class2idx(sd->status.class)][CLASS_EXP_TABLE_JOB]->max_level;
}
/*==========================================
@@ -6935,23 +7161,37 @@ int pc_maxjoblv(const struct map_session_data *sd)
*------------------------------------------*/
//Base exp needed for next level.
-unsigned int pc_nextbaseexp(const struct map_session_data *sd)
+static uint64 pc_nextbaseexp(const struct map_session_data *sd)
{
+ const struct class_exp_group *exp_group = NULL;
+
nullpo_ret(sd);
if (sd->status.base_level >= pc->maxbaselv(sd) || sd->status.base_level <= 0)
return 0;
- return pc->exp_table[pc->class2idx(sd->status.class)][0][sd->status.base_level-1];
+ exp_group = pc->dbs->class_exp_table[pc->class2idx(sd->status.class)][CLASS_EXP_TABLE_BASE];
+
+ nullpo_ret(exp_group);
+
+ return VECTOR_INDEX(exp_group->exp, sd->status.base_level >= exp_group->max_level ? 0 : sd->status.base_level - 1);
}
//Base exp needed for this level.
-unsigned int pc_thisbaseexp(const struct map_session_data *sd)
+static uint64 pc_thisbaseexp(const struct map_session_data *sd)
{
+ const struct class_exp_group *exp_group = NULL;
+
+ nullpo_ret(sd);
+
if (sd->status.base_level > pc->maxbaselv(sd) || sd->status.base_level <= 1)
return 0;
- return pc->exp_table[pc->class2idx(sd->status.class)][0][sd->status.base_level-2];
+ exp_group = pc->dbs->class_exp_table[pc->class2idx(sd->status.class)][CLASS_EXP_TABLE_BASE];
+
+ nullpo_ret(exp_group);
+
+ return VECTOR_INDEX(exp_group->exp, sd->status.base_level - 2);
}
/*==========================================
@@ -6962,25 +7202,39 @@ unsigned int pc_thisbaseexp(const struct map_session_data *sd)
*------------------------------------------*/
//Job exp needed for next level.
-unsigned int pc_nextjobexp(const struct map_session_data *sd)
+static uint64 pc_nextjobexp(const struct map_session_data *sd)
{
+ const struct class_exp_group *exp_group = NULL;
+
nullpo_ret(sd);
if (sd->status.job_level >= pc->maxjoblv(sd) || sd->status.job_level <= 0)
return 0;
- return pc->exp_table[pc->class2idx(sd->status.class)][1][sd->status.job_level-1];
+
+ exp_group = pc->dbs->class_exp_table[pc->class2idx(sd->status.class)][CLASS_EXP_TABLE_JOB];
+
+ nullpo_ret(exp_group);
+
+ return VECTOR_INDEX(exp_group->exp, sd->status.job_level >= exp_group->max_level ? 0 : sd->status.job_level - 1);
}
//Job exp needed for this level.
-unsigned int pc_thisjobexp(const struct map_session_data *sd)
+static uint64 pc_thisjobexp(const struct map_session_data *sd)
{
+ const struct class_exp_group *exp_group = NULL;
+
+ nullpo_ret(sd);
+
if (sd->status.job_level > pc->maxjoblv(sd) || sd->status.job_level <= 1)
return 0;
- return pc->exp_table[pc->class2idx(sd->status.class)][1][sd->status.job_level-2];
+
+ exp_group = pc->dbs->class_exp_table[pc->class2idx(sd->status.class)][CLASS_EXP_TABLE_JOB];
+
+ return VECTOR_INDEX(exp_group->exp, sd->status.job_level - 2);
}
/// Returns the value of the specified stat.
-int pc_getstat(struct map_session_data* sd, int type)
+static int pc_getstat(struct map_session_data *sd, int type)
{
nullpo_retr(-1, sd);
@@ -6998,7 +7252,7 @@ int pc_getstat(struct map_session_data* sd, int type)
/// Sets the specified stat to the specified value.
/// Returns the new value.
-int pc_setstat(struct map_session_data* sd, int type, int val)
+static int pc_setstat(struct map_session_data *sd, int type, int val)
{
nullpo_retr(-1, sd);
@@ -7013,11 +7267,13 @@ int pc_setstat(struct map_session_data* sd, int type, int val)
return -1;
}
+ achievement->validate_stats(sd, type, val); // Achievements [Smokexyz/Hercules]
+
return val;
}
// Calculates the number of status points PC gets when leveling up (from level to level+1)
-int pc_gets_status_point(int level)
+static int pc_gets_status_point(int level)
{
if (battle_config.use_statpoint_table) //Use values from "db/statpoint.txt"
return (pc->statp[level+1] - pc->statp[level]);
@@ -7028,7 +7284,7 @@ int pc_gets_status_point(int level)
/// Returns the number of stat points needed to change the specified stat by val.
/// If val is negative, returns the number of stat points that would be needed to
/// raise the specified stat from (current value - val) to current value.
-int pc_need_status_point(struct map_session_data* sd, int type, int val)
+static int pc_need_status_point(struct map_session_data *sd, int type, int val)
{
int low, high, sp = 0;
@@ -7063,7 +7319,8 @@ int pc_need_status_point(struct map_session_data* sd, int type, int val)
* @param type Stat to verify.
* @return Maximum value the stat could grow by.
*/
-int pc_maxparameterincrease(struct map_session_data* sd, int type) {
+static int pc_maxparameterincrease(struct map_session_data *sd, int type)
+{
int base, final, status_points = sd->status.status_point;
base = final = pc->getstat(sd, type);
@@ -7093,7 +7350,8 @@ int pc_maxparameterincrease(struct map_session_data* sd, int type) {
* @retval true if the stat was increased by any amount.
* @retval false if there were no changes.
*/
-bool pc_statusup(struct map_session_data* sd, int type, int increase) {
+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);
@@ -7152,7 +7410,7 @@ bool pc_statusup(struct map_session_data* sd, int type, int increase) {
* @return the stat increase amount.
* @retval 0 if no changes were made.
*/
-int pc_statusup2(struct map_session_data* sd, int type, int val)
+static int pc_statusup2(struct map_session_data *sd, int type, int val)
{
int max, need;
nullpo_ret(sd);
@@ -7187,8 +7445,9 @@ int pc_statusup2(struct map_session_data* sd, int type, int val)
* Update skill_lv for player sd
* Skill point allocation
*------------------------------------------*/
-int pc_skillup(struct map_session_data *sd,uint16 skill_id) {
- uint16 index = 0;
+static int pc_skillup(struct map_session_data *sd, uint16 skill_id)
+{
+ int index = 0;
nullpo_ret(sd);
if( skill_id >= GD_SKILLBASE && skill_id < GD_SKILLBASE+MAX_GUILDSKILL ) {
@@ -7225,13 +7484,18 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id) {
clif->updatestatus(sd,SP_CARTINFO);
if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown
clif->skillinfoblock(sd);
- } else if( battle_config.skillup_limit ){
- if (sd->sktree.second != 0)
- clif->msgtable_num(sd, MSG_SKILL_POINTS_LEFT_JOB1, sd->sktree.second);
- else if (sd->sktree.third != 0)
- clif->msgtable_num(sd, MSG_SKILL_POINTS_LEFT_JOB2, sd->sktree.third);
- else if (pc->calc_skillpoint(sd) < 9) /* TODO: official response? */
+ } else if (battle_config.skillup_limit) {
+ if (sd->sktree.second != 0) {
+#if PACKETVER >= 20090805
+ clif->msgtable_num(sd, MSG_UPGRADESKILLERROR_MORE_FIRSTJOBSKILL, sd->sktree.second);
+#endif
+ } else if (sd->sktree.third != 0) {
+#if PACKETVER >= 20091013
+ clif->msgtable_num(sd, MSG_UPGRADESKILLERROR_MORE_SECONDJOBSKILL, sd->sktree.third);
+#endif
+ } else if (pc->calc_skillpoint(sd) < 9) { /* TODO: official response? */
clif->messagecolor_self(sd->fd, COLOR_RED, "You need the basic skills");
+ }
}
return 0;
}
@@ -7239,13 +7503,13 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id) {
/*==========================================
* /allskill
*------------------------------------------*/
-int pc_allskillup(struct map_session_data *sd)
+static int pc_allskillup(struct map_session_data *sd)
{
int i;
nullpo_ret(sd);
- for(i=0;i<MAX_SKILL;i++){
+ for (i = 0; i < MAX_SKILL_DB; i++) {
if (sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED) {
sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0;
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
@@ -7256,7 +7520,7 @@ int pc_allskillup(struct map_session_data *sd)
if (pc_has_permission(sd, PC_PERM_ALL_SKILL)) { //Get ALL skills except npc/guild ones. [Skotlex]
//and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage]
- for(i=0;i<MAX_SKILL;i++){
+ for (i = 0; i < MAX_SKILL_DB; i++) {
switch( skill->dbs->db[i].nameid ) {
case SG_DEVIL:
case MO_TRIPLEATTACK:
@@ -7294,7 +7558,7 @@ int pc_allskillup(struct map_session_data *sd)
/*==========================================
* /resetlvl
*------------------------------------------*/
-int pc_resetlvl(struct map_session_data* sd,int type)
+static int pc_resetlvl(struct map_session_data *sd, int type)
{
int i;
@@ -7382,7 +7646,7 @@ int pc_resetlvl(struct map_session_data* sd,int type)
/*==========================================
* /resetstate
*------------------------------------------*/
-int pc_resetstate(struct map_session_data* sd)
+static int pc_resetstate(struct map_session_data *sd)
{
nullpo_ret(sd);
@@ -7436,7 +7700,7 @@ int pc_resetstate(struct map_session_data* sd)
if( sd->mission_mobid ) { //bugreport:2200
sd->mission_mobid = 0;
sd->mission_count = 0;
- pc_setglobalreg(sd,script->add_str("TK_MISSION_ID"), 0);
+ pc_setglobalreg(sd,script->add_variable("TK_MISSION_ID"), 0);
}
status_calc_pc(sd,SCO_NONE);
@@ -7448,7 +7712,7 @@ int pc_resetstate(struct map_session_data* sd)
* /resetskill
* @param flag: @see enum pc_resetskill_flag
*------------------------------------------*/
-int pc_resetskill(struct map_session_data* sd, int flag)
+static int pc_resetskill(struct map_session_data *sd, int flag)
{
int i, inf2, skill_point=0;
nullpo_ret(sd);
@@ -7496,10 +7760,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
status_change_end(&sd->bl, SC_SPRITEMABLE, INVALID_TIMER);
}
- for( i = 1; i < MAX_SKILL; i++ ) {
- // FIXME: We're looping on i = [1..MAX_SKILL-1] (which makes sense as index for sd->status.skill[]) but then we're using the
- // same i to access skill->dbs->db[], and especially to check skill_ischangesex(). This is wrong.
- uint16 skill_id = 0;
+ for (i = 1; i < MAX_SKILL_DB; i++) {
int lv = sd->status.skill[i].lv;
if (lv < 1) continue;
@@ -7508,19 +7769,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
if( inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL) ) //Avoid reseting wedding/linker skills.
continue;
- skill_id = skill->dbs->db[i].nameid;
-
- // Don't reset trick dead if not a novice/baby
- if (skill_id == NV_TRICKDEAD && (sd->job & MAPID_UPPERMASK) != MAPID_NOVICE) {
- sd->status.skill[i].lv = 0;
- sd->status.skill[i].flag = 0;
- continue;
- }
-
- // do not reset basic skill
- if (skill_id == NV_BASIC && (sd->job & MAPID_UPPERMASK) != MAPID_NOVICE)
- continue;
- if (skill_id == SU_BASIC_SKILL && (sd->job & MAPID_BASEMASK) != MAPID_SUMMONER)
+ if (pc->resetskill_job(sd, i))
continue;
if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED )
@@ -7575,10 +7824,34 @@ int pc_resetskill(struct map_session_data* sd, int flag)
return skill_point;
}
+static bool pc_resetskill_job(struct map_session_data *sd, int index)
+{
+ uint16 skill_id;
+
+ nullpo_retr(false, sd);
+ Assert_retr(false, index >= 0 && index < MAX_SKILL_DB);
+
+ skill_id = skill->dbs->db[index].nameid;
+
+ // Don't reset trick dead if not a novice/baby
+ if (skill_id == NV_TRICKDEAD && (sd->job & MAPID_UPPERMASK) != MAPID_NOVICE) {
+ sd->status.skill[index].lv = 0;
+ sd->status.skill[index].flag = 0;
+ return true;
+ }
+
+ // do not reset basic skill
+ if (skill_id == NV_BASIC && (sd->job & MAPID_UPPERMASK) != MAPID_NOVICE)
+ return true;
+ if (skill_id == SU_BASIC_SKILL && (sd->job & MAPID_BASEMASK) != MAPID_SUMMONER)
+ return true;
+ return false;
+}
+
/*==========================================
* /resetfeel [Komurka]
*------------------------------------------*/
-int pc_resetfeel(struct map_session_data* sd)
+static int pc_resetfeel(struct map_session_data *sd)
{
int i;
nullpo_ret(sd);
@@ -7587,25 +7860,25 @@ int pc_resetfeel(struct map_session_data* sd)
{
sd->feel_map[i].m = -1;
sd->feel_map[i].index = 0;
- pc_setglobalreg(sd,script->add_str(pc->sg_info[i].feel_var),0);
+ pc_setglobalreg(sd,script->add_variable(pc->sg_info[i].feel_var),0);
}
return 0;
}
-int pc_resethate(struct map_session_data* sd)
+static int pc_resethate(struct map_session_data *sd)
{
int i;
nullpo_ret(sd);
for (i = 0; i < MAX_PC_FEELHATE; i++) {
sd->hate_mob[i] = -1;
- pc_setglobalreg(sd,script->add_str(pc->sg_info[i].hate_var),0);
+ pc_setglobalreg(sd,script->add_variable(pc->sg_info[i].hate_var),0);
}
return 0;
}
-int pc_skillatk_bonus(struct map_session_data *sd, uint16 skill_id)
+static int pc_skillatk_bonus(struct map_session_data *sd, uint16 skill_id)
{
int i, bonus = 0;
nullpo_ret(sd);
@@ -7619,28 +7892,49 @@ int pc_skillatk_bonus(struct map_session_data *sd, uint16 skill_id)
return bonus;
}
-int pc_skillheal_bonus(struct map_session_data *sd, uint16 skill_id) {
+static int pc_skillheal_bonus(struct map_session_data *sd, uint16 skill_id)
+{
int i, bonus = sd->bonus.add_heal_rate;
- if( bonus ) {
- switch( skill_id ) {
- case AL_HEAL: if( !(battle_config.skill_add_heal_rate&1) ) bonus = 0; break;
- case PR_SANCTUARY: if( !(battle_config.skill_add_heal_rate&2) ) bonus = 0; break;
- case AM_POTIONPITCHER: if( !(battle_config.skill_add_heal_rate&4) ) bonus = 0; break;
- case CR_SLIMPITCHER: if( !(battle_config.skill_add_heal_rate&8) ) bonus = 0; break;
- case BA_APPLEIDUN: if( !(battle_config.skill_add_heal_rate&16)) bonus = 0; break;
+ if (bonus) {
+ switch (skill_id) {
+ case AL_HEAL:
+ if ((battle_config.skill_add_heal_rate & 1) == 0)
+ bonus = 0;
+ break;
+ case PR_SANCTUARY:
+ if ((battle_config.skill_add_heal_rate & 2) == 0)
+ bonus = 0;
+ break;
+ case AM_POTIONPITCHER:
+ if ((battle_config.skill_add_heal_rate & 4) == 0)
+ bonus = 0;
+ break;
+ case CR_SLIMPITCHER:
+ if ((battle_config.skill_add_heal_rate & 8) == 0)
+ bonus = 0;
+ break;
+ case BA_APPLEIDUN:
+ if ((battle_config.skill_add_heal_rate & 16) == 0)
+ bonus = 0;
+ break;
+ case AB_HIGHNESSHEAL:
+ if ((battle_config.skill_add_heal_rate & 32) == 0)
+ bonus = 0;
+ break;
}
}
ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == skill_id);
- if( i < ARRAYLENGTH(sd->skillheal) )
+ if (i < ARRAYLENGTH(sd->skillheal))
bonus += sd->skillheal[i].val;
return bonus;
}
-int pc_skillheal2_bonus(struct map_session_data *sd, uint16 skill_id) {
+static int pc_skillheal2_bonus(struct map_session_data *sd, uint16 skill_id)
+{
int i, bonus = sd->bonus.add_heal2_rate;
ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == skill_id);
@@ -7651,7 +7945,7 @@ int pc_skillheal2_bonus(struct map_session_data *sd, uint16 skill_id) {
return bonus;
}
-void pc_respawn(struct map_session_data* sd, clr_type clrtype)
+static void pc_respawn(struct map_session_data *sd, enum clr_type clrtype)
{
if( !pc_isdead(sd) )
return; // not applicable
@@ -7664,7 +7958,8 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype)
clif->resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet.
}
-int pc_respawn_timer(int tid, int64 tick, int id, intptr_t data) {
+static int pc_respawn_timer(int tid, int64 tick, int id, intptr_t data)
+{
struct map_session_data *sd = map->id2sd(id);
if( sd != NULL )
{
@@ -7678,7 +7973,7 @@ int pc_respawn_timer(int tid, int64 tick, int id, intptr_t data) {
/*==========================================
* Invoked when a player has received damage
*------------------------------------------*/
-void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int hp, unsigned int sp)
+static void pc_damage(struct map_session_data *sd, struct block_list *src, unsigned int hp, unsigned int sp)
{
if (sp) clif->updatestatus(sd,SP_SP);
if (hp) clif->updatestatus(sd,SP_HP);
@@ -7703,13 +7998,23 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h
if( sd->status.ele_id > 0 )
elemental->set_target(sd,src);
- sd->canlog_tick = timer->gettick();
+ if (battle_config.prevent_logout_trigger & PLT_DAMAGE)
+ sd->canlog_tick = timer->gettick();
+
+ // Achievements [Smokexyz/Hercules]
+ if (src != NULL) {
+ if (src->type == BL_PC)
+ achievement->validate_pc_damage(BL_UCAST(BL_PC, src), sd, hp);
+ else if (src->type == BL_MOB)
+ achievement->validate_mob_damage(sd, hp, true);
+ }
}
/*==========================================
* Invoked when a player has negative current hp
*------------------------------------------*/
-int pc_dead(struct map_session_data *sd,struct block_list *src) {
+static int pc_dead(struct map_session_data *sd, struct block_list *src)
+{
int i=0,j=0;
int64 tick = timer->gettick();
@@ -7758,7 +8063,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
if (sd->npc_id && sd->st && sd->st->state != RUN)
npc->event_dequeue(sd);
- pc_setglobalreg(sd,script->add_str("PC_DIE_COUNTER"),sd->die_counter+1);
+ pc_setglobalreg(sd,script->add_variable("PC_DIE_COUNTER"),sd->die_counter+1);
pc->setparam(sd, SP_KILLERRID, src?src->id:0);
if( sd->bg_id ) {/* TODO: purge when bgqueue is deemed ok */
@@ -7798,6 +8103,9 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
}
pc_setdead(sd);
+
+ clif->party_dead_notification(sd);
+
//Reset menu skills/item skills
if (sd->skillitem)
sd->skillitem = sd->skillitemlv = 0;
@@ -7853,6 +8161,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
pc->setparam(ssd, SP_KILLEDRID, sd->bl.id);
npc->script_event(ssd, NPCE_KILLPC);
+ achievement->validate_pc_kill(ssd, sd); // Achievements [Smokexyz/Hercules]
+
if (battle_config.pk_mode&2) {
ssd->status.manner -= 5;
if(ssd->status.manner < 0)
@@ -7894,14 +8204,14 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
item_tmp.card[1]=0;
item_tmp.card[2]=GetWord(sd->status.char_id,0); // CharId
item_tmp.card[3]=GetWord(sd->status.char_id,1);
- map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
+ map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
}
// activate Steel body if a super novice dies at 99+% exp [celest]
if ((sd->job & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && !sd->state.snovice_dead_flag) {
- unsigned int next = pc->nextbaseexp(sd);
+ uint64 next = pc->nextbaseexp(sd);
if( next == 0 ) next = pc->thisbaseexp(sd);
- if( get_percentage(sd->status.base_exp,next) >= 99 ) {
+ if (get_percentage64(sd->status.base_exp, next) >= 99) {
sd->state.snovice_dead_flag = 1;
pc->setstand(sd);
status_percent_heal(&sd->bl, 100, 100);
@@ -7916,8 +8226,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
}
// changed penalty options, added death by player if pk_mode [Valaris]
- if( battle_config.death_penalty_type
- && (sd->job & MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty
+ if (battle_config.death_penalty_type
+ && pc->isDeathPenaltyJob(sd->job)
&& !map->list[sd->bl.m].flag.noexppenalty && !map_flag_gvg2(sd->bl.m)
&& !sd->sc.data[SC_BABY] && !sd->sc.data[SC_CASH_DEATHPENALTY]
) {
@@ -7980,15 +8290,15 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
if(id == 0)
continue;
if(id == -1){
- int eq_num=0,eq_n[MAX_INVENTORY],k;
+ int eq_num = 0, eq_n[MAX_INVENTORY], k;
memset(eq_n,0,sizeof(eq_n));
- for(i=0;i<MAX_INVENTORY;i++){
+ for(i = 0; i < sd->status.inventorySize; i++) {
if( (type == 1 && !sd->status.inventory[i].equip)
|| (type == 2 && sd->status.inventory[i].equip)
|| type == 3)
{
- ARR_FIND( 0, MAX_INVENTORY, k, eq_n[k] <= 0 );
- if( k < MAX_INVENTORY )
+ ARR_FIND(0, sd->status.inventorySize, k, eq_n[k] <= 0);
+ if (k < sd->status.inventorySize)
eq_n[k] = i;
eq_num++;
@@ -8004,7 +8314,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
}
}
else if(id > 0){
- for(i=0;i<MAX_INVENTORY;i++){
+ for( i = 0; i < sd->status.inventorySize; i++) {
if(sd->status.inventory[i].nameid == id
&& rnd()%10000 < per
&& ((type == 1 && !sd->status.inventory[i].equip)
@@ -8065,7 +8375,13 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
return 1;
}
-void pc_revive(struct map_session_data *sd,unsigned int hp, unsigned int sp) {
+static bool pc_isDeathPenaltyJob(uint16 job)
+{
+ return (job & MAPID_UPPERMASK) != MAPID_NOVICE; // only novices will receive no penalty
+}
+
+static void pc_revive(struct map_session_data *sd, unsigned int hp, unsigned int sp)
+{
nullpo_retv(sd);
if(hp) clif->updatestatus(sd,SP_HP);
if(sp) clif->updatestatus(sd,SP_SP);
@@ -8086,9 +8402,9 @@ void pc_revive(struct map_session_data *sd,unsigned int hp, unsigned int sp) {
/*==========================================
* script reading pc status registry
*------------------------------------------*/
-int pc_readparam(const struct map_session_data *sd, int type)
+static int64 pc_readparam(const struct map_session_data *sd, int type)
{
- int val = 0;
+ int64 val = 0;
nullpo_ret(sd);
@@ -8096,6 +8412,7 @@ int pc_readparam(const struct map_session_data *sd, int type)
case SP_SKILLPOINT: val = sd->status.skill_point; break;
case SP_STATUSPOINT: val = sd->status.status_point; break;
case SP_ZENY: val = sd->status.zeny; break;
+ case SP_BANKVAULT: val = sd->status.bank_vault; break;
case SP_BASELEVEL: val = sd->status.base_level; break;
case SP_JOBLEVEL: val = sd->status.job_level; break;
case SP_CLASS: val = sd->status.class; break;
@@ -8238,8 +8555,9 @@ int pc_readparam(const struct map_session_data *sd, int type)
/*==========================================
* script set pc status registry
*------------------------------------------*/
-int pc_setparam(struct map_session_data *sd,int type,int val)
+static int pc_setparam(struct map_session_data *sd, int type, int64 val)
{
+ int delta;
nullpo_ret(sd);
switch(type){
@@ -8252,7 +8570,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
stat += pc->gets_status_point(sd->status.base_level + i);
sd->status.status_point += stat;
}
- sd->status.base_level = val;
+ sd->status.base_level = (int32)val;
sd->status.base_exp = 0;
// clif->updatestatus(sd, SP_BASELEVEL); // Gets updated at the bottom
clif->updatestatus(sd, SP_NEXTBASEEXP);
@@ -8268,10 +8586,10 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
if (val >= sd->status.job_level) {
if (val > pc->maxjoblv(sd))
val = pc->maxjoblv(sd);
- sd->status.skill_point += val - sd->status.job_level;
+ sd->status.skill_point += (int)val - sd->status.job_level;
clif->updatestatus(sd, SP_SKILLPOINT);
}
- sd->status.job_level = val;
+ sd->status.job_level = (int32)val;
sd->status.job_exp = 0;
// clif->updatestatus(sd, SP_JOBLEVEL); // Gets updated at the bottom
clif->updatestatus(sd, SP_NEXTJOBEXP);
@@ -8279,17 +8597,30 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
status_calc_pc(sd, SCO_FORCE);
break;
case SP_SKILLPOINT:
- sd->status.skill_point = val;
+ sd->status.skill_point = (int32)val;
break;
case SP_STATUSPOINT:
- sd->status.status_point = val;
+ sd->status.status_point = (int32)val;
break;
case SP_ZENY:
if( val < 0 )
return 0;// can't set negative zeny
- logs->zeny(sd, LOG_TYPE_SCRIPT, sd, -(sd->status.zeny - cap_value(val, 0, MAX_ZENY)));
- sd->status.zeny = cap_value(val, 0, MAX_ZENY);
+ logs->zeny(sd, LOG_TYPE_SCRIPT, sd, -(sd->status.zeny - cap_value((int32)val, 0, MAX_ZENY)));
+ sd->status.zeny = cap_value((int32)val, 0, MAX_ZENY);
break;
+ case SP_BANKVAULT:
+ val = cap_value(val, 0, MAX_BANK_ZENY);
+ delta = ((int32)val - sd->status.bank_vault);
+ sd->status.bank_vault = (int32)val;
+ if (map->save_settings & 256) {
+ chrif->save(sd, 0); // send to char server
+ }
+ if (delta > 0) {
+ clif->bank_deposit(sd, BDA_SUCCESS);
+ } else if (delta < 0) {
+ clif->bank_withdraw(sd, BWA_SUCCESS);
+ }
+ return 1; // the vault uses a different packet
case SP_BASEEXP:
if(pc->nextbaseexp(sd) > 0) {
sd->status.base_exp = val;
@@ -8306,16 +8637,16 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
sd->status.sex = val ? SEX_MALE : SEX_FEMALE;
break;
case SP_WEIGHT:
- sd->weight = val;
+ sd->weight = (int32)val;
break;
case SP_MAXWEIGHT:
- sd->max_weight = val;
+ sd->max_weight = (int32)val;
break;
case SP_HP:
- sd->battle_status.hp = cap_value(val, 1, (int)sd->battle_status.max_hp);
+ sd->battle_status.hp = cap_value((int32)val, 1, (int)sd->battle_status.max_hp);
break;
case SP_MAXHP:
- sd->battle_status.max_hp = cap_value(val, 1, battle_config.max_hp);
+ sd->battle_status.max_hp = cap_value((int32)val, 1, battle_config.max_hp);
if( sd->battle_status.max_hp < sd->battle_status.hp )
{
@@ -8324,10 +8655,10 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
}
break;
case SP_SP:
- sd->battle_status.sp = cap_value(val, 0, (int)sd->battle_status.max_sp);
+ sd->battle_status.sp = cap_value((int32)val, 0, (int)sd->battle_status.max_sp);
break;
case SP_MAXSP:
- sd->battle_status.max_sp = cap_value(val, 1, battle_config.max_sp);
+ sd->battle_status.max_sp = cap_value((int32)val, 1, battle_config.max_sp);
if( sd->battle_status.max_sp < sd->battle_status.sp )
{
@@ -8336,28 +8667,28 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
}
break;
case SP_STR:
- sd->status.str = cap_value(val, 1, pc_maxparameter(sd));
+ sd->status.str = cap_value((int)val, 1, pc_maxparameter(sd));
break;
case SP_AGI:
- sd->status.agi = cap_value(val, 1, pc_maxparameter(sd));
+ sd->status.agi = cap_value((int)val, 1, pc_maxparameter(sd));
break;
case SP_VIT:
- sd->status.vit = cap_value(val, 1, pc_maxparameter(sd));
+ sd->status.vit = cap_value((int)val, 1, pc_maxparameter(sd));
break;
case SP_INT:
- sd->status.int_ = cap_value(val, 1, pc_maxparameter(sd));
+ sd->status.int_ = cap_value((int)val, 1, pc_maxparameter(sd));
break;
case SP_DEX:
- sd->status.dex = cap_value(val, 1, pc_maxparameter(sd));
+ sd->status.dex = cap_value((int)val, 1, pc_maxparameter(sd));
break;
case SP_LUK:
- sd->status.luk = cap_value(val, 1, pc_maxparameter(sd));
+ sd->status.luk = cap_value((int)val, 1, pc_maxparameter(sd));
break;
case SP_KARMA:
- sd->status.karma = val;
+ sd->status.karma = (int)val;
break;
case SP_MANNER:
- sd->status.manner = val;
+ sd->status.manner = (int)val;
if( val < 0 )
sc_start(NULL, &sd->bl, SC_NOCHAT, 100, 0, 0);
else {
@@ -8366,28 +8697,28 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
}
return 1; // status_change_start/status_change_end already sends packets warning the client
case SP_FAME:
- sd->status.fame = val;
+ sd->status.fame = (int32)val;
break;
case SP_KILLERRID:
- sd->killerrid = val;
+ sd->killerrid = (int32)val;
return 1;
case SP_KILLEDRID:
- sd->killedrid = val;
+ sd->killedrid = (int32)val;
return 1;
case SP_SLOTCHANGE:
- sd->status.slotchange = val;
+ sd->status.slotchange = (int32)val;
return 1;
case SP_CHARRENAME:
- sd->status.rename = val;
+ sd->status.rename = (int32)val;
return 1;
case SP_MOD_EXP:
- sd->status.mod_exp = val;
+ sd->status.mod_exp = (int32)val;
return 1;
case SP_MOD_DROP:
- sd->status.mod_drop = val;
+ sd->status.mod_drop = (int32)val;
return 1;
case SP_MOD_DEATH:
- sd->status.mod_death = val;
+ sd->status.mod_death = (int32)val;
return 1;
default:
ShowError("pc_setparam: Attempted to set unknown parameter '%d'.\n", type);
@@ -8401,7 +8732,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
/*==========================================
* HP/SP Healing. If flag is passed, the heal type is through clif->heal, otherwise update status.
*------------------------------------------*/
-void pc_heal(struct map_session_data *sd,unsigned int hp,unsigned int sp, int type)
+static void pc_heal(struct map_session_data *sd, unsigned int hp, unsigned int sp, int type)
{
nullpo_retv(sd);
if (type) {
@@ -8423,7 +8754,7 @@ void pc_heal(struct map_session_data *sd,unsigned int hp,unsigned int sp, int ty
* Heal player hp and/or sp linearly.
* Calculate bonus by status.
*------------------------------------------*/
-int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
+static int pc_itemheal(struct map_session_data *sd, int itemid, int hp, int sp)
{
int bonus, tmp;
@@ -8499,14 +8830,14 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
}
}
- return status->heal(&sd->bl, hp, sp, 1);
+ return status->heal(&sd->bl, hp, sp, STATUS_HEAL_FORCED);
}
/*==========================================
* HP/SP Recovery
* Heal player hp nad/or sp by rate
*------------------------------------------*/
-int pc_percentheal(struct map_session_data *sd,int hp,int sp)
+static int pc_percentheal(struct map_session_data *sd, int hp, int sp)
{
nullpo_ret(sd);
@@ -8541,7 +8872,7 @@ int pc_percentheal(struct map_session_data *sd,int hp,int sp)
return 0;
}
-int jobchange_killclone(struct block_list *bl, va_list ap)
+static int jobchange_killclone(struct block_list *bl, va_list ap)
{
struct mob_data *md = NULL;
int flag = va_arg(ap, int);
@@ -8559,7 +8890,7 @@ int jobchange_killclone(struct block_list *bl, va_list ap)
* Called when player changes job
* Rewrote to make it tidider [Celest]
*------------------------------------------*/
-int pc_jobchange(struct map_session_data *sd, int class, int upper)
+static int pc_jobchange(struct map_session_data *sd, int class, int upper)
{
int i, fame_flag=0;
int job, idx = 0;
@@ -8593,11 +8924,11 @@ int pc_jobchange(struct map_session_data *sd, int class, int upper)
if ((job & JOBL_2) != 0 && (sd->job & JOBL_2) == 0 && (job & MAPID_UPPERMASK) != MAPID_SUPER_NOVICE) {
// changing from 1st to 2nd job
sd->change_level_2nd = sd->status.job_level;
- pc_setglobalreg(sd, script->add_str("jobchange_level"), sd->change_level_2nd);
+ pc_setglobalreg(sd, script->add_variable("jobchange_level"), sd->change_level_2nd);
} else if((job & JOBL_THIRD) != 0 && (sd->job & JOBL_THIRD) == 0) {
// changing from 2nd to 3rd job
sd->change_level_3rd = sd->status.job_level;
- pc_setglobalreg(sd, script->add_str("jobchange_level_3rd"), sd->change_level_3rd);
+ pc_setglobalreg(sd, script->add_variable("jobchange_level_3rd"), sd->change_level_3rd);
}
if(sd->cloneskill_id) {
@@ -8609,8 +8940,8 @@ int pc_jobchange(struct map_session_data *sd, int class, int upper)
clif->deleteskill(sd,sd->cloneskill_id);
}
sd->cloneskill_id = 0;
- pc_setglobalreg(sd, script->add_str("CLONE_SKILL"), 0);
- pc_setglobalreg(sd, script->add_str("CLONE_SKILL_LV"), 0);
+ pc_setglobalreg(sd, script->add_variable("CLONE_SKILL"), 0);
+ pc_setglobalreg(sd, script->add_variable("CLONE_SKILL_LV"), 0);
}
if(sd->reproduceskill_id) {
@@ -8622,8 +8953,8 @@ int pc_jobchange(struct map_session_data *sd, int class, int upper)
clif->deleteskill(sd,sd->reproduceskill_id);
}
sd->reproduceskill_id = 0;
- pc_setglobalreg(sd, script->add_str("REPRODUCE_SKILL"),0);
- pc_setglobalreg(sd, script->add_str("REPRODUCE_SKILL_LV"),0);
+ pc_setglobalreg(sd, script->add_variable("REPRODUCE_SKILL"),0);
+ pc_setglobalreg(sd, script->add_variable("REPRODUCE_SKILL_LV"),0);
}
if ((job & MAPID_UPPERMASK) != (sd->job & MAPID_UPPERMASK)) { //Things to remove when changing class tree.
@@ -8731,6 +9062,7 @@ int pc_jobchange(struct map_session_data *sd, int class, int upper)
status_calc_pc(sd,SCO_FORCE);
pc->checkallowskill(sd);
pc->equiplookall(sd);
+ pc->update_job_and_level(sd);
//if you were previously famous, not anymore.
if (fame_flag != 0) {
@@ -8747,6 +9079,9 @@ int pc_jobchange(struct map_session_data *sd, int class, int upper)
break;
}
}
+ quest->questinfo_refresh(sd);
+
+ achievement->validate_jobchange(sd); // Achievements [Smokexyz/Hercules]
return 0;
}
@@ -8754,16 +9089,16 @@ int pc_jobchange(struct map_session_data *sd, int class, int upper)
/*==========================================
* Tell client player sd has change equipement
*------------------------------------------*/
-int pc_equiplookall(struct map_session_data *sd)
+static int pc_equiplookall(struct map_session_data *sd)
{
nullpo_ret(sd);
clif->changelook(&sd->bl,LOOK_WEAPON,0);
clif->changelook(&sd->bl,LOOK_SHOES,0);
- clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
- clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
- clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
- clif->changelook(&sd->bl,LOOK_ROBE, sd->status.robe);
+ clif->changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.look.head_bottom);
+ clif->changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.look.head_top);
+ clif->changelook(&sd->bl, LOOK_HEAD_MID, sd->status.look.head_mid);
+ clif->changelook(&sd->bl, LOOK_ROBE, sd->status.look.robe);
return 0;
}
@@ -8771,7 +9106,7 @@ int pc_equiplookall(struct map_session_data *sd)
/*==========================================
* Tell client player sd has change look (hair,equip...)
*------------------------------------------*/
-int pc_changelook(struct map_session_data *sd,int type,int val)
+static int pc_changelook(struct map_session_data *sd, int type, int val)
{
nullpo_ret(sd);
@@ -8779,7 +9114,7 @@ int pc_changelook(struct map_session_data *sd,int type,int val)
case LOOK_BASE:
status->set_viewdata(&sd->bl, val);
clif->changelook(&sd->bl, LOOK_BASE, sd->vd.class);
- clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ clif->changelook(&sd->bl, LOOK_WEAPON, sd->status.look.weapon);
if (sd->vd.cloth_color)
clif->changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
if (sd->vd.body_style)
@@ -8798,16 +9133,16 @@ int pc_changelook(struct map_session_data *sd,int type,int val)
}
break;
case LOOK_WEAPON:
- sd->status.weapon=val;
+ sd->status.look.weapon = val;
break;
case LOOK_HEAD_BOTTOM:
- sd->status.head_bottom=val;
+ sd->status.look.head_bottom = val;
break;
case LOOK_HEAD_TOP:
- sd->status.head_top=val;
+ sd->status.look.head_top = val;
break;
case LOOK_HEAD_MID:
- sd->status.head_mid=val;
+ sd->status.look.head_mid = val;
break;
case LOOK_HAIR_COLOR: //Use the battle_config limits! [Skotlex]
val = cap_value(val, MIN_HAIR_COLOR, MAX_HAIR_COLOR);
@@ -8825,12 +9160,12 @@ int pc_changelook(struct map_session_data *sd,int type,int val)
sd->status.clothes_color=val;
break;
case LOOK_SHIELD:
- sd->status.shield=val;
+ sd->status.look.shield = val;
break;
case LOOK_SHOES:
break;
case LOOK_ROBE:
- sd->status.robe = val;
+ sd->status.look.robe = val;
break;
case LOOK_BODY2:
val = cap_value(val, MIN_BODY_STYLE, MAX_BODY_STYLE);
@@ -8844,7 +9179,7 @@ int pc_changelook(struct map_session_data *sd,int type,int val)
/*==========================================
* Give an option (type) to player (sd) and display it to client
*------------------------------------------*/
-int pc_setoption(struct map_session_data *sd,int type)
+static int pc_setoption(struct map_session_data *sd, int type)
{
int p_type, new_look=0;
nullpo_ret(sd);
@@ -8866,7 +9201,7 @@ int pc_setoption(struct map_session_data *sd,int type)
#ifndef NEW_CARTS
if( type&OPTION_CART && !( p_type&OPTION_CART ) ) { //Cart On
- clif->cartlist(sd);
+ clif->cartList(sd);
clif->updatestatus(sd, SP_CARTINFO);
if(pc->checkskill(sd, MC_PUSHCART) < 10)
status_calc_pc(sd,SCO_NONE); //Apply speed penalty.
@@ -8942,7 +9277,8 @@ int pc_setoption(struct map_session_data *sd,int type)
/*==========================================
* Give player a cart
*------------------------------------------*/
-int pc_setcart(struct map_session_data *sd,int type) {
+static int pc_setcart(struct map_session_data *sd, int type)
+{
#ifndef NEW_CARTS
int cart[6] = {OPTION_NOTHING,OPTION_CART1,OPTION_CART2,OPTION_CART3,OPTION_CART4,OPTION_CART5};
int option;
@@ -8972,7 +9308,7 @@ int pc_setcart(struct map_session_data *sd,int type) {
break;
default:/* everything else is an allowed ID so we can move on */
if( !sd->sc.data[SC_PUSH_CART] ) /* first time, so fill cart data */
- clif->cartlist(sd);
+ clif->cartList(sd);
clif->updatestatus(sd, SP_CARTINFO);
sc_start(NULL,&sd->bl, SC_PUSH_CART, 100, type, 0);
clif->sc_load(&sd->bl, sd->bl.id, AREA, SI_ON_PUSH_CART, type, 0, 0);
@@ -9005,7 +9341,7 @@ int pc_setcart(struct map_session_data *sd,int type) {
* @param sd Target player.
* @param flag New state.
**/
-void pc_setfalcon(struct map_session_data *sd, bool flag)
+static void pc_setfalcon(struct map_session_data *sd, bool flag)
{
nullpo_retv(sd);
if (flag) {
@@ -9024,7 +9360,7 @@ void pc_setfalcon(struct map_session_data *sd, bool flag)
* @param sd Target player.
* @param flag New state.
**/
-void pc_setridingpeco(struct map_session_data *sd, bool flag)
+static void pc_setridingpeco(struct map_session_data *sd, bool flag)
{
nullpo_retv(sd);
if (flag) {
@@ -9043,7 +9379,7 @@ void pc_setridingpeco(struct map_session_data *sd, bool flag)
* @param sd Target player.
* @param flag New state.
**/
-void pc_setmadogear(struct map_session_data *sd, bool flag)
+static void pc_setmadogear(struct map_session_data *sd, bool flag)
{
nullpo_retv(sd);
if (flag) {
@@ -9062,7 +9398,7 @@ void pc_setmadogear(struct map_session_data *sd, bool flag)
* @param sd Target player.
* @param type New state. This must be a valid OPTION_DRAGON* or 0.
**/
-void pc_setridingdragon(struct map_session_data *sd, unsigned int type)
+static void pc_setridingdragon(struct map_session_data *sd, unsigned int type)
{
nullpo_retv(sd);
if (type&OPTION_DRAGON) {
@@ -9095,7 +9431,7 @@ void pc_setridingdragon(struct map_session_data *sd, unsigned int type)
* @param sd Target player.
* @param flag New state.
**/
-void pc_setridingwug(struct map_session_data *sd, bool flag)
+static void pc_setridingwug(struct map_session_data *sd, bool flag)
{
nullpo_retv(sd);
if (flag) {
@@ -9114,7 +9450,8 @@ void pc_setridingwug(struct map_session_data *sd, bool flag)
* Called from unit_attack and unit_attack_timer_sub
* @retval true Can attack
**/
-bool pc_can_attack( struct map_session_data *sd, int target_id ) {
+static bool pc_can_attack(struct map_session_data *sd, int target_id)
+{
nullpo_retr(false, sd);
if( sd->sc.data[SC_BASILICA] ||
@@ -9128,7 +9465,8 @@ bool pc_can_attack( struct map_session_data *sd, int target_id ) {
(sd->sc.data[SC_SIREN] && sd->sc.data[SC_SIREN]->val2 == target_id) ||
sd->sc.data[SC_BLADESTOP] ||
sd->sc.data[SC_DEEP_SLEEP] ||
- sd->sc.data[SC_FALLENEMPIRE] )
+ sd->sc.data[SC_FALLENEMPIRE] ||
+ sd->block_action.attack)
return false;
return true;
@@ -9139,12 +9477,14 @@ bool pc_can_attack( struct map_session_data *sd, int target_id ) {
* Called from clif_parse_GlobalMessage and clif_parse_WisMessage
* @retval true Can talk
**/
-bool pc_can_talk( struct map_session_data *sd ) {
+static bool pc_can_talk(struct map_session_data *sd)
+{
nullpo_retr(false, sd);
if( sd->sc.data[SC_BERSERK] ||
(sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) ||
- pc_ismuted(&sd->sc, MANNER_NOCHAT) )
+ pc_ismuted(&sd->sc, MANNER_NOCHAT) ||
+ sd->block_action.chat)
return false;
return true;
@@ -9153,7 +9493,7 @@ bool pc_can_talk( struct map_session_data *sd ) {
/*==========================================
* Check if player can drop an item
*------------------------------------------*/
-int pc_candrop(struct map_session_data *sd, struct item *item)
+static int pc_candrop(struct map_session_data *sd, struct item *item)
{
if( item && (item->expire_time || (item->bound && !pc_can_give_bound_items(sd))) )
return 0;
@@ -9164,14 +9504,16 @@ int pc_candrop(struct map_session_data *sd, struct item *item)
/**
* For '@type' variables (temporary numeric char reg)
**/
-int pc_readreg(struct map_session_data* sd, int64 reg) {
+static int pc_readreg(struct map_session_data *sd, int64 reg)
+{
nullpo_ret(sd);
return i64db_iget(sd->regs.vars, reg);
}
/**
* For '@type' variables (temporary numeric char reg)
**/
-void pc_setreg(struct map_session_data* sd, int64 reg, int val) {
+static void pc_setreg(struct map_session_data *sd, int64 reg, int val)
+{
unsigned int index = script_getvaridx(reg);
nullpo_retv(sd);
@@ -9189,7 +9531,8 @@ void pc_setreg(struct map_session_data* sd, int64 reg, int val) {
/**
* For '@type$' variables (temporary string char reg)
**/
-char* pc_readregstr(struct map_session_data* sd, int64 reg) {
+static char *pc_readregstr(struct map_session_data *sd, int64 reg)
+{
struct script_reg_str *p = NULL;
nullpo_retr(NULL, sd);
@@ -9200,7 +9543,8 @@ char* pc_readregstr(struct map_session_data* sd, int64 reg) {
/**
* For '@type$' variables (temporary string char reg)
**/
-void pc_setregstr(struct map_session_data* sd, int64 reg, const char* str) {
+static void pc_setregstr(struct map_session_data *sd, int64 reg, const char *str)
+{
struct script_reg_str *p = NULL;
unsigned int index = script_getvaridx(reg);
struct DBData prev;
@@ -9239,7 +9583,8 @@ void pc_setregstr(struct map_session_data* sd, int64 reg, const char* str) {
* - '#type' (permanent numeric account reg)
* - '##type' (permanent numeric account reg2)
**/
-int pc_readregistry(struct map_session_data *sd, int64 reg) {
+static int pc_readregistry(struct map_session_data *sd, int64 reg)
+{
struct script_reg_num *p = NULL;
nullpo_ret(sd);
@@ -9261,7 +9606,8 @@ int pc_readregistry(struct map_session_data *sd, int64 reg) {
* - '#type$' (permanent str account reg)
* - '##type$' (permanent str account reg2)
**/
-char* pc_readregistry_str(struct map_session_data *sd, int64 reg) {
+static char *pc_readregistry_str(struct map_session_data *sd, int64 reg)
+{
struct script_reg_str *p = NULL;
nullpo_retr(NULL, sd);
@@ -9283,7 +9629,8 @@ char* pc_readregistry_str(struct map_session_data *sd, int64 reg) {
* - '#type' (permanent numeric account reg)
* - '##type' (permanent numeric account reg2)
**/
-int pc_setregistry(struct map_session_data *sd, int64 reg, int val) {
+static int pc_setregistry(struct map_session_data *sd, int64 reg, int val)
+{
struct script_reg_num *p = NULL;
const char *regname = script->get_str( script_getvarid(reg) );
unsigned int index = script_getvaridx(reg);
@@ -9359,7 +9706,8 @@ int pc_setregistry(struct map_session_data *sd, int64 reg, int val) {
* - '#type$' (permanent str account reg)
* - '##type$' (permanent str account reg2)
**/
-int pc_setregistry_str(struct map_session_data *sd, int64 reg, const char *val) {
+static int pc_setregistry_str(struct map_session_data *sd, int64 reg, const char *val)
+{
struct script_reg_str *p = NULL;
const char *regname = script->get_str( script_getvarid(reg) );
unsigned int index = script_getvaridx(reg);
@@ -9415,7 +9763,8 @@ int pc_setregistry_str(struct map_session_data *sd, int64 reg, const char *val)
/*==========================================
* Exec eventtimer for player sd (retrieved from map_session (id))
*------------------------------------------*/
-int pc_eventtimer(int tid, int64 tick, int id, intptr_t data) {
+static int pc_eventtimer(int tid, int64 tick, int id, intptr_t data)
+{
struct map_session_data *sd=map->id2sd(id);
char *p = (char *)data;
int i;
@@ -9439,7 +9788,7 @@ int pc_eventtimer(int tid, int64 tick, int id, intptr_t data) {
/*==========================================
* Add eventtimer for player sd ?
*------------------------------------------*/
-int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
+static int pc_addeventtimer(struct map_session_data *sd, int tick, const char *name)
{
int i;
nullpo_ret(sd);
@@ -9458,7 +9807,7 @@ int pc_addeventtimer(struct map_session_data *sd,int tick,const char *name)
/*==========================================
* Del eventtimer for player sd ?
*------------------------------------------*/
-int pc_deleventtimer(struct map_session_data *sd,const char *name)
+static int pc_deleventtimer(struct map_session_data *sd, const char *name)
{
char* p = NULL;
int i;
@@ -9489,7 +9838,7 @@ int pc_deleventtimer(struct map_session_data *sd,const char *name)
/*==========================================
* Update eventtimer count for player sd
*------------------------------------------*/
-int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick)
+static int pc_addeventtimercount(struct map_session_data *sd, const char *name, int tick)
{
int i;
@@ -9508,7 +9857,7 @@ int pc_addeventtimercount(struct map_session_data *sd,const char *name,int tick)
/*==========================================
* Remove all eventtimer for player sd
*------------------------------------------*/
-int pc_cleareventtimer(struct map_session_data *sd)
+static int pc_cleareventtimer(struct map_session_data *sd)
{
int i;
@@ -9528,7 +9877,8 @@ int pc_cleareventtimer(struct map_session_data *sd)
return 0;
}
/* called when a item with combo is worn */
-int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) {
+static int pc_checkcombo(struct map_session_data *sd, struct item_data *data)
+{
int i, j, k, z;
int index, success = 0;
struct pc_combos *combo;
@@ -9607,7 +9957,8 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) {
}
/* called when a item with combo is removed */
-int pc_removecombo(struct map_session_data *sd, struct item_data *data ) {
+static int pc_removecombo(struct map_session_data *sd, struct item_data *data)
+{
int i, retval = 0;
nullpo_ret(sd);
@@ -9654,7 +10005,8 @@ int pc_removecombo(struct map_session_data *sd, struct item_data *data ) {
return retval;
}
-int pc_load_combo(struct map_session_data *sd) {
+static int pc_load_combo(struct map_session_data *sd)
+{
int i, ret = 0;
nullpo_ret(sd);
for( i = 0; i < EQI_MAX; i++ ) {
@@ -9681,94 +10033,102 @@ int pc_load_combo(struct map_session_data *sd) {
}
/**
-* Equip item at given position.
-* @param sd the affected player structure. Must be checked before.
-* @param id item structure for equip. Must be checked before.
-* @param n inventory item position. Must be checked before.
-* @param pos slot position. Must be checked before.
-**/
-void pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int n, int pos)
+ * Equip item at given position.
+ * @param sd the affected player structure. Must be checked before.
+ * @param id item structure for equip. Must be checked before.
+ * @param n inventory item position. Must be checked before.
+ * @param pos slot position. Must be checked before.
+ */
+static void pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int n, int pos)
{
nullpo_retv(sd);
if ((!map_no_view(sd->bl.m,EQP_SHADOW_WEAPON) && pos & EQP_SHADOW_WEAPON) ||
(pos & EQP_HAND_R)) {
- if(id)
- sd->weapontype1 = id->look;
- else
- sd->weapontype1 = 0;
+ if (id != NULL) {
+ sd->weapontype1 = id->subtype;
+ sd->status.look.weapon = id->view_sprite;
+ } else {
+ sd->weapontype1 = W_FIST;
+ sd->status.look.weapon = 0;
+ }
pc->calcweapontype(sd);
- clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ clif->changelook(&sd->bl, LOOK_WEAPON, sd->status.look.weapon);
}
if ((!map_no_view(sd->bl.m,EQP_SHADOW_SHIELD) && pos & EQP_SHADOW_SHIELD) ||
(pos & EQP_HAND_L)) {
- if (id) {
- if(id->type == IT_WEAPON) {
- sd->status.shield = 0;
- sd->weapontype2 = id->look;
- } else if(id->type == IT_ARMOR) {
- sd->status.shield = id->look;
- sd->weapontype2 = 0;
+ if (id != NULL) {
+ if (id->type == IT_WEAPON) {
+ sd->has_shield = false;
+ sd->status.look.shield = 0;
+ sd->weapontype2 = id->subtype;
+ } else if (id->type == IT_ARMOR) {
+ sd->has_shield = true;
+ sd->status.look.shield = id->view_sprite;
+ sd->weapontype2 = W_FIST;
}
- } else
- sd->status.shield = sd->weapontype2 = 0;
+ } else {
+ sd->has_shield = false;
+ sd->status.look.shield = 0;
+ sd->weapontype2 = W_FIST;
+ }
pc->calcweapontype(sd);
- clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
+ clif->changelook(&sd->bl, LOOK_SHIELD, sd->status.look.shield);
}
//Added check to prevent sending the same look on multiple slots ->
//causes client to redraw item on top of itself. (suggested by Lupus)
if (!map_no_view(sd->bl.m,EQP_HEAD_LOW) && pos & EQP_HEAD_LOW && pc->checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) {
if (id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID)))
- sd->status.head_bottom = id->look;
+ sd->status.look.head_bottom = id->view_sprite;
else
- sd->status.head_bottom = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ sd->status.look.head_bottom = 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.look.head_bottom);
}
if (!map_no_view(sd->bl.m,EQP_HEAD_TOP) && pos & EQP_HEAD_TOP && pc->checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) {
if (id)
- sd->status.head_top = id->look;
+ sd->status.look.head_top = id->view_sprite;
else
- sd->status.head_top = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ sd->status.look.head_top = 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.look.head_top);
}
if (!map_no_view(sd->bl.m,EQP_HEAD_MID) && pos & EQP_HEAD_MID && pc->checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) {
if (id && !(pos&EQP_HEAD_TOP))
- sd->status.head_mid = id->look;
+ sd->status.look.head_mid = id->view_sprite;
else
- sd->status.head_mid = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ sd->status.look.head_mid = 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_MID, sd->status.look.head_mid);
}
if (!map_no_view(sd->bl.m,EQP_COSTUME_HEAD_TOP) && pos & EQP_COSTUME_HEAD_TOP) {
if (id){
- sd->status.head_top = id->look;
+ sd->status.look.head_top = id->view_sprite;
} else
- sd->status.head_top = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ sd->status.look.head_top = 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.look.head_top);
}
if (!map_no_view(sd->bl.m,EQP_COSTUME_HEAD_MID) && pos & EQP_COSTUME_HEAD_MID) {
if(id && !(pos&EQP_HEAD_TOP)){
- sd->status.head_mid = id->look;
+ sd->status.look.head_mid = id->view_sprite;
} else
- sd->status.head_mid = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ sd->status.look.head_mid = 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_MID, sd->status.look.head_mid);
}
if (!map_no_view(sd->bl.m,EQP_COSTUME_HEAD_LOW) && pos & EQP_COSTUME_HEAD_LOW) {
if (id && !(pos&(EQP_HEAD_TOP|EQP_HEAD_MID))){
- sd->status.head_bottom = id->look;
+ sd->status.look.head_bottom = id->view_sprite;
} else
- sd->status.head_bottom = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ sd->status.look.head_bottom = 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.look.head_bottom);
}
if (!map_no_view(sd->bl.m,EQP_SHOES) && pos & EQP_SHOES)
clif->changelook(&sd->bl,LOOK_SHOES,0);
if (!map_no_view(sd->bl.m,EQP_GARMENT) && pos&EQP_GARMENT && pc->checkequip(sd,EQP_COSTUME_GARMENT) == -1) {
- sd->status.robe = id ? id->look : 0;
- clif->changelook(&sd->bl, LOOK_ROBE, sd->status.robe);
+ sd->status.look.robe = id ? id->view_sprite : 0;
+ clif->changelook(&sd->bl, LOOK_ROBE, sd->status.look.robe);
}
if (!map_no_view(sd->bl.m,EQP_COSTUME_GARMENT) && pos & EQP_COSTUME_GARMENT) {
- sd->status.robe = id ? id->look : 0;
- clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe);
+ sd->status.look.robe = id ? id->view_sprite : 0;
+ clif->changelook(&sd->bl, LOOK_ROBE, sd->status.look.robe);
}
}
@@ -9778,14 +10138,14 @@ void pc_equipitem_pos(struct map_session_data *sd, struct item_data *id, int n,
* 0 = fail
* 1 = success
*------------------------------------------*/
-int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
+static int pc_equipitem(struct map_session_data *sd, int n, int req_pos)
{
int i,pos,flag=0,iflag;
struct item_data *id;
nullpo_ret(sd);
- if( n < 0 || n >= MAX_INVENTORY ) {
+ if (n < 0 || n >= sd->status.inventorySize) {
clif->equipitemack(sd,0,0,EIA_FAIL);
return 0;
}
@@ -9913,66 +10273,68 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
}
/**
-* Unrquip item ad given position.
-* @param sd the affected player structure. Must be checked before.
-* @param n inventory item position. Must be checked before.
-* @param pos slot position. Must be checked before.
-**/
-void pc_unequipitem_pos(struct map_session_data *sd, int n, int pos)
+ * Unequip an item at the given position.
+ * @param sd the affected player structure. Must be checked before.
+ * @param n inventory item position. Must be checked before.
+ * @param pos slot position. Must be checked before.
+ */
+static void pc_unequipitem_pos(struct map_session_data *sd, int n, int pos)
{
nullpo_retv(sd);
if (pos & EQP_HAND_R) {
- sd->weapontype1 = 0;
- sd->status.weapon = sd->weapontype2;
+ sd->weapontype1 = W_FIST;
pc->calcweapontype(sd);
- clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
+ sd->status.look.weapon = 0;
+ clif->changelook(&sd->bl, LOOK_WEAPON, sd->status.look.weapon);
if (!battle_config.dancing_weaponswitch_fix)
status_change_end(&sd->bl, SC_DANCING, INVALID_TIMER); // Unequipping => stop dancing.
}
if (pos & EQP_HAND_L) {
- sd->status.shield = sd->weapontype2 = 0;
+ sd->has_shield = false;
+ sd->status.look.shield = 0;
+ sd->weapontype2 = W_FIST;
pc->calcweapontype(sd);
- clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
+ clif->changelook(&sd->bl, LOOK_SHIELD, sd->status.look.shield);
}
if (pos & EQP_HEAD_LOW && pc->checkequip(sd,EQP_COSTUME_HEAD_LOW) == -1) {
- sd->status.head_bottom = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ sd->status.look.head_bottom = 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.look.head_bottom);
}
if (pos & EQP_HEAD_TOP && pc->checkequip(sd,EQP_COSTUME_HEAD_TOP) == -1) {
- sd->status.head_top = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ sd->status.look.head_top = 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.look.head_top);
}
if (pos & EQP_HEAD_MID && pc->checkequip(sd,EQP_COSTUME_HEAD_MID) == -1) {
- sd->status.head_mid = 0;
- clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ sd->status.look.head_mid = 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_MID, sd->status.look.head_mid);
}
if (pos & EQP_COSTUME_HEAD_TOP) {
- sd->status.head_top = ( pc->checkequip(sd,EQP_HEAD_TOP) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_TOP)]->look : 0;
- clif->changelook(&sd->bl,LOOK_HEAD_TOP,sd->status.head_top);
+ sd->status.look.head_top = ( pc->checkequip(sd,EQP_HEAD_TOP) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_TOP)]->view_sprite : 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_TOP, sd->status.look.head_top);
}
if (pos & EQP_COSTUME_HEAD_MID) {
- sd->status.head_mid = ( pc->checkequip(sd,EQP_HEAD_MID) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_MID)]->look : 0;
- clif->changelook(&sd->bl,LOOK_HEAD_MID,sd->status.head_mid);
+ sd->status.look.head_mid = ( pc->checkequip(sd,EQP_HEAD_MID) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_MID)]->view_sprite : 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_MID, sd->status.look.head_mid);
}
if (pos & EQP_COSTUME_HEAD_LOW) {
- sd->status.head_bottom = ( pc->checkequip(sd,EQP_HEAD_LOW) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_LOW)]->look : 0;
- clif->changelook(&sd->bl,LOOK_HEAD_BOTTOM,sd->status.head_bottom);
+ sd->status.look.head_bottom = ( pc->checkequip(sd,EQP_HEAD_LOW) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_HEAD_LOW)]->view_sprite : 0;
+ clif->changelook(&sd->bl, LOOK_HEAD_BOTTOM, sd->status.look.head_bottom);
}
if (pos & EQP_SHOES)
clif->changelook(&sd->bl,LOOK_SHOES,0);
if (pos & EQP_GARMENT && pc->checkequip(sd,EQP_COSTUME_GARMENT) == -1) {
- sd->status.robe = 0;
+ sd->status.look.robe = 0;
clif->changelook(&sd->bl, LOOK_ROBE, 0);
}
if (pos & EQP_COSTUME_GARMENT) {
- sd->status.robe = ( pc->checkequip(sd,EQP_GARMENT) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_GARMENT)]->look : 0;
- clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe);
+ sd->status.look.robe = ( pc->checkequip(sd,EQP_GARMENT) >= 0 ) ? sd->inventory_data[pc->checkequip(sd,EQP_GARMENT)]->view_sprite : 0;
+ clif->changelook(&sd->bl, LOOK_ROBE, sd->status.look.robe);
}
}
@@ -9983,129 +10345,144 @@ void pc_unequipitem_pos(struct map_session_data *sd, int n, int pos)
* 0 = fail
* 1 = success
*------------------------------------------*/
-int pc_unequipitem(struct map_session_data *sd,int n,int flag)
+static int pc_unequipitem(struct map_session_data *sd, int n, int flag)
{
- int i,iflag;
- bool status_cacl = false;
+ int i, iflag;
+ bool status_calc = false;
int pos;
+
nullpo_ret(sd);
- if( n < 0 || n >= MAX_INVENTORY ) {
- clif->unequipitemack(sd,0,0,UIA_FAIL);
+ if (n < 0 || n >= sd->status.inventorySize) {
+ clif->unequipitemack(sd, 0, 0, UIA_FAIL);
return 0;
}
// if player is berserk then cannot unequip
- if (!(flag&PCUNEQUIPITEM_FORCE) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_NO_SWITCH_EQUIP]) )
- {
- clif->unequipitemack(sd,n,0,UIA_FAIL);
+ if (!(flag & PCUNEQUIPITEM_FORCE) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_NO_SWITCH_EQUIP])) {
+ clif->unequipitemack(sd, n, 0, UIA_FAIL);
return 0;
}
- if( !(flag&PCUNEQUIPITEM_FORCE) && sd->sc.count && sd->sc.data[SC_KYOUGAKU] )
- {
- clif->unequipitemack(sd,n,0,UIA_FAIL);
+ if (!(flag & PCUNEQUIPITEM_FORCE) && sd->sc.count && sd->sc.data[SC_KYOUGAKU]) {
+ clif->unequipitemack(sd, n, 0, UIA_FAIL);
return 0;
}
- if(battle_config.battle_log)
+ if (battle_config.battle_log)
ShowInfo("unequip %d %x:%x\n", n, (unsigned int)(pc->equippoint(sd, n)), sd->status.inventory[n].equip);
- if(!sd->status.inventory[n].equip){ //Nothing to unequip
- clif->unequipitemack(sd,n,0,UIA_FAIL);
+ if (sd->status.inventory[n].equip == 0) { //Nothing to unequip
+ clif->unequipitemack(sd, n, 0, UIA_FAIL);
return 0;
}
- for(i=0;i<EQI_MAX;i++) {
- if(sd->status.inventory[n].equip & pc->equip_pos[i])
+
+ for (i = 0; i < EQI_MAX; i++) {
+ if (sd->status.inventory[n].equip & pc->equip_pos[i])
sd->equip_index[i] = -1;
}
pos = sd->status.inventory[n].equip;
pc->unequipitem_pos(sd, n, pos);
- clif->unequipitemack(sd,n,pos,UIA_SUCCESS);
+ clif->unequipitemack(sd, n, pos, UIA_SUCCESS);
- if((pos & EQP_ARMS) &&
- sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_TK_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!)
- skill->enchant_elemental_end(&sd->bl,-1);
+ if ((pos & EQP_ARMS) &&
+ sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST && (sd->sc.data[SC_TK_SEVENWIND] == NULL || sd->sc.data[SC_ASPERSIO] != NULL)) //Check for seven wind (but not level seven!)
+ skill->enchant_elemental_end(&sd->bl, -1);
- if(pos & EQP_ARMOR) {
+ if (pos & EQP_ARMOR) {
// On Armor Change...
status_change_end(&sd->bl, SC_BENEDICTIO, INVALID_TIMER);
status_change_end(&sd->bl, SC_ARMOR_RESIST, INVALID_TIMER);
}
+#ifdef RENEWAL
+ if (battle->bc->bow_unequip_arrow && pos&EQP_ARMS && sd->equip_index[EQI_AMMO] > 0)
+ pc->unequipitem(sd, sd->equip_index[EQI_AMMO], PCUNEQUIPITEM_FORCE);
+#endif
+
if( sd->state.autobonus&pos )
sd->state.autobonus &= ~sd->status.inventory[n].equip; //Check for activated autobonus [Inkfish]
- sd->status.inventory[n].equip=0;
+ sd->status.inventory[n].equip = 0;
iflag = sd->npc_item_flag;
/* check for combos (MUST be before status_calc_pc) */
- if ( sd->inventory_data[n] ) {
- if( sd->inventory_data[n]->combos_count ) {
- if( pc->removecombo(sd,sd->inventory_data[n]) )
- status_cacl = true;
- } if(itemdb_isspecial(sd->status.inventory[n].card[0]))
- ; //No cards
- else {
- for( i = 0; i < sd->inventory_data[n]->slot; i++ ) {
+ if (sd->inventory_data[n] != NULL) {
+ if (sd->inventory_data[n]->combos_count) {
+ if (pc->removecombo(sd, sd->inventory_data[n]))
+ status_calc = true;
+ }
+ if (itemdb_isspecial(sd->status.inventory[n].card[0]) == false) {
+ for (i = 0; i < sd->inventory_data[n]->slot; i++) {
struct item_data *data;
- if (!sd->status.inventory[n].card[i])
+ if (sd->status.inventory[n].card[i] == 0)
continue;
- if ( ( data = itemdb->exists(sd->status.inventory[n].card[i]) ) != NULL ) {
- if( data->combos_count ) {
- if( pc->removecombo(sd,data) )
- status_cacl = true;
+ if ((data = itemdb->exists(sd->status.inventory[n].card[i])) != NULL) {
+ if (data->combos_count) {
+ if (pc->removecombo(sd, data))
+ status_calc = true;
}
}
}
}
+ /* Item Options checking */
+ for (i = 0; i < MAX_ITEM_OPTIONS; i++) {
+ struct itemdb_option *ito = NULL;
+ int16 item_option = sd->status.inventory[n].option[i].index;
+
+ if (item_option <= 0)
+ continue;
+ if ((ito = itemdb->option_exists(sd->status.inventory[n].option[i].index)) == NULL)
+ continue;
+
+ status_calc = true;
+ }
}
- if(flag&PCUNEQUIPITEM_RECALC || status_cacl) {
+ if (flag & PCUNEQUIPITEM_RECALC || status_calc) {
pc->checkallowskill(sd);
- status_calc_pc(sd,SCO_NONE);
+ status_calc_pc(sd, SCO_NONE);
}
- if(sd->sc.data[SC_CRUCIS] && !battle->check_undead(sd->battle_status.race,sd->battle_status.def_ele))
+ if (sd->sc.data[SC_CRUCIS] && battle->check_undead(sd->battle_status.race, sd->battle_status.def_ele) == false)
status_change_end(&sd->bl, SC_CRUCIS, INVALID_TIMER);
//OnUnEquip script [Skotlex]
- if (sd->inventory_data[n]) {
- if (sd->inventory_data[n]->unequip_script) {
- if ( battle_config.unequip_restricted_equipment & 1 ) {
- ARR_FIND(0, map->list[sd->bl.m].zone->disabled_items_count, i, map->list[sd->bl.m].zone->disabled_items[i] == sd->status.inventory[n].nameid);
- if ( i == map->list[sd->bl.m].zone->disabled_items_count )
+ if (sd->inventory_data[n] != NULL) {
+ if (sd->inventory_data[n]->unequip_script != NULL) {
+ if (battle_config.unequip_restricted_equipment & 1) {
+ ARR_FIND(0, map->list[sd->bl.m].zone->disabled_items_count, i, map->list[sd->bl.m].zone->disabled_items[i] == sd->status.inventory[n].nameid);
+ if (i == map->list[sd->bl.m].zone->disabled_items_count)
script->run_item_unequip_script(sd, sd->inventory_data[n], npc->fake_nd->bl.id);
}
else
script->run_item_unequip_script(sd, sd->inventory_data[n], npc->fake_nd->bl.id);
}
- if(itemdb_isspecial(sd->status.inventory[n].card[0]))
- ; //No cards
- else {
- for( i = 0; i < sd->inventory_data[n]->slot; i++ ) {
- struct item_data *data;
- if (!sd->status.inventory[n].card[i])
+ if (itemdb_isspecial(sd->status.inventory[n].card[0]) == false) {
+ for (i = 0; i < sd->inventory_data[n]->slot; i++) {
+ struct item_data *data = NULL;
+ if (sd->status.inventory[n].card[i] == 0)
continue;
- if ( ( data = itemdb->exists(sd->status.inventory[n].card[i]) ) != NULL ) {
- if ( data->unequip_script ) {
- if ( battle_config.unequip_restricted_equipment & 2 ) {
+ if ((data = itemdb->exists(sd->status.inventory[n].card[i])) != NULL) {
+ if (data->unequip_script) {
+ if (battle_config.unequip_restricted_equipment & 2) {
int j;
- ARR_FIND(0, map->list[sd->bl.m].zone->disabled_items_count, j, map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[n].card[i]);
- if ( j == map->list[sd->bl.m].zone->disabled_items_count )
+ ARR_FIND(0, map->list[sd->bl.m].zone->disabled_items_count, j, map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[n].card[i]);
+ if (j == map->list[sd->bl.m].zone->disabled_items_count)
script->run_item_unequip_script(sd, data, npc->fake_nd->bl.id);
- }
- else
+ } else {
script->run_item_unequip_script(sd, data, npc->fake_nd->bl.id);
+ }
}
}
}
}
}
+
sd->npc_item_flag = iflag;
return 1;
@@ -10115,105 +10492,114 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag)
* Checking if player (sd) have unauthorize, invalide item
* on inventory, cart, equiped for the map (item_noequip)
*------------------------------------------*/
-int pc_checkitem(struct map_session_data *sd)
+static int pc_checkitem(struct map_session_data *sd)
{
int i, calc_flag = 0;
nullpo_ret(sd);
- if (sd->state.vending) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
+ if (sd->state.vending == 1) // Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam)
return 0;
- if (sd->state.itemcheck) { // check for invalid(ated) items
- int id;
- for (i = 0; i < MAX_INVENTORY; i++) {
- id = sd->status.inventory[i].nameid;
+ if (sd->itemcheck != PCCHECKITEM_NONE) { // check for invalid(ated) items
+ int id = 0;
- if (!id)
- continue;
+ if (sd->itemcheck & PCCHECKITEM_INVENTORY) {
+ for (i = 0; i < sd->status.inventorySize; i++) {
+ if ((id = sd->status.inventory[i].nameid) == 0)
+ continue;
- if (!itemdb_available(id)) {
- ShowWarning("Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id);
- pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_INV_INVALID);
- continue;
+ if (!itemdb_available(id)) {
+ ShowWarning("pc_checkitem: Removed invalid/disabled item id %d from inventory (amount=%d, char_id=%d).\n", id, sd->status.inventory[i].amount, sd->status.char_id);
+ pc->delitem(sd, i, sd->status.inventory[i].amount, 0, DELITEM_NORMAL, LOG_TYPE_INV_INVALID);
+ continue;
+ }
+
+ if (sd->status.inventory[i].unique_id == 0 && !itemdb->isstackable(id))
+ sd->status.inventory[i].unique_id = itemdb->unique_id(sd);
}
- if (!sd->status.inventory[i].unique_id && !itemdb->isstackable(id))
- sd->status.inventory[i].unique_id = itemdb->unique_id(sd);
+ sd->itemcheck &= ~PCCHECKITEM_INVENTORY;
}
- for( i = 0; i < MAX_CART; i++ ) {
- id = sd->status.cart[i].nameid;
+ if (sd->itemcheck & PCCHECKITEM_CART) {
+ for (i = 0; i < MAX_CART; i++) {
+ if ((id = sd->status.cart[i].nameid) == 0)
+ continue;
- if (!id)
- continue;
+ if( !itemdb_available(id) ) {
+ ShowWarning("pc_checkitem: Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", id, sd->status.cart[i].amount, sd->status.char_id);
+ pc->cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_CART_INVALID);
+ continue;
+ }
- if( !itemdb_available(id) ) {
- ShowWarning("Removed invalid/disabled item id %d from cart (amount=%d, char_id=%d).\n", id, sd->status.cart[i].amount, sd->status.char_id);
- pc->cart_delitem(sd, i, sd->status.cart[i].amount, 0, LOG_TYPE_CART_INVALID);
- continue;
+ if (sd->status.cart[i].unique_id == 0 && !itemdb->isstackable(id))
+ sd->status.cart[i].unique_id = itemdb->unique_id(sd);
}
- if ( !sd->status.cart[i].unique_id && !itemdb->isstackable(id) )
- sd->status.cart[i].unique_id = itemdb->unique_id(sd);
+ sd->itemcheck &= ~PCCHECKITEM_CART;
}
- for( i = 0; i < MAX_STORAGE; i++ ) {
- id = sd->status.storage.items[i].nameid;
+ if (sd->itemcheck & PCCHECKITEM_STORAGE && sd->storage.received == true) {
+ for (i = 0; i < VECTOR_LENGTH(sd->storage.item); i++) {
+ struct item *it = &VECTOR_INDEX(sd->storage.item, i);
- if (!id)
- continue;
+ if ((id = it->nameid) == 0)
+ continue;
- if( id && !itemdb_available(id) ) {
- ShowWarning("Removed invalid/disabled item id %d from storage (amount=%d, char_id=%d).\n", id, sd->status.storage.items[i].amount, sd->status.char_id);
- storage->delitem(sd, i, sd->status.storage.items[i].amount);
- storage->close(sd);
- continue;
+ if (!itemdb_available(id)) {
+ ShowWarning("pc_checkitem: Removed invalid/disabled item id %d from storage (amount=%d, char_id=%d).\n", id, it->amount, sd->status.char_id);
+ storage->delitem(sd, i, it->amount);
+ continue;
+ }
+
+ if (it->unique_id == 0 && itemdb->isstackable(id) == 0)
+ it->unique_id = itemdb->unique_id(sd);
}
- if ( !sd->status.storage.items[i].unique_id && !itemdb->isstackable(id) )
- sd->status.storage.items[i].unique_id = itemdb->unique_id(sd);
+ storage->close(sd);
+
+ sd->itemcheck &= ~PCCHECKITEM_STORAGE;
}
- if (sd->guild) {
+ if (sd->guild && sd->itemcheck & PCCHECKITEM_GSTORAGE) {
struct guild_storage *guild_storage = idb_get(gstorage->db,sd->guild->guild_id);
if (guild_storage) {
- for( i = 0; i < MAX_GUILD_STORAGE; i++ ) {
- id = guild_storage->items[i].nameid;
-
- if (!id)
+ for (i = 0; i < MAX_GUILD_STORAGE; i++) {
+ if ((id = guild_storage->items[i].nameid) == 0)
continue;
- if( !itemdb_available(id) ) {
- ShowWarning("Removed invalid/disabled item id %d from guild storage (amount=%d, char_id=%d, guild_id=%d).\n", id, guild_storage->items[i].amount, sd->status.char_id, sd->guild->guild_id);
+ if (!itemdb_available(id)) {
+ ShowWarning("pc_checkitem: Removed invalid/disabled item id %d from guild storage (amount=%d, char_id=%d, guild_id=%d).\n", id, guild_storage->items[i].amount, sd->status.char_id, sd->guild->guild_id);
gstorage->delitem(sd, guild_storage, i, guild_storage->items[i].amount);
gstorage->close(sd); // force closing
continue;
}
- if (!guild_storage->items[i].unique_id && !itemdb->isstackable(id))
+ if (guild_storage->items[i].unique_id == 0 && !itemdb->isstackable(id))
guild_storage->items[i].unique_id = itemdb->unique_id(sd);
}
}
+
+ sd->itemcheck &= ~PCCHECKITEM_GSTORAGE;
}
- sd->state.itemcheck = 0;
}
- for( i = 0; i < MAX_INVENTORY; i++) {
+ for (i = 0; i < sd->status.inventorySize; i++) {
- if( sd->status.inventory[i].nameid == 0 )
+ if (sd->status.inventory[i].nameid == 0)
continue;
- if( !sd->status.inventory[i].equip )
+ if (sd->status.inventory[i].equip == 0)
continue;
- if( sd->status.inventory[i].equip&~pc->equippoint(sd,i) ) {
+ if (sd->status.inventory[i].equip & ~pc->equippoint(sd,i)) {
pc->unequipitem(sd, i, PCUNEQUIPITEM_FORCE);
calc_flag = 1;
continue;
}
- if (battle_config.unequip_restricted_equipment&1) {
+ if (battle_config.unequip_restricted_equipment & 1) {
int j;
for (j = 0; j < map->list[sd->bl.m].zone->disabled_items_count; j++) {
if (map->list[sd->bl.m].zone->disabled_items[j] == sd->status.inventory[i].nameid) {
@@ -10223,7 +10609,7 @@ int pc_checkitem(struct map_session_data *sd)
}
}
- if (battle_config.unequip_restricted_equipment&2) {
+ if (battle_config.unequip_restricted_equipment & 2) {
if (!itemdb_isspecial(sd->status.inventory[i].card[0])) {
int j, slot;
for (slot = 0; slot < MAX_SLOTS; slot++) {
@@ -10239,9 +10625,9 @@ int pc_checkitem(struct map_session_data *sd)
}
- if( calc_flag && sd->state.active ) {
+ if (calc_flag != 0 && sd->state.active == 1) {
pc->checkallowskill(sd);
- status_calc_pc(sd,SCO_NONE);
+ status_calc_pc(sd, SCO_NONE);
}
return 0;
@@ -10250,7 +10636,7 @@ int pc_checkitem(struct map_session_data *sd)
/*==========================================
* Update PVP rank for sd1 in cmp to sd2
*------------------------------------------*/
-int pc_calc_pvprank_sub(struct block_list *bl, va_list ap)
+static int pc_calc_pvprank_sub(struct block_list *bl, va_list ap)
{
struct map_session_data *sd1 = NULL;
struct map_session_data *sd2 = va_arg(ap,struct map_session_data *);
@@ -10273,7 +10659,8 @@ int pc_calc_pvprank_sub(struct block_list *bl, va_list ap)
* Calculate new rank beetween all present players (map->foreachinarea)
* and display result
*------------------------------------------*/
-int pc_calc_pvprank(struct map_session_data *sd) {
+static int pc_calc_pvprank(struct map_session_data *sd)
+{
int old;
struct map_data *m;
nullpo_ret(sd);
@@ -10288,7 +10675,8 @@ int pc_calc_pvprank(struct map_session_data *sd) {
/*==========================================
* Calculate next sd ranking calculation from config
*------------------------------------------*/
-int pc_calc_pvprank_timer(int tid, int64 tick, int id, intptr_t data) {
+static int pc_calc_pvprank_timer(int tid, int64 tick, int id, intptr_t data)
+{
struct map_session_data *sd;
sd=map->id2sd(id);
@@ -10312,7 +10700,7 @@ int pc_calc_pvprank_timer(int tid, int64 tick, int id, intptr_t data) {
* partner_id = yes
* 0 = no
*------------------------------------------*/
-int pc_ismarried(struct map_session_data *sd)
+static int pc_ismarried(struct map_session_data *sd)
{
if(sd == NULL)
return -1;
@@ -10327,7 +10715,7 @@ int pc_ismarried(struct map_session_data *sd)
* -1 = fail
* 0 = success
*------------------------------------------*/
-int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd)
+static int pc_marriage(struct map_session_data *sd, struct map_session_data *dstsd)
{
if(sd == NULL || dstsd == NULL ||
sd->status.partner_id > 0 || dstsd->status.partner_id > 0 ||
@@ -10335,6 +10723,11 @@ int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd)
return -1;
sd->status.partner_id = dstsd->status.char_id;
dstsd->status.partner_id = sd->status.char_id;
+
+ // Achievements [Smokexyz/Hercules]
+ achievement->validate_marry(sd);
+ achievement->validate_marry(dstsd);
+
return 0;
}
@@ -10344,7 +10737,7 @@ int pc_marriage(struct map_session_data *sd,struct map_session_data *dstsd)
* -1 = fail
* 0 = success
*------------------------------------------*/
-int pc_divorce(struct map_session_data *sd)
+static int pc_divorce(struct map_session_data *sd)
{
struct map_session_data *p_sd;
int i;
@@ -10366,11 +10759,14 @@ int pc_divorce(struct map_session_data *sd)
// Both players online, lets do the divorce manually
sd->status.partner_id = 0;
p_sd->status.partner_id = 0;
- for( i = 0; i < MAX_INVENTORY; i++ )
+ for (i = 0; i < sd->status.inventorySize; i++)
{
- if( sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F )
+ if (sd->status.inventory[i].nameid == WEDDING_RING_M || sd->status.inventory[i].nameid == WEDDING_RING_F)
pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_DIVORCE);
- if( p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F )
+ }
+ for (i = 0; i < p_sd->status.inventorySize; i++)
+ {
+ if (p_sd->status.inventory[i].nameid == WEDDING_RING_M || p_sd->status.inventory[i].nameid == WEDDING_RING_F)
pc->delitem(p_sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_DIVORCE);
}
@@ -10383,7 +10779,8 @@ int pc_divorce(struct map_session_data *sd)
/*==========================================
* Get sd partner charid. (Married partner)
*------------------------------------------*/
-struct map_session_data *pc_get_partner(struct map_session_data *sd) {
+static struct map_session_data *pc_get_partner(struct map_session_data *sd)
+{
if (sd && pc->ismarried(sd))
// charid2sd returns NULL if not found
return map->charid2sd(sd->status.partner_id);
@@ -10394,7 +10791,8 @@ struct map_session_data *pc_get_partner(struct map_session_data *sd) {
/*==========================================
* Get sd father charid. (Need to be baby)
*------------------------------------------*/
-struct map_session_data *pc_get_father(struct map_session_data *sd) {
+static struct map_session_data *pc_get_father(struct map_session_data *sd)
+{
if (sd && (sd->job & JOBL_BABY) != 0 && sd->status.father > 0)
// charid2sd returns NULL if not found
return map->charid2sd(sd->status.father);
@@ -10405,7 +10803,8 @@ struct map_session_data *pc_get_father(struct map_session_data *sd) {
/*==========================================
* Get sd mother charid. (Need to be baby)
*------------------------------------------*/
-struct map_session_data *pc_get_mother(struct map_session_data *sd) {
+static struct map_session_data *pc_get_mother(struct map_session_data *sd)
+{
if (sd && (sd->job & JOBL_BABY) != 0 && sd->status.mother > 0)
// charid2sd returns NULL if not found
return map->charid2sd(sd->status.mother);
@@ -10416,7 +10815,8 @@ struct map_session_data *pc_get_mother(struct map_session_data *sd) {
/*==========================================
* Get sd children charid. (Need to be married)
*------------------------------------------*/
-struct map_session_data *pc_get_child(struct map_session_data *sd) {
+static struct map_session_data *pc_get_child(struct map_session_data *sd)
+{
if (sd && pc->ismarried(sd) && sd->status.child > 0)
// charid2sd returns NULL if not found
return map->charid2sd(sd->status.child);
@@ -10427,7 +10827,7 @@ struct map_session_data *pc_get_child(struct map_session_data *sd) {
/*==========================================
* Set player sd to bleed. (losing hp and/or sp each diff_tick)
*------------------------------------------*/
-void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick)
+static void pc_bleeding(struct map_session_data *sd, unsigned int diff_tick)
{
int hp = 0, sp = 0;
@@ -10462,7 +10862,8 @@ void pc_bleeding (struct map_session_data *sd, unsigned int diff_tick)
//Character regen. Flag is used to know which types of regen can take place.
//&1: HP regen
//&2: SP regen
-void pc_regen (struct map_session_data *sd, unsigned int diff_tick) {
+static void pc_regen(struct map_session_data *sd, unsigned int diff_tick)
+{
int hp = 0, sp = 0;
nullpo_retv(sd);
@@ -10483,7 +10884,7 @@ void pc_regen (struct map_session_data *sd, unsigned int diff_tick) {
}
if (hp > 0 || sp > 0)
- status->heal(&sd->bl, hp, sp, 0);
+ status->heal(&sd->bl, hp, sp, STATUS_HEAL_DEFAULT);
return;
}
@@ -10491,7 +10892,8 @@ void pc_regen (struct map_session_data *sd, unsigned int diff_tick) {
/*==========================================
* Memo player sd savepoint. (map,x,y)
*------------------------------------------*/
-int pc_setsavepoint(struct map_session_data *sd, short map_index, int x, int y) {
+static int pc_setsavepoint(struct map_session_data *sd, short map_index, int x, int y)
+{
nullpo_ret(sd);
sd->status.save_point.map = map_index;
@@ -10504,7 +10906,8 @@ int pc_setsavepoint(struct map_session_data *sd, short map_index, int x, int y)
/*==========================================
* Save 1 player data at autosave intervall
*------------------------------------------*/
-int pc_autosave(int tid, int64 tick, int id, intptr_t data) {
+static int pc_autosave(int tid, int64 tick, int id, intptr_t data)
+{
int interval;
struct s_mapiterator* iter;
struct map_session_data* sd;
@@ -10542,7 +10945,8 @@ int pc_autosave(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
-int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap) {
+static int pc_daynight_timer_sub(struct map_session_data *sd, va_list ap)
+{
nullpo_ret(sd);
if (sd->state.night != map->night_flag && map->list[sd->bl.m].flag.nightenabled) { //Night/day state does not match.
clif->status_change(&sd->bl, SI_SKE, map->night_flag, 0, 0, 0, 0); //New night effect by dynamix [Skotlex]
@@ -10555,7 +10959,8 @@ int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap) {
* timer to do the day [Yor]
* data: 0 = called by timer, 1 = gmcommand/script
*------------------------------------------------*/
-int map_day_timer(int tid, int64 tick, int id, intptr_t data) {
+static int map_day_timer(int tid, int64 tick, int id, intptr_t data)
+{
char tmp_soutput[1024];
if (data == 0 && battle_config.day_duration <= 0) // if we want a day
@@ -10575,7 +10980,8 @@ int map_day_timer(int tid, int64 tick, int id, intptr_t data) {
* timer to do the night [Yor]
* data: 0 = called by timer, 1 = gmcommand/script
*------------------------------------------------*/
-int map_night_timer(int tid, int64 tick, int id, intptr_t data) {
+static int map_night_timer(int tid, int64 tick, int id, intptr_t data)
+{
char tmp_soutput[1024];
if (data == 0 && battle_config.night_duration <= 0) // if we want a night
@@ -10591,20 +10997,27 @@ int map_night_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
-void pc_setstand(struct map_session_data *sd) {
+static void pc_setstand(struct map_session_data *sd)
+{
nullpo_retv(sd);
status_change_end(&sd->bl, SC_TENSIONRELAX, INVALID_TIMER);
clif->sc_end(&sd->bl,sd->bl.id,SELF,SI_SIT);
//Reset sitting tick.
sd->ssregen.tick.hp = sd->ssregen.tick.sp = 0;
- sd->state.dead_sit = sd->vd.dead_sit = 0;
+ if (pc_isdead(sd)) {
+ sd->state.dead_sit = sd->vd.dead_sit = 0;
+ clif->party_dead_notification(sd);
+ } else {
+ sd->state.dead_sit = sd->vd.dead_sit = 0;
+ }
}
/**
* Mechanic (MADO GEAR)
**/
-void pc_overheat(struct map_session_data *sd, int val) {
+static void pc_overheat(struct map_session_data *sd, int val)
+{
int heat = val, skill_lv,
limit[] = { 10, 20, 28, 46, 66 };
@@ -10630,7 +11043,7 @@ void pc_overheat(struct map_session_data *sd, int val) {
/**
* Check if player is autolooting given itemID.
*/
-bool pc_isautolooting(struct map_session_data *sd, int nameid)
+static bool pc_isautolooting(struct map_session_data *sd, int nameid)
{
int i = 0;
@@ -10651,7 +11064,8 @@ bool pc_isautolooting(struct map_session_data *sd, int nameid)
* @param sd Player map session data
* @param command Command name with @/# and without params
*/
-bool pc_can_use_command(struct map_session_data *sd, const char *command) {
+static bool pc_can_use_command(struct map_session_data *sd, const char *command)
+{
return atcommand->can_use(sd,command);
}
@@ -10660,7 +11074,7 @@ bool pc_can_use_command(struct map_session_data *sd, const char *command) {
*
* @see TimerFunc
*/
-int pc_charm_timer(int tid, int64 tick, int id, intptr_t data)
+static int pc_charm_timer(int tid, int64 tick, int id, intptr_t data)
{
struct map_session_data *sd = map->id2sd(id);
int i;
@@ -10701,7 +11115,7 @@ int pc_charm_timer(int tid, int64 tick, int id, intptr_t data)
* @param max Maximum amount of charms to add.
* @param type Charm type (@see spirit_charm_types)
*/
-void pc_add_charm(struct map_session_data *sd, int interval, int max, int type)
+static void pc_add_charm(struct map_session_data *sd, int interval, int max, int type)
{
int tid, i;
@@ -10743,7 +11157,7 @@ void pc_add_charm(struct map_session_data *sd, int interval, int max, int type)
* @param count Amount of charms to remove.
* @param type Type of charm to remove.
*/
-void pc_del_charm(struct map_session_data *sd, int count, int type)
+static void pc_del_charm(struct map_session_data *sd, int count, int type)
{
int i;
@@ -10790,7 +11204,7 @@ void pc_del_charm(struct map_session_data *sd, int count, int type)
* @param type Modifier type (1=exp 2=itemdrop)
* @return The percent rate modifier (100 = 100%)
*/
-int pc_level_penalty_mod(int diff, unsigned char race, uint32 mode, int type)
+static int pc_level_penalty_mod(int diff, unsigned char race, uint32 mode, int type)
{
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
int rate = 100, i;
@@ -10819,64 +11233,10 @@ int pc_level_penalty_mod(int diff, unsigned char race, uint32 mode, int type)
return 100;
#endif
}
-int pc_split_str(char *str,char **val,int num)
-{
- int i;
- nullpo_ret(val);
- for (i=0; i<num && str; i++){
- val[i] = str;
- str = strchr(str,',');
- if (str && i<num-1) //Do not remove a trailing comma.
- *str++=0;
- }
- return i;
-}
-
-int pc_split_atoi(char* str, int* val, char sep, int max)
+static bool pc_read_skill_job_skip(short skill_id, int job_id)
{
- int i,j;
- nullpo_ret(val);
- for (i=0; i<max; i++) {
- if (!str) break;
- val[i] = atoi(str);
- str = strchr(str,sep);
- if (str)
- *str++=0;
- }
- //Zero up the remaining.
- for(j=i; j < max; j++)
- val[j] = 0;
- return i;
-}
-
-int pc_split_atoui(char* str, unsigned int* val, char sep, int max)
-{
- static int warning=0;
- int i,j;
- nullpo_ret(val);
- for (i=0; i<max; i++) {
- double f;
- if (!str) break;
- f = atof(str);
- if (f < 0)
- val[i] = 0;
- else if (f > UINT_MAX) {
- val[i] = UINT_MAX;
- if (!warning) {
- warning = 1;
- ShowWarning("pc_readdb (exp.txt): Required exp per level is capped to %u\n", UINT_MAX);
- }
- } else
- val[i] = (unsigned int)f;
- str = strchr(str,sep);
- if (str)
- *str++=0;
- }
- //Zero up the remaining.
- for(j=i; j < max; j++)
- val[j] = 0;
- return i;
+ return skill_id == NV_TRICKDEAD && ((pc->jobid2mapid(job_id) & (MAPID_BASEMASK | JOBL_2)) != MAPID_NOVICE); // skip trickdead for non-novices
}
/**
@@ -10892,7 +11252,7 @@ int pc_split_atoui(char* str, unsigned int* val, char sep, int max)
*
* @author [Ind/Hercules]
*/
-void pc_read_skill_tree(void)
+static void pc_read_skill_tree(void)
{
struct config_t skill_tree_conf;
struct config_setting_t *skt = NULL;
@@ -10959,8 +11319,8 @@ void pc_read_skill_tree(void)
ShowWarning("pc_read_skill_tree: '%s' can't inherit '%s', skill tree is full!\n", job_name, ijob_name);
break;
}
- if (src->id == NV_TRICKDEAD && ((pc->jobid2mapid(job_id)&(MAPID_BASEMASK | JOBL_2)) != MAPID_NOVICE))
- continue; // skip trickdead for non-novices
+ if (pc->read_skill_job_skip(src->id, job_id))
+ continue;
dst = &pc->skill_tree[job_idx][cur];
dst->inherited = 1;
if (dst->id == 0) {
@@ -11089,7 +11449,7 @@ void pc_read_skill_tree(void)
/**
* Clears the skill tree and frees any allocated memory.
*/
-void pc_clear_skill_tree(void)
+static void pc_clear_skill_tree(void)
{
int i;
for (i = 0; i < CLASS_COUNT; i++) {
@@ -11103,7 +11463,8 @@ void pc_clear_skill_tree(void)
memset(pc->skill_tree, 0, sizeof(pc->skill_tree));
}
-bool pc_readdb_levelpenalty(char* fields[], int columns, int current) {
+static bool pc_readdb_levelpenalty(char *fields[], int columns, int current)
+{
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
int type, race, diff;
@@ -11132,93 +11493,134 @@ bool pc_readdb_levelpenalty(char* fields[], int columns, int current) {
return true;
}
-/*==========================================
- * pc DB reading.
- * exp.txt - required experience values
- * skill_tree.txt - skill tree for every class
- * attr_fix.txt - elemental adjustment table
- *------------------------------------------*/
-int pc_readdb(void) {
- int i,j,k;
- unsigned int count = 0;
- FILE *fp;
- char line[24000],*p;
+static bool pc_read_exp_db_sub_class(struct config_setting_t *t, bool base)
+{
+ struct class_exp_group entry = { { 0 } };
+ struct config_setting_t *exp_t = NULL;
+ int maxlv = 0;
- //reset
- memset(pc->exp_table,0,sizeof(pc->exp_table));
- memset(pc->max_level,0,sizeof(pc->max_level));
+ nullpo_retr(false, t);
- sprintf(line, "%s/"DBPATH"exp.txt", map->db_path);
+ safestrncpy(entry.name, config_setting_name(t), SCRIPT_VARNAME_LENGTH);
- fp=fopen(line, "r");
- if(fp==NULL){
- ShowError("can't read %s\n", line);
- return 1;
+ if (libconfig->setting_lookup_int(t, "MaxLevel", &maxlv) == 0
+ || (maxlv <= 0 || maxlv > MAX_LEVEL)) {
+ ShowError("pc_read_exp_db_sub_class: Invalid max %s level '%d' set for entry '%s'. Defaulting to %d...", base ? "base" : "job", maxlv, entry.name, MAX_LEVEL);
+ maxlv = MAX_LEVEL;
}
- while(fgets(line, sizeof(line), fp)) {
- int jobs[CLASS_COUNT], job_count, job, job_id;
- int type;
- int maxlv;
- char *split[4];
- if(line[0]=='/' && line[1]=='/')
- continue;
- if (pc_split_str(line,split,4) < 4)
- continue;
- job_count = pc_split_atoi(split[1],jobs,':',CLASS_COUNT);
- if (job_count < 1)
- continue;
- job_id = jobs[0];
- if (!pc->db_checkid(job_id)) {
- ShowError("pc_readdb: Invalid job ID %d.\n", job_id);
- continue;
- }
- type = atoi(split[2]);
- if (type < 0 || type > 1) {
- ShowError("pc_readdb: Invalid type %d (must be 0 for base levels, 1 for job levels).\n", type);
- continue;
- }
- maxlv = atoi(split[0]);
- if (maxlv > MAX_LEVEL) {
- ShowWarning("pc_readdb: Specified max level %d for job %d is beyond server's limit (%d).\n ", maxlv, job_id, MAX_LEVEL);
- maxlv = MAX_LEVEL;
+ entry.max_level = maxlv;
+
+ if ((exp_t = libconfig->setting_lookup(t, "Exp")) != NULL && config_setting_is_array(exp_t)) {
+ int j = 0;
+
+ VECTOR_ENSURE(entry.exp, maxlv - 2, 10);
+
+ if (libconfig->setting_length(exp_t) > maxlv - 1) {
+ ShowWarning("pc_read_exp_db_sub_class: Exp table length (%d) for %s exp group '%s' exceeds specified max level %d. Skipping remaining entries...\n", libconfig->setting_length(exp_t), base ? "base" : "job", entry.name, maxlv);
}
- count++;
- job = jobs[0] = pc->class2idx(job_id);
- //We send one less and then one more because the last entry in the exp array should hold 0.
- pc->max_level[job][type] = pc_split_atoui(split[3], pc->exp_table[job][type],',',maxlv-1)+1;
- //Reverse check in case the array has a bunch of trailing zeros... [Skotlex]
- //The reasoning behind the -2 is this... if the max level is 5, then the array
- //should look like this:
- //0: x, 1: x, 2: x: 3: x 4: 0 <- last valid value is at 3.
- while ((i = pc->max_level[job][type]) >= 2 && pc->exp_table[job][type][i-2] <= 0)
- pc->max_level[job][type]--;
- if (pc->max_level[job][type] < maxlv) {
- ShowWarning("pc_readdb: Specified max %d for job %d, but that job's exp table only goes up to level %d.\n", maxlv, job_id, pc->max_level[job][type]);
+
+ while (j < libconfig->setting_length(exp_t) && j <= maxlv - 2)
+ VECTOR_PUSH(entry.exp, libconfig->setting_get_int64_elem(exp_t, j++));
+
+ if (j - 1 < maxlv - 2) {
+ ShowError("pc_read_exp_db_sub_class: Specified max %d for group '%s', but that group's %s exp table only goes up to level %d.\n", maxlv, entry.name, base ? "base" : "job", VECTOR_LENGTH(entry.exp));
ShowInfo("Filling the missing values with the last exp entry.\n");
- //Fill the requested values with the last entry.
- i = (pc->max_level[job][type] <= 2 ? 0: pc->max_level[job][type]-2);
- for (; i+2 < maxlv; i++)
- pc->exp_table[job][type][i] = pc->exp_table[job][type][i-1];
- pc->max_level[job][type] = maxlv;
- }
- //ShowDebug("%s - Class %d: %d\n", type?"Job":"Base", job_id, pc->max_level[job][type]);
- for (i = 1; i < job_count; i++) {
- job_id = jobs[i];
- if (!pc->db_checkid(job_id)) {
- ShowError("pc_readdb: Invalid job ID %d.\n", job_id);
- continue;
- }
- job = pc->class2idx(job_id);
- memcpy(pc->exp_table[job][type], pc->exp_table[jobs[0]][type], sizeof(pc->exp_table[0][0]));
- pc->max_level[job][type] = maxlv;
- //ShowDebug("%s - Class %d: %d\n", type?"Job":"Base", job_id, pc->max_level[job][type]);
+ while (j++ <= maxlv - 2)
+ VECTOR_PUSH(entry.exp, VECTOR_LAST(entry.exp));
}
+ } else {
+ ShowError("pc_read_exp_db_sub_class: Invalid or non-existent 'Exp' field set for %s level entry '%s'. Skipping...\n", entry.name, base ? "base" : "job");
+ return false;
}
- fclose(fp);
- pc->validate_levels();
- ShowStatus("Done reading '"CL_WHITE"%u"CL_RESET"' entries in '"CL_WHITE"%s/"DBPATH"%s"CL_RESET"'.\n",count,map->db_path,"exp.txt");
- count = 0;
+
+ VECTOR_ENSURE(pc->class_exp_groups[base ? CLASS_EXP_TABLE_BASE : CLASS_EXP_TABLE_JOB], 1, 1);
+ VECTOR_PUSH(pc->class_exp_groups[base ? CLASS_EXP_TABLE_BASE : CLASS_EXP_TABLE_JOB], entry);
+ return true;
+}
+
+/**
+ * Description: Helper function to read a root configuration in the exp_group_db.conf file.
+ * @param[in] t pointer to the root config setting
+ * @param[in] base boolean switch determining whether to read either base or job exp.
+ * @return total number of valid entries read from the setting.
+ */
+static int pc_read_exp_db_sub(struct config_setting_t *t, bool base)
+{
+ int i = 0, entry_count = 0;
+ struct config_setting_t *tt = NULL;
+
+ nullpo_ret(t);
+
+ while ((tt = libconfig->setting_get_elem(t, i++)) != NULL) {
+ pc->read_exp_db_sub_class(tt, base);
+ entry_count++;
+ }
+
+ return entry_count;
+}
+
+/**
+ * Description: Initiates reading of the exp_group_db.conf.
+ * @return true success, false on failure.
+ */
+static bool pc_read_exp_db(void)
+{
+ struct config_t exp_db_conf;
+ struct config_setting_t *edb = NULL;
+ int entry_count = 0;
+
+#ifdef RENEWAL
+ const char *config_filename = "db/re/exp_group_db.conf";
+#else
+ const char *config_filename = "db/pre-re/exp_group_db.conf";
+#endif
+
+ if (!libconfig->load_file(&exp_db_conf, config_filename))
+ return false;
+
+ if ((edb = libconfig->setting_lookup(exp_db_conf.root, "base_exp_group_db")) != NULL) {
+ entry_count += pc->read_exp_db_sub(edb, true);
+ } else {
+ ShowError("pc_read_exp_db: Error reading base exp group db in '%s'.\n", config_filename);
+ libconfig->destroy(&exp_db_conf);
+ return false;
+ }
+
+ if ((edb = libconfig->setting_lookup(exp_db_conf.root, "job_exp_group_db")) != NULL) {
+ entry_count += pc->read_exp_db_sub(edb, false);
+ } else {
+ ShowError("pc_read_exp_db: Error reading job exp group db in '%s'.\n", config_filename);
+ libconfig->destroy(&exp_db_conf);
+ return false;
+ }
+
+ libconfig->destroy(&exp_db_conf);
+
+ ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", entry_count, config_filename);
+
+ return true;
+}
+
+/*==========================================
+ * PC DB reading.
+ * exp_group_db.conf - required experience values
+ * skill_tree.txt - skill tree for every class
+ * attr_fix.txt - elemental adjustment table
+ *------------------------------------------*/
+static int pc_readdb(void)
+{
+ int i,j,k;
+ unsigned int count = 0;
+ FILE *fp;
+ char line[24000],*p;
+
+ /**
+ * Read and load into memory, the exp_group_db.conf file.
+ */
+ pc->clear_exp_groups();
+ pc->read_exp_db();
+
// Reset and read skilltree
pc->clear_skill_tree();
pc->read_skill_tree();
@@ -11332,22 +11734,37 @@ int pc_readdb(void) {
return 0;
}
-void pc_validate_levels(void) {
+static bool pc_job_is_dummy(int job)
+{
+ if (job == JOB_KNIGHT2 || job == JOB_CRUSADER2
+ || job == JOB_WEDDING || job == JOB_XMAS || job == JOB_SUMMER
+ || job == JOB_LORD_KNIGHT2 || job == JOB_PALADIN2
+ || job == JOB_BABY_KNIGHT2 || job == JOB_BABY_CRUSADER2
+ || job == JOB_STAR_GLADIATOR2
+ || (job >= JOB_RUNE_KNIGHT2 && job <= JOB_MECHANIC_T2)
+ || (job >= JOB_BABY_RUNE2 && job <= JOB_BABY_MECHANIC2))
+ return true;
+ return false;
+}
+
+static void pc_validate_levels(void)
+{
int i;
int j;
for (i = 0; i < JOB_MAX; i++) {
if (!pc->db_checkid(i)) continue;
- if (i == JOB_WEDDING || i == JOB_XMAS || i == JOB_SUMMER)
+ if (pc->job_is_dummy(i))
continue; //Classes that do not need exp tables.
j = pc->class2idx(i);
- if (pc->max_level[j][0] == 0)
- ShowWarning("Class %s (%d) does not has a base exp table.\n", pc->job_name(i), i);
- if (pc->max_level[j][1] == 0)
- ShowWarning("Class %s (%d) does not has a job exp table.\n", pc->job_name(i), i);
+ if (pc->dbs->class_exp_table[j][CLASS_EXP_TABLE_BASE] == NULL)
+ ShowWarning("Class %s (%d - %d) does not have a base exp table.\n", pc->job_name(i), i, j);
+ if (pc->dbs->class_exp_table[j][CLASS_EXP_TABLE_JOB] == NULL)
+ ShowWarning("Class %s (%d - %d) does not have a job exp table.\n", pc->job_name(i), i, j);
}
}
-void pc_itemcd_do(struct map_session_data *sd, bool load) {
+static void pc_itemcd_do(struct map_session_data *sd, bool load)
+{
int i,cursor = 0;
struct item_cd* cd = NULL;
@@ -11382,7 +11799,8 @@ void pc_itemcd_do(struct map_session_data *sd, bool load) {
return;
}
-void pc_bank_deposit(struct map_session_data *sd, int money) {
+static void pc_bank_deposit(struct map_session_data *sd, int money)
+{
unsigned int limit_check;
nullpo_retv(sd);
@@ -11405,7 +11823,8 @@ void pc_bank_deposit(struct map_session_data *sd, int money) {
clif->bank_deposit(sd,BDA_SUCCESS);
}
}
-void pc_bank_withdraw(struct map_session_data *sd, int money) {
+static void pc_bank_withdraw(struct map_session_data *sd, int money)
+{
unsigned int limit_check;
nullpo_retv(sd);
@@ -11432,7 +11851,8 @@ void pc_bank_withdraw(struct map_session_data *sd, int money) {
}
}
/* status change data arrived from char-server */
-void pc_scdata_received(struct map_session_data *sd) {
+static void pc_scdata_received(struct map_session_data *sd)
+{
nullpo_retv(sd);
pc->inventory_rentals(sd);
clif->show_modifiers(sd);
@@ -11452,7 +11872,8 @@ void pc_scdata_received(struct map_session_data *sd) {
pc->autotrade_start(sd);
}
}
-int pc_expiration_timer(int tid, int64 tick, int id, intptr_t data) {
+static int pc_expiration_timer(int tid, int64 tick, int id, intptr_t data)
+{
struct map_session_data *sd = map->id2sd(id);
if( !sd ) return 0;
@@ -11468,7 +11889,8 @@ int pc_expiration_timer(int tid, int64 tick, int id, intptr_t data) {
}
/* This timer exists only when a character with an expire timer > 24h is online */
/* It loops through online players once an hour to check whether a new < 24h is available */
-int pc_global_expiration_timer(int tid, int64 tick, int id, intptr_t data) {
+static int pc_global_expiration_timer(int tid, int64 tick, int id, intptr_t data)
+{
struct s_mapiterator* iter;
struct map_session_data* sd;
@@ -11481,7 +11903,8 @@ int pc_global_expiration_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
-void pc_expire_check(struct map_session_data *sd) {
+static void pc_expire_check(struct map_session_data *sd)
+{
nullpo_retv(sd);
/* ongoing timer */
if( sd->expiration_tid != INVALID_TIMER )
@@ -11502,7 +11925,7 @@ void pc_expire_check(struct map_session_data *sd) {
/**
* Loads autotraders
***/
-void pc_autotrade_load(void)
+static void pc_autotrade_load(void)
{
char *data;
@@ -11535,7 +11958,8 @@ void pc_autotrade_load(void)
/**
* Loads vending data and sets it up, is triggered when char server data that pc_autotrade_load requested arrives
**/
-void pc_autotrade_start(struct map_session_data *sd) {
+static void pc_autotrade_start(struct map_session_data *sd)
+{
unsigned int count = 0;
int i;
char *data;
@@ -11582,7 +12006,8 @@ void pc_autotrade_start(struct map_session_data *sd) {
/**
* Perform a autotrade action
**/
-void pc_autotrade_update(struct map_session_data *sd, enum e_pc_autotrade_update_action action) {
+static void pc_autotrade_update(struct map_session_data *sd, enum e_pc_autotrade_update_action action)
+{
int i;
nullpo_retv(sd);
@@ -11632,7 +12057,8 @@ void pc_autotrade_update(struct map_session_data *sd, enum e_pc_autotrade_update
/**
* Handles characters upon @autotrade usage
**/
-void pc_autotrade_prepare(struct map_session_data *sd) {
+static void pc_autotrade_prepare(struct map_session_data *sd)
+{
struct autotrade_vending *data;
int i, cursor = 0;
int account_id, char_id;
@@ -11682,7 +12108,8 @@ void pc_autotrade_prepare(struct map_session_data *sd) {
/**
* Prepares autotrade data from pc->at_db from a player that has already returned from char server
**/
-void pc_autotrade_populate(struct map_session_data *sd) {
+static void pc_autotrade_populate(struct map_session_data *sd)
+{
struct autotrade_vending *data;
int i, j, k, cursor = 0;
@@ -11726,7 +12153,7 @@ void pc_autotrade_populate(struct map_session_data *sd) {
/**
* @see DBApply
*/
-int pc_autotrade_final(union DBKey key, struct DBData *data, va_list ap)
+static int pc_autotrade_final(union DBKey key, struct DBData *data, va_list ap)
{
struct autotrade_vending* at_v = DB->data2ptr(data);
nullpo_ret(at_v);
@@ -11734,7 +12161,7 @@ int pc_autotrade_final(union DBKey key, struct DBData *data, va_list ap)
return 0;
}
-void pc_update_idle_time(struct map_session_data* sd, enum e_battle_config_idletime type)
+static void pc_update_idle_time(struct map_session_data *sd, enum e_battle_config_idletime type)
{
nullpo_retv(sd);
if (battle_config.idletime_criteria&type)
@@ -11743,7 +12170,7 @@ void pc_update_idle_time(struct map_session_data* sd, enum e_battle_config_idlet
//Checks if the given class value corresponds to a player class. [Skotlex]
//JOB_NOVICE isn't checked for class is supposed to be unsigned
-bool pc_db_checkid(int class)
+static bool pc_db_checkid(int class)
{
return class < JOB_MAX_BASIC
|| (class >= JOB_NOVICE_HIGH && class <= JOB_DARK_COLLECTOR )
@@ -11760,7 +12187,7 @@ bool pc_db_checkid(int class)
* @param sd map_session_data of Player
* @return index of magnifer, INDEX_NOT_FOUND if it is not found
*/
-int pc_have_magnifier(struct map_session_data *sd)
+static int pc_have_magnifier(struct map_session_data *sd)
{
int n;
n = pc->search_inventory(sd, ITEMID_SPECTACLES);
@@ -11775,7 +12202,8 @@ int pc_have_magnifier(struct map_session_data *sd)
* @param level Required Level of Novice Skill
* @return bool true, if requirement is satisfied
*/
-bool pc_check_basicskill(struct map_session_data *sd, int level) {
+static bool pc_check_basicskill(struct map_session_data *sd, int level)
+{
if (pc->checkskill(sd, NV_BASIC) >= level || pc->checkskill(sd, SU_BASIC_SKILL))
return true;
return false;
@@ -11789,7 +12217,7 @@ bool pc_check_basicskill(struct map_session_data *sd, int level) {
* @param message The message text.
* @return Whether the message is a valid chat message.
*/
-bool pc_process_chat_message(struct map_session_data *sd, const char *message)
+static bool pc_process_chat_message(struct map_session_data *sd, const char *message)
{
nullpo_retr(false, sd);
if (atcommand->exec(sd->fd, sd, message, true)) {
@@ -11821,9 +12249,9 @@ bool pc_process_chat_message(struct map_session_data *sd, const char *message)
* @param sd The sender character.
* @param message The message text.
*/
-void pc_check_supernovice_call(struct map_session_data *sd, const char *message)
+static void pc_check_supernovice_call(struct map_session_data *sd, const char *message)
{
- unsigned int next = pc->nextbaseexp(sd);
+ uint64 next = pc->nextbaseexp(sd);
int percent = 0;
nullpo_retv(sd);
@@ -11865,7 +12293,73 @@ void pc_check_supernovice_call(struct map_session_data *sd, const char *message)
}
}
-void do_final_pc(void) {
+static void pc_update_job_and_level(struct map_session_data *sd)
+{
+ nullpo_retv(sd);
+
+ if (sd->status.party_id) {
+ struct party_data *p;
+ int i;
+
+ if ((p = party->search(sd->status.party_id)) != NULL) {
+ ARR_FIND(0, MAX_PARTY, i, p->party.member[i].char_id == sd->status.char_id);
+ if (i < MAX_PARTY) {
+ p->party.member[i].lv = sd->status.base_level;
+ clif->party_job_and_level(sd);
+ }
+ }
+ }
+}
+
+static void pc_clear_exp_groups(void)
+{
+ int i, k, size;
+ for (k = 0; k < 2; k++) {
+ size = VECTOR_LENGTH(pc->class_exp_groups[k]);
+
+ for (i = 0; i < size; i++)
+ VECTOR_CLEAR(VECTOR_INDEX(pc->class_exp_groups[k], i).exp);
+ VECTOR_CLEAR(pc->class_exp_groups[k]);
+ }
+}
+
+static void pc_init_exp_groups(void)
+{
+ int i;
+ for (i = 0; i < 2; i++) {
+ VECTOR_INIT(pc->class_exp_groups[i]);
+ }
+}
+
+static bool pc_has_second_costume(struct map_session_data *sd)
+{
+ nullpo_retr(false, sd);
+
+ if ((sd->job & JOBL_THIRD) != 0)
+ return true;
+ return false;
+}
+
+static bool pc_expandInventory(struct map_session_data *sd, int adjustSize)
+{
+ nullpo_retr(false, sd);
+ const int invSize = sd->status.inventorySize;
+ if (adjustSize > MAX_INVENTORY || invSize + adjustSize <= FIXED_INVENTORY_SIZE || invSize + adjustSize > MAX_INVENTORY) {
+ clif->inventoryExpandResult(sd, EXPAND_INVENTORY_RESULT_MAX_SIZE);
+ return false;
+ }
+ if (pc_isdead(sd) || sd->state.vending || sd->state.buyingstore || sd->chat_id != 0 || sd->state.trading || sd->state.storage_flag || sd->state.prevend) {
+ clif->inventoryExpandResult(sd, EXPAND_INVENTORY_RESULT_OTHER_WORK);
+ return false;
+ }
+ sd->status.inventorySize += adjustSize;
+ clif->inventoryExpansionInfo(sd);
+ return true;
+}
+
+static void do_final_pc(void)
+{
+
db_destroy(pc->itemcd_db);
pc->at_db->destroy(pc->at_db,pc->autotrade_final);
@@ -11873,6 +12367,8 @@ void do_final_pc(void) {
pc->clear_skill_tree();
+ pc->clear_exp_groups();
+
ers_destroy(pc->sc_display_ers);
ers_destroy(pc->num_reg_ers);
ers_destroy(pc->str_reg_ers);
@@ -11880,13 +12376,15 @@ void do_final_pc(void) {
return;
}
-void do_init_pc(bool minimal) {
+static void do_init_pc(bool minimal)
+{
if (minimal)
return;
pc->itemcd_db = idb_alloc(DB_OPT_RELEASE_DATA);
pc->at_db = idb_alloc(DB_OPT_RELEASE_DATA);
+ pc->init_exp_groups();
pc->readdb();
timer->add_func_list(pc->invincible_timer, "pc_invincible_timer");
@@ -11927,12 +12425,14 @@ void do_init_pc(bool minimal) {
ers_chunk_size(pc->num_reg_ers, 300);
ers_chunk_size(pc->str_reg_ers, 50);
}
+
/*=====================================
-* Default Functions : pc.h
-* Generated by HerculesInterfaceMaker
-* created by Susu
-*-------------------------------------*/
-void pc_defaults(void) {
+ * Default Functions : pc.h
+ * Generated by HerculesInterfaceMaker
+ * created by Susu
+ *-------------------------------------*/
+void pc_defaults(void)
+{
const struct sg_data sg_info[MAX_PC_FEELHATE] = {
{ SG_SUN_ANGER, SG_SUN_BLESS, SG_SUN_COMFORT, "PC_FEEL_SUN", "PC_HATE_MOB_SUN", is_day_of_sun },
{ SG_MOON_ANGER, SG_MOON_BLESS, SG_MOON_COMFORT, "PC_FEEL_MOON", "PC_HATE_MOB_MOON", is_day_of_moon },
@@ -11941,6 +12441,7 @@ void pc_defaults(void) {
unsigned int equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARMENT,EQP_HEAD_LOW,EQP_HEAD_MID,EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_GARMENT,EQP_AMMO, EQP_SHADOW_ARMOR, EQP_SHADOW_WEAPON, EQP_SHADOW_SHIELD, EQP_SHADOW_SHOES, EQP_SHADOW_ACC_R, EQP_SHADOW_ACC_L };
pc = &pc_s;
+ pc->dbs = &exptables;
/* vars */
pc->at_db = NULL;
@@ -11986,6 +12487,7 @@ void pc_defaults(void) {
pc->isequip = pc_isequip;
pc->equippoint = pc_equippoint;
+ pc->item_equippoint = pc_item_equippoint;
pc->setinventorydata = pc_setinventorydata;
pc->checkskill = pc_checkskill;
@@ -11994,6 +12496,8 @@ void pc_defaults(void) {
pc->checkequip = pc_checkequip;
pc->calc_skilltree = pc_calc_skilltree;
+ pc->calc_skilltree_bonus = pc_calc_skilltree_bonus;
+ pc->calc_skilltree_clear = pc_calc_skilltree_clear;
pc->calc_skilltree_normalize_job = pc_calc_skilltree_normalize_job;
pc->clean_skilltree = pc_clean_skilltree;
@@ -12056,6 +12560,7 @@ void pc_defaults(void) {
pc->maxbaselv = pc_maxbaselv;
pc->maxjoblv = pc_maxjoblv;
pc->checkbaselevelup = pc_checkbaselevelup;
+ pc->checkbaselevelup_sc = pc_checkbaselevelup_sc;
pc->checkjoblevelup = pc_checkjoblevelup;
pc->gainexp = pc_gainexp;
pc->nextbaseexp = pc_nextbaseexp;
@@ -12072,6 +12577,7 @@ void pc_defaults(void) {
pc->resetlvl = pc_resetlvl;
pc->resetstate = pc_resetstate;
pc->resetskill = pc_resetskill;
+ pc->resetskill_job = pc_resetskill_job;
pc->resetfeel = pc_resetfeel;
pc->resethate = pc_resethate;
pc->equipitem = pc_equipitem;
@@ -12146,7 +12652,9 @@ void pc_defaults(void) {
pc->delinvincibletimer = pc_delinvincibletimer;
pc->addspiritball = pc_addspiritball;
+ pc->addspiritball_sub = pc_addspiritball_sub;
pc->delspiritball = pc_delspiritball;
+ pc->delspiritball_sub = pc_delspiritball_sub;
pc->addfame = pc_addfame;
pc->fame_rank = pc_fame_rank;
pc->famelist_type = pc_famelist_type;
@@ -12154,6 +12662,9 @@ void pc_defaults(void) {
pc->getmaxspiritball = pc_getmaxspiritball;
pc->readdb = pc_readdb;
+ pc->read_exp_db = pc_read_exp_db;
+ pc->read_exp_db_sub = pc_read_exp_db_sub;
+ pc->read_exp_db_sub_class = pc_read_exp_db_sub_class;
pc->map_day_timer = map_day_timer; // by [yor]
pc->map_night_timer = map_night_timer; // by [yor]
// Rental System
@@ -12200,12 +12711,17 @@ void pc_defaults(void) {
pc->autosave = pc_autosave;
pc->follow_timer = pc_follow_timer;
pc->read_skill_tree = pc_read_skill_tree;
+ pc->read_skill_job_skip = pc_read_skill_job_skip;
pc->clear_skill_tree = pc_clear_skill_tree;
pc->isUseitem = pc_isUseitem;
pc->show_steal = pc_show_steal;
pc->checkcombo = pc_checkcombo;
pc->calcweapontype = pc_calcweapontype;
pc->removecombo = pc_removecombo;
+ pc->update_job_and_level = pc_update_job_and_level;
+ pc->clear_exp_groups = pc_clear_exp_groups;
+ pc->init_exp_groups = pc_init_exp_groups;
+ pc->job_is_dummy = pc_job_is_dummy;
pc->bank_withdraw = pc_bank_withdraw;
pc->bank_deposit = pc_bank_deposit;
@@ -12240,4 +12756,8 @@ void pc_defaults(void) {
pc->have_magnifier = pc_have_magnifier;
pc->check_basicskill = pc_check_basicskill;
+
+ pc->isDeathPenaltyJob = pc_isDeathPenaltyJob;
+ pc->has_second_costume = pc_has_second_costume;
+ pc->expandInventory = pc_expandInventory;
}