Compare commits

...

23 Commits

Author SHA1 Message Date
Aleos
e1997bc11f Small typos
* Fixed a couple other small typos.
2019-04-23 10:06:29 -04:00
norm
9fd95bf006 Fixed typo 2019-04-10 22:48:36 +02:00
norm
ac6b5ae996 Create guidelines.md 2019-04-10 20:09:29 +02:00
Atemo
9aa5f7d834 Added several warning messages (#4062)
* enablenpc / disablenpc / hideoffnpc / hideonnpc now display the npc source when the npc named doesn't exist
* Added the NPC source to status_set_viewdata when no view data has been found
* Added export_deprecated_constant3 to display the constant name replacing the deprecated
* Removed the debug message from `@ warp` when the map name is wrong
* Added clif_name_area to UMOB_LEVEL on setunitdata and a capvalue to UPET_HUNGER
* areamonster now checks if the monster ID exists

Thanks to @Normynator and @aleos89 for the review!
2019-04-10 15:59:42 +02:00
Aleos
c772262469 Corrected guild level increases (#4094)
* Resolves guild levels being capped to various hard coded limits rather than using the constant.
Thanks to @datleeroy!
2019-04-10 09:15:54 -04:00
rAthenaAPI
26ebaf732c Effect State Update 2019-04-09 13:05:32 +02:00
rAthenaAPI
5cbbec78b9 Effect State Update 2019-04-09 12:06:41 +02:00
Aleos
a0bcb92b8a Added caps to item bonus rates (#4081)
* Fixes #4069.
* Added caps to item bonus rates so that they don't exceed the -10000~10000 range.
* Added warning messages when initial rate exceeds range.
* Added a missing vector size check for HP/SP Vanish bonus.
Thanks to @Litro and @Lemongrass3110!
2019-04-08 10:11:56 -04:00
rAthenaAPI
e2b4e0d588 SQL synchronization 2019-04-07 19:07:57 +02:00
Aleos
4a6a545a63 Added Hanbok Bag item script (#4084)
* Fixes #4054.
* Added the item script to Hanbok Bag.
Thanks to @JohnnyPlayy!
2019-04-07 13:07:25 -04:00
rAthenaAPI
edfbf3f5a6 SQL synchronization 2019-04-07 18:16:46 +02:00
Aleos
7c0d9bf300 Corrected Gunslinger shops (#4086)
* Fixes #4076.
* Updated renewal Gunslinger shops to the new bullets.
* Adjusted name of older bullets. Now called Surplus.
Thanks to @mazvi!
2019-04-07 12:16:19 -04:00
rAthenaAPI
de421d8f16 SQL synchronization 2019-04-07 16:26:49 +02:00
Aleos
b6e383b8ed Corrected Sword Stick equip requirements (#4091)
* Fixes #4089.
* Sword Stick can be equipped by all Mage-based classes, not just Wizards.
Thanks to @cahya1992!
2019-04-07 10:26:40 -04:00
Lemongrass3110
ee2f49509a Fixed the upgrade script for pet evolution (#4082)
Fixes #4075

Thanks to @mazvi
2019-04-07 14:17:11 +02:00
rAthenaAPI
4ef5764d8d Effect State Update 2019-04-06 10:05:39 +02:00
rAthenaAPI
c2fbfdd4b7 Effect State Update 2019-04-06 09:18:47 +02:00
Cydh Ramdh
a8185e6294 Fixes #4066 (#4070)
* Fixed Defending Aura effect taking twice as incorrect Devotion behavior (leftover from old fixes)
2019-04-05 07:32:35 +07:00
Aleos
7c313a776a Updated Firewall cast check (#3556)
* Firewall should check at cast begin if unit max count has been reached.
* Removed redundancy with the unit max count checks by merging into a single function.
Thanks to @mrjnumber1!
2019-04-04 18:57:17 -04:00
Aleos
1504507e71 Fixed pre-renewal pet fullness values (#4074)
* Fixes #4073.
* Corrected the fullness values for pets.
Thanks to @sader1992!
2019-04-04 07:42:06 -04:00
Aleos
c977558cfd Adjusted OnTouch overlap behavior (#2382)
* Fixes #1939 and fixes #2274.
* OnTouch NPC are now able to overlap one another and properly trigger as they do on official servers.
* When entering an overlap area it should trigger both NPC.
* Walking from overlap area to either NPC should trigger neither.
* Walking from one NPC to the other (skipping the overlap area) should trigger the NPC area you enter.
* Entering an OnTouch area will no longer stop the player from walking unless a message or menu window opens (or other events that should stop the player).
* Resolves OnTouch_ overlapping issues.
* Dead players don't trigger OnTouch_ anymore.
* Hidden players don't trigger NPC clicks when OnTouch_ label is defined.
Thanks to @Tokeiburu, @Lemongrass3110, @Atemo, and @Normynator!
2019-04-03 19:25:47 -04:00
rAthenaAPI
98a685d706 Effect State Update 2019-04-03 07:05:57 +02:00
rAthenaAPI
83a0ae9480 Effect State Update 2019-04-03 05:06:00 +02:00
28 changed files with 734 additions and 469 deletions

View File

@@ -60,7 +60,7 @@ Body:
EggItem: Poring_Egg
EquipItem: Backpack
FoodItem: Apple_Juice
Fullness: 80
Fullness: 3
IntimacyFed: 50
CaptureRate: 2000
Script: >
@@ -75,7 +75,7 @@ Body:
EggItem: Drops_Egg
EquipItem: Backpack
FoodItem: Yellow_Herb
Fullness: 80
Fullness: 4
IntimacyFed: 40
CaptureRate: 1500
Script: >
@@ -90,7 +90,7 @@ Body:
EggItem: Poporing_Egg
EquipItem: Backpack
FoodItem: Green_Herb
Fullness: 80
Fullness: 5
IntimacyFed: 30
CaptureRate: 1000
Script: >
@@ -105,7 +105,7 @@ Body:
EggItem: Lunatic_Egg
EquipItem: Silk_Ribbon
FoodItem: Carrot_Juice
Fullness: 80
Fullness: 4
IntimacyFed: 40
CaptureRate: 1500
SpecialPerformance: false
@@ -121,7 +121,7 @@ Body:
EggItem: Picky_Egg
EquipItem: Tiny_Egg_Shell
FoodItem: Red_Herb
Fullness: 80
Fullness: 4
IntimacyFed: 40
CaptureRate: 2000
Script: >
@@ -136,7 +136,7 @@ Body:
EggItem: Chonchon_Egg
EquipItem: Monster_Oxygen_Mask
FoodItem: Pet_Food
Fullness: 80
Fullness: 6
IntimacyFed: 30
CaptureRate: 1500
Script: >
@@ -151,7 +151,7 @@ Body:
EggItem: Steel_Chonchon_Egg
EquipItem: Monster_Oxygen_Mask
FoodItem: Iron_Ore
Fullness: 80
Fullness: 5
IntimacyFed: 20
CaptureRate: 1000
Script: >
@@ -166,7 +166,7 @@ Body:
EggItem: Hunter_Fly_Egg
EquipItem: Monster_Oxygen_Mask
FoodItem: Red_Gemstone
Fullness: 80
Fullness: 5
IntimacyFed: 10
CaptureRate: 500
Script: >
@@ -181,7 +181,7 @@ Body:
EggItem: Savage_Bebe_Egg
EquipItem: Green_Lace
FoodItem: Pet_Food
Fullness: 80
Fullness: 7
IntimacyFed: 40
CaptureRate: 1500
SpecialPerformance: false
@@ -197,7 +197,7 @@ Body:
EggItem: Baby_Desert_Wolf_Egg
EquipItem: Transparent_Headgear
FoodItem: Pet_Food
Fullness: 80
Fullness: 6
IntimacyFed: 40
CaptureRate: 1000
SpecialPerformance: false
@@ -213,7 +213,7 @@ Body:
EggItem: Rocker_Egg
EquipItem: Rocker_Glasses
FoodItem: Pet_Food
Fullness: 80
Fullness: 1
IntimacyFed: 30
CaptureRate: 1500
SpecialPerformance: false
@@ -229,7 +229,7 @@ Body:
EggItem: Spore_Egg
EquipItem: Bark_Shorts
FoodItem: Pet_Food
Fullness: 80
Fullness: 3
IntimacyFed: 30
CaptureRate: 1500
SpecialPerformance: false
@@ -245,7 +245,7 @@ Body:
EggItem: Poison_Spore_Egg
EquipItem: Bark_Shorts
FoodItem: Pet_Food
Fullness: 80
Fullness: 3
IntimacyFed: 20
CaptureRate: 1000
SpecialPerformance: false
@@ -261,7 +261,7 @@ Body:
EggItem: PecoPeco_Egg
EquipItem: Battered_Pot
FoodItem: Pet_Food
Fullness: 80
Fullness: 4
IntimacyFed: 30
CaptureRate: 1000
Script: >
@@ -276,7 +276,7 @@ Body:
EggItem: Smokie_Egg
EquipItem: Red_Muffler
FoodItem: Pet_Food
Fullness: 80
Fullness: 4
IntimacyFed: 30
CaptureRate: 1000
Script: >
@@ -291,7 +291,7 @@ Body:
EggItem: Yoyo_Egg
EquipItem: Monkey_Circlet
FoodItem: Banana_Juice
Fullness: 80
Fullness: 5
IntimacyFed: 20
CaptureRate: 1000
Script: >
@@ -306,7 +306,7 @@ Body:
EggItem: Orc_Warrior_Egg
EquipItem: Wild_Flower
FoodItem: Pet_Food
Fullness: 80
Fullness: 5
IntimacyFed: 20
CaptureRate: 500
Script: >
@@ -321,7 +321,7 @@ Body:
EggItem: Munak_Egg
EquipItem: Punisher
FoodItem: Pet_Food
Fullness: 80
Fullness: 3
IntimacyFed: 20
CaptureRate: 500
SpecialPerformance: false
@@ -337,7 +337,7 @@ Body:
EggItem: Dokkaebi_Egg
EquipItem: Wig
FoodItem: Pet_Food
Fullness: 80
Fullness: 4
IntimacyFed: 20
CaptureRate: 500
SpecialPerformance: false
@@ -353,7 +353,7 @@ Body:
EggItem: Sohee_Egg
EquipItem: Golden_Bell
FoodItem: Pet_Food
Fullness: 80
Fullness: 3
IntimacyFed: 10
CaptureRate: 500
SpecialPerformance: false
@@ -369,7 +369,7 @@ Body:
EggItem: Isis_Egg
EquipItem: Queen's_Hair_Ornament
FoodItem: Pet_Food
Fullness: 80
Fullness: 3
IntimacyFed: 10
CaptureRate: 500
SpecialPerformance: false
@@ -385,7 +385,7 @@ Body:
EggItem: Green_Petite_Egg
EquipItem: Stellar_Hairpin
FoodItem: Pet_Food
Fullness: 80
Fullness: 4
IntimacyFed: 20
CaptureRate: 500
SpecialPerformance: false
@@ -402,7 +402,7 @@ Body:
EggItem: Deviruchi_Egg
EquipItem: Pacifier
FoodItem: Shoot
Fullness: 80
Fullness: 2
IntimacyFed: 10
CaptureRate: 500
SpecialPerformance: false
@@ -420,7 +420,7 @@ Body:
EggItem: Bapho_Jr._Egg
EquipItem: Skull_Helm
FoodItem: Honey
Fullness: 80
Fullness: 2
IntimacyFed: 10
CaptureRate: 200
SpecialPerformance: false
@@ -437,7 +437,7 @@ Body:
EggItem: Bongun_Egg
EquipItem: Sword_Of_Grave_Keeper
FoodItem: Pet_Food
Fullness: 80
Fullness: 4
IntimacyFed: 30
CaptureRate: 500
Script: >
@@ -451,7 +451,7 @@ Body:
TameItem: Prohibition_Red_Candle
EggItem: Zherlthsh_Egg
FoodItem: Immortal_Heart
Fullness: 80
Fullness: 7
IntimacyFed: 10
CaptureRate: 300
SpecialPerformance: false
@@ -468,7 +468,7 @@ Body:
TameItem: Sway_Apron
EggItem: Alice_Egg
FoodItem: White_Potion
Fullness: 80
Fullness: 2
IntimacyFed: 20
CaptureRate: 800
SpecialPerformance: false
@@ -483,7 +483,7 @@ Body:
- Mob: EVENT_RICECAKE
EggItem: Rice_Cake_Egg
FoodItem: Green_Herb
Fullness: 80
Fullness: 3
IntimacyFed: 50
CaptureRate: 2000
Script: >
@@ -497,7 +497,7 @@ Body:
TameItem: Sweet_Candy_Striper
EggItem: Santa_Goblin_Egg
FoodItem: Scell
Fullness: 80
Fullness: 3
IntimacyFed: 50
CaptureRate: 2000
SpecialPerformance: false
@@ -512,7 +512,7 @@ Body:
TameItem: Tantanmen
EggItem: Chung_E_Egg
FoodItem: Bun_
Fullness: 80
Fullness: 3
IntimacyFed: 50
CaptureRate: 2000
SpecialPerformance: false
@@ -527,7 +527,7 @@ Body:
- Mob: ECLIPSE_P
EggItem: Spring_Rabbit_Egg
FoodItem: Bok_Choy
Fullness: 80
Fullness: 3
IntimacyFed: 50
CaptureRate: 2000
SpecialPerformance: false
@@ -535,7 +535,7 @@ Body:
TameItem: Knife_Goblin_Ring
EggItem: Knife_Goblin_Egg
FoodItem: Green_Apple
Fullness: 80
Fullness: 3
IntimacyFed: 50
CaptureRate: 800
SpecialPerformance: false
@@ -543,7 +543,7 @@ Body:
TameItem: Flail_Goblin_Ring
EggItem: Flail_Goblin_Egg
FoodItem: Green_Apple
Fullness: 80
Fullness: 3
IntimacyFed: 50
CaptureRate: 800
SpecialPerformance: false
@@ -551,7 +551,7 @@ Body:
TameItem: Hammer_Goblin_Ring
EggItem: Hammer_Goblin_Egg
FoodItem: Green_Apple
Fullness: 80
Fullness: 3
IntimacyFed: 50
CaptureRate: 800
SpecialPerformance: false
@@ -559,7 +559,7 @@ Body:
TameItem: Holy_Marble
EggItem: Red_Deleter_Egg
FoodItem: Whole_Barbecue
Fullness: 80
Fullness: 4
IntimacyFed: 20
CaptureRate: 800
SpecialPerformance: false
@@ -567,7 +567,7 @@ Body:
TameItem: Red_Burning_Stone
EggItem: Diabolic_Egg
FoodItem: Meat_Veg_Skewer
Fullness: 80
Fullness: 2
IntimacyFed: 10
CaptureRate: 800
SpecialPerformance: false
@@ -575,7 +575,7 @@ Body:
TameItem: Skull_Of_Vagabond
EggItem: Wanderer_Egg
FoodItem: Spirit_Liquor
Fullness: 80
Fullness: 2
IntimacyFed: 20
CaptureRate: 800
SpecialPerformance: false
@@ -589,7 +589,7 @@ Body:
- Mob: P_CHUNG_E
EggItem: New_Year_Doll_Egg
FoodItem: Mojji
Fullness: 80
Fullness: 3
IntimacyFed: 30
CaptureRate: 800
SpecialPerformance: false
@@ -598,7 +598,7 @@ Body:
EggItem: Golem_Egg
EquipItem: Windup_Spring
FoodItem: Mystic_Stone
Fullness: 80
Fullness: 7
IntimacyFed: 20
CaptureRate: 500
SpecialPerformance: false
@@ -614,7 +614,7 @@ Body:
EggItem: Marionette_Egg
EquipItem: Star_Hairband
FoodItem: Small_Snow_Flower
Fullness: 80
Fullness: 3
IntimacyFed: 10
CaptureRate: 500
SpecialPerformance: false
@@ -629,7 +629,7 @@ Body:
EggItem: Medusa_Egg
EquipItem: Queen's_Coronet
FoodItem: Apple_Pudding
Fullness: 80
Fullness: 3
IntimacyFed: 10
CaptureRate: 200
SpecialPerformance: false
@@ -645,7 +645,7 @@ Body:
EggItem: Whisper_Egg
EquipItem: Spirit_Chain_
FoodItem: Damp_Darkness
Fullness: 80
Fullness: 7
IntimacyFed: 20
CaptureRate: 500
SpecialPerformance: false
@@ -661,7 +661,7 @@ Body:
EggItem: Goblin_Leader_Egg
EquipItem: Nice_Badge
FoodItem: Big_Cell
Fullness: 80
Fullness: 7
IntimacyFed: 10
CaptureRate: 50
SpecialPerformance: false
@@ -677,7 +677,7 @@ Body:
EggItem: Succubus_Egg
EquipItem: Black_Butterfly_Mask
FoodItem: Vital_Flower_
Fullness: 80
Fullness: 3
IntimacyFed: 10
CaptureRate: 200
SpecialPerformance: false
@@ -692,7 +692,7 @@ Body:
EggItem: Incubus_Egg
EquipItem: Ball_Mask
FoodItem: Vital_Flower
Fullness: 80
Fullness: 3
IntimacyFed: 10
CaptureRate: 50
SpecialPerformance: false
@@ -707,7 +707,7 @@ Body:
EggItem: Nightmare_Terror_Egg
EquipItem: Hell_Horn
FoodItem: Fresh_Plant
Fullness: 80
Fullness: 3
IntimacyFed: 10
CaptureRate: 200
SpecialPerformance: false
@@ -722,7 +722,7 @@ Body:
EggItem: Shinobi_Egg
EquipItem: Wine_On_Sleeve
FoodItem: Grilled_Rice_Cake
Fullness: 80
Fullness: 7
IntimacyFed: 20
CaptureRate: 500
SpecialPerformance: false
@@ -737,7 +737,7 @@ Body:
EggItem: Miyabi_Ningyo_Egg
EquipItem: Summer_Fan
FoodItem: Well_Ripened_Berry
Fullness: 80
Fullness: 3
IntimacyFed: 15
CaptureRate: 200
SpecialPerformance: false
@@ -753,7 +753,7 @@ Body:
EggItem: Wicked_Nymph_Egg
EquipItem: Jade_Trinket
FoodItem: Morning_Dew
Fullness: 80
Fullness: 3
IntimacyFed: 15
CaptureRate: 500
SpecialPerformance: false
@@ -769,7 +769,7 @@ Body:
EggItem: Stone_Shooter_Egg
EquipItem: Apro_Hair
FoodItem: Plant_Neutrient
Fullness: 80
Fullness: 7
IntimacyFed: 20
CaptureRate: 500
SpecialPerformance: false
@@ -784,7 +784,7 @@ Body:
EggItem: Dullahan_Egg
EquipItem: Death_Coil
FoodItem: Sunset_On_The_Rock
Fullness: 80
Fullness: 3
IntimacyFed: 10
CaptureRate: 200
SpecialPerformance: false
@@ -799,7 +799,7 @@ Body:
EggItem: Loli_Ruri_Egg
EquipItem: Fashionable_Glasses
FoodItem: Pumpkin_Pie_
Fullness: 80
Fullness: 3
IntimacyFed: 15
CaptureRate: 200
SpecialPerformance: false
@@ -815,7 +815,7 @@ Body:
EggItem: Civil_Servant_Egg
EquipItem: Golden_Earing
FoodItem: Flavored_Alcohol
Fullness: 80
Fullness: 3
IntimacyFed: 10
CaptureRate: 500
SpecialPerformance: false
@@ -830,7 +830,7 @@ Body:
EggItem: Leaf_Cat_Egg
EquipItem: Green_Lucky_Bag
FoodItem: Fish_With_Blue_Back
Fullness: 80
Fullness: 7
IntimacyFed: 20
CaptureRate: 200
SpecialPerformance: false
@@ -845,7 +845,7 @@ Body:
EggItem: Bacsojin_Egg
EquipItem: Round_Hair_Ornament
FoodItem: Traditional_Cookie
Fullness: 80
Fullness: 7
IntimacyFed: 10
CaptureRate: 2000
SpecialPerformance: false
@@ -854,7 +854,7 @@ Body:
EggItem: Imp_Egg
EquipItem: Horn_Protector
FoodItem: Flame_Gemstone
Fullness: 80
Fullness: 3
IntimacyFed: 10
CaptureRate: 200
SpecialPerformance: false

View File

@@ -1019,7 +1019,7 @@
1665,Piercing_Staff_,Piercing Staff,5,20,,500,80:145,,1,2,0x00018314,18,2,2,3,70,1,10,{ .@r = getrefine(); bonus bInt,4; bonus2 bIgnoreMdefClassRate,Class_Normal,10+.@r; bonus2 bIgnoreMdefClassRate,Class_Boss,10+.@r; },{},{}
1666,Healing_Staff_,Healing Staff,5,20,,400,10:105,,1,2,0x00008110,63,2,2,3,55,1,10,{ bonus bAtkEle,Ele_Holy; bonus bHealPower,(getrefine()*3/2); },{},{}
1667,TE_Woe_Staff,TE Woe Staff,5,0,,0,50:100,,1,0,0x00818315,63,2,2,3,40,1,10,{ bonus2 bMagicAddRace,RC_Player,10; bonus3 bAddEff,Eff_Blind,1000,ATF_MAGIC; bonus bHPRecovRate,5; bonus bSPRecovRate,5; },{},{}
1668,Sword_Stick,Sword Stick,5,10,,500,120:150,,,2,0x800200,63,2,2,4,80,1,10,{ bonus bAspdRate,10; },{},{}
1668,Sword_Stick,Sword Stick,5,10,,500,120:150,,,2,0x810204,63,2,2,4,80,1,10,{ bonus bAspdRate,10; },{},{}
1669,Thanos_Staff,Thanos Staff,5,10,,1000,100:200,,1,1,0x00018314,56,2,2,4,120,1,10,{ bonus bInt,6; bonus bVit,6; bonus bLuk,-6; bonus bHealPower,15; bonus bMagicHPGainValue,500; bonus bMagicSPGainValue,50; bonus2 bHPLossRate,100,10000; },{},{ heal -1000,0; }
1670,RWC_Memory_Staff,RWC Memory Staff,5,20,,500,25:30,,1,1,0x00818315,63,2,2,3,1,1,10,{ .@r = getrefine(); bonus bMatk,30*(.@r/3); if(.@r>=6) bonus2 bMagicAddClass,Class_All,(.@r>=9?10:5); if(.@r>=9) bonus4 bAutoSpell,"HW_MAGICPOWER",1,10,0; },{},{}
1671,Devil_Won_Staff,Evil Slayer Vanquisher Staff,5,0,,800,30:155,,,1,0x00818315,63,2,2,3,100,1,10,{ bonus2 bAddRace,RC_Undead,10; bonus2 bAddRace,RC_Demon,10; bonus2 bMagicAddRace,RC_Undead,10; bonus2 bMagicAddRace,RC_Demon,10; .@r = getrefine(); if(.@r>=9) { .@dmg = 5; if(.@r>=12) { .@dmg += 7; } bonus bMatkRate,.@dmg; } },{},{}
@@ -7442,13 +7442,13 @@
// Bullets
//===================================================================
13200,Bullet,Bullet,10,1,,1,25,,,,0x41000000,63,2,32768,,1,,3,{},{},{}
13201,Silver_Bullet,Silver Bullet,10,15,,2,15,,,,0x41000000,63,2,32768,,1,,3,{ bonus bAtkEle,Ele_Holy; },{},{}
13202,Shell_Of_Blood,Bloody Shell,10,30,,2,30,,,,0x41000000,63,2,32768,,1,,3,{ bonus2 bAddEff,Eff_Bleeding,100; },{},{}
13203,Flare_Sphere,Flare Sphere,10,80,,5,50,,,,,,,32768,,,,5,{ bonus bAtkEle,Ele_Fire; },{},{}
13204,Lighting_Sphere,Lightning Sphere,10,80,,5,50,,,,,,,32768,,,,5,{ bonus bAtkEle,Ele_Wind; },{},{}
13205,Poison_Sphere,Poison Sphere,10,80,,5,50,,,,,,,32768,,,,5,{ bonus bAtkEle,Ele_Poison; bonus2 bAddEff,Eff_Poison,500; },{},{}
13206,Blind_Sphere,Blind Sphere,10,80,,5,50,,,,,,,32768,,,,5,{ bonus bAtkEle,Ele_Dark; bonus2 bAddEff,Eff_Blind,500; },{},{}
13207,Freezing_Sphere,Freezing Sphere,10,80,,5,50,,,,,,,32768,,,,5,{ bonus bAtkEle,Ele_Water; },{},{}
13201,Silver_Bullet,Surplus Silver Bullet,10,15,,2,15,,,,0x41000000,63,2,32768,,1,,3,{ bonus bAtkEle,Ele_Holy; },{},{}
13202,Shell_Of_Blood,Surplus Bloody Shell,10,30,,2,30,,,,0x41000000,63,2,32768,,1,,3,{ bonus2 bAddEff,Eff_Bleeding,100; },{},{}
13203,Flare_Sphere,Surplus Flare Sphere,10,80,,5,50,,,,,,,32768,,,,5,{ bonus bAtkEle,Ele_Fire; },{},{}
13204,Lighting_Sphere,Surplus Lightning Sphere,10,80,,5,50,,,,,,,32768,,,,5,{ bonus bAtkEle,Ele_Wind; },{},{}
13205,Poison_Sphere,Surplus Poison Sphere,10,80,,5,50,,,,,,,32768,,,,5,{ bonus bAtkEle,Ele_Poison; bonus2 bAddEff,Eff_Poison,500; },{},{}
13206,Blind_Sphere,Surplus Blind Sphere,10,80,,5,50,,,,,,,32768,,,,5,{ bonus bAtkEle,Ele_Dark; bonus2 bAddEff,Eff_Blind,500; },{},{}
13207,Freezing_Sphere,Surplus Freezing Sphere,10,80,,5,50,,,,,,,32768,,,,5,{ bonus bAtkEle,Ele_Water; },{},{}
13208,Gong_Bug,Sow Bug,10,0,,5,50,,,,0x41000000,63,2,32768,,50,,3,{ bonus2 bAddEff,Eff_Stun,1000; },{},{}
13210,Slug_Bullet_1,Slug Ammunition L,10,250,,250,30,,,,,,,32768,,,,3,{},{},{}
13211,Slug_Bullet_2,Slug Ammunition M,10,500,,500,30,,,,,,,32768,,,,3,{},{},{}
@@ -11163,7 +11163,7 @@
22535,WorkerScroll_A,Scroll Summoning Workers(Male),2,10,,10,,,,0,0xFFFFFFFF,63,2,,,,,,{},{},{}
22536,WorkerScroll_B,Scroll Summoning Workers(Female),2,10,,10,,,,0,0xFFFFFFFF,63,2,,,,,,{},{},{}
22537,PrizeOfHero,Prize Of Hero,2,0,,100,,,,0,0xFFFFFFFF,63,2,,,1,,,{ getrandgroupitem(IG_PrizeOfHero,1); },{},{}
22538,Hanbok_bag,Hanbok bag,2,10,,10,,,,0,0xFFFFFFFF,63,2,,,1,,,{},{},{}
22538,Hanbok_bag,Hanbok bag,2,0,,10,,,,0,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_HANBOK,600000,0; },{},{}
22540,Runstone_Lux,Lux Anima Runestone,11,2,,100,,,,,0xFFFFFFFF,56,2,,,,,,{ itemskill "RK_LUXANIMA",1; },{},{}
22541,PC_Room_Coupon_Box_VI,PC Room Coupon Box VI,18,10,,10,,,,0,0xFFFFFFFF,63,2,,,,,,{},{},{}
22542,Center_Potion_B,Concentration Potion,2,10,,100,,,,0,0xFFFFFFFF,63,2,,,,,,{ sc_start SC_ASPDPOTION0,1800000,4; },{},{}

View File

@@ -162,7 +162,7 @@ Body:
EggItem: Picky_Egg
EquipItem: Tiny_Egg_Shell
FoodItem: Red_Herb
Fullness: 4
Fullness: 4
IntimacyFed: 40
CaptureRate: 2000
Script: >

156
guidelines.md Normal file
View File

@@ -0,0 +1,156 @@
# Welcome
Welcome to the rAthena Code Guidelines.
This is here to help all developers in creating safe, maintainable, easily readable and understandable code.
# References
These guidelines are inspired by the CppCoreGuidelines. Some of the examples below maybe taken directly from there.
If you need more information that may not be listed here, please be sure to check out [CppCoreGuidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md).
If your questions are still unanswered after consulting this or CppCoreGuidelines, consider consulting the [rAthena forum](https://rathena.org/board/), [rAthena's Discord](https://rathena.org/discord/), or add your concerns directly to a pull request.
# Code Guidelines
### 1. Don't unnecessarily remove or add blank lines when committing new code
##### Reason
Commits should be on point, documented and as small as possible.
##### Enforcement
Check for removed or added blank lines on each commit.
### 2. Use std::remove_if, std::remove & ... within std::vector::erase
##### Reason
`std::vector` requires to be shrunk after using `std::remove`. To avoid forgetting about proper shrinking after removing an element the removing should always be bound to a call to `erase`.
##### Note
If using a `std::list` one should rely on `std::list::remove` instead of `std::remove`.
##### Example
vec.erase(std::remove_if(vec.begin(), vec.end(), [](int a) {return a % 2 == 0;}), vec.end()); // good
##### Enforcement
Check for `std::remove` on datatype `std::vector` without being surrounded by an `erase`.
### 3. Don't add redundant `==` or `!=` to conditions
##### Reason
Doing so avoids verbosity and eliminates some opportunities for mistakes.
Helps make style consistent and conventional.
##### Example
By definition, a condition in an `if`-statement, `while`-statement, or a `for`-statement selects between `true` and `false`.
A numeric value is compared to `0` and a pointer value to `nullptr`.
// These all mean "if `p` is not `nullptr`"
if (p) { ... } // good
if (p != 0) { ... } // redundant `!=0`; bad: don't use 0 for pointers
if (p != nullptr) { ... } // redundant `!=nullptr`, not recommended
Often, `if (p)` is read as "if `p` is valid" which is a direct expression of the programmers intent,
whereas `if (p != nullptr)` would be a long-winded workaround.
##### All examples
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es87-dont-add-redundant--or--to-conditions
##### Note
Explicit comparison of an integer to `0` is in general not redundant.
The reason is that (as opposed to pointers and Booleans) an integer often has more than two reasonable values.
Furthermore `0` (zero) is often used to indicate success.
Consequently, it is best to be specific about the comparison.
void f(int i)
{
if (i) // suspect
// ...
if (i == success) // possibly better
// ...
}
Always remember that an integer can have more than two values.
##### Enforcement
Easy, just check for redundant use of `!=` and `==` in conditions.
### 5. Avoid "magic constants"; use symbolic constants
##### Reason
Unnamed constants embedded in expressions are easily overlooked and often hard to understand:
##### Example
for (int m = 1; m <= 12; ++m) // don't: magic constant 12
cout << month[m] << '\n';
No, we don't all know that there are 12 months, numbered 1..12, in a year. Better:
// months are indexed 1..12
constexpr int first_month = 1;
constexpr int last_month = 12;
for (int m = first_month; m <= last_month; ++m) // better
cout << month[m] << '\n';
Better still, don't expose constants:
for (auto m : month)
cout << m << '\n';
##### Enforcement
Flag literals in code. Give a pass to `0`, `1`, `nullptr`, `\n`, `""`, and others on a positive list.
### 4. Use `auto` to avoid redundant repetition of type names
##### Reason
* Simple repetition is tedious and error-prone.
* When you use `auto`, the name of the declared entity is in a fixed position in the declaration, increasing readability.
* In a template function declaration the return type can be a member type.
##### Example
Consider:
auto p = v.begin(); // vector<int>::iterator
auto h = t.future();
auto q = make_unique<int[]>(s);
auto f = [](int x){ return x + 10; };
In each case, we save writing a longish, hard-to-remember type that the compiler already knows but a programmer could get wrong.
##### Exception
Avoid 'auto' when declaring a variable which is directly initiated with a return value of a function call which does not indicate the type. This is only required when using the function call the first time within a method.
Also avoid `auto` for initializer lists and in cases where you know exactly which type you want and where an initializer might require conversion.
##### Example (bad)
auto lst = { 1, 2, 3 }; // lst is an initializer list
auto x{1}; // x is an int (in C++17; initializer_list in C++11)
##### Example (good)
void some_function()
{
my_type a = my_function();
auto b = my_function(); // here we already know the return type of 'my_function'
...
}
##### All examples
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es11-use-auto-to-avoid-redundant-repetition-of-type-names
##### Enforcement
Flag redundant repetition of type names in a declaration.

View File

@@ -51,7 +51,6 @@ alberta_in,182,97,0 shop Tool Dealer#alb2 73,1750:-1,611:-1,501:-1,502:-1,503:-1
alberta_in,180,15,0 shop Armor Dealer#alb 101,2101:-1,2103:-1,2401:-1,2403:-1,2405:-1,2501:-1,2503:-1,2505:-1,2203:-1,2201:-1,2205:-1,2226:-1,2301:-1,2303:-1,2305:-1,2321:-1,2328:-1,2332:-1,2307:-1,2309:-1,2312:-1,2314:-1,2628:-1
alberta_in,188,21,0 shop Weapon Dealer#alb 49,1750:-1,1751:-1,1101:-1,1104:-1,1107:-1,1201:-1,1204:-1,1207:-1,1601:-1,1701:-1,1301:-1,1351:-1,1354:-1,1357:-1,1360:-1
alberta_in,175,97,4 shop Weapon Dealer#alb2 82,1146:-1,1245:-1
alberta_in,176,81,3 shop Trading Merchant#alb 900,13200:-1,13201:-1,13202:-1,13150:-1,13102:-1,13151:-1,13154:-1,13155:-1,13163:-1,13165:-1,13168:-1
//=======================================================
// Al De Baran
@@ -106,7 +105,6 @@ einbroch,138,66,4 shop Flu Mask Dealer#ein 850,5114:-1,2218:-1
einbroch,82,199,4 shop Paddler#ein 855,512:-1,645:-1,1750:-1,501:-1
//Official Gunslingers shops.
que_ng,179,91,3 shop Chivas Lugal 900,13150:-1,13102:-1,13151:-1,13154:-1,13155:-1,13163:-1,13165:-1,13168:-1
que_ng,180,79,3 shop Johnny Waiker 900,13200:-1,13201:-1,13202:-1
//=======================================================
// Geffen

View File

@@ -15,6 +15,16 @@
//= 1.3 Moved Morocc shops to Pre-RE/RE paths. [zackdreaver]
//============================================================
//=======================================================
// Alberta
//=======================================================
alberta_in,176,81,3 shop Trading Merchant#alb 900,13200:-1,13201:-1,13202:-1,13150:-1,13102:-1,13151:-1,13154:-1,13155:-1,13163:-1,13165:-1,13168:-1
//=======================================================
// Einbroch
//=======================================================
que_ng,180,79,3 shop Johnny Waiker 900,13200:-1,13201:-1,13202:-1
//=======================================================
// Izlude
//=======================================================

View File

@@ -22,6 +22,11 @@
//= 2.0 Moved and updated Morocc merchants. [zackdreaver]
//============================================================
//=======================================================
// Alberta
//=======================================================
alberta_in,176,81,3 shop Trading Merchant#alb 900,13200:-1,13221:-1,13222:-1,13150:-1,13102:-1,13151:-1,13154:-1,13155:-1,13163:-1,13165:-1,13168:-1
//=======================================================
// Comodo
//=======================================================
@@ -40,6 +45,7 @@ dewata,158,182,6 shop Armor Dealer 536,2211:-1,2401:-1,2403:-1,2501:-1,2503:-1,2
// Einbroch
//=======================================================
einbroch,122,250,4 shop Black Marketeer#ein 49,2139:-1,2800:-1,2801:-1,2802:-1,2803:-1,2804:-1,2805:-1,2806:-1,2807:-1,18000:-1,18001:-1,18002:-1,18003:-1,18004:-1,12392:-1,12393:-1,12394:-1,6145:-1,6146:-1,6147:-1,6186:-1,2808:-1
que_ng,180,79,3 shop Johnny Waiker 900,13200:-1,13221:-1,13222:-1
//=======================================================
// El Dicastes
@@ -67,7 +73,7 @@ izlude_c,128,158,7 duplicate(Vendor from Milk Ranch#i) Vendor from Milk Ranch#c
izlude_d,128,158,7 duplicate(Vendor from Milk Ranch#i) Vendor from Milk Ranch#d 90
izlude_in,72,98,3 shop Pet Groomer#iz 124,537:-1,643:-1,10013:-1,10014:-1,554:-1,6113:-1,6114:-1,6115:-1
izlude_in,57,110,0 shop Tool Dealer#iz 47,611:-1,501:-1,502:-1,503:-1,504:-1,506:-1,645:-1,656:-1,601:-1,602:-1,1065:-1,1750:-1
izlude_in,72,102,3 shop Trading Merchant#iz 900,13200:-1,13201:-1,13202:-1,13150:-1,13102:-1,13151:-1,13154:-1,13155:-1,13163:-1,13165:-1,13168:-1
izlude_in,72,102,3 shop Trading Merchant#iz 900,13200:-1,13221:-1,13222:-1,13150:-1,13102:-1,13151:-1,13154:-1,13155:-1,13163:-1,13165:-1,13168:-1
//=======================================================
// Juno

View File

@@ -1051,7 +1051,7 @@ REPLACE INTO `item_db_re` VALUES (1664,'Thorn_Staff_','Thorn Staff of Darkness',
REPLACE INTO `item_db_re` VALUES (1665,'Piercing_Staff_','Piercing Staff',5,20,NULL,500,'80:145',NULL,1,2,0x00018314,18,2,2,3,'70',1,10,'.@r = getrefine(); bonus bInt,4; bonus2 bIgnoreMdefClassRate,Class_Normal,10+.@r; bonus2 bIgnoreMdefClassRate,Class_Boss,10+.@r;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (1666,'Healing_Staff_','Healing Staff',5,20,NULL,400,'10:105',NULL,1,2,0x00008110,63,2,2,3,'55',1,10,'bonus bAtkEle,Ele_Holy; bonus bHealPower,(getrefine()*3/2);',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (1667,'TE_Woe_Staff','TE Woe Staff',5,0,NULL,0,'50:100',NULL,1,0,0x00818315,63,2,2,3,'40',1,10,'bonus2 bMagicAddRace,RC_Player,10; bonus3 bAddEff,Eff_Blind,1000,ATF_MAGIC; bonus bHPRecovRate,5; bonus bSPRecovRate,5;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (1668,'Sword_Stick','Sword Stick',5,10,NULL,500,'120:150',NULL,NULL,2,0x800200,63,2,2,4,'80',1,10,'bonus bAspdRate,10;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (1668,'Sword_Stick','Sword Stick',5,10,NULL,500,'120:150',NULL,NULL,2,0x810204,63,2,2,4,'80',1,10,'bonus bAspdRate,10;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (1669,'Thanos_Staff','Thanos Staff',5,10,NULL,1000,'100:200',NULL,1,1,0x00018314,56,2,2,4,'120',1,10,'bonus bInt,6; bonus bVit,6; bonus bLuk,-6; bonus bHealPower,15; bonus bMagicHPGainValue,500; bonus bMagicSPGainValue,50; bonus2 bHPLossRate,100,10000;',NULL,'heal -1000,0;');
REPLACE INTO `item_db_re` VALUES (1670,'RWC_Memory_Staff','RWC Memory Staff',5,20,NULL,500,'25:30',NULL,1,1,0x00818315,63,2,2,3,'1',1,10,'.@r = getrefine(); bonus bMatk,30*(.@r/3); if(.@r>=6) bonus2 bMagicAddClass,Class_All,(.@r>=9?10:5); if(.@r>=9) bonus4 bAutoSpell,"HW_MAGICPOWER",1,10,0;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (1671,'Devil_Won_Staff','Evil Slayer Vanquisher Staff',5,0,NULL,800,'30:155',NULL,NULL,1,0x00818315,63,2,2,3,'100',1,10,'bonus2 bAddRace,RC_Undead,10; bonus2 bAddRace,RC_Demon,10; bonus2 bMagicAddRace,RC_Undead,10; bonus2 bMagicAddRace,RC_Demon,10; .@r = getrefine(); if(.@r>=9) { .@dmg = 5; if(.@r>=12) { .@dmg += 7; } bonus bMatkRate,.@dmg; }',NULL,NULL);
@@ -7474,13 +7474,13 @@ REPLACE INTO `item_db_re` VALUES (13199,'TEMPEST_','Tempest',5,2200000,NULL,2500
# Bullets
#===================================================================
REPLACE INTO `item_db_re` VALUES (13200,'Bullet','Bullet',10,1,NULL,1,'25',NULL,NULL,NULL,0x41000000,63,2,32768,NULL,'1',NULL,3,NULL,NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13201,'Silver_Bullet','Silver Bullet',10,15,NULL,2,'15',NULL,NULL,NULL,0x41000000,63,2,32768,NULL,'1',NULL,3,'bonus bAtkEle,Ele_Holy;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13202,'Shell_Of_Blood','Bloody Shell',10,30,NULL,2,'30',NULL,NULL,NULL,0x41000000,63,2,32768,NULL,'1',NULL,3,'bonus2 bAddEff,Eff_Bleeding,100;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13203,'Flare_Sphere','Flare Sphere',10,80,NULL,5,'50',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,5,'bonus bAtkEle,Ele_Fire;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13204,'Lighting_Sphere','Lightning Sphere',10,80,NULL,5,'50',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,5,'bonus bAtkEle,Ele_Wind;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13205,'Poison_Sphere','Poison Sphere',10,80,NULL,5,'50',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,5,'bonus bAtkEle,Ele_Poison; bonus2 bAddEff,Eff_Poison,500;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13206,'Blind_Sphere','Blind Sphere',10,80,NULL,5,'50',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,5,'bonus bAtkEle,Ele_Dark; bonus2 bAddEff,Eff_Blind,500;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13207,'Freezing_Sphere','Freezing Sphere',10,80,NULL,5,'50',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,5,'bonus bAtkEle,Ele_Water;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13201,'Silver_Bullet','Surplus Silver Bullet',10,15,NULL,2,'15',NULL,NULL,NULL,0x41000000,63,2,32768,NULL,'1',NULL,3,'bonus bAtkEle,Ele_Holy;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13202,'Shell_Of_Blood','Surplus Bloody Shell',10,30,NULL,2,'30',NULL,NULL,NULL,0x41000000,63,2,32768,NULL,'1',NULL,3,'bonus2 bAddEff,Eff_Bleeding,100;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13203,'Flare_Sphere','Surplus Flare Sphere',10,80,NULL,5,'50',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,5,'bonus bAtkEle,Ele_Fire;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13204,'Lighting_Sphere','Surplus Lightning Sphere',10,80,NULL,5,'50',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,5,'bonus bAtkEle,Ele_Wind;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13205,'Poison_Sphere','Surplus Poison Sphere',10,80,NULL,5,'50',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,5,'bonus bAtkEle,Ele_Poison; bonus2 bAddEff,Eff_Poison,500;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13206,'Blind_Sphere','Surplus Blind Sphere',10,80,NULL,5,'50',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,5,'bonus bAtkEle,Ele_Dark; bonus2 bAddEff,Eff_Blind,500;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13207,'Freezing_Sphere','Surplus Freezing Sphere',10,80,NULL,5,'50',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,5,'bonus bAtkEle,Ele_Water;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13208,'Gong_Bug','Sow Bug',10,0,NULL,5,'50',NULL,NULL,NULL,0x41000000,63,2,32768,NULL,'50',NULL,3,'bonus2 bAddEff,Eff_Stun,1000;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13210,'Slug_Bullet_1','Slug Ammunition L',10,250,NULL,250,'30',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,3,NULL,NULL,NULL);
REPLACE INTO `item_db_re` VALUES (13211,'Slug_Bullet_2','Slug Ammunition M',10,500,NULL,500,'30',NULL,NULL,NULL,NULL,NULL,NULL,32768,NULL,NULL,NULL,3,NULL,NULL,NULL);
@@ -11195,7 +11195,7 @@ REPLACE INTO `item_db_re` VALUES (22534,'Closedmind_Box','Closed Mind Box',18,10
REPLACE INTO `item_db_re` VALUES (22535,'WorkerScroll_A','Scroll Summoning Workers(Male)',2,10,NULL,10,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `item_db_re` VALUES (22536,'WorkerScroll_B','Scroll Summoning Workers(Female)',2,10,NULL,10,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `item_db_re` VALUES (22537,'PrizeOfHero','Prize Of Hero',2,0,NULL,100,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,'1',NULL,NULL,'getrandgroupitem(IG_PrizeOfHero,1);',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (22538,'Hanbok_bag','Hanbok bag',2,10,NULL,10,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,'1',NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `item_db_re` VALUES (22538,'Hanbok_bag','Hanbok bag',2,0,NULL,10,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start SC_HANBOK,600000,0;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (22540,'Runstone_Lux','Lux Anima Runestone',11,2,NULL,100,NULL,NULL,NULL,NULL,0xFFFFFFFF,56,2,NULL,NULL,NULL,NULL,NULL,'itemskill "RK_LUXANIMA",1;',NULL,NULL);
REPLACE INTO `item_db_re` VALUES (22541,'PC_Room_Coupon_Box_VI','PC Room Coupon Box VI',18,10,NULL,10,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `item_db_re` VALUES (22542,'Center_Potion_B','Concentration Potion',2,10,NULL,100,NULL,NULL,NULL,0,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'sc_start SC_ASPDPOTION0,1800000,4;',NULL,NULL);

View File

@@ -1,2 +1,12 @@
ALTER TABLE `pet`
ADD COLUMN `autofeed` tinyint(2) NOT NULL default '0' AFTER `incubate`;
UPDATE `inventory` `i`
INNER JOIN `char` `c`
ON `i`.`char_id` = `c`.`char_id` AND `c`.`pet_id` <> '0'
SET `i`.`attribute` = '1'
WHERE
`i`.`card0` = '256'
AND
( `i`.`card1` | ( `i`.`card2` << 16 ) ) = `c`.`pet_id`
;

View File

@@ -758,7 +758,7 @@ int inter_guild_sql_init(void)
//Read exp file
for(i = 0; i<ARRAYLENGTH(filename); i++){
sv_readdb(db_path, filename[i], ',', 1, 1, 100, exp_guild_parse_row, i > 0);
sv_readdb(db_path, filename[i], ',', 1, 1, MAX_GUILDLEVEL, exp_guild_parse_row, i > 0);
}
add_timer_func_list(guild_save_timer, "guild_save_timer");
@@ -829,7 +829,10 @@ unsigned int guild_nextexp(int level)
{
if (level == 0)
return 1;
return level < 100 && level > 0 ? guild_exp[level-1] : 0;
if (level < 0 || level > MAX_GUILDLEVEL)
return 0;
return guild_exp[level-1];
}
int guild_checkskill(struct guild *g,int id)
@@ -867,7 +870,7 @@ int guild_calcinfo(struct guild *g)
g->max_member = MAX_GUILD;
}
// Compute the guild average level level
// Compute the guild average level
g->average_lv=0;
g->connect_member=0;
for(i=c=0;i<g->max_member;i++)
@@ -1451,23 +1454,22 @@ int mapif_parse_GuildMessage(int fd,int guild_id,uint32 account_id,char *mes,int
// Modification of the guild
int mapif_parse_GuildBasicInfoChange(int fd,int guild_id,int type,const char *data,int len)
{
struct guild * g;
short dw=*((short *)data);
g = inter_guild_fromsql(guild_id);
if(g==NULL)
struct guild *g = inter_guild_fromsql(guild_id);
if (!g)
return 0;
switch(type)
{
short data_value = *((short *)data);
switch(type) {
case GBI_GUILDLV:
if(dw>0 && g->guild_lv+dw<=50)
{
g->guild_lv+=dw;
g->skill_point+=dw;
}
else if(dw<0 && g->guild_lv+dw>=1)
g->guild_lv+=dw;
mapif_guild_info(-1,g);
if (data_value > 0 && g->guild_lv + data_value <= MAX_GUILDLEVEL) {
g->guild_lv += data_value;
g->skill_point += data_value;
} else if (data_value < 0 && g->guild_lv + data_value >= 1)
g->guild_lv += data_value;
mapif_guild_info(-1, g);
g->save_flag |= GS_LEVEL;
return 0;
default:

View File

@@ -115,7 +115,8 @@ unsigned short mapindex_name2idx(const char* name, const char *func) {
if( (i = strdb_iget(mapindex_db, map_name)) )
return i;
ShowDebug("(%s) mapindex_name2id: Map \"%s\" not found in index list!\n", func, map_name);
if (func)
ShowDebug("(%s) mapindex_name2id: Map \"%s\" not found in index list!\n", func, map_name);
return 0;
}

View File

@@ -504,11 +504,11 @@ ACMD_FUNC(mapmove)
return -1;
}
mapindex = mapindex_name2id(map_name);
mapindex = mapindex_name2idx(map_name, nullptr);
if (mapindex)
m = map_mapindex2mapid(mapindex);
if (!mapindex) { // m < 0 means on different server! [Kevin]
if (m < 0) { // m < 0 means on different server! [Kevin]
clif_displaymessage(fd, msg_txt(sd,1)); // Map not found.
if (battle_config.warp_suggestions_enabled)

View File

@@ -1301,22 +1301,6 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
status_change_end(bl,SC_VOICEOFSIREN,INVALID_TIMER);
}
if( sc->data[SC_DEVOTION] ) {
struct status_change_entry *sce_d = sc->data[SC_DEVOTION];
struct block_list *d_bl = map_id2bl(sce_d->val1);
if( d_bl &&
((d_bl->type == BL_MER && ((TBL_MER*)d_bl)->master && ((TBL_MER*)d_bl)->master->bl.id == bl->id) ||
(d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce_d->val2] == bl->id)) &&
check_distance_bl(bl,d_bl,sce_d->val3) )
{
struct status_change *d_sc = status_get_sc(d_bl);
if( d_sc && d_sc->data[SC_DEFENDER] && (flag&(BF_LONG|BF_MAGIC)) == BF_LONG && skill_id != ASC_BREAKER && skill_id != CR_ACIDDEMONSTRATION && skill_id != NJ_ZENYNAGE && skill_id != GN_FIRE_EXPANSION_ACID && skill_id != KO_MUCHANAGE )
damage -= damage * d_sc->data[SC_DEFENDER]->val2 / 100;
}
}
// Damage reductions
// Assumptio doubles the def & mdef on RE mode, otherwise gives a reduction on the final damage. [Igniz]
#ifndef RENEWAL

View File

@@ -10655,7 +10655,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
if (map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNPC))
npc_touch_areanpc(sd,sd->bl.m,sd->bl.x,sd->bl.y);
else
sd->areanpc_id = 0;
sd->areanpc.clear();
/* it broke at some point (e.g. during a crash), so we make it visibly dead again. */
if( !sd->status.hp && !pc_isdead(sd) && status_isdead(&sd->bl) )

View File

@@ -2642,7 +2642,43 @@ bool map_addnpc(int16 m,struct npc_data *nd)
return false;
}
mapdata->npc[mapdata->npc_num]=nd;
int xs = -1, ys = -1;
switch (nd->subtype) {
case NPCTYPE_WARP:
xs = nd->u.warp.xs;
ys = nd->u.warp.ys;
break;
case NPCTYPE_SCRIPT:
xs = nd->u.scr.xs;
ys = nd->u.scr.ys;
break;
default:
break;
}
// npcs with trigger area are grouped
// 0 < npc_num_warp < npc_num_area < npc_num
if (xs < 0 && ys < 0)
mapdata->npc[ mapdata->npc_num ] = nd;
else {
switch (nd->subtype) {
case NPCTYPE_WARP:
mapdata->npc[ mapdata->npc_num ] = mapdata->npc[ mapdata->npc_num_area ];
mapdata->npc[ mapdata->npc_num_area ] = mapdata->npc[ mapdata->npc_num_warp ];
mapdata->npc[ mapdata->npc_num_warp ] = nd;
mapdata->npc_num_warp++;
mapdata->npc_num_area++;
break;
case NPCTYPE_SCRIPT:
mapdata->npc[ mapdata->npc_num ] = mapdata->npc[ mapdata->npc_num_area ];
mapdata->npc[ mapdata->npc_num_area ] = nd;
mapdata->npc_num_area++;
break;
default:
mapdata->npc[ mapdata->npc_num ] = nd;
break;
}
}
mapdata->npc_num++;
idb_put(id_db,nd->bl.id,nd);
return true;
@@ -2709,6 +2745,8 @@ int map_addinstancemap(const char *name, unsigned short instance_id)
memset(dst_map->npc, 0, sizeof(dst_map->npc));
dst_map->npc_num = 0;
dst_map->npc_num_area = 0;
dst_map->npc_num_warp = 0;
// Reallocate cells
num_cell = dst_map->xs * dst_map->ys;

View File

@@ -726,7 +726,9 @@ struct map_data {
int16 xs,ys; // map dimensions (in cells)
int16 bxs,bys; // map dimensions (in blocks)
int16 bgscore_lion, bgscore_eagle; // Battleground ScoreBoard
int npc_num;
int npc_num; // number total of npc on the map
int npc_num_area; // number of npc with a trigger area on the map
int npc_num_warp; // number of warp npc on the map
int users;
int users_pvp;
int iwall_num; // Total of invisible walls in this map

View File

@@ -169,11 +169,21 @@ int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd)
{
char name[EVENT_NAME_LENGTH];
if (pc_isdead(sd)) // Dead player don't trigger 'OnTouch_'
return 0;
if( nd->touching_id )
return 0; // Attached a player already. Can't trigger on anyone else.
if( pc_ishiding(sd) )
return 1; // Can't trigger 'OnTouch_'. try 'OnTouch' later.
// pc_ishiding moved in npc_event for now.
// If OnTouch_ event exists hiding player doesn't click the npc.
// if( pc_ishiding(sd) )
// return 1; // Can't trigger 'OnTouch_'.
auto it = std::find(sd->npc_ontouch_.begin(), sd->npc_ontouch_.end(), nd->bl.id);
if (it != sd->npc_ontouch_.end())
return 0;
safesnprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_event_name);
return npc_event(sd,name,1);
@@ -182,8 +192,9 @@ int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd)
int npc_ontouch2_event(struct map_session_data *sd, struct npc_data *nd)
{
char name[EVENT_NAME_LENGTH];
auto it = std::find(sd->areanpc.begin(), sd->areanpc.end(), nd->bl.id);
if( sd->areanpc_id == nd->bl.id )
if (it != sd->areanpc.end())
return 0;
safesnprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch2_event_name);
@@ -206,6 +217,7 @@ int npc_enable_sub(struct block_list *bl, va_list ap)
if (nd->sc.option&OPTION_INVISIBLE)
return 1;
// note : disablenpc doesn't reset the previous trigger status on official
if( npc_ontouch_event(sd,nd) > 0 && npc_ontouch2_event(sd,nd) > 0 )
{ // failed to run OnTouch event, so just click the npc
if (sd->npc_id != 0)
@@ -221,14 +233,14 @@ int npc_enable_sub(struct block_list *bl, va_list ap)
/*==========================================
* Disable / Enable NPC
*------------------------------------------*/
int npc_enable(const char* name, int flag)
bool npc_enable(const char* name, int flag)
{
struct npc_data* nd = npc_name2id(name);
if (nd==NULL)
{
ShowError("npc_enable: Attempted to %s a non-existing NPC '%s' (flag=%d).\n", (flag&3) ? "show" : "hide", name, flag);
return 0;
return false;
}
if (flag&1) {
@@ -252,10 +264,10 @@ int npc_enable(const char* name, int flag)
} else
clif_changeoption(&nd->bl);
if( flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0) ) //check if player standing on a OnTouchArea
if( flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0) )// check if player standing on a OnTouchArea
map_foreachinallarea( npc_enable_sub, nd->bl.m, nd->bl.x-nd->u.scr.xs, nd->bl.y-nd->u.scr.ys, nd->bl.x+nd->u.scr.xs, nd->bl.y+nd->u.scr.ys, BL_PC, nd );
return 0;
return true;
}
/*==========================================
@@ -898,18 +910,25 @@ int npc_event(struct map_session_data* sd, const char* eventname, int ontouch)
return ontouch;
}
switch(ontouch)
{
case 1:
if (ontouch == 1) { // OnTouch_
if (pc_ishiding(sd))
return 0;
nd->touching_id = sd->bl.id;
sd->touching_id = nd->bl.id;
break;
case 2:
sd->areanpc_id = nd->bl.id;
break;
auto it = std::find(sd->npc_ontouch_.begin(), sd->npc_ontouch_.end(), nd->bl.id);
if (it == sd->npc_ontouch_.end())
sd->npc_ontouch_.push_back(nd->bl.id);
} else if (ontouch == 2) { // OnTouch
auto it = std::find(sd->areanpc.begin(), sd->areanpc.end(), nd->bl.id);
if (it == sd->areanpc.end())
sd->areanpc.push_back(nd->bl.id);
}
return npc_event_sub(sd,ev,eventname);
npc_event_sub(sd,ev,eventname); // Don't return this value so npc_enable_sub doesn't attempt to "click" the NPC if OnTouch fails.
return 0;
}
/*==========================================
@@ -931,6 +950,8 @@ int npc_touch_areanpc_sub(struct block_list *bl, va_list ap)
return 0;
if( pc_ishiding(sd) )
return 0;
if( pc_isdead(sd) )
return 0;
if( pc_id == sd->bl.id )
return 0;
@@ -945,27 +966,40 @@ int npc_touch_areanpc_sub(struct block_list *bl, va_list ap)
*------------------------------------------*/
int npc_touchnext_areanpc(struct map_session_data* sd, bool leavemap)
{
struct npc_data *nd = map_id2nd(sd->touching_id);
short xs, ys;
if (sd->npc_ontouch_.empty())
return 0;
if( !nd || nd->touching_id != sd->bl.id )
return 1;
bool found = false;
xs = nd->u.scr.xs;
ys = nd->u.scr.ys;
sd->npc_ontouch_.erase(std::remove_if(sd->npc_ontouch_.begin(), sd->npc_ontouch_.end(), [&] (const int &current_npc_id) {
struct npc_data *nd = map_id2nd(current_npc_id);
if( sd->bl.m != nd->bl.m ||
sd->bl.x < nd->bl.x - xs || sd->bl.x > nd->bl.x + xs ||
sd->bl.y < nd->bl.y - ys || sd->bl.y > nd->bl.y + ys ||
pc_ishiding(sd) || leavemap )
{
char name[EVENT_NAME_LENGTH];
if (!nd) {
return true;
} else {
int16 xs = nd->u.scr.xs;
int16 ys = nd->u.scr.ys;
nd->touching_id = sd->touching_id = 0;
safesnprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_event_name);
map_forcountinarea(npc_touch_areanpc_sub,nd->bl.m,nd->bl.x - xs,nd->bl.y - ys,nd->bl.x + xs,nd->bl.y + ys,1,BL_PC,sd->bl.id,name);
}
return 0;
// note : hiding doesn't reset the previous trigger status
// player must leave the area to reset nd->touching_id on official
if (sd->bl.m != nd->bl.m || sd->bl.x < nd->bl.x - xs || sd->bl.x > nd->bl.x + xs || sd->bl.y < nd->bl.y - ys || sd->bl.y > nd->bl.y + ys || leavemap) {
char name[EVENT_NAME_LENGTH];
if (nd->touching_id && nd->touching_id == sd->bl.id) {// empty when reload script
found = true;
nd->touching_id = 0;
safesnprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_event_name);
map_forcountinarea(npc_touch_areanpc_sub,nd->bl.m,nd->bl.x - xs,nd->bl.y - ys,nd->bl.x + xs,nd->bl.y + ys,1,BL_PC,sd->bl.id,name);
}
return true;
}
}
return false;
}), sd->npc_ontouch_.end());
return found;
}
/*==========================================
@@ -973,97 +1007,81 @@ int npc_touchnext_areanpc(struct map_session_data* sd, bool leavemap)
*------------------------------------------*/
int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y)
{
int xs,ys;
int f = 1;
int i;
int j, found_warp = 0;
int xs, ys, i, f = 1;
nullpo_retr(1, sd);
// Why not enqueue it? [Inkfish]
//if(sd->npc_id)
// return 1;
// Remove NPCs that are no longer within the OnTouch area
for (i = 0; i < sd->areanpc.size(); i++) {
struct npc_data *nd = map_id2nd(sd->areanpc[i]);
if (!nd || nd->subtype != NPCTYPE_SCRIPT ||
!(x >= nd->bl.x - nd->u.scr.xs && x <= nd->bl.x + nd->u.scr.xs && y >= nd->bl.y - nd->u.scr.ys && y <= nd->bl.y + nd->u.scr.ys))
sd->areanpc.erase(sd->areanpc.begin() + i);
}
if (sd->state.block_action & PCBLOCK_NPCCLICK)
return 0;
struct map_data *mapdata = map_getmapdata(m);
for(i=0;i<mapdata->npc_num;i++)
{
for (i = 0; i < mapdata->npc_num_area; i++) {
if (mapdata->npc[i]->sc.option&OPTION_INVISIBLE) {
f=0; // a npc was found, but it is disabled; don't print warning
f = 0; // a npc was found, but it is disabled; don't print warning
continue;
}
switch(mapdata->npc[i]->subtype) {
case NPCTYPE_WARP:
xs=mapdata->npc[i]->u.warp.xs;
ys=mapdata->npc[i]->u.warp.ys;
xs = mapdata->npc[i]->u.warp.xs;
ys = mapdata->npc[i]->u.warp.ys;
break;
case NPCTYPE_SCRIPT:
xs=mapdata->npc[i]->u.scr.xs;
ys=mapdata->npc[i]->u.scr.ys;
xs = mapdata->npc[i]->u.scr.xs;
ys = mapdata->npc[i]->u.scr.ys;
break;
default:
continue;
}
if( x >= mapdata->npc[i]->bl.x-xs && x <= mapdata->npc[i]->bl.x+xs
&& y >= mapdata->npc[i]->bl.y-ys && y <= mapdata->npc[i]->bl.y+ys )
break;
}
if( i == mapdata->npc_num )
{
if( f == 1 ) // no npc found
ShowError("npc_touch_areanpc : stray NPC cell/NPC not found in the block on coordinates '%s',%d,%d\n", mapdata->name, x, y);
return 1;
}
switch(mapdata->npc[i]->subtype) {
case NPCTYPE_WARP:
if ((!mapdata->npc[i]->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd))
break; // hidden or dead chars cannot use warps
if (!pc_job_can_entermap((enum e_job)sd->status.class_, map_mapindex2mapid(mapdata->npc[i]->u.warp.mapindex), sd->group_level))
break;
if(sd->count_rewarp > 10){
ShowWarning("Prevented infinite warp loop for player (%d:%d). Please fix NPC: '%s', path: '%s'\n", sd->status.account_id, sd->status.char_id, mapdata->npc[i]->exname, mapdata->npc[i]->path);
sd->count_rewarp=0;
break;
}
pc_setpos(sd,mapdata->npc[i]->u.warp.mapindex,mapdata->npc[i]->u.warp.x,mapdata->npc[i]->u.warp.y,CLR_OUTSIGHT);
break;
case NPCTYPE_SCRIPT:
for (j = i; j < mapdata->npc_num; j++) {
if (mapdata->npc[j]->subtype != NPCTYPE_WARP) {
continue;
}
if ((sd->bl.x >= (mapdata->npc[j]->bl.x - mapdata->npc[j]->u.warp.xs) && sd->bl.x <= (mapdata->npc[j]->bl.x + mapdata->npc[j]->u.warp.xs)) &&
(sd->bl.y >= (mapdata->npc[j]->bl.y - mapdata->npc[j]->u.warp.ys) && sd->bl.y <= (mapdata->npc[j]->bl.y + mapdata->npc[j]->u.warp.ys))) {
if ((!mapdata->npc[i]->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd))
break; // hidden or dead chars cannot use warps
pc_setpos(sd,mapdata->npc[j]->u.warp.mapindex,mapdata->npc[j]->u.warp.x,mapdata->npc[j]->u.warp.y,CLR_OUTSIGHT);
found_warp = 1;
if (x >= mapdata->npc[i]->bl.x - xs && x <= mapdata->npc[i]->bl.x + xs && y >= mapdata->npc[i]->bl.y - ys && y <= mapdata->npc[i]->bl.y + ys) {
f = 0;
switch (mapdata->npc[i]->subtype) {
case NPCTYPE_WARP:
if ((!mapdata->npc[i]->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd))
break; // hidden or dead chars cannot use warps
if (!pc_job_can_entermap((enum e_job)sd->status.class_, map_mapindex2mapid(mapdata->npc[i]->u.warp.mapindex), sd->group_level))
break;
if (sd->count_rewarp > 10) {
ShowWarning("Prevented infinite warp loop for player (%d:%d). Please fix NPC: '%s', path: '%s'\n", sd->status.account_id, sd->status.char_id, mapdata->npc[i]->exname, mapdata->npc[i]->path);
sd->count_rewarp = 0;
break;
}
}
pc_setpos(sd, mapdata->npc[i]->u.warp.mapindex, mapdata->npc[i]->u.warp.x, mapdata->npc[i]->u.warp.y, CLR_OUTSIGHT);
return 0;
case NPCTYPE_SCRIPT:
// warp type sorted first, no need to check if they override any other OnTouch areas.
if (npc_ontouch_event(sd, mapdata->npc[i]) > 0 && npc_ontouch2_event(sd, mapdata->npc[i]) > 0) { // failed to run OnTouch event, so just click the npc
auto it = std::find(sd->areanpc.begin(), sd->areanpc.end(), mapdata->npc[i]->bl.id);
if (it == sd->areanpc.end())
sd->areanpc.push_back(mapdata->npc[i]->bl.id);
npc_click(sd, mapdata->npc[i]);
}
if (found_warp > 0) {
break;
}
if( npc_ontouch_event(sd,mapdata->npc[i]) > 0 && npc_ontouch2_event(sd,mapdata->npc[i]) > 0 )
{ // failed to run OnTouch event, so just click the npc
struct unit_data *ud = unit_bl2ud(&sd->bl);
if( ud && ud->walkpath.path_pos < ud->walkpath.path_len )
{ // Since walktimer always == INVALID_TIMER at this time, we stop walking manually. [Inkfish]
clif_fixpos(&sd->bl);
ud->walkpath.path_pos = ud->walkpath.path_len;
}
sd->areanpc_id = mapdata->npc[i]->bl.id;
npc_click(sd,mapdata->npc[i]);
}
break;
}
}
if (f == 1) {
ShowError("npc_touch_areanpc : stray NPC cell/NPC not found in the block on coordinates '%s',%d,%d\n", mapdata->name, x, y);
return 1;
}
return 0;
}
@@ -1077,7 +1095,7 @@ int npc_touch_areanpc2(struct mob_data *md)
int xs, ys;
struct map_data *mapdata = map_getmapdata(md->bl.m);
for( i = 0; i < mapdata->npc_num; i++ )
for( i = 0; i < mapdata->npc_num_area; i++ )
{
if( mapdata->npc[i]->sc.option&OPTION_INVISIBLE )
continue;
@@ -1166,7 +1184,7 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range)
if (!i) return 0; //No NPC_CELLs.
//Now check for the actual NPC on said range.
for(i=0;i<mapdata->npc_num;i++)
for (i = 0; i < mapdata->npc_num_area; i++)
{
if (mapdata->npc[i]->sc.option&OPTION_INVISIBLE)
continue;
@@ -1193,7 +1211,7 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range)
&& y1 >= mapdata->npc[i]->bl.y-ys && y0 <= mapdata->npc[i]->bl.y+ys )
break; // found a npc
}
if (i==mapdata->npc_num)
if (i == mapdata->npc_num_area)
return 0;
return (mapdata->npc[i]->bl.id);
@@ -2164,8 +2182,21 @@ int npc_remove_map(struct npc_data* nd)
if( i == mapdata->npc_num ) return 2; //failed to find it?
mapdata->npc_num--;
mapdata->npc[i] = mapdata->npc[mapdata->npc_num];
mapdata->npc[mapdata->npc_num] = NULL;
if (i >= mapdata->npc_num_area)
mapdata->npc[i] = mapdata->npc[ mapdata->npc_num ];
else if (i >= mapdata->npc_num_warp) {
mapdata->npc_num_area--;
mapdata->npc[i] = mapdata->npc[ mapdata->npc_num_area ];
mapdata->npc[ mapdata->npc_num_area ] = mapdata->npc[ mapdata->npc_num ];
}
else {
mapdata->npc_num_warp--;
mapdata->npc_num_area--;
mapdata->npc[i] = mapdata->npc[ mapdata->npc_num_warp ];
mapdata->npc[ mapdata->npc_num_warp ] = mapdata->npc[ mapdata->npc_num_area ];
mapdata->npc[ mapdata->npc_num_area ] = mapdata->npc[ mapdata->npc_num ];
}
mapdata->npc[ mapdata->npc_num ] = NULL;
return 0;
}
@@ -2570,7 +2601,6 @@ struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short
struct npc_data *nd;
nd = npc_create_npc(from_mapid, from_x, from_y);
map_addnpc(from_mapid, nd);
safestrncpy(nd->exname, name, ARRAYLENGTH(nd->exname));
if (npc_name2id(nd->exname) != NULL)
@@ -2597,6 +2627,7 @@ struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short
nd->bl.type = BL_NPC;
nd->subtype = NPCTYPE_WARP;
nd->trigger_on_hidden = false;
map_addnpc(from_mapid, nd);
npc_setcells(nd);
if(map_addblock(&nd->bl))
return NULL;
@@ -2654,7 +2685,6 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
}
nd = npc_create_npc(m, x, y);
map_addnpc(m, nd);
npc_parsename(nd, w3, start, buffer, filepath);
if (!battle_config.warp_point_debug)
@@ -2675,6 +2705,7 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const
nd->trigger_on_hidden = true;
else
nd->trigger_on_hidden = false;
map_addnpc(m, nd);
npc_setcells(nd);
if(map_addblock(&nd->bl)) //couldn't add on map
return strchr(start,'\n');
@@ -3376,7 +3407,6 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
}
wnd = npc_create_npc(m, snd->bl.x, snd->bl.y);
map_addnpc(m, wnd);
safestrncpy(wnd->name, "", ARRAYLENGTH(wnd->name));
safestrncpy(wnd->exname, newname, ARRAYLENGTH(wnd->exname));
wnd->class_ = JT_WARPNPC;
@@ -3390,6 +3420,7 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
wnd->subtype = NPCTYPE_WARP;
wnd->trigger_on_hidden = snd->trigger_on_hidden;
wnd->src_id = snd->src_id ? snd->src_id : snd->bl.id;
map_addnpc(m, wnd);
npc_setcells(wnd);
if(map_addblock(&wnd->bl))
return 1;

View File

@@ -1203,7 +1203,7 @@ const char *npc_get_script_event_name(int npce_index);
void npc_setcells(struct npc_data* nd);
void npc_unsetcells(struct npc_data* nd);
bool npc_movenpc(struct npc_data* nd, int16 x, int16 y);
int npc_enable(const char* name, int flag);
bool npc_enable(const char* name, int flag);
void npc_setdisplayname(struct npc_data* nd, const char* newname);
void npc_setclass(struct npc_data* nd, short class_);
struct npc_data* npc_name2id(const char* name);

View File

@@ -2306,7 +2306,7 @@ static void pc_bonus_autospell(std::vector<s_autospell> &spell, short id, short
else {
for (auto &it : spell) {
if ((it.card_id == card_id || it.rate < 0 || rate < 0) && it.id == id && it.lv == lv && it.flag == flag) {
it.rate += rate;
it.rate = cap_value(it.rate + rate, -10000, 10000);
return;
}
}
@@ -2314,9 +2314,12 @@ static void pc_bonus_autospell(std::vector<s_autospell> &spell, short id, short
struct s_autospell entry = {};
if (rate < -10000 || rate > 10000)
ShowWarning("pc_bonus_autospell: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate);
entry.id = id;
entry.lv = lv;
entry.rate = rate;
entry.rate = cap_value(rate, -10000, 10000);
entry.flag = flag;
entry.card_id = card_id;
@@ -2344,10 +2347,13 @@ static void pc_bonus_autospell_onskill(std::vector<s_autospell> &spell, short sr
struct s_autospell entry = {};
if (rate < -10000 || rate > 10000)
ShowWarning("pc_bonus_onskill: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate);
entry.flag = src_skill;
entry.id = id;
entry.lv = lv;
entry.rate = rate;
entry.rate = cap_value(rate, -10000, 10000);
entry.card_id = card_id;
spell.push_back(entry);
@@ -2381,7 +2387,7 @@ static void pc_bonus_addeff(std::vector<s_addeffect> &effect, enum sc_type sc, s
for (auto &it : effect) {
if (it.sc == sc && it.flag == flag) {
it.rate += rate;
it.rate = cap_value(it.rate + rate, -10000, 10000);
it.arrow_rate += arrow_rate;
it.duration = umax(it.duration, duration);
return;
@@ -2390,8 +2396,11 @@ static void pc_bonus_addeff(std::vector<s_addeffect> &effect, enum sc_type sc, s
struct s_addeffect entry = {};
if (rate < -10000 || rate > 10000)
ShowWarning("pc_bonus_addeff: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate);
entry.sc = sc;
entry.rate = rate;
entry.rate = cap_value(rate, -10000, 10000);
entry.arrow_rate = arrow_rate;
entry.flag = flag;
entry.duration = duration;
@@ -2420,7 +2429,7 @@ static void pc_bonus_addeff_onskill(std::vector<s_addeffectonskill> &effect, enu
for (auto &it : effect) {
if (it.sc == sc && it.skill_id == skill_id && it.target == target) {
it.rate += rate;
it.rate = cap_value(it.rate + rate, -10000, 10000);
it.duration = umax(it.duration, duration);
return;
}
@@ -2428,8 +2437,11 @@ static void pc_bonus_addeff_onskill(std::vector<s_addeffectonskill> &effect, enu
struct s_addeffectonskill entry = {};
if (rate < -10000 || rate > 10000)
ShowWarning("pc_bonus_addeff_onskill: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate);
entry.sc = sc;
entry.rate = rate;
entry.rate = cap_value(rate, -10000, 10000);
entry.skill_id = skill_id;
entry.target = target;
entry.duration = duration;
@@ -2484,18 +2496,21 @@ static void pc_bonus_item_drop(std::vector<s_add_drop> &drop, unsigned short nam
for (auto &it : drop) {
if (it.nameid == nameid && it.group == group && it.race == race && it.class_ == class_) {
if ((rate < 0 && it.rate < 0) || (rate > 0 && it.rate > 0)) //Adjust the rate if it has same classification
it.rate += rate;
it.rate = cap_value(it.rate + rate, -10000, 10000);
return;
}
}
struct s_add_drop entry = {};
if (rate < -10000 || rate > 10000)
ShowWarning("pc_bonus_item_drop: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate);
entry.nameid = nameid;
entry.group = group;
entry.race = race;
entry.class_ = class_;
entry.rate = rate;
entry.rate = cap_value(rate, -10000, 10000);
drop.push_back(entry);
}
@@ -2534,7 +2549,10 @@ bool pc_addautobonus(std::vector<s_autobonus> &bonus, const char *script, short
struct s_autobonus entry = {};
entry.rate = rate;
if (rate < -10000 || rate > 10000)
ShowWarning("pc_addautobonus: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate);
entry.rate = cap_value(rate, -10000, 10000);
entry.duration = dur;
entry.active = INVALID_TIMER;
entry.atk_type = flag;
@@ -2679,15 +2697,18 @@ static void pc_bonus_addele(struct map_session_data* sd, unsigned char ele, shor
for (auto &it : wd->addele2) {
if (it.ele == ele && it.flag == flag) {
it.rate += rate;
it.rate = cap_value(it.rate + rate, -10000, 10000);
return;
}
}
struct s_addele2 entry = {};
if (rate < -10000 || rate > 10000)
ShowWarning("pc_bonus_addele: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate);
entry.ele = ele;
entry.rate = rate;
entry.rate = cap_value(rate, -10000, 10000);
entry.flag = flag;
wd->addele2.push_back(entry);
@@ -2722,15 +2743,18 @@ static void pc_bonus_subele(struct map_session_data* sd, unsigned char ele, shor
for (auto &it : sd->subele2) {
if (it.ele == ele && it.flag == flag) {
it.rate += rate;
it.rate = cap_value(it.rate + rate, -10000, 10000);
return;
}
}
struct s_addele2 entry = {};
if (rate < -10000 || rate > 10000)
ShowWarning("pc_bonus_subele: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate);
entry.ele = ele;
entry.rate = rate;
entry.rate = cap_value(rate, -10000, 10000);
entry.flag = flag;
sd->subele2.push_back(entry);
@@ -2746,18 +2770,22 @@ static void pc_bonus_itembonus(std::vector<s_item_bonus> &bonus, uint16 id, int
{
for (auto &it : bonus) {
if (it.id == id) {
it.val += val;
it.val = cap_value(it.val + val, -10000, 10000);
return;
}
}
struct s_item_bonus entry = {};
if (val < -10000 || val > 10000)
ShowWarning("pc_bonus_itembonus: Item bonus val %d exceeds -10000~10000 range, capping.\n", val);
entry.id = id;
entry.val = val;
entry.val = cap_value(val, -10000, 10000);
bonus.push_back(entry);
}
/**
* Remove HP/SP to player when attacking
* @param bonus: Bonus array
@@ -2766,6 +2794,11 @@ static void pc_bonus_itembonus(std::vector<s_item_bonus> &bonus, uint16 id, int
* @param flag: Battle flag
*/
static void pc_bonus_addvanish(std::vector<s_vanish_bonus> &bonus, int16 rate, int16 per, int flag) {
if (bonus.size() == MAX_PC_BONUS) {
ShowWarning("pc_bonus_addvanish: Reached max (%d) number of vanish damage bonuses per character!\n", MAX_PC_BONUS);
return;
}
if (!(flag&BF_RANGEMASK))
flag |= BF_SHORT | BF_LONG;
if (!(flag&BF_WEAPONMASK))
@@ -2779,7 +2812,7 @@ static void pc_bonus_addvanish(std::vector<s_vanish_bonus> &bonus, int16 rate, i
for (auto &it : bonus) {
if (it.flag == flag) {
it.rate += rate;
it.rate = cap_value(it.rate + rate, -10000, 10000);
it.per += per;
return;
}
@@ -2787,7 +2820,10 @@ static void pc_bonus_addvanish(std::vector<s_vanish_bonus> &bonus, int16 rate, i
struct s_vanish_bonus entry = {};
entry.rate = rate;
if (rate < -10000 || rate > 10000)
ShowWarning("pc_bonus_addvanish: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate);
entry.rate = cap_value(rate, -10000, 10000);
entry.per = per;
entry.flag = flag;
@@ -3520,7 +3556,6 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val)
break;
}
val = cap_value(val, -10000, 10000);
pc_bonus_itembonus(sd->reseff, type2, val);
break;
case SP_MAGIC_ADDELE: // bonus2 bMagicAddEle,e,x;

View File

@@ -333,7 +333,8 @@ struct map_session_data {
unsigned short mapindex;
unsigned char head_dir; //0: Look forward. 1: Look right, 2: Look left.
t_tick client_tick;
int npc_id,areanpc_id,npc_shopid,touching_id; //for script follow scriptoid; ,npcid
int npc_id,npc_shopid; //for script follow scriptoid; ,npcid
std::vector<int> areanpc, npc_ontouch_; ///< Array of OnTouch and OnTouch_ NPC ID
int npc_item_flag; //Marks the npc_id with which you can use items during interactions with said npc (see script command enable_itemuse)
int npc_menu; // internal variable, used in npc menu handling
int npc_amount;

View File

@@ -210,8 +210,9 @@ static struct str_data_struct {
int (*func)(struct script_state *st);
int val;
int next;
const char *name;
bool deprecated;
} *str_data = NULL;
} *str_data = nullptr;
static int str_data_size = 0; // size of the data
static int str_num = LABEL_START; // next id to be assigned
@@ -481,13 +482,12 @@ static void script_dump_stack(struct script_state* st)
/// Reports on the console the src of a script error.
static void script_reportsrc(struct script_state *st)
{
struct block_list* bl;
if( st->oid == 0 )
return; //Can't report source.
bl = map_id2bl(st->oid);
if( bl == NULL )
struct block_list* bl = map_id2bl(st->oid);
if (!bl)
return;
switch( bl->type ) {
@@ -1366,6 +1366,8 @@ const char* parse_simpleexpr(const char *p)
if( str_data[l].type == C_INT && str_data[l].deprecated ){
ShowWarning( "Usage of deprecated constant '%s'.\n", get_str(l) );
ShowWarning( "This constant was deprecated and could become unavailable anytime soon.\n" );
if (str_data[l].name)
ShowWarning( "Please use '%s' instead!\n", str_data[l].name );
}
#endif
@@ -2303,6 +2305,8 @@ bool script_get_constant(const char* name, int* value)
if( str_data[n].deprecated ){
ShowWarning( "Usage of deprecated constant '%s'.\n", name );
ShowWarning( "This constant was deprecated and could become unavailable anytime soon.\n" );
if (str_data[n].name)
ShowWarning( "Please use '%s' instead!\n", str_data[n].name );
}
#endif
@@ -2310,7 +2314,7 @@ bool script_get_constant(const char* name, int* value)
}
/// Creates new constant or parameter with given value.
void script_set_constant(const char* name, int value, bool isparameter, bool deprecated)
void script_set_constant_(const char* name, int value, const char* constant_name, bool isparameter, bool deprecated)
{
int n = add_str(name);
@@ -2319,6 +2323,7 @@ void script_set_constant(const char* name, int value, bool isparameter, bool dep
str_data[n].type = isparameter ? C_PARAM : C_INT;
str_data[n].val = value;
str_data[n].deprecated = deprecated;
str_data[n].name = constant_name;
}
else if( str_data[n].type == C_PARAM || str_data[n].type == C_INT )
{// existing parameter or constant
@@ -10353,6 +10358,11 @@ BUILDIN_FUNC(areamonster)
}
}
if (class_ >= 0 && !mobdb_checkid(class_)) {
ShowWarning("buildin_monster: Attempted to spawn non-existing monster class %d\n", class_);
return SCRIPT_CMD_FAILURE;
}
sd = map_id2sd(st->rid);
if (sd && strcmp(mapn, "this") == 0)
@@ -11255,39 +11265,43 @@ BUILDIN_FUNC(getareadropitem)
*------------------------------------------*/
BUILDIN_FUNC(enablenpc)
{
const char *str;
str=script_getstr(st,2);
npc_enable(str,1);
return SCRIPT_CMD_SUCCESS;
const char *str = script_getstr(st,2);
if (npc_enable(str,1))
return SCRIPT_CMD_SUCCESS;
return SCRIPT_CMD_FAILURE;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(disablenpc)
{
const char *str;
str=script_getstr(st,2);
npc_enable(str,0);
return SCRIPT_CMD_SUCCESS;
const char *str = script_getstr(st,2);
if (npc_enable(str,0))
return SCRIPT_CMD_SUCCESS;
return SCRIPT_CMD_FAILURE;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(hideoffnpc)
{
const char *str;
str=script_getstr(st,2);
npc_enable(str,2);
return SCRIPT_CMD_SUCCESS;
const char *str = script_getstr(st,2);
if (npc_enable(str,2))
return SCRIPT_CMD_SUCCESS;
return SCRIPT_CMD_FAILURE;
}
/*==========================================
*------------------------------------------*/
BUILDIN_FUNC(hideonnpc)
{
const char *str;
str=script_getstr(st,2);
npc_enable(str,4);
return SCRIPT_CMD_SUCCESS;
const char *str = script_getstr(st,2);
if (npc_enable(str,4))
return SCRIPT_CMD_SUCCESS;
return SCRIPT_CMD_FAILURE;
}
/* Starts a status effect on the target unit or on the attached player.
@@ -17756,7 +17770,7 @@ BUILDIN_FUNC(setunitdata)
switch (type) {
case UMOB_SIZE: md->status.size = md->base_status->size = (unsigned char)value; break;
case UMOB_LEVEL: md->level = (unsigned short)value; break;
case UMOB_LEVEL: md->level = (unsigned short)value; clif_name_area(&md->bl); break;
case UMOB_HP: md->base_status->hp = (unsigned int)value; status_set_hp(bl, (unsigned int)value, 0); clif_name_area(&md->bl); break;
case UMOB_MAXHP: md->base_status->hp = md->base_status->max_hp = (unsigned int)value; status_set_maxhp(bl, (unsigned int)value, 0); clif_name_area(&md->bl); break;
case UMOB_MASTERAID: md->master_id = value; break;
@@ -17909,7 +17923,7 @@ BUILDIN_FUNC(setunitdata)
case UPET_MAPID: if (mapname) value = map_mapname2mapid(mapname); unit_warp(bl, (short)value, 0, 0, CLR_TELEPORT); break;
case UPET_X: if (!unit_walktoxy(bl, (short)value, pd->bl.y, 2)) unit_movepos(bl, (short)value, md->bl.y, 0, 0); break;
case UPET_Y: if (!unit_walktoxy(bl, pd->bl.x, (short)value, 2)) unit_movepos(bl, pd->bl.x, (short)value, 0, 0); break;
case UPET_HUNGER: pd->pet.hungry = (short)value; clif_send_petdata(map_id2sd(pd->pet.account_id), pd, 2, pd->pet.hungry); break;
case UPET_HUNGER: pd->pet.hungry = cap_value((short)value, 0, 100); clif_send_petdata(map_id2sd(pd->pet.account_id), pd, 2, pd->pet.hungry); break;
case UPET_INTIMACY: pet_set_intimate(pd, (unsigned int)value); clif_send_petdata(map_id2sd(pd->pet.account_id), pd, 1, pd->pet.intimate); break;
case UPET_SPEED: pd->status.speed = (unsigned short)value; status_calc_misc(bl, &pd->status, pd->pet.level); break;
case UPET_LOOKDIR: unit_setdir(bl, (uint8)value); break;

View File

@@ -1959,7 +1959,8 @@ void script_run_autobonus(const char *autobonus, struct map_session_data *sd, un
const char* script_get_constant_str(const char* prefix, int64 value);
bool script_get_parameter(const char* name, int* value);
bool script_get_constant(const char* name, int* value);
void script_set_constant(const char* name, int value, bool isparameter, bool deprecated);
void script_set_constant_(const char* name, int value, const char* constant_name, bool isparameter, bool deprecated);
#define script_set_constant(name, value, isparameter, deprecated) script_set_constant_(name, value, NULL, isparameter, deprecated)
void script_hardcoded_constants(void);
void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value);

View File

@@ -10,6 +10,7 @@
#define export_parameter(a,b) script_set_constant(a,b,true,false)
#define export_deprecated_constant(a) script_set_constant(#a,a,false,true)
#define export_deprecated_constant2(a,b) script_set_constant(a,b,false,true)
#define export_deprecated_constant3(a,b,c) script_set_constant_(a,b,c,false,true)
/* min and maximum variable value */
export_constant(INT_MIN);
@@ -420,7 +421,7 @@
export_constant(MF_NORETURN);
export_constant(MF_NOWARPTO);
export_constant(MF_PVP_NIGHTMAREDROP);
script_set_constant("mf_nightmaredrop",MF_PVP_NIGHTMAREDROP,false,true);
export_deprecated_constant3("mf_nightmaredrop", MF_PVP_NIGHTMAREDROP, "MF_PVP_NIGHTMAREDROP");
export_constant(MF_RESTRICTED);
export_constant(MF_NOCOMMAND);
export_constant(MF_NODROP);
@@ -442,7 +443,7 @@
export_constant(MF_NOUSECART);
export_constant(MF_NOITEMCONSUMPTION);
export_constant(MF_NOSUNMOONSTARMIRACLE);
script_set_constant("mf_sumstarmiracle",MF_NOSUNMOONSTARMIRACLE,false,true);
export_deprecated_constant3("mf_sumstarmiracle", MF_NOSUNMOONSTARMIRACLE, "MF_NOSUNMOONSTARMIRACLE");
export_constant(MF_NOMINEEFFECT);
export_constant(MF_NOLOCKON);
export_constant(MF_NOTOMB);
@@ -3413,11 +3414,15 @@
export_constant(EFST_BASILICA_BUFF);
export_constant(EFST_OVERLAPEXPUP2);
export_constant(EFST_SOULCURSE);
export_constant(EFST_SOUND_OF_DESTRUCTION);
export_constant(EFST_NV_BREAKTHROUGH);
export_constant(EFST_HELPANGEL);
export_constant(EFST_NV_TRANSCENDENCE);
export_constant(EFST_SWEETSFAIR_ATK);
export_constant(EFST_SWEETSFAIR_MATK);
export_constant(EFST_FLOWER_LEAF2);
export_constant(EFST_FLOWER_LEAF3);
export_constant(EFST_FLOWER_LEAF4);
/// @APIHOOK_END
/// Do not modify code above this, since it will be automatically generated by the API again
export_constant(EFST_MAX);
@@ -3604,94 +3609,94 @@
export_constant(ET_YUT7);
/* emoticons deprecated */
script_set_constant("E_GASP",ET_SURPRISE,false,true);
script_set_constant("E_WHAT",ET_QUESTION,false,true);
script_set_constant("E_HO",ET_DELIGHT,false,true);
script_set_constant("E_LV",ET_THROB,false,true);
script_set_constant("E_SWT",ET_SWEAT,false,true);
script_set_constant("E_IC",ET_AHA,false,true);
script_set_constant("E_AN",ET_FRET,false,true);
script_set_constant("E_AG",ET_ANGER,false,true);
script_set_constant("E_CASH",ET_MONEY,false,true);
script_set_constant("E_DOTS",ET_THINK,false,true);
script_set_constant("E_SCISSORS",ET_SCISSOR,false,true);
script_set_constant("E_ROCK",ET_ROCK,false,true);
script_set_constant("E_PAPER",ET_WRAP,false,true);
script_set_constant("E_KOREA",ET_FLAG,false,true);
script_set_constant("E_LV2",ET_BIGTHROB,false,true);
script_set_constant("E_THX",ET_THANKS,false,true);
script_set_constant("E_WAH",ET_KEK,false,true);
script_set_constant("E_SRY",ET_SORRY,false,true);
script_set_constant("E_HEH",ET_SMILE,false,true);
script_set_constant("E_SWT2",ET_PROFUSELY_SWEAT,false,true);
script_set_constant("E_HMM",ET_SCRATCH,false,true);
script_set_constant("E_NO1",ET_BEST,false,true);
script_set_constant("E_NO",ET_STARE_ABOUT,false,true);
script_set_constant("E_OMG",ET_HUK,false,true);
script_set_constant("E_OH",ET_O,false,true);
script_set_constant("E_X",ET_X,false,true);
script_set_constant("E_HLP",ET_HELP,false,true);
script_set_constant("E_GO",ET_GO,false,true);
script_set_constant("E_SOB",ET_CRY,false,true);
script_set_constant("E_GG",ET_KIK,false,true);
script_set_constant("E_KIS",ET_CHUP,false,true);
script_set_constant("E_KIS2",ET_CHUPCHUP,false,true);
script_set_constant("E_PIF",ET_HNG,false,true);
script_set_constant("E_OK",ET_OK,false,true);
script_set_constant("E_MUTE",ET_CHAT_PROHIBIT,false,true);
script_set_constant("E_INDONESIA",ET_INDONESIA_FLAG,false,true);
script_set_constant("E_BZZ",ET_STARE,false,true);
script_set_constant("E_RICE",ET_HUNGRY,false,true);
script_set_constant("E_AWSM",ET_COOL,false,true);
script_set_constant("E_MEH",ET_MERONG,false,true);
script_set_constant("E_SHY",ET_SHY,false,true);
script_set_constant("E_PAT",ET_GOODBOY,false,true);
script_set_constant("E_MP",ET_SPTIME,false,true);
script_set_constant("E_SLUR",ET_SEXY,false,true);
script_set_constant("E_COM",ET_COMEON,false,true);
script_set_constant("E_YAWN",ET_SLEEPY,false,true);
script_set_constant("E_GRAT",ET_CONGRATULATION,false,true);
script_set_constant("E_HP",ET_HPTIME,false,true);
script_set_constant("E_PHILIPPINES",ET_PH_FLAG,false,true);
script_set_constant("E_MALAYSIA",ET_MY_FLAG,false,true);
script_set_constant("E_SINGAPORE",ET_SI_FLAG,false,true);
script_set_constant("E_BRAZIL",ET_BR_FLAG,false,true);
script_set_constant("E_FLASH",ET_SPARK,false,true);
script_set_constant("E_SPIN",ET_CONFUSE,false,true);
script_set_constant("E_SIGH",ET_OHNO,false,true);
script_set_constant("E_DUM",ET_HUM,false,true);
script_set_constant("E_LOUD",ET_BLABLA,false,true);
script_set_constant("E_OTL",ET_OTL,false,true);
script_set_constant("E_DICE1",ET_DICE1,false,true);
script_set_constant("E_DICE2",ET_DICE2,false,true);
script_set_constant("E_DICE3",ET_DICE3,false,true);
script_set_constant("E_DICE4",ET_DICE4,false,true);
script_set_constant("E_DICE5",ET_DICE5,false,true);
script_set_constant("E_DICE6",ET_DICE6,false,true);
script_set_constant("E_INDIA",ET_INDIA_FLAG,false,true);
script_set_constant("E_LUV",ET_LUV,false,true);
script_set_constant("E_RUSSIA",ET_FLAG8,false,true);
script_set_constant("E_VIRGIN",ET_FLAG9,false,true);
script_set_constant("E_MOBILE",ET_MOBILE,false,true);
script_set_constant("E_MAIL",ET_MAIL,false,true);
script_set_constant("E_CHINESE",ET_ANTENNA0,false,true);
script_set_constant("E_ANTENNA1",ET_ANTENNA1,false,true);
script_set_constant("E_ANTENNA2",ET_ANTENNA2,false,true);
script_set_constant("E_ANTENNA3",ET_ANTENNA3,false,true);
script_set_constant("E_HUM",ET_HUM2,false,true);
script_set_constant("E_ABS",ET_ABS,false,true);
script_set_constant("E_OOPS",ET_OOPS,false,true);
script_set_constant("E_SPIT",ET_SPIT,false,true);
script_set_constant("E_ENE",ET_ENE,false,true);
script_set_constant("E_PANIC",ET_PANIC,false,true);
script_set_constant("E_WHISP",ET_WHISP,false,true);
script_set_constant("E_YUT1",ET_YUT1,false,true);
script_set_constant("E_YUT2",ET_YUT2,false,true);
script_set_constant("E_YUT3",ET_YUT3,false,true);
script_set_constant("E_YUT4",ET_YUT4,false,true);
script_set_constant("E_YUT5",ET_YUT5,false,true);
script_set_constant("E_YUT6",ET_YUT6,false,true);
script_set_constant("E_YUT7",ET_YUT7,false,true);
export_deprecated_constant3("E_GASP", ET_SURPRISE, "ET_SURPRISE");
export_deprecated_constant3("E_WHAT", ET_QUESTION, "ET_QUESTION");
export_deprecated_constant3("E_HO", ET_DELIGHT, "ET_DELIGHT");
export_deprecated_constant3("E_LV", ET_THROB, "ET_THROB");
export_deprecated_constant3("E_SWT", ET_SWEAT, "ET_SWEAT");
export_deprecated_constant3("E_IC", ET_AHA, "ET_AHA");
export_deprecated_constant3("E_AN", ET_FRET, "ET_FRET");
export_deprecated_constant3("E_AG", ET_ANGER, "ET_ANGER");
export_deprecated_constant3("E_CASH", ET_MONEY, "ET_MONEY");
export_deprecated_constant3("E_DOTS", ET_THINK, "ET_THINK");
export_deprecated_constant3("E_SCISSORS", ET_SCISSOR, "ET_SCISSOR");
export_deprecated_constant3("E_ROCK", ET_ROCK, "ET_ROCK");
export_deprecated_constant3("E_PAPER", ET_WRAP, "ET_WRAP");
export_deprecated_constant3("E_KOREA", ET_FLAG, "ET_FLAG");
export_deprecated_constant3("E_LV2", ET_BIGTHROB, "ET_BIGTHROB");
export_deprecated_constant3("E_THX", ET_THANKS, "ET_THANKS");
export_deprecated_constant3("E_WAH", ET_KEK, "ET_KEK");
export_deprecated_constant3("E_SRY", ET_SORRY, "ET_SORRY");
export_deprecated_constant3("E_HEH", ET_SMILE, "ET_SMILE");
export_deprecated_constant3("E_SWT2", ET_PROFUSELY_SWEAT, "ET_PROFUSELY_SWEAT");
export_deprecated_constant3("E_HMM", ET_SCRATCH, "ET_SCRATCH");
export_deprecated_constant3("E_NO1", ET_BEST, "ET_BEST");
export_deprecated_constant3("E_NO", ET_STARE_ABOUT, "ET_STARE_ABOUT");
export_deprecated_constant3("E_OMG", ET_HUK, "ET_HUK");
export_deprecated_constant3("E_OH", ET_O, "ET_O");
export_deprecated_constant3("E_X", ET_X, "ET_X");
export_deprecated_constant3("E_HLP", ET_HELP, "ET_HELP");
export_deprecated_constant3("E_GO", ET_GO, "ET_GO");
export_deprecated_constant3("E_SOB", ET_CRY, "ET_CRY");
export_deprecated_constant3("E_GG", ET_KIK, "ET_KIK");
export_deprecated_constant3("E_KIS", ET_CHUP, "ET_CHUP");
export_deprecated_constant3("E_KIS2", ET_CHUPCHUP, "ET_CHUPCHUP");
export_deprecated_constant3("E_PIF", ET_HNG, "ET_HNG");
export_deprecated_constant3("E_OK", ET_OK, "ET_OK");
export_deprecated_constant3("E_MUTE", ET_CHAT_PROHIBIT, "ET_CHAT_PROHIBIT");
export_deprecated_constant3("E_INDONESIA", ET_INDONESIA_FLAG, "ET_INDONESIA_FLAG");
export_deprecated_constant3("E_BZZ", ET_STARE, "ET_STARE");
export_deprecated_constant3("E_RICE", ET_HUNGRY, "ET_HUNGRY");
export_deprecated_constant3("E_AWSM", ET_COOL, "ET_COOL");
export_deprecated_constant3("E_MEH", ET_MERONG, "ET_MERONG");
export_deprecated_constant3("E_SHY", ET_SHY, "ET_SHY");
export_deprecated_constant3("E_PAT", ET_GOODBOY, "ET_GOODBOY");
export_deprecated_constant3("E_MP", ET_SPTIME, "ET_SPTIME");
export_deprecated_constant3("E_SLUR", ET_SEXY, "ET_SEXY");
export_deprecated_constant3("E_COM", ET_COMEON, "ET_COMEON");
export_deprecated_constant3("E_YAWN", ET_SLEEPY, "ET_SLEEPY");
export_deprecated_constant3("E_GRAT", ET_CONGRATULATION, "ET_CONGRATULATION");
export_deprecated_constant3("E_HP", ET_HPTIME, "ET_HPTIME");
export_deprecated_constant3("E_PHILIPPINES", ET_PH_FLAG, "ET_PH_FLAG");
export_deprecated_constant3("E_MALAYSIA", ET_MY_FLAG, "ET_MY_FLAG");
export_deprecated_constant3("E_SINGAPORE", ET_SI_FLAG, "ET_SI_FLAG");
export_deprecated_constant3("E_BRAZIL", ET_BR_FLAG, "ET_BR_FLAG");
export_deprecated_constant3("E_FLASH", ET_SPARK, "ET_SPARK");
export_deprecated_constant3("E_SPIN", ET_CONFUSE, "ET_CONFUSE");
export_deprecated_constant3("E_SIGH", ET_OHNO, "ET_OHNO");
export_deprecated_constant3("E_DUM", ET_HUM, "ET_HUM");
export_deprecated_constant3("E_LOUD", ET_BLABLA, "ET_BLABLA");
export_deprecated_constant3("E_OTL", ET_OTL, "ET_OTL");
export_deprecated_constant3("E_DICE1", ET_DICE1, "ET_DICE1");
export_deprecated_constant3("E_DICE2", ET_DICE2, "ET_DICE2");
export_deprecated_constant3("E_DICE3", ET_DICE3, "ET_DICE3");
export_deprecated_constant3("E_DICE4", ET_DICE4, "ET_DICE4");
export_deprecated_constant3("E_DICE5", ET_DICE5, "ET_DICE5");
export_deprecated_constant3("E_DICE6", ET_DICE6, "ET_DICE6");
export_deprecated_constant3("E_INDIA", ET_INDIA_FLAG, "ET_INDIA_FLAG");
export_deprecated_constant3("E_LUV", ET_LUV, "ET_LUV");
export_deprecated_constant3("E_RUSSIA", ET_FLAG8, "ET_FLAG8");
export_deprecated_constant3("E_VIRGIN", ET_FLAG9, "ET_FLAG9");
export_deprecated_constant3("E_MOBILE", ET_MOBILE, "ET_MOBILE");
export_deprecated_constant3("E_MAIL", ET_MAIL, "ET_MAIL");
export_deprecated_constant3("E_CHINESE", ET_ANTENNA0, "ET_ANTENNA0");
export_deprecated_constant3("E_ANTENNA1", ET_ANTENNA1, "ET_ANTENNA1");
export_deprecated_constant3("E_ANTENNA2", ET_ANTENNA2, "ET_ANTENNA2");
export_deprecated_constant3("E_ANTENNA3", ET_ANTENNA3, "ET_ANTENNA3");
export_deprecated_constant3("E_HUM", ET_HUM2, "ET_HUM2");
export_deprecated_constant3("E_ABS", ET_ABS, "ET_ABS");
export_deprecated_constant3("E_OOPS", ET_OOPS, "ET_OOPS");
export_deprecated_constant3("E_SPIT", ET_SPIT, "ET_SPIT");
export_deprecated_constant3("E_ENE", ET_ENE, "ET_ENE");
export_deprecated_constant3("E_PANIC", ET_PANIC, "ET_PANIC");
export_deprecated_constant3("E_WHISP", ET_WHISP, "ET_WHISP");
export_deprecated_constant3("E_YUT1", ET_YUT1, "ET_YUT1");
export_deprecated_constant3("E_YUT2", ET_YUT2, "ET_YUT2");
export_deprecated_constant3("E_YUT3", ET_YUT3, "ET_YUT3");
export_deprecated_constant3("E_YUT4", ET_YUT4, "ET_YUT4");
export_deprecated_constant3("E_YUT5", ET_YUT5, "ET_YUT5");
export_deprecated_constant3("E_YUT6", ET_YUT6, "ET_YUT6");
export_deprecated_constant3("E_YUT7", ET_YUT7, "ET_YUT7");
/* send targets */
export_constant(ALL_CLIENT);
@@ -3938,13 +3943,13 @@
/* unit control - types */
/* Send deprecation notice and temporarily replace with new constant value. */
export_deprecated_constant2("UNITTYPE_PC", BL_PC);
export_deprecated_constant2("UNITTYPE_NPC", BL_NPC);
export_deprecated_constant2("UNITTYPE_PET", BL_PET);
export_deprecated_constant2("UNITTYPE_MOB", BL_MOB);
export_deprecated_constant2("UNITTYPE_HOM", BL_HOM);
export_deprecated_constant2("UNITTYPE_MER", BL_MER);
export_deprecated_constant2("UNITTYPE_ELEM", BL_ELEM);
export_deprecated_constant3("UNITTYPE_PC", BL_PC, "BL_PC");
export_deprecated_constant3("UNITTYPE_NPC", BL_NPC, "BL_NPC");
export_deprecated_constant3("UNITTYPE_PET", BL_PET, "BL_PET");
export_deprecated_constant3("UNITTYPE_MOB", BL_MOB, "BL_MOB");
export_deprecated_constant3("UNITTYPE_HOM", BL_HOM, "BL_HOM");
export_deprecated_constant3("UNITTYPE_MER", BL_MER, "BL_MER");
export_deprecated_constant3("UNITTYPE_ELEM", BL_ELEM, "BL_ELEM");
/* unit control - mob */
export_constant(UMOB_SIZE);

View File

@@ -434,6 +434,50 @@ unsigned short skill_dummy2skill_id(unsigned short skill_id) {
return skill_id;
}
/**
* Check skill unit maxcount
* @param src: Caster to check against
* @param x: X location of skill
* @param y: Y location of skill
* @param skill_id: Skill used
* @param skill_lv: Skill level used
* @param type: Type of unit to check against for battle_config checks
* @param display_failure: Display skill failure message
* @return True on skill cast success or false on failure
*/
bool skill_pos_maxcount_check(struct block_list *src, int16 x, int16 y, uint16 skill_id, uint16 skill_lv, enum bl_type type, bool display_failure) {
if (!src)
return false;
struct unit_data *ud = unit_bl2ud(src);
struct map_session_data *sd = map_id2sd(src->id);
int maxcount = 0;
if (!(type&battle_config.skill_reiteration) && skill_get_unit_flag(skill_id)&UF_NOREITERATION && skill_check_unit_range(src, x, y, skill_id, skill_lv)) {
if (sd && display_failure)
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
return false;
}
if (type&battle_config.skill_nofootset && skill_get_unit_flag(skill_id)&UF_NOFOOTSET && skill_check_unit_range2(src, x, y, skill_id, skill_lv, false)) {
if (sd && display_failure)
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
return false;
}
if (type&battle_config.land_skill_limit && (maxcount = skill_get_maxcount(skill_id, skill_lv)) > 0) {
for (int i = 0; i < MAX_SKILLUNITGROUP && ud->skillunit[i] && maxcount; i++) {
if (ud->skillunit[i]->skill_id == skill_id)
maxcount--;
}
if (maxcount == 0) {
if (sd && display_failure)
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
return false;
}
}
return true;
}
/**
* Calculates heal value of skill's effect
* @param src: Unit casting heal
@@ -649,7 +693,7 @@ static int8 skill_isCopyable(struct map_session_data *sd, uint16 skill_idx) {
/**
* Check if the skill is ok to cast and when.
* Done before check_condition_begin, requirement
* Done before skill_check_condition_castbegin, requirement
* @param skill_id: Skill ID that casted
* @param sd: Player who casted
* @return true: Skill cannot be used, false: otherwise
@@ -2106,29 +2150,9 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
tbl = (it.id < 0) ? src : bl;
if( (type = skill_get_casttype(skill)) == CAST_GROUND ) {
int maxcount = 0;
if( !(BL_PC&battle_config.skill_reiteration) &&
skill_get_unit_flag(skill)&UF_NOREITERATION &&
skill_check_unit_range(src,tbl->x,tbl->y,skill,autospl_skill_lv)
)
if ((type = skill_get_casttype(skill)) == CAST_GROUND) {
if (!skill_pos_maxcount_check(src, tbl->x, tbl->y, skill, autospl_skill_lv, BL_PC, false))
continue;
if( BL_PC&battle_config.skill_nofootset &&
skill_get_unit_flag(skill)&UF_NOFOOTSET &&
skill_check_unit_range2(src,tbl->x,tbl->y,skill,autospl_skill_lv,false)
)
continue;
if( BL_PC&battle_config.land_skill_limit &&
(maxcount = skill_get_maxcount(skill, autospl_skill_lv)) > 0
) {
int v;
for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) {
if(sd->ud.skillunit[v]->skill_id == skill)
maxcount--;
}
if( maxcount == 0 )
continue;
}
}
if (battle_config.autospell_check_range &&
!battle_check_range(bl, tbl, skill_get_range2(src, skill, autospl_skill_lv, true)))
@@ -2233,27 +2257,9 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint1
else
tbl = bl;
if( (type = skill_get_casttype(skill)) == CAST_GROUND ) {
int maxcount = 0;
if( !(BL_PC&battle_config.skill_reiteration) &&
skill_get_unit_flag(skill)&UF_NOREITERATION &&
skill_check_unit_range(&sd->bl,tbl->x,tbl->y,skill,skill_lv) )
if ((type = skill_get_casttype(skill)) == CAST_GROUND) {
if (!skill_pos_maxcount_check(&sd->bl, tbl->x, tbl->y, skill_id, skill_lv, BL_PC, false))
continue;
if( BL_PC&battle_config.skill_nofootset &&
skill_get_unit_flag(skill)&UF_NOFOOTSET &&
skill_check_unit_range2(&sd->bl,tbl->x,tbl->y,skill,skill_lv,false) )
continue;
if( BL_PC&battle_config.land_skill_limit &&
(maxcount = skill_get_maxcount(skill, skill_lv)) > 0 )
{
int v;
for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) {
if(sd->ud.skillunit[v]->skill_id == skill)
maxcount--;
}
if( maxcount == 0 )
continue;
}
}
if (battle_config.autospell_check_range &&
!battle_check_range(bl, tbl, skill_get_range2(&sd->bl, skill, skill_lv, true)))
@@ -2443,30 +2449,9 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
continue;
tbl = (it.id < 0) ? bl : src;
if( (type = skill_get_casttype(autospl_skill_id)) == CAST_GROUND ) {
int maxcount = 0;
if( !(BL_PC&battle_config.skill_reiteration) &&
skill_get_unit_flag(autospl_skill_id)&UF_NOREITERATION &&
skill_check_unit_range(bl,tbl->x,tbl->y,autospl_skill_id,autospl_skill_lv)
)
if ((type = skill_get_casttype(autospl_skill_id)) == CAST_GROUND) {
if (!skill_pos_maxcount_check(bl, tbl->x, tbl->y, autospl_skill_id, autospl_skill_lv, BL_PC, false))
continue;
if( BL_PC&battle_config.skill_nofootset &&
skill_get_unit_flag(autospl_skill_id)&UF_NOFOOTSET &&
skill_check_unit_range2(bl,tbl->x,tbl->y,autospl_skill_id,autospl_skill_lv,false)
)
continue;
if( BL_PC&battle_config.land_skill_limit &&
(maxcount = skill_get_maxcount(autospl_skill_id, autospl_skill_lv)) > 0
) {
int v;
for(v=0;v<MAX_SKILLUNITGROUP && dstsd->ud.skillunit[v] && maxcount;v++) {
if(dstsd->ud.skillunit[v]->skill_id == autospl_skill_id)
maxcount--;
}
if( maxcount == 0 ) {
continue;
}
}
}
if (!battle_check_range(bl, tbl, skill_get_range2(src, autospl_skill_id, autospl_skill_lv, true)) && battle_config.autospell_check_range)
@@ -11576,39 +11561,11 @@ TIMER_FUNC(skill_castend_pos){
ud->skilltimer = INVALID_TIMER;
do {
int maxcount=0;
if( status_isdead(src) )
break;
if( !(src->type&battle_config.skill_reiteration) &&
skill_get_unit_flag(ud->skill_id)&UF_NOREITERATION &&
skill_check_unit_range(src,ud->skillx,ud->skilly,ud->skill_id,ud->skill_lv)
)
{
if (sd) clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
if (!skill_pos_maxcount_check(src, ud->skillx, ud->skilly, ud->skill_id, ud->skill_lv, src->type, true))
break;
}
if( skill_get_unit_flag(ud->skill_id)&UF_NOFOOTSET &&
skill_check_unit_range2(src,ud->skillx,ud->skilly,ud->skill_id,ud->skill_lv,false)
)
{
if (sd) clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
if( src->type&battle_config.land_skill_limit &&
(maxcount = skill_get_maxcount(ud->skill_id, ud->skill_lv)) > 0
) {
int i;
for(i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i] && maxcount;i++) {
if(ud->skillunit[i]->skill_id == ud->skill_id)
maxcount--;
}
if( maxcount == 0 )
{
if (sd) clif_skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
}
if(tid != INVALID_TIMER)
{ //Avoid double checks on instant cast skills. [Skotlex]

View File

@@ -487,6 +487,7 @@ int skill_check_condition_char_sub (struct block_list *bl, va_list ap);
void skill_consume_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type);
struct skill_condition skill_get_requirement(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv);
int skill_disable_check(struct status_change *sc, uint16 skill_id);
bool skill_pos_maxcount_check(struct block_list *src, int16 x, int16 y, uint16 skill_id, uint16 skill_lv, enum bl_type type, bool display_failure);
int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint16 *skill_lv, int range, int cast_flag);
int skill_unit_move(struct block_list *bl,t_tick tick,int flag);

View File

@@ -7925,8 +7925,14 @@ void status_set_viewdata(struct block_list *bl, int class_)
TBL_NPC* nd = (TBL_NPC*)bl;
if (vd)
nd->vd = vd;
else
else {
ShowError("status_set_viewdata (NPC): No view data for class %d\n", class_);
if (bl->m >= 0)
ShowDebug("Source (NPC): %s at %s (%d,%d)\n", nd->name, map_mapid2mapname(bl->m), bl->x, bl->y);
else
ShowDebug("Source (NPC): %s (invisible/not on a map)\n", nd->name);
break;
}
}
break;
case BL_HOM:
@@ -10069,7 +10075,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
while( i >= 0 ) {
enum sc_type type2 = types[i];
if( d_sc->data[type2] )
status_change_start(d_bl, bl, type2, 10000, d_sc->data[type2]->val1, 0, 0, (type2 == SC_REFLECTSHIELD ? 1 : 0), skill_get_time(status_sc2skill(type2),d_sc->data[type2]->val1), (type2 == SC_DEFENDER) ? 1 : SCSTART_NOAVOID|SCSTART_NOICON);
status_change_start(d_bl, bl, type2, 10000, d_sc->data[type2]->val1, 0, 0, (type2 == SC_REFLECTSHIELD ? 1 : 0), skill_get_time(status_sc2skill(type2),d_sc->data[type2]->val1), (type2 == SC_DEFENDER) ? SCSTART_NOAVOID : SCSTART_NOAVOID|SCSTART_NOICON);
i--;
}
}
@@ -11851,7 +11857,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
break;
}
if( opt_flag&2 && sd && sd->touching_id )
if( opt_flag&2 && sd && !sd->npc_ontouch_.empty() )
npc_touchnext_areanpc(sd,false); // Run OnTouch_ on next char in range
return 1;

View File

@@ -1936,12 +1936,17 @@ enum efst_types : short{
EFST_OVERLAPEXPUP2,
EFST_SOULCURSE = 1125,
EFST_SOUND_OF_DESTRUCTION,
EFST_NV_BREAKTHROUGH = 1129,
EFST_HELPANGEL,
EFST_NV_TRANSCENDENCE,
EFST_SWEETSFAIR_ATK,
EFST_SWEETSFAIR_MATK,
EFST_FLOWER_LEAF2 = 1135,
EFST_FLOWER_LEAF3,
EFST_FLOWER_LEAF4,
/// @APIHOOK_END
/// Do not modify code above this, since it will be automatically generated by the API again
EFST_MAX,

View File

@@ -444,14 +444,14 @@ static TIMER_FUNC(unit_walktoxy_timer){
switch(bl->type) {
case BL_PC:
if( sd->touching_id )
if( !sd->npc_ontouch_.empty() )
npc_touchnext_areanpc(sd,false);
if(map_getcell(bl->m,x,y,CELL_CHKNPC)) {
npc_touch_areanpc(sd,bl->m,x,y);
if (bl->prev == NULL) // Script could have warped char, abort remaining of the function.
return 0;
} else
sd->areanpc_id=0;
sd->areanpc.clear();
pc_cell_basilica(sd);
break;
case BL_MOB:
@@ -971,7 +971,7 @@ bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, boo
ud->walktimer = INVALID_TIMER;
if(sd) {
if( sd->touching_id )
if( !sd->npc_ontouch_.empty() )
npc_touchnext_areanpc(sd,false);
if(map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC)) {
@@ -980,7 +980,7 @@ bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, boo
if (bl->prev == NULL) // Script could have warped char, abort remaining of the function.
return false;
} else
sd->areanpc_id=0;
sd->areanpc.clear();
if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > PET_INTIMATE_NONE ) {
// Check if pet needs to be teleported. [Skotlex]
@@ -1102,13 +1102,13 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, enum e_skill_bl
clif_blown(bl);
if(sd) {
if(sd->touching_id)
if(!sd->npc_ontouch_.empty())
npc_touchnext_areanpc(sd, false);
if(map_getcell(bl->m, bl->x, bl->y, CELL_CHKNPC))
npc_touch_areanpc(sd, bl->m, bl->x, bl->y);
else
sd->areanpc_id = 0;
sd->areanpc.clear();
}
}
@@ -1998,6 +1998,8 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
if( sd ) {
if( skill_isNotOk(skill_id, sd) || !skill_check_condition_castbegin(sd, skill_id, skill_lv) )
return 0;
if (skill_id == MG_FIREWALL && !skill_pos_maxcount_check(src, skill_x, skill_y, skill_id, skill_lv, BL_PC, true))
return 0; // Special check for Firewall only
}
if( (skill_id >= SC_MANHOLE && skill_id <= SC_FEINTBOMB) && map_getcell(src->m, skill_x, skill_y, CELL_CHKMAELSTROM) ) {
@@ -2955,7 +2957,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
if(sd->menuskill_id)
sd->menuskill_id = sd->menuskill_val = 0;
if( sd->touching_id )
if( !sd->npc_ontouch_.empty() )
npc_touchnext_areanpc(sd,true);
// Check if warping and not changing the map.