From 51c422cf7cc9e6046886ec89cb9cec07c9cb0d3e Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Mon, 22 Feb 2016 22:34:08 +0700 Subject: [PATCH 001/319] Corrected trap invisibilty behavior. * Changed `traps_setting` config values. * 0 = Always visible (default) * 1 = Enable invisibility in versus maps (GVG/PVP/BG) * 2 = Enable invisibility in all maps * Added skill unit flag `UF_HIDDEN_TRAP 0x20000` for trap invisibilty. NOTES: * Invisible traps are always visible for the trapper and trapper's partymates. * If the trap is invisible, it always be hid immediately (except the people above). * Revealed hidden traps, are always visible by everyone. * Currently, only `HT_DETECTING` that can reveal the hidden traps (hardcoded). TODO: Sight, Ruwach, and Improve Concentration also able to reveal hidden traps. Signed-off-by: Cydh Ramdh --- conf/battle/skill.conf | 10 ++--- db/pre-re/skill_unit_db.txt | 1 + db/re/skill_unit_db.txt | 17 +++---- src/map/battle.c | 2 +- src/map/clif.c | 33 ++++---------- src/map/clif.h | 2 +- src/map/skill.c | 90 ++++++++++++++++++++++++++++++++++--- src/map/skill.h | 11 ++++- 8 files changed, 118 insertions(+), 48 deletions(-) diff --git a/conf/battle/skill.conf b/conf/battle/skill.conf index 71998453f3..5ecf557645 100644 --- a/conf/battle/skill.conf +++ b/conf/battle/skill.conf @@ -119,11 +119,11 @@ skill_nofootset: 1 // Default on official servers: 1 (for players) gvg_traps_target_all: 1 -// Hunter's traps visibility setting: -// 1: (Official) Many of Hunter's traps are invisible at all times. -// But any player who see the Hunter laying the trap will be able to see the trap until they move out of sight of it. -// Although, invisible traps can be revealed through Hunter's Detecting skill. -traps_setting: 1 +// Traps visibility setting (trap with UF_HIDDEN_TRAP flag): +// 0 = Always visible +// 1 = Enable invisibility in versus maps (GVG/PVP/BG) +// 2 = Enable invisibility in all maps +traps_setting: 0 // Restrictions applied to the Alchemist's Summon Flora skill (add as necessary) // 1: Enable players to damage the floras outside of versus grounds. diff --git a/db/pre-re/skill_unit_db.txt b/db/pre-re/skill_unit_db.txt index 6c63760ce1..4649b551aa 100644 --- a/db/pre-re/skill_unit_db.txt +++ b/db/pre-re/skill_unit_db.txt @@ -23,6 +23,7 @@ // 0x04000(UF_REM_CRAZYWEED) Removed if be overlapped by GN_CRAZYWEED // 0x08000(UF_REM_FIRERAIN) Removed if be overlapped by RL_FIRE_RAIN // 0x10000(UF_KNOCKBACK_GROUP) Knock back a whole skill group (by default, skill unit is knocked back each unit) +// 0x20000(UF_HIDDEN_TRAP) Hidden trap, see 'traps_setting' skill config to enable this flag // Example: 0x006 = 0x002+0x004 -> Cannot be stacked nor cast near targets // // Notes: diff --git a/db/re/skill_unit_db.txt b/db/re/skill_unit_db.txt index 0bee4b7ccf..c224fc8ad1 100644 --- a/db/re/skill_unit_db.txt +++ b/db/re/skill_unit_db.txt @@ -23,6 +23,7 @@ // 0x04000(UF_REM_CRAZYWEED) Removed if be overlapped by GN_CRAZYWEED // 0x08000(UF_REM_FIRERAIN) Removed if be overlapped by RL_FIRE_RAIN // 0x10000(UF_KNOCKBACK_GROUP) Knock back a whole skill group (by default, skill unit is knocked back each unit) +// 0x20000(UF_HIDDEN_TRAP) Hidden trap, see 'traps_setting' skill config to enable this flag // Example: 0x006 = 0x002+0x004 -> Cannot be stacked nor cast near targets // // Notes: @@ -47,16 +48,16 @@ 89,0x86, , 4, 1, 450,enemy, 0x018 //WZ_STORMGUST 91,0x86, , 2, 0,1000,enemy, 0x010 //WZ_HEAVENDRIVE 92,0x8e, , 2, 0, -1,enemy, 0x8010 //WZ_QUAGMIRE -115,0x90, , 0, 1,1000,enemy, 0x8006 //HT_SKIDTRAP -116,0x93, , 0, 1,1000,enemy, 0x8006 //HT_LANDMINE -117,0x91, , 0, 1,1000,enemy, 0x9006 //HT_ANKLESNARE -118,0x94, , 0, 1,1000,enemy, 0x8006 //HT_SHOCKWAVE -119,0x95, , 0, 1,1000,enemy, 0x8006 //HT_SANDMAN -120,0x96, , 0, 1,1000,enemy, 0x8006 //HT_FLASHER -121,0x97, , 0, 1,1000,enemy, 0x8006 //HT_FREEZINGTRAP +115,0x90, , 0, 1,1000,enemy, 0x28006 //HT_SKIDTRAP +116,0x93, , 0, 1,1000,enemy, 0x28006 //HT_LANDMINE +117,0x91, , 0, 1,1000,enemy, 0x29006 //HT_ANKLESNARE +118,0x94, , 0, 1,1000,enemy, 0x28006 //HT_SHOCKWAVE +119,0x95, , 0, 1,1000,enemy, 0x28006 //HT_SANDMAN +120,0x96, , 0, 1,1000,enemy, 0x28006 //HT_FLASHER +121,0x97, , 0, 1,1000,enemy, 0x28006 //HT_FREEZINGTRAP 122,0x8f, , 0, 1,1000,enemy, 0x8006 //HT_BLASTMINE 123,0x98, , 0, 1,1000,enemy, 0x8006 //HT_CLAYMORETRAP -125,0x99, , 0, 1,1000,all, 0x8000 //HT_TALKIEBOX +125,0x99, , 0, 1,1000,all, 0x28000 //HT_TALKIEBOX 140,0x92, , -1, 1,1000,enemy, 0x8000 //AS_VENOMDUST 220,0xb0, , 0, 0, -1,all, 0x8002 //RG_GRAFFITI 229,0xb1, , 0, 1, 500,enemy, 0x006 //AM_DEMONSTRATION diff --git a/src/map/battle.c b/src/map/battle.c index 6bf09cdb3b..d41c26c822 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7747,7 +7747,7 @@ static const struct _battle_data { { "player_damage_delay_rate", &battle_config.pc_damage_delay_rate, 100, 0, INT_MAX, }, { "defunit_not_enemy", &battle_config.defnotenemy, 0, 0, 1, }, { "gvg_traps_target_all", &battle_config.vs_traps_bctall, BL_PC, BL_NUL, BL_ALL, }, - { "traps_setting", &battle_config.traps_setting, 0, 0, 1, }, + { "traps_setting", &battle_config.traps_setting, 0, 0, 2, }, { "summon_flora_setting", &battle_config.summon_flora, 1|2, 0, 1|2, }, { "clear_skills_on_death", &battle_config.clear_unit_ondeath, BL_NUL, BL_NUL, BL_ALL, }, { "clear_skills_on_warp", &battle_config.clear_unit_onwarp, BL_ALL, BL_NUL, BL_ALL, }, diff --git a/src/map/clif.c b/src/map/clif.c index 989762b97a..ca6ec3d3e4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -4878,7 +4878,7 @@ static void clif_graffiti(struct block_list *bl, struct skill_unit *unit, enum s /// 08c7 .W L .L .W .W .B .W .B (ZC_SKILL_ENTRY3) /// 099f .W L .L .W .W .L .W .B (ZC_SKILL_ENTRY4) /// 09ca .W L .L .W .W .L .B .B .B (ZC_SKILL_ENTRY5) -void clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *unit, enum send_target target, uint8 flag) { +void clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *unit, enum send_target target, bool visible) { int header = 0, unit_id = 0, pos = 0, fd = 0, len = -1; unsigned char buf[128]; @@ -4898,23 +4898,8 @@ void clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *unit, else unit_id = unit->group->unit_id; - if (flag && battle_config.traps_setting&1) { - switch(unit->group->skill_id) { - case HT_ANKLESNARE: - if (!map_flag_vs(((TBL_PC*)bl)->bl.m)) - break; - case HT_SKIDTRAP: - case MA_SKIDTRAP: - case HT_SHOCKWAVE: - case HT_SANDMAN: - case MA_SANDMAN: - case HT_FLASHER: - case HT_FREEZINGTRAP: - case MA_FREEZINGTRAP: - unit_id = UNT_DUMMYSKILL; // Use invisible unit id for Hunter's traps - break; - } - } + if (!visible) + unit_id = UNT_DUMMYSKILL; // Hack to makes hidden trap really hidden! #if PACKETVER >= 3 if (unit_id == UNT_GRAFFITI) { // Graffiti [Valaris] @@ -4948,22 +4933,22 @@ void clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *unit, switch (header) { case 0x011f: WBUFB(buf,pos+14) = unit_id; - WBUFB(buf,pos+15) = 1; + WBUFB(buf,pos+15) = visible; break; case 0x08c7: WBUFB(buf,pos+14) = unit_id; WBUFW(buf,pos+15) = unit->range; - WBUFB(buf,pos+17) = 1; + WBUFB(buf,pos+17) = visible; break; case 0x099f: WBUFL(buf,pos+14) = unit_id; WBUFW(buf,pos+18) = unit->range; - WBUFB(buf,pos+20) = 1; + WBUFB(buf,pos+20) = visible; break; case 0x09ca: WBUFL(buf,pos+14) = unit_id; WBUFB(buf,pos+18) = (unsigned char)unit->range; - WBUFB(buf,pos+19) = 1; + WBUFB(buf,pos+19) = visible; WBUFB(buf,pos+20) = (unsigned char)unit->group->skill_lv; break; } @@ -5039,7 +5024,7 @@ static int clif_getareachar(struct block_list* bl,va_list ap) clif_getareachar_item(sd,(struct flooritem_data*) bl); break; case BL_SKILL: - clif_getareachar_skillunit(&sd->bl, (TBL_SKILL*)bl, SELF, 1); + skill_getareachar_skillunit_visibilty_single((TBL_SKILL*)bl, &sd->bl); break; default: if(&sd->bl == bl) @@ -5127,7 +5112,7 @@ int clif_insight(struct block_list *bl,va_list ap) clif_getareachar_item(tsd,(struct flooritem_data*)bl); break; case BL_SKILL: - clif_getareachar_skillunit(&tsd->bl, (TBL_SKILL*)bl, SELF, 1); + skill_getareachar_skillunit_visibilty_single((TBL_SKILL*)bl, &tsd->bl); break; default: clif_getareachar_unit(tsd,bl); diff --git a/src/map/clif.h b/src/map/clif.h index 3c24c7504c..19812aaa18 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -613,7 +613,7 @@ void clif_cooking_list(struct map_session_data *sd, int trigger, uint16 skill_id void clif_produceeffect(struct map_session_data* sd,int flag, unsigned short nameid); -void clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *unit, enum send_target target, uint8 flag); +void clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *unit, enum send_target target, bool visible); void clif_skill_delunit(struct skill_unit *unit); void clif_skillunit_update(struct block_list* bl); diff --git a/src/map/skill.c b/src/map/skill.c index 8c6965b695..e4e8f1b2b9 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4213,7 +4213,9 @@ static int skill_reveal_trap(struct block_list *bl, va_list ap) { //Reveal trap. //Change look is not good enough, the client ignores it as an actual trap still. [Skotlex] //clif_changetraplook(bl, su->group->unit_id); - clif_getareachar_skillunit(&su->bl, su, AREA, 0); + + su->hidden = false; + skill_getareachar_skillunit_visibilty(su, AREA); return 1; } return 0; @@ -12228,7 +12230,7 @@ static int skill_dance_overlap_sub(struct block_list* bl, va_list ap) else //Remove dissonance target->val2 &= ~UF_ENSEMBLE; - clif_getareachar_skillunit(&target->bl, target, AREA, 0); //Update look of affected cell. + skill_getareachar_skillunit_visibilty(target, AREA); return 1; } @@ -12336,6 +12338,7 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_ struct status_change *sc; int active_flag = 1; int subunt = 0; + bool hidden = false; nullpo_retr(NULL, src); @@ -12349,6 +12352,7 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_ sd = BL_CAST(BL_PC, src); status = status_get_status_data(src); sc = status_get_sc(src); // for traps, firewall and fogwall - celest + hidden = (unit_flag&UF_HIDDEN_TRAP && (battle_config.traps_setting == 2 || (battle_config.traps_setting == 1 && map_flag_vs(src->m)))); switch( skill_id ) { case MH_STEINWAND: @@ -12809,7 +12813,7 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_ if( !alive ) continue; - nullpo_retr(NULL, (unit = skill_initunit(group,i,ux,uy,unit_val1,unit_val2))); + nullpo_retr(NULL, (unit = skill_initunit(group,i,ux,uy,unit_val1,unit_val2,hidden))); unit->limit = limit; unit->range = range; @@ -17222,6 +17226,77 @@ bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *s return wall; } +/** + * Process skill unit visibilty for single BL in area + * @param bl + * @param ap + * @author [Cydh] + **/ +int skill_getareachar_skillunit_visibilty_sub(struct block_list *bl, va_list ap) { + struct skill_unit *su = NULL; + struct block_list *src = NULL; + unsigned int party1 = 0; + bool visible = true; + + nullpo_ret(bl); + nullpo_ret((su = va_arg(ap, struct skill_unit*))); + nullpo_ret((src = va_arg(ap, struct block_list*))); + party1 = va_arg(ap, unsigned int); + + if (src != bl) { + unsigned int party2 = status_get_party_id(bl); + if (!party1 || !party2 || party1 != party2) + visible = false; + } + + clif_getareachar_skillunit(bl, su, SELF, visible); + return 1; +} + +/** + * Check for skill unit visibilty in area on + * - skill first placement + * - skill moved (knocked back, moved dance) + * @param su Skill unit + * @param target Affected target for this visibility @see enum send_target + * @author [Cydh] + **/ +void skill_getareachar_skillunit_visibilty(struct skill_unit *su, enum send_target target) { + nullpo_retv(su); + + if (!su->hidden) // It's not hidden, just do this! + clif_getareachar_skillunit(&su->bl, su, target, true); + else { + struct block_list *src = battle_get_master(&su->bl); + map_foreachinarea(skill_getareachar_skillunit_visibilty_sub, su->bl.m, su->bl.x-AREA_SIZE, su->bl.y-AREA_SIZE, + su->bl.x+AREA_SIZE, su->bl.y+AREA_SIZE, BL_PC, su, src, status_get_party_id(src)); + } +} + +/** + * Check for skill unit visibilty on single BL on insight/spawn action + * @param su Skill unit + * @param bl Block list + * @author [Cydh] + **/ +void skill_getareachar_skillunit_visibilty_single(struct skill_unit *su, struct block_list *bl) { + bool visible = true; + struct block_list *src = NULL; + + nullpo_retv(bl); + nullpo_retv(su); + nullpo_retv((src = battle_get_master(&su->bl))); + + if (su->hidden && src != bl) { + unsigned int party1 = status_get_party_id(src); + unsigned int party2 = status_get_party_id(bl); + if (!party1 || !party2 || party1 != party2) + visible = false; + } + + clif_getareachar_skillunit(bl, su, SELF, visible); +} + /** * Initialize new skill unit for skill unit group. * Overall, Skill Unit makes skill unit group which each group holds their cell datas (skill unit) @@ -17232,7 +17307,7 @@ bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *s * @param val1 * @param val2 */ -struct skill_unit *skill_initunit(struct skill_unit_group *group, int idx, int x, int y, int val1, int val2) +struct skill_unit *skill_initunit(struct skill_unit_group *group, int idx, int x, int y, int val1, int val2, bool hidden) { struct skill_unit *unit; @@ -17255,6 +17330,7 @@ struct skill_unit *skill_initunit(struct skill_unit_group *group, int idx, int x unit->alive = 1; unit->val1 = val1; unit->val2 = val2; + unit->hidden = hidden; // Stores new skill unit idb_put(skillunit_db, unit->bl.id, unit); @@ -17284,7 +17360,7 @@ struct skill_unit *skill_initunit(struct skill_unit_group *group, int idx, int x break; } - clif_getareachar_skillunit(&unit->bl, unit, AREA, 0); + skill_getareachar_skillunit_visibilty(unit, AREA); return unit; } @@ -18135,7 +18211,7 @@ void skill_unit_move_unit(struct block_list *bl, int dx, int dy) { map_moveblock(bl, dx, dy, tick); map_foreachincell(skill_unit_effect,bl->m,bl->x,bl->y,su->group->bl_flag,bl,tick,1); - clif_getareachar_skillunit(bl, su, AREA, 0); + skill_getareachar_skillunit_visibilty(su, AREA); return; } @@ -18229,7 +18305,7 @@ void skill_unit_move_unit_group(struct skill_unit_group *group, int16 m, int16 d if (!(m_flag[i]&0x2)) { //We only moved the cell in 0-1 if (group->state.song_dance&0x1) //Check for dissonance effect. skill_dance_overlap(unit1, 1); - clif_getareachar_skillunit(&unit1->bl, unit1, AREA, 0); + skill_getareachar_skillunit_visibilty(unit1, AREA); map_foreachincell(skill_unit_effect,unit1->bl.m,unit1->bl.x,unit1->bl.y,group->bl_flag,&unit1->bl,tick,1); } } diff --git a/src/map/skill.h b/src/map/skill.h index 0ac3216893..b9f84f9933 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -291,7 +291,9 @@ struct skill_unit { struct skill_unit_group *group; /// Skill group reference int limit; int val1, val2; - short alive, range; + short range; + unsigned alive : 1; + unsigned hidden : 1; }; #define MAX_SKILLUNITGROUPTICKSET 25 @@ -319,6 +321,7 @@ enum e_skill_unit_flag { UF_REM_CRAZYWEED = 0x04000, // removed by Crazyweed UF_REM_FIRERAIN = 0x08000, // removed by Fire Rain UF_KNOCKBACK_GROUP = 0x10000, // knockback skill unit with its group instead of single unit + UF_HIDDEN_TRAP = 0x20000, // Hidden trap [Cydh] }; /// Create Database item @@ -431,7 +434,7 @@ int skill_strip_equip(struct block_list *src,struct block_list *bl, unsigned sho // Skills unit struct skill_unit_group *skill_id2group(int group_id); struct skill_unit_group *skill_unitsetting(struct block_list* src, uint16 skill_id, uint16 skill_lv, short x, short y, int flag); -struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int x, int y, int val1, int val2); +struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int x, int y, int val1, int val2, bool hidden); int skill_delunit(struct skill_unit *unit); struct skill_unit_group *skill_initunitgroup(struct block_list* src, int count, uint16 skill_id, uint16 skill_lv, int unit_id, int limit, int interval); int skill_delunitgroup_(struct skill_unit_group *group, const char* file, int line, const char* func); @@ -441,6 +444,10 @@ int skill_clear_group(struct block_list *bl, int flag); void ext_skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, unsigned int tick); int64 skill_unit_ondamaged(struct skill_unit *unit,int64 damage); +// Skill unit visibility [Cydh] +void skill_getareachar_skillunit_visibilty(struct skill_unit *su, enum send_target target); +void skill_getareachar_skillunit_visibilty_single(struct skill_unit *su, struct block_list *bl); + int skill_castfix(struct block_list *bl, uint16 skill_id, uint16 skill_lv); int skill_castfix_sc(struct block_list *bl, double time, uint8 flag); #ifdef RENEWAL_CAST From d9a35c8c6a7c08d5397647cb0ae470bd5692898d Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Mon, 22 Feb 2016 23:33:27 +0700 Subject: [PATCH 002/319] Follow up 51c422cf7cc9e6046886ec89cb9cec07c9cb0d3e. * Added some skills and effects that can reveal hidden traps. Signed-off-by: Cydh Ramdh --- src/map/skill.c | 28 +++++++++++++++++++++------- src/map/skill.h | 2 ++ src/map/status.c | 4 +++- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/map/skill.c b/src/map/skill.c index e4e8f1b2b9..db72044934 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4205,12 +4205,14 @@ static int skill_active_reverberation(struct block_list *bl, va_list ap) { return 1; } +/** + * Reveal hidden trap + **/ static int skill_reveal_trap(struct block_list *bl, va_list ap) { TBL_SKILL *su = (TBL_SKILL*)bl; - if (su->alive && su->group && skill_get_inf2(su->group->skill_id)&INF2_TRAP) - { //Reveal trap. + if (su->alive && su->group && su->hidden && skill_get_inf2(su->group->skill_id)&INF2_TRAP) { //Change look is not good enough, the client ignores it as an actual trap still. [Skotlex] //clif_changetraplook(bl, su->group->unit_id); @@ -4221,6 +4223,19 @@ static int skill_reveal_trap(struct block_list *bl, va_list ap) return 0; } +/** + * Attempt to reaveal trap in area + * @param src Skill caster + * @param range Affected range + * @param x + * @param y + * TODO: Remove this hardcodes + **/ +void skill_reveal_trap_inarea(struct block_list *src, int range, int x, int y) { + nullpo_retv(src); + map_foreachinarea(skill_reveal_trap, src->m, x-range, y-range, x+range, y+range, BL_SKILL); +} + /*========================================== * * @@ -6531,11 +6546,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case AC_CONCENTRATION: { + int splash = skill_get_splash(skill_id, skill_lv); clif_skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv))); + skill_reveal_trap_inarea(src, splash, src->x, src->y); map_foreachinrange( status_change_timer_sub, src, - skill_get_splash(skill_id, skill_lv), BL_CHAR, - src,NULL,type,tick); + splash, BL_CHAR, src, NULL, type, tick); } break; @@ -11356,9 +11372,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui map_foreachinarea( status_change_timer_sub, src->m, x-i, y-i, x+i,y+i,BL_CHAR, src,NULL,SC_SIGHT,tick); - if(battle_config.traps_setting&1) - map_foreachinarea(skill_reveal_trap, src->m, x-i, y-i, x+i, y+i, BL_SKILL); - break; + skill_reveal_trap_inarea(src, i, x, y); break; case SR_RIDEINLIGHTNING: diff --git a/src/map/skill.h b/src/map/skill.h index b9f84f9933..0cfcb35799 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -2080,6 +2080,8 @@ bool skill_is_combo(uint16 skill_id); void skill_combo_toogle_inf(struct block_list* bl, uint16 skill_id, int inf); void skill_combo(struct block_list* src,struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int tick); +void skill_reveal_trap_inarea(struct block_list *src, int range, int x, int y); + #ifdef ADJUST_SKILL_DAMAGE /// Skill Damage target enum e_skill_damage_caster { diff --git a/src/map/status.c b/src/map/status.c index 896e14e6d9..1618e626c4 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -11812,8 +11812,10 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) if(sce->val4%2) sce->val4--; map_foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR|BL_SKILL, bl, sce, type, tick); - } else + } else { map_foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR, bl, sce, type, tick); + skill_reveal_trap_inarea(bl, sce->val3, bl->x, bl->y); + } if( --(sce->val2)>0 ) { sce->val4 += 20; // Use for Shadow Form 2 seconds checking. From 321b1d22e819023f40fe72128bb25d4177d83970 Mon Sep 17 00:00:00 2001 From: Atemo Date: Tue, 23 Feb 2016 22:12:18 +0100 Subject: [PATCH 003/319] Removed the displayed name in from of the message displayed by npctalk and unittalk scripts commands (so we can append whatever we want to). Signed-off-by: Atemo --- doc/script_commands.txt | 5 +- npc/custom/etc/marriage.txt | 38 ++--- npc/custom/events/cluckers.txt | 16 +- npc/custom/events/disguise.txt | 4 +- npc/custom/item_signer.txt | 2 +- npc/re/cities/izlude.txt | 64 ++++---- npc/re/instances/OldGlastHeim.txt | 256 +++++++++++++++--------------- npc/re/jobs/novice/academy.txt | 8 +- src/map/script.c | 17 +- 9 files changed, 202 insertions(+), 208 deletions(-) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 7e5f73a28b..5d7cc75f27 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -5930,8 +5930,7 @@ It is an approximation of official server script language's 'cmdothernpc'. This command will display a message to the surrounding area as if the NPC object running it was a player talking - that is, above their head and in the chat -window. The display name of the NPC will get appended in front of the message to -complete the effect. +window. The display name of the NPC won't get appended in front of the message. // This will make everyone in the area see the NPC greet the character // who just invoked it. @@ -7088,7 +7087,7 @@ Suggest to use 'unitblockmove' to forcefully stop the unit with OnTouch. *unittalk ,""; -This command will make a say a message. +This command will make a say a message. The display name of the won't get appended in front of the message. --------------------------------------- diff --git a/npc/custom/etc/marriage.txt b/npc/custom/etc/marriage.txt index b7604c5fcf..e1a3b6204a 100644 --- a/npc/custom/etc/marriage.txt +++ b/npc/custom/etc/marriage.txt @@ -104,7 +104,7 @@ prt_church,100,123,4 script Vomars 60,{ mes "I am going to wed "+$wed_groom$+" and "+$wed_bride$+", do you have an objection to it?"; if (select("Sorry, please go on.","Yes, I actually do.") == 2) { //Abort - npctalk "Ladies and gentlemen, "+strcharinfo(0)+" has an objection to the wedding!"; + npctalk strnpcinfo(1) +" : Ladies and gentlemen, "+strcharinfo(0)+" has an objection to the wedding!"; SF_wed_end(); mes "Why should they not be wed?"; input $@msg$; @@ -203,7 +203,7 @@ function SF_AcceptGroom { mes "Ah... err... ehm... okay. You two seem to have some differences to settle first."; close2; emotion e_omg; - npctalk "Ladies and gentlemen, "+$wed_bride$+" has rejected to marry "+$wed_groom$+"!"; + npctalk strnpcinfo(1) +" : Ladies and gentlemen, "+$wed_bride$+" has rejected to marry "+$wed_groom$+"!"; SF_wed_end(); break; case 3: @@ -236,7 +236,7 @@ function SF_AcceptBride { mes "Ah... err... ehm... okay. You two seem to have some differences to settle first."; emotion e_omg; close2; - npctalk "Ladies and gentlemen, "+$wed_groom$+" has rejected to marry "+$wed_bride$+"!"; + npctalk strnpcinfo(1) +" : Ladies and gentlemen, "+$wed_groom$+" has rejected to marry "+$wed_bride$+"!"; SF_wed_end(); break; case 3: @@ -260,7 +260,7 @@ function SF_RingsAccepted { announce $wed_groom$+" and "+$wed_bride$+"'s wedding ceremony will be held at the church!",8; close2; emotion e_lv; - npctalk "May the groom and bride please step forward and retrieve their rings?"; + npctalk strnpcinfo(1) +" : May the groom and bride please step forward and retrieve their rings?"; } function SF_RetrieveRingM { @@ -336,35 +336,35 @@ function SF_StartCeremony { } OnTimer1000: - npctalk "Ladies and Gentlemen, We will now join in holy matrimony these two lovers."; + npctalk strnpcinfo(1) +" : Ladies and Gentlemen, We will now join in holy matrimony these two lovers."; end; OnTimer5000: - npctalk "Now more than ever, will both of your lives be entwined together as so will be your souls."; + npctalk strnpcinfo(1) +" : Now more than ever, will both of your lives be entwined together as so will be your souls."; end; OnTimer10000: - npctalk "You will both honor and cherish each other through the best and worst of times."; + npctalk strnpcinfo(1) +" : You will both honor and cherish each other through the best and worst of times."; end; OnTimer15000: - npctalk "The safety and well being of your other will now also be your responsibility."; + npctalk strnpcinfo(1) +" : The safety and well being of your other will now also be your responsibility."; end; OnTimer20000: - npctalk "May in sickness or good health, your love burn bright like no force can extinguish it."; + npctalk strnpcinfo(1) +" : May in sickness or good health, your love burn bright like no force can extinguish it."; end; OnTimer25000: - npctalk "Those here stand witness to these vows bestowed upon you, you must act accordingly to them."; + npctalk strnpcinfo(1) +" : Those here stand witness to these vows bestowed upon you, you must act accordingly to them."; end; OnTimer30000: - npctalk "Understanding that, we are nothing more but mortals on this earth, but this is our triumph."; + npctalk strnpcinfo(1) +" : Understanding that, we are nothing more but mortals on this earth, but this is our triumph."; end; OnTimer35000: - npctalk "We here will now join these two mortal entities, and create an immortal love."; + npctalk strnpcinfo(1) +" : We here will now join these two mortal entities, and create an immortal love."; end; OnTimer40000: @@ -372,15 +372,15 @@ OnTimer40000: end; OnTimer45000: - npctalk "and you, "+$wed_bride$+", have accepted take "+$wed_groom$+" as your lawfully wedded husband."; + npctalk strnpcinfo(1) +" : and you, "+$wed_bride$+", have accepted take "+$wed_groom$+" as your lawfully wedded husband."; end; OnTimer50000: - npctalk "And as such, now, by the powers vested in me..."; + npctalk strnpcinfo(1) +" : And as such, now, by the powers vested in me..."; end; OnTimer55000: - npctalk "I pronounce you Husband and Wife, you may kiss the bride and exchange rings."; + npctalk strnpcinfo(1) +" : I pronounce you Husband and Wife, you may kiss the bride and exchange rings."; if ($wedding_effect_id && isloggedin($wedding_effect_id)) { attachrid($wedding_effect_id); @@ -561,7 +561,7 @@ function SF_WedProgress { mes "Very well, now go to the Priest to reaffirm your vows and the ceremony will begin."; emotion e_no1; close2; - npctalk "Registration finished. "+$wed_groom$+" and "+$wed_bride$+", please reaffirm your vows with the Priest."; + npctalk strnpcinfo(1) +" : Registration finished. "+$wed_groom$+" and "+$wed_bride$+", please reaffirm your vows with the Priest."; emotion e_no1; end; } else { @@ -582,7 +582,7 @@ function SF_WedProgress { mes "Very well, now go to the Priest to reaffirm your vows and the ceremony will begin."; emotion e_no1; close2; - npctalk "Registration finished. "+$wed_groom$+" and "+$wed_bride$+", please reaffirm your vows with the Priest."; + npctalk strnpcinfo(1) +" : Registration finished. "+$wed_groom$+" and "+$wed_bride$+", please reaffirm your vows with the Priest."; emotion e_no1; end; } else { @@ -658,7 +658,7 @@ OnTimer60000: else set $@msg$, $wed_groom$; - npctalk "Registration timed out. Is it that noone wants to marry "+$@msg$+"..?"; + npctalk strnpcinfo(1) +" : Registration timed out. Is it that noone wants to marry "+$@msg$+"..?"; emotion e_hmm; set $wed_groom$,""; @@ -930,7 +930,7 @@ function SF_DivorceEnd { } OnTimer60000: - npctalk "Divorce confirmation time's is up. Where did "+$@divorcer$+"'s spouse go..."; + npctalk strnpcinfo(1) +" : Divorce confirmation time's is up. Where did "+$@divorcer$+"'s spouse go..."; emotion e_what; SF_DivorceEnd(); end; diff --git a/npc/custom/events/cluckers.txt b/npc/custom/events/cluckers.txt index dac847c682..ffc56b49da 100644 --- a/npc/custom/events/cluckers.txt +++ b/npc/custom/events/cluckers.txt @@ -26,29 +26,29 @@ prontera,156,219,4 script Cluckers 800,{ if (.startcluck) { specialeffect2 EF_HIT3; switch(rand(15)) { - case 0: npctalk "CLUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; - case 1: npctalk "Cluuuuuck!~"; break; + case 0: npctalk strnpcinfo(1) +" : CLUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; + case 1: npctalk strnpcinfo(1) +" : Cluuuuuck!~"; break; case 2: unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; break; case 3: sc_start SC_Freeze,10000,0; break; - case 4: npctalk "CLUUUUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; + case 4: npctalk strnpcinfo(1) +" : CLUUUUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; case 5: sc_start SC_Sleep,10000,0; break; case 6: sc_start SC_Stone,10000,0; emotion e_gg; break; - case 7: npctalk "CLUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; - case 8: npctalk "Cluck! CLUUUCK!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; + case 7: npctalk strnpcinfo(1) +" : CLUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; + case 8: npctalk strnpcinfo(1) +" : Cluck! CLUUUCK!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; case 9: sc_start SC_Stun,10000,0; break; case 10: sc_start SC_Sleep,10000,0; emotion e_gg; break; - case 11: npctalk "Cluck! Cluck!"; break; + case 11: npctalk strnpcinfo(1) +" : Cluck! Cluck!"; break; case 12: sc_start SC_Stun,10000,0; break; case 13: unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; break; default: if (rand(50) < 4) { - npctalk "WOOF!..........."; + npctalk strnpcinfo(1) +" : WOOF!..........."; specialeffect2 EF_SPHERE; announce "[Cluck! Cluck! Boom!] " + strcharinfo(0) + " squeezed out the prize! Well done!",0; getitem $cluck_item_id,$cluck_item_amount; set .startcluck,0; } else { - npctalk "Cluck! CLUUUCK!!"; + npctalk strnpcinfo(1) +" : Cluck! CLUUUCK!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; } break; diff --git a/npc/custom/events/disguise.txt b/npc/custom/events/disguise.txt index 9191fec8a3..355487dd17 100644 --- a/npc/custom/events/disguise.txt +++ b/npc/custom/events/disguise.txt @@ -177,7 +177,7 @@ OnTimer30000: if (.Timer) end; set .Change,0; setnpcdisplay "Disguise Event",795; - npctalk "You took too long to guess what I was. Please wait 10 seconds while I disguise again."; + npctalk strnpcinfo(1) +" : You took too long to guess what I was. Please wait 10 seconds while I disguise again."; specialeffect EF_DETECT2; set $MonsterName$,""; deletepset 1; @@ -238,7 +238,7 @@ iCorrect: setnpcdisplay "Disguise Event",795; set .RoundCount,0; set .Change,0; set .EventON,0; setnpctimer 0; stopnpctimer; - npctalk "Thank you all for playing. That was the last round of the Disguise Event. Come play again later."; + npctalk strnpcinfo(1) +" : Thank you all for playing. That was the last round of the Disguise Event. Come play again later."; end; } setnpcdisplay "Disguise Event",795; diff --git a/npc/custom/item_signer.txt b/npc/custom/item_signer.txt index 75fc891f0a..b52d346ff4 100644 --- a/npc/custom/item_signer.txt +++ b/npc/custom/item_signer.txt @@ -118,7 +118,7 @@ prt_in,24,61,7 script Perchik 47,{ } if (!countitem2(.@id,1,.@ref,0,.@slot[0],.@slot[1],.@slot[2],.@slot[3])) { mes "Where is "+getitemname(@id)+"...?"; - npctalk "You're a snoozy cheater!"; + npctalk strnpcinfo(1) +" : You're a snoozy cheater!"; logmes "Hack: Tried to sign an item not having it: "+getitemname(@id); emotion e_wah; close; diff --git a/npc/re/cities/izlude.txt b/npc/re/cities/izlude.txt index d19fb32141..b56bef515e 100644 --- a/npc/re/cities/izlude.txt +++ b/npc/re/cities/izlude.txt @@ -112,59 +112,59 @@ izlude,143,205,7 script Talkative Kid#iz 4_F_KID2,{ end; OnTimer64000: - npctalk "I used all my Novice Red Potions. What should I do?"; + npctalk strnpcinfo(1) +" : I used all my Novice Red Potions. What should I do?"; end; OnTimer72000: - npctalk "Where is the shop?"; + npctalk strnpcinfo(1) +" : Where is the shop?"; end; OnTimer136000: - npctalk "Idiot! You do not know about the 'shortcut window'?"; + npctalk strnpcinfo(1) +" : Idiot! You do not know about the 'shortcut window'?"; end; OnTimer144000: - npctalk "The items in your inventory can be dragged and put in the shortcut window."; + npctalk strnpcinfo(1) +" : The items in your inventory can be dragged and put in the shortcut window."; end; OnTimer212000: - npctalk "I got so many beginner's items in the Academy!"; + npctalk strnpcinfo(1) +" : I got so many beginner's items in the Academy!"; end; OnTimer276000: - npctalk "They even gave me weapons and a shield!"; + npctalk strnpcinfo(1) +" : They even gave me weapons and a shield!"; end; OnTimer284000: - npctalk "Just press to open the map you have."; + npctalk strnpcinfo(1) +" : Just press to open the map you have."; end; OnTimer344000: - npctalk "Then do you want to go Criatura Academy with me? I'm learning how to battle from Instructor Subino!"; + npctalk strnpcinfo(1) +" : Then do you want to go Criatura Academy with me? I'm learning how to battle from Instructor Subino!"; end; OnTimer348000: - npctalk "The Academy is in North side of Izlude. Let's go~!"; + npctalk strnpcinfo(1) +" : The Academy is in North side of Izlude. Let's go~!"; end; OnTimer416000: - npctalk "It's a system to guide you to a destination."; + npctalk strnpcinfo(1) +" : It's a system to guide you to a destination."; end; OnTimer424000: - npctalk "In the basic menu, please click the [Navigation] button."; + npctalk strnpcinfo(1) +" : In the basic menu, please click the [Navigation] button."; end; OnTimer492000: - npctalk "Whee, Ain't gonna use your brain? Please type /where in the chat window now!"; + npctalk strnpcinfo(1) +" : Whee, Ain't gonna use your brain? Please type /where in the chat window now!"; end; OnTimer552000: - npctalk "In this case, you can push the key."; + npctalk strnpcinfo(1) +" : In this case, you can push the key."; end; OnTimer560000: - npctalk "We are just repeating the same dialog. HaHaha."; + npctalk strnpcinfo(1) +" : We are just repeating the same dialog. HaHaha."; end; OnTimer565000: @@ -182,67 +182,67 @@ izlude,146,205,7 script Talkative Adventurer#iz 4_M_KID1,{ end; OnTimer69000: - npctalk "You can buy potion from Merchants."; + npctalk strnpcinfo(1) +" : You can buy potion from Merchants."; end; OnTimer77000: - npctalk "It's the Potion image in the mini map."; + npctalk strnpcinfo(1) +" : It's the Potion image in the mini map."; end; OnTimer131000: - npctalk "Is there any way to use items easily?"; + npctalk strnpcinfo(1) +" : Is there any way to use items easily?"; end; OnTimer141000: - npctalk "Shortcut window? The slots at the top of the screen? How can I use it?"; + npctalk strnpcinfo(1) +" : Shortcut window? The slots at the top of the screen? How can I use it?"; end; OnTimer149000: - npctalk "For inventory, do you mean 'item' menu? Oh, it is!"; + npctalk strnpcinfo(1) +" : For inventory, do you mean 'item' menu? Oh, it is!"; end; OnTimer217000: - npctalk "I have a bunch of potions?"; + npctalk strnpcinfo(1) +" : I have a bunch of potions?"; end; OnTimer281000: - npctalk "What?! I should go to the Academy now!"; + npctalk strnpcinfo(1) +" : What?! I should go to the Academy now!"; end; OnTimer279000: - npctalk "Where is Izlude? In the center?"; + npctalk strnpcinfo(1) +" : Where is Izlude? In the center?"; end; OnTimer339000: - npctalk "I do not know what to do."; + npctalk strnpcinfo(1) +" : I do not know what to do."; end; OnTimer349000: - npctalk "Oh yea? I want to know so many things~ I will go with you!"; + npctalk strnpcinfo(1) +" : Oh yea? I want to know so many things~ I will go with you!"; end; OnTimer411000: - npctalk "Navigation, What is that?"; + npctalk strnpcinfo(1) +" : Navigation, What is that?"; end; OnTimer421000: - npctalk "Oh-! Should I search for a Kafra Employee?"; + npctalk strnpcinfo(1) +" : Oh-! Should I search for a Kafra Employee?"; end; OnTimer487000: - npctalk "What is the town name?"; + npctalk strnpcinfo(1) +" : What is the town name?"; end; OnTimer497000: - npctalk "I cannot see the part where I can write something in the chat window?"; + npctalk strnpcinfo(1) +" : I cannot see the part where I can write something in the chat window?"; end; OnTimer557000: - npctalk "Oh you smarty..."; + npctalk strnpcinfo(1) +" : Oh you smarty..."; end; OnTimer555000: - npctalk "A while ago, one Novice talked to me like hey 'Talkative Adventurer'?. HaHaha."; + npctalk strnpcinfo(1) +" : A while ago, one Novice talked to me like hey 'Talkative Adventurer'?. HaHaha."; end; OnTimer565000: @@ -260,11 +260,11 @@ prt_fild08,338,217,7 script Resting Adventurer#iz 4_F_SITDOWN,{ end; OnTimer60000: - npctalk "You know what? If you are sitting, HP and SP recovery is faster."; + npctalk strnpcinfo(1) +" : You know what? If you are sitting, HP and SP recovery is faster."; end; OnTimer65000: - npctalk "Sitting is possible if your basic job skill level is more than 3. Shortcut is pressing the key."; + npctalk strnpcinfo(1) +" : Sitting is possible if your basic job skill level is more than 3. Shortcut is pressing the key."; OnInit: initnpctimer; end; diff --git a/npc/re/instances/OldGlastHeim.txt b/npc/re/instances/OldGlastHeim.txt index 513e959823..2093e39113 100644 --- a/npc/re/instances/OldGlastHeim.txt +++ b/npc/re/instances/OldGlastHeim.txt @@ -94,41 +94,41 @@ glast_01,204,273,6 script Hugin#ghinstance 755,{ 1@gl_k,149,41,6 script Varmunt#ghinstance1 654,{ if (getcharid(0) == getpartyleader(getcharid(1),2)) { mes "Hey ^0000ffguys^000000, were you sent here to help me?"; - npctalk "Hey guys, were you sent here to help me?"; + npctalk strnpcinfo(1) +" : Hey guys, were you sent here to help me?"; cutin "gl_barmund1",2; next; select("Oh. Well, about that..."); mes "["+strcharinfo(0)+"]"; mes "Oh yeah, hahaha, we were told to meet someone called Varmunt."; - unittalk getcharid(3),"Oh yeah, hahaha, we were told to meet someone called Varmunt."; + unittalk getcharid(3), strcharinfo(0) +" : Oh yeah, hahaha, we were told to meet someone called Varmunt."; next; mes "[Varmunt]"; mes "We don't have time. We must tell Sir Heinrich about Himmelmez's invasion."; - npctalk "We don't have time. We must tell Sir Heinrich about Himmelmez's invasion."; + npctalk strnpcinfo(1) +" : We don't have time. We must tell Sir Heinrich about Himmelmez's invasion."; cutin "gl_barmund2",2; next; select("What Himmelmez..."); mes "["+strcharinfo(0)+"]"; mes "Himmelmez? Who the hell is she?"; - unittalk getcharid(3),"Himmelmez? Who the hell is she?"; + unittalk getcharid(3), strcharinfo(0) +" : Himmelmez? Who the hell is she?"; next; mes "[Varmunt]"; mes "Didn't anybody give you the basic informations?"; - npctalk "Didn't anybody give you the basic informations?"; + npctalk strnpcinfo(1) +" : Didn't anybody give you the basic informations?"; cutin "gl_barmund3",2; next; mes "[Varmunt]"; mes "The Valkyrie of the dead. She's after the Ymir's Heart pieces hidden here."; - npctalk "The Valkyrie of the dead. She's after the Ymir's Heart pieces hidden here"; + npctalk strnpcinfo(1) +" : The Valkyrie of the dead. She's after the Ymir's Heart pieces hidden here"; cutin "gl_barmund2",2; next; mes "[Varmunt]"; mes "She's capable of destroying the whole castle for this purpose."; - npctalk "She's capable of destroying the whole castle for this purpose."; + npctalk strnpcinfo(1) +" : She's capable of destroying the whole castle for this purpose."; next; mes "[Varmunt]"; mes "Hurry up! Inform Sir Heinrich that Himmelmez is coming. I will briefly explore the enchantments she made to this place!"; - npctalk "Hurry up! Inform Sir Heinrich that Himmelmez is coming. I will briefly explore the enchantments she made to this place!"; + npctalk strnpcinfo(1) +" : Hurry up! Inform Sir Heinrich that Himmelmez is coming. I will briefly explore the enchantments she made to this place!"; close2; cutin "gl_barmund2",255; donpcevent instance_npcname("Varmunt#ghinstance1")+"::OnDisable2"; @@ -220,24 +220,24 @@ OnEnable: select("Heinrich, about the castle..."); mes "["+strcharinfo(0)+"]"; mes "Do you know what is happening now in the castle, Heinrich?"; - unittalk getcharid(3),"Do you know what is happening now in the castle, Heinrich?"; + unittalk getcharid(3), strcharinfo(0) +" : Do you know what is happening now in the castle, Heinrich?"; next; mes "[Heinrich]"; mes "You are the adventurers who have come with Varmunt, right?"; - npctalk "You are the adventurers who have come with Varmunt, right?"; + npctalk strnpcinfo(1) +" : You are the adventurers who have come with Varmunt, right?"; next; mes "[Heinrich]"; mes "What can I do for you? Is there something wrong?"; - npctalk "What can I do for you? Is there something wrong?"; + npctalk strnpcinfo(1) +" : What can I do for you? Is there something wrong?"; next; select("The Ymir's Heart. Himmelmez..."); mes "["+strcharinfo(0)+"]"; mes "Himmelmez, the Valkyrie of the dead is looking to get a piece of the Ymir's heart hidden in the castle!"; - unittalk getcharid(3),"Himmelmez, the Valkyrie of the dead is looking to get a piece of the Ymir's heart hidden in the castle!"; + unittalk getcharid(3), strcharinfo(0) +" : Himmelmez, the Valkyrie of the dead is looking to get a piece of the Ymir's heart hidden in the castle!"; next; mes "[Heinrich]"; mes "Haha. That's a nice joke. Now tell me what brings you here."; - npctalk "Haha. That's a nice joke. Now tell me what brings you here."; + npctalk strnpcinfo(1) +" : Haha. That's a nice joke. Now tell me what brings you here."; cutin "gl_heinrich1",2; next; mes "[Varmunt]"; @@ -252,17 +252,17 @@ OnEnable: select("Even if you do not believe..."); mes "["+strcharinfo(0)+"]"; mes "Even if you don't believe it, do something. We do not have much time!"; - unittalk getcharid(3),"Even if you don't believe it, do something. We do not have much time!"; + unittalk getcharid(3), strcharinfo(0) +" : Even if you don't believe it, do something. We do not have much time!"; cutin "gl_barmund2",255; next; mes "[Heinrich]"; mes "I will be glad if you give me two minutes, please. But now the king isn't in his room."; - npctalk "I will be glad if you give me two minutes, please. But now the king isn't in his room."; + npctalk strnpcinfo(1) +" : I will be glad if you give me two minutes, please. But now the king isn't in his room."; cutin "gl_heinrich1",2; next; mes "[Heinrich]"; mes "But I think that with such a busy agenda, he won't be able to take care of this."; - npctalk "But I think that with such a busy agenda, he won't be able to take care of this."; + npctalk strnpcinfo(1) +" : But I think that with such a busy agenda, he won't be able to take care of this."; donpcevent instance_npcname("Heinrich#ghinstance1")+"::OnDisable"; donpcevent instance_npcname("Heinrich#ghinstance2")+"::OnEnable"; donpcevent instance_npcname("Himmelmez#ghinstance1")+"::OnEnable"; @@ -299,25 +299,25 @@ OnEnable: hideoffnpc instance_npcname("Varmunt#ghinstance2"); end; OnTalk1: - npctalk "I am not joking Heinrich, Sir. Now, if my judgement is correct, she will be here soon."; + npctalk strnpcinfo(1) +" : I am not joking Heinrich, Sir. Now, if my judgement is correct, she will be here soon."; end; OnTalk2: - npctalk "I trust this guy following me. The Ymir's Heart pieces must be hidden in a safe place before Himmelmez takes them!"; + npctalk strnpcinfo(1) +" : I trust this guy following me. The Ymir's Heart pieces must be hidden in a safe place before Himmelmez takes them!"; end; OnTalk3: - npctalk "Himmelmez!! Through the cracks!"; + npctalk strnpcinfo(1) +" : Himmelmez!! Through the cracks!"; end; OnTalk4: - npctalk "Unbelievable. My men are...This kind of thing is not possible!"; + npctalk strnpcinfo(1) +" : Unbelievable. My men are...This kind of thing is not possible!"; end; OnTalk5: - npctalk "Heinrich, Sir! I need a quick decision."; + npctalk strnpcinfo(1) +" : Heinrich, Sir! I need a quick decision."; end; OnTalk6: - npctalk "To prevent other attacks, go chase her!"; + npctalk strnpcinfo(1) +" : To prevent other attacks, go chase her!"; end; OnTalk7: - npctalk "Now, your help is desperately needed. I hopefully ask you."; + npctalk strnpcinfo(1) +" : Now, your help is desperately needed. I hopefully ask you."; end; } @@ -331,34 +331,34 @@ OnEnable: hideoffnpc instance_npcname("Heinrich#ghinstance2"); end; OnTalk1: - npctalk "Who?!"; + npctalk strnpcinfo(1) +" : Who?!"; end; OnTalk2: - npctalk "That who rules the dead? No doubt, a pretty story. Here, some tea will be served to entertain the ladies. Unfortunately, I do not..."; + npctalk strnpcinfo(1) +" : That who rules the dead? No doubt, a pretty story. Here, some tea will be served to entertain the ladies. Unfortunately, I do not..."; end; OnTalk3: - npctalk "What did you say?"; + npctalk strnpcinfo(1) +" : What did you say?"; end; OnTalk4: - npctalk "The King responded to the invitation of the Rune Midgard's Royal Family and hasn't come back yet."; + npctalk strnpcinfo(1) +" : The King responded to the invitation of the Rune Midgard's Royal Family and hasn't come back yet."; end; OnTalk5: - npctalk "Just leave before you get in trouble. This is the King's will!"; + npctalk strnpcinfo(1) +" : Just leave before you get in trouble. This is the King's will!"; end; OnTalk6: - npctalk "Damn! She has detected the position of the Ymir's Heart pieces."; + npctalk strnpcinfo(1) +" : Damn! She has detected the position of the Ymir's Heart pieces."; end; OnTalk7: - npctalk "Now, Khalitzburg Crusaders and White Knights, follow me..."; + npctalk strnpcinfo(1) +" : Now, Khalitzburg Crusaders and White Knights, follow me..."; end; OnTalk8: - npctalk "Unbelievable. My men are...This kind of thing is not possible!"; + npctalk strnpcinfo(1) +" : Unbelievable. My men are...This kind of thing is not possible!"; end; OnTalk9: - npctalk "I'm sorry..."; + npctalk strnpcinfo(1) +" : I'm sorry..."; end; OnTalk10: - npctalk "I'm sorry, my lord! Do not forgive me!"; + npctalk strnpcinfo(1) +" : I'm sorry, my lord! Do not forgive me!"; end; } @@ -372,28 +372,28 @@ OnEnable: hideoffnpc instance_npcname("Heinrich#ghinstance3"); end; OnTalk1: - npctalk "I cannot believe I killed my men with my own hands!"; + npctalk strnpcinfo(1) +" : I cannot believe I killed my men with my own hands!"; end; OnTalk2: - npctalk "Varmunt is right about that. Now is not the time to regret."; + npctalk strnpcinfo(1) +" : Varmunt is right about that. Now is not the time to regret."; end; OnTalk3: - npctalk "People, gather around and follow my orders."; + npctalk strnpcinfo(1) +" : People, gather around and follow my orders."; end; OnTalk4: - npctalk "Himmelmez is turning into monsters all the people she put to sleep."; + npctalk strnpcinfo(1) +" : Himmelmez is turning into monsters all the people she put to sleep."; end; OnTalk5: - npctalk "I don't know if there are survivors around here yet."; + npctalk strnpcinfo(1) +" : I don't know if there are survivors around here yet."; end; OnTalk6: - npctalk "If there are survivors from this evil thing, please rescue them."; + npctalk strnpcinfo(1) +" : If there are survivors from this evil thing, please rescue them."; end; OnTalk7: - npctalk "With Varmunt by my side, I'm going to chase Himmelmez down."; + npctalk strnpcinfo(1) +" : With Varmunt by my side, I'm going to chase Himmelmez down."; end; OnTalk8: - npctalk "Hurry up Varmunt, let's chase her down."; + npctalk strnpcinfo(1) +" : Hurry up Varmunt, let's chase her down."; end; } @@ -407,28 +407,28 @@ OnEnable: hideoffnpc instance_npcname("Himmelmez#ghinstance1"); end; OnTalk1: - npctalk "This~ Did I interrupt your conversation? The thing is, it's been too long since the last guests saw some sadness spread..."; + npctalk strnpcinfo(1) +" : This~ Did I interrupt your conversation? The thing is, it's been too long since the last guests saw some sadness spread..."; end; OnTalk2: - npctalk "My name is Lisa Kahn Himmelmez. I am called the Valkyrie of the dead, master of the Dullahan."; + npctalk strnpcinfo(1) +" : My name is Lisa Kahn Himmelmez. I am called the Valkyrie of the dead, master of the Dullahan."; end; OnTalk3: - npctalk "There's no need to pretend to be so laid back. Don't bluff about the whereabouts of you Majesty and things will be alright."; + npctalk strnpcinfo(1) +" : There's no need to pretend to be so laid back. Don't bluff about the whereabouts of you Majesty and things will be alright."; end; OnTalk4: - npctalk "Hohoho, do you have any questions? You're a really mysterious man."; + npctalk strnpcinfo(1) +" : Hohoho, do you have any questions? You're a really mysterious man."; end; OnTalk5: - npctalk "Not coveting the king's throne, you're such a stupid man, only waiting for his return. Your innocence is true, I love it."; + npctalk strnpcinfo(1) +" : Not coveting the king's throne, you're such a stupid man, only waiting for his return. Your innocence is true, I love it."; end; Ontalk6: - npctalk "You make me wish we hadn't met in this situation. Too bad we did."; + npctalk strnpcinfo(1) +" : You make me wish we hadn't met in this situation. Too bad we did."; end; Ontalk7: - npctalk "Well~ Today, with such a busy commandant, I won't be able to talk as much as I'd love for you to contemplate my explanation~"; + npctalk strnpcinfo(1) +" : Well~ Today, with such a busy commandant, I won't be able to talk as much as I'd love for you to contemplate my explanation~"; end; OnTalk8: - npctalk "I gotta get my job done. Meanwhile why don't you meet my men? Hohoho."; + npctalk strnpcinfo(1) +" : I gotta get my job done. Meanwhile why don't you meet my men? Hohoho."; end; } @@ -703,18 +703,18 @@ OnEffect1: end; OnTalkK: switch(atoi(replacestr(strnpcinfo(2),"ghinstance",""))) { - case 1: npctalk "I do not want to die."; break; - case 2: npctalk "Mom..."; break; - case 5: npctalk "Help."; break; - case 6: npctalk "My stomach hurts..."; break; - case 9: npctalk "Heinrich Sir, help!"; break; - case 10: npctalk "Ack... Ugh."; break; - case 13: npctalk "I'm thirsty."; break; - case 14: npctalk "Oh... No... I cannot die..."; break; - case 17: npctalk "This is so uncomfortable. Eww!"; break; - case 18: npctalk "Who am I..."; break; - case 21: npctalk "Uhh... My body."; break; - case 22: npctalk "I'm so thirsty!"; break; + case 1: npctalk strnpcinfo(1) +" : I do not want to die."; break; + case 2: npctalk strnpcinfo(1) +" : Mom..."; break; + case 5: npctalk strnpcinfo(1) +" : Help."; break; + case 6: npctalk strnpcinfo(1) +" : My stomach hurts..."; break; + case 9: npctalk strnpcinfo(1) +" : Heinrich Sir, help!"; break; + case 10: npctalk strnpcinfo(1) +" : Ack... Ugh."; break; + case 13: npctalk strnpcinfo(1) +" : I'm thirsty."; break; + case 14: npctalk strnpcinfo(1) +" : Oh... No... I cannot die..."; break; + case 17: npctalk strnpcinfo(1) +" : This is so uncomfortable. Eww!"; break; + case 18: npctalk strnpcinfo(1) +" : Who am I..."; break; + case 21: npctalk strnpcinfo(1) +" : Uhh... My body."; break; + case 22: npctalk strnpcinfo(1) +" : I'm so thirsty!"; break; } end; } @@ -833,33 +833,33 @@ OnMyMobDead: select("Hey, wake up! Are there any other survivors?"); mes "["+strcharinfo(0)+"]"; mes "Hey, wake up! Are you alone?"; - unittalk getcharid(3),"Hey, wake up! Are you alone?"; + unittalk getcharid(3), strcharinfo(0) +" : Hey, wake up! Are you alone?"; next; mes "[Aspiring Butcher]"; mes "The Chamberlain... the Monk... They've become monsters. I couldn't do anything."; - npctalk "The Chamberlain... the Monk... They've become monsters. I couldn't do anything."; + npctalk strnpcinfo(1) +" : The Chamberlain... the Monk... They've become monsters. I couldn't do anything."; next; mes "[Aspiring Butcher]"; mes "I just stood still... Nothing, I couldn't do anything..."; - npctalk "I just stood still... Nothing, I couldn't do anything..."; + npctalk strnpcinfo(1) +" : I just stood still... Nothing, I couldn't do anything..."; next; select("Wake up!"); mes "["+strcharinfo(0)+"]"; mes "Wake up kid! Go east along the central passage to the outside! The path is safe!"; - unittalk getcharid(3),"Wake up kid! Go east along the central passage to the outside! The path is safe!"; + unittalk getcharid(3), strcharinfo(0) +" : Wake up kid! Go east along the central passage to the outside! The path is safe!"; next; mes "[Aspiring Butcher]"; mes "East passage? Alone? How?"; - npctalk "East passage? Alone? How?"; + npctalk strnpcinfo(1) +" : East passage? Alone? How?"; next; select("I can guide you through the path."); mes "["+strcharinfo(0)+"]"; mes "I will guide you, perhaps that will help. If you want to close your eyes try not to hit anything."; - unittalk getcharid(3),"I will guide you, perhaps that will help. If you want to close your eyes try not to hit anything."; + unittalk getcharid(3), strcharinfo(0) +" : I will guide you, perhaps that will help. If you want to close your eyes try not to hit anything."; next; mes "[Aspiring Butcher]"; mes "Aspiring Butcher: I know, I... I'm trying to."; - npctalk "Aspiring Butcher: I know, I... I'm trying to."; + npctalk strnpcinfo(1) +" : Aspiring Butcher: I know, I... I'm trying to."; donpcevent instance_npcname("Aspiring Butcher#clearGH")+"::OnDisable"; donpcevent instance_npcname("#ghmemorialmob02")+"::OnEnable"; close; @@ -883,35 +883,35 @@ OnEnable: if (getcharid(0) == getpartyleader(getcharid(1),2)) { mes "[Hollgrehenn Destroyer]"; mes "Yaaa!! Die!!!"; - npctalk "Yaaa!! Die!!!"; + npctalk strnpcinfo(1) +" : Yaaa!! Die!!!"; specialeffect EF_CRASHEARTH; next; select("Don't worry!"); mes "["+strcharinfo(0)+"]"; mes "Don't worry! Mam. Are you alone? No other survivors?"; - unittalk getcharid(3),"Don't worry! Mam. Are you alone? No other survivors?"; + unittalk getcharid(3), strcharinfo(0) +" : Don't worry! Mam. Are you alone? No other survivors?"; next; mes "[Hollgrehenn Destroyer]"; mes "I'm the only survivor left"; - npctalk "I'm the only survivor left"; + npctalk strnpcinfo(1) +" : I'm the only survivor left"; next; select("This is a very dangerous place."); mes "["+strcharinfo(0)+"]"; mes "This is a very dangerous place. You know the central passage? Do you think you can move... and get to a safer place?"; - unittalk getcharid(3),"This is a very dangerous place. You know the central passage? Do you think you can move... and get to a safer place?"; + unittalk getcharid(3), strcharinfo(0) +" : This is a very dangerous place. You know the central passage? Do you think you can move... and get to a safer place?"; next; mes "[Hollgrehenn Destroyer]"; mes "Yes, I am able to move. I'll move for my baby's sake."; - npctalk "Yes, I am able to move. I'll move for my baby's sake."; + npctalk strnpcinfo(1) +" : Yes, I am able to move. I'll move for my baby's sake."; next; select("Survive the road..."); mes "["+strcharinfo(0)+"]"; mes "You and your baby will get out of here safely. But I'm sorry I can't help you more."; - unittalk getcharid(3),"You and your baby will get out of here safely. But I'm sorry I can't help you more."; + unittalk getcharid(3), strcharinfo(0) +" : You and your baby will get out of here safely. But I'm sorry I can't help you more."; next; mes "[Hollgrehenn Destroyer]"; mes "That's ok. Thank you for helping us. I'm good to go alone. Ah and good luck also."; - npctalk "That's ok. Thank you for helping us. I'm good to go alone. Ah and good luck also."; + npctalk strnpcinfo(1) +" : That's ok. Thank you for helping us. I'm good to go alone. Ah and good luck also."; donpcevent instance_npcname("Hollgrehenn Destroyer")+"::OnDisable"; donpcevent instance_npcname("#ghmemorialmob03")+"::OnEnable"; close; @@ -1172,13 +1172,13 @@ OnEnable: hideoffnpc instance_npcname("Heinrich#ghinstance4"); end; OnTalk1: - npctalk "Himmelmez! I won't let you take even a single more step here."; + npctalk strnpcinfo(1) +" : Himmelmez! I won't let you take even a single more step here."; end; OnTalk2: - npctalk "What... is this?!"; + npctalk strnpcinfo(1) +" : What... is this?!"; end; OnTalk3: - npctalk "Varmunt Sir! Help the adventurers and I'll chase Himmelmez!"; + npctalk strnpcinfo(1) +" : Varmunt Sir! Help the adventurers and I'll chase Himmelmez!"; end; } @@ -1197,22 +1197,22 @@ OnEnable: hideoffnpc instance_npcname("Himmelmez#ghinstance2"); end; OnTalk1: - npctalk "What an awfully lucky, I flew all the way over here and just one of them is really powerful."; + npctalk strnpcinfo(1) +" : What an awfully lucky, I flew all the way over here and just one of them is really powerful."; end; OnTalk2: - npctalk "But it doesn't matter to me."; + npctalk strnpcinfo(1) +" : But it doesn't matter to me."; end; OnTalk3: - npctalk "Now, all of you will die."; + npctalk strnpcinfo(1) +" : Now, all of you will die."; end; OnTalk4: - npctalk "Hahaha, so you guys thought I would come alone?"; + npctalk strnpcinfo(1) +" : Hahaha, so you guys thought I would come alone?"; end; OnTalk5: - npctalk "This is my new toy to keep you at my feet. Why don't you guys play while I entertain?"; + npctalk strnpcinfo(1) +" : This is my new toy to keep you at my feet. Why don't you guys play while I entertain?"; end; OnTalk6: - npctalk "Sincerely~, If I am given the opportunity I'd like to meet you again, Heinrich."; + npctalk strnpcinfo(1) +" : Sincerely~, If I am given the opportunity I'd like to meet you again, Heinrich."; end; } @@ -1243,10 +1243,10 @@ OnEnable: hideoffnpc instance_npcname("Varmunt#ghinstance3"); end; OnTalk1: - npctalk "Heinrich Sir! Something unknown holds an inexplicably powerful force!"; + npctalk strnpcinfo(1) +" : Heinrich Sir! Something unknown holds an inexplicably powerful force!"; end; OnTalk2: - npctalk "From the monster I picked up some great stuff. People who are interested, talk to me."; + npctalk strnpcinfo(1) +" : From the monster I picked up some great stuff. People who are interested, talk to me."; end; } @@ -1268,19 +1268,19 @@ OnEnable: hideoffnpc instance_npcname("Heinrich#ghinstance5"); end; OnTalk1: - npctalk "These things have never been in the castle!"; + npctalk strnpcinfo(1) +" : These things have never been in the castle!"; end; OnTalk2: - npctalk "Trying to break this power with common weapons doesn't work. I tried it."; + npctalk strnpcinfo(1) +" : Trying to break this power with common weapons doesn't work. I tried it."; end; OnTalk3: - npctalk "It is really unforgivable."; + npctalk strnpcinfo(1) +" : It is really unforgivable."; end; OnTalk4: - npctalk "I, who already was a subordinate of genocide. How much more in the future..."; + npctalk strnpcinfo(1) +" : I, who already was a subordinate of genocide. How much more in the future..."; end; OnTalk5: - npctalk "..."; + npctalk strnpcinfo(1) +" : ..."; end; } @@ -1299,52 +1299,52 @@ OnEnable: hideoffnpc instance_npcname("Varmunt#ghinstance4"); end; OnTalk2: - npctalk "Himmelmez's enchantment has completely blocked the passage to each section."; + npctalk strnpcinfo(1) +" : Himmelmez's enchantment has completely blocked the passage to each section."; end; OnTalk3: - npctalk "Get out of the way for a moment. I'll try to somehow break the spell with magical powers."; + npctalk strnpcinfo(1) +" : Get out of the way for a moment. I'll try to somehow break the spell with magical powers."; end; OnTalk4: - npctalk "The enchantment seems to be broken."; + npctalk strnpcinfo(1) +" : The enchantment seems to be broken."; end; OnTalk5: - npctalk "I've never seen this spell before."; + npctalk strnpcinfo(1) +" : I've never seen this spell before."; end; OnTalk6: - npctalk "Himmelmez doesn't use a seal on a person's body to turn it into an undead."; + npctalk strnpcinfo(1) +" : Himmelmez doesn't use a seal on a person's body to turn it into an undead."; end; OnTalk7: - npctalk "She uses enchantment stones.This way, the spell is probably maintained."; + npctalk strnpcinfo(1) +" : She uses enchantment stones.This way, the spell is probably maintained."; end; OnTalk8: - npctalk "We should kill the people who have the enchantment stones to break the spell."; + npctalk strnpcinfo(1) +" : We should kill the people who have the enchantment stones to break the spell."; end; OnTalk9: - npctalk "However, we can't identify them. The purification can only be done randomly."; + npctalk strnpcinfo(1) +" : However, we can't identify them. The purification can only be done randomly."; end; OnTalk10: - npctalk "Commandant..."; + npctalk strnpcinfo(1) +" : Commandant..."; end; OnTalk11: - npctalk "Commandant, it seems too loose."; + npctalk strnpcinfo(1) +" : Commandant, it seems too loose."; end; OnTalk12: - npctalk "We are related to all these people, not just a few."; + npctalk strnpcinfo(1) +" : We are related to all these people, not just a few."; end; OnTalk13: - npctalk "We can't deny that it's not their fault for what is going on."; + npctalk strnpcinfo(1) +" : We can't deny that it's not their fault for what is going on."; end; OnTalk14: - npctalk "Well, let's do it then."; + npctalk strnpcinfo(1) +" : Well, let's do it then."; end; OnTalk15: - npctalk "You guys are of a great help. Try to follow us."; + npctalk strnpcinfo(1) +" : You guys are of a great help. Try to follow us."; end; OnTalk16: - npctalk "There can be a tough fight. Hold on, and it would be nice to eat something."; + npctalk strnpcinfo(1) +" : There can be a tough fight. Hold on, and it would be nice to eat something."; end; OnTalk17: - npctalk "Guys. It is time to depart, Heinrich Sir."; + npctalk strnpcinfo(1) +" : Guys. It is time to depart, Heinrich Sir."; end; } @@ -1665,22 +1665,22 @@ OnEnable: hideoffnpc instance_npcname("Heinrich#ghinstance6"); end; OnTalk1: - npctalk "Gerhard!"; + npctalk strnpcinfo(1) +" : Gerhard!"; end; OnTalk2: - npctalk "What are you doing to my men, Himmelmez?!"; + npctalk strnpcinfo(1) +" : What are you doing to my men, Himmelmez?!"; end; OnTalk3: - npctalk "Himmelmez! You don't need to make any more sacrifices!"; + npctalk strnpcinfo(1) +" : Himmelmez! You don't need to make any more sacrifices!"; end; OnTalk4: - npctalk "Let him go! I don't want one more sacrifice!"; + npctalk strnpcinfo(1) +" : Let him go! I don't want one more sacrifice!"; end; OnTalk5: - npctalk "I will not forgive you."; + npctalk strnpcinfo(1) +" : I will not forgive you."; end; OnTalk6: - npctalk "Just leave us alone, Himmelmez!!"; + npctalk strnpcinfo(1) +" : Just leave us alone, Himmelmez!!"; end; } @@ -1700,7 +1700,7 @@ OnEnable: hideoffnpc instance_npcname("Varmunt#ghinstance5"); end; OnTalk1: - npctalk "What? This cannot be. We must prevent Amdarias's attacks!"; + npctalk strnpcinfo(1) +" : What? This cannot be. We must prevent Amdarias's attacks!"; end; } @@ -1714,37 +1714,37 @@ OnEnable: hideoffnpc instance_npcname("Himmelmez#ghinstance4"); end; OnTalk1: - npctalk "Great~ I thought you wouldn't come near the end..."; + npctalk strnpcinfo(1) +" : Great~ I thought you wouldn't come near the end..."; end; OnTalk2: - npctalk "Huhu, I have already found a piece of Ymir's Heart, Heinrich."; + npctalk strnpcinfo(1) +" : Huhu, I have already found a piece of Ymir's Heart, Heinrich."; end; OnTalk3: - npctalk "It would've been faster if there were no distractions."; + npctalk strnpcinfo(1) +" : It would've been faster if there were no distractions."; end; OnTalk4: - npctalk "What do you think? Making it look like an accidental disease infected the king and the people around..."; + npctalk strnpcinfo(1) +" : What do you think? Making it look like an accidental disease infected the king and the people around..."; end; OnTalk5: - npctalk "You want that?"; + npctalk strnpcinfo(1) +" : You want that?"; end; OnTalk6: - npctalk "This one is your final blow, Heinrich."; + npctalk strnpcinfo(1) +" : This one is your final blow, Heinrich."; end; OnTalk7: - npctalk "It is said that stopping me requires a skillfull person."; + npctalk strnpcinfo(1) +" : It is said that stopping me requires a skillfull person."; end; OnTalk8: - npctalk "Seems like a perfect scenario to make my new monster, Amdarias."; + npctalk strnpcinfo(1) +" : Seems like a perfect scenario to make my new monster, Amdarias."; end; OnTalk9: - npctalk "Booh~ I'm scared."; + npctalk strnpcinfo(1) +" : Booh~ I'm scared."; end; OnTalk10: - npctalk "Anyway, it was nice talking to you. Maybe we'll have the chance to meet again in the next story."; + npctalk strnpcinfo(1) +" : Anyway, it was nice talking to you. Maybe we'll have the chance to meet again in the next story."; end; OnTalk11: - npctalk "Well, make sure you will come back again."; + npctalk strnpcinfo(1) +" : Well, make sure you will come back again."; end; } @@ -1795,13 +1795,13 @@ OnEnable: hideoffnpc instance_npcname("Gerhard#ghinstance1"); end; OnTalk1: - npctalk "Damn it! Run away! I can't withstand anymore!"; + npctalk strnpcinfo(1) +" : Damn it! Run away! I can't withstand anymore!"; end; OnTalk2: - npctalk "Commandant... Come on, you need to run away from here... Ugh."; + npctalk strnpcinfo(1) +" : Commandant... Come on, you need to run away from here... Ugh."; end; OnTalk3: - npctalk "Even if you defile my body, I won't let you take my soul, Himmelmez!"; + npctalk strnpcinfo(1) +" : Even if you defile my body, I won't let you take my soul, Himmelmez!"; end; OnEffect1: specialeffect EF_BARRIER; diff --git a/npc/re/jobs/novice/academy.txt b/npc/re/jobs/novice/academy.txt index d044a03392..2fbc31cc73 100644 --- a/npc/re/jobs/novice/academy.txt +++ b/npc/re/jobs/novice/academy.txt @@ -4722,16 +4722,16 @@ iz_ac01,43,80,7 script Adventurer's Pet#ac 4_DEVIRUCHI,{ OnTimer60000: switch(rand(1,4)) { case 1: - npctalk "Yawn~ I am so bored!"; + npctalk strnpcinfo(1) +" : Yawn~ I am so bored!"; break; case 2: - npctalk "Red Potion.. Is it delicious? Herb does not look delicious.. I bet that is bitter."; + npctalk strnpcinfo(1) +" : Red Potion.. Is it delicious? Herb does not look delicious.. I bet that is bitter."; break; case 3: - npctalk "Ha. You are lucky to have this Devi."; + npctalk strnpcinfo(1) +" : Ha. You are lucky to have this Devi."; break; case 4: - npctalk "Isn't the floor cold? Well.. For me, Undead is more familiar."; + npctalk strnpcinfo(1) +" : Isn't the floor cold? Well.. For me, Undead is more familiar."; break; } diff --git a/src/map/script.c b/src/map/script.c index 6a86d0e523..a55f518cc3 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -14252,18 +14252,13 @@ BUILDIN_FUNC(message) *------------------------------------------*/ BUILDIN_FUNC(npctalk) { - const char* str; - struct npc_data* nd = (struct npc_data *)map_id2bl(st->oid); - str = script_getstr(st,2); + const char* str = script_getstr(st,2); - if(nd) - { - char name[NAME_LENGTH], message[256]; - safestrncpy(name, nd->name, sizeof(name)); - strtok(name, "#"); // discard extra name identifier if present - safesnprintf(message, sizeof(message), "%s : %s", name, str); - clif_disp_overhead(&nd->bl, message); + if (nd) { + char message[256]; + safesnprintf(message, sizeof(message), "%s", str); + clif_disp_overhead(&nd->bl, str); } return SCRIPT_CMD_SUCCESS; } @@ -17769,7 +17764,7 @@ BUILDIN_FUNC(unittalk) struct StringBuf sbuf; StringBuf_Init(&sbuf); - StringBuf_Printf(&sbuf, "%s : %s", status_get_name(bl), message); + StringBuf_Printf(&sbuf, "%s", message); clif_disp_overhead(bl, StringBuf_Value(&sbuf)); StringBuf_Destroy(&sbuf); } From dc679b8c06338d380d0caed9303faf1538093c04 Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Mon, 29 Feb 2016 19:50:24 +0700 Subject: [PATCH 004/319] Follow up d9a35c8c6a7c08d5397647cb0ae470bd5692898d * A little check to avoid unnecessary process. Signed-off-by: Cydh Ramdh --- src/map/skill.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/map/skill.c b/src/map/skill.c index db72044934..0844fa19cd 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4229,9 +4229,11 @@ static int skill_reveal_trap(struct block_list *bl, va_list ap) * @param range Affected range * @param x * @param y - * TODO: Remove this hardcodes + * TODO: Remove hardcode usages for this function **/ void skill_reveal_trap_inarea(struct block_list *src, int range, int x, int y) { + if (!battle_config.traps_setting) + return; nullpo_retv(src); map_foreachinarea(skill_reveal_trap, src->m, x-range, y-range, x+range, y+range, BL_SKILL); } From 7e66be59320fa32c8c0ec58174847298ff98a69e Mon Sep 17 00:00:00 2001 From: Atemo Date: Mon, 29 Feb 2016 19:45:45 +0100 Subject: [PATCH 005/319] Replace strnpcinfo(1) by the current npc name and fix some mistake Signed-off-by: Atemo --- npc/custom/etc/marriage.txt | 42 +++--- npc/custom/events/cluckers.txt | 16 +- npc/custom/events/disguise.txt | 4 +- npc/custom/item_signer.txt | 2 +- npc/re/cities/izlude.txt | 64 ++++---- npc/re/instances/OldGlastHeim.txt | 234 +++++++++++++++--------------- npc/re/jobs/novice/academy.txt | 8 +- 7 files changed, 185 insertions(+), 185 deletions(-) diff --git a/npc/custom/etc/marriage.txt b/npc/custom/etc/marriage.txt index e1a3b6204a..5a3db0e248 100644 --- a/npc/custom/etc/marriage.txt +++ b/npc/custom/etc/marriage.txt @@ -104,11 +104,11 @@ prt_church,100,123,4 script Vomars 60,{ mes "I am going to wed "+$wed_groom$+" and "+$wed_bride$+", do you have an objection to it?"; if (select("Sorry, please go on.","Yes, I actually do.") == 2) { //Abort - npctalk strnpcinfo(1) +" : Ladies and gentlemen, "+strcharinfo(0)+" has an objection to the wedding!"; + npctalk @name$ +" : Ladies and gentlemen, "+strcharinfo(0)+" has an objection to the wedding!"; SF_wed_end(); mes "Why should they not be wed?"; input $@msg$; - npctalk strcharinfo(0)+"'s objection is: "+$@msg$; + npctalk @name$ +" : "+ strcharinfo(0) +"'s objection is: "+$@msg$; emotion e_sob; mes "I see..."; } else @@ -203,7 +203,7 @@ function SF_AcceptGroom { mes "Ah... err... ehm... okay. You two seem to have some differences to settle first."; close2; emotion e_omg; - npctalk strnpcinfo(1) +" : Ladies and gentlemen, "+$wed_bride$+" has rejected to marry "+$wed_groom$+"!"; + npctalk @name$ +" : Ladies and gentlemen, "+$wed_bride$+" has rejected to marry "+$wed_groom$+"!"; SF_wed_end(); break; case 3: @@ -236,7 +236,7 @@ function SF_AcceptBride { mes "Ah... err... ehm... okay. You two seem to have some differences to settle first."; emotion e_omg; close2; - npctalk strnpcinfo(1) +" : Ladies and gentlemen, "+$wed_groom$+" has rejected to marry "+$wed_bride$+"!"; + npctalk @name$ +" : Ladies and gentlemen, "+$wed_groom$+" has rejected to marry "+$wed_bride$+"!"; SF_wed_end(); break; case 3: @@ -260,7 +260,7 @@ function SF_RingsAccepted { announce $wed_groom$+" and "+$wed_bride$+"'s wedding ceremony will be held at the church!",8; close2; emotion e_lv; - npctalk strnpcinfo(1) +" : May the groom and bride please step forward and retrieve their rings?"; + npctalk @name$ +" : May the groom and bride please step forward and retrieve their rings?"; } function SF_RetrieveRingM { @@ -336,51 +336,51 @@ function SF_StartCeremony { } OnTimer1000: - npctalk strnpcinfo(1) +" : Ladies and Gentlemen, We will now join in holy matrimony these two lovers."; + npctalk @name$ +" : Ladies and Gentlemen, We will now join in holy matrimony these two lovers."; end; OnTimer5000: - npctalk strnpcinfo(1) +" : Now more than ever, will both of your lives be entwined together as so will be your souls."; + npctalk @name$ +" : Now more than ever, will both of your lives be entwined together as so will be your souls."; end; OnTimer10000: - npctalk strnpcinfo(1) +" : You will both honor and cherish each other through the best and worst of times."; + npctalk @name$ +" : You will both honor and cherish each other through the best and worst of times."; end; OnTimer15000: - npctalk strnpcinfo(1) +" : The safety and well being of your other will now also be your responsibility."; + npctalk @name$ +" : The safety and well being of your other will now also be your responsibility."; end; OnTimer20000: - npctalk strnpcinfo(1) +" : May in sickness or good health, your love burn bright like no force can extinguish it."; + npctalk @name$ +" : May in sickness or good health, your love burn bright like no force can extinguish it."; end; OnTimer25000: - npctalk strnpcinfo(1) +" : Those here stand witness to these vows bestowed upon you, you must act accordingly to them."; + npctalk @name$ +" : Those here stand witness to these vows bestowed upon you, you must act accordingly to them."; end; OnTimer30000: - npctalk strnpcinfo(1) +" : Understanding that, we are nothing more but mortals on this earth, but this is our triumph."; + npctalk @name$ +" : Understanding that, we are nothing more but mortals on this earth, but this is our triumph."; end; OnTimer35000: - npctalk strnpcinfo(1) +" : We here will now join these two mortal entities, and create an immortal love."; + npctalk @name$ +" : We here will now join these two mortal entities, and create an immortal love."; end; OnTimer40000: - npctalk $wed_groom$+", you have accepted to take "+$wed_bride$+" as your lawfully wedded wife,"; + npctalk @name$ +" : "+ $wed_groom$ +", you have accepted to take "+$wed_bride$+" as your lawfully wedded wife,"; end; OnTimer45000: - npctalk strnpcinfo(1) +" : and you, "+$wed_bride$+", have accepted take "+$wed_groom$+" as your lawfully wedded husband."; + npctalk @name$ +" : and you, "+$wed_bride$+", have accepted take "+$wed_groom$+" as your lawfully wedded husband."; end; OnTimer50000: - npctalk strnpcinfo(1) +" : And as such, now, by the powers vested in me..."; + npctalk @name$ +" : And as such, now, by the powers vested in me..."; end; OnTimer55000: - npctalk strnpcinfo(1) +" : I pronounce you Husband and Wife, you may kiss the bride and exchange rings."; + npctalk @name$ +" : I pronounce you Husband and Wife, you may kiss the bride and exchange rings."; if ($wedding_effect_id && isloggedin($wedding_effect_id)) { attachrid($wedding_effect_id); @@ -561,7 +561,7 @@ function SF_WedProgress { mes "Very well, now go to the Priest to reaffirm your vows and the ceremony will begin."; emotion e_no1; close2; - npctalk strnpcinfo(1) +" : Registration finished. "+$wed_groom$+" and "+$wed_bride$+", please reaffirm your vows with the Priest."; + npctalk @name$ +" : Registration finished. "+$wed_groom$+" and "+$wed_bride$+", please reaffirm your vows with the Priest."; emotion e_no1; end; } else { @@ -582,7 +582,7 @@ function SF_WedProgress { mes "Very well, now go to the Priest to reaffirm your vows and the ceremony will begin."; emotion e_no1; close2; - npctalk strnpcinfo(1) +" : Registration finished. "+$wed_groom$+" and "+$wed_bride$+", please reaffirm your vows with the Priest."; + npctalk @name$ +" : Registration finished. "+$wed_groom$+" and "+$wed_bride$+", please reaffirm your vows with the Priest."; emotion e_no1; end; } else { @@ -658,7 +658,7 @@ OnTimer60000: else set $@msg$, $wed_groom$; - npctalk strnpcinfo(1) +" : Registration timed out. Is it that noone wants to marry "+$@msg$+"..?"; + npctalk @name$ +" : Registration timed out. Is it that noone wants to marry "+$@msg$+"..?"; emotion e_hmm; set $wed_groom$,""; @@ -930,7 +930,7 @@ function SF_DivorceEnd { } OnTimer60000: - npctalk strnpcinfo(1) +" : Divorce confirmation time's is up. Where did "+$@divorcer$+"'s spouse go..."; + npctalk @name$ +" : Divorce confirmation time's is up. Where did "+$@divorcer$+"'s spouse go..."; emotion e_what; SF_DivorceEnd(); end; diff --git a/npc/custom/events/cluckers.txt b/npc/custom/events/cluckers.txt index ffc56b49da..9d375f6d86 100644 --- a/npc/custom/events/cluckers.txt +++ b/npc/custom/events/cluckers.txt @@ -26,29 +26,29 @@ prontera,156,219,4 script Cluckers 800,{ if (.startcluck) { specialeffect2 EF_HIT3; switch(rand(15)) { - case 0: npctalk strnpcinfo(1) +" : CLUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; - case 1: npctalk strnpcinfo(1) +" : Cluuuuuck!~"; break; + case 0: npctalk "Cluckers : CLUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; + case 1: npctalk "Cluckers : Cluuuuuck!~"; break; case 2: unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; break; case 3: sc_start SC_Freeze,10000,0; break; - case 4: npctalk strnpcinfo(1) +" : CLUUUUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; + case 4: npctalk "Cluckers : CLUUUUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; case 5: sc_start SC_Sleep,10000,0; break; case 6: sc_start SC_Stone,10000,0; emotion e_gg; break; - case 7: npctalk strnpcinfo(1) +" : CLUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; - case 8: npctalk strnpcinfo(1) +" : Cluck! CLUUUCK!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; + case 7: npctalk "Cluckers : CLUUUUUUCK!!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; + case 8: npctalk "Cluckers : Cluck! CLUUUCK!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; emotion e_omg; break; case 9: sc_start SC_Stun,10000,0; break; case 10: sc_start SC_Sleep,10000,0; emotion e_gg; break; - case 11: npctalk strnpcinfo(1) +" : Cluck! Cluck!"; break; + case 11: npctalk "Cluckers : Cluck! Cluck!"; break; case 12: sc_start SC_Stun,10000,0; break; case 13: unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; break; default: if (rand(50) < 4) { - npctalk strnpcinfo(1) +" : WOOF!..........."; + npctalk "Cluckers : WOOF!..........."; specialeffect2 EF_SPHERE; announce "[Cluck! Cluck! Boom!] " + strcharinfo(0) + " squeezed out the prize! Well done!",0; getitem $cluck_item_id,$cluck_item_amount; set .startcluck,0; } else { - npctalk strnpcinfo(1) +" : Cluck! CLUUUCK!!"; + npctalk "Cluckers : Cluck! CLUUUCK!!"; unitkill getcharid(3); skilleffect "NPC_SELFDESTRUCTION",1; } break; diff --git a/npc/custom/events/disguise.txt b/npc/custom/events/disguise.txt index 355487dd17..5c858bd815 100644 --- a/npc/custom/events/disguise.txt +++ b/npc/custom/events/disguise.txt @@ -177,7 +177,7 @@ OnTimer30000: if (.Timer) end; set .Change,0; setnpcdisplay "Disguise Event",795; - npctalk strnpcinfo(1) +" : You took too long to guess what I was. Please wait 10 seconds while I disguise again."; + npctalk "Disguise Event : You took too long to guess what I was. Please wait 10 seconds while I disguise again."; specialeffect EF_DETECT2; set $MonsterName$,""; deletepset 1; @@ -238,7 +238,7 @@ iCorrect: setnpcdisplay "Disguise Event",795; set .RoundCount,0; set .Change,0; set .EventON,0; setnpctimer 0; stopnpctimer; - npctalk strnpcinfo(1) +" : Thank you all for playing. That was the last round of the Disguise Event. Come play again later."; + npctalk "Disguise Event : Thank you all for playing. That was the last round of the Disguise Event. Come play again later."; end; } setnpcdisplay "Disguise Event",795; diff --git a/npc/custom/item_signer.txt b/npc/custom/item_signer.txt index b52d346ff4..6bd94dd274 100644 --- a/npc/custom/item_signer.txt +++ b/npc/custom/item_signer.txt @@ -118,7 +118,7 @@ prt_in,24,61,7 script Perchik 47,{ } if (!countitem2(.@id,1,.@ref,0,.@slot[0],.@slot[1],.@slot[2],.@slot[3])) { mes "Where is "+getitemname(@id)+"...?"; - npctalk strnpcinfo(1) +" : You're a snoozy cheater!"; + npctalk "Perchik : You're a snoozy cheater!"; logmes "Hack: Tried to sign an item not having it: "+getitemname(@id); emotion e_wah; close; diff --git a/npc/re/cities/izlude.txt b/npc/re/cities/izlude.txt index b56bef515e..611eb433c9 100644 --- a/npc/re/cities/izlude.txt +++ b/npc/re/cities/izlude.txt @@ -112,59 +112,59 @@ izlude,143,205,7 script Talkative Kid#iz 4_F_KID2,{ end; OnTimer64000: - npctalk strnpcinfo(1) +" : I used all my Novice Red Potions. What should I do?"; + npctalk "Talkative Kid : I used all my Novice Red Potions. What should I do?"; end; OnTimer72000: - npctalk strnpcinfo(1) +" : Where is the shop?"; + npctalk "Talkative Kid : Where is the shop?"; end; OnTimer136000: - npctalk strnpcinfo(1) +" : Idiot! You do not know about the 'shortcut window'?"; + npctalk "Talkative Kid : Idiot! You do not know about the 'shortcut window'?"; end; OnTimer144000: - npctalk strnpcinfo(1) +" : The items in your inventory can be dragged and put in the shortcut window."; + npctalk "Talkative Kid : The items in your inventory can be dragged and put in the shortcut window."; end; OnTimer212000: - npctalk strnpcinfo(1) +" : I got so many beginner's items in the Academy!"; + npctalk "Talkative Kid : I got so many beginner's items in the Academy!"; end; OnTimer276000: - npctalk strnpcinfo(1) +" : They even gave me weapons and a shield!"; + npctalk "Talkative Kid : They even gave me weapons and a shield!"; end; OnTimer284000: - npctalk strnpcinfo(1) +" : Just press to open the map you have."; + npctalk "Talkative Kid : Just press to open the map you have."; end; OnTimer344000: - npctalk strnpcinfo(1) +" : Then do you want to go Criatura Academy with me? I'm learning how to battle from Instructor Subino!"; + npctalk "Talkative Kid : Then do you want to go Criatura Academy with me? I'm learning how to battle from Instructor Subino!"; end; OnTimer348000: - npctalk strnpcinfo(1) +" : The Academy is in North side of Izlude. Let's go~!"; + npctalk "Talkative Kid : The Academy is in North side of Izlude. Let's go~!"; end; OnTimer416000: - npctalk strnpcinfo(1) +" : It's a system to guide you to a destination."; + npctalk "Talkative Kid : It's a system to guide you to a destination."; end; OnTimer424000: - npctalk strnpcinfo(1) +" : In the basic menu, please click the [Navigation] button."; + npctalk "Talkative Kid : In the basic menu, please click the [Navigation] button."; end; OnTimer492000: - npctalk strnpcinfo(1) +" : Whee, Ain't gonna use your brain? Please type /where in the chat window now!"; + npctalk "Talkative Kid : Whee, Ain't gonna use your brain? Please type /where in the chat window now!"; end; OnTimer552000: - npctalk strnpcinfo(1) +" : In this case, you can push the key."; + npctalk "Talkative Kid : In this case, you can push the key."; end; OnTimer560000: - npctalk strnpcinfo(1) +" : We are just repeating the same dialog. HaHaha."; + npctalk "Talkative Kid : We are just repeating the same dialog. HaHaha."; end; OnTimer565000: @@ -182,67 +182,67 @@ izlude,146,205,7 script Talkative Adventurer#iz 4_M_KID1,{ end; OnTimer69000: - npctalk strnpcinfo(1) +" : You can buy potion from Merchants."; + npctalk "Talkative Adventurer : You can buy potion from Merchants."; end; OnTimer77000: - npctalk strnpcinfo(1) +" : It's the Potion image in the mini map."; + npctalk "Talkative Adventurer : It's the Potion image in the mini map."; end; OnTimer131000: - npctalk strnpcinfo(1) +" : Is there any way to use items easily?"; + npctalk "Talkative Adventurer : Is there any way to use items easily?"; end; OnTimer141000: - npctalk strnpcinfo(1) +" : Shortcut window? The slots at the top of the screen? How can I use it?"; + npctalk "Talkative Adventurer : Shortcut window? The slots at the top of the screen? How can I use it?"; end; OnTimer149000: - npctalk strnpcinfo(1) +" : For inventory, do you mean 'item' menu? Oh, it is!"; + npctalk "Talkative Adventurer : For inventory, do you mean 'item' menu? Oh, it is!"; end; OnTimer217000: - npctalk strnpcinfo(1) +" : I have a bunch of potions?"; + npctalk "Talkative Adventurer : I have a bunch of potions?"; end; OnTimer281000: - npctalk strnpcinfo(1) +" : What?! I should go to the Academy now!"; + npctalk "Talkative Adventurer : What?! I should go to the Academy now!"; end; OnTimer279000: - npctalk strnpcinfo(1) +" : Where is Izlude? In the center?"; + npctalk "Talkative Adventurer : Where is Izlude? In the center?"; end; OnTimer339000: - npctalk strnpcinfo(1) +" : I do not know what to do."; + npctalk "Talkative Adventurer : I do not know what to do."; end; OnTimer349000: - npctalk strnpcinfo(1) +" : Oh yea? I want to know so many things~ I will go with you!"; + npctalk "Talkative Adventurer : Oh yea? I want to know so many things~ I will go with you!"; end; OnTimer411000: - npctalk strnpcinfo(1) +" : Navigation, What is that?"; + npctalk "Talkative Adventurer : Navigation, What is that?"; end; OnTimer421000: - npctalk strnpcinfo(1) +" : Oh-! Should I search for a Kafra Employee?"; + npctalk "Talkative Adventurer : Oh-! Should I search for a Kafra Employee?"; end; OnTimer487000: - npctalk strnpcinfo(1) +" : What is the town name?"; + npctalk "Talkative Adventurer : What is the town name?"; end; OnTimer497000: - npctalk strnpcinfo(1) +" : I cannot see the part where I can write something in the chat window?"; + npctalk "Talkative Adventurer : I cannot see the part where I can write something in the chat window?"; end; OnTimer557000: - npctalk strnpcinfo(1) +" : Oh you smarty..."; + npctalk "Talkative Adventurer : Oh you smarty..."; end; OnTimer555000: - npctalk strnpcinfo(1) +" : A while ago, one Novice talked to me like hey 'Talkative Adventurer'?. HaHaha."; + npctalk "Talkative Adventurer : A while ago, one Novice talked to me like hey 'Talkative Adventurer'?. HaHaha."; end; OnTimer565000: @@ -260,11 +260,11 @@ prt_fild08,338,217,7 script Resting Adventurer#iz 4_F_SITDOWN,{ end; OnTimer60000: - npctalk strnpcinfo(1) +" : You know what? If you are sitting, HP and SP recovery is faster."; + npctalk "Resting Adventurer : You know what? If you are sitting, HP and SP recovery is faster."; end; OnTimer65000: - npctalk strnpcinfo(1) +" : Sitting is possible if your basic job skill level is more than 3. Shortcut is pressing the key."; + npctalk "Resting Adventurer : Sitting is possible if your basic job skill level is more than 3. Shortcut is pressing the key."; OnInit: initnpctimer; end; diff --git a/npc/re/instances/OldGlastHeim.txt b/npc/re/instances/OldGlastHeim.txt index 2093e39113..73def91209 100644 --- a/npc/re/instances/OldGlastHeim.txt +++ b/npc/re/instances/OldGlastHeim.txt @@ -94,7 +94,7 @@ glast_01,204,273,6 script Hugin#ghinstance 755,{ 1@gl_k,149,41,6 script Varmunt#ghinstance1 654,{ if (getcharid(0) == getpartyleader(getcharid(1),2)) { mes "Hey ^0000ffguys^000000, were you sent here to help me?"; - npctalk strnpcinfo(1) +" : Hey guys, were you sent here to help me?"; + npctalk "Varmunt : Hey guys, were you sent here to help me?"; cutin "gl_barmund1",2; next; select("Oh. Well, about that..."); @@ -104,7 +104,7 @@ glast_01,204,273,6 script Hugin#ghinstance 755,{ next; mes "[Varmunt]"; mes "We don't have time. We must tell Sir Heinrich about Himmelmez's invasion."; - npctalk strnpcinfo(1) +" : We don't have time. We must tell Sir Heinrich about Himmelmez's invasion."; + npctalk "Varmunt : We don't have time. We must tell Sir Heinrich about Himmelmez's invasion."; cutin "gl_barmund2",2; next; select("What Himmelmez..."); @@ -114,21 +114,21 @@ glast_01,204,273,6 script Hugin#ghinstance 755,{ next; mes "[Varmunt]"; mes "Didn't anybody give you the basic informations?"; - npctalk strnpcinfo(1) +" : Didn't anybody give you the basic informations?"; + npctalk "Varmunt : Didn't anybody give you the basic informations?"; cutin "gl_barmund3",2; next; mes "[Varmunt]"; mes "The Valkyrie of the dead. She's after the Ymir's Heart pieces hidden here."; - npctalk strnpcinfo(1) +" : The Valkyrie of the dead. She's after the Ymir's Heart pieces hidden here"; + npctalk "Varmunt : The Valkyrie of the dead. She's after the Ymir's Heart pieces hidden here"; cutin "gl_barmund2",2; next; mes "[Varmunt]"; mes "She's capable of destroying the whole castle for this purpose."; - npctalk strnpcinfo(1) +" : She's capable of destroying the whole castle for this purpose."; + npctalk "Varmunt : She's capable of destroying the whole castle for this purpose."; next; mes "[Varmunt]"; mes "Hurry up! Inform Sir Heinrich that Himmelmez is coming. I will briefly explore the enchantments she made to this place!"; - npctalk strnpcinfo(1) +" : Hurry up! Inform Sir Heinrich that Himmelmez is coming. I will briefly explore the enchantments she made to this place!"; + npctalk "Varmunt : Hurry up! Inform Sir Heinrich that Himmelmez is coming. I will briefly explore the enchantments she made to this place!"; close2; cutin "gl_barmund2",255; donpcevent instance_npcname("Varmunt#ghinstance1")+"::OnDisable2"; @@ -224,11 +224,11 @@ OnEnable: next; mes "[Heinrich]"; mes "You are the adventurers who have come with Varmunt, right?"; - npctalk strnpcinfo(1) +" : You are the adventurers who have come with Varmunt, right?"; + npctalk "Heinrich : You are the adventurers who have come with Varmunt, right?"; next; mes "[Heinrich]"; mes "What can I do for you? Is there something wrong?"; - npctalk strnpcinfo(1) +" : What can I do for you? Is there something wrong?"; + npctalk "Heinrich : What can I do for you? Is there something wrong?"; next; select("The Ymir's Heart. Himmelmez..."); mes "["+strcharinfo(0)+"]"; @@ -237,7 +237,7 @@ OnEnable: next; mes "[Heinrich]"; mes "Haha. That's a nice joke. Now tell me what brings you here."; - npctalk strnpcinfo(1) +" : Haha. That's a nice joke. Now tell me what brings you here."; + npctalk "Heinrich : Haha. That's a nice joke. Now tell me what brings you here."; cutin "gl_heinrich1",2; next; mes "[Varmunt]"; @@ -257,12 +257,12 @@ OnEnable: next; mes "[Heinrich]"; mes "I will be glad if you give me two minutes, please. But now the king isn't in his room."; - npctalk strnpcinfo(1) +" : I will be glad if you give me two minutes, please. But now the king isn't in his room."; + npctalk "Heinrich : I will be glad if you give me two minutes, please. But now the king isn't in his room."; cutin "gl_heinrich1",2; next; mes "[Heinrich]"; mes "But I think that with such a busy agenda, he won't be able to take care of this."; - npctalk strnpcinfo(1) +" : But I think that with such a busy agenda, he won't be able to take care of this."; + npctalk "Heinrich : But I think that with such a busy agenda, he won't be able to take care of this."; donpcevent instance_npcname("Heinrich#ghinstance1")+"::OnDisable"; donpcevent instance_npcname("Heinrich#ghinstance2")+"::OnEnable"; donpcevent instance_npcname("Himmelmez#ghinstance1")+"::OnEnable"; @@ -299,25 +299,25 @@ OnEnable: hideoffnpc instance_npcname("Varmunt#ghinstance2"); end; OnTalk1: - npctalk strnpcinfo(1) +" : I am not joking Heinrich, Sir. Now, if my judgement is correct, she will be here soon."; + npctalk "Varmunt : I am not joking Heinrich, Sir. Now, if my judgement is correct, she will be here soon."; end; OnTalk2: - npctalk strnpcinfo(1) +" : I trust this guy following me. The Ymir's Heart pieces must be hidden in a safe place before Himmelmez takes them!"; + npctalk "Varmunt : I trust this guy following me. The Ymir's Heart pieces must be hidden in a safe place before Himmelmez takes them!"; end; OnTalk3: - npctalk strnpcinfo(1) +" : Himmelmez!! Through the cracks!"; + npctalk "Varmunt : Himmelmez!! Through the cracks!"; end; OnTalk4: - npctalk strnpcinfo(1) +" : Unbelievable. My men are...This kind of thing is not possible!"; + npctalk "Varmunt : Unbelievable. My men are...This kind of thing is not possible!"; end; OnTalk5: - npctalk strnpcinfo(1) +" : Heinrich, Sir! I need a quick decision."; + npctalk "Varmunt : Heinrich, Sir! I need a quick decision."; end; OnTalk6: - npctalk strnpcinfo(1) +" : To prevent other attacks, go chase her!"; + npctalk "Varmunt : To prevent other attacks, go chase her!"; end; OnTalk7: - npctalk strnpcinfo(1) +" : Now, your help is desperately needed. I hopefully ask you."; + npctalk "Varmunt : Now, your help is desperately needed. I hopefully ask you."; end; } @@ -331,34 +331,34 @@ OnEnable: hideoffnpc instance_npcname("Heinrich#ghinstance2"); end; OnTalk1: - npctalk strnpcinfo(1) +" : Who?!"; + npctalk "Heinrich : Who?!"; end; OnTalk2: - npctalk strnpcinfo(1) +" : That who rules the dead? No doubt, a pretty story. Here, some tea will be served to entertain the ladies. Unfortunately, I do not..."; + npctalk "Heinrich : That who rules the dead? No doubt, a pretty story. Here, some tea will be served to entertain the ladies. Unfortunately, I do not..."; end; OnTalk3: - npctalk strnpcinfo(1) +" : What did you say?"; + npctalk "Heinrich : What did you say?"; end; OnTalk4: - npctalk strnpcinfo(1) +" : The King responded to the invitation of the Rune Midgard's Royal Family and hasn't come back yet."; + npctalk "Heinrich : The King responded to the invitation of the Rune Midgard's Royal Family and hasn't come back yet."; end; OnTalk5: - npctalk strnpcinfo(1) +" : Just leave before you get in trouble. This is the King's will!"; + npctalk "Heinrich : Just leave before you get in trouble. This is the King's will!"; end; OnTalk6: - npctalk strnpcinfo(1) +" : Damn! She has detected the position of the Ymir's Heart pieces."; + npctalk "Heinrich : Damn! She has detected the position of the Ymir's Heart pieces."; end; OnTalk7: - npctalk strnpcinfo(1) +" : Now, Khalitzburg Crusaders and White Knights, follow me..."; + npctalk "Heinrich : Now, Khalitzburg Crusaders and White Knights, follow me..."; end; OnTalk8: - npctalk strnpcinfo(1) +" : Unbelievable. My men are...This kind of thing is not possible!"; + npctalk "Heinrich : Unbelievable. My men are...This kind of thing is not possible!"; end; OnTalk9: - npctalk strnpcinfo(1) +" : I'm sorry..."; + npctalk "Heinrich : I'm sorry..."; end; OnTalk10: - npctalk strnpcinfo(1) +" : I'm sorry, my lord! Do not forgive me!"; + npctalk "Heinrich : I'm sorry, my lord! Do not forgive me!"; end; } @@ -372,28 +372,28 @@ OnEnable: hideoffnpc instance_npcname("Heinrich#ghinstance3"); end; OnTalk1: - npctalk strnpcinfo(1) +" : I cannot believe I killed my men with my own hands!"; + npctalk "Heinrich : I cannot believe I killed my men with my own hands!"; end; OnTalk2: - npctalk strnpcinfo(1) +" : Varmunt is right about that. Now is not the time to regret."; + npctalk "Heinrich : Varmunt is right about that. Now is not the time to regret."; end; OnTalk3: - npctalk strnpcinfo(1) +" : People, gather around and follow my orders."; + npctalk "Heinrich : People, gather around and follow my orders."; end; OnTalk4: - npctalk strnpcinfo(1) +" : Himmelmez is turning into monsters all the people she put to sleep."; + npctalk "Heinrich : Himmelmez is turning into monsters all the people she put to sleep."; end; OnTalk5: - npctalk strnpcinfo(1) +" : I don't know if there are survivors around here yet."; + npctalk "Heinrich : I don't know if there are survivors around here yet."; end; OnTalk6: - npctalk strnpcinfo(1) +" : If there are survivors from this evil thing, please rescue them."; + npctalk "Heinrich : If there are survivors from this evil thing, please rescue them."; end; OnTalk7: - npctalk strnpcinfo(1) +" : With Varmunt by my side, I'm going to chase Himmelmez down."; + npctalk "Heinrich : With Varmunt by my side, I'm going to chase Himmelmez down."; end; OnTalk8: - npctalk strnpcinfo(1) +" : Hurry up Varmunt, let's chase her down."; + npctalk "Heinrich : Hurry up Varmunt, let's chase her down."; end; } @@ -407,28 +407,28 @@ OnEnable: hideoffnpc instance_npcname("Himmelmez#ghinstance1"); end; OnTalk1: - npctalk strnpcinfo(1) +" : This~ Did I interrupt your conversation? The thing is, it's been too long since the last guests saw some sadness spread..."; + npctalk "Himmelmez : This~ Did I interrupt your conversation? The thing is, it's been too long since the last guests saw some sadness spread..."; end; OnTalk2: - npctalk strnpcinfo(1) +" : My name is Lisa Kahn Himmelmez. I am called the Valkyrie of the dead, master of the Dullahan."; + npctalk "Himmelmez : My name is Lisa Kahn Himmelmez. I am called the Valkyrie of the dead, master of the Dullahan."; end; OnTalk3: - npctalk strnpcinfo(1) +" : There's no need to pretend to be so laid back. Don't bluff about the whereabouts of you Majesty and things will be alright."; + npctalk "Himmelmez : There's no need to pretend to be so laid back. Don't bluff about the whereabouts of you Majesty and things will be alright."; end; OnTalk4: - npctalk strnpcinfo(1) +" : Hohoho, do you have any questions? You're a really mysterious man."; + npctalk "Himmelmez : Hohoho, do you have any questions? You're a really mysterious man."; end; OnTalk5: - npctalk strnpcinfo(1) +" : Not coveting the king's throne, you're such a stupid man, only waiting for his return. Your innocence is true, I love it."; + npctalk "Himmelmez : Not coveting the king's throne, you're such a stupid man, only waiting for his return. Your innocence is true, I love it."; end; Ontalk6: - npctalk strnpcinfo(1) +" : You make me wish we hadn't met in this situation. Too bad we did."; + npctalk "Himmelmez : You make me wish we hadn't met in this situation. Too bad we did."; end; Ontalk7: - npctalk strnpcinfo(1) +" : Well~ Today, with such a busy commandant, I won't be able to talk as much as I'd love for you to contemplate my explanation~"; + npctalk "Himmelmez : Well~ Today, with such a busy commandant, I won't be able to talk as much as I'd love for you to contemplate my explanation~"; end; OnTalk8: - npctalk strnpcinfo(1) +" : I gotta get my job done. Meanwhile why don't you meet my men? Hohoho."; + npctalk "Himmelmez : I gotta get my job done. Meanwhile why don't you meet my men? Hohoho."; end; } @@ -703,18 +703,18 @@ OnEffect1: end; OnTalkK: switch(atoi(replacestr(strnpcinfo(2),"ghinstance",""))) { - case 1: npctalk strnpcinfo(1) +" : I do not want to die."; break; - case 2: npctalk strnpcinfo(1) +" : Mom..."; break; - case 5: npctalk strnpcinfo(1) +" : Help."; break; - case 6: npctalk strnpcinfo(1) +" : My stomach hurts..."; break; - case 9: npctalk strnpcinfo(1) +" : Heinrich Sir, help!"; break; - case 10: npctalk strnpcinfo(1) +" : Ack... Ugh."; break; - case 13: npctalk strnpcinfo(1) +" : I'm thirsty."; break; - case 14: npctalk strnpcinfo(1) +" : Oh... No... I cannot die..."; break; - case 17: npctalk strnpcinfo(1) +" : This is so uncomfortable. Eww!"; break; - case 18: npctalk strnpcinfo(1) +" : Who am I..."; break; - case 21: npctalk strnpcinfo(1) +" : Uhh... My body."; break; - case 22: npctalk strnpcinfo(1) +" : I'm so thirsty!"; break; + case 1: npctalk ". : I do not want to die."; break; + case 2: npctalk ". : Mom..."; break; + case 5: npctalk ". : Help."; break; + case 6: npctalk ". : My stomach hurts..."; break; + case 9: npctalk ". : Heinrich Sir, help!"; break; + case 10: npctalk ". : Ack... Ugh."; break; + case 13: npctalk ". : I'm thirsty."; break; + case 14: npctalk ". : Oh... No... I cannot die..."; break; + case 17: npctalk ". : This is so uncomfortable. Eww!"; break; + case 18: npctalk ". : Who am I..."; break; + case 21: npctalk ". : Uhh... My body."; break; + case 22: npctalk ". : I'm so thirsty!"; break; } end; } @@ -837,11 +837,11 @@ OnMyMobDead: next; mes "[Aspiring Butcher]"; mes "The Chamberlain... the Monk... They've become monsters. I couldn't do anything."; - npctalk strnpcinfo(1) +" : The Chamberlain... the Monk... They've become monsters. I couldn't do anything."; + npctalk "Aspiring Butcher : The Chamberlain... the Monk... They've become monsters. I couldn't do anything."; next; mes "[Aspiring Butcher]"; mes "I just stood still... Nothing, I couldn't do anything..."; - npctalk strnpcinfo(1) +" : I just stood still... Nothing, I couldn't do anything..."; + npctalk "Aspiring Butcher : I just stood still... Nothing, I couldn't do anything..."; next; select("Wake up!"); mes "["+strcharinfo(0)+"]"; @@ -850,7 +850,7 @@ OnMyMobDead: next; mes "[Aspiring Butcher]"; mes "East passage? Alone? How?"; - npctalk strnpcinfo(1) +" : East passage? Alone? How?"; + npctalk "Aspiring Butcher : East passage? Alone? How?"; next; select("I can guide you through the path."); mes "["+strcharinfo(0)+"]"; @@ -859,7 +859,7 @@ OnMyMobDead: next; mes "[Aspiring Butcher]"; mes "Aspiring Butcher: I know, I... I'm trying to."; - npctalk strnpcinfo(1) +" : Aspiring Butcher: I know, I... I'm trying to."; + npctalk "Aspiring Butcher : Aspiring Butcher: I know, I... I'm trying to."; donpcevent instance_npcname("Aspiring Butcher#clearGH")+"::OnDisable"; donpcevent instance_npcname("#ghmemorialmob02")+"::OnEnable"; close; @@ -883,7 +883,7 @@ OnEnable: if (getcharid(0) == getpartyleader(getcharid(1),2)) { mes "[Hollgrehenn Destroyer]"; mes "Yaaa!! Die!!!"; - npctalk strnpcinfo(1) +" : Yaaa!! Die!!!"; + npctalk "Hollgrehenn Destroyer : Yaaa!! Die!!!"; specialeffect EF_CRASHEARTH; next; select("Don't worry!"); @@ -893,7 +893,7 @@ OnEnable: next; mes "[Hollgrehenn Destroyer]"; mes "I'm the only survivor left"; - npctalk strnpcinfo(1) +" : I'm the only survivor left"; + npctalk "Hollgrehenn Destroyer : I'm the only survivor left"; next; select("This is a very dangerous place."); mes "["+strcharinfo(0)+"]"; @@ -902,7 +902,7 @@ OnEnable: next; mes "[Hollgrehenn Destroyer]"; mes "Yes, I am able to move. I'll move for my baby's sake."; - npctalk strnpcinfo(1) +" : Yes, I am able to move. I'll move for my baby's sake."; + npctalk "Hollgrehenn Destroyer : Yes, I am able to move. I'll move for my baby's sake."; next; select("Survive the road..."); mes "["+strcharinfo(0)+"]"; @@ -911,7 +911,7 @@ OnEnable: next; mes "[Hollgrehenn Destroyer]"; mes "That's ok. Thank you for helping us. I'm good to go alone. Ah and good luck also."; - npctalk strnpcinfo(1) +" : That's ok. Thank you for helping us. I'm good to go alone. Ah and good luck also."; + npctalk "Hollgrehenn Destroyer : That's ok. Thank you for helping us. I'm good to go alone. Ah and good luck also."; donpcevent instance_npcname("Hollgrehenn Destroyer")+"::OnDisable"; donpcevent instance_npcname("#ghmemorialmob03")+"::OnEnable"; close; @@ -1172,13 +1172,13 @@ OnEnable: hideoffnpc instance_npcname("Heinrich#ghinstance4"); end; OnTalk1: - npctalk strnpcinfo(1) +" : Himmelmez! I won't let you take even a single more step here."; + npctalk "Heinrich : Himmelmez! I won't let you take even a single more step here."; end; OnTalk2: - npctalk strnpcinfo(1) +" : What... is this?!"; + npctalk "Heinrich : What... is this?!"; end; OnTalk3: - npctalk strnpcinfo(1) +" : Varmunt Sir! Help the adventurers and I'll chase Himmelmez!"; + npctalk "Heinrich : Varmunt Sir! Help the adventurers and I'll chase Himmelmez!"; end; } @@ -1197,22 +1197,22 @@ OnEnable: hideoffnpc instance_npcname("Himmelmez#ghinstance2"); end; OnTalk1: - npctalk strnpcinfo(1) +" : What an awfully lucky, I flew all the way over here and just one of them is really powerful."; + npctalk "Himmelmez : What an awfully lucky, I flew all the way over here and just one of them is really powerful."; end; OnTalk2: - npctalk strnpcinfo(1) +" : But it doesn't matter to me."; + npctalk "Himmelmez : But it doesn't matter to me."; end; OnTalk3: - npctalk strnpcinfo(1) +" : Now, all of you will die."; + npctalk "Himmelmez : Now, all of you will die."; end; OnTalk4: - npctalk strnpcinfo(1) +" : Hahaha, so you guys thought I would come alone?"; + npctalk "Himmelmez : Hahaha, so you guys thought I would come alone?"; end; OnTalk5: - npctalk strnpcinfo(1) +" : This is my new toy to keep you at my feet. Why don't you guys play while I entertain?"; + npctalk "Himmelmez : This is my new toy to keep you at my feet. Why don't you guys play while I entertain?"; end; OnTalk6: - npctalk strnpcinfo(1) +" : Sincerely~, If I am given the opportunity I'd like to meet you again, Heinrich."; + npctalk "Himmelmez : Sincerely~, If I am given the opportunity I'd like to meet you again, Heinrich."; end; } @@ -1243,10 +1243,10 @@ OnEnable: hideoffnpc instance_npcname("Varmunt#ghinstance3"); end; OnTalk1: - npctalk strnpcinfo(1) +" : Heinrich Sir! Something unknown holds an inexplicably powerful force!"; + npctalk "Varmunt : Heinrich Sir! Something unknown holds an inexplicably powerful force!"; end; OnTalk2: - npctalk strnpcinfo(1) +" : From the monster I picked up some great stuff. People who are interested, talk to me."; + npctalk "Varmunt : From the monster I picked up some great stuff. People who are interested, talk to me."; end; } @@ -1268,19 +1268,19 @@ OnEnable: hideoffnpc instance_npcname("Heinrich#ghinstance5"); end; OnTalk1: - npctalk strnpcinfo(1) +" : These things have never been in the castle!"; + npctalk "Heinrich : These things have never been in the castle!"; end; OnTalk2: - npctalk strnpcinfo(1) +" : Trying to break this power with common weapons doesn't work. I tried it."; + npctalk "Heinrich : Trying to break this power with common weapons doesn't work. I tried it."; end; OnTalk3: - npctalk strnpcinfo(1) +" : It is really unforgivable."; + npctalk "Heinrich : It is really unforgivable."; end; OnTalk4: - npctalk strnpcinfo(1) +" : I, who already was a subordinate of genocide. How much more in the future..."; + npctalk "Heinrich : I, who already was a subordinate of genocide. How much more in the future..."; end; OnTalk5: - npctalk strnpcinfo(1) +" : ..."; + npctalk "Heinrich : ..."; end; } @@ -1299,52 +1299,52 @@ OnEnable: hideoffnpc instance_npcname("Varmunt#ghinstance4"); end; OnTalk2: - npctalk strnpcinfo(1) +" : Himmelmez's enchantment has completely blocked the passage to each section."; + npctalk "Varmunt : Himmelmez's enchantment has completely blocked the passage to each section."; end; OnTalk3: - npctalk strnpcinfo(1) +" : Get out of the way for a moment. I'll try to somehow break the spell with magical powers."; + npctalk "Varmunt : Get out of the way for a moment. I'll try to somehow break the spell with magical powers."; end; OnTalk4: - npctalk strnpcinfo(1) +" : The enchantment seems to be broken."; + npctalk "Varmunt : The enchantment seems to be broken."; end; OnTalk5: - npctalk strnpcinfo(1) +" : I've never seen this spell before."; + npctalk "Varmunt : I've never seen this spell before."; end; OnTalk6: - npctalk strnpcinfo(1) +" : Himmelmez doesn't use a seal on a person's body to turn it into an undead."; + npctalk "Varmunt : Himmelmez doesn't use a seal on a person's body to turn it into an undead."; end; OnTalk7: - npctalk strnpcinfo(1) +" : She uses enchantment stones.This way, the spell is probably maintained."; + npctalk "Varmunt : She uses enchantment stones.This way, the spell is probably maintained."; end; OnTalk8: - npctalk strnpcinfo(1) +" : We should kill the people who have the enchantment stones to break the spell."; + npctalk "Varmunt : We should kill the people who have the enchantment stones to break the spell."; end; OnTalk9: - npctalk strnpcinfo(1) +" : However, we can't identify them. The purification can only be done randomly."; + npctalk "Varmunt : However, we can't identify them. The purification can only be done randomly."; end; OnTalk10: - npctalk strnpcinfo(1) +" : Commandant..."; + npctalk "Varmunt : Commandant..."; end; OnTalk11: - npctalk strnpcinfo(1) +" : Commandant, it seems too loose."; + npctalk "Varmunt : Commandant, it seems too loose."; end; OnTalk12: - npctalk strnpcinfo(1) +" : We are related to all these people, not just a few."; + npctalk "Varmunt : We are related to all these people, not just a few."; end; OnTalk13: - npctalk strnpcinfo(1) +" : We can't deny that it's not their fault for what is going on."; + npctalk "Varmunt : We can't deny that it's not their fault for what is going on."; end; OnTalk14: - npctalk strnpcinfo(1) +" : Well, let's do it then."; + npctalk "Varmunt : Well, let's do it then."; end; OnTalk15: - npctalk strnpcinfo(1) +" : You guys are of a great help. Try to follow us."; + npctalk "Varmunt : You guys are of a great help. Try to follow us."; end; OnTalk16: - npctalk strnpcinfo(1) +" : There can be a tough fight. Hold on, and it would be nice to eat something."; + npctalk "Varmunt : There can be a tough fight. Hold on, and it would be nice to eat something."; end; OnTalk17: - npctalk strnpcinfo(1) +" : Guys. It is time to depart, Heinrich Sir."; + npctalk "Varmunt : Guys. It is time to depart, Heinrich Sir."; end; } @@ -1665,22 +1665,22 @@ OnEnable: hideoffnpc instance_npcname("Heinrich#ghinstance6"); end; OnTalk1: - npctalk strnpcinfo(1) +" : Gerhard!"; + npctalk "Heinrich : Gerhard!"; end; OnTalk2: - npctalk strnpcinfo(1) +" : What are you doing to my men, Himmelmez?!"; + npctalk "Heinrich : What are you doing to my men, Himmelmez?!"; end; OnTalk3: - npctalk strnpcinfo(1) +" : Himmelmez! You don't need to make any more sacrifices!"; + npctalk "Heinrich : Himmelmez! You don't need to make any more sacrifices!"; end; OnTalk4: - npctalk strnpcinfo(1) +" : Let him go! I don't want one more sacrifice!"; + npctalk "Heinrich : Let him go! I don't want one more sacrifice!"; end; OnTalk5: - npctalk strnpcinfo(1) +" : I will not forgive you."; + npctalk "Heinrich : I will not forgive you."; end; OnTalk6: - npctalk strnpcinfo(1) +" : Just leave us alone, Himmelmez!!"; + npctalk "Heinrich : Just leave us alone, Himmelmez!!"; end; } @@ -1700,7 +1700,7 @@ OnEnable: hideoffnpc instance_npcname("Varmunt#ghinstance5"); end; OnTalk1: - npctalk strnpcinfo(1) +" : What? This cannot be. We must prevent Amdarias's attacks!"; + npctalk "Varmunt : What? This cannot be. We must prevent Amdarias's attacks!"; end; } @@ -1714,37 +1714,37 @@ OnEnable: hideoffnpc instance_npcname("Himmelmez#ghinstance4"); end; OnTalk1: - npctalk strnpcinfo(1) +" : Great~ I thought you wouldn't come near the end..."; + npctalk "Himmelmez : Great~ I thought you wouldn't come near the end..."; end; OnTalk2: - npctalk strnpcinfo(1) +" : Huhu, I have already found a piece of Ymir's Heart, Heinrich."; + npctalk "Himmelmez : Huhu, I have already found a piece of Ymir's Heart, Heinrich."; end; OnTalk3: - npctalk strnpcinfo(1) +" : It would've been faster if there were no distractions."; + npctalk "Himmelmez : It would've been faster if there were no distractions."; end; OnTalk4: - npctalk strnpcinfo(1) +" : What do you think? Making it look like an accidental disease infected the king and the people around..."; + npctalk "Himmelmez : What do you think? Making it look like an accidental disease infected the king and the people around..."; end; OnTalk5: - npctalk strnpcinfo(1) +" : You want that?"; + npctalk "Himmelmez : You want that?"; end; OnTalk6: - npctalk strnpcinfo(1) +" : This one is your final blow, Heinrich."; + npctalk "Himmelmez : This one is your final blow, Heinrich."; end; OnTalk7: - npctalk strnpcinfo(1) +" : It is said that stopping me requires a skillfull person."; + npctalk "Himmelmez : It is said that stopping me requires a skillfull person."; end; OnTalk8: - npctalk strnpcinfo(1) +" : Seems like a perfect scenario to make my new monster, Amdarias."; + npctalk "Himmelmez : Seems like a perfect scenario to make my new monster, Amdarias."; end; OnTalk9: - npctalk strnpcinfo(1) +" : Booh~ I'm scared."; + npctalk "Himmelmez : Booh~ I'm scared."; end; OnTalk10: - npctalk strnpcinfo(1) +" : Anyway, it was nice talking to you. Maybe we'll have the chance to meet again in the next story."; + npctalk "Himmelmez : Anyway, it was nice talking to you. Maybe we'll have the chance to meet again in the next story."; end; OnTalk11: - npctalk strnpcinfo(1) +" : Well, make sure you will come back again."; + npctalk "Himmelmez : Well, make sure you will come back again."; end; } @@ -1795,13 +1795,13 @@ OnEnable: hideoffnpc instance_npcname("Gerhard#ghinstance1"); end; OnTalk1: - npctalk strnpcinfo(1) +" : Damn it! Run away! I can't withstand anymore!"; + npctalk "Gerhard : Damn it! Run away! I can't withstand anymore!"; end; OnTalk2: - npctalk strnpcinfo(1) +" : Commandant... Come on, you need to run away from here... Ugh."; + npctalk "Gerhard : Commandant... Come on, you need to run away from here... Ugh."; end; OnTalk3: - npctalk strnpcinfo(1) +" : Even if you defile my body, I won't let you take my soul, Himmelmez!"; + npctalk "Gerhard : Even if you defile my body, I won't let you take my soul, Himmelmez!"; end; OnEffect1: specialeffect EF_BARRIER; diff --git a/npc/re/jobs/novice/academy.txt b/npc/re/jobs/novice/academy.txt index 2fbc31cc73..65a0f6be0f 100644 --- a/npc/re/jobs/novice/academy.txt +++ b/npc/re/jobs/novice/academy.txt @@ -4722,16 +4722,16 @@ iz_ac01,43,80,7 script Adventurer's Pet#ac 4_DEVIRUCHI,{ OnTimer60000: switch(rand(1,4)) { case 1: - npctalk strnpcinfo(1) +" : Yawn~ I am so bored!"; + npctalk "Adventurer's Pet : Yawn~ I am so bored!"; break; case 2: - npctalk strnpcinfo(1) +" : Red Potion.. Is it delicious? Herb does not look delicious.. I bet that is bitter."; + npctalk "Adventurer's Pet : Red Potion.. Is it delicious? Herb does not look delicious.. I bet that is bitter."; break; case 3: - npctalk strnpcinfo(1) +" : Ha. You are lucky to have this Devi."; + npctalk "Adventurer's Pet : Ha. You are lucky to have this Devi."; break; case 4: - npctalk strnpcinfo(1) +" : Isn't the floor cold? Well.. For me, Undead is more familiar."; + npctalk "Adventurer's Pet : Isn't the floor cold? Well.. For me, Undead is more familiar."; break; } From 9ebf59c37bd58e9346e74beddcbe85c1c31fdf28 Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Tue, 8 Mar 2016 18:03:59 +0700 Subject: [PATCH 006/319] * Official EXP-Giving Script * Fixed #980. * Job Quest EXP always be shown in yellow color. * Miracle Tonic (12259) and Leap of Fantasy (12261) give fixed EXP through `pc_setparam` that ignore EXP item bonuses and exp rates. Not as Quest EXP from `getexp` script. * If given EXP is 0 by `getexp`, it won't be notified in client EXP log. * If given EXP for base/job that reach max level, client will be notified as 0 EXP gained. * Follow up 20588abcd83fab53f9e52deafc08bfcddfe1658a * Some clean up on `pc_gainexp`. Signed-off-by: Cydh Ramdh --- db/re/item_db.txt | 4 +- src/map/clif.c | 2 +- src/map/pc.c | 118 +++++++++++++++++++++++++++++++--------------- src/map/pc.h | 2 +- 4 files changed, 83 insertions(+), 43 deletions(-) diff --git a/db/re/item_db.txt b/db/re/item_db.txt index f1e23e71f6..4b8a0d0bba 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -6270,9 +6270,9 @@ 12256,PRO_Gift_Box,PRO Gift Box,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} 12257,Cold_Medicine,Cold Medicine,0,20,,100,,,,,0xFFFFFFFF,63,2,,,50,,,{ percentheal 25,25; },{},{} 12258,Bombring_Box,Bomb Poring Box,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ if(strcharinfo(3)=="job3_rang02") { monster "this",-1,-1,"--ja--",1904,1,""; } },{},{} -12259,Miracle_Medicine,Miracle Tonic,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ getexp 3000000,1500000; },{},{} +12259,Miracle_Medicine,Miracle Tonic,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ BaseExp += 3000000; JobExp += 1500000; },{},{} 12260,Cool_Summer_Outfit,Cool Summer Outfit,2,0,,100,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_SUMMER,600000,0; },{},{} -12261,Secret_Medicine,Leap of Fantasy,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ getexp 2000000,1000000; },{},{} +12261,Secret_Medicine,Leap of Fantasy,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ BaseExp += 2000000; JobExp += 1000000; },{},{} 12262,Inspector_Certificate_,Authoritative Badge,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_SPEEDUP0,540000,25; },{},{} 12263,Comp_Battle_Manual,Field Manual,2,2,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_EXPBOOST,1800000,50; },{},{} 12264,Comp_Bubble_Gum,Bubble Gum,2,2,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_ITEMBOOST,1800000,200; },{},{} diff --git a/src/map/clif.c b/src/map/clif.c index d42ff2c88a..0521ea0574 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -16697,7 +16697,7 @@ void clif_displayexp(struct map_session_data *sd, unsigned int exp, char type, b WFIFOL(fd,2) = sd->bl.id; WFIFOL(fd,6) = (int)umin(exp, INT_MAX) * (lost ? -1 : 1); WFIFOW(fd,10) = type; - WFIFOW(fd,12) = quest?1:0;// Normal exp is shown in yellow, quest exp is shown in purple. + WFIFOW(fd,12) = (quest && type != SP_JOBEXP) ? 1 : 0; // NOTE: Somehow JobEXP always in yellow color WFIFOSET(fd,packet_len(0x7f6)); } diff --git a/src/map/pc.c b/src/map/pc.c index eed61e1ad3..13c07d6a97 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1296,6 +1296,16 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_ sd->bonus_script.head = NULL; sd->bonus_script.count = 0; + // Check EXP overflow, since in previous revision EXP on Max Level can be more than 'official' Max EXP + if (pc_is_maxbaselv(sd) && sd->status.base_exp > MAX_LEVEL_BASE_EXP) { + sd->status.base_exp = MAX_LEVEL_BASE_EXP; + clif_updatestatus(sd, SP_BASEEXP); + } + if (pc_is_maxjoblv(sd) && sd->status.job_exp > MAX_LEVEL_JOB_EXP) { + sd->status.job_exp = MAX_LEVEL_JOB_EXP; + clif_updatestatus(sd, SP_JOBEXP); + } + // Request all registries (auth is considered completed whence they arrive) intif_request_registry(sd,7); return true; @@ -6394,13 +6404,19 @@ static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsi bonus += ( sd->sc.data[SC_EXPBOOST]->val1 / battle_config.vip_bm_increase ); } - *base_exp = (unsigned int) cap_value(*base_exp + (double)*base_exp * (bonus + vip_bonus_base)/100., 1, UINT_MAX); + if (*base_exp) { + unsigned int exp = (unsigned int)(*base_exp + (double)*base_exp * (bonus + vip_bonus_base)/100.); + *base_exp = cap_value(exp, 1, UINT_MAX); + } // Give JEXPBOOST for quests even if src is NULL. if (&sd->sc && sd->sc.data[SC_JEXPBOOST]) bonus += sd->sc.data[SC_JEXPBOOST]->val1; - *job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * (bonus + vip_bonus_job)/100., 1, UINT_MAX); + if (*job_exp) { + unsigned int exp = (unsigned int)(*job_exp + (double)*job_exp * (bonus + vip_bonus_job)/100.); + *job_exp = cap_value(exp, 1, UINT_MAX); + } return; } @@ -6437,7 +6453,6 @@ void pc_gainexp_disp(struct map_session_data *sd, unsigned int base_exp, unsigne **/ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int base_exp, unsigned int job_exp, bool quest) { - float nextbp = 0, nextjp = 0; unsigned int nextb = 0, nextj = 0; uint8 flag = 0; ///< 1: Base EXP given, 2: Job EXP given, 4: Max Base level, 8: Max Job Level @@ -6452,15 +6467,15 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int if(sd->status.guild_id>0) base_exp-=guild_payexp(sd,base_exp); + flag = ((base_exp) ? 1 : 0) | + ((job_exp) ? 2 : 0) | + ((pc_is_maxbaselv(sd)) ? 4 : 0) | + ((pc_is_maxjoblv(sd)) ? 8 : 0); + pc_calcexp(sd, &base_exp, &job_exp, src); nextb = pc_nextbaseexp(sd); nextj = pc_nextjobexp(sd); - - flag = ((base_exp) ? 1 : 0) | - ((job_exp) ? 2 : 0) | - (pc_is_maxbaselv(sd) ? 4 : 0) | - (pc_is_maxjoblv(sd) ? 8 : 0); if (flag&4){ if( sd->status.base_exp >= MAX_LEVEL_BASE_EXP ) @@ -6475,25 +6490,18 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int job_exp = MAX_LEVEL_JOB_EXP - sd->status.job_exp; } - if ((base_exp || job_exp) && (sd->state.showexp || battle_config.max_exp_gain_rate)){ - if (nextb > 0) - nextbp = (float) base_exp / (float) nextb; - if (nextj > 0) - nextjp = (float) job_exp / (float) nextj; - - 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] + if (battle_config.max_exp_gain_rate && (base_exp || job_exp)) { + //Note that this value should never be greater than the original + //therefore no overflow checks are needed. [Skotlex] + if (nextb > 0) { + float nextbp = (float) base_exp / (float) nextb; + if (nextbp > battle_config.max_exp_gain_rate/1000.) base_exp = (unsigned int)(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.) { + } + if (nextj > 0) { + float nextjp = (float) job_exp / (float) nextj; + if (nextjp > battle_config.max_exp_gain_rate/1000.) job_exp = (unsigned int)(battle_config.max_exp_gain_rate/1000.*nextj); - if (sd->state.showexp) - nextjp = (float) job_exp / (float) nextj; - } } } @@ -7923,23 +7931,55 @@ bool pc_setparam(struct map_session_data *sd,int type,int val) sd->status.zeny = cap_value(val, 0, MAX_ZENY); break; case SP_BASEEXP: - if(pc_nextbaseexp(sd) > 0) { - if( pc_is_maxbaselv(sd) ) - sd->status.base_exp = u32min(val,MAX_LEVEL_BASE_EXP); - else - sd->status.base_exp = val; - if (!pc_checkbaselevelup(sd)) - clif_updatestatus(sd, SP_BASEEXP); + { + unsigned int exp = sd->status.base_exp; + unsigned int next = pc_nextbaseexp(sd); + bool isLost = false; + bool isMax = false; + + val = cap_value(val, 0, INT_MAX); + sd->status.base_exp = val; + + if ((unsigned int)val < exp) { // Lost + exp -= val; + isLost = true; + } + else { // Gained + if ((isMax = pc_is_maxbaselv(sd)) && sd->status.base_exp >= MAX_LEVEL_BASE_EXP) + exp = 0; + else + exp = val-exp; + pc_checkbaselevelup(sd); + } + clif_displayexp(sd, isMax ? 0 : exp, SP_BASEEXP, false, isLost); + if (sd->state.showexp) + pc_gainexp_disp(sd, exp, next, 0, pc_nextjobexp(sd), isLost); } break; case SP_JOBEXP: - if(pc_nextjobexp(sd) > 0) { - if( pc_is_maxjoblv(sd) ) - sd->status.job_exp = u32min(val,MAX_LEVEL_JOB_EXP); - else - sd->status.job_exp = val; - if (!pc_checkjoblevelup(sd)) - clif_updatestatus(sd, SP_JOBEXP); + { + unsigned int exp = sd->status.job_exp; + unsigned int next = pc_nextjobexp(sd); + bool isLost = false; + bool isMax = false; + + val = cap_value(val, 0, INT_MAX); + sd->status.job_exp = val; + + if ((unsigned int)val < exp) { // Lost + exp -= val; + isLost = true; + } + else { // Gained + if ((isMax = pc_is_maxjoblv(sd)) && sd->status.job_exp >= MAX_LEVEL_JOB_EXP) + exp = 0; + else + exp = val-exp; + pc_checkjoblevelup(sd); + } + clif_displayexp(sd, isMax ? 0 : exp, SP_JOBEXP, false, isLost); + if (sd->state.showexp) + pc_gainexp_disp(sd, 0, pc_nextbaseexp(sd), exp, next, isLost); } break; case SP_SEX: diff --git a/src/map/pc.h b/src/map/pc.h index 1ed2069cfd..d145fa1584 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -1008,7 +1008,7 @@ bool pc_is_maxbaselv(struct map_session_data *sd); bool pc_is_maxjoblv(struct map_session_data *sd); int pc_checkbaselevelup(struct map_session_data *sd); int pc_checkjoblevelup(struct map_session_data *sd); -int pc_gainexp(struct map_session_data*,struct block_list*,unsigned int,unsigned int, bool); +int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int base_exp, unsigned int job_exp, bool quest); void pc_gainexp_disp(struct map_session_data *sd, unsigned int base_exp, unsigned int next_base_exp, unsigned int job_exp, unsigned int next_job_exp, bool lost); unsigned int pc_nextbaseexp(struct map_session_data *sd); unsigned int pc_nextjobexp(struct map_session_data *sd); From 0f5b6db8139d78da17587406d1cee45c7954b2ab Mon Sep 17 00:00:00 2001 From: aleos89 Date: Fri, 11 Mar 2016 13:45:17 -0500 Subject: [PATCH 007/319] Implemented new adoption methods * Implemented atcommand adopt. * Implemented script command adopt. * Circumvents adoption issues with 2013-08+ clients (Related to #768). * Suggested from https://rathena.org/board/topic/104014-suggestion-add-adopt-or-etc/ --- conf/msg_conf/map_msg.conf | 10 ++++- doc/script_commands.txt | 20 ++++++++++ src/map/atcommand.c | 44 ++++++++++++++++++++++ src/map/clif.c | 8 ++-- src/map/clif.h | 7 ++++ src/map/pc.c | 55 ++++++++++++++++------------ src/map/pc.h | 14 ++++++- src/map/script.c | 75 ++++++++++++++++++++++++++++++++++++++ src/map/script_constants.h | 10 +++++ 9 files changed, 214 insertions(+), 29 deletions(-) diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf index a778f7f16e..9966b79de1 100644 --- a/conf/msg_conf/map_msg.conf +++ b/conf/msg_conf/map_msg.conf @@ -785,7 +785,15 @@ 741: Gained 742: Lost 743: Experience %s Base:%ld (%0.2f%%) Job:%ld (%0.2f%%) -//744-899 free + +// @adopt +744: Baby already adopted or is in the process of being adopted. +745: You need to be married and in a party with your partner and the Baby to adopt. +746: Both parents need to have their wedding rings equipped. +747: The Baby is not a Novice. +748: A parent or Baby was not found. + +//749-899 free //------------------------------------ // More atcommands message diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 20eea4a81f..7788ef560f 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -5536,6 +5536,26 @@ current SVN, which prevents the cases of multi-spouse problems). It will return This function will also destroy both wedding rings and send a message to both players, telling them they are now divorced. +--------------------------------------- + +*adopt("",""); +*adopt(,); + +This function will send the client adoption request to the specified baby +character. The parent value can be either parent. Both parents and the baby +need to be online in order for adoption to work. + +Return values: + ADOPT_ALLOWED - Sent message to Baby to accept or deny. + ADOPT_ALREADY_ADOPTED - Character is already adopted. + ADOPT_MARRIED_AND_PARTY - Parents need to be married and in a party with the baby. + ADOPT_EQUIP_RINGS - Parents need wedding rings equipped. + ADOPT_NOT_NOVICE - Baby is not a Novice. + ADOPT_CHARACTER_NOT_FOUND - A parent or Baby was not found. + ADOPT_MORE_CHILDREN - You cannot adopt more than 1 child. (client message) + ADOPT_LEVEL_70 - Parents need to be at least level 70 in order to adopt someone. (client message) + ADOPT_MARRIED - You cannot adopt a married person. (client message) + --------------------------------------- // 4,3.- End of marriage-related commands diff --git a/src/map/atcommand.c b/src/map/atcommand.c index dddcdf7134..1895f3165a 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -9783,6 +9783,49 @@ ACMD_FUNC(clonestat) { return 0; } +/** + * Adopt a character. + * Usage: @adopt + * https://rathena.org/board/topic/104014-suggestion-add-adopt-or-etc/ + */ +ACMD_FUNC(adopt) +{ + TBL_PC *b_sd; + enum adopt_responses response; + + nullpo_retr(-1, sd); + + memset(atcmd_output, '\0', sizeof(atcmd_output)); + memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); + + if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) { + sprintf(atcmd_output, msg_txt(sd, 435), command); // Please enter a player name (usage: %s ). + clif_displaymessage(fd, atcmd_output); + return -1; + } + + if ((b_sd = map_nick2sd((char *)atcmd_player_name)) == NULL) { + clif_displaymessage(fd, msg_txt(sd, 3)); // Character not found. + return -1; + } + + response = pc_try_adopt(sd, map_charid2sd(sd->status.partner_id), b_sd); + + if (response == ADOPT_ALLOWED) { + TBL_PC *p_sd = map_charid2sd(sd->status.partner_id); + + b_sd->adopt_invite = sd->status.account_id; + clif_Adopt_request(b_sd, sd, p_sd->status.account_id); + return 0; + } + + if (response < ADOPT_MORE_CHILDREN) { // No displaymessage for client-type responses + sprintf(atcmd_output, msg_txt(sd, 744 + response - 1)); + clif_displaymessage(fd, atcmd_output); + } + return -1; +} + #include "../custom/atcommand.inc" /** @@ -10075,6 +10118,7 @@ void atcommand_basecommands(void) { ACMD_DEF(cloneequip), ACMD_DEF(clonestat), ACMD_DEF(bodystyle), + ACMD_DEF(adopt), }; AtCommandInfo* atcommand; int i; diff --git a/src/map/clif.c b/src/map/clif.c index 3a378ff6cc..5b5fa00a5f 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -15755,9 +15755,9 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd){ /// Adoption message (ZC_BABYMSG). /// 0216 .L /// msg: -/// 0 = "You cannot adopt more than 1 child." -/// 1 = "You must be at least character level 70 in order to adopt someone." -/// 2 = "You cannot adopt a married person." +/// ADOPT_REPLY_MORE_CHILDREN = "You cannot adopt more than 1 child." +/// ADOPT_REPLY_LEVEL_70 = "You must be at least character level 70 in order to adopt someone." +/// ADOPT_REPLY_MARRIED = "You cannot adopt a married person." void clif_Adopt_reply(struct map_session_data *sd, int type) { int fd = sd->fd; @@ -15791,7 +15791,7 @@ void clif_parse_Adopt_request(int fd, struct map_session_data *sd) TBL_PC *tsd = map_id2sd(RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])); TBL_PC *p_sd = map_charid2sd(sd->status.partner_id); - if( pc_can_Adopt(sd, p_sd, tsd) ) + if( pc_try_adopt(sd, p_sd, tsd) == ADOPT_ALLOWED ) { tsd->adopt_invite = sd->status.account_id; clif_Adopt_request(tsd, sd, p_sd->status.account_id); diff --git a/src/map/clif.h b/src/map/clif.h index a3aa6e897d..77035f68ef 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -136,6 +136,12 @@ enum BROADCASTING_SPECIAL_ITEM_OBTAIN { ITEMOBTAIN_TYPE_NPC = 0x2, }; +enum e_adopt_reply { + ADOPT_REPLY_MORE_CHILDREN = 0, + ADOPT_REPLY_LEVEL_70, + ADOPT_REPLY_MARRIED, +}; + // packet_db[SERVER] is reserved for server use #define SERVER 0 #define packet_len(cmd) packet_db[SERVER][cmd].len @@ -855,6 +861,7 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd); // ADOPTION void clif_Adopt_reply(struct map_session_data *sd, int type); +void clif_Adopt_request(struct map_session_data *sd, struct map_session_data *src, int p_id); // MERCENARIES void clif_mercenary_info(struct map_session_data *sd); diff --git a/src/map/pc.c b/src/map/pc.c index eed61e1ad3..1b028d7f9a 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -868,57 +868,66 @@ bool pc_isequipped(struct map_session_data *sd, unsigned short nameid) return false; } -/** Check adopt rule -* @param p1_sd Player 1 -* @param p2_sd Player 2 -* @param b_sd Player that will be adopted -* @return True - if can be adopted, False otherwise -*/ -bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd ) +/** + * Check adoption rules + * @param p1_sd: Player 1 + * @param p2_sd: Player 2 + * @param b_sd: Player that will be adopted + * @return ADOPT_ALLOWED - Sent message to Baby to accept or deny + * ADOPT_ALREADY_ADOPTED - Already adopted + * ADOPT_MARRIED_AND_PARTY - Need to be married and in the same party + * ADOPT_EQUIP_RINGS - Need wedding rings equipped + * ADOPT_NOT_NOVICE - Adoptee is not a Novice + * ADOPT_CHARACTER_NOT_FOUND - Parent or Baby not found + * ADOPT_MORE_CHILDREN - Cannot adopt more than 1 Baby (client message) + * ADOPT_LEVEL_70 - Parents need to be level 70+ (client message) + * ADOPT_MARRIED - Cannot adopt a married person (client message) + */ +enum adopt_responses pc_try_adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd) { if( !p1_sd || !p2_sd || !b_sd ) - return false; + return ADOPT_CHARACTER_NOT_FOUND; if( b_sd->status.father || b_sd->status.mother || b_sd->adopt_invite ) - return false; // already adopted baby / in adopt request + return ADOPT_ALREADY_ADOPTED; // already adopted baby / in adopt request if( !p1_sd->status.partner_id || !p1_sd->status.party_id || p1_sd->status.party_id != b_sd->status.party_id ) - return false; // You need to be married and in party with baby to adopt + return ADOPT_MARRIED_AND_PARTY; // You need to be married and in party with baby to adopt if( p1_sd->status.partner_id != p2_sd->status.char_id || p2_sd->status.partner_id != p1_sd->status.char_id ) - return false; // Not married, wrong married + return ADOPT_MARRIED_AND_PARTY; // Not married, wrong married if( p2_sd->status.party_id != p1_sd->status.party_id ) - return false; // Both parents need to be in the same party + return ADOPT_MARRIED_AND_PARTY; // Both parents need to be in the same party // Parents need to have their ring equipped if( !pc_isequipped(p1_sd, WEDDING_RING_M) && !pc_isequipped(p1_sd, WEDDING_RING_F) ) - return false; + return ADOPT_EQUIP_RINGS; if( !pc_isequipped(p2_sd, WEDDING_RING_M) && !pc_isequipped(p2_sd, WEDDING_RING_F) ) - return false; + return ADOPT_EQUIP_RINGS; // Already adopted a baby if( p1_sd->status.child || p2_sd->status.child ) { - clif_Adopt_reply(p1_sd, 0); - return false; + clif_Adopt_reply(p1_sd, ADOPT_REPLY_MORE_CHILDREN); + return ADOPT_MORE_CHILDREN; } // Parents need at least lvl 70 to adopt if( p1_sd->status.base_level < 70 || p2_sd->status.base_level < 70 ) { - clif_Adopt_reply(p1_sd, 1); - return false; + clif_Adopt_reply(p1_sd, ADOPT_REPLY_LEVEL_70); + return ADOPT_LEVEL_70; } if( b_sd->status.partner_id ) { - clif_Adopt_reply(p1_sd, 2); - return false; + clif_Adopt_reply(p1_sd, ADOPT_REPLY_MARRIED); + return ADOPT_MARRIED; } if( !( ( b_sd->status.class_ >= JOB_NOVICE && b_sd->status.class_ <= JOB_THIEF ) || b_sd->status.class_ == JOB_SUPER_NOVICE || b_sd->status.class_ == JOB_SUPER_NOVICE_E ) ) - return false; + return ADOPT_NOT_NOVICE; - return true; + return ADOPT_ALLOWED; } /*========================================== @@ -929,7 +938,7 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd, int job, joblevel; unsigned int jobexp; - if( !pc_can_Adopt(p1_sd, p2_sd, b_sd) ) + if( pc_try_adopt(p1_sd, p2_sd, b_sd) != ADOPT_ALLOWED ) return false; // Preserve current job levels and progress diff --git a/src/map/pc.h b/src/map/pc.h index 1ed2069cfd..637ec30802 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -749,6 +749,18 @@ enum idletime_option { IDLE_ATCOMMAND = 0x200, }; +enum adopt_responses { + ADOPT_ALLOWED = 0, + ADOPT_ALREADY_ADOPTED, + ADOPT_MARRIED_AND_PARTY, + ADOPT_EQUIP_RINGS, + ADOPT_NOT_NOVICE, + ADOPT_CHARACTER_NOT_FOUND, + ADOPT_MORE_CHILDREN, + ADOPT_LEVEL_70, + ADOPT_MARRIED, +}; + struct { unsigned int base_hp[MAX_LEVEL], base_sp[MAX_LEVEL]; //Storage for the first calculation with hp/sp factor and multiplicator int hp_factor, hp_multiplicator, sp_factor; @@ -966,7 +978,7 @@ bool pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem); bool pc_dropitem(struct map_session_data *sd,int n,int amount); bool pc_isequipped(struct map_session_data *sd, unsigned short nameid); -bool pc_can_Adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd ); +enum adopt_responses pc_try_adopt(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd); bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd, struct map_session_data *b_sd); void pc_updateweightstatus(struct map_session_data *sd); diff --git a/src/map/script.c b/src/map/script.c index 29ead848f1..43392ad594 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -21095,6 +21095,80 @@ BUILDIN_FUNC(navigateto){ #endif } +/** + * adopt("",""); + * adopt(,); + * https://rathena.org/board/topic/104014-suggestion-add-adopt-or-etc/ + */ +BUILDIN_FUNC(adopt) +{ + TBL_PC *sd, *b_sd; + struct script_data *data; + enum adopt_responses response; + + data = script_getdata(st, 2); + get_val(st, data); + + if (data_isstring(data)) { + const char *name = conv_str(st, data); + + sd = map_nick2sd(name); + if (sd == NULL) { + ShowError("buildin_adopt: Non-existant parent character %s requested.\n", name); + return SCRIPT_CMD_FAILURE; + } + } else if (data_isint(data)) { + uint32 char_id = conv_num(st, data); + + sd = map_charid2sd(char_id); + if (sd == NULL) { + ShowError("buildin_adopt: Non-existant parent character %d requested.\n", char_id); + return SCRIPT_CMD_FAILURE; + } + } else { + ShowError("buildin_adopt: Invalid data type for argument #1 (%d).", data->type); + return SCRIPT_CMD_FAILURE; + } + + data = script_getdata(st, 3); + get_val(st, data); + + if (data_isstring(data)) { + const char *name = conv_str(st, data); + + b_sd = map_nick2sd(name); + if (b_sd == NULL) { + ShowError("buildin_adopt: Non-existant baby character %s requested.\n", name); + return SCRIPT_CMD_FAILURE; + } + } else if (data_isint(data)) { + uint32 char_id = conv_num(st, data); + + b_sd = map_charid2sd(char_id); + if (b_sd == NULL) { + ShowError("buildin_adopt: Non-existant baby character %d requested.\n", char_id); + return SCRIPT_CMD_FAILURE; + } + } else { + ShowError("buildin_adopt: Invalid data type for argument #2 (%d).", data->type); + return SCRIPT_CMD_FAILURE; + } + + response = pc_try_adopt(sd, map_charid2sd(sd->status.partner_id), b_sd); + + if (response == ADOPT_ALLOWED) { + TBL_PC *p_sd = map_charid2sd(sd->status.partner_id); + + b_sd->adopt_invite = sd->status.account_id; + clif_Adopt_request(b_sd, sd, p_sd->status.account_id); + script_pushint(st, ADOPT_ALLOWED); + return SCRIPT_CMD_SUCCESS; + } + + script_pushint(st, response); + return SCRIPT_CMD_FAILURE; +} + #include "../custom/script.inc" // declarations that were supposed to be exported from npc_chat.c @@ -21662,6 +21736,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(setquestinfo_job,"ii*"), BUILDIN_DEF(opendressroom,"i?"), BUILDIN_DEF(navigateto,"s???????"), + BUILDIN_DEF(adopt,"vv"), #include "../custom/script_def.inc" diff --git a/src/map/script_constants.h b/src/map/script_constants.h index d2ff1c43ea..fe6688f304 100644 --- a/src/map/script_constants.h +++ b/src/map/script_constants.h @@ -3004,6 +3004,16 @@ export_constant(NAV_KAFRA_AND_SCROLL); export_constant(NAV_ALL); + export_constant(ADOPT_ALLOWED); + export_constant(ADOPT_ALREADY_ADOPTED); + export_constant(ADOPT_MARRIED_AND_PARTY); + export_constant(ADOPT_EQUIP_RINGS); + export_constant(ADOPT_NOT_NOVICE); + export_constant(ADOPT_CHARACTER_NOT_FOUND); + export_constant(ADOPT_MORE_CHILDREN); + export_constant(ADOPT_LEVEL_70); + export_constant(ADOPT_MARRIED); + #undef export_constant #endif /* _SCRIPT_CONSTANTS_H_ */ From 6f34c14c0e4e1b029d2a0cceafebf1241653de83 Mon Sep 17 00:00:00 2001 From: Atemo Date: Sat, 12 Mar 2016 16:03:16 +0100 Subject: [PATCH 008/319] Fix a mistake in npctalk --- src/map/script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/map/script.c b/src/map/script.c index a55f518cc3..9dc3f88a48 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -14258,7 +14258,7 @@ BUILDIN_FUNC(npctalk) if (nd) { char message[256]; safesnprintf(message, sizeof(message), "%s", str); - clif_disp_overhead(&nd->bl, str); + clif_disp_overhead(&nd->bl, message); } return SCRIPT_CMD_SUCCESS; } From 180dbc88fb74f0ae6e99e1a07b8076691f407255 Mon Sep 17 00:00:00 2001 From: rAthenaAPI Date: Sat, 12 Mar 2016 16:34:16 +0100 Subject: [PATCH 009/319] SQL synchronization [ci skip] --- sql-files/item_db_re.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql index fa701e99f0..6ea200d025 100644 --- a/sql-files/item_db_re.sql +++ b/sql-files/item_db_re.sql @@ -2154,8 +2154,8 @@ REPLACE INTO `item_db_re` VALUES (2984,'Glove_Save_Rimnil','Glove Save Rimnil',4 REPLACE INTO `item_db_re` VALUES (2985,'Gyges_Ring','Gyges Ring',4,10,NULL,100,NULL,NULL,NULL,1,0xFFFFFFFF,63,2,136,NULL,'50',NULL,NULL,'bonus bInt,3; bonus bMatk,30; skill "TF_HIDING",1;',NULL,'sc_end SC_HIDING;'); REPLACE INTO `item_db_re` VALUES (2986,'Snake_Ring','Snake Ring',4,20,NULL,100,NULL,2,NULL,1,0xFFFFFFFF,63,2,136,NULL,'0',0,0,'bonus bDex,3; bonus bMdef,2;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2987,'Snake_Pendant','Snake Pendant',4,20,NULL,100,NULL,3,NULL,1,0xFFFFFFFF,63,2,136,NULL,'0',0,0,'bonus bAgi,3; bonus bLuk,2; bonus bMdef,3;',NULL,NULL); -REPLACE INTO `item_db_re` VALUES (2988,'Ozs_New_Wing_Ring','Oz\'s New Wing Ring',4,20,NULL,100,NULL,0,NULL,1,0xFFFFFFFF,63,2,136,NULL,'130',NULL,NULL,'bonus bVariableCastrate,-25;',NULL,NULL); -REPLACE INTO `item_db_re` VALUES (2989,'Bloody_Floral_Decoration_Bracelet','Bloody Floral Decoration Bracelet',4,20,NULL,100,NULL,0,NULL,1,0xFFFFFFFF,63,2,136,NULL,'130',NULL,NULL,'bonus bVariableCastrate,-25;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (2988,'Ozs_New_Wing_Ring','Oz\'s New Wing Ring',4,20,NULL,100,NULL,0,NULL,1,0x00080000,56,1,136,NULL,'130',NULL,NULL,'bonus bVariableCastrate,-25;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (2989,'Bloody_Floral_Decoration_Bracelet','Bloody Floral Decoration Bracelet',4,20,NULL,100,NULL,0,NULL,1,0x00080000,56,0,136,NULL,'130',NULL,NULL,'bonus bVariableCastrate,-25;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2990,'Pendant_of_Harmony','Pendant of Harmony',4,20,NULL,100,NULL,0,NULL,0,0xFFFFFFFF,63,2,136,NULL,'130',NULL,NULL,'bonus bMatkRate,6; bonus bHPrecovRate,50; bonus bSPrecovRate,50; bonus2 bSubEle,Ele_Water,5; bonus2 bSubEle,Ele_Earth,5; bonus2 bSubEle,Ele_Fire,5; bonus2 bSubEle,Ele_Wind,5; bonus2 bSubEle,Ele_Poison,5; bonus2 bSubEle,Ele_Ghost,5; bonus2 bSubEle,Ele_Undead,5; bonus4 bAutoSpellWhenHit,"PR_SANCTUARY",3,100,0; bonus3 bAutoSpellWhenHit,"AB_RENOVATIO",1,100; bonus bStr,-5;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2991,'Pendant_of_Chaos','Pendant of Chaos',4,20,NULL,100,NULL,0,NULL,0,0xFFFFFFFF,63,2,136,NULL,'130',NULL,NULL,'bonus bAtkRate,6; bonus2 bSubEle,Ele_Water,5; bonus2 bSubEle,Ele_Earth,5; bonus2 bSubEle,Ele_Fire,5; bonus2 bSubEle,Ele_Wind,5; bonus2 bSubEle,Ele_Poison,5; bonus2 bSubEle,Ele_Ghost,5; bonus2 bSubEle,Ele_Undead,5; bonus2 bResEff,Eff_Confusion,10000; bonus2 bAddEff,Eff_Confusion,500; bonus4 bAutoSpellWhenHit,"SC_CHAOSPANIC",1,100,1; bonus bInt,-5;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (2992,'Pendant_of_Maelstrom','Pendant of Maelstrom',4,20,NULL,100,NULL,0,NULL,1,0xFFFFFFFF,63,2,136,NULL,'130',NULL,NULL,'bonus bAtkRate,6; bonus bMatkRate,6; bonus bAllStats,1; bonus5 bAutoSpellWhenHit,"SC_MAELSTROM",1,100,BF_MAGIC,0;',NULL,NULL); From 081b03c646803d4da33442714641df697d7366f5 Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Sat, 12 Mar 2016 16:40:24 +0100 Subject: [PATCH 010/319] Added placeholders for mob db entries from kRO patch 2016-03-09 --- db/re/mob_db.txt | 15 +++++++++++++++ sql-files/mob_db_re.sql | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/db/re/mob_db.txt b/db/re/mob_db.txt index 4c45c59e32..6f0938638b 100644 --- a/db/re/mob_db.txt +++ b/db/re/mob_db.txt @@ -2686,3 +2686,18 @@ // //3569,POPE_MD_H_MERC_NORMAL //3570,POPE_MD_H_MERC_CASUAL +// +//3621,EP16_2_MM_CUTIE +//3622,EP16_2_MM_S_GUARDS +//3623,EP16_2_MM_U_ENERGY_R +//3624,EP16_2_MM_U_ENERGY_G +//3625,EP16_2_MM_U_ENERGY_B +//3626,EP16_2_H_HUNTER_V +//3627,EP16_2_H_HUNTER_MD +//3628,EP16_2_H_HUNTER_EV +//3629,EP16_2_BROKEN_GUN +//3630,EP16_2_E_BOLKOBA +//3631,EP16_2_HUMAN_KIMERA +//3632,EP16_2_MATTER_KIMERA +//3633,EP16_2_VENOM_KIMERA +//3634,MYSTCASE_GIANT diff --git a/sql-files/mob_db_re.sql b/sql-files/mob_db_re.sql index 97a54a095b..8af323562d 100644 --- a/sql-files/mob_db_re.sql +++ b/sql-files/mob_db_re.sql @@ -2752,4 +2752,19 @@ REPLACE INTO `mob_db_re` VALUES (3203,'INORGANIC_JAKK','Inorganic Pumpkin','Inor # #3569,POPE_MD_H_MERC_NORMAL #3570,POPE_MD_H_MERC_CASUAL +# +#3621,EP16_2_MM_CUTIE +#3622,EP16_2_MM_S_GUARDS +#3623,EP16_2_MM_U_ENERGY_R +#3624,EP16_2_MM_U_ENERGY_G +#3625,EP16_2_MM_U_ENERGY_B +#3626,EP16_2_H_HUNTER_V +#3627,EP16_2_H_HUNTER_MD +#3628,EP16_2_H_HUNTER_EV +#3629,EP16_2_BROKEN_GUN +#3630,EP16_2_E_BOLKOBA +#3631,EP16_2_HUMAN_KIMERA +#3632,EP16_2_MATTER_KIMERA +#3633,EP16_2_VENOM_KIMERA +#3634,MYSTCASE_GIANT From a6f73a6227bc9158127a7544acdb27acbfdc9651 Mon Sep 17 00:00:00 2001 From: Playtester Date: Sat, 12 Mar 2016 16:50:50 +0100 Subject: [PATCH 011/319] Status changes that cause damage reworked (fixes #1033, fixes #448) * Created a better structure for status changes with intervals and integrated the status changes Stone, Poison, Deadly Poison, Bleeding, Magic Mushroom, Burning, Pyrexia, Leech's End and Toxin into the new structure -- The exact remaining duration of these status changes will now be stored -- The correct duration is reloaded when logging back in, you can't avoid a single tick be re-logging -- It will now show the correct duration on the icon of the status change after re-logging, no longer negative values -- The durations are now accurately transferred when using Deadly Infect -- These status changes now use unified code, which makes it much easier to integrate more status changes into this structure with low risk of breaking something * Removed all the status change specific logging of damage and integrated it into the normal logging behavior -- The following skills deal "No source" damage: Stone, Poison, Deadly Poison, Bleeding, Coma, Magic Mushroom -- The following skills deal "Self" damage: Burning, Pyrexia, Leech's End, Toxin -- "No source" will neither be logged nor contribute to the total damage, your exp share doesn't increase from the damage, but it also won't cause the monster to give less EXP, it won't break freeze or similar status changes, it won't make you stand up, it won't make you stop moving, it won't prevent you from logging out -- "Self" damage will now be logged and contribute to the total damage, it makes monster give the exp tap bonus, but also makes monsters give less exp the more "self damage" they've taken, it will break freeze and similar status changes, it will make you stand up properly now, it will make you flinch and stop moving, it will prevent you from logging out, but angry type monsters will not lose their aggressive bit from it and it will not cause monsters to use their rude-attack skill -- Monsters will now use their rude-attack skill on the first rude-attack as long as the damage does not come from self -- When a monster takes damage from a status change, its HP meter will now be updated * Burning now has an interval of 3s and a minimum duration of 10s * Pyrexia now causes blind for Pyrexia's duration instead of just 30s * Ground Drift's poison base duration is now 60s in pre-re (follow-up to e7150ee) * Fixed a bug where the minimum duration failed to apply when the received duration was below 1ms * map_foreachindir and map_foreachinshootarea will now properly print their function names in case of an error * Updated documentation (transferring source ID is no longer required, remaining tick should now always be in val4) If this breaks anything, please report asap. --- db/pre-re/skill_cast_db.txt | 2 +- doc/status_change.txt | 34 +-- src/map/map.c | 4 +- src/map/mob.c | 47 ++-- src/map/mob.h | 1 + src/map/pc.c | 2 +- src/map/skill.c | 4 +- src/map/status.c | 468 ++++++++++++++++-------------------- src/map/status.h | 1 + 9 files changed, 258 insertions(+), 305 deletions(-) diff --git a/db/pre-re/skill_cast_db.txt b/db/pre-re/skill_cast_db.txt index d3b58f3fd1..253cc58cc8 100644 --- a/db/pre-re/skill_cast_db.txt +++ b/db/pre-re/skill_cast_db.txt @@ -859,7 +859,7 @@ //-- GS_FULLBUSTER 519,0,1200:1400:1600:1800:2000:2200:2400:2600:2800:3000,0,0,10000,0 //-- GS_GROUNDDRIFT (Upkeep2 times are duration of: Stun(lv1), Blind(lv2), Poison(lv3) and Freeze(lv4)) -521,2000,0,0,3000:6000:9000:12000:15000:18000:21000:24000:27000:30000,5000:30000:30000:12000,0 +521,2000,0,0,3000:6000:9000:12000:15000:18000:21000:24000:27000:30000,5000:30000:60000:12000,0 //========================================== diff --git a/doc/status_change.txt b/doc/status_change.txt index 5867c915f9..01fe1f873f 100644 --- a/doc/status_change.txt +++ b/doc/status_change.txt @@ -25,9 +25,9 @@ SC_STONE () desc: DEF -50%; if HP>25% lose 1% HP/5 sec; MDEF +25%; change element to Earth Lv 1; ignore Steal & Lex Aeterna; can't move/attack/pick item/use item/use skill/sit/logout val1: - val2: Caster's object ID (for mob_log_damage) - val3: Tick - val4: Petrifying tick + val2: Caster's object ID + val3: Incubation time + val4: Remaining tick SC_FREEZE () desc: DEF -50%; FLEE = 0; MDEF +25%; ignore Steal, Lex Aeterna, Storm Gust, Falling Ice Pillar; change element to Water Lv 1; can't move/attack/pick item/use item/sit/logout @@ -44,9 +44,9 @@ SC_SLEEP () SC_POISON () desc: DEF -25%; if HP>25% lose 1.5% + 2 HP/sec; SP Regeneration is disabled val1: Skill Level - val2: Caster's object ID (for mob_log_damage) - val3: Tick - val4: HP Damage + val2: Caster's object ID + val3: + val4: Remaining tick SC_CURSE () desc: ATK-25%; LUK = 0; Movement speed -300 @@ -69,14 +69,14 @@ SC_BLEEDING (SI_BLEEDING) val1: Skill Level val2: Caster's object ID (for mob_log_damage) val3: - val4: Tick + val4: Remaining tick SC_DPOISON () desc: DEF -25%; if HP>25% lose 10/15% HP/sec val1: Skill Level val2: Caster's object ID (for mob_log_damage) - val3: Tick - val4: HP Damage + val3: + val4: Remaining tick SC_PROVOKE (SI_PROVOKE) desc: Decrease DEF by (5+(5*Skill Lv))%; Increase ATK by (2+(3*Skill lv))% @@ -1283,7 +1283,7 @@ SC_BURNING (SI_BURNT) val1: Skill Level val2: 1000 val3: Caster's object ID (for mob_log_damage) - val4: Tick + val4: Remaining tick SC_FREEZING () desc: @@ -1519,9 +1519,9 @@ SC_ROLLINGCUTTER () SC_TOXIN (SI_TOXIN) desc: Inflict damage, which causes the affected entity to flinch every 10 seconds; This will interrupt the skill casting, even if protected against it val1: GC_WEAPONRESEARCH Skill Level - val2: Caster's object ID (for mob_log_damage) + val2: Caster's object ID val3: - val4: Tick + val4: Remaining tick SC_PARALYSE (SI_PARALYSE) desc: Decrease both ASPD and Flee Rate by 10% and halve Movement Speed, which does not stack with Decrease AGI, Quagmire, Marsh Of Abyss or Freezing status @@ -1540,9 +1540,9 @@ SC_VENOMBLEED (SI_VENOMBLEED) SC_MAGICMUSHROOM (SI_MAGICMUSHROOM) desc: Force the affected entity to use /heh emote, to randomly use skills and drain 3% of Max HP every 4 seconds val1: GC_WEAPONRESEARCH Skill Level - val2: Caster's object ID (for mob_log_damage) + val2: Caster's object ID val3: - val4: Tick + val4: Remaining tick SC_DEATHHURT (SI_DEATHHURT) desc: Drop the healing effectiveness by 20%; This effect stacks with Critical Wounds @@ -1556,7 +1556,7 @@ SC_PYREXIA (SI_PYREXIA) val1: GC_WEAPONRESEARCH Skill Level val2: val3: - val4: Tick + val4: Remaining tick SC_OBLIVIONCURSE (SI_OBLIVIONCURSE) desc: Force the affected entity to use /? emote, block SP Recovery and cause Oblivion status; There is a chance (100% - (Target INT * 0.8)%) of being inflicted, with a minimum of 5% @@ -1568,9 +1568,9 @@ SC_OBLIVIONCURSE (SI_OBLIVIONCURSE) SC_LEECHESEND (SI_LEECHESEND) desc: Drain (Target VIT * (SkillLv - 3)) + (Target HP / 100) HP each second val1: GC_WEAPONRESEARCH Skill Level - val2: Caster's object ID (for mob_log_damage) + val2: Caster's object ID val3: - val4: Tick + val4: Remaining tick SC_REFLECTDAMAGE () desc: diff --git a/src/map/map.c b/src/map/map.c index 986b22469d..fecf13480a 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -795,7 +795,7 @@ int map_foreachinshootarea(int(*func)(struct block_list*, va_list), int16 m, int bl_list[bl_list_count++] = bl; if (bl_list_count >= BL_LIST_MAX) - ShowWarning("map_foreachinarea: block count too many!\n"); + ShowWarning("map_foreachinshootarea: block count too many!\n"); map_freeblock_lock(); @@ -1423,7 +1423,7 @@ int map_foreachindir(int(*func)(struct block_list*, va_list), int16 m, int16 x0, } if( bl_list_count >= BL_LIST_MAX ) - ShowWarning("map_foreachinpath: block count too many!\n"); + ShowWarning("map_foreachindir: block count too many!\n"); map_freeblock_lock(); diff --git a/src/map/mob.c b/src/map/mob.c index c8b42d14c2..a7984ccbda 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -40,7 +40,7 @@ #define MOB_LAZYMOVEPERC(md) (md->state.spotted?1000:0) #define MOB_MAX_DELAY (24*3600*1000) #define MAX_MINCHASE 30 //Max minimum chase value to use for mobs. -#define RUDE_ATTACKED_COUNT 2 //After how many rude-attacks should the skill be used? +#define RUDE_ATTACKED_COUNT 1 //After how many rude-attacks should the skill be used? #define MAX_MOB_CHAT 50 //Max Skill's messages // On official servers, monsters will only seek targets that are closer to walk to than their @@ -1565,7 +1565,8 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) ) ) ) { // Rude attacked - if (md->state.attacked_count++ >= RUDE_ATTACKED_COUNT + if (abl->id != md->bl.id //Self damage does not cause rude attack + && md->state.attacked_count++ >= RUDE_ATTACKED_COUNT && !mobskill_use(md, tick, MSC_RUDEATTACKED) && can_move && !tbl && unit_escape(&md->bl, abl, rnd()%10 +1)) { //Escaped. @@ -2041,8 +2042,6 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage) return; //Do nothing for absorbed damage. if( !damage && !(src->type&DEFAULT_ENEMY_TYPE(md)) ) return; //Do not log non-damaging effects from non-enemies. - if( src->id == md->bl.id ) - return; //Do not log self-damage. switch( src->type ) { @@ -2116,6 +2115,12 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage) md->attacked_id = src->id; } + //Self damage increases tap bonus + if (!char_id && src->id == md->bl.id) { + char_id = src->id; + flag = MDLF_SELF; + } + if( char_id ) { //Log damage... int i,minpos; @@ -2154,28 +2159,24 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage) //Call when a mob has received damage. void mob_damage(struct mob_data *md, struct block_list *src, int damage) { - if (damage > 0) { //Store total damage... + if (src && damage > 0) { //Store total damage... if (UINT_MAX - (unsigned int)damage > md->tdmg) - md->tdmg+=damage; + md->tdmg += damage; else if (md->tdmg == UINT_MAX) damage = 0; //Stop recording damage once the cap has been reached. else { //Cap damage log... damage = (int)(UINT_MAX - md->tdmg); md->tdmg = UINT_MAX; } - if (md->state.aggressive) //No longer aggressive, change to retaliate AI. + if ((src != &md->bl) && md->state.aggressive) //No longer aggressive, change to retaliate AI. md->state.aggressive = 0; //Log damage - if (src) - mob_log_damage(md, src, damage); + mob_log_damage(md, src, damage); md->dmgtick = gettick(); } if (battle_config.show_mob_info&3) - clif_charnameack (0, &md->bl); - - if (!src) - return; + clif_charnameack(0, &md->bl); #if PACKETVER >= 20120404 if( battle_config.monster_hp_bars_info){ @@ -2188,6 +2189,9 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage) } #endif + if (!src) + return; + if( md->special_state.ai == AI_SPHERE ) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex] md->state.alchemist = 1; mobskill_use(md, gettick(), MSC_ALCHEMIST); @@ -2241,18 +2245,23 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) // filter out entries not eligible for exp distribution memset(tmpsd,0,sizeof(tmpsd)); for(i = 0, count = 0, mvp_damage = 0; i < DAMAGELOG_SIZE && md->dmglog[i].id; i++) { - struct map_session_data* tsd = map_charid2sd(md->dmglog[i].id); - - if(tsd == NULL) + struct map_session_data* tsd = NULL; + if (md->dmglog[i].flag == MDLF_SELF) { + //Self damage counts as exp tap + count++; + continue; + } + tsd = map_charid2sd(md->dmglog[i].id); + if (tsd == NULL) continue; // skip empty entries - if(tsd->bl.m != m) + if (tsd->bl.m != m) continue; // skip players not on this map count++; //Only logged into same map chars are counted for the total. if (pc_isdead(tsd)) continue; // skip dead players - if(md->dmglog[i].flag == MDLF_HOMUN && !hom_is_active(tsd->hd)) + if (md->dmglog[i].flag == MDLF_HOMUN && !hom_is_active(tsd->hd)) continue; // skip homunc's share if inactive - if( md->dmglog[i].flag == MDLF_PET && (!tsd->status.pet_id || !tsd->pd) ) + if (md->dmglog[i].flag == MDLF_PET && (!tsd->status.pet_id || !tsd->pd)) continue; // skip pet's share if inactive if(md->dmglog[i].dmg > mvp_damage) { diff --git a/src/map/mob.h b/src/map/mob.h index 9d91678fda..05481e7e80 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -61,6 +61,7 @@ enum MobDamageLogFlag MDLF_NORMAL = 0, MDLF_HOMUN, MDLF_PET, + MDLF_SELF }; enum size { diff --git a/src/map/pc.c b/src/map/pc.c index 1b028d7f9a..eb6fb56b25 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -7312,7 +7312,7 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h if (hp) clif_updatestatus(sd,SP_HP); else return; - if( !src || src == &sd->bl ) + if (!src) return; if( pc_issit(sd) ) { diff --git a/src/map/skill.c b/src/map/skill.c index 878caecf54..8c6e9b16c9 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -7053,7 +7053,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; } if (sc_start4(src,bl,type,(skill_lv*4+20)+brate, - skill_lv, src->id, 0, skill_get_time(skill_id, skill_lv), + skill_lv, src->id, skill_get_time(skill_id, skill_lv), 0, skill_get_time2(skill_id,skill_lv))) clif_skill_nodamage(src,bl,skill_id,skill_lv,1); else if(sd) { @@ -13412,7 +13412,7 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns case UNT_VENOMDUST: if(tsc && !tsc->data[type]) - status_change_start(ss, bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),SCSTART_NONE); + status_change_start(ss,bl,type,10000,sg->skill_lv,sg->src_id,0,0,skill_get_time2(sg->skill_id,sg->skill_lv),SCSTART_NONE); break; case UNT_LANDMINE: diff --git a/src/map/status.c b/src/map/status.c index 647ef27aa9..48e0809577 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -7304,6 +7304,34 @@ void status_change_init(struct block_list *bl) memset(sc, 0, sizeof (struct status_change)); } +/*========================================== [Playtester] +* Returns the interval for status changes that iterate multiple times +* through the timer (e.g. those that deal damage in regular intervals) +* @param type: Status change (SC_*) +*------------------------------------------*/ +int status_get_sc_interval(enum sc_type type) +{ + switch (type) { + case SC_POISON: + case SC_DPOISON: + case SC_LEECHESEND: + return 1000; + case SC_BURNING: + case SC_PYREXIA: + return 3000; + case SC_MAGICMUSHROOM: + return 4000; + case SC_STONE: + return 5000; + case SC_BLEEDING: + case SC_TOXIN: + return 10000; + default: + break; + } + return 0; +} + /** * Applies SC defense to a given status change * This function also determines whether or not the status change will be applied @@ -7606,13 +7634,9 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ if (!(rnd()%10000 < rate)) return 0; - // Even if a status change doesn't have a duration, it should still trigger - if (tick < 1) - return 1; - // Duration cannot be reduced if (flag&SCSTART_NOTICKDEF) - return tick; + return max(tick, 1); tick -= tick*tick_def/10000; tick -= tick_def2; @@ -7620,7 +7644,6 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ // Minimum durations switch (type) { case SC_ANKLE: - case SC_BURNING: case SC_MARSHOFABYSS: case SC_DEEPSLEEP: tick = max(tick, 5000); // Minimum duration 5s @@ -7628,6 +7651,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ case SC_FREEZING: tick = max(tick, 6000); // Minimum duration 6s break; + case SC_BURNING: case SC_STASIS: tick = max(tick, 10000); // Minimum duration 10s break; @@ -8935,10 +8959,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty break; case SC_STONE: - val4 = max(val4, 100); // Incubation time - val3 = (tick-val4)/100; // Petrified timer iterations - if(val3 < 1) val3 = 1; - tick = val4; + val3 = max(val3, 100); // Incubation time + val4 = max(tick-val3, 100); // Petrify time + tick = val3; calc_flag = 0; // Actual status changes take effect on petrified state. break; @@ -8948,34 +8971,30 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty int diff = status->max_hp*(bl->type==BL_PC?10:15)/100; if (status->hp - diff < status->max_hp>>2) diff = status->hp - (status->max_hp>>2); - if( val2 && bl->type == BL_MOB ) { - struct block_list* src2 = map_id2bl(val2); - if( src2 ) - mob_log_damage((TBL_MOB*)bl,src2,diff); - } status_zap(bl, diff, 0); } - case SC_POISON: // Fall through - val3 = tick/1000; // Damage iterations - if(val3 < 1) val3 = 1; - tick_time = 1000; // [GodLesZ] tick time - // val4: HP damage - if (bl->type == BL_PC) - val4 = (type == SC_DPOISON) ? 2 + status->max_hp/50 : 2 + status->max_hp*3/200; - else - val4 = (type == SC_DPOISON) ? 2 + status->max_hp/100 : 2 + status->max_hp/200; + case SC_POISON: + case SC_BLEEDING: + case SC_BURNING: + case SC_TOXIN: + case SC_MAGICMUSHROOM: + case SC_LEECHESEND: + tick_time = status_get_sc_interval(type); + val4 = tick-tick_time; // Remaining time + break; + + case SC_PYREXIA: + //Causes blind for duration of pyrexia, unreducable and unavoidable, but can be healed with e.g. green potion + status_change_start(src,bl,SC_BLIND,10000,val1,0,0,0,tick,SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF); + tick_time = status_get_sc_interval(type); + val4 = tick-tick_time; // Remaining time break; case SC_CONFUSION: if (!val4) clif_emotion(bl,E_WHAT); break; - case SC_BLEEDING: - val4 = tick/10000; - if (!val4) val4 = 1; - tick_time = 10000; // [GodLesZ] tick time - break; case SC_S_LIFEPOTION: case SC_L_LIFEPOTION: if( val1 == 0 ) return 0; @@ -9219,11 +9238,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty } case SC_COMA: // Coma. Sends a char to 1HP. If val2, do not zap sp - if( val3 && bl->type == BL_MOB ) { - struct block_list* src2 = map_id2bl(val3); - if( src2 ) - mob_log_damage((TBL_MOB*)bl,src2,status->hp - 1); - } status_zap(bl, status->hp-1, val2?0:status->sp); return 1; break; @@ -9561,10 +9575,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty val4 = tick / 1000; tick_time = 1000; // [GodLesZ] tick time break; - case SC_BURNING: - val4 = tick / 2000; // Total Ticks to Burn!! - tick_time = 2000; // [GodLesZ] tick time - break; /* Rune Knight */ case SC_DEATHBOUND: @@ -9598,23 +9608,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty val4 = tick / 5000; tick_time = 5000; // [GodLesZ] tick time break; - case SC_TOXIN: - val4 = tick / 10000; - tick_time = 10000; // [GodLesZ] tick time - break; - case SC_MAGICMUSHROOM: - val4 = tick / 4000; - tick_time = 4000; // [GodLesZ] tick time - break; - case SC_PYREXIA: - status_change_start(src,bl,SC_BLIND,10000,val1,0,0,0,30000,SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF); // Blind status that last for 30 seconds - val4 = tick / 3000; - tick_time = 3000; // [GodLesZ] tick time - break; - case SC_LEECHESEND: - val4 = tick / 1000; - tick_time = 1000; // [GodLesZ] tick time - break; case SC_OBLIVIONCURSE: val4 = tick / 3000; tick_time = 3000; // [GodLesZ] tick time @@ -10331,6 +10324,21 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color); clif_changelook(bl,LOOK_BODY2,0); break; + case SC_STONE: + if (val3 > 0) + break; //Incubation time still active + //Fall through + case SC_POISON: + case SC_DPOISON: + case SC_BLEEDING: + case SC_BURNING: + case SC_TOXIN: + case SC_MAGICMUSHROOM: + case SC_PYREXIA: + case SC_LEECHESEND: + tick_time = tick; + tick = tick_time + max(val4,0); + break; } // Values that must be set regardless of flag&4 e.g. val_flag [Ind] @@ -10500,7 +10508,12 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty opt_flag = 1; switch(type) { // OPT1 - case SC_STONE: sc->opt1 = OPT1_STONEWAIT; break; + case SC_STONE: + if (val3 > 0) + sc->opt1 = OPT1_STONEWAIT; + else + sc->opt1 = OPT1_STONE; + break; case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break; case SC_STUN: sc->opt1 = OPT1_STUN; break; case SC_DEEPSLEEP: opt_flag = 0; @@ -11018,7 +11031,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const // delays status change ending so that a skill that sets opt1 fails to // trigger when it also removed one case SC_STONE: - sce->val3 = 0; // Petrify time counter. + sce->val4 = -1; // Petrify time case SC_FREEZE: case SC_STUN: case SC_SLEEP: @@ -11743,6 +11756,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) struct status_data *status; struct status_change *sc; struct status_change_entry *sce; + int interval = status_get_sc_interval(type); + bool dounlock = false; bl = map_id2bl(id); if(!bl) { @@ -11837,8 +11852,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) break; case SC_STONE: - if(sc->opt1 == OPT1_STONEWAIT && sce->val3) { - sce->val4 = 0; + if (sc->opt1 == OPT1_STONEWAIT && sce->val4) { + sce->val3 = 0; //Incubation time used up unit_stop_attack(bl); if (sc->data[SC_DANCING]) { unit_stop_walking(bl, 1); @@ -11847,45 +11862,117 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) status_change_end(bl, SC_AETERNA, INVALID_TIMER); sc->opt1 = OPT1_STONE; clif_changeoption(bl); - sc_timer_next(100+tick,status_change_timer, bl->id, data ); + sc_timer_next(min(sce->val4, interval) + tick, status_change_timer, bl->id, data); + sce->val4 -= interval; //Remaining time status_calc_bl(bl, StatusChangeFlagTable[type]); return 0; } - if (++(sce->val4)%50 == 0 && status->hp > status->max_hp/4) { - if (sce->val2 && bl->type == BL_MOB) { - struct block_list *src = map_id2bl(sce->val2); - - if (src) - mob_log_damage((TBL_MOB*)bl, src, apply_rate(status->hp, 1)); - } + if (sce->val4 >= 0 && !(sce->val3) && status->hp > status->max_hp / 4) { status_percent_damage(NULL, bl, 1, 0, false); } - if(--(sce->val3) > 0) { - sc_timer_next(100+tick,status_change_timer, bl->id, data ); - return 0; - } break; case SC_POISON: case SC_DPOISON: - if (--(sce->val3) > 0) { - if (!sc->data[SC_SLOWPOISON]) { - if( sce->val2 && bl->type == BL_MOB ) { - struct block_list* src = map_id2bl(sce->val2); - if( src ) - mob_log_damage((TBL_MOB*)bl,src,sce->val4); - } + if (sce->val4 >= 0 && !sc->data[SC_SLOWPOISON]) { + int64 damage = 0; + if (sd) + damage = (type == SC_DPOISON) ? 2 + status->max_hp / 50 : 2 + status->max_hp * 3 / 200; + else + damage = (type == SC_DPOISON) ? 2 + status->max_hp / 100 : 2 + status->max_hp / 200; + if (status->hp > max(status->max_hp / 4, damage)) // Stop damaging after 25% HP left. + status_zap(bl, damage, 0); + } + break; + + case SC_BLEEDING: + if (sce->val4 >= 0) { + int64 damage = rnd() % 600 + 200; + if (!sd && damage >= status->hp) + damage = status->hp - 1; // No deadly damage for monsters + map_freeblock_lock(); + dounlock = true; + status_zap(bl, damage, 0); + } + break; + + case SC_BURNING: + if (sce->val4 >= 0) { + int64 damage = 1000 + (3 * status->max_hp) / 100; // Deals fixed (1000 + 3%*MaxHP) + map_freeblock_lock(); + dounlock = true; + status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, 0, 1, damage, 1, DMG_NORMAL, 0)); + } + break; + + case SC_TOXIN: + if (sce->val4 >= 0) { // Damage is every 10 seconds including 3%sp drain. + map_freeblock_lock(); + dounlock = true; + status_damage(bl, bl, 1, status->max_sp * 3 / 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 1, 1, DMG_NORMAL, 0), 0); + } + break; + + case SC_MAGICMUSHROOM: + if (sce->val4 >= 0) { + bool flag = 0; + int64 damage = status->max_hp * 3 / 100; + if (status->hp <= damage) + damage = status->hp - 1; // Cannot Kill + + if (damage > 0) { // 3% Damage each 4 seconds map_freeblock_lock(); - if(status->hp >= max(status->max_hp>>2, sce->val4)) // Stop damaging after 25% HP left. - status_zap(bl, sce->val4, 0); - if (sc->data[type]) { // Check if the status still last ( can be dead since then ). - sc_timer_next(1000 + tick, status_change_timer, bl->id, data ); - } + status_zap(bl, damage, 0); + flag = !sc->data[type]; // Killed? Should not map_freeblock_unlock(); } - return 0; - } + if (!flag) { // Random Skill Cast + if (skill_magicmushroom_count && sd && !pc_issit(sd)) { // Can't cast if sit + int mushroom_skill_id = 0, checked = 0, checked_max = MAX_SKILL_MAGICMUSHROOM_DB * 3; + unit_stop_attack(bl); + unit_skillcastcancel(bl, 1); + do { + int i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB; + mushroom_skill_id = skill_magicmushroom_db[i].skill_id; + } while (checked++ < checked_max && mushroom_skill_id == 0); + + if (!skill_get_index(mushroom_skill_id)) + break; + + switch (skill_get_casttype(mushroom_skill_id)) { // Magic Mushroom skills are buffs or area damage + case CAST_GROUND: + skill_castend_pos2(bl, bl->x, bl->y, mushroom_skill_id, 1, tick, 0); + break; + case CAST_NODAMAGE: + skill_castend_nodamage_id(bl, bl, mushroom_skill_id, 1, tick, 0); + break; + case CAST_DAMAGE: + skill_castend_damage_id(bl, bl, mushroom_skill_id, 1, tick, 0); + break; + } + } + clif_emotion(bl, E_HEH); + } + } + break; + + case SC_PYREXIA: + if (sce->val4 >= 0) { + map_freeblock_lock(); + dounlock = true; + status_fix_damage(bl, bl, 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 100, 1, DMG_NORMAL, 0)); + } + break; + + case SC_LEECHESEND: + if (sce->val4 >= 0) { + int64 damage = status->vit * (sce->val1 - 3) + status->max_hp / 100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100) + map_freeblock_lock(); + dounlock = true; + status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, damage, 1, DMG_NORMAL, 0)); + unit_skillcastcancel(bl, 2); + } break; case SC_TENSIONRELAX: @@ -11906,26 +11993,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) } break; - case SC_BLEEDING: - if (--(sce->val4) >= 0) { - int hp = rnd()%600 + 200; - struct block_list* src = map_id2bl(sce->val2); - if( src && bl && bl->type == BL_MOB ) - mob_log_damage( (TBL_MOB*)bl, src, sd || hp < status->hp ? hp : status->hp - 1 ); - map_freeblock_lock(); - status_fix_damage(src, bl, sd||hphp?hp:status->hp-1, 1); - if( sc->data[type] ) { - if( status->hp == 1 ) { - map_freeblock_unlock(); - break; - } - sc_timer_next(10000 + tick, status_change_timer, bl->id, data); - } - map_freeblock_unlock(); - return 0; - } - break; - case SC_S_LIFEPOTION: case SC_L_LIFEPOTION: if( sd && --(sce->val4) >= 0 ) { @@ -12083,114 +12150,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) } break; - case SC_PYREXIA: - if( --(sce->val4) >= 0 ) { - map_freeblock_lock(); - clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,DMG_NORMAL,0); - status_fix_damage(NULL,bl,100,0); - if( sc->data[type] ) { - sc_timer_next(3000+tick,status_change_timer,bl->id,data); - } - map_freeblock_unlock(); - return 0; - } - break; - - case SC_LEECHESEND: - if( --(sce->val4) >= 0 ) { - int damage = status->vit * (sce->val1 - 3) + status->max_hp / 100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100) - - if (sce->val2 && bl->type == BL_MOB) { - struct block_list *src2 = map_id2bl(sce->val2); - - if (src2) - mob_log_damage((TBL_MOB*)bl, src2, damage); - } - map_freeblock_lock(); - status_damage(bl, bl, damage, 0, clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,DMG_NORMAL,0), 0); - unit_skillcastcancel(bl, 2); - if (sc->data[type]) { - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); - } - map_freeblock_unlock(); - return 0; - } - break; - - case SC_MAGICMUSHROOM: - if( --(sce->val4) >= 0 ) { - bool flag = 0; - int damage = status->max_hp * 3 / 100; - if( status->hp <= damage ) - damage = status->hp - 1; // Cannot Kill - - if( damage > 0 ) { // 3% Damage each 4 seconds - map_freeblock_lock(); - status_zap(bl,damage,0); - flag = !sc->data[type]; // Killed? Should not - map_freeblock_unlock(); - } - - if (sce->val2 && bl->type == BL_MOB) { - struct block_list *src2 = map_id2bl(sce->val2); - - if (src2) - mob_log_damage((TBL_MOB*)bl, src2, damage); - } - - if( !flag ) { // Random Skill Cast - if (skill_magicmushroom_count && sd && !pc_issit(sd)) { // Can't cast if sit - int mushroom_skill_id = 0, checked = 0, checked_max = MAX_SKILL_MAGICMUSHROOM_DB * 3; - unit_stop_attack(bl); - unit_skillcastcancel(bl,1); - do { - int i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB; - mushroom_skill_id = skill_magicmushroom_db[i].skill_id; - } - while( checked++ < checked_max && mushroom_skill_id == 0 ); - - if (!skill_get_index(mushroom_skill_id)) - break; - - switch( skill_get_casttype(mushroom_skill_id) ) { // Magic Mushroom skills are buffs or area damage - case CAST_GROUND: - skill_castend_pos2(bl,bl->x,bl->y,mushroom_skill_id,1,tick,0); - break; - case CAST_NODAMAGE: - skill_castend_nodamage_id(bl,bl,mushroom_skill_id,1,tick,0); - break; - case CAST_DAMAGE: - skill_castend_damage_id(bl,bl,mushroom_skill_id,1,tick,0); - break; - } - } - - clif_emotion(bl,E_HEH); - sc_timer_next(4000+tick,status_change_timer,bl->id,data); - } - return 0; - } - break; - - case SC_TOXIN: - if( --(sce->val4) >= 0 ) { // Damage is every 10 seconds including 3%sp drain. - if (sce->val2 && bl->type == BL_MOB) { - struct block_list *src2 = map_id2bl(sce->val2); - - if (src2) - mob_log_damage((TBL_MOB*)bl, src2, 1); - } - map_freeblock_lock(); - clif_damage(bl,bl,tick,status_get_amotion(bl),1,1,0,DMG_NORMAL,0); - status_damage(NULL, bl, 1, status->max_sp * 3 / 100, 0, 0); // Cancel dmg only if cancelable - if( sc->data[type] ) { - sc_timer_next(10000 + tick, status_change_timer, bl->id, data ); - } - map_freeblock_unlock(); - return 0; - } - break; - case SC_OBLIVIONCURSE: if( --(sce->val4) >= 0 ) { clif_emotion(bl,E_WHAT); @@ -12225,24 +12184,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) } break; - case SC_BURNING: - if( --(sce->val4) >= 0 ) { - struct block_list *src = map_id2bl(sce->val3); - int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP) - - if (src && bl->type == BL_MOB) - mob_log_damage((TBL_MOB*)bl, src, damage); - map_freeblock_lock(); - clif_damage(bl,bl,tick,0,0,damage,1,DMG_MULTI_HIT_ENDURE,0); // Damage is like endure effect with no walk delay - status_damage(src, bl, damage, 0, 0, 1); - if( sc->data[type]) { // Target still lives. [LimitLine] - sc_timer_next(2000 + tick, status_change_timer, bl->id, data); - } - map_freeblock_unlock(); - return 0; - } - break; - case SC_FEAR: if( --(sce->val4) >= 0 ) { if( sce->val2 > 0 ) @@ -12657,8 +12598,19 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) break; } - // Default for all non-handled control paths is to end the status + // If status has an interval and there is at least 100ms remaining time, wait for next interval + if(interval > 0 && sc->data[type] && sce->val4 >= 100) { + sc_timer_next(min(sce->val4,interval)+tick, status_change_timer, bl->id, data); + sce->val4 -= interval; + if (dounlock) + map_freeblock_unlock(); + return 0; + } + if (dounlock) + map_freeblock_unlock(); + + // Default for all non-handled control paths is to end the status return status_change_end( bl,type,tid ); #undef sc_timer_next } @@ -12965,7 +12917,7 @@ int status_change_spread(struct block_list *src, struct block_list *bl, bool typ { int i, flag = 0; struct status_change *sc = status_get_sc(src); - const struct TimerData *timer; + const struct TimerData *timer = NULL; unsigned int tick; struct status_change_data data; @@ -12981,6 +12933,11 @@ int status_change_spread(struct block_list *src, struct block_list *bl, bool typ for( i = SC_COMMON_MIN; i < SC_MAX; i++ ) { if( !sc->data[i] || i == SC_COMMON_MAX ) continue; + if (sc->data[i]->timer != INVALID_TIMER) { + timer = get_timer(sc->data[i]->timer); + if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick, tick) < 0) + continue; + } switch( i ) { // Debuffs that can be spread. @@ -13009,45 +12966,30 @@ int status_change_spread(struct block_list *src, struct block_list *bl, bool typ //case SC_BITE: case SC_FREEZING: case SC_VENOMBLEED: - if( sc->data[i]->timer != INVALID_TIMER ) { - timer = get_timer(sc->data[i]->timer); - if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0) - continue; - data.tick = DIFF_TICK(timer->tick,tick); - } else + if (sc->data[i]->timer != INVALID_TIMER) + data.tick = DIFF_TICK(timer->tick, tick); + else data.tick = INVALID_TIMER; break; // Special cases - case SC_POISON: - case SC_DPOISON: - data.tick = sc->data[i]->val3 * 1000; - break; + case SC_TOXIN: + case SC_MAGICMUSHROOM: + case SC_PYREXIA: case SC_LEECHESEND: if (type) continue; + case SC_POISON: + case SC_DPOISON: + case SC_BLEEDING: + case SC_BURNING: + if (sc->data[i]->timer != INVALID_TIMER) + data.tick = DIFF_TICK(timer->tick, tick) + sc->data[i]->val4; + else + data.tick = INVALID_TIMER; + break; case SC_FEAR: data.tick = sc->data[i]->val4 * 1000; break; - case SC_BURNING: - data.tick = sc->data[i]->val4 * 2000; - break; - case SC_PYREXIA: - if (type) - continue; - //case SC_OBLIVIONCURSE: // Players are not affected by Oblivion Curse. - data.tick = sc->data[i]->val4 * 3000; - break; - case SC_MAGICMUSHROOM: - if (type) - continue; - data.tick = sc->data[i]->val4 * 4000; - break; - case SC_TOXIN: - if (type) - continue; - case SC_BLEEDING: - data.tick = sc->data[i]->val4 * 10000; - break; default: continue; } diff --git a/src/map/status.h b/src/map/status.h index bb24b23807..d3885fce5b 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -2150,6 +2150,7 @@ struct status_change *status_get_sc(struct block_list *bl); int status_isdead(struct block_list *bl); int status_isimmune(struct block_list *bl); +int status_get_sc_interval(enum sc_type type); int status_get_sc_def(struct block_list *src,struct block_list *bl, enum sc_type type, int rate, int tick, unsigned char flag); //Short version, receives rate in 1->100 range, and does not uses a flag setting. #define sc_start(src, bl, type, rate, val1, tick) status_change_start(src,bl,type,100*(rate),val1,0,0,0,tick,SCSTART_NONE) From 4b3d8ddc5c713bc1ad62cedb6073ce5402e7639e Mon Sep 17 00:00:00 2001 From: Aleos Date: Sat, 12 Mar 2016 13:07:24 -0500 Subject: [PATCH 012/319] Small typo in Ayothaya Dungeon Quest * Fixed Shaman displaying the incorrect item requirement from the array. Thanks to @Jeybla! --- npc/quests/quests_ayothaya.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npc/quests/quests_ayothaya.txt b/npc/quests/quests_ayothaya.txt index e18e7ac53f..f8bc9cd6e0 100644 --- a/npc/quests/quests_ayothaya.txt +++ b/npc/quests/quests_ayothaya.txt @@ -1612,7 +1612,7 @@ ayo_in01,181,193,4 script Shaman#thai 840,{ mes "^3366992 Holy Water^000000,"; mes "^3366991 Yggdrasil Leaf^000000,"; mes "^3366992 "+getitemname(.@items[0])+"^000000 and"; - mes "^3366992 "+getitemname(.@items[0])+"^000000."; + mes "^3366992 "+getitemname(.@items[1])+"^000000."; set ayodunquest,10; changequest 12037,12038; next; From fbb8edba3949035b10fa1eaf112a2e2319c2ae57 Mon Sep 17 00:00:00 2001 From: Playtester Date: Sat, 12 Mar 2016 23:07:13 +0100 Subject: [PATCH 013/319] Fear status change (#1048) * Fear now causes the SC_ANKLE status change for 2 seconds rather than having a weird custom implementation * Fear now removes blind and makes you immune to it * Fixed SC_ANKLE not properly blocking teleportation * Some code optimizations --- doc/status_change.txt | 2 +- src/map/status.c | 40 +++++++++++++++------------------------- src/map/status.h | 1 - src/map/unit.c | 1 - 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/doc/status_change.txt b/doc/status_change.txt index 01fe1f873f..05d65001b6 100644 --- a/doc/status_change.txt +++ b/doc/status_change.txt @@ -1275,7 +1275,7 @@ SC_FOOD_LUK_CASH (SI_FOOD_LUK_CASH) val1: +LUK SC_FEAR () - desc: + desc: Cause SC_ANKLE for 2 seconds, Hit/Flee -20%, remove blind, immune to blind val1: SC_BURNING (SI_BURNT) diff --git a/src/map/status.c b/src/map/status.c index 48e0809577..e1292dd968 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -87,6 +87,7 @@ static unsigned short status_calc_ematk(struct block_list *,struct status_change static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type); static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type); static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned int stat, bool isHP); +static int status_get_sc_interval(enum sc_type type); static bool status_change_isDisabledOnMap_(sc_type type, bool mapIsVS, bool mapIsPVP, bool mapIsGVG, bool mapIsBG, unsigned int mapZone); #define status_change_isDisabledOnMap(type, m) ( status_change_isDisabledOnMap_((type), map_flag_vs((m)), map[(m)].flag.pvp, map_flag_gvg((m)), map[(m)].flag.battleground, map[(m)].zone << 3) ) @@ -2004,6 +2005,7 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui (sc->data[SC_BASILICA] && (sc->data[SC_BASILICA]->val4 != src->id || skill_id != HP_BASILICA)) || // Only Basilica caster that can cast, and only Basilica to cancel it (sc->data[SC_MARIONETTE] && skill_id != CG_MARIONETTE) || // Only skill you can use is marionette again to cancel it (sc->data[SC_MARIONETTE2] && skill_id == CG_MARIONETTE) || // Cannot use marionette if you are being buffed by another + (sc->data[SC_ANKLE] && skill_block_check(src, SC_ANKLE, skill_id)) || (sc->data[SC_STASIS] && skill_block_check(src, SC_STASIS, skill_id)) || (sc->data[SC_BITE] && skill_block_check(src, SC_BITE, skill_id)) || (sc->data[SC_KAGEHUMI] && skill_block_check(src, SC_KAGEHUMI, skill_id)) @@ -7309,7 +7311,7 @@ void status_change_init(struct block_list *bl) * through the timer (e.g. those that deal damage in regular intervals) * @param type: Status change (SC_*) *------------------------------------------*/ -int status_get_sc_interval(enum sc_type type) +static int status_get_sc_interval(enum sc_type type) { switch (type) { case SC_POISON: @@ -7893,8 +7895,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty return 0; // Cannot override other opt1 status changes. [Skotlex] if((type == SC_FREEZE || type == SC_FREEZING || type == SC_CRYSTALIZE) && sc->data[SC_WARMER]) return 0; // Immune to Frozen and Freezing status if under Warmer status. [Jobbie] - break; - + break; + case SC_BLIND: + if (sc->data[SC_FEAR]) + return 0; + break; case SC_ALL_RIDING: if( !sd || !&sd->sc || sc->option&(OPTION_RIDING|OPTION_DRAGON|OPTION_WUGRIDER|OPTION_MADOGEAR) ) return 0; @@ -7903,19 +7908,16 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty status_change_end(bl, SC_ALL_RIDING, INVALID_TIMER); return 0; } - break; - + break; // They're all like berserk, do not everlap each other case SC_BERSERK: if(sc->data[SC_SATURDAYNIGHTFEVER]) return 0; break; - case SC_BURNING: if(sc->opt1 || sc->data[SC_FREEZING]) return 0; - break; - + break; case SC_SIGNUMCRUCIS: // Only affects demons and undead element (but not players) if((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) @@ -7960,7 +7962,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty case SC_TWOHANDQUICKEN: if(sc->data[SC_DECREASEAGI] || sc->data[SC_ADORAMUS]) return 0; - case SC_INCREASEAGI: case SC_CONCENTRATE: case SC_SPEARQUICKEN: @@ -8513,6 +8514,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty status_change_end(bl, SC_FREEZE, INVALID_TIMER); status_change_end(bl, SC_STONE, INVALID_TIMER); break; + case SC_FEAR: + status_change_end(bl, SC_BLIND, INVALID_TIMER); + break; case SC_FREEZING: status_change_end(bl, SC_BURNING, INVALID_TIMER); break; @@ -9571,9 +9575,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty /* General */ case SC_FEAR: - val2 = 2; - val4 = tick / 1000; - tick_time = 1000; // [GodLesZ] tick time + status_change_start(src,bl,SC_ANKLE,10000,val1,0,0,0,2000,SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF); break; /* Rune Knight */ @@ -10449,7 +10451,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty case SC_TINDER_BREAKER2: case SC_BITE: case SC_THORNSTRAP: - case SC_FEAR: case SC_MEIKYOUSISUI: case SC_KYOUGAKU: case SC_PARALYSIS: @@ -12184,15 +12185,6 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) } break; - case SC_FEAR: - if( --(sce->val4) >= 0 ) { - if( sce->val2 > 0 ) - sce->val2--; - sc_timer_next(1000 + tick, status_change_timer, bl->id, data); - return 0; - } - break; - case SC_SPHERE_1: case SC_SPHERE_2: case SC_SPHERE_3: @@ -12964,6 +12956,7 @@ int status_change_spread(struct block_list *src, struct block_list *bl, bool typ //case SC_STRIPHELM: //case SC__STRIPACCESSORY: //case SC_BITE: + case SC_FEAR: case SC_FREEZING: case SC_VENOMBLEED: if (sc->data[i]->timer != INVALID_TIMER) @@ -12987,9 +12980,6 @@ int status_change_spread(struct block_list *src, struct block_list *bl, bool typ else data.tick = INVALID_TIMER; break; - case SC_FEAR: - data.tick = sc->data[i]->val4 * 1000; - break; default: continue; } diff --git a/src/map/status.h b/src/map/status.h index d3885fce5b..bb24b23807 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -2150,7 +2150,6 @@ struct status_change *status_get_sc(struct block_list *bl); int status_isdead(struct block_list *bl); int status_isimmune(struct block_list *bl); -int status_get_sc_interval(enum sc_type type); int status_get_sc_def(struct block_list *src,struct block_list *bl, enum sc_type type, int rate, int tick, unsigned char flag); //Short version, receives rate in 1->100 range, and does not uses a flag setting. #define sc_start(src, bl, type, rate, val1, tick) status_change_start(src,bl,type,100*(rate),val1,0,0,0,tick,SCSTART_NONE) diff --git a/src/map/unit.c b/src/map/unit.c index 4c722a046e..8e3d3fbe1d 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1358,7 +1358,6 @@ int unit_can_move(struct block_list *bl) { // Status changes that block movement if (sc) { if( sc->cant.move // status placed here are ones that cannot be cached by sc->cant.move for they depend on other conditions other than their availability - || (sc->data[SC_FEAR] && sc->data[SC_FEAR]->val2 > 0) || (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1) || (sc->data[SC_DANCING] && sc->data[SC_DANCING]->val4 && ( !sc->data[SC_LONGING] || From b5de854b90353f2decf83a95fba8c19fbe641fb7 Mon Sep 17 00:00:00 2001 From: Playtester Date: Sun, 13 Mar 2016 16:42:46 +0100 Subject: [PATCH 014/319] Snap, Ganbantein, Gravitational Field, Flying Kick (fixes #1052) * Snap now has a server-sided range of 14 * Snap, Ganbantein and Gravitational Field will no longer cause you to move if you target a cell out of range * Snap and Flying Kick will now check for obstacles on a linear path rather than on the normal walkpath * Range specified in skill_db is now equal to the client-sided range * Some range code cleanup --- db/pre-re/skill_db.txt | 6 ++--- db/re/skill_db.txt | 6 ++--- src/map/battle.c | 2 +- src/map/clif.c | 18 +++++++------- src/map/mob.c | 12 +++++----- src/map/path.c | 4 ++++ src/map/pc.c | 2 +- src/map/script.c | 2 +- src/map/skill.c | 53 ++++++++++++++++++++++-------------------- src/map/skill.h | 2 +- src/map/status.c | 4 ++-- src/map/unit.c | 9 ++++--- 12 files changed, 65 insertions(+), 55 deletions(-) diff --git a/db/pre-re/skill_db.txt b/db/pre-re/skill_db.txt index fd0b5ea96c..3f2a158397 100644 --- a/db/pre-re/skill_db.txt +++ b/db/pre-re/skill_db.txt @@ -638,7 +638,7 @@ 431,0,0,4,0,0x1,0,4,1,yes,0,0,0,magic,0,0x0, SG_SUN_COMFORT,Comfort of the Sun 432,0,0,4,0,0x1,0,4,1,yes,0,0,0,magic,0,0x0, SG_MOON_COMFORT,Comfort of the Moon 433,0,0,4,0,0x1,0,4,1,yes,0,0,0,magic,0,0x0, SG_STAR_COMFORT,Comfort of the Stars -434,10,6,1,0,0x1,0,3,1,yes,0,0,0,magic,0,0x0, SG_HATE,Hatred of the Sun Moon and Stars +434,9,6,1,0,0x1,0,3,1,yes,0,0,0,magic,0,0x0, SG_HATE,Hatred of the Sun Moon and Stars 435,0,0,0,0,0,0,3,0,no,0,0,0,none,0,0x0, SG_SUN_ANGER,Anger of the Sun 436,0,0,0,0,0,0,3,0,no,0,0,0,none,0,0x0, SG_MOON_ANGER,Anger of the Moon 437,0,0,0,0,0,0,3,0,no,0,0,0,none,0,0x0, SG_STAR_ANGER,Anger of the Stars @@ -702,8 +702,8 @@ 480,5,8,1,0,0,0,5,5,no,0,0,0,weapon,0,0x20000, PA_SHIELDCHAIN,Shield Chain 481,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, HP_MANARECHARGE,Mana Recharge 482,0,6,4,0,0x1,0,5,1,no,0,0,0,magic,0,0x0, PF_DOUBLECASTING,Double Casting -483,14,6,2,0,0x1,1:2:3:4:5,1,1,no,0,0,0,none,0,0x0, HW_GANBANTEIN,Ganbantein -484,14,6,2,2,0xD1,0,5,1,yes,0,0x18000,0,misc,0,0x11010, HW_GRAVITATION,Gravitation Field +483,18,6,2,0,0x1,1:2:3:4:5,1,1,no,0,0,0,none,0,0x0, HW_GANBANTEIN,Ganbantein +484,18,6,2,2,0xD1,0,5,1,yes,0,0x18000,0,misc,0,0x11010, HW_GRAVITATION,Gravitation Field 485,-2,6,1,-1,0x8,0,10,1,no,0,0,0,weapon,0,0x4000, WS_CARTTERMINATION,Cart Termination 486,0,6,4,0,0x1,0,5,1,no,0,0,0,weapon,0,0x4000, WS_OVERTHRUSTMAX,Maximum Power Thrust 487,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x8, CG_LONGINGFREEDOM,Longing for Freedom diff --git a/db/re/skill_db.txt b/db/re/skill_db.txt index 11a0fac42d..a90d84f8c2 100644 --- a/db/re/skill_db.txt +++ b/db/re/skill_db.txt @@ -638,7 +638,7 @@ 431,0,0,4,0,0x1,0,4,1,yes,0,0,0,magic,0,0x0, SG_SUN_COMFORT,Comfort of the Sun 432,0,0,4,0,0x1,0,4,1,yes,0,0,0,magic,0,0x0, SG_MOON_COMFORT,Comfort of the Moon 433,0,0,4,0,0x1,0,4,1,yes,0,0,0,magic,0,0x0, SG_STAR_COMFORT,Comfort of the Stars -434,10,6,1,0,0x1,0,3,1,yes,0,0,0,magic,0,0x0, SG_HATE,Hatred of the Sun Moon and Stars +434,9,6,1,0,0x1,0,3,1,yes,0,0,0,magic,0,0x0, SG_HATE,Hatred of the Sun Moon and Stars 435,0,0,0,0,0,0,3,0,no,0,0,0,none,0,0x0, SG_SUN_ANGER,Anger of the Sun 436,0,0,0,0,0,0,3,0,no,0,0,0,none,0,0x0, SG_MOON_ANGER,Anger of the Moon 437,0,0,0,0,0,0,3,0,no,0,0,0,none,0,0x0, SG_STAR_ANGER,Anger of the Stars @@ -702,8 +702,8 @@ 480,5,8,1,-1,0,0,5,5,no,0,0,0,weapon,0,0x20000, PA_SHIELDCHAIN,Shield Chain 481,0,0,0,0,0,0,5,0,no,0,0,0,none,0,0x0, HP_MANARECHARGE,Mana Recharge 482,0,6,4,0,0x1,0,5,1,no,0,0,0,magic,0,0x0, PF_DOUBLECASTING,Double Casting -483,14,6,2,0,0x1,1:2:3:4:5,1,1,no,0,0,0,none,0,0x0, HW_GANBANTEIN,Ganbantein -484,14,6,2,2,0xD1,0,5,1,yes,0,0x18000,0,misc,0,0x11010, HW_GRAVITATION,Gravitation Field +483,18,6,2,0,0x1,1:2:3:4:5,1,1,no,0,0,0,none,0,0x0, HW_GANBANTEIN,Ganbantein +484,18,6,2,2,0xD1,0,5,1,yes,0,0x18000,0,misc,0,0x11010, HW_GRAVITATION,Gravitation Field 485,-2,6,1,-1,0x8,0,10,1,no,0,0,0,weapon,0,0x4000, WS_CARTTERMINATION,Cart Termination 486,0,6,4,0,0x1,0,5,1,no,0,0,0,weapon,0,0x4000, WS_OVERTHRUSTMAX,Maximum Power Thrust 487,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x8, CG_LONGINGFREEDOM,Longing for Freedom diff --git a/src/map/battle.c b/src/map/battle.c index 0b6a0fa259..87861f0dee 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2001,7 +2001,7 @@ static int battle_range_type(struct block_list *src, struct block_list *target, } //based on used skill's range - if (skill_get_range2(src, skill_id, skill_lv) < 4) + if (skill_get_range2(src, skill_id, skill_lv, true) < 4) return BF_SHORT; return BF_LONG; } diff --git a/src/map/clif.c b/src/map/clif.c index 5b5fa00a5f..c00bed7c29 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1620,7 +1620,7 @@ int clif_homskillinfoblock(struct map_session_data *sd) WFIFOW(fd,len+4) = 0; WFIFOW(fd,len+6) = hd->homunculus.hskill[idx].lv; WFIFOW(fd,len+8) = skill_get_sp(id,hd->homunculus.hskill[idx].lv); - WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,hd->homunculus.hskill[idx].lv); + WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl,id,hd->homunculus.hskill[idx].lv,false); safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH); WFIFOB(fd,len+36) = (hd->homunculus.level < hom_skill_get_min_level(hd->homunculus.class_, id) || hd->homunculus.hskill[idx].lv >= hom_skill_tree_get_max(id, hd->homunculus.class_)) ? 0 : 1; len+=37; @@ -1650,7 +1650,7 @@ void clif_homskillup(struct map_session_data *sd, uint16 skill_id) WFIFOW(fd,2) = skill_id; WFIFOW(fd,4) = hd->homunculus.hskill[idx].lv; WFIFOW(fd,6) = skill_get_sp(skill_id,hd->homunculus.hskill[idx].lv); - WFIFOW(fd,8) = skill_get_range2(&hd->bl, skill_id,hd->homunculus.hskill[idx].lv); + WFIFOW(fd,8) = skill_get_range2(&hd->bl,skill_id,hd->homunculus.hskill[idx].lv,false); WFIFOB(fd,10) = (hd->homunculus.level < hom_skill_get_min_level(hd->homunculus.class_, skill_id) || hd->homunculus.hskill[idx].lv >= hom_skill_tree_get_max(hd->homunculus.hskill[idx].id, hd->homunculus.class_)) ? 0 : 1; WFIFOSET(fd,packet_len(0x239)); } @@ -5168,7 +5168,7 @@ void clif_skillinfoblock(struct map_session_data *sd) WFIFOL(fd,len+2) = skill_get_inf(id); WFIFOW(fd,len+6) = sd->status.skill[i].lv; WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv); - WFIFOW(fd,len+10)= skill_get_range2(&sd->bl, id,sd->status.skill[i].lv); + WFIFOW(fd,len+10)= skill_get_range2(&sd->bl,id,sd->status.skill[i].lv,false); safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH); if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) WFIFOB(fd,len+36) = (sd->status.skill[i].lv < skill_tree_get_max(id, sd->status.class_))? 1:0; @@ -5216,7 +5216,7 @@ void clif_addskill(struct map_session_data *sd, int skill_id) WFIFOL(fd,4) = skill_get_inf(skill_id); WFIFOW(fd,8) = sd->status.skill[idx].lv; WFIFOW(fd,10) = skill_get_sp(skill_id,sd->status.skill[idx].lv); - WFIFOW(fd,12)= skill_get_range2(&sd->bl, skill_id,sd->status.skill[idx].lv); + WFIFOW(fd,12)= skill_get_range2(&sd->bl,skill_id,sd->status.skill[idx].lv,false); safestrncpy((char*)WFIFOP(fd,14), skill_get_name(skill_id), NAME_LENGTH); if( sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT ) WFIFOB(fd,38) = (sd->status.skill[idx].lv < skill_tree_get_max(skill_id, sd->status.class_))? 1:0; @@ -5282,7 +5282,7 @@ void clif_skillinfo(struct map_session_data *sd,int skill_id, int inf) WFIFOL(fd,4) = inf?inf:skill_get_inf(skill_id); WFIFOW(fd,8) = sd->status.skill[idx].lv; WFIFOW(fd,10) = skill_get_sp(skill_id,sd->status.skill[idx].lv); - WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill_id,sd->status.skill[idx].lv); + WFIFOW(fd,12) = skill_get_range2(&sd->bl,skill_id,sd->status.skill[idx].lv,false); if( sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT ) WFIFOB(fd,14) = (sd->status.skill[idx].lv < skill_tree_get_max(skill_id, sd->status.class_))? 1:0; else @@ -6597,7 +6597,7 @@ void clif_item_skill(struct map_session_data *sd,uint16 skill_id,uint16 skill_lv WFIFOW(fd, 6)=0; WFIFOW(fd, 8)=skill_lv; WFIFOW(fd,10)=skill_get_sp(skill_id,skill_lv); - WFIFOW(fd,12)=skill_get_range2(&sd->bl, skill_id,skill_lv); + WFIFOW(fd,12)=skill_get_range2(&sd->bl,skill_id,skill_lv,false); safestrncpy((char*)WFIFOP(fd,14),skill_get_name(skill_id),NAME_LENGTH); WFIFOB(fd,38)=0; WFIFOSET(fd,packet_len(0x147)); @@ -7796,7 +7796,7 @@ void clif_devotion(struct block_list *src, struct map_session_data *tsd) if( md && md->master && md->devotion_flag ) WBUFL(buf,6) = md->master->bl.id; - WBUFW(buf,26) = skill_get_range2(src, ML_DEVOTION, mercenary_checkskill(md, ML_DEVOTION)); + WBUFW(buf,26) = skill_get_range2(src, ML_DEVOTION, mercenary_checkskill(md, ML_DEVOTION), false); } else { @@ -7807,7 +7807,7 @@ void clif_devotion(struct block_list *src, struct map_session_data *tsd) for( i = 0; i < 5 /*MAX_DEVOTION*/; i++ ) // Client only able show to 5 links WBUFL(buf,6+4*i) = sd->devotion[i]; - WBUFW(buf,26) = skill_get_range2(src, CR_DEVOTION, pc_checkskill(sd, CR_DEVOTION)); + WBUFW(buf,26) = skill_get_range2(src, CR_DEVOTION, pc_checkskill(sd, CR_DEVOTION), false); } if( tsd ) @@ -16296,7 +16296,7 @@ void clif_mercenary_skillblock(struct map_session_data *sd) WFIFOL(fd,len+2) = skill_get_inf(id); WFIFOW(fd,len+6) = md->db->skill[idx].lv; WFIFOW(fd,len+8) = skill_get_sp(id, md->db->skill[idx].lv); - WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, md->db->skill[idx].lv); + WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, md->db->skill[idx].lv, false); safestrncpy((char*)WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH); WFIFOB(fd,len+36) = 0; // Skillable for Mercenary? len += 37; diff --git a/src/map/mob.c b/src/map/mob.c index a7984ccbda..e3520bfe2c 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -3369,7 +3369,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) switch (skill_target) { case MST_RANDOM: //Pick a random enemy within skill range. bl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md), - skill_get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv)); + skill_get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv, true)); break; case MST_TARGET: case MST_AROUND5: @@ -3404,8 +3404,8 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) } md->skill_idx = i; map_freeblock_lock(); - if( !battle_check_range(&md->bl,bl,skill_get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv)) || - !unit_skilluse_pos2(&md->bl, x, y,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel) ) + if (!battle_check_range(&md->bl, bl, skill_get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv, true)) || + !unit_skilluse_pos2(&md->bl, x, y, ms[i].skill_id, ms[i].skill_lv, ms[i].casttime, ms[i].cancel)) { map_freeblock_unlock(); continue; @@ -3415,7 +3415,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) switch (skill_target) { case MST_RANDOM: //Pick a random enemy within skill range. bl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md), - skill_get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv)); + skill_get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv, true)); break; case MST_TARGET: bl = map_id2bl(md->target_id); @@ -3442,8 +3442,8 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) md->skill_idx = i; map_freeblock_lock(); - if( !battle_check_range(&md->bl,bl,skill_get_range2(&md->bl, ms[i].skill_id,ms[i].skill_lv)) || - !unit_skilluse_id2(&md->bl, bl->id,ms[i].skill_id, ms[i].skill_lv,ms[i].casttime, ms[i].cancel) ) + if (!battle_check_range(&md->bl, bl, skill_get_range2(&md->bl, ms[i].skill_id, ms[i].skill_lv, true)) || + !unit_skilluse_id2(&md->bl, bl->id, ms[i].skill_id, ms[i].skill_lv, ms[i].casttime, ms[i].cancel)) { map_freeblock_unlock(); continue; diff --git a/src/map/path.c b/src/map/path.c index b653da9d52..e20e48946d 100644 --- a/src/map/path.c +++ b/src/map/path.c @@ -247,6 +247,7 @@ static int add_path(struct node_heap *heap, struct path_node *tp, int16 x, int16 * path search (x0,y0)->(x1,y1) * wpd: path info will be written here * flag: &1 = easy path search only + * flag: &2 = call path_search_long instead * cell: type of obstruction to check for *------------------------------------------*/ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int flag, cell_chk cell) @@ -255,6 +256,9 @@ bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x struct map_data *md; struct walkpath_data s_wpd; + if (flag&2) + return path_search_long(NULL, m, x0, y0, x1, y1, cell); + if (wpd == NULL) wpd = &s_wpd; // use dummy output variable diff --git a/src/map/pc.c b/src/map/pc.c index eb6fb56b25..a4f87404ca 100755 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -6856,7 +6856,7 @@ void pc_skillup(struct map_session_data *sd,uint16 skill_id) pc_check_skilltree(sd); // Check if a new skill can Lvlup lv = sd->status.skill[idx].lv; - range = skill_get_range2(&sd->bl, skill_id, lv); + range = skill_get_range2(&sd->bl, skill_id, lv, false); upgradable = (lv < skill_tree_get_max(sd->status.skill[idx].id, sd->status.class_)) ? 1 : 0; clif_skillup(sd,skill_id,lv,range,upgradable); clif_updatestatus(sd,SP_SKILLPOINT); diff --git a/src/map/script.c b/src/map/script.c index 43392ad594..9a88bc4b8e 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -19161,7 +19161,7 @@ static int buildin_mobuseskill_sub(struct block_list *bl,va_list ap) case 0: tbl = map_id2bl(md->bl.id); break; case 1: tbl = map_id2bl(md->target_id); break; case 2: tbl = map_id2bl(md->master_id); break; - default:tbl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md),skill_get_range2(&md->bl, skill_id, skill_lv)); break; + default:tbl = battle_getenemy(&md->bl, DEFAULT_ENEMY_TYPE(md), skill_get_range2(&md->bl, skill_id, skill_lv, true)); break; } if( !tbl ) diff --git a/src/map/skill.c b/src/map/skill.c index 8c6e9b16c9..8f20a2ea81 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -343,7 +343,7 @@ int skill_get_casttype (uint16 skill_id) { } //Returns actual skill range taking into account attack range and AC_OWL [Skotlex] -int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) { +int skill_get_range2(struct block_list *bl, uint16 skill_id, uint16 skill_lv, bool isServer) { int range, inf3=0; if( bl->type == BL_MOB && battle_config.mob_ai&0x400 ) return 9; //Mobs have a range of 9 regardless of skill used. @@ -355,8 +355,12 @@ int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) { return status_get_range(bl); range *=-1; } - inf3 = skill_get_inf3(skill_id); + if (isServer && range > 14) { + range = 14; // Server-sided base range can't be above 14 + } + + inf3 = skill_get_inf3(skill_id); if(inf3&(INF3_EFF_VULTURE|INF3_EFF_SNAKEEYE) ){ if( bl->type == BL_PC ) { if(inf3&INF3_EFF_VULTURE) range += pc_checkskill((TBL_PC*)bl, AC_VULTURE); @@ -365,7 +369,6 @@ int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) { } else range += battle_config.mob_eye_range_bonus; } - if(inf3&(INF3_EFF_SHADOWJUMP|INF3_EFF_RADIUS|INF3_EFF_RESEARCHTRAP) ){ if( bl->type == BL_PC ) { if(inf3&INF3_EFF_SHADOWJUMP) range = skill_get_range(NJ_SHADOWJUMP,pc_checkskill((TBL_PC*)bl,NJ_SHADOWJUMP)); @@ -1989,8 +1992,8 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 continue; } } - if( battle_config.autospell_check_range && - !battle_check_range(src, tbl, skill_get_range2(src, skill,autospl_skill_lv) + (skill == RG_CLOSECONFINE?0:1)) ) + if (battle_config.autospell_check_range && + !battle_check_range(src, tbl, skill_get_range2(src, skill, autospl_skill_lv, true))) continue; if (skill == AS_SONICBLOW) @@ -2118,8 +2121,8 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint1 continue; } } - if( battle_config.autospell_check_range && - !battle_check_range(&sd->bl, tbl, skill_get_range2(&sd->bl, skill,skill_lv) + (skill == RG_CLOSECONFINE?0:1)) ) + if (battle_config.autospell_check_range && + !battle_check_range(&sd->bl, tbl, skill_get_range2(&sd->bl, skill, skill_lv, true))) continue; sd->state.autocast = 1; @@ -2330,7 +2333,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * } } - if( !battle_check_range(src, tbl, skill_get_range2(src, autospl_skill_id,autospl_skill_lv) + (autospl_skill_id == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range ) + if (!battle_check_range(src, tbl, skill_get_range2(src, autospl_skill_id, autospl_skill_lv, true)) && battle_config.autospell_check_range) continue; dstsd->state.autocast = 1; @@ -6298,7 +6301,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case TK_JUMPKICK: /* Check if the target is an enemy; if not, skill should fail so the character doesn't unit_movepos (exploitable) */ if( battle_check_target(src, bl, BCT_ENEMY) > 0 ) { - if( unit_movepos(src, bl->x, bl->y, 1, 1) ) { + if( unit_movepos(src, bl->x, bl->y, 2, 1) ) { skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); clif_blown(src); } @@ -6566,7 +6569,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( dstmd ) { dstmd->state.provoke_flag = src->id; - mob_target(dstmd, src, skill_get_range2(src,skill_id,skill_lv)); + mob_target(dstmd, src, skill_get_range2(src, skill_id, skill_lv, true)); } break; @@ -6617,7 +6620,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui mer->devotion_flag = 1; // Mercenary Devoting Owner clif_skill_nodamage(src, bl, skill_id, skill_lv, - sc_start4(src, bl, type, 10000, src->id, i, skill_get_range2(src,skill_id,skill_lv), 0, skill_get_time2(skill_id, skill_lv))); + sc_start4(src, bl, type, 10000, src->id, i, skill_get_range2(src, skill_id, skill_lv, true), 0, skill_get_time2(skill_id, skill_lv))); clif_devotion(src, NULL); } break; @@ -7025,7 +7028,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if(pc_steal_coin(sd,bl)) { dstmd->state.provoke_flag = src->id; - mob_target(dstmd, src, skill_get_range2(src,skill_id,skill_lv)); + mob_target(dstmd, src, skill_get_range2(src, skill_id, skill_lv, true)); clif_skill_nodamage(src,bl,skill_id,skill_lv,1); } @@ -8169,8 +8172,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui status_change_end(bl, SC_SLEEP, INVALID_TIMER); } - if(dstmd) - mob_target(dstmd,src,skill_get_range2(src,skill_id,skill_lv)); + if (dstmd) + mob_target(dstmd, src, skill_get_range2(src, skill_id, skill_lv, true)); } break; @@ -10964,13 +10967,13 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) clif_emotion(src, md->db->skill[md->skill_idx].emotion); } - if(src != target && battle_config.skill_add_range && - !check_distance_bl(src, target, skill_get_range2(src,ud->skill_id,ud->skill_lv)+battle_config.skill_add_range)) + if (src != target && battle_config.skill_add_range && + !check_distance_bl(src, target, skill_get_range2(src, ud->skill_id, ud->skill_lv, true) + battle_config.skill_add_range)) { if (sd) { - clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0); - if(battle_config.skill_out_range_consume) //Consume items anyway. [Skotlex] - skill_consume_requirement(sd,ud->skill_id,ud->skill_lv,3); + clif_skill_fail(sd, ud->skill_id, USESKILL_FAIL_LEVEL, 0); + if (battle_config.skill_out_range_consume) //Consume items anyway. [Skotlex] + skill_consume_requirement(sd, ud->skill_id, ud->skill_lv, 3); } break; } @@ -11201,10 +11204,10 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) { //Avoid double checks on instant cast skills. [Skotlex] if (!status_check_skilluse(src, NULL, ud->skill_id, 1)) break; - if(battle_config.skill_add_range && - !check_distance_blxy(src, ud->skillx, ud->skilly, skill_get_range2(src,ud->skill_id,ud->skill_lv)+battle_config.skill_add_range)) { + if (battle_config.skill_add_range && + !check_distance_blxy(src, ud->skillx, ud->skilly, skill_get_range2(src, ud->skill_id, ud->skill_lv, true) + battle_config.skill_add_range)) { if (sd && battle_config.skill_out_range_consume) //Consume items anyway. - skill_consume_requirement(sd,ud->skill_id,ud->skill_lv,3); + skill_consume_requirement(sd, ud->skill_id, ud->skill_lv, 3); break; } } @@ -11577,7 +11580,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui return 0; // not to consume item. case MO_BODYRELOCATION: - if (unit_movepos(src, x, y, 1, 1)) { + if (unit_movepos(src, x, y, 2, 1)) { #if PACKETVER >= 20111005 clif_snap(src, src->x, src->y); #else @@ -16277,8 +16280,8 @@ void skill_repairweapon(struct map_session_data *sd, int idx) { if( !item->nameid || !item->attribute ) return; //Again invalid item.... - if( sd != target_sd && !battle_check_range(&sd->bl,&target_sd->bl, skill_get_range2(&sd->bl, sd->menuskill_id,sd->menuskill_val2) ) ){ - clif_item_repaireffect(sd,idx,1); + if (sd != target_sd && !battle_check_range(&sd->bl, &target_sd->bl, skill_get_range2(&sd->bl, sd->menuskill_id, sd->menuskill_val2, true))) { + clif_item_repaireffect(sd, idx, 1); return; } diff --git a/src/map/skill.h b/src/map/skill.h index c93cbc5349..82d850e4c1 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -375,7 +375,7 @@ int skill_get_ele( uint16 skill_id , uint16 skill_lv ); int skill_get_nk( uint16 skill_id ); int skill_get_max( uint16 skill_id ); int skill_get_range( uint16 skill_id , uint16 skill_lv ); -int skill_get_range2(struct block_list *bl, uint16 skill_id, uint16 skill_lv); +int skill_get_range2(struct block_list *bl, uint16 skill_id, uint16 skill_lv, bool isServer); int skill_get_splash( uint16 skill_id , uint16 skill_lv ); int skill_get_num( uint16 skill_id ,uint16 skill_lv ); int skill_get_cast( uint16 skill_id ,uint16 skill_lv ); diff --git a/src/map/status.c b/src/map/status.c index e1292dd968..dcf501dcf8 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -11225,8 +11225,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const if (sce->val2 > 0) { // Caster has been unlocked... nearby chars need to be unlocked. int range = 1 - +skill_get_range2(bl, status_sc2skill(type), sce->val1) - +skill_get_range2(bl, TF_BACKSLIDING, 1); // Since most people use this to escape the hold.... + + skill_get_range2(bl, status_sc2skill(type), sce->val1, true) + + skill_get_range2(bl, TF_BACKSLIDING, 1, true); // Since most people use this to escape the hold.... map_foreachinarea(status_change_timer_sub, bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick()); } diff --git a/src/map/unit.c b/src/map/unit.c index 8e3d3fbe1d..426673b322 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -898,7 +898,10 @@ int unit_escape(struct block_list *bl, struct block_list *target, short dist) * @param bl: Object to instant warp * @param dst_x: X coordinate to warp to * @param dst_y: Y coordinate to warp to - * @param easy: Easy(1) or Hard(0) path check (hard attempts to go around obstacles) + * @param easy: + * 0: Hard path check (attempt to go around obstacle) + * 1: Easy path check (no obstacle on movement path) + * 2: Long path check (no obstacle on line from start to destination) * @param checkpath: Whether or not to do a cell and path check for NOPASS and NOREACH * @return True: Success False: Fail */ @@ -1691,7 +1694,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui if (src->type == BL_NPC) // NPC-objects can override cast distance range = AREA_SIZE; // Maximum visible distance before NPC goes out of sight else - range = skill_get_range2(src, skill_id, skill_lv); // Skill cast distance from database + range = skill_get_range2(src, skill_id, skill_lv, true); // Skill cast distance from database // New action request received, delete previous action request if not executed yet if(ud->stepaction || ud->steptimer != INVALID_TIMER) @@ -1994,7 +1997,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui if (src->type == BL_NPC) // NPC-objects can override cast distance range = AREA_SIZE; // Maximum visible distance before NPC goes out of sight else - range = skill_get_range2(src, skill_id, skill_lv); // Skill cast distance from database + range = skill_get_range2(src, skill_id, skill_lv, true); // Skill cast distance from database // New action request received, delete previous action request if not executed yet if(ud->stepaction || ud->steptimer != INVALID_TIMER) From dce590706251f0efa9004c624698805f607a2297 Mon Sep 17 00:00:00 2001 From: Aleos Date: Sun, 13 Mar 2016 16:16:16 -0400 Subject: [PATCH 015/319] Updated atcommand documentation * Added missing atccommand adopt (from 0f5b6db). * Added a missing variation for atcommand duel which allows an integer value for duel size. --- doc/atcommands.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/atcommands.txt b/doc/atcommands.txt index 7a647f61ac..b81fbd887e 100644 --- a/doc/atcommands.txt +++ b/doc/atcommands.txt @@ -3,7 +3,7 @@ //===== By: ================================================== //= rAthena Dev Team //===== Last Updated: ======================================== -//= 20140425 +//= 20160313 //===== Description: ========================================= //= List of available atcommands and their functions. //============================================================ @@ -1019,6 +1019,7 @@ Additionally, @sizeall will change the size of all online players. --------------------------------------- +@duel {} @duel {} @invite @accept @@ -1026,6 +1027,7 @@ Additionally, @sizeall will change the size of all online players. @leave Duel-organizing commands. +When specifying the participant count accepted values are 2 ~ 65535. Some options can be found in '/conf/battle/misc.conf'. --------------------------------------- @@ -1164,6 +1166,12 @@ Marries or divorces two players. --------------------------------------- +@adopt + +Adopts the specified player with the attached character as one of the parents. + +--------------------------------------- + @request Sends a message to all connected GMs (via the GM whisper system). From 074bdded0979bb503288c02ec47cc5498da4023e Mon Sep 17 00:00:00 2001 From: aleos89 Date: Mon, 14 Mar 2016 18:50:29 -0400 Subject: [PATCH 016/319] Cleaned up rental item expiration * Boarding Halter will now properly be removed on expiration when a player is logged out. (fixes #1035) * Removed hard coded checks for other official rental items. * Rental items now call the OnUnequip Script of the item which can be used to remove player states. * Updated various items in the database to match the new format. --- db/pre-re/item_db.txt | 18 +++---- db/re/item_db.txt | 26 +++++----- doc/item_db.txt | 3 +- doc/script_commands.txt | 4 ++ src/char/char_mapif.c | 8 +++ src/map/itemdb.h | 9 ---- src/map/pc.c | 109 +++++++--------------------------------- src/map/pc.h | 1 - src/map/status.c | 1 - 9 files changed, 54 insertions(+), 125 deletions(-) diff --git a/db/pre-re/item_db.txt b/db/pre-re/item_db.txt index 96a4d1ae3c..b975b23aa9 100644 --- a/db/pre-re/item_db.txt +++ b/db/pre-re/item_db.txt @@ -4848,9 +4848,9 @@ 12284,Internet_Cafe3,Internet Cafe3,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ sc_start SC_INCINT,5400000,8; sc_start SC_INCVIT,5400000,4; sc_start SC_INCDEX,5400000,6; sc_start SC_MATKPOTION,5400000,40; },{},{} 12285,Internet_Cafe4,Internet Cafe4,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ sc_start SC_INCDEX,5400000,8; sc_start SC_INCLUK,5400000,4; sc_start SC_INCAGI,5400000,6; sc_start SC_ATKPOTION,5400000,24; sc_start SC_MATKPOTION,5400000,24; },{},{} 12286,Masquerade_Ball_Box2,Masquerade Ball Box2,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ getrandgroupitem(IG_Masquerade_2),1; },{},{} -12287,Love_Angel,Love Angel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 1; },{},{} -12288,Squirrel,Squirrel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 2; },{},{} -12289,Gogo,Gogo Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 3; },{},{} +12287,Love_Angel,Love Angel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 1; },{},{ setfont 0; } +12288,Squirrel,Squirrel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 2; },{},{ setfont 0; } +12289,Gogo,Gogo Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 3; },{},{ setfont 0; } 12290,Mysterious_Can,Mysterious Can Magic Powder,2,10,,100,,,,,0xFFFFFFFF,7,2,,,,,,{ percentheal 5,0; skilleffect "AL_BLESSING",0; sc_start SC_BLESSING,120000,5; },{},{} 12291,Mysterious_PET_Bottle,Mysterious PET Bottle,2,10,,100,,,,,0xFFFFFFFF,7,2,,,,,,{ percentheal 5,0; skilleffect "AL_INCAGI",0; sc_start SC_INCREASEAGI,120000,5; },{},{} 12292,Unripe_Fruit,Unripe Fruit,0,500,,200,,,,,0xFFFFFFFF,7,2,,,,,,{ percentheal 20,0; },{},{} @@ -4865,12 +4865,12 @@ 12301,Doppelganger_Scroll,Doppelganger Contract,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ mercenary_create 1966,1800000; },{},{} 12302,Ygnizem_Scroll,Egnigem Cenia Contract,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{ mercenary_create 1967,1800000; },{},{} 12303,Water_Of_Blessing,Blessing Of Water,2,0,,10,,,,,0xFFFFFFFF,7,2,,,,,,{},{},{} -12304,Picture_Diary,Diary Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 4; },{},{} -12305,Mini_Heart,Mini Heart Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 5; },{},{} -12306,Newcomer,Freshman Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 6; },{},{} -12307,Kid,Kid Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 7; },{},{} -12308,Magic_Castle,Magic Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 8; },{},{} -12309,Bulging_Head,JJangu Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 9; },{},{} +12304,Picture_Diary,Diary Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 4; },{},{ setfont 0; } +12305,Mini_Heart,Mini Heart Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 5; },{},{ setfont 0; } +12306,Newcomer,Freshman Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 6; },{},{ setfont 0; } +12307,Kid,Kid Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 7; },{},{ setfont 0; } +12308,Magic_Castle,Magic Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 8; },{},{ setfont 0; } +12309,Bulging_Head,JJangu Magic Powder,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ setfont 9; },{},{ setfont 0; } 12310,Spray_Of_Flowers,Spray Of Flowers,2,0,,50,,,,,0xFFFFFFFF,7,2,,,,,,{ sc_start SC_INCFLEE,600000,10; },{},{} 12311,Large_Spray_Of_Flowers,Huge Spray Of Flowers,11,0,,100,,,,,0xFFFFFFFF,7,2,,,,,,{ itemskill "ALL_PARTYFLEE",1; },{},{} 12312,Thick_Manual50,Thick Battle Manual,2,0,,0,,,,,0xFFFFFFFF,7,2,,,,,,{ sc_start SC_EXPBOOST,3600000,50; },{},{} diff --git a/db/re/item_db.txt b/db/re/item_db.txt index f1e23e71f6..ff2a1016cf 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -3886,9 +3886,9 @@ 5885,Blue_Wizardry_Hat_C,Blue Mage Hat C,4,20,,300,,1,,0,0x00810204,63,2,256,,0,1,285,{ bonus bInt,2; bonus bMaxSP,150; },{},{} 5886,Yellow_Wizardry_Hat_C,Yellow Mage Hat C,4,20,,300,,1,,0,0x00810204,63,2,256,,0,1,286,{ bonus bInt,2; bonus bMaxSP,150; },{},{} 5887,Half_L_Magestic_Goat,Half L Majestic Goat,4,20,,800,,5,,0,0xFFFFFFFF,63,2,256,,0,1,380,{ bonus2 bAddRace,RC_DemiHuman,10; bonus2 bAddRace,RC_Player,10; bonus bBaseAtk,(JobLevel*2)/7; },{},{} -5892,RCC2013_1ST_CROWN,RCC2013 1ST CROWN,4,20,,2500,,7,,1,0xFFFFFFFF,63,2,256,,1,0,1106,{ bonus bAllStats,5; sc_start SC_SPEEDUP0,-1,25; skill "AL_TELEPORT",1; },{ sc_end SC_SPEEDUP0; },{} -5893,RCC2013_2ND_CROWN,RCC2013 2ND CROWN,4,20,,2500,,7,,1,0xFFFFFFFF,63,2,256,,1,0,1107,{ bonus bAllStats,4; sc_start SC_SPEEDUP0,-1,25; skill "AL_TELEPORT",1; },{ sc_end SC_SPEEDUP0; },{} -5894,RCC2013_3RD_CROWN,RCC2013 3RD CROWN,4,20,,2500,,7,,1,0xFFFFFFFF,63,2,256,,1,0,1108,{ bonus bAllStats,3; sc_start SC_SPEEDUP0,-1,25; skill "AL_TELEPORT",1; },{ sc_end SC_SPEEDUP0; },{} +5892,RCC2013_1ST_CROWN,RCC2013 1ST CROWN,4,20,,2500,,7,,1,0xFFFFFFFF,63,2,256,,1,0,1106,{ bonus bAllStats,5; skill "AL_TELEPORT",1; },{ sc_start SC_SPEEDUP0,-1,25; },{ sc_end SC_SPEEDUP0; } +5893,RCC2013_2ND_CROWN,RCC2013 2ND CROWN,4,20,,2500,,7,,1,0xFFFFFFFF,63,2,256,,1,0,1107,{ bonus bAllStats,4; skill "AL_TELEPORT",1; },{ sc_start SC_SPEEDUP0,-1,25; },{ sc_end SC_SPEEDUP0; } +5894,RCC2013_3RD_CROWN,RCC2013 3RD CROWN,4,20,,2500,,7,,1,0xFFFFFFFF,63,2,256,,1,0,1108,{ bonus bAllStats,3; skill "AL_TELEPORT",1; },{ sc_start SC_SPEEDUP0,-1,25; },{ sc_end SC_SPEEDUP0; } 5895,RCC2013_ANV_Hat,RCC2013 ANV Hat,4,20,,2500,,7,,1,0xFFFFFFFF,63,2,256,,1,0,1109,{ bonus bAllStats,1; bonus2 bAddClass,Class_All,2; bonus bMatkRate,2; },{},{} 5918,Gambler_Seal,Gambler Seal,4,0,,500,,,,0,0xFFFFFFFF,63,2,512,,,1,1202,{ bonus bCritical,3; bonus bCritAtkRate,3; bonus2 bSubSkill,"RA_ARROWSTORM",10; bonus2 bSubSkill,"SR_GATEOFHELL",10; .@dex = readparam(bDex); .@luk = readparam(bLuk); bonus bCritAtkRate,-(.@dex/10)*2; bonus bCritical,.@luk/10; bonus bBaseAtk,(.@luk/10)*2; bonus bMatk,(.@luk/10)*2; if (.@luk > 120) { bonus bCritical,10; bonus bCritAtkRate,10; bonus2 bSubSkill,"RA_ARROWSTORM",30; bonus2 bSubSkill,"SR_GATEOFHELL",30; } else if (.@luk > 108) { bonus bCritical,5; bonus bCritAtkRate,10; } },{},{} 5920,Medical_Boots,Medical Boots,4,0,,300,,10,,0,0xFFFFFFFF,63,2,64,,10,1,,{ .@r = getrefine(); bonus bHealPower,10+((.@r/2) * 2); bonus2 bSkillUseSP,"AB_CHEAL",(.@r * 5); },{},{} @@ -6298,9 +6298,9 @@ 12284,Internet_Cafe3,Internet Cafe3,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_INCINT,5400000,8; sc_start SC_INCVIT,5400000,4; sc_start SC_INCDEX,5400000,6; sc_start SC_MATKPOTION,5400000,40; },{},{} 12285,Internet_Cafe4,Internet Cafe4,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_INCDEX,5400000,8; sc_start SC_INCLUK,5400000,4; sc_start SC_INCAGI,5400000,6; sc_start SC_ATKPOTION,5400000,24; sc_start SC_MATKPOTION,5400000,24; },{},{} 12286,Masquerade_Ball_Box2,Masquerade Ball Box2,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ getrandgroupitem(IG_Masquerade_2,1); },{},{} -12287,Love_Angel,Love Angel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 1; },{},{} -12288,Squirrel,Squirrel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 2; },{},{} -12289,Gogo,Gogo Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 3; },{},{} +12287,Love_Angel,Love Angel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 1; },{},{ setfont 0; } +12288,Squirrel,Squirrel Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 2; },{},{ setfont 0; } +12289,Gogo,Gogo Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 3; },{},{ setfont 0; } 12290,Mysterious_Can,Mysterious Can Magic Powder,2,10,,100,,,,,0xFFFFFFFF,63,2,,,,,,{ percentheal 5,0; skilleffect "AL_BLESSING",0; sc_start SC_BLESSING,120000,5; },{},{} 12291,Mysterious_PET_Bottle,Mysterious PET Bottle,2,10,,100,,,,,0xFFFFFFFF,63,2,,,,,,{ percentheal 5,0; skilleffect "AL_INCAGI",0; sc_start SC_INCREASEAGI,120000,5; },{},{} 12292,Unripe_Fruit,Unripe Yggdrasilberry,0,500,,200,,,,,0xFFFFFFFF,63,2,,,,,,{ percentheal 20,0; },{},{} @@ -6315,12 +6315,12 @@ 12301,Doppelganger_Scroll,Doppelganger Contract,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ mercenary_create 1966,1800000; },{},{} 12302,Ygnizem_Scroll,Egnigem Cenia Contract,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ mercenary_create 1967,1800000; },{},{} 12303,Water_Of_Blessing,Blessing Of Water,2,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} -12304,Picture_Diary,Diary Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 4; },{},{} -12305,Mini_Heart,Mini Heart Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 5; },{},{} -12306,Newcomer,Freshman Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 6; },{},{} -12307,Kid,Kid Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 7; },{},{} -12308,Magic_Castle,Magic Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 8; },{},{} -12309,Bulging_Head,JJangu Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 9; },{},{} +12304,Picture_Diary,Diary Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 4; },{},{ setfont 0; } +12305,Mini_Heart,Mini Heart Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 5; },{},{ setfont 0; } +12306,Newcomer,Freshman Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 6; },{},{ setfont 0; } +12307,Kid,Kid Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 7; },{},{ setfont 0; } +12308,Magic_Castle,Magic Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 8; },{},{ setfont 0; } +12309,Bulging_Head,JJangu Magic Powder,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ setfont 9; },{},{ setfont 0; } 12310,Spray_Of_Flowers,Spray Of Flowers,2,0,,50,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_FLEEFOOD,300000,5; },{},{} 12311,Large_Spray_Of_Flowers,Huge Spray Of Flowers,11,0,,100,,,,,0xFFFFFFFF,63,2,,,,,,{ itemskill "ALL_PARTYFLEE",5; },{},{} 12312,Thick_Manual50,Thick Battle Manual,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_EXPBOOST,3600000,50; },{},{} @@ -6628,7 +6628,7 @@ 12619,Cgrade_Pocket,C Grade Coin Bag,2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ getgroupitem(IG_Cgrade_Pocket); },{},{} 12620,Dgrade_Pocket,D Grade Coin Bag,2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ getgroupitem(IG_Dgrade_Pocket); },{},{} 12621,Egrade_Pocket,E Grade Coin Bag,2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ getgroupitem(IG_Egrade_Pocket); },{},{} -12622,Boarding_Halter,Reins Of Mount,11,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_ALL_RIDING,-1,1; },{},{} +12622,Boarding_Halter,Reins Of Mount,11,0,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ setmounting(); },{},{ if (ismounting()) setmounting(); } 12623,High_Weapon_Box,Advanced Weapons Box,2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ getrandgroupitem(IG_Advanced_Weapons_Box,1); },{},{} 12624,Delicious_Jelly,Delicious Jelly,0,20,,50,,,,,0xFFFFFFFF,63,2,,,,,,{ percentheal 3,3; },{},{} 12625,Sapa_Feat_Cert_Pack,Sapa Feat Cert Pack,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} diff --git a/doc/item_db.txt b/doc/item_db.txt index 2591a33f93..b0876dd861 100644 --- a/doc/item_db.txt +++ b/doc/item_db.txt @@ -223,7 +223,8 @@ OnEquip_Script: Script to execute when the item is equipped. --------------------------------------- -OnUnequip_Script: Script to execute when the item is unequipped. +OnUnequip_Script: Script to execute when the item is unequipped + or when a rental item expires. Warning, not all item bonuses will work here as expected. --------------------------------------- diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 7788ef560f..c2949191e4 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -4480,6 +4480,10 @@ in