Merge pull request #191 from rathena/cleanup/petdb

* Separated pet_db for Renewal & Pre-Renewal to avoid non-existant monster in different mode.
* Cleaned script command in pet_db.txt file, just point it to doc/script_commands.txt. Read them there!
* Separated damage value for petskillattack2 to its own var 'damage', that previously use 'lv' var to store the value.
* Added config 'pet_ignore_infinite_def' in conf/battle/pet.conf,
- If disabled (val:"no"), fixed damage from pet script 'petskillattack2' will be adjusted to 1. Example, just like player attacks Shining Plant.
- Enabled by default. Previously, fixed damage ignore the infinite defense, that's why it's enabled by default.
- TODO: Correcting the logic and maybe also confirm the correct behavior!
* Added validation for pet script commands,
- Skill for petskillattack, petskillattack2, & petskillsupport
- SC range for petrecovery.
* Cleaned up some source documentation.
This commit is contained in:
aleos89 2015-01-13 12:43:07 -05:00
commit 4860a7c7c4
12 changed files with 270 additions and 150 deletions

View File

@ -75,3 +75,6 @@ pet_max_atk2: 1000
// If set to yes, pets are automatically returned to egg when entering castles during WoE times // If set to yes, pets are automatically returned to egg when entering castles during WoE times
// and hatching is forbidden within as well. // and hatching is forbidden within as well.
pet_disable_in_gvg: no pet_disable_in_gvg: no
// Will does petskillattack2 fixed damage ignore plant infnite defense? (Note 1)
pet_ignore_infinite_def: yes

104
db/pre-re/pet_db.txt Normal file
View File

