* Fixed a typo in quests/all_quest.txt

* Set 'killerrid' and do PCKillEvent before calling PCDieEvent
* Added some new script event related options to script config
* Added 10 of the new card effects on the 2/15's patch
* Minor rewrites on self and enemy weapon/armor breaking
* Added missing code for 'bBreakWeaponRate' and 'bBreakWeaponRate' effects
* Added missing code for 'bAddStealRate' effect
* Removed redundant 'infinite_autospell' in map_session_data

git-svn-id: https://svn.code.sf.net/p/rathena/svn/branches/stable@1116 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
celest 2005-02-16 08:25:45 +00:00
parent 03b82d9adb
commit 899b3ebeeb
14 changed files with 410 additions and 112 deletions

View File

@ -1,6 +1,25 @@
Date Added Date Added
02/16 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 Treasure Box spawn bug in all castles. [Lupus]
* Fixed wrong PresentLOG (it wasn't showing PRESENT BOX type ID) [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] * 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. On expanding MOB_DB.TXT we'll remove that plug.
We are adding new cards and some monsters We are adding new cards and some monsters
have no free slots for them. Current state is tested and works fine. have no free slots for them. Current state is tested and works fine.
02/15 02/15
* Allow Potion Pitcher to be able to cast on yourself -- i've almost forgot * 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] about this, thanks to Filougarou and Poki#3 for the fix ^^; [celest]

View File

@ -12,3 +12,26 @@ warn_cmd_mismatch_paramnum: yes
check_cmdcount: 8192 check_cmdcount: 8192
check_gotocount: 512 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

View File

@ -110,8 +110,8 @@ MaxHp 6 1
Sp 7 1 Sp 7 1
MaxSp 8 1 MaxSp 8 1
BaseJob 119 1 BaseJob 119 1
Karma 4 Karma 4 1
Manner 5 Manner 5 1
bMaxHP 6 bMaxHP 6
bMaxSP 8 bMaxSP 8
@ -241,9 +241,7 @@ bAddEffWhenHit 2016
bAutoSpellWhenHit 2017 bAutoSpellWhenHit 2017
bSkillAtk 2018 bSkillAtk 2018
bUnstripable 2019 bUnstripable 2019
bAddMob 2020 bAddDamageByClass 2020
bSubMob 2021
bAddByMob 2022
Eff_Stone 0 Eff_Stone 0

View File

@ -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. // 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. // 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

View File

@ -35,6 +35,7 @@ Other Ppl
Date Added Date Added
====== ======
02/16 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] * Fixed treasure chests spawn in the castles. (had to simplify some code and unroll some loops) [Lupus]
02/13 02/13

View File

@ -501,7 +501,7 @@ LCancel6:
Headset: Headset:
mes "[Quest Assistant]"; mes "[Quest Assistant]";
mes "These are Articles needed for my Grandfather's masterpiece."; mes "These are Articles needed for my Grandfather's masterpiece.";
mes "^3355FF100 Steel^000000"; mes "^3355FF40 Steel^000000";
mes "^3355FF1 Oridecon^000000"; mes "^3355FF1 Oridecon^000000";
mes "^3355FF1 Alchol^000000"; mes "^3355FF1 Alchol^000000";
mes "^3355FF1 Coal^000000"; mes "^3355FF1 Coal^000000";

View File

