summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--[-rwxr-xr-x]src/common/HPM.c0
-rw-r--r--src/map/clif.c20
-rw-r--r--src/map/pc.h1
-rw-r--r--src/map/script.c54
-rw-r--r--src/map/script.h3
-rw-r--r--src/map/skill.c11
-rw-r--r--src/map/status.c4
-rw-r--r--src/map/unit.c2
-rw-r--r--src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking.HookingPoints.inc1
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Hooks.inc25
11 files changed, 94 insertions, 31 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c
index a25a17782..a25a17782 100755..100644
--- a/src/common/HPM.c
+++ b/src/common/HPM.c
diff --git a/src/map/clif.c b/src/map/clif.c
index c61a72597..1c5f7e003 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -99,17 +99,16 @@ static inline void WBUFPOS2(uint8* p, unsigned short pos, short x0, short y0, sh
p[5] = (uint8)((sx0<<4) | (sy0&0x0f));
}
-
+#if 0 // Currently unused
static inline void WFIFOPOS(int fd, unsigned short pos, short x, short y, unsigned char dir) {
WBUFPOS(WFIFOP(fd,pos), 0, x, y, dir);
}
-
+#endif // 0
static inline void WFIFOPOS2(int fd, unsigned short pos, short x0, short y0, short x1, short y1, unsigned char sx0, unsigned char sy0) {
WBUFPOS2(WFIFOP(fd,pos), 0, x0, y0, x1, y1, sx0, sy0);
}
-
static inline void RBUFPOS(const uint8* p, unsigned short pos, short* x, short* y, unsigned char* dir) {
p += pos;
@@ -126,7 +125,11 @@ static inline void RBUFPOS(const uint8* p, unsigned short pos, short* x, short*
}
}
+static inline void RFIFOPOS(int fd, unsigned short pos, short* x, short* y, unsigned char* dir) {
+ RBUFPOS(RFIFOP(fd,pos), 0, x, y, dir);
+}
+#if 0 // currently unused
static inline void RBUFPOS2(const uint8* p, unsigned short pos, short* x0, short* y0, short* x1, short* y1, unsigned char* sx0, unsigned char* sy0) {
p += pos;
@@ -154,19 +157,12 @@ static inline void RBUFPOS2(const uint8* p, unsigned short pos, short* x0, short
sy0[0] = ( p[5] & 0x0f ) >> 0;
}
}
-
-
-static inline void RFIFOPOS(int fd, unsigned short pos, short* x, short* y, unsigned char* dir) {
- RBUFPOS(RFIFOP(fd,pos), 0, x, y, dir);
-}
-
-
static inline void RFIFOPOS2(int fd, unsigned short pos, short* x0, short* y0, short* x1, short* y1, unsigned char* sx0, unsigned char* sy0) {
RBUFPOS2(WFIFOP(fd,pos), 0, x0, y0, x1, y1, sx0, sy0);
}
+#endif // 0
-
-//To idenfity disguised characters.
+//To identify disguised characters.
static inline bool disguised(struct block_list* bl) {
return (bool)( bl->type == BL_PC && ((TBL_PC*)bl)->disguise != -1 );
}
diff --git a/src/map/pc.h b/src/map/pc.h
index 66915492a..cc95b07e1 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -187,6 +187,7 @@ struct map_session_data {
unsigned int hpmeter_visible : 1;
unsigned int itemcheck : 1;
unsigned int standalone : 1;/* [Ind/Hercules <3] */
+ unsigned int loggingout : 1;
} state;
struct {
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
diff --git a/src/map/script.c b/src/map/script.c
index 3aba1b031..c2d9b2278 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -3130,8 +3130,7 @@ struct script_data* push_copy(struct script_stack* stack, int pos) {
/// Removes the values in indexes [start,end[ from the stack.
/// Adjusts all stack pointers.
-void pop_stack(struct script_state* st, int start, int end)
-{
+void pop_stack(struct script_state* st, int start, int end) {
struct script_stack* stack = st->stack;
struct script_data* data;
int i;
@@ -3153,6 +3152,10 @@ void pop_stack(struct script_state* st, int start, int end)
{
struct script_retinfo* ri = data->u.ri;
if( ri->scope.vars ) {
+ // Note: This is necessary evern if we're also doing it in run_func
+ // (in the RETFUNC block) because not all functions return. If a
+ // function (or a sub) has an 'end' or a 'close', it'll reach this
+ // block with its scope vars still to be freed.
script->free_vars(ri->scope.vars);
ri->scope.vars = NULL;
}
@@ -3224,6 +3227,8 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
st = ers_alloc(script->st_ers, struct script_state);
st->stack = ers_alloc(script->stack_ers, struct script_stack);
+ st->pending_refs = NULL;
+ st->pending_ref_count = 0;
st->stack->sp = 0;
st->stack->sp_max = 64;
CREATE(st->stack->stack_data, struct script_data, st->stack->sp_max);
@@ -3280,6 +3285,12 @@ void script_free_state(struct script_state* st) {
}
}
st->pos = -1;
+ if (st->pending_ref_count > 0) {
+ while (st->pending_ref_count > 0)
+ aFree(st->pending_refs[--st->pending_ref_count]);
+ aFree(st->pending_refs);
+ st->pending_refs = NULL;
+ }
idb_remove(script->st_db, st->id);
ers_free(script->st_ers, st);
if( --script->active_scripts == 0 ) {
@@ -3288,6 +3299,19 @@ void script_free_state(struct script_state* st) {
}
}
+/**
+ * Adds a pending reference entry to the current script.
+ *
+ * @see struct script_state::pending_refs
+ *
+ * @param st[in] Script state.
+ * @param ref[in] Reference to be added.
+ */
+void script_add_pending_ref(struct script_state *st, struct reg_db *ref) {
+ RECREATE(st->pending_refs, struct reg_db*, ++st->pending_ref_count);
+ st->pending_refs[st->pending_ref_count-1] = ref;
+}
+
//
// Main execution unit
//
@@ -4883,7 +4907,10 @@ BUILDIN(callfunc)
st->stack->defsp = st->stack->sp;
st->state = GOTO;
st->stack->scope.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
- st->stack->scope.arrays = i64db_alloc(DB_OPT_BASE);
+ st->stack->scope.arrays = idb_alloc(DB_OPT_BASE);
+
+ if( !st->script->local.vars )
+ st->script->local.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
return true;
}
@@ -4934,7 +4961,7 @@ BUILDIN(callsub)
st->stack->defsp = st->stack->sp;
st->state = GOTO;
st->stack->scope.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
- st->stack->scope.arrays = i64db_alloc(DB_OPT_BASE);
+ st->stack->scope.arrays = idb_alloc(DB_OPT_BASE);
return true;
}
@@ -4977,30 +5004,30 @@ BUILDIN(getarg)
///
/// return;
/// return <value>;
-BUILDIN(return)
-{
+BUILDIN(return) {
if( script_hasdata(st,2) )
{// return value
struct script_data* data;
script_pushcopy(st, 2);
data = script_getdatatop(st, -1);
- if( data_isreference(data) )
- {
+ if( data_isreference(data) ) {
const char* name = reference_getname(data);
- if( name[0] == '.' && name[1] == '@' )
- {// scope variable
+ if( name[0] == '.' && name[1] == '@' ) {
+ // scope variable
if( !data->ref || data->ref->vars == st->stack->scope.vars )
script->get_val(st, data);// current scope, convert to value
if( data->ref && data->ref->vars == st->stack->stack_data[st->stack->defsp-1].u.ri->scope.vars )
data->ref = NULL; // Reference to the parent scope, remove reference pointer
- }
- else if( name[0] == '.' && !data->ref )
- {// script variable, link to current script
+ } else if( name[0] == '.' && !data->ref ) {
+ // script variable without a reference set, link to current script
data->ref = (struct reg_db *)aCalloc(sizeof(struct reg_db), 1);
+ script->add_pending_ref(st, data->ref);
data->ref->vars = st->script->local.vars;
if( !st->script->local.arrays )
st->script->local.arrays = idb_alloc(DB_OPT_BASE);
data->ref->arrays = st->script->local.arrays;
+ } else if ( name[0] == '.' /* && data->ref != NULL */ ) {
+ data->ref = NULL; // Reference to the parent scope's script, remove reference pointer.
}
}
}
@@ -19265,6 +19292,7 @@ void script_defaults(void) {
script->free_vars = script_free_vars;
script->alloc_state = script_alloc_state;
script->free_state = script_free_state;
+ script->add_pending_ref = script_add_pending_ref;
script->run_autobonus = script_run_autobonus;
script->cleararray_pc = script_cleararray_pc;
script->setarray_pc = script_setarray_pc;
diff --git a/src/map/script.h b/src/map/script.h
index ff947bf79..73ba7303e 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -401,6 +401,8 @@ struct hQueueIterator {
struct script_state {
struct script_stack* stack;
+ struct reg_db **pending_refs; ///< References to .vars returned by sub-functions, pending deletion.
+ int pending_ref_count; ///< Amount of pending_refs currently stored.
int start,end;
int pos;
enum e_script_state state;
@@ -589,6 +591,7 @@ struct script_interface {
void (*free_vars) (struct DBMap *var_storage);
struct script_state* (*alloc_state) (struct script_code* rootscript, int pos, int rid, int oid);
void (*free_state) (struct script_state* st);
+ void (*add_pending_ref) (struct script_state *st, struct reg_db *ref);
void (*run_autobonus) (const char *autobonus,int id, int pos);
void (*cleararray_pc) (struct map_session_data* sd, const char* varname, void* value);
void (*setarray_pc) (struct map_session_data* sd, const char* varname, uint32 idx, void* value, int* refcache);
diff --git a/src/map/skill.c b/src/map/skill.c
index 72b59aab7..e854b5fe9 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -585,7 +585,7 @@ int skillnotok_hom(uint16 skill_id, struct homun_data *hd)
return 1;
switch(skill_id){
case MH_LIGHT_OF_REGENE:
- if(hd->homunculus.intimacy <= 750) //if not cordial
+ if(hd->homunculus.intimacy <= 75000) //if not cordial
return 1;
break;
case MH_OVERED_BOOST:
@@ -8151,7 +8151,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
case AB_LAUDAAGNUS:
- if( flag&1 || sd == NULL ) {
+ if( (flag&1 || sd == NULL) || !sd->status.party_id) {
if( tsc && (tsc->data[SC_FREEZE] || tsc->data[SC_STONE] || tsc->data[SC_BLIND] ||
tsc->data[SC_BURNING] || tsc->data[SC_FROSTMISTY] || tsc->data[SC_COLD])) {
// Success Chance: (40 + 10 * Skill Level) %
@@ -8171,8 +8171,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
case AB_LAUDARAMUS:
- if( flag&1 || sd == NULL ) {
- if( tsc && (tsc->data[SC_SLEEP] || tsc->data[SC_STUN] || tsc->data[SC_MANDRAGORA] || tsc->data[SC_SILENCE] || tsc->data[SC_DEEP_SLEEP]) ){
+ if( (flag&1 || sd == NULL) || !sd->status.party_id ) {
+ if( tsc && (tsc->data[SC_SLEEP] || tsc->data[SC_STUN] || tsc->data[SC_MANDRAGORA] ||
+ tsc->data[SC_SILENCE] || tsc->data[SC_DEEP_SLEEP]) ){
// Success Chance: (40 + 10 * Skill Level) %
if( rnd()%100 > 40+10*skill_lv ) break;
status_change_end(bl, SC_SLEEP, INVALID_TIMER);
@@ -9449,7 +9450,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case MH_LIGHT_OF_REGENE:
if(hd) {
- hd->homunculus.intimacy = 251; //change to neutral (can't be cast if < 750)
+ hd->homunculus.intimacy = 25100; //change to neutral (can't be cast if < 750)
if(sd) clif->send_homdata(sd, SP_INTIMATE, hd->homunculus.intimacy); //refresh intimacy info
}
//don't break need to start status and start block timer
diff --git a/src/map/status.c b/src/map/status.c
index 5dcf35198..4a81fcb05 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -1985,7 +1985,9 @@ unsigned short status_base_atk(const struct block_list *bl, const struct status_
return cap_value(str, 0, USHRT_MAX);
}
+#ifndef RENEWAL
static inline unsigned short status_base_matk_min(const struct status_data *st){ return st->int_+(st->int_/7)*(st->int_/7); }
+#endif // not RENEWAL
static inline unsigned short status_base_matk_max(const struct status_data *st){ return st->int_+(st->int_/5)*(st->int_/5); }
unsigned short status_base_matk(const struct status_data *st, int level) {
@@ -9605,7 +9607,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if (sce->timer != tid && tid != INVALID_TIMER)
return 0;
- if( sd && sce->timer == INVALID_TIMER )
+ if( sd && sce->timer == INVALID_TIMER && !sd->state.loggingout )
chrif->del_scdata_single(sd->status.account_id,sd->status.char_id,type);
if (tid == INVALID_TIMER) {
diff --git a/src/map/unit.c b/src/map/unit.c
index 47cf07ef6..5dd63879f 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -2330,6 +2330,8 @@ int unit_free(struct block_list *bl, clr_type clrtype) {
int i;
unsigned int k;
+ sd->state.loggingout = 1;
+
if( status->isdead(bl) )
pc->setrestartvalue(sd,2);
diff --git a/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
index fa9b04d39..4f37743f6 100644
--- a/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
@@ -4081,6 +4081,8 @@ struct {
struct HPMHookPoint *HP_script_alloc_state_post;
struct HPMHookPoint *HP_script_free_state_pre;
struct HPMHookPoint *HP_script_free_state_post;
+ struct HPMHookPoint *HP_script_add_pending_ref_pre;
+ struct HPMHookPoint *HP_script_add_pending_ref_post;
struct HPMHookPoint *HP_script_run_autobonus_pre;
struct HPMHookPoint *HP_script_run_autobonus_post;
struct HPMHookPoint *HP_script_cleararray_pc_pre;
@@ -9112,6 +9114,8 @@ struct {
int HP_script_alloc_state_post;
int HP_script_free_state_pre;
int HP_script_free_state_post;
+ int HP_script_add_pending_ref_pre;
+ int HP_script_add_pending_ref_post;
int HP_script_run_autobonus_pre;
int HP_script_run_autobonus_post;
int HP_script_cleararray_pc_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
index b90bb6a88..dd8c603d3 100644
--- a/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
@@ -2074,6 +2074,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(script->free_vars, HP_script_free_vars) },
{ HP_POP(script->alloc_state, HP_script_alloc_state) },
{ HP_POP(script->free_state, HP_script_free_state) },
+ { HP_POP(script->add_pending_ref, HP_script_add_pending_ref) },
{ HP_POP(script->run_autobonus, HP_script_run_autobonus) },
{ HP_POP(script->cleararray_pc, HP_script_cleararray_pc) },
{ HP_POP(script->setarray_pc, HP_script_setarray_pc) },
diff --git a/src/plugins/HPMHooking/HPMHooking.Hooks.inc b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
index 49d276edb..78987f81a 100644
--- a/src/plugins/HPMHooking/HPMHooking.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
@@ -52614,6 +52614,31 @@ void HP_script_free_state(struct script_state *st) {
}
return;
}
+void HP_script_add_pending_ref(struct script_state *st, struct reg_db *ref) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_script_add_pending_ref_pre ) {
+ void (*preHookFunc) (struct script_state *st, struct reg_db *ref);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_add_pending_ref_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_script_add_pending_ref_pre[hIndex].func;
+ preHookFunc(st, ref);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.script.add_pending_ref(st, ref);
+ }
+ if( HPMHooks.count.HP_script_add_pending_ref_post ) {
+ void (*postHookFunc) (struct script_state *st, struct reg_db *ref);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_script_add_pending_ref_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_script_add_pending_ref_post[hIndex].func;
+ postHookFunc(st, ref);
+ }
+ }
+ return;
+}
void HP_script_run_autobonus(const char *autobonus, int id, int pos) {
int hIndex = 0;
if( HPMHooks.count.HP_script_run_autobonus_pre ) {