@ -0,0 +1,104 @@
// Pet Database
//
// Structure of Database:
// MobID,Name,JName,LureID,EggID,EquipID,FoodID,Fullness,HungryDelay,R_Hungry,R_Full,Intimate,Die,Capture,Speed,S_Performance,talk_convert_class,attack_rate,defence_attack_rate,change_target_rate,pet_script,loyal_script
//
// 01. MobID Monster ID of the pet.
// 02. Name Name of the monster as defined in the database.
// 03. JName The display name of the monster when hatched.
// 04. LureID Pet Tame Item ID.
// 05. EggID Pet Egg ID.
// 06. EquipID Pet Accessory ID.
// 07. FoodID Pet Food ID.
// 08. Fullness The amount Hunger is decreased every [HungryDelay] seconds.
// 09. HungryDelay The amount of time it takes for hunger to decrease after feeding. (Default: 60 seconds)
// 10. R_Hungry Amount of Intimacy that is increased when fed.
// 11. R_Full Amount of Intimacy that is decreased when over-fed.
// 12. Intimate Amount of Intimacy the pet starts with.
// 13. Die Amount of Intimacy that is decreased when the pet owner dies.
// 14. Capture Capture succes rate (10000 = 100%)
// 15. Speed Pet's walk speed. (Defaul: 150)
// 16. S_Performance Special Performance. (Yes = 1, No = 0)
// 17. talk_convert_class Disables pet talk (instead of talking they emote with /!.)
// 18. attack_rate Rate of which the pet will attack (requires at least pet_support_min_friendly intimacy).
// 19. defence_attack_rate Rate of which the pet will retaliate when master is being attacked (requires at least pet_support_min_friendly intimacy).
// 20. change_target_rate Rate of which the pet will change its attack target.
// 21. pet_script Script to execute when the pet is hatched.
// 22. loyal_script Script to execute when the pet is hatched (requires at least pet_equip_min_friendly intimacy, independent of pet_script).
//NOTE: The max value (100%) of attack_rate, defense_rate & change_target_rate is 10000.
//In theory you can use any valid script, but it is run only once upon pet
//loading, so it is recommended you use the specific pet scripts.
//Please see "The Pet AI commands" in 'doc/script_commands.txt'.
1002,PORING,Poring,619,9001,10013,531,80,60,50,100,250,20,2000,150,1,0,350,400,800,{ petloot 10; },{ bonus bLuk,2; bonus bCritical,1; }
1113,DROPS,Drops,620,9002,10013,508,80,60,40,100,250,20,1500,150,1,0,300,400,500,{ petloot 10; },{ bonus bHit,3; bonus bAtk,3; }
1031,POPORING,Poporing,621,9003,10013,511,80,60,30,100,250,20,1000,150,1,0,300,500,400,{ petloot 15; },{ bonus bLuk,2; bonus2 bSubEle,Ele_Poison,10; }
1063,LUNATIC,Lunatic,622,9004,10007,534,80,60,40,100,250,20,1500,150,0,0,300,300,1000,{ petskillbonus bLuk,3,10,50; },{ bonus bCritical,2; bonus bAtk,2; }
1049,PICKY,Picky,623,9005,10012,507,80,60,40,100,250,20,2000,150,1,0,500,600,50,{ petskillbonus bStr,3,10,50;},{ bonus bStr,1; bonus bAtk,5; }
1011,CHONCHON,ChonChon,624,9006,10002,537,80,60,30,100,250,20,1500,150,1,0,500,500,250,{ petskillbonus bAgi,4,10,50; },{ bonus bAgi,1; bonus bFlee,2; }
1042,STEEL_CHONCHON,Steel ChonChon,625,9007,10002,1002,80,60,20,100,250,20,1000,150,1,0,500,500,200,{ petskillbonus bAgiVit,4,20,40; },{ bonus bFlee,6; bonus bAgi,-1; }
1035,HUNTER_FLY,Hunter Fly,626,9008,10002,716,80,60,10,100,250,20,500,150,1,0,500,500,200,{ petskillattack2 "NPC_WINDATTACK",888,2,0,10; },{ bonus bFlee,-5; bonus bFlee2,2; }
1167,SAVAGE_BABE,Savage Babe,627,9009,10015,537,80,60,40,100,250,20,1500,150,0,0,500,500,200,{ petskillbonus bVit,4,10,50; },{ bonus bVit,1; bonus bMaxHP,50; }
1107,DESERT_WOLF_B,Baby Desert Wolf,628,9010,10003,537,80,60,40,100,250,20,1000,150,0,0,400,400,400,{ petskillattack "SM_PROVOKE",1,0,5;},{ bonus bInt,1; bonus bMaxSP,50; }
1052,ROCKER,Rocker,629,9011,10014,537,80,60,30,100,250,20,1500,150,0,0,350,350,600,{ petskillbonus bAllStats,1,10,50; },{ bonus bHPrecovRate,5; bonus bMaxHP,25; }
1014,SPORE,Spore,630,9012,10017,537,80,60,30,100,250,20,1500,150,0,0,350,500,500,{ petrecovery SC_POISON,60; },{ bonus bHit,5; bonus bAtk,-2; }
1077,POISON_SPORE,Poison Spore,631,9013,10017,537,80,60,20,100,250,20,1000,150,0,0,600,200,400,{ petskillattack "NPC_POISON",20,0,10; },{ bonus bStr,1; bonus bInt,1; }
1019,PECOPECO,PecoPeco,632,9014,10010,537,80,60,30,100,250,20,1000,150,1,0,400,500,800,{ petskillbonus bSpeedRate,25,20,20; },{ bonus bMaxHP,150; bonus bMaxSP,-10; }
1056,SMOKIE,Smokie,633,9015,10019,537,80,60,30,100,250,20,1000,150,1,0,600,600,100,{ petskillbonus bPerfectHide,1,3600,0; },{ bonus bAgi,1; bonus bFlee2,1; }
1057,YOYO,Yoyo,634,9016,10018,532,80,60,20,100,250,20,1000,150,1,0,300,800,400,{ petloot 20; },{ bonus bCritical,3; bonus bLuk,-1; }
1023,ORK_WARRIOR,Orc Warrior,635,9017,10009,537,80,60,20,100,250,20,500,150,1,0,600,200,300,{ petskillattack2 "NPC_PIERCINGATT",100,1,0,10; },{ bonus bAtk,10; bonus bDef,-3; }
1026,MUNAK,Munak,636,9018,10008,537,80,60,20,100,250,20,500,150,0,0,300,750,300,{ petskillattack2 "NPC_DARKNESSATTACK",444,1,0,10; },{ bonus bInt,1; bonus bDef,1; }
1110,DOKEBI,Dokebi,637,9019,10005,537,80,60,20,100,250,20,500,150,0,0,300,300,800,{ petskillattack "BS_HAMMERFALL",1,0,10; },{ bonus bMatkRate,1; bonus bAtkRate,-1; }
1170,SOHEE,Sohee,638,9020,10016,537,80,60,10,100,250,20,500,150,0,0,100,1000,200,{ petheal 400,60,33,100; },{ bonus bStr,1; bonus bDex,1; }
1029,ISIS,Isis,639,9021,10006,537,80,60,10,100,250,20,500,150,0,0,650,450,150,{ petskillsupport "PR_MAGNIFICAT",2,60,50,50; },{ bonus bMatkRate,-1; bonus bAtkRate,1; }
1155,PETIT,Petite,640,9022,10011,537,80,60,20,100,250,20,500,150,0,0,800,400,100,{ petskillattack2 "WZ_HEAVENDRIVE",500,1,0,10; },{ bonus bDef,-2; bonus bMdef,-2; bonus bAspdRate,1; }
1109,DEVIRUCHI,Deviruchi,641,9023,10004,711,80,60,10,100,250,20,500,150,0,0,800,200,100,{ petskillbonus bAgiDexStr,6,20,40; },{ bonus bMatkRate,1; bonus bAtkRate,1; bonus bMaxHPrate,-3; bonus bMaxSPrate,-3; }
1101,BAPHOMET_,Baphomet Jr.,642,9024,10001,518,80,60,10,100,250,20,200,150,0,0,1000,100,200,{ petskillattack2 "NPC_DARKNESSATTACK",1776,4,0,5; },{ bonus bDef,1; bonus bMdef,1; bonus2 bResEff,Eff_Stun,-100; }
1188,BON_GUN,Bon Gun,659,9025,10020,537,80,60,30,100,250,20,500,150,1,0,600,200,400,{ petskillattack2 "NPC_DARKNESSATTACK",555,1,1,1; },{ bonus bVit,1; bonus2 bResEff,Eff_Stun,100; }
1200,ZHERLTHSH,Zealotus,660,9026,0,929,80,60,10,100,250,20,300,150,0,0,1000,100,500,{ petskillattack "AS_SONICBLOW",1,0,3; },{ bonus2 bAddRace,RC_Demihuman,2; bonus2 bMagicAddRace,RC_DemiHuman,2; }
1275,ALICE,Alice,661,9027,0,504,80,60,20,100,250,20,800,150,0,0,100,1000,200,{ petskillsupport "AL_HEAL",5,60,25,100; },{ bonus bMdef,1; bonus2 bSubRace,RC_DemiHuman,1; }
1815,EVENT_RICECAKE,Rice Cake,0,9028,0,511,80,60,50,100,250,20,2000,150,1,0,500,500,200,{ petskillsupport "CR_DEFENDER",3,240,50,100; },{ bonus2 bSubEle,Ele_Neutral,1; bonus bMaxHPrate,-1; }
1245,GOBLINE_XMAS,Christmas Goblin,12225,9029,0,911,80,60,50,100,250,20,2000,150,0,0,300,300,800,{ petskillattack "MG_SIGHT",5,5,5; },{ bonus bMaxHP,30; bonus2 bSubEle,Ele_Water,1; }
1519,CHUNG_E,Green Maiden,12395,9030,0,6115,80,60,50,100,250,20,2000,150,0,0,300,300,800,{ petskillattack "CR_SHIELDCHARGE",5,5,5; },{ bonus bDef,1; bonus2 bSubRace,RC_DemiHuman,1; }
1879,ECLIPSE_P,Spring Rabbit,0,9031,0,7766,80,60,50,100,250,20,2000,150,0,0,300,300,800,{ petskillattack "TF_THROWSTONE",1,5,5; },{}
1122,GOBLIN_1,Goblin,14569,9032,0,7821,80,60,50,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_WINDATTACK",5,5,5; },{}
1123,GOBLIN_2,Goblin,14570,9033,0,7821,80,60,50,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_FIREATTACK",5,5,5; },{}
1125,GOBLIN_4,Goblin,14571,9034,0,7821,80,60,50,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_GROUNDATTACK",5,5,5; },{}
1385,DELETER_,Deleter,14572,9035,0,7822,80,60,20,100,250,20,800,150,0,0,300,300,800,{ petskillattack "SM_MAGNUM",5,5,5; },{}
1382,DIABOLIC,Diabolic,14573,9036,0,7823,80,60,10,100,250,20,800,150,0,0,300,300,800,{ petskillattack "WZ_METEOR",2,5,5; },{}
1208,WANDER_MAN,Wanderer,14574,9037,0,7824,80,60,20,100,250,20,800,150,0,0,300,300,800,{ petskillattack "NPC_UNDEADATTACK",5,5,5; },{ bonus bAgi,3; bonus bDex,1; }
1963,P_CHUNG_E,New Year Doll,0,9038,0,554,80,60,30,100,250,20,800,150,0,0,300,300,800,{ petskillattack "CR_SHIELDCHARGE",5,5,5; },{}
// New pets JapanRO Mobile
1040,GOLEM,Golem,12371,9053,10035,6111,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus bMaxHP,100; bonus bFlee,-5; }
1143,MARIONETTE,Marionette,12361,9043,10025,6098,80,60,10,100,250,20,500,150,0,0,300,300,800,{},{ bonus bSPrecovRate,3; }
1148,MEDUSA,Medusa,12368,9050,10032,6108,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus bVit,1; bonus2 bResEff,Eff_Stone,500; }
1179,WHISPER,Whisper,12363,9045,10027,6100,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus bFlee,7; bonus bDef,-3; }
1299,GOBLIN_LEADER,Goblin Leader,12364,9046,10028,6104,80,60,10,100,250,20,50,150,0,0,300,300,800,{},{ bonus2 bAddRace,RC_DemiHuman,3; }
1370,SUCCUBUS,Succubus,12373,9055,10037,6113,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bHpDrainRate,50,5; }
1374,INCUBUS,Incubus,12370,9052,10034,6110,80,60,10,100,250,20,50,150,0,0,300,300,800,{},{ bonus bMaxSPRate,3; }
1379,NIGHTMARE_TERROR,Nightmare Terror,12372,9054,10036,6112,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bResEff,Eff_Sleep,10000; }
1401,SHINOBI,Shinobi,12362,9044,10026,6099,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus bAgi,2; }
1404,MIYABI_NINGYO,Miyabi Doll,12366,9048,10030,6106,80,60,15,100,250,20,200,150,0,0,300,300,800,{},{ bonus bInt,1; bonus bCastrate,-3; }
1416,WICKED_NYMPH,Evil Nymph,12365,9047,10029,6105,80,60,15,100,250,20,500,150,0,0,300,300,800,{},{ bonus bMaxSP,30; bonus bSPrecovRate,5; }
1495,STONE_SHOOTER,Stone Shooter,12369,9051,10033,6109,80,60,20,100,250,20,500,150,0,0,300,300,800,{},{ bonus2 bSubEle,Ele_Fire,3; }
1504,DULLAHAN,Dullahan,12367,9049,10031,6107,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus bCritAtkRate,5; }
1505,LOLI_RURI,Loli Ruri,12360,9042,10024,6097,80,60,15,100,250,20,200,150,0,0,300,300,800,{},{ bonus bMaxHPRate,3; bonus3 bAutoSpellWhenHit,"AL_HEAL",1,10; }
1513,CIVIL_SERVANT,Mao Guai,12358,9040,10022,6095,80,60,10,100,250,20,500,150,0,0,300,300,800,{},{ bonus bMaxSP,10; }
1586,LEAF_CAT,Leaf Cat,12359,9041,10023,6096,80,60,20,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bSubRace,RC_Brute,3; }
1630,BACSOJIN_,White Lady,12357,9039,10021,6094,80,60,10,100,250,20,2000,150,0,0,300,300,800,{},{}
1837,IMP,Fire Imp,12374,9056,10038,6114,80,60,10,100,250,20,200,150,0,0,300,300,800,{},{ bonus2 bSubEle,Ele_Fire,2; bonus2 bAddEle,Ele_Fire,2; }
// Brasilis Quest - Suspicious Beach [UNHATCHABLE]
2057,E_CRAMP,Strange Cramp,12408,6221,0,0,0,0,0,0,0,0,50,0,0,0,350,400,800,{},{} // kRO version
2081,E_HYDRA,Strange Hydra,12408,6221,0,0,0,0,0,0,0,0,50,0,0,0,350,400,800,{},{} // iRO/cRO version
// New pets (FIX ME: pet bonuses for 2210 and 2313 do not require loyalty)
//2200,J_TAINI,Tiny,0,9057,0,512,80,60,10,100,250,20,0,150,1,0,300,300,800,{},{}
//2210,XMAS_LUNATIC,Christmas Snow Rabbit,0,9058,0,529,80,60,10,100,250,20,0,150,1,0,300,300,800,{},{ bonus2 bExpAddRace,RC_All,5; }
//2313,TIKBALANG,Tikbalang,12699,9059,0,528,80,60,10,100,250,20,1000,150,1,0,300,300,800,{},{ bonus2 bAddDamageClass,2320,10; bonus2 bAddDamageClass,2321,10; bonus2 bAddDamageClass,2322,10; bonus2 bAddDamageClass,2317,10; bonus2 bAddDamageClass,2318,10; bonus2 bAddDamageClass,2327,10; bonus2 bAddDamageClass,2319,10; bonus2 bAddDamageClass,2333,10; bonus2 bAddDamageClass,2332,10; }
1242,MARIN,Marin,12789,9061,10039,6534,80,60,50,100,250,20,2000,150,1,0,300,300,800,{},{}
//2398,LITTLE_PORING,Novice Poring,12846,9062,0,531,80,60,1000,0,250,0,5000,150,0,0,300,300,800,{},{ bonus bHPrecovRate,50; }