@ -1508,6 +1508,12 @@ static struct Damage battle_calc_mob_weapon_attack(
break; 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) if(flag&BF_LONG)
cardfix=cardfix*(100-tsd->long_attack_def_rate)/100; cardfix=cardfix*(100-tsd->long_attack_def_rate)/100;
if(flag&BF_SHORT) if(flag&BF_SHORT)
@ -1776,6 +1782,7 @@ static struct Damage battle_calc_pc_weapon_attack(
if(da == 0){ //ダブルアタックが発動していない if(da == 0){ //ダブルアタックが発動していない
// クリティカル計算 // クリティカル計算
cri = status_get_critical(src); cri = status_get_critical(src);
cri += sd->critaddrace[t_race];
if(sd->state.arrow_atk) if(sd->state.arrow_atk)
cri += sd->arrow_cri; cri += sd->arrow_cri;
@ -1798,7 +1805,6 @@ static struct Damage battle_calc_pc_weapon_attack(
else else
cri <<= 1; cri <<= 1;
} }
if(skill_num == SN_SHARPSHOOTING) if(skill_num == SN_SHARPSHOOTING)
cri += 200; cri += 200;
} }
@ -1819,6 +1825,9 @@ static struct Damage battle_calc_pc_weapon_attack(
} }
if(sd->state.arrow_atk) if(sd->state.arrow_atk)
damage += sd->arrow_atk; damage += sd->arrow_atk;
damage += damage * sd->crit_atk_rate / 100;
type = 0x0a; type = 0x0a;
/* if(def1 < 1000000) { /* if(def1 < 1000000) {
@ -2322,6 +2331,8 @@ static struct Damage battle_calc_pc_weapon_attack(
damage *= div_; damage *= div_;
damage2 *= div_; damage2 *= div_;
} }
if (sd && skill_num > 0 && sd->skillatk[0] == skill_num)
damage += damage*sd->skillatk[1]/100;
} }
if(da == 2) { //三段掌が発動しているか if(da == 2) { //三段掌が発動しているか
type = 0x08; type = 0x08;
@ -2816,36 +2827,44 @@ struct Damage battle_calc_weapon_attack(
if(battle_config.equipment_breaking && src->type==BL_PC && (wd.damage > 0 || wd.damage2 > 0)) { 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; struct map_session_data *sd = (struct map_session_data *)src;
int breakrate = 1; //0.01% weapon breaking chance [DracoRPG] // 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;
if(sd->status.weapon && sd->status.weapon != 11) { breakrate_[0] += sd->break_weapon_rate;
breakrate_[1] += sd->break_armor_rate;
if (sd->sc_count) {
if (sd->sc_data[SC_MELTDOWN].timer!=-1) { if (sd->sc_data[SC_MELTDOWN].timer!=-1) {
int breakrate_; // separate breaking rates for meltdown [Celest] breakrate_[0] += 100*sd->sc_data[SC_MELTDOWN].val1;
breakrate_ = 100*sd->sc_data[SC_MELTDOWN].val1; breakrate_[1] = 70*sd->sc_data[SC_MELTDOWN].val1;
if(rand()%10000 < breakrate_*battle_config.equipment_break_rate/100 || breakrate_ >= 10000) { breaktime = skill_get_time2(WS_MELTDOWN,1);
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 );
}
} }
if(sd->sc_data[SC_OVERTHRUST].timer!=-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] if(sd->status.weapon && sd->status.weapon != 11) {
// breakrate*=2; if(rand() % 10000 < breakrate * battle_config.equipment_break_rate / 100 || breakrate >= 10000)
if(rand()%10000 < breakrate*battle_config.equipment_break_rate/100 || breakrate >= 10000) {
if (pc_breakweapon(sd) == 1) if (pc_breakweapon(sd) == 1)
wd = battle_calc_pc_weapon_attack(src,target,skill_num,skill_lv,wflag); 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; damage=damage*cardfix/100;
if (skill_num > 0 && sd->skillatk[0] == skill_num)
damage += damage*sd->skillatk[1]/100;
} }
if( tsd ){ if( tsd ){
@ -3283,6 +3304,9 @@ struct Damage battle_calc_misc_attack(
cardfix=cardfix*(100-tsd->misc_def_rate)/100; cardfix=cardfix*(100-tsd->misc_def_rate)/100;
damage=damage*cardfix/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; if(damage < 0) damage = 0;
damage=battle_attr_fix(damage, ele, status_get_element(target) ); // 属性修正 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) {
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; int skilllv=sd->autospell_lv,i,f=0,sp;
i = rand()%100; i = rand()%100;
if(i >= 50) skilllv -= 2; 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 (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:/* Žx‰‡Œn */
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) if(rdamage > 0)
battle_damage(target,src,rdamage,0); battle_damage(target,src,rdamage,0);

View File

@ -1426,9 +1426,10 @@ int map_quit(struct map_session_data *sd) {
if (sd->state.event_disconnect) { if (sd->state.event_disconnect) {
struct npc_data *npc; 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 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);
} }
} }

View File

