diff options
-rw-r--r-- | Changelog-SVN.txt | 20 | ||||
-rw-r--r-- | conf-tmpl/script_athena.conf | 25 | ||||
-rw-r--r-- | db/const.txt | 8 | ||||
-rw-r--r-- | doc/item_bonus.txt | 20 | ||||
-rw-r--r-- | npc/Changelog.txt | 1 | ||||
-rw-r--r-- | npc/quests/all_quest.txt | 2 | ||||
-rw-r--r-- | src/map/battle.c | 120 | ||||
-rw-r--r-- | src/map/map.c | 5 | ||||
-rw-r--r-- | src/map/map.h | 12 | ||||
-rw-r--r-- | src/map/pc.c | 117 | ||||
-rw-r--r-- | src/map/script.c | 43 | ||||
-rw-r--r-- | src/map/script.h | 7 | ||||
-rw-r--r-- | src/map/skill.c | 116 | ||||
-rw-r--r-- | src/map/status.c | 24 |
14 files changed, 409 insertions, 111 deletions
diff --git a/Changelog-SVN.txt b/Changelog-SVN.txt index 87da4e190..bbbe894e7 100644 --- a/Changelog-SVN.txt +++ b/Changelog-SVN.txt @@ -1,6 +1,25 @@ Date Added
02/16
+ * Set 'killerrid' and do PCKillEvent before calling PCDieEvent, thanks to
+ mrmagoo for pointing it out [celest]
+
+ * Added some new script event related options to script config [celest]
+
+ - [die/kill/login/logout]_event_name: Name of script to activate when an
+ event has occured
+ - event_requires_trigger: whether or not a 'set [EventName],1;' has to be
+ defined first for the event to be activated
+
+ * Added 10 of the new card effects on the 2/15's patch (still untested and
+ not yet added to the item_db)
+ - Refer to doc/item_bonus.txt for description
+
+ * Minor rewrites on self and enemy weapon/armor breaking during battle [celest]
+ * Added missing code for 'bBreakWeaponRate' and 'bBreakWeaponRate' effects
+ [celest]
+ * Added missing code for 'bAddStealRate' effect [celest]
+ * Removed redundant 'infinite_autospell' in map_session_data [celest]
* Fixed Treasure Box spawn bug in all castles. [Lupus]
* Fixed wrong PresentLOG (it wasn't showing PRESENT BOX type ID) [Lupus]
* Expanded Monsters Drops Slots from 8 to 10. Everywhere in the sources. [Lupus]
@@ -10,6 +29,7 @@ Date Added On expanding MOB_DB.TXT we'll remove that plug.
We are adding new cards and some monsters
have no free slots for them. Current state is tested and works fine.
+
02/15
* Allow Potion Pitcher to be able to cast on yourself -- i've almost forgot
about this, thanks to Filougarou and Poki#3 for the fix ^^; [celest]
diff --git a/conf-tmpl/script_athena.conf b/conf-tmpl/script_athena.conf index 45ee734f7..bc8f1c907 100644 --- a/conf-tmpl/script_athena.conf +++ b/conf-tmpl/script_athena.conf @@ -11,4 +11,27 @@ warn_cmd_mismatch_paramnum: yes check_cmdcount: 8192 -check_gotocount: 512
\ No newline at end of file +check_gotocount: 512 + + +//---- Custom script functions ---- + +// 0 - Event script is defined as an NPC by itself +// 1 - Event script can be called by script label +event_script_type: 0 + +// Name of event when a player has died +die_event_name: PCDieEvent + +// Name of event when a player kills something +kill_event_name: PCKillEvent + +// Name of event when a player logs out +logout_event_name: PCLogoutEvent + +// Name of event when a player logs in +login_event_name: PCLoginEvent + +// For events to be activated do we require +// a 'set [EventName],1;' to be called first? +event_requires_trigger: yes diff --git a/db/const.txt b/db/const.txt index 71082acce..e8cd07893 100644 --- a/db/const.txt +++ b/db/const.txt @@ -110,8 +110,8 @@ MaxHp 6 1 Sp 7 1 MaxSp 8 1 BaseJob 119 1 -Karma 4 -Manner 5 +Karma 4 1 +Manner 5 1 bMaxHP 6 bMaxSP 8 @@ -241,9 +241,7 @@ bAddEffWhenHit 2016 bAutoSpellWhenHit 2017 bSkillAtk 2018 bUnstripable 2019 -bAddMob 2020 -bSubMob 2021 -bAddByMob 2022 +bAddDamageByClass 2020 Eff_Stone 0 diff --git a/doc/item_bonus.txt b/doc/item_bonus.txt index 30202ee2d..818a1980f 100644 --- a/doc/item_bonus.txt +++ b/doc/item_bonus.txt @@ -135,3 +135,23 @@ bonus3 bAutoSpell,n,x,y; Auto Spell casting of spell n at level x with y% chanc // bAddDamageClass, bAddMagicDamageClass and bAddMonsterDropItem it is setting possible up to 10. Those which exceed 10 are ignored. // those which can be used with the arrow are only bCritical, bAtkEle, bHit, bAddEle, bAddRace, bAddSize and bAddEff. The other things are ignored. + + + +//---- 2/15 new card effects ---- + +bonus bCritAtkRate,n; Increase critical damage by +n% +bonus bNoRegen,n; Stops regeneration for n. + n: 1=HP, 2=SP +bonus bUnstripable,n; Armor cannot be taken off via Strip skills + +bonus2 bCriticalAddRace,n,x; Increase critical + n vs. enemies of type x + +bonus2 bAddEffWhenHit,n,x; n% chance to cause x state to the enemy when + being hit by physical close range damage +bonus2 bSkillAtk,n,x; Increase damage of skill n by x% +bonus2 bAddDamageByClass,n,x; When being hit by monster of class n increase + damage taken by x% + +bonus3 bAutoSpellWhenHit,x,y,n; n% chance to cast skill x of level y when + being hit by physical close range damage diff --git a/npc/Changelog.txt b/npc/Changelog.txt index 12a9e1871..afd47834e 100644 --- a/npc/Changelog.txt +++ b/npc/Changelog.txt @@ -35,6 +35,7 @@ Other Ppl Date Added ====== 02/16 + * Fixed a typo in quests/all_quest.txt, thanks to hongmei [celest] * Fixed treasure chests spawn in the castles. (had to simplify some code and unroll some loops) [Lupus] 02/13 diff --git a/npc/quests/all_quest.txt b/npc/quests/all_quest.txt index a6a6e3264..73a47c6e7 100644 --- a/npc/quests/all_quest.txt +++ b/npc/quests/all_quest.txt @@ -501,7 +501,7 @@ LCancel6: Headset: mes "[Quest Assistant]"; mes "These are Articles needed for my Grandfather's masterpiece."; - mes "^3355FF100 Steel^000000"; + mes "^3355FF40 Steel^000000"; mes "^3355FF1 Oridecon^000000"; mes "^3355FF1 Alchol^000000"; mes "^3355FF1 Coal^000000"; diff --git a/src/map/battle.c b/src/map/battle.c index aa94ac9fc..35b1d2737 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1508,6 +1508,12 @@ static struct Damage battle_calc_mob_weapon_attack( break; } } + for(i=0;i<tsd->add_damage_class_count2;i++) { + if(tsd->add_damage_classid2[i] == md->class_) { + cardfix=cardfix*(100+tsd->add_damage_classrate2[i])/100; + break; + } + } if(flag&BF_LONG) cardfix=cardfix*(100-tsd->long_attack_def_rate)/100; if(flag&BF_SHORT) @@ -1776,6 +1782,7 @@ static struct Damage battle_calc_pc_weapon_attack( if(da == 0){ //ダブルアタックが発動していない // クリティカル計算 cri = status_get_critical(src); + cri += sd->critaddrace[t_race]; if(sd->state.arrow_atk) cri += sd->arrow_cri; @@ -1798,7 +1805,6 @@ static struct Damage battle_calc_pc_weapon_attack( else cri <<= 1; } - if(skill_num == SN_SHARPSHOOTING) cri += 200; } @@ -1812,13 +1818,16 @@ static struct Damage battle_calc_pc_weapon_attack( damage += atkmax; damage2 += atkmax_; if(sd->atk_rate != 100 || sd->weapon_atk_rate != 0) { - if (sd->status.weapon < 16) { - damage = (damage * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; - damage2 = (damage2 * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; - } + if (sd->status.weapon < 16) { + damage = (damage * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; + damage2 = (damage2 * (sd->atk_rate + sd->weapon_atk_rate[sd->status.weapon]))/100; + } } if(sd->state.arrow_atk) damage += sd->arrow_atk; + + damage += damage * sd->crit_atk_rate / 100; + type = 0x0a; /* if(def1 < 1000000) { @@ -2322,6 +2331,8 @@ static struct Damage battle_calc_pc_weapon_attack( damage *= div_; damage2 *= div_; } + if (sd && skill_num > 0 && sd->skillatk[0] == skill_num) + damage += damage*sd->skillatk[1]/100; } if(da == 2) { //三段掌が発動しているか type = 0x08; @@ -2815,37 +2826,45 @@ struct Damage battle_calc_weapon_attack( memset(&wd,0,sizeof(wd)); if(battle_config.equipment_breaking && src->type==BL_PC && (wd.damage > 0 || wd.damage2 > 0)) { - struct map_session_data *sd=(struct map_session_data *)src; - int breakrate = 1; //0.01% weapon breaking chance [DracoRPG] - - if(sd->status.weapon && sd->status.weapon != 11) { - if(sd->sc_data[SC_MELTDOWN].timer!=-1) { - int breakrate_; // separate breaking rates for meltdown [Celest] - breakrate_ = 100*sd->sc_data[SC_MELTDOWN].val1; - if(rand()%10000 < breakrate_*battle_config.equipment_break_rate/100 || breakrate_ >= 10000) { - if (target->type == BL_PC) - pc_breakweapon((struct map_session_data *)target); - else - status_change_start(target,SC_STRIPWEAPON,1,75,0,0,skill_get_time2(WS_MELTDOWN,1),0 ); - } - - breakrate_ = 70*sd->sc_data[SC_MELTDOWN].val1; - if (rand()%10000 < breakrate_*battle_config.equipment_break_rate/100 || breakrate_ >= 10000) { - if (target->type == BL_PC) - pc_breakarmor((struct map_session_data *)target); - else - status_change_start(target,SC_STRIPSHIELD,1,75,0,0,skill_get_time2(WS_MELTDOWN,1),0 ); - } + struct map_session_data *sd = (struct map_session_data *)src; + // weapon = 0, armor = 1 + int breakrate = 1; //0.01% default self weapon breaking chance [DracoRPG] + int breakrate_[2] = {0,0}; //enemy breaking chance [celest] + int breaktime = 5000; + + breakrate_[0] += sd->break_weapon_rate; + breakrate_[1] += sd->break_armor_rate; + + if (sd->sc_count) { + if (sd->sc_data[SC_MELTDOWN].timer!=-1) { + breakrate_[0] += 100*sd->sc_data[SC_MELTDOWN].val1; + breakrate_[1] = 70*sd->sc_data[SC_MELTDOWN].val1; + breaktime = skill_get_time2(WS_MELTDOWN,1); } if(sd->sc_data[SC_OVERTHRUST].timer!=-1) - breakrate += 10; //+ 0.1% whatever skill level you use [DracoRPG] + breakrate += 10; + } - //if(wd.type==0x0a) //removed! because CRITS don't affect on breaking chance [Lupus] - // breakrate*=2; - if(rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) { - if(pc_breakweapon(sd)==1) + if(sd->status.weapon && sd->status.weapon != 11) { + if(rand() % 10000 < breakrate * battle_config.equipment_break_rate / 100 || breakrate >= 10000) + if (pc_breakweapon(sd) == 1) wd = battle_calc_pc_weapon_attack(src,target,skill_num,skill_lv,wflag); - } + } + if(rand() % 10000 < breakrate_[0] * battle_config.equipment_break_rate / 100 || breakrate_[0] >= 10000) { + if (target->type == BL_PC) { + struct map_session_data *tsd = (struct map_session_data *)target; + if(tsd->status.weapon != 11) + pc_breakweapon(tsd); + } else + status_change_start(target,SC_STRIPWEAPON,1,75,0,0,breaktime,0); + } + if(rand() % 10000 < breakrate_[1] * battle_config.equipment_break_rate/100 || breakrate_[1] >= 10000) { + if (target->type == BL_PC) { + struct map_session_data *tsd = (struct map_session_data *)target; + if(tsd->status.weapon != 11) + pc_breakarmor(tsd); + } else + status_change_start(target,SC_STRIPSHIELD,1,75,0,0,breaktime,0); } } @@ -3084,6 +3103,8 @@ struct Damage battle_calc_magic_attack( } } damage=damage*cardfix/100; + if (skill_num > 0 && sd->skillatk[0] == skill_num) + damage += damage*sd->skillatk[1]/100; } if( tsd ){ @@ -3283,6 +3304,9 @@ struct Damage battle_calc_misc_attack( cardfix=cardfix*(100-tsd->misc_def_rate)/100; damage=damage*cardfix/100; } + if (sd && skill_num > 0 && sd->skillatk[0] == skill_num) + damage += damage*sd->skillatk[1]/100; + if(damage < 0) damage = 0; damage=battle_attr_fix(damage, ele, status_get_element(target) ); // 属性修正 } @@ -3517,7 +3541,7 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target, } } if(sd) { - if(sd->autospell_id > 0 && sd->autospell_lv > 0 && rand()%100 < sd->autospell_rate) { + if(sd->autospell_id > 0 && rand()%100 < sd->autospell_rate) { int skilllv=sd->autospell_lv,i,f=0,sp; i = rand()%100; if(i >= 50) skilllv -= 2; @@ -3564,6 +3588,36 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target, if (hp || sp) pc_heal(sd, hp, sp); } } + if (target->type == BL_PC) { + struct map_session_data *tsd = (struct map_session_data *)target; + if(tsd->autospell2_id > 0 && rand()%100 < tsd->autospell2_rate) { + int skilllv = tsd->autospell_lv,i,f=0,sp; + i = rand()%100; + if(i >= 50) skilllv -= 2; + else if(i >= 15) skilllv--; + if(skilllv < 1) skilllv = 1; + sp = skill_get_sp(tsd->autospell2_id,skilllv)*2/3; + if(tsd->status.sp >= sp) { + if((i=skill_get_inf(tsd->autospell2_id) == 2) || i == 32) + f = skill_castend_pos2(target,src->x,src->y,tsd->autospell2_id,skilllv,tick,flag); + else { + switch( skill_get_nk(tsd->autospell2_id) ) { + case 0: case 2: + f = skill_castend_damage_id(target,src,tsd->autospell2_id,skilllv,tick,flag); + break; + case 1:/* 支援系 */ + if((tsd->autospell2_id==AL_HEAL || (tsd->autospell2_id==ALL_RESURRECTION && src->type != BL_PC)) && + battle_check_undead(status_get_race(src),status_get_elem_type(src))) + f = skill_castend_damage_id(target,src,tsd->autospell2_id,skilllv,tick,flag); + else + f = skill_castend_nodamage_id(target,src,tsd->autospell2_id,skilllv,tick,flag); + break; + } + } + if(!f) pc_heal(tsd,0,-sp); + } + } + } if(rdamage > 0) battle_damage(target,src,rdamage,0); diff --git a/src/map/map.c b/src/map/map.c index f47d705c1..ee597789c 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1426,9 +1426,10 @@ int map_quit(struct map_session_data *sd) { if (sd->state.event_disconnect) { struct npc_data *npc; - if ((npc = npc_name2id("PCLogoutEvent"))) { + if ((npc = npc_name2id(script_config.logout_event_name))) { run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLogoutNPC - ShowStatus("Event '"CL_WHITE"PCLogoutEvent"CL_RESET"' executed.\n"); + sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.logout_event_name); + ShowStatus(tmp_output); } } diff --git a/src/map/map.h b/src/map/map.h index ef104680b..4c5dbb15e 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -275,15 +275,17 @@ struct map_session_data { int weapon_coma_ele[10],weapon_coma_race[12]; int break_weapon_rate,break_armor_rate; short add_steal_rate; - //--- 02/15's new card effectds [celest] + //--- 02/15's new card effects [celest] int crit_atk_rate; - int critaddrace[12],critaddrace_[12],arrow_critaddrace[12]; + int critaddrace[12]; int no_regen; - int addeff3[10], arrow_addeff3[10]; + int addeff3[10]; short autospell2_id,autospell2_lv,autospell2_rate; int skillatk[2]; unsigned short unstripable_equip; - int addmob[2],submob[2],addbymob[2]; + short add_damage_classid2[10]; + int add_damage_classrate2[10]; + int add_damage_class_count2; short spiritball, spiritball_old; int spirit_timer[MAX_SKILL_LEVEL]; @@ -625,7 +627,7 @@ enum { SP_CRIT_ATK_RATE, SP_CRITICAL_ADDRACE, SP_NO_REGEN, SP_ADDEFF_WHENHIT, SP_AUTOSPELL_WHENHIT, // 2013-2017 SP_SKILL_ATK, SP_UNSTRIPABLE, // 2018-2019 - SP_ADDMOB, SP_SUBMOB, SP_ADDBYMOB // 2020-2022 + SP_ADD_DAMAGE_BY_CLASS // 2020-2022 }; enum { diff --git a/src/map/pc.c b/src/map/pc.c index 8cfebbaf2..c8ab8fae4 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -808,9 +808,16 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars sd->die_counter = pc_readglobalreg(sd,"PC_DIE_COUNTER"); // Automated script events - sd->state.event_death = pc_readglobalreg(sd,"PCDieEvent"); - sd->state.event_kill = pc_readglobalreg(sd,"PCKillEvent"); - sd->state.event_disconnect = pc_readglobalreg(sd,"PCLogoffEvent"); + if (script_config.event_requires_trigger) { + sd->state.event_death = pc_readglobalreg(sd,"PCDieEvent"); + sd->state.event_kill = pc_readglobalreg(sd,"PCKillEvent"); + sd->state.event_disconnect = pc_readglobalreg(sd,"PCLogoffEvent"); + // if script triggers are not required + } else { + sd->state.event_death = 1; + sd->state.event_kill = 1; + sd->state.event_disconnect = 1; + } if (night_flag == 1 && !map[sd->bl.m].flag.indoors) { char tmpstr[1024]; @@ -835,9 +842,10 @@ int pc_authok(int id, int login_id2, time_t connect_until_time, struct mmo_chars { struct npc_data *npc; //printf("pc: OnPCLogin event done. (%d events)\n", npc_event_doall("OnPCLogin") ); - if ((npc = npc_name2id("PCLoginEvent"))) { + if ((npc = npc_name2id(script_config.login_event_name))) { run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCLoginNPC - ShowStatus("Event '"CL_WHITE"PCLoginEvent"CL_RESET"' executed.\n"); + sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.login_event_name); + ShowStatus(tmp_output); } } // Send friends list @@ -1539,10 +1547,34 @@ int pc_bonus(struct map_session_data *sd,int type,int val) if(sd->status.weapon == 11 && sd->state.lr_flag != 2) sd->atk_rate += val; break; + case SP_BREAK_WEAPON_RATE: + if(sd->state.lr_flag != 2) + sd->break_weapon_rate+=val; + break; + case SP_BREAK_ARMOR_RATE: + if(sd->state.lr_flag != 2) + sd->break_armor_rate+=val; + break; + case SP_ADD_STEAL_RATE: + if(sd->state.lr_flag != 2) + sd->add_steal_rate+=val; + break; case SP_DELAYRATE: if(sd->state.lr_flag != 2) sd->delayrate+=val; break; + case SP_CRIT_ATK_RATE: + if(sd->state.lr_flag != 2) + sd->crit_atk_rate += val; + break; + case SP_NO_REGEN: + if(sd->state.lr_flag != 2) + sd->no_regen = val; + break; + case SP_UNSTRIPABLE: + if(sd->state.lr_flag != 2) + sd->unstripable_equip |= EQP_ARMOR; + break; default: if(battle_config.error_log) printf("pc_bonus: unknown type %d %d !\n",type,val); @@ -1758,6 +1790,39 @@ int pc_bonus2(struct map_session_data *sd,int type,int type2,int val) if(sd->state.lr_flag != 2) sd->weapon_atk_rate[type2]+=val; break; + case SP_CRITICAL_ADDRACE: + if(sd->state.lr_flag != 2) + sd->critaddrace[type2]+=val; + break; + case SP_ADDEFF_WHENHIT: + if(sd->state.lr_flag != 2) + sd->addeff3[type2]+=val; + break; + case SP_SKILL_ATK: + if(sd->state.lr_flag != 2) { + if (sd->skillatk[0] == type2) + sd->skillatk[1] += val; + else { + sd->skillatk[0] = type2; + sd->skillatk[1] = val; + } + } + break; + case SP_ADD_DAMAGE_BY_CLASS: + if(sd->state.lr_flag != 2) { + for(i=0;i<sd->add_damage_class_count2;i++) { + if(sd->add_damage_classid2[i] == type2) { + sd->add_damage_classrate2[i] += val; + break; + } + } + if(i >= sd->add_damage_class_count2 && sd->add_damage_class_count2 < 10) { + sd->add_damage_classid2[sd->add_damage_class_count2] = type2; + sd->add_damage_classrate2[sd->add_damage_class_count2] += val; + sd->add_damage_class_count2++; + } + } + break; default: if(battle_config.error_log) printf("pc_bonus2: unknown type %d %d %d!\n",type,type2,val); @@ -1795,6 +1860,13 @@ int pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) sd->autospell_rate = val; } break; + case SP_AUTOSPELL_WHENHIT: + if(sd->state.lr_flag != 2){ + sd->autospell2_id = type2; + sd->autospell2_lv = type3; + sd->autospell2_rate = val; + } + break; default: if(battle_config.error_log) printf("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val); @@ -2622,6 +2694,7 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl) if(itemid > 0 && itemdb_type(itemid) != 6) { rate = (mob_db[md->class_].dropitem[i].p / battle_config.item_rate_common * 100 * skill)/100; + rate += sd->add_steal_rate; if(rand()%10000 < rate) { @@ -4467,25 +4540,27 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) clif_updatestatus(sd,SP_HP); status_calc_pc(sd,0); - if (sd->state.event_death) { - struct npc_data *npc; - if ((npc = npc_name2id("PCDeathEvent"))) { - run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCDeathNPC - ShowStatus("Event '"CL_WHITE"PCDeathEvent"CL_RESET"' executed.\n"); - } - } - if (src && src->type == BL_PC) { + if (sd->state.event_death) + pc_setglobalreg(sd,"killerrid",((struct map_session_data *)src)->status.account_id); + if (((struct map_session_data *)src)->state.event_kill) { struct npc_data *npc; - if ((npc = npc_name2id("PCKillEvent"))) { + if ((npc = npc_name2id(script_config.kill_event_name))) { run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCKillNPC - ShowStatus("Event '"CL_WHITE"PCKillEvent"CL_RESET"' executed.\n"); + sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.kill_event_name); + ShowStatus(tmp_output); } - } + } + } - if (sd->state.event_death) - pc_setglobalreg(sd,"killerrid",((struct map_session_data *)src)->status.account_id); + if (sd->state.event_death) { + struct npc_data *npc; + if ((npc = npc_name2id(script_config.die_event_name))) { + run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCDeathNPC + sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.die_event_name); + ShowStatus(tmp_output); + } } if(battle_config.bone_drop==2 @@ -6277,6 +6352,9 @@ static int pc_natural_heal_hp(struct map_session_data *sd) if (sd->sc_count && sd->sc_data[SC_TRICKDEAD].timer != -1) // Modified by RoVeRT return 0; + if (sd->no_regen & 1) + return 0; + if(pc_checkoverhp(sd)) { sd->hp_sub = sd->inchealhptick = 0; return 0; @@ -6376,6 +6454,9 @@ static int pc_natural_heal_sp(struct map_session_data *sd) sd->sc_data[SC_BERSERK].timer != -1)) return 0; + if (sd->no_regen & 2) + return 0; + if(pc_checkoversp(sd)) { sd->sp_sub = sd->inchealsptick = 0; return 0; diff --git a/src/map/script.c b/src/map/script.c index 6daa1340a..263aba6bc 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -7222,6 +7222,14 @@ int script_config_read(char *cfgName) script_config.check_cmdcount=8192; script_config.check_gotocount=512; + script_config.die_event_name = (char *)aCallocA(24,sizeof(char)); + script_config.kill_event_name = (char *)aCallocA(24,sizeof(char)); + script_config.login_event_name = (char *)aCallocA(24,sizeof(char)); + script_config.logout_event_name = (char *)aCallocA(24,sizeof(char)); + + script_config.event_script_type = 0; + script_config.event_requires_trigger = 1; + fp=fopen(cfgName,"r"); if(fp==NULL){ printf("file not found: %s\n",cfgName); @@ -7254,6 +7262,24 @@ int script_config_read(char *cfgName) else if(strcmpi(w1,"check_gotocount")==0) { script_config.check_gotocount = battle_config_switch(w2); } + else if(strcmpi(w1,"event_script_type")==0) { + script_config.event_script_type = battle_config_switch(w2); + } + else if(strcmpi(w1,"die_event_name")==0) { + strcpy(script_config.die_event_name, w2); + } + else if(strcmpi(w1,"kill_event_name")==0) { + strcpy(script_config.kill_event_name, w2); + } + else if(strcmpi(w1,"login_event_name")==0) { + strcpy(script_config.login_event_name, w2); + } + else if(strcmpi(w1,"logout_event_name")==0) { + strcpy(script_config.logout_event_name, w2); + } + else if(strcmpi(w1,"require_set_trigger")==0) { + script_config.event_requires_trigger = battle_config_switch(w2); + } else if(strcmpi(w1,"import")==0){ script_config_read(w2); } @@ -7302,10 +7328,19 @@ int do_final_script() if(userfunc_db) strdb_final(userfunc_db,userfunc_db_final); - if (str_data) - aFree(str_data); - if (str_buf) - aFree(str_buf); + if (str_data) + aFree(str_data); + if (str_buf) + aFree(str_buf); + + if (script_config.die_event_name) + aFree(script_config.die_event_name); + if (script_config.kill_event_name) + aFree(script_config.die_event_name); + if (script_config.login_event_name) + aFree(script_config.die_event_name); + if (script_config.logout_event_name) + aFree(script_config.die_event_name); return 0; } diff --git a/src/map/script.h b/src/map/script.h index eecc45e8f..759013e95 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -9,6 +9,13 @@ extern struct Script_Config { int warn_cmd_mismatch_paramnum; int check_cmdcount; int check_gotocount; + + int event_script_type; + char* die_event_name; + char* kill_event_name; + char* login_event_name; + char* logout_event_name; + int event_requires_trigger; } script_config; struct script_data { diff --git a/src/map/skill.c b/src/map/skill.c index 78849469c..e4b171636 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1050,7 +1050,7 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s diff = mhp*10/100; if (hp - diff < mhp>>2) diff = hp - (mhp>>2); - pc_heal((struct map_session_data *)bl, -hp, 0); + pc_heal(dstsd, -hp, 0); } else if(bl->type == BL_MOB) { struct mob_data *md = (struct mob_data *)bl; hp -= mhp*15/100; @@ -1287,59 +1287,89 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s break; } - if(sd && skillid != MC_CARTREVOLUTION && attack_type&BF_WEAPON){ /* カ?ドによる追加?果 */ + if((sd||dstsd) && skillid != MC_CARTREVOLUTION && attack_type&BF_WEAPON){ /* カ?ドによる追加?果 */ int i; int sc_def_card=100; for(i=SC_STONE;i<=SC_BLIND;i++){ //?象に?態異常 - if(i==SC_STONE || i==SC_FREEZE) - sc_def_card=sc_def_mdef; - else if(i==SC_STAN || i==SC_POISON || i==SC_SILENCE) - sc_def_card=sc_def_vit; - else if(i==SC_SLEEP || i==SC_CONFUSION || i==SC_BLIND) - sc_def_card=sc_def_int; - else if(i==SC_CURSE) - sc_def_card=sc_def_luk; - - if(!sd->state.arrow_atk) { - if(rand()%10000 < (sd->addeff[i-SC_STONE])*sc_def_card/100 ){ - if(battle_config.battle_log) - printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",sd->bl.id,i,sd->addeff[i-SC_STONE]); - status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); - } + switch (i) { + case SC_STONE: + case SC_FREEZE: + sc_def_card=sc_def_mdef; + break; + case SC_STAN: + case SC_POISON: + case SC_SILENCE: + sc_def_card=sc_def_vit; + break; + case SC_SLEEP: + case SC_CONFUSION: + case SC_BLIND: + sc_def_card=sc_def_int; + break; + case SC_CURSE: + sc_def_card=sc_def_luk; } - else { - if(rand()%10000 < (sd->addeff[i-SC_STONE]+sd->arrow_addeff[i-SC_STONE])*sc_def_card/100 ){ - if(battle_config.battle_log) - printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",sd->bl.id,i,sd->addeff[i-SC_STONE]); - status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); + + if (sd) { + if(!sd->state.arrow_atk) { + if(rand()%10000 < (sd->addeff[i-SC_STONE])*sc_def_card/100 ){ + if(battle_config.battle_log) + printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",sd->bl.id,i,sd->addeff[i-SC_STONE]); + status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); + } + } + else { + if(rand()%10000 < (sd->addeff[i-SC_STONE]+sd->arrow_addeff[i-SC_STONE])*sc_def_card/100 ){ + if(battle_config.battle_log) + printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",sd->bl.id,i,sd->addeff[i-SC_STONE]); + status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); + } } } //自分に?態異常 - if(i==SC_STONE || i==SC_FREEZE) - sc_def_card=sc_def_mdef2; - else if(i==SC_STAN || i==SC_POISON || i==SC_SILENCE) - sc_def_card=sc_def_vit2; - else if(i==SC_SLEEP || i==SC_CONFUSION || i==SC_BLIND) - sc_def_card=sc_def_int2; - else if(i==SC_CURSE) - sc_def_card=sc_def_luk2; - - if(!sd->state.arrow_atk) { - if(rand()%10000 < (sd->addeff2[i-SC_STONE])*sc_def_card/100 ){ - if(battle_config.battle_log) - printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",src->id,i,sd->addeff2[i-SC_STONE]); - status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); - } + switch (i) { + case SC_STONE: + case SC_FREEZE: + sc_def_card=sc_def_mdef2; + break; + case SC_STAN: + case SC_POISON: + case SC_SILENCE: + sc_def_card=sc_def_vit2; + break; + case SC_SLEEP: + case SC_CONFUSION: + case SC_BLIND: + sc_def_card=sc_def_int2; + break; + case SC_CURSE: + sc_def_card=sc_def_luk2; } - else { - if(rand()%10000 < (sd->addeff2[i-SC_STONE]+sd->arrow_addeff2[i-SC_STONE])*sc_def_card/100 ){ - if(battle_config.battle_log) - printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",src->id,i,sd->addeff2[i-SC_STONE]); - status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); + + if (sd) { + if(!sd->state.arrow_atk) { + if(rand()%10000 < (sd->addeff2[i-SC_STONE])*sc_def_card/100 ){ + if(battle_config.battle_log) + printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",src->id,i,sd->addeff2[i-SC_STONE]); + status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); + } + } + else { + if(rand()%10000 < (sd->addeff2[i-SC_STONE]+sd->arrow_addeff2[i-SC_STONE])*sc_def_card/100 ){ + if(battle_config.battle_log) + printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",src->id,i,sd->addeff2[i-SC_STONE]); + status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); + } } } + if (dstsd && + rand()%10000 < dstsd->addeff3[i-SC_STONE]*sc_def_card/100){ + if(battle_config.battle_log) + printf("PC %d skill_addeff: cardによる異常?動 %d %d\n",src->id,i,dstsd->addeff3[i-SC_STONE]); + status_change_start(src,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); + } } } return 0; @@ -3952,6 +3982,8 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int if (tsc_data && tsc_data[scid].timer != -1) break; + if (dstsd && dstsd->unstripable_equip & equip) + break; strip_fix = status_get_dex(src) - status_get_dex(bl); if(strip_fix < 0) diff --git a/src/map/status.c b/src/map/status.c index a98fd9559..d6a8b1a22 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -252,6 +252,30 @@ int status_calc_pc(struct map_session_data* sd,int first) sd->hp_drain_value = sd->hp_drain_value_ = sd->sp_drain_value = sd->sp_drain_value_ = 0; sd->unbreakable_equip = 0; + sd->break_weapon_rate = sd->break_armor_rate = 0; + sd->add_steal_rate = 0; + sd->crit_atk_rate = 0; + sd->no_regen = 0; + sd->unstripable_equip = 0; + sd->autospell2_id = sd->autospell2_lv = sd->autospell2_rate = 0; + memset(sd->critaddrace,0,sizeof(sd->critaddrace)); + memset(sd->addeff3,0,sizeof(sd->addeff3)); + memset(sd->skillatk,0,sizeof(sd->skillatk)); + sd->add_damage_class_count = sd->add_damage_class_count_ = sd->add_magic_damage_class_count = 0; + sd->add_def_class_count = sd->add_mdef_class_count = 0; + sd->add_damage_class_count2 = 0; + memset(sd->add_damage_classid,0,sizeof(sd->add_damage_classid)); + memset(sd->add_damage_classid_,0,sizeof(sd->add_damage_classid_)); + memset(sd->add_magic_damage_classid,0,sizeof(sd->add_magic_damage_classid)); + memset(sd->add_damage_classrate,0,sizeof(sd->add_damage_classrate)); + memset(sd->add_damage_classrate_,0,sizeof(sd->add_damage_classrate_)); + memset(sd->add_magic_damage_classrate,0,sizeof(sd->add_magic_damage_classrate)); + memset(sd->add_def_classid,0,sizeof(sd->add_def_classid)); + memset(sd->add_def_classrate,0,sizeof(sd->add_def_classrate)); + memset(sd->add_mdef_classid,0,sizeof(sd->add_mdef_classid)); + memset(sd->add_mdef_classrate,0,sizeof(sd->add_mdef_classrate)); + memset(sd->add_damage_classid2,0,sizeof(sd->add_damage_classid2)); + memset(sd->add_damage_classrate2,0,sizeof(sd->add_damage_classrate2)); if(!sd->disguiseflag && sd->disguise) { sd->disguise=0; |