View File

@ -28,35 +28,8 @@
//NOTE: The max value (100%) of attack_rate, defense_rate & change_target_rate is 10000. //NOTE: The max value (100%) of attack_rate, defense_rate & change_target_rate is 10000.
//In theory you can use any valid script, but it is run only once upon pet //In theory you can use any valid script, but it is run only once upon pet
//loading, so it is recommended you use the specific pet scripts: //loading, so it is recommended you use the specific pet scripts.
//Please see "The Pet AI commands" in 'doc/script_commands.txt'.
//petskillattack skillid, skilllv, rate, bonusrate
//Skill attack that triggers while the pet is attacking. Rate is the base
//chance of execution per attack. Bonusrate is an additional success rate when
//intimacy reaches max.
//petskillattack2 skillid, damage, hits, rate, bonusrate
//Same as petskillattack, but the damage and number of hits is fixed
//the damage specified is total, not per hit.
//petskillsupport skillid, skilllv, delay, hp%, sp%
//Casts a support skill when the health levels are below the specified hp% and
//sp%. Delay is the minimum time in seconds before the skill can be cast again
//petheal amount, delay, hp%, sp%
//Similar to petskillsupport, but the skill is fixed to heal (28) and the
//heal-amount is fixed to the value given.
//petrecovery type, delay: Cures the "type" status effect after "delay" seconds
//petskillbonus type, value, duration, delay
//Gives bonus stats. Type is the stat to increase (bStr, bLuk), value is the
//amount by which it is increased, duration signals how long the bonus lasts
//delay is the time elapsed after the bonus ends and before it starts again.
//A single pet can have petloot, petskillbonus, petskillattack (or
//petskillattack2) and petskillsupport (or petheal) at the same time,
//but only one of each.
1002,PORING,Poring,619,9001,10013,531,80,60,50,100,250,20,2000,150,1,0,350,400,800,{ petloot 10; },{ bonus bLuk,2; bonus bCritical,1; } 1002,PORING,Poring,619,9001,10013,531,80,60,50,100,250,20,2000,150,1,0,350,400,800,{ petloot 10; },{ bonus bLuk,2; bonus bCritical,1; }
1113,DROPS,Drops,620,9002,10013,508,80,60,40,100,250,20,1500,150,1,0,300,400,500,{ petloot 10; },{ bonus bHit,3; bonus bAtk,3; } 1113,DROPS,Drops,620,9002,10013,508,80,60,40,100,250,20,1500,150,1,0,300,400,500,{ petloot 10; },{ bonus bHit,3; bonus bAtk,3; }
@ -69,7 +42,7 @@
1167,SAVAGE_BABE,Savage Babe,627,9009,10015,537,80,60,40,100,250,20,1500,150,0,0,500,500,200,{ petskillbonus bVit,4,10,50; },{ bonus bVit,1; bonus bMaxHP,50; } 1167,SAVAGE_BABE,Savage Babe,627,9009,10015,537,80,60,40,100,250,20,1500,150,0,0,500,500,200,{ petskillbonus bVit,4,10,50; },{ bonus bVit,1; bonus bMaxHP,50; }
1107,DESERT_WOLF_B,Baby Desert Wolf,628,9010,10003,537,80,60,40,100,250,20,1000,150,0,0,400,400,400,{ petskillattack "SM_PROVOKE",1,0,5;},{ bonus bInt,1; bonus bMaxSP,50; } 1107,DESERT_WOLF_B,Baby Desert Wolf,628,9010,10003,537,80,60,40,100,250,20,1000,150,0,0,400,400,400,{ petskillattack "SM_PROVOKE",1,0,5;},{ bonus bInt,1; bonus bMaxSP,50; }
1052,ROCKER,Rocker,629,9011,10014,537,80,60,30,100,250,20,1500,150,0,0,350,350,600,{ petskillbonus bAllStats,1,10,50; },{ bonus bHPrecovRate,5; bonus bMaxHP,25; } 1052,ROCKER,Rocker,629,9011,10014,537,80,60,30,100,250,20,1500,150,0,0,350,350,600,{ petskillbonus bAllStats,1,10,50; },{ bonus bHPrecovRate,5; bonus bMaxHP,25; }
1014,SPORE,Spore,630,9012,10017,537,80,60,30,100,250,20,1500,150,0,0,350,500,500,{ petrecovery SC_Poison,60; },{ bonus bHit,5; bonus bAtk,-2; } 1014,SPORE,Spore,630,9012,10017,537,80,60,30,100,250,20,1500,150,0,0,350,500,500,{ petrecovery SC_POISON,60; },{ bonus bHit,5; bonus bAtk,-2; }
1077,POISON_SPORE,Poison Spore,631,9013,10017,537,80,60,20,100,250,20,1000,150,0,0,600,200,400,{ petskillattack "NPC_POISON",20,0,10; },{ bonus bStr,1; bonus bInt,1; } 1077,POISON_SPORE,Poison Spore,631,9013,10017,537,80,60,20,100,250,20,1000,150,0,0,600,200,400,{ petskillattack "NPC_POISON",20,0,10; },{ bonus bStr,1; bonus bInt,1; }
1019,PECOPECO,PecoPeco,632,9014,10010,537,80,60,30,100,250,20,1000,150,1,0,400,500,800,{ petskillbonus bSpeedRate,25,20,20; },{ bonus bMaxHP,150; bonus bMaxSP,-10; } 1019,PECOPECO,PecoPeco,632,9014,10010,537,80,60,30,100,250,20,1000,150,1,0,400,500,800,{ petskillbonus bSpeedRate,25,20,20; },{ bonus bMaxHP,150; bonus bMaxSP,-10; }
1056,SMOKIE,Smokie,633,9015,10019,537,80,60,30,100,250,20,1000,150,1,0,600,600,100,{ petskillbonus bPerfectHide,1,3600,0; },{ bonus bAgi,1; bonus bFlee2,1; } 1056,SMOKIE,Smokie,633,9015,10019,537,80,60,30,100,250,20,1000,150,1,0,600,600,100,{ petskillbonus bPerfectHide,1,3600,0; },{ bonus bAgi,1; bonus bFlee2,1; }