@ -275,15 +275,17 @@ struct map_session_data {
int weapon_coma_ele[10],weapon_coma_race[12]; int weapon_coma_ele[10],weapon_coma_race[12];
int break_weapon_rate,break_armor_rate; int break_weapon_rate,break_armor_rate;
short add_steal_rate; short add_steal_rate;
//--- 02/15's new card effectds [celest] //--- 02/15's new card effects [celest]
int crit_atk_rate; int crit_atk_rate;
int critaddrace[12],critaddrace_[12],arrow_critaddrace[12]; int critaddrace[12];
int no_regen; int no_regen;
int addeff3[10], arrow_addeff3[10]; int addeff3[10];
short autospell2_id,autospell2_lv,autospell2_rate; short autospell2_id,autospell2_lv,autospell2_rate;
int skillatk[2]; int skillatk[2];
unsigned short unstripable_equip; 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; short spiritball, spiritball_old;
int spirit_timer[MAX_SKILL_LEVEL]; 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_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_SKILL_ATK, SP_UNSTRIPABLE, // 2018-2019
SP_ADDMOB, SP_SUBMOB, SP_ADDBYMOB // 2020-2022 SP_ADD_DAMAGE_BY_CLASS // 2020-2022
}; };
enum { enum {

View File

@ -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"); sd->die_counter = pc_readglobalreg(sd,"PC_DIE_COUNTER");
// Automated script events // Automated script events
if (script_config.event_requires_trigger) {
sd->state.event_death = pc_readglobalreg(sd,"PCDieEvent"); sd->state.event_death = pc_readglobalreg(sd,"PCDieEvent");
sd->state.event_kill = pc_readglobalreg(sd,"PCKillEvent"); sd->state.event_kill = pc_readglobalreg(sd,"PCKillEvent");
sd->state.event_disconnect = pc_readglobalreg(sd,"PCLogoffEvent"); 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) { if (night_flag == 1 && !map[sd->bl.m].flag.indoors) {
char tmpstr[1024]; 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; struct npc_data *npc;
//printf("pc: OnPCLogin event done. (%d events)\n", npc_event_doall("OnPCLogin") ); //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 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 // 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) if(sd->status.weapon == 11 && sd->state.lr_flag != 2)
sd->atk_rate += val; sd->atk_rate += val;
break; 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: case SP_DELAYRATE:
if(sd->state.lr_flag != 2) if(sd->state.lr_flag != 2)
sd->delayrate+=val; sd->delayrate+=val;
break; 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: default:
if(battle_config.error_log) if(battle_config.error_log)
printf("pc_bonus: unknown type %d %d !\n",type,val); 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) if(sd->state.lr_flag != 2)
sd->weapon_atk_rate[type2]+=val; sd->weapon_atk_rate[type2]+=val;
break; 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: default:
if(battle_config.error_log) if(battle_config.error_log)
printf("pc_bonus2: unknown type %d %d %d!\n",type,type2,val); 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; sd->autospell_rate = val;
} }
break; 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: default:
if(battle_config.error_log) if(battle_config.error_log)
printf("pc_bonus3: unknown type %d %d %d %d!\n",type,type2,type3,val); 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) if(itemid > 0 && itemdb_type(itemid) != 6)
{ {
rate = (mob_db[md->class_].dropitem[i].p / battle_config.item_rate_common * 100 * skill)/100; 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) 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); clif_updatestatus(sd,SP_HP);
status_calc_pc(sd,0); 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 (src && src->type == BL_PC) {
if (((struct map_session_data *)src)->state.event_kill) {
struct npc_data *npc;
if ((npc = npc_name2id("PCKillEvent"))) {
run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCKillNPC
ShowStatus("Event '"CL_WHITE"PCKillEvent"CL_RESET"' executed.\n");
}
}
if (sd->state.event_death) if (sd->state.event_death)
pc_setglobalreg(sd,"killerrid",((struct map_session_data *)src)->status.account_id); 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(script_config.kill_event_name))) {
run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id); // PCKillNPC
sprintf (tmp_output, "Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.kill_event_name);
ShowStatus(tmp_output);
}
}
}
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 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 if (sd->sc_count && sd->sc_data[SC_TRICKDEAD].timer != -1) // Modified by RoVeRT
return 0; return 0;
if (sd->no_regen & 1)
return 0;
if(pc_checkoverhp(sd)) { if(pc_checkoverhp(sd)) {
sd->hp_sub = sd->inchealhptick = 0; sd->hp_sub = sd->inchealhptick = 0;
return 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)) sd->sc_data[SC_BERSERK].timer != -1))
return 0; return 0;
if (sd->no_regen & 2)
return 0;
if(pc_checkoversp(sd)) { if(pc_checkoversp(sd)) {
sd->sp_sub = sd->inchealsptick = 0; sd->sp_sub = sd->inchealsptick = 0;
return 0; return 0;

View File

@ -7222,6 +7222,14 @@ int script_config_read(char *cfgName)
script_config.check_cmdcount=8192; script_config.check_cmdcount=8192;
script_config.check_gotocount=512; 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"); fp=fopen(cfgName,"r");
if(fp==NULL){ if(fp==NULL){
printf("file not found: %s\n",cfgName); printf("file not found: %s\n",cfgName);
@ -7254,6 +7262,24 @@ int script_config_read(char *cfgName)
else if(strcmpi(w1,"check_gotocount")==0) { else if(strcmpi(w1,"check_gotocount")==0) {
script_config.check_gotocount = battle_config_switch(w2); 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){ else if(strcmpi(w1,"import")==0){
script_config_read(w2); script_config_read(w2);
} }
@ -7307,6 +7333,15 @@ int do_final_script()
if (str_buf) if (str_buf)
aFree(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; return 0;
} }
/*========================================== /*==========================================

View File

@ -9,6 +9,13 @@ extern struct Script_Config {
int warn_cmd_mismatch_paramnum; int warn_cmd_mismatch_paramnum;
int check_cmdcount; int check_cmdcount;
int check_gotocount; 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; } script_config;
struct script_data { struct script_data {

View File

@ -1050,7 +1050,7 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s
diff = mhp*10/100; diff = mhp*10/100;
if (hp - diff < mhp>>2) if (hp - diff < mhp>>2)
diff = hp - (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) { } else if(bl->type == BL_MOB) {
struct mob_data *md = (struct mob_data *)bl; struct mob_data *md = (struct mob_data *)bl;
hp -= mhp*15/100; hp -= mhp*15/100;
@ -1287,21 +1287,32 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s
break; break;
} }
if(sd && skillid != MC_CARTREVOLUTION && attack_type&BF_WEAPON){ /* カ?ドによる追加?果 */ if((sd||dstsd) && skillid != MC_CARTREVOLUTION && attack_type&BF_WEAPON){ /* カ?ドによる追加?果 */
int i; int i;
int sc_def_card=100; int sc_def_card=100;
for(i=SC_STONE;i<=SC_BLIND;i++){ for(i=SC_STONE;i<=SC_BLIND;i++){
//?象に?態異常 //?象に?態異常
if(i==SC_STONE || i==SC_FREEZE) switch (i) {
case SC_STONE:
case SC_FREEZE:
sc_def_card=sc_def_mdef; sc_def_card=sc_def_mdef;
else if(i==SC_STAN || i==SC_POISON || i==SC_SILENCE) break;
case SC_STAN:
case SC_POISON:
case SC_SILENCE:
sc_def_card=sc_def_vit; sc_def_card=sc_def_vit;
else if(i==SC_SLEEP || i==SC_CONFUSION || i==SC_BLIND) break;
case SC_SLEEP:
case SC_CONFUSION:
case SC_BLIND:
sc_def_card=sc_def_int; sc_def_card=sc_def_int;
else if(i==SC_CURSE) break;
case SC_CURSE:
sc_def_card=sc_def_luk; sc_def_card=sc_def_luk;
}
if (sd) {
if(!sd->state.arrow_atk) { if(!sd->state.arrow_atk) {
if(rand()%10000 < (sd->addeff[i-SC_STONE])*sc_def_card/100 ){ if(rand()%10000 < (sd->addeff[i-SC_STONE])*sc_def_card/100 ){
if(battle_config.battle_log) if(battle_config.battle_log)
@ -1316,16 +1327,28 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s
status_change_start(bl,i,7,0,0,0,(i==SC_CONFUSION)? 10000+7000:skill_get_time2(sc2[i-SC_STONE],7),0); 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) switch (i) {
case SC_STONE:
case SC_FREEZE:
sc_def_card=sc_def_mdef2; sc_def_card=sc_def_mdef2;
else if(i==SC_STAN || i==SC_POISON || i==SC_SILENCE) break;
case SC_STAN:
case SC_POISON:
case SC_SILENCE:
sc_def_card=sc_def_vit2; sc_def_card=sc_def_vit2;
else if(i==SC_SLEEP || i==SC_CONFUSION || i==SC_BLIND) break;
case SC_SLEEP:
case SC_CONFUSION:
case SC_BLIND:
sc_def_card=sc_def_int2; sc_def_card=sc_def_int2;
else if(i==SC_CURSE) break;
case SC_CURSE:
sc_def_card=sc_def_luk2; sc_def_card=sc_def_luk2;
}
if (sd) {
if(!sd->state.arrow_atk) { if(!sd->state.arrow_atk) {
if(rand()%10000 < (sd->addeff2[i-SC_STONE])*sc_def_card/100 ){ if(rand()%10000 < (sd->addeff2[i-SC_STONE])*sc_def_card/100 ){
if(battle_config.battle_log) if(battle_config.battle_log)
@ -1341,6 +1364,13 @@ int skill_additional_effect( struct block_list* src, struct block_list *bl,int s
} }
} }
} }
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; 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) if (tsc_data && tsc_data[scid].timer != -1)
break; break;
if (dstsd && dstsd->unstripable_equip & equip)
break;
strip_fix = status_get_dex(src) - status_get_dex(bl); strip_fix = status_get_dex(src) - status_get_dex(bl);
if(strip_fix < 0) if(strip_fix < 0)

View File

@ -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->hp_drain_value = sd->hp_drain_value_ = sd->sp_drain_value = sd->sp_drain_value_ = 0;
sd->unbreakable_equip = 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) { if(!sd->disguiseflag && sd->disguise) {
sd->disguise=0; sd->disguise=0;