View File

@ -1044,6 +1044,7 @@ From here on, we will have the commands sorted as follow:
8.- Quest Log commands. 8.- Quest Log commands.
9.- Battleground commands. 9.- Battleground commands.
10.- Pet commands. 10.- Pet commands.
10.1.- The Pet AI commands.
11.- Homunculus commands. 11.- Homunculus commands.
12.- Mercenary commands. 12.- Mercenary commands.
13.- Party commands. 13.- Party commands.
@ -8048,8 +8049,10 @@ currently has active. Valid types are:
--------------------------------------- ---------------------------------------
* The Pet AI commands =============================
------------------- |10.1.- The Pet AI commands.|
=============================
---------------------------------------
These commands will only work if the invoking character has a pet, and are meant These commands will only work if the invoking character has a pet, and are meant
to be executed from pet scripts. They will modify the pet AI decision-making for to be executed from pet scripts. They will modify the pet AI decision-making for
@ -8086,9 +8089,11 @@ Nobody tried this before, so you're essentially on your own here.
*petskillbonus <bonus type>,<value>,<duration>,<delay>; *petskillbonus <bonus type>,<value>,<duration>,<delay>;
This command will make the pet give a bonus to the owner's stat (bonus type - This command will make the pet give a bonus to the owner's stat in certain
bInt,bVit,bDex,bAgi,bLuk,bStr,bSpeedRate - for a full list, see the values duration in seconds and will be repeated for certain delay in seconds.
starting with 'b' in 'db/const.txt')
For a full bonus list, see 'doc/item_bonus.txt'
NOTE: Currently ONLY supported for bonuses that used by 'bonus' script.
--------------------------------------- ---------------------------------------
@ -8117,7 +8122,7 @@ This will make the pet use a specified support skill on the owner whenever the
HP and SP are below the given percent values, with a specified delay time HP and SP are below the given percent values, with a specified delay time
between activations. The skill numbers are as per 'db/(pre-)re/skill_db.txt'. between activations. The skill numbers are as per 'db/(pre-)re/skill_db.txt'.
'petheal' works the same as 'petskillsupport' but has the skill ID hard-coded to 'petheal' works the same as 'petskillsupport' but has the skill ID hard-coded to
28 (Heal). This command is deprecated. AL_HEAL (ID:28). This command is deprecated.
It's not quite certain who's stats will be used for the skills cast, the It's not quite certain who's stats will be used for the skills cast, the
character's or the pets. Probably, Skotlex can answer that question. character's or the pets. Probably, Skotlex can answer that question.
@ -8133,6 +8138,8 @@ owner is currently fighting. Skill IDs and levels are as per 'petskillsupport'.
'petskillattack2' will make the pet cast the skill with a fixed amount of damage 'petskillattack2' will make the pet cast the skill with a fixed amount of damage
inflicted and the specified number of attacks. inflicted and the specified number of attacks.
Value of 'rate' is between 1 and 100. 100 = 100%
--------------------------------------- ---------------------------------------
=========================== ===========================

View File

@ -2024,7 +2024,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
* Refined and optimized by helvetica * Refined and optimized by helvetica
* flag - see e_battle_flag * flag - see e_battle_flag
*/ */
static bool is_infinite_defense(struct block_list *target, int flag) bool is_infinite_defense(struct block_list *target, int flag)
{ {
struct status_data *tstatus = status_get_status_data(target); struct status_data *tstatus = status_get_status_data(target);
@ -7947,6 +7947,7 @@ static const struct _battle_data {
{ "stormgust_knockback", &battle_config.stormgust_knockback, 1, 0, 1, }, { "stormgust_knockback", &battle_config.stormgust_knockback, 1, 0, 1, },
{ "default_fixed_castrate", &battle_config.default_fixed_castrate, 20, 0, 100, }, { "default_fixed_castrate", &battle_config.default_fixed_castrate, 20, 0, 100, },
{ "default_bind_on_equip", &battle_config.default_bind_on_equip, BOUND_CHAR, BOUND_NONE, BOUND_MAX-1, }, { "default_bind_on_equip", &battle_config.default_bind_on_equip, BOUND_CHAR, BOUND_NONE, BOUND_MAX-1, },
{ "pet_ignore_infinite_def", &battle_config.pet_ignore_infinite_def, 0, 0, 1, },
}; };
#ifndef STATS_OPT_OUT #ifndef STATS_OPT_OUT

View File

@ -113,6 +113,9 @@ int battle_check_target(struct block_list *src, struct block_list *target,int fl
bool battle_check_range(struct block_list *src,struct block_list *bl,int range); bool battle_check_range(struct block_list *src,struct block_list *bl,int range);
void battle_consume_ammo(struct map_session_data* sd, int skill, int lv); void battle_consume_ammo(struct map_session_data* sd, int skill, int lv);
bool is_infinite_defense(struct block_list *target, int flag);
// Settings // Settings
#define MIN_HAIR_STYLE battle_config.min_hair_style #define MIN_HAIR_STYLE battle_config.min_hair_style
@ -581,6 +584,7 @@ extern struct Battle_Config
int stormgust_knockback; int stormgust_knockback;
int default_fixed_castrate; int default_fixed_castrate;
int default_bind_on_equip; int default_bind_on_equip;
int pet_ignore_infinite_def; // Makes fixed damage of petskillattack2 ignores infinite defense
} battle_config; } battle_config;
void do_init_battle(void); void do_init_battle(void);

View File

@ -463,7 +463,7 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *pet)
run_script(pet_db[i].pet_script,0,sd->bl.id,0); run_script(pet_db[i].pet_script,0,sd->bl.id,0);
if( pd->petDB ) { if( pd->petDB ) {
if( pd->petDB->equip_script ) if( pd->petDB->pet_loyal_script )
status_calc_pc(sd,SCO_NONE); status_calc_pc(sd,SCO_NONE);
if( battle_config.pet_hungry_delay_rate != 100 ) if( battle_config.pet_hungry_delay_rate != 100 )
@ -1372,7 +1372,6 @@ int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data)
if(pd->bonus->timer != tid) { if(pd->bonus->timer != tid) {
ShowError("pet_skill_bonus_timer %d != %d\n",pd->bonus->timer,tid); ShowError("pet_skill_bonus_timer %d != %d\n",pd->bonus->timer,tid);
pd->bonus->timer = INVALID_TIMER; pd->bonus->timer = INVALID_TIMER;
return 0; return 0;
} }
@ -1385,7 +1384,6 @@ int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data)
timer = pd->bonus->duration*1000; // the duration for pet bonuses to be in effect timer = pd->bonus->duration*1000; // the duration for pet bonuses to be in effect
} else { //Lost pet... } else { //Lost pet...
pd->bonus->timer = INVALID_TIMER; pd->bonus->timer = INVALID_TIMER;
return 0; return 0;
} }
@ -1396,7 +1394,6 @@ int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data)
// wait for the next timer // wait for the next timer
pd->bonus->timer=add_timer(tick+timer,pet_skill_bonus_timer,sd->bl.id,0); pd->bonus->timer=add_timer(tick+timer,pet_skill_bonus_timer,sd->bl.id,0);
return 0; return 0;
} }
@ -1421,7 +1418,6 @@ int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data)
if(pd->recovery->timer != tid) { if(pd->recovery->timer != tid) {
ShowError("pet_recovery_timer %d != %d\n",pd->recovery->timer,tid); ShowError("pet_recovery_timer %d != %d\n",pd->recovery->timer,tid);
return 0; return 0;
} }
@ -1434,7 +1430,6 @@ int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data)
} }
pd->recovery->timer = INVALID_TIMER; pd->recovery->timer = INVALID_TIMER;
return 0; return 0;
} }
@ -1458,7 +1453,6 @@ int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
if(pd->s_skill->timer != tid) { if(pd->s_skill->timer != tid) {
ShowError("pet_heal_timer %d != %d\n",pd->s_skill->timer,tid); ShowError("pet_heal_timer %d != %d\n",pd->s_skill->timer,tid);
return 0; return 0;
} }
@ -1470,7 +1464,6 @@ int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
(rate = (pd->ud.skilltimer != INVALID_TIMER)) //Another skill is in effect (rate = (pd->ud.skilltimer != INVALID_TIMER)) //Another skill is in effect
) { //Wait (how long? 1 sec for every 10% of remaining) ) { //Wait (how long? 1 sec for every 10% of remaining)
pd->s_skill->timer=add_timer(gettick()+(rate>10?rate:10)*100,pet_heal_timer,sd->bl.id,0); pd->s_skill->timer=add_timer(gettick()+(rate>10?rate:10)*100,pet_heal_timer,sd->bl.id,0);
return 0; return 0;
} }
@ -1479,7 +1472,6 @@ int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
clif_skill_nodamage(&pd->bl,&sd->bl,AL_HEAL,pd->s_skill->lv,1); clif_skill_nodamage(&pd->bl,&sd->bl,AL_HEAL,pd->s_skill->lv,1);
status_heal(&sd->bl, pd->s_skill->lv,0, 0); status_heal(&sd->bl, pd->s_skill->lv,0, 0);
pd->s_skill->timer = add_timer(tick+pd->s_skill->delay*1000,pet_heal_timer,sd->bl.id,0); pd->s_skill->timer = add_timer(tick+pd->s_skill->delay*1000,pet_heal_timer,sd->bl.id,0);
return 0; return 0;
} }
@ -1505,7 +1497,6 @@ int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data)
if(pd->s_skill->timer != tid) { if(pd->s_skill->timer != tid) {
ShowError("pet_skill_support_timer %d != %d\n",pd->s_skill->timer,tid); ShowError("pet_skill_support_timer %d != %d\n",pd->s_skill->timer,tid);
return 0; return 0;
} }
@ -1514,7 +1505,6 @@ int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data)
if (DIFF_TICK(pd->ud.canact_tick, tick) > 0) { if (DIFF_TICK(pd->ud.canact_tick, tick) > 0) {
//Wait until the pet can act again. //Wait until the pet can act again.
pd->s_skill->timer=add_timer(pd->ud.canact_tick,pet_skill_support_timer,sd->bl.id,0); pd->s_skill->timer=add_timer(pd->ud.canact_tick,pet_skill_support_timer,sd->bl.id,0);
return 0; return 0;
} }
@ -1535,7 +1525,6 @@ int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data)
unit_skilluse_pos(&pd->bl, sd->bl.x, sd->bl.y, pd->s_skill->id, pd->s_skill->lv); unit_skilluse_pos(&pd->bl, sd->bl.x, sd->bl.y, pd->s_skill->id, pd->s_skill->lv);
else else
unit_skilluse_id(&pd->bl, sd->bl.id, pd->s_skill->id, pd->s_skill->lv); unit_skilluse_id(&pd->bl, sd->bl.id, pd->s_skill->id, pd->s_skill->lv);
return 0; return 0;
} }
@ -1544,7 +1533,10 @@ int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data)
*/ */
void read_petdb() void read_petdb()
{ {
char* filename[] = {"pet_db.txt",DBIMPORT"/pet_db.txt"}; char* filename[] = {
DBPATH"pet_db.txt",
DBIMPORT"/pet_db.txt"
};
unsigned short nameid; unsigned short nameid;
int i,j; int i,j;
@ -1555,9 +1547,9 @@ void read_petdb()
pet_db[j].pet_script = NULL; pet_db[j].pet_script = NULL;
} }
if( pet_db[j].equip_script ) { if( pet_db[j].pet_loyal_script ) {
script_free_code(pet_db[j].equip_script); script_free_code(pet_db[j].pet_loyal_script);
pet_db[j].pet_script = NULL; pet_db[j].pet_loyal_script = NULL;
} }
} }
@ -1670,13 +1662,13 @@ void read_petdb()
pet_db[j].defence_attack_rate=atoi(str[18]); pet_db[j].defence_attack_rate=atoi(str[18]);
pet_db[j].change_target_rate=atoi(str[19]); pet_db[j].change_target_rate=atoi(str[19]);
pet_db[j].pet_script = NULL; pet_db[j].pet_script = NULL;
pet_db[j].equip_script = NULL; pet_db[j].pet_loyal_script = NULL;
if( *str[20] ) if( *str[20] )
pet_db[j].pet_script = parse_script(str[20], filename[i], lines, 0); pet_db[j].pet_script = parse_script(str[20], filename[i], lines, 0);
if( *str[21] ) if( *str[21] )
pet_db[j].equip_script = parse_script(str[21], filename[i], lines, 0); pet_db[j].pet_loyal_script = parse_script(str[21], filename[i], lines, 0);
j++; j++;
entries++; entries++;
@ -1723,9 +1715,9 @@ void do_final_pet(void)
pet_db[i].pet_script = NULL; pet_db[i].pet_script = NULL;
} }
if( pet_db[i].equip_script ) { if( pet_db[i].pet_loyal_script ) {
script_free_code(pet_db[i].equip_script); script_free_code(pet_db[i].pet_loyal_script);
pet_db[i].equip_script = NULL; pet_db[i].pet_loyal_script = NULL;
} }
} }

View File

@ -7,28 +7,31 @@
#define MAX_PET_DB 300 #define MAX_PET_DB 300
#define MAX_PETLOOT_SIZE 30 #define MAX_PETLOOT_SIZE 30
/// Pet DB
struct s_pet_db { struct s_pet_db {
short class_; short class_; ///< Monster ID
char name[NAME_LENGTH],jname[NAME_LENGTH]; char name[NAME_LENGTH], ///< AEGIS name
short itemID; jname[NAME_LENGTH]; ///< English name
short EggID; short itemID; ///< Lure ID
short AcceID; short EggID; ///< Egg ID
short FoodID; short AcceID; ///< Accessory ID
int fullness; short FoodID; ///< Food ID
int hungry_delay; int fullness; ///< Amount of hunger decresed each hungry_delay interval
int r_hungry; int hungry_delay; ///< Hunger value decrease each x seconds
int r_full; int r_hungry; ///< Intimacy increased after feeding
int intimate; int r_full; ///< Intimacy reduced when over-fed
int die; int intimate; ///< Initial intimacy value
int capture; int die; ///< Intimacy decreased when die
int speed; int capture; ///< Capture success rate 1000 = 100%
char s_perfor; int speed; ///< Walk speed
int talk_convert_class; char s_perfor; ///< Special performance
int attack_rate; int talk_convert_class; ///< Disables pet talk (instead of talking they emote with /!.) (?)
int defence_attack_rate; int attack_rate; ///< Rate of which the pet will attack (requires at least pet_support_min_friendly intimacy).
int change_target_rate; int defence_attack_rate; ///< Rate of which the pet will retaliate when master is being attacked (requires at least pet_support_min_friendly intimacy).
struct script_code *equip_script; int change_target_rate; ///< Rate of which the pet will change its attack target.
struct script_code *pet_script; struct script_code
*pet_script, ///< Script since pet hatched
*pet_loyal_script; ///< Script when pet is loyal
}; };
extern struct s_pet_db pet_db[MAX_PET_DB]; extern struct s_pet_db pet_db[MAX_PET_DB];
@ -42,15 +45,16 @@ struct pet_recovery { //Stat recovery
struct pet_bonus { struct pet_bonus {
unsigned short type; //bStr, bVit? unsigned short type; //bStr, bVit?
unsigned short val; //Qty unsigned short val; //value
unsigned short duration; //in secs unsigned short duration; //in seconds
unsigned short delay; //Time before RENEWAL_CAST (secs) unsigned short delay; //Time before re-effect the bonus in seconds
int timer; int timer;
}; };
struct pet_skill_attack { //Attack Skill struct pet_skill_attack { //Attack Skill
unsigned short id; unsigned short id;
unsigned short lv; unsigned short lv; // Skill level
unsigned short damage; // Fixed damage value of petskillattack2
unsigned short div_; //0 = Normal skill. >0 = Fixed damage (lv), fixed div_. unsigned short div_; //0 = Normal skill. >0 = Fixed damage (lv), fixed div_.
unsigned short rate; //Base chance of skill ocurrance (10 = 10% of attacks) unsigned short rate; //Base chance of skill ocurrance (10 = 10% of attacks)
unsigned short bonusrate; //How being 100% loyal affects cast rate (10 = At 1000 intimacy->rate+10% unsigned short bonusrate; //How being 100% loyal affects cast rate (10 = At 1000 intimacy->rate+10%
@ -87,7 +91,7 @@ struct pet_data {
} state; } state;
int move_fail_count; int move_fail_count;
unsigned int next_walktime,last_thinktime; unsigned int next_walktime,last_thinktime;
short rate_fix; //Support rate as modified by intimacy (1000 = 100%) [Skotlex] unsigned short rate_fix; //Support rate as modified by intimacy (1000 = 100%) [Skotlex]
struct pet_recovery* recovery; struct pet_recovery* recovery;
struct pet_bonus* bonus; struct pet_bonus* bonus;

View File

@ -12720,13 +12720,12 @@ BUILDIN_FUNC(getequipcardid)
BUILDIN_FUNC(petskillbonus) BUILDIN_FUNC(petskillbonus)
{ {
struct pet_data *pd; struct pet_data *pd;
TBL_PC *sd = script_rid2sd(st);
TBL_PC *sd=script_rid2sd(st); if(sd == NULL || sd->pd == NULL)
return SCRIPT_CMD_FAILURE;
if(sd==NULL || sd->pd==NULL) pd = sd->pd;
return 0;
pd=sd->pd;
if (pd->bonus) if (pd->bonus)
{ //Clear previous bonus { //Clear previous bonus
if (pd->bonus->timer != INVALID_TIMER) if (pd->bonus->timer != INVALID_TIMER)
@ -12734,13 +12733,13 @@ BUILDIN_FUNC(petskillbonus)
} else //init } else //init
pd->bonus = (struct pet_bonus *) aMalloc(sizeof(struct pet_bonus)); pd->bonus = (struct pet_bonus *) aMalloc(sizeof(struct pet_bonus));
pd->bonus->type=script_getnum(st,2); pd->bonus->type = script_getnum(st,2);
pd->bonus->val=script_getnum(st,3); pd->bonus->val = script_getnum(st,3);
pd->bonus->duration=script_getnum(st,4); pd->bonus->duration = script_getnum(st,4);
pd->bonus->delay=script_getnum(st,5); pd->bonus->delay = script_getnum(st,5);
if (pd->state.skillbonus == 1) if (pd->state.skillbonus == 1)
pd->state.skillbonus=0; // waiting state pd->state.skillbonus = 0; // waiting state
// wait for timer to start // wait for timer to start
if (battle_config.pet_equip_required && pd->pet.equip == 0) if (battle_config.pet_equip_required && pd->pet.equip == 0)
@ -13055,11 +13054,18 @@ BUILDIN_FUNC(petrecovery)
{ {
struct pet_data *pd; struct pet_data *pd;
TBL_PC *sd=script_rid2sd(st); TBL_PC *sd=script_rid2sd(st);
int sc;
if(sd==NULL || sd->pd==NULL) if(sd == NULL || sd->pd == NULL)
return 0; return SCRIPT_CMD_FAILURE;
pd=sd->pd; sc = script_getnum(st,2);
if (sc <= SC_NONE || sc >= SC_MAX) {
ShowError("buildin_petrecovery: Invalid SC type: %d\n", sc);
return SCRIPT_CMD_FAILURE;
}
pd = sd->pd;
if (pd->recovery) if (pd->recovery)
{ //Halt previous bonus { //Halt previous bonus
@ -13068,7 +13074,7 @@ BUILDIN_FUNC(petrecovery)
} else //Init } else //Init
pd->recovery = (struct pet_recovery *)aMalloc(sizeof(struct pet_recovery)); pd->recovery = (struct pet_recovery *)aMalloc(sizeof(struct pet_recovery));
pd->recovery->type = (sc_type)script_getnum(st,2); pd->recovery->type = (sc_type)sc;
pd->recovery->delay = script_getnum(st,3); pd->recovery->delay = script_getnum(st,3);
pd->recovery->timer = INVALID_TIMER; pd->recovery->timer = INVALID_TIMER;
return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_SUCCESS;
@ -13122,50 +13128,66 @@ BUILDIN_FUNC(petskillattack)
{ {
struct pet_data *pd; struct pet_data *pd;
struct script_data *data; struct script_data *data;
TBL_PC *sd=script_rid2sd(st); TBL_PC *sd = script_rid2sd(st);
int id = 0;
if(sd==NULL || sd->pd==NULL) if(sd == NULL || sd->pd == NULL)
return 0; return SCRIPT_CMD_FAILURE;
pd=sd->pd; data = script_getdata(st, 2);
get_val(st, data);
id = (data_isstring(data) ? skill_name2id(script_getstr(st,2)) : skill_get_index(script_getnum(st,2)));
if (!id) {
ShowError("buildin_petskillattack: Invalid skill defined!\n");
return SCRIPT_CMD_FAILURE;
}
pd = sd->pd;
if (pd->a_skill == NULL) if (pd->a_skill == NULL)
pd->a_skill = (struct pet_skill_attack *)aMalloc(sizeof(struct pet_skill_attack)); pd->a_skill = (struct pet_skill_attack *)aMalloc(sizeof(struct pet_skill_attack));
data = script_getdata(st, 2); pd->a_skill->id = id;
get_val(st, data); // Convert into value in case of a variable pd->a_skill->damage = 0;
pd->a_skill->id=( data_isstring(data) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) ); pd->a_skill->lv = (unsigned short)min(script_getnum(st,3), skill_get_max(pd->a_skill->id));
pd->a_skill->lv=script_getnum(st,3);
pd->a_skill->div_ = 0; pd->a_skill->div_ = 0;
pd->a_skill->rate=script_getnum(st,4); pd->a_skill->rate = script_getnum(st,4);
pd->a_skill->bonusrate=script_getnum(st,5); pd->a_skill->bonusrate = script_getnum(st,5);
return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_SUCCESS;
} }
/*========================================== /*==========================================
* pet attack skills [Valaris] * pet attack skills [Valaris]
*------------------------------------------*/ *------------------------------------------*/
/// petskillattack2 <skill id>,<level>,<div>,<rate>,<bonusrate> /// petskillattack2 <skill id>,<damage>,<div>,<rate>,<bonusrate>
/// petskillattack2 "<skill name>",<level>,<div>,<rate>,<bonusrate> /// petskillattack2 "<skill name>",<damage>,<div>,<rate>,<bonusrate>
BUILDIN_FUNC(petskillattack2) BUILDIN_FUNC(petskillattack2)
{ {
struct pet_data *pd; struct pet_data *pd;
struct script_data *data; struct script_data *data;
TBL_PC *sd=script_rid2sd(st); TBL_PC *sd = script_rid2sd(st);
int id = 0;
if(sd==NULL || sd->pd==NULL) if(sd == NULL || sd->pd == NULL)
return 0; return SCRIPT_CMD_FAILURE;
pd=sd->pd; data = script_getdata(st, 2);
get_val(st, data);
id = (data_isstring(data) ? skill_name2id(script_getstr(st,2)) : skill_get_index(script_getnum(st,2)));
if (!id) {
ShowError("buildin_petskillattack2: Invalid skill defined!\n");
return SCRIPT_CMD_FAILURE;
}
pd = sd->pd;
if (pd->a_skill == NULL) if (pd->a_skill == NULL)
pd->a_skill = (struct pet_skill_attack *)aMalloc(sizeof(struct pet_skill_attack)); pd->a_skill = (struct pet_skill_attack *)aMalloc(sizeof(struct pet_skill_attack));
data = script_getdata(st, 2); pd->a_skill->id = id;
get_val(st, data); // Convert into value in case of a variable pd->a_skill->damage = script_getnum(st,3); // Fixed damage
pd->a_skill->id=( data_isstring(data) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) ); pd->a_skill->lv = (unsigned short)skill_get_max(pd->a_skill->id); // Adjust to max skill level
pd->a_skill->lv=script_getnum(st,3);
pd->a_skill->div_ = script_getnum(st,4); pd->a_skill->div_ = script_getnum(st,4);
pd->a_skill->rate=script_getnum(st,5); pd->a_skill->rate = script_getnum(st,5);
pd->a_skill->bonusrate=script_getnum(st,6); pd->a_skill->bonusrate = script_getnum(st,6);
return SCRIPT_CMD_SUCCESS; return SCRIPT_CMD_SUCCESS;
} }
@ -13178,12 +13200,21 @@ BUILDIN_FUNC(petskillsupport)
{ {
struct pet_data *pd; struct pet_data *pd;
struct script_data *data; struct script_data *data;
TBL_PC *sd=script_rid2sd(st); TBL_PC *sd = script_rid2sd(st);
int id = 0;
if(sd==NULL || sd->pd==NULL) if(sd == NULL || sd->pd == NULL)
return 0; return SCRIPT_CMD_FAILURE;
pd=sd->pd; data = script_getdata(st, 2);
get_val(st, data);
id = (data_isstring(data) ? skill_name2id(script_getstr(st,2)) : skill_get_index(script_getnum(st,2)));
if (!id) {
ShowError("buildin_petskillsupport: Invalid skill defined!\n");
return SCRIPT_CMD_FAILURE;
}
pd = sd->pd;
if (pd->s_skill) if (pd->s_skill)
{ //Clear previous skill { //Clear previous skill
if (pd->s_skill->timer != INVALID_TIMER) if (pd->s_skill->timer != INVALID_TIMER)
@ -13196,13 +13227,11 @@ BUILDIN_FUNC(petskillsupport)
} else //init memory } else //init memory
pd->s_skill = (struct pet_skill_support *) aMalloc(sizeof(struct pet_skill_support)); pd->s_skill = (struct pet_skill_support *) aMalloc(sizeof(struct pet_skill_support));
data = script_getdata(st, 2); pd->s_skill->id = id;
get_val(st, data); // Convert into value in case of a variable pd->s_skill->lv = script_getnum(st,3);
pd->s_skill->id=( data_isstring(data) ? skill_name2id(script_getstr(st,2)) : script_getnum(st,2) ); pd->s_skill->delay = script_getnum(st,4);
pd->s_skill->lv=script_getnum(st,3); pd->s_skill->hp = script_getnum(st,5);
pd->s_skill->delay=script_getnum(st,4); pd->s_skill->sp = script_getnum(st,6);
pd->s_skill->hp=script_getnum(st,5);
pd->s_skill->sp=script_getnum(st,6);
//Use delay as initial offset to avoid skill/heal exploits //Use delay as initial offset to avoid skill/heal exploits
if (battle_config.pet_equip_required && pd->pet.equip == 0) if (battle_config.pet_equip_required && pd->pet.equip == 0)

View File

@ -2892,18 +2892,24 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
dmg = battle_calc_attack(attack_type,src,bl,skill_id,skill_lv,flag&0xFFF); dmg = battle_calc_attack(attack_type,src,bl,skill_id,skill_lv,flag&0xFFF);
//Skotlex: Adjusted to the new system //! CHECKME: This check maybe breaks the battle_calc_attack, and maybe need better calculation.
// Adjusted to the new system [Skotlex]
if( src->type == BL_PET ) { // [Valaris] if( src->type == BL_PET ) { // [Valaris]
struct pet_data *pd = (TBL_PET*)src; struct pet_data *pd = (TBL_PET*)src;
if (pd->a_skill && pd->a_skill->div_ && pd->a_skill->id == skill_id) { if (pd->a_skill && pd->a_skill->div_ && pd->a_skill->id == skill_id) { //petskillattack2
if (battle_config.pet_ignore_infinite_def || !is_infinite_defense(bl,dmg.flag)) {
int element = skill_get_ele(skill_id, skill_lv); int element = skill_get_ele(skill_id, skill_lv);
/*if (skill_id == -1) Does it ever worked? /*if (skill_id == -1) Does it ever worked?
element = sstatus->rhw.ele;*/ element = sstatus->rhw.ele;*/
if (element != ELE_NEUTRAL || !(battle_config.attack_attr_none&BL_PET)) if (element != ELE_NEUTRAL || !(battle_config.attack_attr_none&BL_PET))
dmg.damage=battle_attr_fix(src, bl, skill_lv, element, tstatus->def_ele, tstatus->ele_lv); dmg.damage = battle_attr_fix(src, bl, pd->a_skill->damage, element, tstatus->def_ele, tstatus->ele_lv);
else else
dmg.damage= skill_lv; dmg.damage = pd->a_skill->damage; // Fixed damage
dmg.damage2=0;
}
else
dmg.damage = 1*pd->a_skill->div_;
dmg.damage2 = 0;
dmg.div_= pd->a_skill->div_; dmg.div_= pd->a_skill->div_;
} }
} }

View File

@ -2481,9 +2481,9 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt)
* @return 1 * @return 1
* @author [Skotlex] * @author [Skotlex]
*/ */
int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt) void status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
{ {
nullpo_ret(pd); nullpo_retv(pd);
if (opt&SCO_FIRST) { if (opt&SCO_FIRST) {
memcpy(&pd->status, &pd->db->status, sizeof(struct status_data)); memcpy(&pd->status, &pd->db->status, sizeof(struct status_data));
@ -2540,11 +2540,8 @@ int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
} }
// Support rate modifier (1000 = 100%) // Support rate modifier (1000 = 100%)
pd->rate_fix = 1000*(pd->pet.intimate - battle_config.pet_support_min_friendly)/(1000- battle_config.pet_support_min_friendly) +500; pd->rate_fix = min(1000 * (pd->pet.intimate - battle_config.pet_support_min_friendly) / (1000 - battle_config.pet_support_min_friendly) + 500, USHRT_MAX);
if(battle_config.pet_support_rate != 100) pd->rate_fix = min(apply_rate(pd->rate_fix, battle_config.pet_support_rate), USHRT_MAX);
pd->rate_fix = pd->rate_fix*battle_config.pet_support_rate/100;
return 1;
} }
/** /**
@ -3158,8 +3155,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
if( sd->pd ) { // Pet Bonus if( sd->pd ) { // Pet Bonus
struct pet_data *pd = sd->pd; struct pet_data *pd = sd->pd;
if( pd && pd->petDB && pd->petDB->equip_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly ) if( pd && pd->petDB && pd->petDB->pet_loyal_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly )
run_script(pd->petDB->equip_script,0,sd->bl.id,0); run_script(pd->petDB->pet_loyal_script,0,sd->bl.id,0);
if( pd && pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus ) if( pd && pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus )
pc_bonus(sd,pd->bonus->type, pd->bonus->val); pc_bonus(sd,pd->bonus->type, pd->bonus->val);
} }

View File

@ -2030,7 +2030,7 @@ void status_change_clear_buffs(struct block_list* bl, int type);
void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt); void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt);
int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt); int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt);
int status_calc_pet_(struct pet_data* pd, enum e_status_calc_opt opt); void status_calc_pet_(struct pet_data* pd, enum e_status_calc_opt opt);
int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt); int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt);
int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt); int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt);
int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt); int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt);