Initial support for Genetic, Sorcerer and Elemental Summons. Special Thanks to 3CeAM for the base.
Notice this revision onwards requires you to update your char sql table and add the elemental sql table (check sql-files/upgrade_svn15885_log.sql) If you step by any bugs, let us know at http://rathena.org/board/tracker/ Thank you very much. ARRIBA ARRIBA. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@15885 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
9003fa4eca
commit
a1612031a6
@ -87,6 +87,7 @@ groups: (
|
||||
inherit: ( /*empty list*/ )
|
||||
commands: {
|
||||
/* no commands by default */
|
||||
warp: true
|
||||
}
|
||||
permissions: {
|
||||
/* without this basic permissions regular players could not
|
||||
|
27
db/elemental_db.txt
Normal file
27
db/elemental_db.txt
Normal file
@ -0,0 +1,27 @@
|
||||
//ID,Sprite_Name,Name,LV,HP,SP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Speed,aDelay,aMotion,dMotion
|
||||
// Monster Elementals
|
||||
2114,EL_AGNI_S,Agni,100,5000,1,1,100,100,10,10,1,1,1,1,1,1,5,12,0,0,83,200,504,1020,360
|
||||
2115,EL_AGNI_M,Agni,100,7500,1,1,250,250,25,25,1,1,1,1,1,1,5,12,1,0,83,200,504,1020,360
|
||||
2116,EL_AGNI_L,Agni,100,10000,1,1,500,500,50,50,1,1,1,1,1,1,5,12,2,0,83,200,504,1020,360
|
||||
2117,EL_AQUA_S,Aqua,100,5000,1,1,100,100,10,10,1,1,1,1,1,1,5,12,0,0,81,200,504,1020,360
|
||||
2118,EL_AQUA_M,Aqua,100,7500,1,1,250,250,25,25,1,1,1,1,1,1,5,12,1,0,81,200,504,1020,360
|
||||
2119,EL_AQUA_L,Aqua,100,10000,1,1,500,500,50,50,1,1,1,1,1,1,5,12,2,0,81,200,504,1020,360
|
||||
2120,EL_VENTUS_S,Ventus,100,5000,1,4,100,100,10,10,1,1,1,1,1,1,5,12,0,0,84,200,504,1020,360
|
||||
2121,EL_VENTUS_M,Ventus,100,7500,1,4,250,250,25,25,1,1,1,1,1,1,5,12,1,0,84,200,504,1020,360
|
||||
2122,EL_VENTUS_L,Ventus,100,10000,1,4,500,500,50,50,1,1,1,1,1,1,5,12,2,0,84,200,504,1020,360
|
||||
2123,EL_TERA_S,Tera,100,5000,1,1,100,100,10,10,1,1,1,1,1,1,5,12,0,0,82,200,504,1020,360
|
||||
2124,EL_TERA_M,Tera,100,7500,1,1,250,250,25,25,1,1,1,1,1,1,5,12,1,0,82,200,504,1020,360
|
||||
2125,EL_TERA_L,Tera,100,10000,1,1,500,500,50,50,1,1,1,1,1,1,5,12,2,0,82,200,504,1020,360
|
||||
|
||||
//2114,EL_AGNI_S,Agni ,100,5000,500 ,1,250,250 ,10,10, 25,25,25,25,25,25, 10,12,0,0,83,200,504,1020,360
|
||||
//2115,EL_AGNI_M,Agni ,100,7500,750 ,1,500,500 ,25,25, 50,50,50,50,50,50, 10,12,1,0,83,200,504,1020,360
|
||||
//2116,EL_AGNI_L,Agni ,100,10000,1000 ,1,1000,1000 ,50,50, 100,100,100,100,100,100, 10,12,2,0,83,200,504,1020,360
|
||||
//2117,EL_AQUA_S,Aqua ,100,5000,500 ,1,250,250 ,10,10, 25,25,25,25,25,25, 10,12,0,0,81,200,504,1020,360
|
||||
//2118,EL_AQUA_M,Aqua ,100,7500,750 ,1,500,500 ,25,25, 50,50,50,50,50,50, 10,12,1,0,81,200,504,1020,360
|
||||
//2119,EL_AQUA_L,Aqua ,100,10000,1000 ,1,1000,1000 ,50,50, 100,100,100,100,100,100, 10,12,2,0,81,200,504,1020,360
|
||||
//2120,EL_VENTUS_S,Ventus ,100,5000,500 ,4,250,250 ,10,10, 25,25,25,25,25,25, 10,12,0,0,84,200,504,1020,360
|
||||
//2121,EL_VENTUS_M,Ventus ,100,7500,750 ,4,500,500 ,25,25, 50,50,50,50,50,50, 10,12,1,0,84,200,504,1020,360
|
||||
//2122,EL_VENTUS_L,Ventus ,100,10000,1000 ,4,1000,1000 ,50,50, 100,100,100,100,100,100, 10,12,2,0,84,200,504,1020,360
|
||||
//2123,EL_TERA_S,Tera ,100,5000,500 ,1,250,250 ,10,10, 25,25,25,25,25,25, 10,12,0,0,82,200,504,1020,360
|
||||
//2124,EL_TERA_M,Tera ,100,7500,750 ,1,500,500 ,25,25, 50,50,50,50,50,50, 10,12,1,0,82,200,504,1020,360
|
||||
//2125,EL_TERA_L,Tera ,100,10000,1000 ,1,1000,1000 ,50,50, 100,100,100,100,100,100, 10,12,2,0,82,200,504,1020,360
|
51
db/elemental_skill_db.txt
Normal file
51
db/elemental_skill_db.txt
Normal file
@ -0,0 +1,51 @@
|
||||
//ElementalID,SkillID,SkillLevel,ReqMode
|
||||
//Spirit Modes (1 = Passive, 2 = Defensive, 4 = Agressive)
|
||||
//
|
||||
// EL_AGNI_S
|
||||
2114,8413,1,1 //EL_PYROTECHNIC,Pyrotechnic
|
||||
2114,8401,1,2 //EL_CIRCLE_OF_FIRE,Circle of Fire
|
||||
2114,8425,1,4 //EL_FIRE_ARROW,Fire Arrow
|
||||
// EL_AGNI_M
|
||||
2115,8414,1,1 //EL_HEATER,Heater
|
||||
2115,8402,1,2 //EL_FIRE_CLOAK,Fire Cloak
|
||||
2115,8426,1,4 //EL_FIRE_BOMB,Fire Bomb
|
||||
// EL_AGNI_L
|
||||
2116,8415,1,1 //EL_TROPIC,Tropic
|
||||
2116,8403,1,2 //EL_FIRE_MANTLE,Fire Mantle
|
||||
2116,8428,1,4 //EL_FIRE_WAVE,Fire Wave
|
||||
// EL_AQUA_S
|
||||
2117,8416,1,1 //EL_AQUAPLAY,Aqua Play
|
||||
2117,8404,1,2 //EL_WATER_SCREEN,Water Screen
|
||||
2117,8430,1,4 //EL_ICE_NEEDLE,Ice Needle
|
||||
// EL_AQUA_M
|
||||
2118,8417,1,1 //EL_COOLER,Cooler
|
||||
2118,8405,1,2 //EL_WATER_DROP,Water Drop
|
||||
2118,8431,1,4 //EL_WATER_SCREW,Water Screw
|
||||
// EL_AQUA_L
|
||||
2119,8418,1,1 //EL_CHILLY_AIR,Cool Air
|
||||
2119,8406,1,2 //EL_WATER_BARRIER,Water Barrier
|
||||
2119,8433,1,4 //EL_TIDAL_WEAPON,Tidal Weapon
|
||||
// EL_VENTUS_S
|
||||
2120,8419,1,1 //EL_GUST,Gust
|
||||
2120,8407,1,2 //EL_WIND_STEP,Wind Step
|
||||
2120,8434,1,4 //EL_WIND_SLASH,Wind Slasher
|
||||
// EL_VENTUS_M
|
||||
2121,8420,1,1 //EL_BLAST,Blast
|
||||
2121,8408,1,2 //EL_WIND_CURTAIN,Wind Curtain
|
||||
2121,8435,1,4 //EL_HURRICANE,Hurricane Rage
|
||||
// EL_VENTUS_L
|
||||
2122,8421,1,1 //EL_WILD_STORM,Wild Storm
|
||||
2122,8409,1,2 //EL_ZEPHYR,Zephyr
|
||||
2122,8437,1,4 //EL_TYPOON_MIS,Typhoon Missile
|
||||
// EL_TERA_S
|
||||
2123,8422,1,1 //EL_PETROLOGY,Petrology
|
||||
2123,8410,1,2 //EL_SOLID_SKIN,Solid Skin
|
||||
2123,8439,1,4 //EL_STONE_HAMMER,Stone Hammer
|
||||
// EL_TERA_M
|
||||
2124,8423,1,1 //EL_CURSED_SOIL,Cursed Soil
|
||||
2124,8411,1,2 //EL_STONE_SHIELD,Stone Shield
|
||||
2124,8440,1,4 //EL_ROCK_CRUSHER,Rock Launcher
|
||||
// EL_TERA_L
|
||||
2125,8424,1,1 //EL_UPHEAVAL,Upheaval
|
||||
2125,8412,1,2 //EL_POWER_OF_GAIA,Power of Gaia
|
||||
2125,8442,1,4 //EL_STONE_RAIN,Stone Rain
|
@ -442,3 +442,85 @@
|
||||
//-- Poison Fatigue <-- GC_RESEARCHNEWPOISON Lv6, 1 Izidor, 1 Medicine Bowl, 10 Sticky Poison, 1 Poison Kit
|
||||
12724,25,2024,6,709,1,7134,1,7565,10,7931,1
|
||||
//==============================================
|
||||
|
||||
//==============================================
|
||||
// Genetic Foods And Potions (LV= 26 -> 29)
|
||||
//==============================================
|
||||
//---- Change Material --- ItemLV=26 -----------
|
||||
//-- Phracon [8] <-- GN_CHANGEMATERIAL Lv1, 40 Glass Bead, 45 Spawn
|
||||
1010,26,2494,1,746,40,908,45
|
||||
//-- Witch Starsand [2] <-- GN_CHANGEMATERIAL Lv1, 15 Blue Porcelain, 10 InsectFeeler
|
||||
1061,26,2494,1,735,15,928,10
|
||||
//-- Throwable HP Increase Potion (Small) [10] <-- GN_CHANGEMATERIAL Lv1, 10 Throwing Bottle, 10 HP Potions (Small)
|
||||
13275,26,2494,1,6297,10,12422,10
|
||||
//-- Throwable HP Increase Potion (Medium) [10] <-- GN_CHANGEMATERIAL Lv1, 10 Throwing Bottle, 10 HP Potions (Medium)
|
||||
13276,26,2494,1,6297,10,12423,10
|
||||
//-- Throwable HP Increase Potion (Large) [10] <-- GN_CHANGEMATERIAL Lv1, 10 Throwing Bottle, 10 HP Potions (Large)
|
||||
13277,26,2494,1,6297,10,12424,10
|
||||
//-- Throwable SP Increase Potion (Small) [10] <-- GN_CHANGEMATERIAL Lv1, 10 Throwing Bottle, 10 SP Potions (Small)
|
||||
13278,26,2494,1,6297,10,12425,10
|
||||
//-- Throwable SP Increase Potion (Medium) [10] <-- GN_CHANGEMATERIAL Lv1, 10 Throwing Bottle, 10 SP Potions (Medium)
|
||||
13279,26,2494,1,6297,10,12426,10
|
||||
//-- Throwable SP Increase Potion (Large) [10] <-- GN_CHANGEMATERIAL Lv1, 10 Throwing Bottle, 10 SP Potions (Large)
|
||||
13280,26,2494,1,6297,10,12427,10
|
||||
//-- Throwable Enrich White Potion Z [10] <-- GN_CHANGEMATERIAL Lv1, 10 Throwing Bottle, 10 Enrich White Potion Z
|
||||
13281,26,2494,1,6297,10,12428,10
|
||||
//-- Vitata 500 [10] <-- GN_CHANGEMATERIAL Lv1, 10 Throwing Bottle, 10 Vitata 500
|
||||
13282,26,2494,1,6297,10,12436,10
|
||||
//-- Enrich Celermine Juice [10] <-- GN_CHANGEMATERIAL Lv1, 10 Throwing Bottle, 10 Enrich Celermine Juice
|
||||
13283,26,2494,1,6297,10,12437,10
|
||||
|
||||
//---- Mix Cooking --- ItemLV=27 ---------------
|
||||
//-- Savage BBQ <-- GN_MIX_COOKING Lv1, Mix Cook Book, 1 Melange Pot, 1 Savage Meat, 1 Cooking Skewer, 1 Black Charcoal
|
||||
12429,27,2495,1,11022,0,6248,1,6249,1,6250,1,6251,1
|
||||
//-- Wug Blood Cocktail <-- GN_MIX_COOKING Lv1, Mix Cook Book, 1 Melange Pot, 3 Wolf Blood, 2 Cold Ice
|
||||
12430,27,2495,1,11022,0,6248,1,6252,3,6253,2
|
||||
//-- Minor Brisket <-- GN_MIX_COOKING Lv1, Mix Cook Book, 1 Melange Pot, 2 Beef Head Meat, 1 Large Cookpot
|
||||
12431,27,2495,1,11022,0,6248,1,6254,2,6255,1
|
||||
//-- Siroma Icetea <-- GN_MIX_COOKING Lv1, Mix Cook Book, 1 Melange Pot, 3 Ice Fragment, 2 Ice Crystal, 1 Comodo Tropic Fruit
|
||||
12432,27,2495,1,11022,0,6248,1,6256,3,6257,2,6258,1
|
||||
//-- Drocera Herb Stew <-- GN_MIX_COOKING Lv1, Mix Cook Book, 3 Red Herb, 3 White Herb, 3 Blue Herb, 1 Melange Pot, 1 Large Cookpot, 1 Drocera Tentacle
|
||||
12433,27,2495,1,11022,0,507,3,509,3,510,3,6248,1,6255,1,6259,3
|
||||
//-- Petti Tail Noodle <-- GN_MIX_COOKING Lv1, Mix Cook Book, 1 Melange Pot, 2 Petti Tail, 1 Fine Noodle, 1 Cool Gravy
|
||||
12434,27,2495,1,11022,0,6248,1,6260,2,6261,1,6262,1
|
||||
|
||||
//---- Create Bomb --- ItemLV=28 ---------------
|
||||
//-- Apple Bomb <-- GN_MAKEBOMB Lv1, Apple Bomb CB, 1 Apple, 1 Scell, 1 Detonator, 1 Gun Powder
|
||||
13260,28,2496,1,6279,0,512,1,911,1,1051,1,6244,1
|
||||
//-- Coconut Bomb <-- GN_MAKEBOMB Lv1, Coconut Bomb CB, 1 Detonator, 1 Coconut Fruit, 2 Gun Powder
|
||||
13261,28,2496,1,6281,0,1051,1,6263,1,6244,2
|
||||
//-- Melon Bomb <-- GN_MAKEBOMB Lv1, Melon Bomb CB, 1 Sticky Mucus, 1 Detonator, 2 Gun Powder, 1 Melon
|
||||
13262,28,2496,1,6282,0,938,1,1051,1,6244,2,6264,1
|
||||
//-- Pineapple Bomb <-- GN_MAKEBOMB Lv1, Pinepple Bomb CB, 1 Cactus Needle, 1 Detonator, 3 Gun Powder, 1 Pineapple
|
||||
13263,28,2496,1,6280,0,952,1,1051,1,6244,3,6265,1
|
||||
//-- Banana Bomb <-- GN_MAKEBOMB Lv1, Banana Bomb CB, 1 Banana, 1 Detonator, 4 Gun Powder, 1 Mould Powder
|
||||
13264,28,2496,1,6283,0,513,1,1051,1,6244,4,7001,1
|
||||
|
||||
//---- Special Pharmacy --- ItemLV=29 ----------
|
||||
//-- Seed Of Horny Plant <-- GN_S_PHARMACY Lv1, Plant Genetic Grow, 10 Prickly Fruit
|
||||
6210,29,2497,1,6284,0,576,10
|
||||
//-- Bloodsuck Plant Seed <-- GN_S_PHARMACY Lv1, Plant Genetic Grow, 10 Root Of Maneater
|
||||
6211,29,2497,1,6284,0,1033,10
|
||||
//-- Bomb Mushroom Spore <-- GN_S_PHARMACY Lv1, Plant Genetic Grow, 10 Mushroom Spore, 2 Gun Powder, 5 Poison Spore
|
||||
6212,29,2497,1,6284,0,921,10,6244,2,7033,5
|
||||
//-- HP Increase Potion (Small) <-- GN_S_PHARMACY Lv1, Increase Stamina Study, 10 White Herb, 5 Monster's Feed, 10 Empty Bottle, 1 Hot Sauce
|
||||
12422,29,2497,1,11023,0,509,10,528,5,713,10,7455,1
|
||||
//-- HP Increase Potion (Medium) <-- GN_S_PHARMACY Lv1, Increase Stamina Study, 10 Yellow Herb, 10 White Herb, 10 Empty Bottle, 1 Hot Sauce
|
||||
12423,29,2497,1,11023,0,508,10,509,10,713,10,7455,1
|
||||
//-- HP Increase Potion (Large) <-- GN_S_PHARMACY Lv1, Increase Stamina Study, 15 White Herb, 3 Fruit Of Mastela, 1 Holy Water, 10 Empty Bottle, 1 Hot Sauce
|
||||
12424,29,2497,1,11023,0,509,15,522,3,523,1,713,10,7455,1
|
||||
//-- SP Increase Potion (Small) <-- GN_S_PHARMACY Lv1, Vital Drink CB, 10 Grape, 10 Lemon, 10 Empty Bottle, 1 Sweet Sauce
|
||||
12425,29,2497,1,11024,0,514,10,568,10,713,10,7453,1
|
||||
//-- SP Increase Potion (Medium) <-- GN_S_PHARMACY Lv1, Vital Drink CB, 10 Blue Herb, 10 Honey, 10 Empty Bottle, 1 Sweet Sauce
|
||||
12426,29,2497,1,11024,0,510,10,518,10,713,10,7453,1
|
||||
//-- SP Increase Potion (Large) <-- GN_S_PHARMACY Lv1, Vital Drink CB, 15 Blue Herb, 10 Royal Jelly, 10 Empty Bottle, 1 Sweet Sauce
|
||||
12427,29,2497,1,11024,0,510,15,526,10,713,10,7453,1
|
||||
//-- Enrich White Potion Z <-- GN_S_PHARMACY Lv1, Quality Potion Book, 20 White Potion, 10 White Herb, 1 Alchol, 10 Empty Cylinder
|
||||
12428,29,2497,1,6285,0,504,20,509,10,970,1,1092,10
|
||||
//-- Vitata 500 <-- GN_S_PHARMACY Lv1, Quality Potion Book, 10 Blue Herb, 10 Grape, 10 Honey, 10 Empty Cylinder
|
||||
12436,29,2497,1,6285,0,510,10,514,10,518,10,1092,10
|
||||
//-- Enrich Celermine Juice <-- GN_S_PHARMACY Lv1, Quality Potion Book, 5 Center Potion, 5 Awakening Potion, 10 Empty Cylinder, 5 Hot Sauce
|
||||
12437,29,2497,1,6285,0,645,5,656,5,1092,10,7455,5
|
||||
//-- Cure Free <-- GN_S_PHARMACY Lv1, Quality Potion Book, 20 Green Herb, 1 Fruit Of Mastela, 5 Panacea, 1 Leaf Of Yggdrasil, 10 Empty Cylinder
|
||||
12475,29,2497,1,6285,0,511,20,522,1,525,5,610,1,1092,10
|
||||
//===============================================
|
||||
|
@ -1783,61 +1783,61 @@
|
||||
|
||||
//===== Elemental Skills =======================
|
||||
//-- EL_CIRCLE_OF_FIRE
|
||||
//8401,0,0,0,-1,0,0
|
||||
8401,0,0,0,-1,0,0
|
||||
//-- EL_FIRE_CLOAK
|
||||
//8402,0,0,0,-1,0,0
|
||||
8402,0,0,0,-1,0,0
|
||||
//-- EL_FIRE_MANTLE
|
||||
//8403,0,0,0,15000,0,0
|
||||
8403,0,0,0,15000,0,0
|
||||
//-- EL_WATER_SCREEN
|
||||
//8404,0,0,0,-1,0,0
|
||||
8404,0,0,0,-1,0,0
|
||||
//-- EL_WATER_DROP
|
||||
//8405,0,0,0,-1,0,0
|
||||
8405,0,0,0,-1,0,0
|
||||
//-- EL_WATER_BARRIER
|
||||
//8406,1000,0,0,15000,0,0
|
||||
8406,1000,0,0,15000,0,0
|
||||
//-- EL_WIND_STEP
|
||||
//8407,0,0,0,-1,0,0
|
||||
8407,0,0,0,-1,0,0
|
||||
//-- EL_WIND_CURTAIN
|
||||
//8408,0,0,0,-1,0,0
|
||||
8408,0,0,0,-1,0,0
|
||||
//-- EL_ZEPHYR
|
||||
//8409,0,0,0,15000,0,0
|
||||
8409,0,0,0,15000,0,0
|
||||
//-- EL_STONE_SHIELD
|
||||
//8411,0,0,0,-1,0,0
|
||||
8411,0,0,0,-1,0,0
|
||||
//-- EL_POWER_OF_GAIA
|
||||
//8412,0,0,0,15000,0,0
|
||||
8412,0,0,0,15000,0,0
|
||||
//-- EL_PYROTECHNIC
|
||||
//8413,0,0,0,-1,0,0
|
||||
8413,0,0,0,-1,0,0
|
||||
//-- EL_HEATER
|
||||
//8414,0,0,0,-1,0,0
|
||||
8414,0,0,0,-1,0,0
|
||||
//-- EL_TROPIC
|
||||
//8415,0,0,0,-1,0,0
|
||||
8415,0,0,0,-1,0,0
|
||||
//-- EL_AQUAPLAY
|
||||
//8416,0,0,0,-1,0,0
|
||||
8416,0,0,0,-1,0,0
|
||||
//-- EL_COOLER
|
||||
//8417,0,0,0,-1,0,0
|
||||
8417,0,0,0,-1,0,0
|
||||
//-- EL_CHILLY_AIR
|
||||
//8418,0,0,0,-1,0,0
|
||||
8418,0,0,0,-1,0,0
|
||||
//-- EL_GUST
|
||||
//8419,0,0,0,-1,0,0
|
||||
8419,0,0,0,-1,0,0
|
||||
//-- EL_BLAST
|
||||
//8420,0,0,0,-1,0,0
|
||||
8420,0,0,0,-1,0,0
|
||||
//-- EL_WILD_STORM
|
||||
//8421,0,0,0,-1,0,0
|
||||
8421,0,0,0,-1,0,0
|
||||
//-- EL_PETROLOGY
|
||||
//8422,0,0,0,-1,0,0
|
||||
8422,0,0,0,-1,0,0
|
||||
//-- EL_CURSED_SOIL
|
||||
//8423,0,0,0,-1,0,0
|
||||
8423,0,0,0,-1,0,0
|
||||
//-- EL_UPHEAVAL
|
||||
//8424,0,0,0,-1,0,0
|
||||
8424,0,0,0,-1,0,0
|
||||
//-- EL_TIDAL_WEAPON
|
||||
//8433,0,0,0,-1,0,0
|
||||
8433,0,0,0,-1,0,0
|
||||
//-- EL_TYPOON_MIS
|
||||
//8437,0,0,0,15000,0,0
|
||||
8437,0,0,0,15000,0,0
|
||||
//-- EL_STONE_HAMMER
|
||||
//8439,0,0,0,5000,0,0
|
||||
8439,0,0,0,5000,0,0
|
||||
//-- EL_ROCK_CRUSHER
|
||||
//8440,0,0,0,15000,0,0
|
||||
8440,0,0,0,15000,0,0
|
||||
//-- EL_ROCK_CRUSHER_ATK
|
||||
//8441,0,0,0,15000,0,0
|
||||
8441,0,0,0,15000,0,0
|
||||
//==========================================
|
||||
|
||||
//===== Guild Skills =======================
|
||||
|
@ -944,256 +944,62 @@
|
||||
2434,0,6,4,0,0x3,5,5,1,yes,0,0x4000,0,none,0, WM_UNLIMITED_HUMMING_VOICE,Unlimited Humming Voice
|
||||
2516,11,6,1,-1,0x2,5,5,1,no,0,0,0,weapon,0, WM_SEVERE_RAINSTORM_MELEE,Severe Rainstorm Melee
|
||||
|
||||
//2021,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_VENOMIMPRESS,
|
||||
//2022,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_CROSSIMPACT,
|
||||
//2023,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_DARKILLUSION,
|
||||
//2024,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_RESEARCHNEWPOISON,
|
||||
//2025,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_CREATENEWPOISON,
|
||||
//2026,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_ANTIDOTE,
|
||||
//2027,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_POISONINGWEAPON,
|
||||
//2028,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_WEAPONBLOCKING,
|
||||
//2029,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_COUNTERSLASH,
|
||||
//2030,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_WEAPONCRUSH,
|
||||
//2031,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_VENOMPRESSURE,
|
||||
//2032,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_POISONSMOKE,
|
||||
//2033,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_CLOAKINGEXCEED,
|
||||
//2034,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_PHANTOMMENACE,
|
||||
//2035,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_HALLUCINATIONWALK,
|
||||
//2036,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_ROLLINGCUTTER,
|
||||
//2037,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GC_CROSSRIPPERSLASHER,
|
||||
//2038,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_JUDEX,
|
||||
//2039,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_ANCILLA,
|
||||
//2040,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_ADORAMUS,
|
||||
//2041,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_CLEMENTIA,
|
||||
//2042,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_CANTO,
|
||||
//2043,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_CHEAL,
|
||||
//2044,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_EPICLESIS,
|
||||
//2045,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_PRAEFATIO,
|
||||
//2046,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_ORATIO,
|
||||
//2047,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_LAUDAAGNUS,
|
||||
//2048,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_LAUDARAMUS,
|
||||
//2049,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_EUCHARISTICA,
|
||||
//2050,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_RENOVATIO,
|
||||
//2051,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_HIGHNESSHEAL,
|
||||
//2052,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_CLEARANCE,
|
||||
//2053,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_EXPIATIO,
|
||||
//2054,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_DUPLELIGHT,
|
||||
//2055,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_DUPLELIGHT_MELEE,
|
||||
//2056,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_DUPLELIGHT_MAGIC,
|
||||
//2057,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_SILENTIUM,
|
||||
//2201,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_WHITEIMPRISON,
|
||||
//2202,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_SOULEXPANSION,
|
||||
//2203,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_FROSTMISTY,
|
||||
//2204,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_JACKFROST,
|
||||
//2205,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_MARSHOFABYSS,
|
||||
//2206,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_RECOGNIZEDSPELL,
|
||||
//2207,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_SIENNAEXECRATE,
|
||||
//2208,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_RADIUS,
|
||||
//2209,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_STASIS,
|
||||
//2210,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_DRAINLIFE,
|
||||
//2211,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_CRIMSONROCK,
|
||||
//2212,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_HELLINFERNO,
|
||||
//2213,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_COMET,
|
||||
//2214,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_CHAINLIGHTNING,
|
||||
//2216,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_EARTHSTRAIN,
|
||||
//2217,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_TETRAVORTEX,
|
||||
//2222,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_SUMMONFB,
|
||||
//2223,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_SUMMONBL,
|
||||
//2224,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_SUMMONWB,
|
||||
//2229,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_SUMMONSTONE,
|
||||
//2230,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_RELEASE,
|
||||
//2231,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_READING_SB,
|
||||
//2232,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WL_FREEZE_SP,
|
||||
//2233,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_ARROWSTORM,
|
||||
//2234,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_FEARBREEZE,
|
||||
//2235,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_RANGERMAIN,
|
||||
//2236,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_AIMEDBOLT,
|
||||
//2237,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_DETONATOR,
|
||||
//2238,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_ELECTRICSHOCKER,
|
||||
//2239,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_CLUSTERBOMB,
|
||||
//2240,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_WUGMASTERY,
|
||||
//2241,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_WUGRIDER,
|
||||
//2242,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_WUGDASH,
|
||||
//2243,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_WUGSTRIKE,
|
||||
//2244,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_WUGBITE,
|
||||
//2245,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_TOOTHOFWUG,
|
||||
//2246,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_SENSITIVEKEEN,
|
||||
//2247,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_CAMOUFLAGE,
|
||||
//2248,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_RESEARCHTRAP,
|
||||
//2249,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_MAGENTATRAP,
|
||||
//2250,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_COBALTTRAP,
|
||||
//2251,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_MAIZETRAP,
|
||||
//2252,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_VERDURETRAP,
|
||||
//2253,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_FIRINGTRAP,
|
||||
//2254,0,0,0,0,0,0,9,0,no,0,0,0,none,0 RA_ICEBOUNDTRAP,
|
||||
//2255,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_MADOLICENCE,
|
||||
//2256,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_BOOSTKNUCKLE,
|
||||
//2257,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_PILEBUNKER,
|
||||
//2258,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_VULCANARM,
|
||||
//2259,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_FLAMELAUNCHER,
|
||||
//2260,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_COLDSLOWER,
|
||||
//2261,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_ARMSCANNON,
|
||||
//2262,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_ACCELERATION,
|
||||
//2263,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_HOVERING,
|
||||
//2264,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_F_SIDESLIDE,
|
||||
//2265,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_B_SIDESLIDE,
|
||||
//2266,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_MAINFRAME,
|
||||
//2267,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_SELFDESTRUCTION,
|
||||
//2268,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_SHAPESHIFT,
|
||||
//2269,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_EMERGENCYCOOL,
|
||||
//2270,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_INFRAREDSCAN,
|
||||
//2271,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_ANALYZE,
|
||||
//2272,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_MAGNETICFIELD,
|
||||
//2273,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_NEUTRALBARRIER,
|
||||
//2274,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_STEALTHFIELD,
|
||||
//2275,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_REPAIR,
|
||||
//2276,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_TRAININGAXE,
|
||||
//2277,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_RESEARCHFE,
|
||||
//2278,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_AXEBOOMERANG,
|
||||
//2279,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_POWERSWING,
|
||||
//2280,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_AXETORNADO,
|
||||
//2281,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_SILVERSNIPER,
|
||||
//2282,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_MAGICDECOY,
|
||||
//2283,0,0,0,0,0,0,9,0,no,0,0,0,none,0 NC_DISJOINT,
|
||||
//2284,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_FATALMENACE,
|
||||
//2285,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_REPRODUCE,
|
||||
//2286,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_AUTOSHADOWSPELL,
|
||||
//2287,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_SHADOWFORM,
|
||||
//2288,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_TRIANGLESHOT,
|
||||
//2289,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_BODYPAINT,
|
||||
//2290,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_INVISIBILITY,
|
||||
//2291,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_DEADLYINFECT,
|
||||
//2292,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_ENERVATION,
|
||||
//2293,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_GROOMY,
|
||||
//2294,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_IGNORANCE,
|
||||
//2295,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_LAZINESS,
|
||||
//2296,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_UNLUCKY,
|
||||
//2297,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_WEAKNESS,
|
||||
//2298,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_STRIPACCESSARY,
|
||||
//2299,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_MANHOLE,
|
||||
//2300,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_DIMENSIONDOOR,
|
||||
//2301,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_CHAOSPANIC,
|
||||
//2302,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_MAELSTROM,
|
||||
//2303,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_BLOODYLUST,
|
||||
//2304,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SC_FEINTBOMB,
|
||||
//2307,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_CANNONSPEAR,
|
||||
//2308,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_BANISHINGPOINT,
|
||||
//2309,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_TRAMPLE,
|
||||
//2310,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_SHIELDPRESS,
|
||||
//2311,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_REFLECTDAMAGE,
|
||||
//2312,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_PINPOINTATTACK,
|
||||
//2313,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_FORCEOFVANGUARD,
|
||||
//2314,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_RAGEBURST,
|
||||
//2315,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_SHIELDSPELL,
|
||||
//2316,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_EXEEDBREAK,
|
||||
//2317,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_OVERBRAND,
|
||||
//2318,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_PRESTIGE,
|
||||
//2319,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_BANDING,
|
||||
//2320,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_MOONSLASHER,
|
||||
//2321,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_RAYOFGENESIS,
|
||||
//2322,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_PIETY,
|
||||
//2323,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_EARTHDRIVE,
|
||||
//2324,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_HESPERUSLIT,
|
||||
//2325,0,0,0,0,0,0,9,0,no,0,0,0,none,0 LG_INSPIRATION,
|
||||
//2326,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_DRAGONCOMBO,
|
||||
//2327,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_SKYNETBLOW,
|
||||
//2328,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_EARTHSHAKER,
|
||||
//2329,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_FALLENEMPIRE,
|
||||
//2330,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_TIGERCANNON,
|
||||
//2332,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_RAMPAGEBLASTER,
|
||||
//2333,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_CRESCENTELBOW,
|
||||
//2334,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_CURSEDCIRCLE,
|
||||
//2335,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_LIGHTNINGWALK,
|
||||
//2336,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_KNUCKLEARROW,
|
||||
//2337,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_WINDMILL,
|
||||
//2338,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_RAISINGDRAGON,
|
||||
//2340,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_ASSIMILATEPOWER,
|
||||
//2341,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_POWERVELOCITY,
|
||||
//2343,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_GATEOFHELL,
|
||||
//2344,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_GENTLETOUCH_QUIET,
|
||||
//2345,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_GENTLETOUCH_CURE,
|
||||
//2346,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_GENTLETOUCH_ENERGYGAIN,
|
||||
//2347,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_GENTLETOUCH_CHANGE,
|
||||
//2348,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_GENTLETOUCH_REVITALIZE,
|
||||
//2350,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WA_SWING_DANCE,
|
||||
//2351,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WA_SYMPHONY_OF_LOVER,
|
||||
//2352,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WA_MOONLIT_SERENADE,
|
||||
//2381,0,0,0,0,0,0,9,0,no,0,0,0,none,0 MI_RUSH_WINDMILL,
|
||||
//2382,0,0,0,0,0,0,9,0,no,0,0,0,none,0 MI_ECHOSONG,
|
||||
//2383,0,0,0,0,0,0,9,0,no,0,0,0,none,0 MI_HARMONIZE,
|
||||
//2412,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_LESSON,
|
||||
//2413,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_METALICSOUND,
|
||||
//2414,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_REVERBERATION,
|
||||
//2417,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_DOMINION_IMPULSE,
|
||||
//2418,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_SEVERE_RAINSTORM,
|
||||
//2419,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_POEMOFNETHERWORLD,
|
||||
//2420,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_VOICEOFSIREN,
|
||||
//2421,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_DEADHILLHERE,
|
||||
//2422,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_LULLABY_DEEPSLEEP,
|
||||
//2423,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_SIRCLEOFNATURE,
|
||||
//2424,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_RANDOMIZESPELL,
|
||||
//2425,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_GLOOMYDAY,
|
||||
//2426,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_GREAT_ECHO,
|
||||
//2427,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_SONG_OF_MANA,
|
||||
//2428,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_DANCE_WITH_WUG,
|
||||
//2429,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_SOUND_OF_DESTRUCTION,
|
||||
//2430,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_SATURDAY_NIGHT_FEVER,
|
||||
//2431,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_LERADS_DEW,
|
||||
//2432,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_MELODYOFSINK,
|
||||
//2433,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_BEYOND_OF_WARCRY,
|
||||
//2434,0,0,0,0,0,0,9,0,no,0,0,0,none,0 WM_UNLIMITED_HUMMING_VOICE,
|
||||
//2443,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_FIREWALK,
|
||||
//2444,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_ELECTRICWALK,
|
||||
//2445,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_SPELLFIST,
|
||||
//2446,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_EARTHGRAVE,
|
||||
//2447,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_DIAMONDDUST,
|
||||
//2448,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_POISON_BUSTER,
|
||||
//2449,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_PSYCHIC_WAVE,
|
||||
//2450,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_CLOUD_KILL,
|
||||
//2451,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_STRIKING,
|
||||
//2452,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_WARMER,
|
||||
//2453,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_VACUUM_EXTREME,
|
||||
//2454,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_VARETYR_SPEAR,
|
||||
//2455,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_ARRULLO,
|
||||
//2456,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_EL_CONTROL,
|
||||
//2457,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_SUMMON_AGNI,
|
||||
//2458,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_SUMMON_AQUA,
|
||||
//2459,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_SUMMON_VENTUS,
|
||||
//2460,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_SUMMON_TERA,
|
||||
//2461,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_EL_ACTION,
|
||||
//2462,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_EL_ANALYSIS,
|
||||
//2463,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_EL_SYMPATHY,
|
||||
//2464,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_EL_CURE,
|
||||
//2465,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_FIRE_INSIGNIA,
|
||||
//2466,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_WATER_INSIGNIA,
|
||||
//2467,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_WIND_INSIGNIA,
|
||||
//2468,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SO_EARTH_INSIGNIA,
|
||||
//2535,0,0,0,0,0,0,9,0,no,0,0,0,none,0 ALL_BUYING_STORE,
|
||||
//2474,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_TRAINING_SWORD,
|
||||
//2475,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_REMODELING_CART,
|
||||
//2476,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_CART_TORNADO,
|
||||
//2477,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_CARTCANNON,
|
||||
//2478,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_CARTBOOST,
|
||||
//2479,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_THORNS_TRAP,
|
||||
//2480,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_BLOOD_SUCKER,
|
||||
//2481,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_SPORE_EXPLOSION,
|
||||
//2482,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_WALLOFTHORN,
|
||||
//2483,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_CRAZYWEED,
|
||||
//2485,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_DEMONIC_FIRE,
|
||||
//2486,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_FIRE_EXPANSION,
|
||||
//2490,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_HELLS_PLANT,
|
||||
//2492,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_MANDRAGORA,
|
||||
//2493,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_SLINGITEM,
|
||||
//2494,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_CHANGEMATERIAL,
|
||||
//2495,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_MIX_COOKING,
|
||||
//2496,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_MAKEBOMB,
|
||||
//2497,0,0,0,0,0,0,9,0,no,0,0,0,none,0 GN_S_PHARMACY,
|
||||
//2515,0,0,0,0,0,0,9,0,no,0,0,0,none,0 AB_SECRAMENT,
|
||||
//2517,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_HOWLINGOFLION,
|
||||
//2518,0,0,0,0,0,0,9,0,no,0,0,0,none,0 SR_RIDEINLIGHTNING,
|
||||
//****
|
||||
// SO Sorcerer
|
||||
2443,0,6,4,3,0,0,5,1,yes,0,0,8:10:12:14:16,magic,0, SO_FIREWALK,Fire Walk //CHECK Video and data shows each cell only hits once.
|
||||
2444,0,6,4,4,0,0,5,1,yes,0,0,8:10:12:14:16,magic,0, SO_ELECTRICWALK,Electric Walk
|
||||
2445,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0, SO_SPELLFIST,Spell Fist
|
||||
2446,9,6,2,2,0,0,5,-3,yes,0,0,0,magic,0, SO_EARTHGRAVE,Earth Grave
|
||||
2447,9,6,2,1,0,0,5,-5,yes,0,0,0,magic,0, SO_DIAMONDDUST,Diamond Dust
|
||||
2448,9,6,1,5,0x2,1:1:1:1:2,5,1,yes,0,0,0,magic,0, SO_POISON_BUSTER,Poison Buster
|
||||
2449,9,6,2,0,0,0,5,1,yes,0,0,0,magic,0, SO_PSYCHIC_WAVE,Psychic Wave
|
||||
2450,9,6,2,5,0,0,5,1,yes,0,0,0,magic,0, SO_CLOUD_KILL,Cloud Kill
|
||||
2451,9,6,16,0,0x1,0,5,1,yes,0,0,0,none,0, SO_STRIKING,Striking //CHECK Data shows a % for increased successful refine rate. Is this true?
|
||||
2452,9,6,2,3,0x1,0,5,1,yes,0,0,0,magic,0, SO_WARMER,Warmer
|
||||
2453,9,6,2,0,0x1,0,5,1,yes,0,0,0,magic,0, SO_VACUUM_EXTREME,Vacuum Extreme
|
||||
2454,9,6,1,4,0x2,1:1:2:2:3,5,1,yes,0,0,0,magic,0, SO_VARETYR_SPEAR,Varetyr Spear
|
||||
2455,9,6,1,0,0x3,1:1:2:2:3,5,1,yes,0,0,0,magic,0, SO_ARRULLO,Arrullo
|
||||
2456,0,6,4,0,0x1,0,4,1,yes,0,0,0,none,0, SO_EL_CONTROL,Spirit Control
|
||||
2457,0,6,4,3,0x1,0,3,1,yes,0,0,0,none,0, SO_SUMMON_AGNI,Summon Fire Spirit Agni
|
||||
2458,0,6,4,1,0x1,0,3,1,yes,0,0,0,none,0, SO_SUMMON_AQUA,Summon Water Spirit Aqua
|
||||
2459,0,6,4,4,0x1,0,3,1,yes,0,0,0,none,0, SO_SUMMON_VENTUS,Summon Wind Spirit Ventus
|
||||
2460,0,6,4,2,0x1,0,3,1,yes,0,0,0,none,0, SO_SUMMON_TERA,Summon Earth Spirit Tera
|
||||
2461,5,6,1,0,0x1,0,1,1,no,0,0,0,none,0, SO_EL_ACTION,Elemental Action
|
||||
2462,0,6,4,0,0x1,0,2,1,yes,0,0,0,none,0, SO_EL_ANALYSIS,Four Spirit Analysis
|
||||
2463,0,0,0,0,0,0,5,0,no,0,0,0,none,0, SO_EL_SYMPATHY,Spirit Sympathy
|
||||
2464,0,6,4,0,0x1,0,1,1,yes,0,0,0,none,0, SO_EL_CURE,Spirit Recovery
|
||||
2465,9,6,2,3,0x1,0,3,1,yes,0,0,1,magic,0, SO_FIRE_INSIGNIA,Fire Insignia //CHECK All 4 insignia skills can be targeted and animations work
|
||||
2466,9,6,2,1,0x1,0,3,1,yes,0,0,1,magic,0, SO_WATER_INSIGNIA,Water Insignia // but its effects havent been coded yet.
|
||||
2467,9,6,2,4,0x1,0,3,1,yes,0,0,1,magic,0, SO_WIND_INSIGNIA,Wind Insignia
|
||||
2468,9,6,2,2,0x1,0,3,1,yes,0,0,1,magic,0, SO_EARTH_INSIGNIA,Earth Insignia
|
||||
|
||||
// Unknown
|
||||
//2533,0,0,0,0,0,0,9,0,no,0,0,0,none,0 ALL_ODINS_RECALL,
|
||||
//****
|
||||
// GN Genetic
|
||||
2474,0,0,0,0,0,0,5,0,no,0,0,0,none,0, GN_TRAINING_SWORD,Sword Training
|
||||
2475,0,0,0,0,0,0,5,0,no,0,0,0,none,0, GN_REMODELING_CART,Cart Remodeling
|
||||
2476,0,6,4,-1,0x2,2,5,1,no,0,0,0,weapon,2, GN_CART_TORNADO,Cart Tornado
|
||||
2477,7:8:9:10:11,6,1,-1,0x2,1:1:2:2:3,5,1,yes,0,0,0,weapon,0, GN_CARTCANNON,Cart Cannon
|
||||
2478,0,6,4,0,0x1,0,5,1,yes,0,0,0,none,0, GN_CARTBOOST,Cart Boost
|
||||
2479,9,6,2,0,0,0,5,1,yes,0,0x80,5,misc,0, GN_THORNS_TRAP,Thorn Trap
|
||||
2480,11,6,1,0,0x1,0,5,1,yes,0,0,3,misc,0, GN_BLOOD_SUCKER,Blood Sucker //CHECK Data says its a magic attack. Hmmmm....
|
||||
2481,11,6,1,-1,0x2,1:2:3:4:5,5,1,yes,0,0,0,weapon,0, GN_SPORE_EXPLOSION,Spore Explosion //CHECK Data says its element is set to neutral. Need to confirm.
|
||||
2482,11,6,16,0,0,0,5,1,yes,0,0,1,weapon,2, GN_WALLOFTHORN,Wall of Thorns
|
||||
2483,11,6,2,0,0x3,4,10,1,yes,0,0,0,weapon,0, GN_CRAZYWEED,Crazy Weed
|
||||
2484,0,6,2,2,0x2,2,10,1,no,0,0,0,weapon,0, GN_CRAZYWEED_ATK,Crazy Weed Attack
|
||||
2485,9,6,2,3,0,0,5,1,yes,0,0,0,magic,0, GN_DEMONIC_FIRE,Demonic Fire
|
||||
2486,9,6,2,0,0,0,5,1,yes,0,0,0,none,0, GN_FIRE_EXPANSION,Fire Expansion //CHECK FIX ME!!!! Level 1 is reducing the damage. Should increase it by 50%
|
||||
2487,9,6,2,0,0,0,1,1,no,0,0,0,none,0, GN_FIRE_EXPANSION_SMOKE_POWDER,Fire Expansion Smoke Powder
|
||||
2488,9,6,2,0,0,0,1,1,no,0,0,0,none,0, GN_FIRE_EXPANSION_TEAR_GAS,Fire Expansion Tear Gas
|
||||
2489,11,6,1,0,0,0,10,1:2:3:4:5:6:7:8:9:10,no,0,0,0,weapon,0, GN_FIRE_EXPANSION_ACID,Fire Expansion Acid
|
||||
2490,9,6,2,0,0x3,1,5,1,yes,0,0x80,2:3:4:5:6,none,0, GN_HELLS_PLANT,Hell's Plant
|
||||
2491,0,6,1,0,0x90,0,5,1,no,0,0,0,misc,0, GN_HELLS_PLANT_ATK,Hell's Plant Attack
|
||||
2492,0,6,4,0,0x3,6:7:8:9:10,5,1,yes,0,0,0,none,0, GN_MANDRAGORA,Howling of Mandragora
|
||||
2493,11,6,16,0,0x1,0,1,1,yes,0,0,0,none,0, GN_SLINGITEM,Sling Item
|
||||
2494,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, GN_CHANGEMATERIAL,Change Material
|
||||
2495,0,6,4,0,0x1,0,2,1,no,0,0,0,none,0, GN_MIX_COOKING,Mix Cooking
|
||||
2496,0,6,4,0,0x1,0,2,1,no,0,0,0,none,0, GN_MAKEBOMB,Create Bomb
|
||||
2497,0,6,4,0,0x1,0,10,1,no,0,0,0,none,0, GN_S_PHARMACY,Special Pharmacy
|
||||
2498,11,6,1,0,0,0,1,1,no,0,0,0,weapon,0, GN_SLINGITEM_RANGEMELEEATK,Sling Item Attack
|
||||
|
||||
// Episode 13.3
|
||||
//2533,0,0,4,0,0x1,0,1,0,no,0,0,0,none,0, ALL_ODINS_RECALL,Odin's Recall
|
||||
@ -1261,49 +1067,49 @@
|
||||
8239,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0, MER_BLESSING,Blessing
|
||||
8240,9,6,16,0,0x1,0,10,1,yes,0,0,0,magic,0, MER_INCAGI,Increase Agility
|
||||
|
||||
// Summons skills.
|
||||
//8416,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_AQUAPLAY,
|
||||
//8420,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_BLAST,
|
||||
//8418,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_CHILLY_AIR,
|
||||
//8401,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_CIRCLE_OF_FIRE,
|
||||
//8417,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_COOLER,
|
||||
//8423,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_CURSED_SOIL,
|
||||
//8425,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_FIRE_ARROW,
|
||||
//8426,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_FIRE_BOMB,
|
||||
//8427,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_FIRE_BOMB_ATK,
|
||||
//8402,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_FIRE_CLOAK,
|
||||
//8403,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_FIRE_MANTLE,
|
||||
//8428,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_FIRE_WAVE,
|
||||
//8429,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_FIRE_WAVE_ATK,
|
||||
//8419,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_GUST,
|
||||
//8414,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_HEATER,
|
||||
//8435,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_HURRICANE,
|
||||
//8436,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_HURRICANE_ATK,
|
||||
//8430,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_ICE_NEEDLE,
|
||||
//8422,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_PETROLOGY,
|
||||
//8412,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_POWER_OF_GAIA,
|
||||
//8413,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_PYROTECHNIC,
|
||||
//8440,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_ROCK_CRUSHER,
|
||||
//8441,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_ROCK_CRUSHER_ATK,
|
||||
//8410,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_SOLID_SKIN,
|
||||
//8439,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_STONE_HAMMER,
|
||||
//8442,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_STONE_RAIN,
|
||||
//8411,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_STONE_SHIELD,
|
||||
//8433,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_TIDAL_WEAPON,
|
||||
//8415,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_TROPIC,
|
||||
//8437,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_TYPOON_MIS,
|
||||
//8438,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_TYPOON_MIS_ATK,
|
||||
//8424,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_UPHEAVAL,
|
||||
//8406,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_WATER_BARRIER,
|
||||
//8405,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_WATER_DROP,
|
||||
//8404,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_WATER_SCREEN,
|
||||
//8431,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_WATER_SCREW,
|
||||
//8432,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_WATER_SCREW_ATK,
|
||||
//8421,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_WILD_STORM,
|
||||
//8408,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_WIND_CURTAIN,
|
||||
//8434,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_WIND_SLASH,
|
||||
//8407,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_WIND_STEP,
|
||||
//8409,0,0,0,0,0,0,9,0,no,0,0,0,none,0 EL_ZEPHYR,
|
||||
// Elemental Spirits Skills
|
||||
8401,0,6,4,3,0,0,1,1,no,0,0,0,weapon,2, EL_CIRCLE_OF_FIRE,Circle of Fire
|
||||
8402,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_FIRE_CLOAK,Fire Cloak
|
||||
8403,0,6,4,3,0,0,1,1,no,0,0,3,magic,2, EL_FIRE_MANTLE,Fire Mantle
|
||||
8404,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_WATER_SCREEN,Water Screen
|
||||
8405,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_WATER_DROP,Water Drop
|
||||
8406,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_WATER_BARRIER,Water Barrier
|
||||
8407,0,6,4,0,0x1,0,1,1,no,0,0,0,none,5, EL_WIND_STEP,Wind Step
|
||||
8408,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_WIND_CURTAIN,Wind Curtain
|
||||
8409,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_ZEPHYR,Zephyr
|
||||
8410,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_SOLID_SKIN,Solid Skin
|
||||
8411,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_STONE_SHIELD,Stone Shield
|
||||
8412,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_POWER_OF_GAIA,Power of Gaia
|
||||
8413,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_PYROTECHNIC,Pyrotechnic
|
||||
8414,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_HEATER,Heater
|
||||
8415,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_TROPIC,Tropic
|
||||
8416,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_AQUAPLAY,Aqua Play
|
||||
8417,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_COOLER,Cooler
|
||||
8418,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_CHILLY_AIR,Cool Air
|
||||
8419,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_GUST,Gust
|
||||
8420,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_BLAST,Blast
|
||||
8421,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_WILD_STORM,Wild Storm
|
||||
8422,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_PETROLOGY,Petrology
|
||||
8423,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_CURSED_SOIL,Cursed Soil
|
||||
8424,0,6,4,0,0x1,0,1,1,no,0,0,0,none,0, EL_UPHEAVAL,Upheaval
|
||||
8425,6,6,1,3,0,0,1,1,no,0,0,0,magic,0, EL_FIRE_ARROW,Fire Arrow
|
||||
8426,6,6,1,3,0,1,1,1,no,0,0,0,magic,0, EL_FIRE_BOMB,Fire Bomb
|
||||
8427,6,6,1,3,0,1,1,1,no,0,0,0,weapon,0, EL_FIRE_BOMB_ATK,Fire Bomb Attack
|
||||
8428,6,6,1,3,0,1,1,1,no,0,0,0,magic,0, EL_FIRE_WAVE,Fire Wave
|
||||
8429,6,6,1,3,0,1,1,1,no,0,0,0,weapon,0, EL_FIRE_WAVE_ATK,Fire Wave Attack
|
||||
8430,9,6,1,1,0,0,1,1,no,0,0,0,magic,0, EL_ICE_NEEDLE,Ice Needle
|
||||
8431,9,6,1,1,0,1,1,1,no,0,0,0,magic,0, EL_WATER_SCREW,Water Screw
|
||||
8432,9,6,1,1,0,1,1,1,no,0,0,0,weapon,0, EL_WATER_SCREW_ATK,Water Screw Attack
|
||||
8433,9,6,1,1,0,1,1,1,no,0,0,0,weapon,0, EL_TIDAL_WEAPON,Tidal Weapon
|
||||
8434,11,6,1,4,0,0,1,1,no,0,0,0,weapon,0, EL_WIND_SLASH,Wind Slasher
|
||||
8435,11,6,1,4,0,1,1,1,no,0,0,0,weapon,0, EL_HURRICANE,Hurricane Rage
|
||||
8436,7,6,1,4,0,0,1,1,no,0,0,0,magic,0, EL_HURRICANE_ATK,Hurricane Rage Attack
|
||||
8437,11,6,1,4,0,1,1,1,no,0,0,0,weapon,0, EL_TYPOON_MIS,Typhoon Missile
|
||||
8438,11,6,1,4,0,1,1,1,no,0,0,0,magic,0, EL_TYPOON_MIS_ATK,Typhoon Missile Attack
|
||||
8439,5,6,1,2,0,0,1,1,no,0,0,0,weapon,0, EL_STONE_HAMMER,Stone Hammer
|
||||
8440,3,6,1,2,0,1,1,1,no,0,0,0,weapon,0, EL_ROCK_CRUSHER,Rock Launcher
|
||||
8441,5,6,1,2,0,1,1,1,no,0,0,0,magic,0, EL_ROCK_CRUSHER_ATK,Rock Launcher Attack
|
||||
8442,9,6,1,2,0,1,1,-5,no,0,0,0,weapon,0, EL_STONE_RAIN,Stone Rain
|
||||
|
||||
10000,0,0,0,0,0,0,1,0,no,0,0x10,0,none,0, GD_APPROVAL,Official Guild Approval
|
||||
10001,0,0,0,0,0,0,1,0,no,0,0x10,0,none,0, GD_KAFRACONTRACT,Kafra Contract
|
||||
|
@ -724,6 +724,61 @@
|
||||
2433,0,0,120:130:140:150:160,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WM_WARCRY_OF_BEYOND#Warcry of Beyond#
|
||||
2434,0,0,120:130:140:150:160,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WM_UNLIMITED_HUMMING_VOICE#Unlimited Humming Voice#
|
||||
|
||||
//****
|
||||
// SO Sorcerer
|
||||
2443,0,0,30:34:38:42:46,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_FIREWALK#Fire Walk#
|
||||
2444,0,0,30:34:38:42:46,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_ELECTRICWALK#Electric Walk#
|
||||
2445,0,0,40:44:48:52:56,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_SPELLFIST#Spell Fist#
|
||||
2446,0,0,62:70:78:86:94,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_EARTHGRAVE#Earth Grave#
|
||||
2447,0,0,50:56:62:68:74,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_DIAMONDDUST#Diamond Dust#
|
||||
2448,0,0,70:90:110:130:150,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_POISON_BUSTER#Poison Buster#
|
||||
2449,0,0,48:56:64:70:78,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_PSYCHIC_WAVE#Psychic Wave#
|
||||
2450,0,0,48:56:64:70:78,0,0,0,99,0,0,none,0,716,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_CLOUD_KILL#Cloud Kill#
|
||||
2451,0,0,50:55:60:65:70,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_STRIKING#Striking#
|
||||
2452,0,0,40:52:64:76:88,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_WARMER#Warmer#
|
||||
2453,0,0,34:42:50:58:66,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_VACUUM_EXTREME#Vacuum Extreme#
|
||||
2454,0,0,55:62:69:76:83,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_VARETYR_SPEAR#Varetyr Spear#
|
||||
2455,0,0,30:35:40:45:50,0,0,0,99,0,0,none,0,715,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_ARRULLO#Arrullo#
|
||||
2456,0,0,10,0,0,0,99,0,0,elementalspirit,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_EL_CONTROL#Spirit Control#
|
||||
2457,0,0,100:150:200,0,0,0,99,0,0,none,0,990,3,990,6,994,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_SUMMON_AGNI#Summon Fire Spirit Agni#
|
||||
2458,0,0,100:150:200,0,0,0,99,0,0,none,0,991,3,991,6,995,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_SUMMON_AQUA#Summon Water Spirit Aqua#
|
||||
2459,0,0,100:150:200,0,0,0,99,0,0,none,0,992,3,992,6,996,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_SUMMON_VENTUS#Summon Wind Spirit Ventus#
|
||||
2460,0,0,100:150:200,0,0,0,99,0,0,none,0,993,3,993,6,997,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_SUMMON_TERA#Summon Wind Spirit Tera#
|
||||
2461,0,0,50,0,0,0,99,0,0,elementalspirit,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_EL_ACTION#Elemental Action#
|
||||
2462,0,0,10:20,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_EL_ANALYSIS#Four Spirit Analysis#
|
||||
2464,0,0,10,0,0,0,99,0,0,elementalspirit,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_EL_CURE#Spirit Recovery#
|
||||
2465,0,0,22:30:38,0,0,0,99,0,0,none,0,6360,1:2:3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_FIRE_INSIGNIA#Fire Insignia#
|
||||
2466,0,0,22:30:38,0,0,0,99,0,0,none,0,6361,1:2:3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_WATER_INSIGNIA#Water Insignia#
|
||||
2467,0,0,22:30:38,0,0,0,99,0,0,none,0,6362,1:2:3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_WIND_INSIGNIA#Wind Insignia#
|
||||
2468,0,0,22:30:38,0,0,0,99,0,0,none,0,6363,1:2:3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SO_EARTH_INSIGNIA#Earth Insignia#
|
||||
|
||||
//****
|
||||
// GN Genetic
|
||||
2476,0,0,30,0,0,0,99,0,0,cart,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_CART_TORNADO#Cart Tornado#
|
||||
2477,0,0,40:42:46:48:50,0,0,0,99,8,1,cart,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_CARTCANNON#Cart Cannon#
|
||||
2478,0,0,20:24:28:32:36,0,0,0,99,0,0,cart,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_CARTBOOST#Cart Boost#
|
||||
2479,0,0,22:26:30:34:38,0,0,0,99,0,0,none,0,6210,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_THORNS_TRAP#Thorn Trap#
|
||||
2480,0,0,30:35:40:45:50,0,0,0,99,0,0,none,0,6211,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_BLOOD_SUCKER#Blood Sucker#
|
||||
2481,0,0,55:60:65:70:75,0,0,0,99,0,0,none,0,6212,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_SPORE_EXPLOSION#Spore Explosion#
|
||||
2482,0,0,40:50:60:70:80,0,0,0,99,0,0,none,0,6210,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_WALLOFTHORN#Wall of Thorns#
|
||||
2483,0,0,24:28:32:36:40:44:48:52:56:60,0,0,0,99,0,0,none,0,6210,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_CRAZYWEED#Crazy Weed#
|
||||
2484,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_CRAZYWEED_ATK#Crazy Weed Attack#
|
||||
2485,0,0,24:28:32:36:40,0,0,0,99,0,0,none,0,7135,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_DEMONIC_FIRE#Demonic Fire#
|
||||
2486,0,0,30:35:40:45:50,0,0,0,99,0,0,none,0,6216,1,6213,1,6214,1,6215,1,7136,1,0,0,0,0,0,0,0,0,0,0 //GN_FIRE_EXPANSION#Fire Expansion#
|
||||
2487,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_FIRE_EXPANSION_SMOKE_POWDER#Fire Expansion Smoke Powder#
|
||||
2488,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_FIRE_EXPANSION_TEAR_GAS#Fire Expansion Tear Gas#
|
||||
2489,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_FIRE_EXPANSION_ACID#Fire Expansion Acid#
|
||||
2490,0,0,40:45:50:55:60,0,0,0,99,0,0,none,0,7137,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_HELLS_PLANT#Hell's Plant#
|
||||
2491,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_HELLS_PLANT_ATK#Hell's Plant Attack#
|
||||
2492,0,0,40:45:50:55:60,0,0,0,99,0,0,none,0,6217,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_MANDRAGORA#Howling of Mandragora#
|
||||
2493,0,0,4,0,0,0,99,9,1,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_SLINGITEM#Sling Item#
|
||||
2494,0,0,5,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_CHANGEMATERIAL#Change Material#
|
||||
2495,0,0,5:40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_MIX_COOKING#Mix Cooking#
|
||||
2496,0,0,5:40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_MAKEBOMB#Create Bomb#
|
||||
2497,0,0,12,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_S_PHARMACY#Special Pharmacy#
|
||||
2498,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //GN_SLINGITEM_RANGEMELEEATK#Sling Item Attack#
|
||||
|
||||
|
||||
//2533,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //ALL_ODINS_RECALL#Odin's Recall#
|
||||
2534,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //RETURN_TO_ELDICASTES#Return To Eldicastes#
|
||||
2535,0,0,1,0,0,0,99,0,0,none,0,6377,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //ALL_BUYING_STORE#Open Buying Store
|
||||
@ -789,3 +844,47 @@
|
||||
8238,0,0,20:20:20:25:25:25:30:30:30:35,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //MER_KYRIE
|
||||
8239,0,0,28:32:36:40:44:48:52:56:60:64,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //MER_BLESSING
|
||||
8240,15,0,18:21:24:27:30:33:36:39:42:45,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //MER_INCAGI
|
||||
|
||||
// Elemental Spirits Skills
|
||||
8401,0,0,40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_CIRCLE_OF_FIRE#Circle of Fire#
|
||||
8402,0,0,60,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_FIRE_CLOAK#Fire Cloak#
|
||||
8403,0,0,80,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_FIRE_MANTLE#Fire Mantle#
|
||||
8404,0,0,40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_WATER_SCREEN#Water Screen#
|
||||
8405,0,0,60,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_WATER_DROP#Water Drop#
|
||||
8406,0,0,80,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_WATER_BARRIER#Water Barrier#
|
||||
8407,0,0,40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_WIND_STEP#Wind Step#
|
||||
8408,0,0,60,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_WIND_CURTAIN#Wind Curtain#
|
||||
8409,0,0,80,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_ZEPHYR#Zephyr#
|
||||
8410,0,0,40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_SOLID_SKIN#Solid Skin#
|
||||
8411,0,0,60,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_STONE_SHIELD#Stone Shield#
|
||||
8412,0,0,80,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_POWER_OF_GAIA#Power of Gaia#
|
||||
8413,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_PYROTECHNIC#Pyrotechnic#
|
||||
8414,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_HEATER#Heater#
|
||||
8415,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_TROPIC#Tropic#
|
||||
8416,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_AQUAPLAY#Aqua Play#
|
||||
8417,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_COOLER#Cooler#
|
||||
8418,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_CHILLY_AIR#Cool Air#
|
||||
8419,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_GUST#Gust#
|
||||
8420,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_BLAST#Blast#
|
||||
8421,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_WILD_STORM#Wild Storm#
|
||||
8422,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_PETROLOGY#Petrology#
|
||||
8423,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_CURSED_SOIL#Cursed Soil#
|
||||
8424,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_UPHEAVAL#Upheaval#
|
||||
8425,0,0,40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_FIRE_ARROW#Fire Arrow#
|
||||
8426,0,0,60,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_FIRE_BOMB#Fire Bomb#
|
||||
8427,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_FIRE_BOMB_ATK#Fire Bomb Attack#
|
||||
8428,0,0,80,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_FIRE_WAVE#Fire Wave#
|
||||
8429,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_FIRE_WAVE_ATK#Fire Wave Attack#
|
||||
8430,0,0,40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_ICE_NEEDLE#Ice Needle#
|
||||
8431,0,0,60,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_WATER_SCREW#Water Screw#
|
||||
8432,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_WATER_SCREW_ATK#Water Screw Attack#
|
||||
8433,0,0,80,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_TIDAL_WEAPON#Tidal Weapon#
|
||||
8434,0,0,40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_WIND_SLASH#Wind Slasher#
|
||||
8435,0,0,60,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_HURRICANE#Hurricane Rage#
|
||||
8436,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_HURRICANE_ATK#Hurricane Rage Attack#
|
||||
8437,0,0,80,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_TYPOON_MIS#Typhoon Missile#
|
||||
8438,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_TYPOON_MIS_ATK#Typhoon Missile Attack#
|
||||
8439,0,0,40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_STONE_HAMMER#Stone Hammer#
|
||||
8440,0,0,60,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_ROCK_CRUSHER#Rock Launcher#
|
||||
8441,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_ROCK_CRUSHER_ATK#Rock Launcher Attack#
|
||||
8442,0,0,80,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //EL_STONE_RAIN#Stone Rain#
|
||||
|
1903
db/re/skill_tree.txt
1903
db/re/skill_tree.txt
File diff suppressed because it is too large
Load Diff
@ -128,12 +128,36 @@
|
||||
2418,0xdb, , 0, 5, 300,enemy, 0x800 //WM_SEVERE_RAINSTORM
|
||||
2419,0xde, , 0, 1,1000,enemy, 0x010 //WM_POEMOFNETHERWORLD
|
||||
|
||||
2443,0xdc, , 0, 0,1000,enemy, 0x00A //SO_FIREWALK
|
||||
2444,0xdd, , 0, 0,1000,enemy, 0x00A //SO_ELECTRICWALK
|
||||
2446,0x86, , 0, 3:3:3:4:4,1000,enemy, 0x018 //SO_EARTHGRAVE
|
||||
2447,0x86, , 0, 3:3:3:4:4,1000,enemy, 0x018 //SO_DIAMONDDUST
|
||||
2449,0xdf, , 0, 3:3:4:4:5,500,enemy, 0x018 //SO_PSYCHIC_WAVE
|
||||
2450,0xe0, , 3, 0, 500,enemy, 0x010 //SO_CLOUD_KILL
|
||||
2452,0xe4, , 0, 3,3000,all, 0x010 //SO_WARMER
|
||||
2465,0xf1, , 0, 1,1000,all, 0x010 //SO_FIRE_INSIGNIA
|
||||
2466,0xf2, , 0, 1,1000,all, 0x010 //SO_WATER_INSIGNIA
|
||||
2467,0xf3, , 0, 1,1000,all, 0x010 //SO_WIND_INSIGNIA
|
||||
2468,0xf4, , 0, 1,1000,all, 0x010 //SO_EARTH_INSIGNIA
|
||||
|
||||
2479,0xe5, , 0, 1,1000,enemy, 0x000 //GN_THORNS_TRAP
|
||||
2482,0xe6,0x7f, -1, 1, -1,all, 0x000 //GN_WALLOFTHORN
|
||||
2485,0xe7, , 0, 3,1000,enemy, 0x098 //GN_DEMONIC_FIRE
|
||||
2487,0xe8, , 0, 3,1000,enemy, 0x000 //GN_FIRE_EXPANSION_SMOKE_POWDER
|
||||
2488,0xe9, , 0, 3,1000,enemy, 0x000 //GN_FIRE_EXPANSION_TEAR_GAS
|
||||
2490,0xea, , 0, 1,1000,all, 0x000 //GN_HELLS_PLANT
|
||||
|
||||
8208,0x86, , 0, 2,1000,enemy, 0x080 //MA_SHOWER
|
||||
8209,0x90, , 0, 1,1000,enemy, 0x006 //MA_SKIDTRAP
|
||||
8210,0x93, , 0, 0,1000,enemy, 0x006 //MA_LANDMINE
|
||||
8211,0x95, , 0, 1,1000,enemy, 0x006 //MA_SANDMAN
|
||||
8212,0x97, , 0, 1,1000,enemy, 0x006 //MA_FREEZINGTRAP
|
||||
|
||||
8403,0xed, , -1, 1,1000,enemy, 0x018 //EL_FIRE_MANTLE
|
||||
8406,0xee, , 0, 1, -1,friend,0x018 //EL_WATER_BARRIER
|
||||
8409,0xef, , 0, 1, -1,friend,0x018 //EL_ZEPHYR
|
||||
8412,0xf0, , 0, 1, -1,friend,0x018 //EL_POWER_OF_GAIA
|
||||
|
||||
10006,0xc1, , 2, 0, -1,guild, 0x040 //GD_LEADERSHIP
|
||||
10007,0xc2, , 2, 0, -1,guild, 0x040 //GD_GLORYWOUNDS
|
||||
10008,0xc3, , 2, 0, -1,guild, 0x040 //GD_SOULCOLD
|
||||
|
@ -80,6 +80,7 @@ CREATE TABLE IF NOT EXISTS `char` (
|
||||
`guild_id` int(11) unsigned NOT NULL default '0',
|
||||
`pet_id` int(11) unsigned NOT NULL default '0',
|
||||
`homun_id` int(11) unsigned NOT NULL default '0',
|
||||
`elemental_id` int(11) unsigned NOT NULL default '0'
|
||||
`hair` tinyint(4) unsigned NOT NULL default '0',
|
||||
`hair_color` smallint(5) unsigned NOT NULL default '0',
|
||||
`clothes_color` smallint(5) unsigned NOT NULL default '0',
|
||||
@ -131,6 +132,29 @@ CREATE TABLE IF NOT EXISTS `charlog` (
|
||||
`hair_color` int(11) NOT NULL default '0'
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
--
|
||||
-- Table structure for table `elemental`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `elemental` (
|
||||
`ele_id` int(11) unsigned NOT NULL auto_increment,
|
||||
`char_id` int(11) NOT NULL,
|
||||
`class` mediumint(9) unsigned NOT NULL default '0',
|
||||
`mode` int(11) unsigned NOT NULL default '1',
|
||||
`hp` int(12) NOT NULL default '1',
|
||||
`sp` int(12) NOT NULL default '1',
|
||||
`max_hp` mediumint(8) unsigned NOT NULL default '0',
|
||||
`max_sp` mediumint(6) unsigned NOT NULL default '0',
|
||||
`str` smallint(4) unsigned NOT NULL default '0',
|
||||
`agi` smallint(4) unsigned NOT NULL default '0',
|
||||
`vit` smallint(4) unsigned NOT NULL default '0',
|
||||
`int` smallint(4) unsigned NOT NULL default '0',
|
||||
`dex` smallint(4) unsigned NOT NULL default '0',
|
||||
`luk` smallint(4) unsigned NOT NULL default '0',
|
||||
`life_time` int(11) NOT NULL default '0',
|
||||
PRIMARY KEY (`ele_id`)
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
--
|
||||
-- Table structure for table `friends`
|
||||
--
|
||||
|
26
sql-files/upgrade_svn15885_log.sql
Normal file
26
sql-files/upgrade_svn15885_log.sql
Normal file
@ -0,0 +1,26 @@
|
||||
-- Adds 'I' to `type` in `zenylog`
|
||||
|
||||
ALTER TABLE `char` ADD COLUMN `elemental_id` int(11) unsigned NOT NULL default '0';
|
||||
|
||||
--
|
||||
-- Table structure for table `elemental`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `elemental` (
|
||||
`ele_id` int(11) unsigned NOT NULL auto_increment,
|
||||
`char_id` int(11) NOT NULL,
|
||||
`class` mediumint(9) unsigned NOT NULL default '0',
|
||||
`mode` int(11) unsigned NOT NULL default '1',
|
||||
`hp` int(12) NOT NULL default '1',
|
||||
`sp` int(12) NOT NULL default '1',
|
||||
`max_hp` mediumint(8) unsigned NOT NULL default '0',
|
||||
`max_sp` mediumint(6) unsigned NOT NULL default '0',
|
||||
`str` smallint(4) unsigned NOT NULL default '0',
|
||||
`agi` smallint(4) unsigned NOT NULL default '0',
|
||||
`vit` smallint(4) unsigned NOT NULL default '0',
|
||||
`int` smallint(4) unsigned NOT NULL default '0',
|
||||
`dex` smallint(4) unsigned NOT NULL default '0',
|
||||
`luk` smallint(4) unsigned NOT NULL default '0',
|
||||
`life_time` int(11) NOT NULL default '0',
|
||||
PRIMARY KEY (`ele_id`)
|
||||
) ENGINE=MyISAM;
|
@ -25,8 +25,8 @@ COMMON_SQL_OBJ = ../common/obj_sql/sql.o
|
||||
COMMON_H = ../common/sql.h
|
||||
|
||||
CHAR_OBJ = obj_sql/char.o obj_sql/inter.o obj_sql/int_party.o obj_sql/int_guild.o \
|
||||
obj_sql/int_storage.o obj_sql/int_pet.o obj_sql/int_homun.o obj_sql/int_mail.o obj_sql/int_auction.o obj_sql/int_quest.o obj_sql/int_mercenary.o
|
||||
CHAR_H = char.h inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h int_mail.h int_auction.h int_quest.h int_mercenary.h
|
||||
obj_sql/int_storage.o obj_sql/int_pet.o obj_sql/int_homun.o obj_sql/int_mail.o obj_sql/int_auction.o obj_sql/int_quest.o obj_sql/int_mercenary.o obj_sql/int_elemental.o
|
||||
CHAR_H = char.h inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h int_mail.h int_auction.h int_quest.h int_mercenary.h int_elemental.h
|
||||
|
||||
HAVE_MYSQL=@HAVE_MYSQL@
|
||||
ifeq ($(HAVE_MYSQL),yes)
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "int_guild.h"
|
||||
#include "int_homun.h"
|
||||
#include "int_mercenary.h"
|
||||
#include "int_elemental.h"
|
||||
#include "int_party.h"
|
||||
#include "int_storage.h"
|
||||
#include "char.h"
|
||||
@ -471,7 +472,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
|
||||
(p->option != cp->option) ||
|
||||
(p->party_id != cp->party_id) || (p->guild_id != cp->guild_id) ||
|
||||
(p->pet_id != cp->pet_id) || (p->weapon != cp->weapon) || (p->hom_id != cp->hom_id) ||
|
||||
(p->shield != cp->shield) || (p->head_top != cp->head_top) ||
|
||||
(p->ele_id != cp->ele_id) || (p->shield != cp->shield) || (p->head_top != cp->head_top) ||
|
||||
(p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || (p->delete_date != cp->delete_date) ||
|
||||
(p->rename != cp->rename) || (p->robe != cp->robe)
|
||||
)
|
||||
@ -480,7 +481,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
|
||||
"`base_exp`='%u', `job_exp`='%u', `zeny`='%d',"
|
||||
"`max_hp`='%d',`hp`='%d',`max_sp`='%d',`sp`='%d',`status_point`='%d',`skill_point`='%d',"
|
||||
"`str`='%d',`agi`='%d',`vit`='%d',`int`='%d',`dex`='%d',`luk`='%d',"
|
||||
"`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',"
|
||||
"`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`elemental_id`='%d',"
|
||||
"`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
|
||||
"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
|
||||
"`delete_date`='%lu',`robe`='%d'"
|
||||
@ -489,7 +490,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
|
||||
p->base_exp, p->job_exp, p->zeny,
|
||||
p->max_hp, p->hp, p->max_sp, p->sp, p->status_point, p->skill_point,
|
||||
p->str, p->agi, p->vit, p->int_, p->dex, p->luk,
|
||||
p->option, p->party_id, p->guild_id, p->pet_id, p->hom_id,
|
||||
p->option, p->party_id, p->guild_id, p->pet_id, p->hom_id, p->ele_id,
|
||||
p->weapon, p->shield, p->head_top, p->head_mid, p->head_bottom,
|
||||
mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y,
|
||||
mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
|
||||
@ -969,7 +970,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
|
||||
if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT "
|
||||
"`char_id`,`account_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`,"
|
||||
"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`,"
|
||||
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`hair`,"
|
||||
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,"
|
||||
"`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
|
||||
"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`"
|
||||
" FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
|
||||
@ -1004,28 +1005,29 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 26, SQLDT_INT, &p->guild_id, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 27, SQLDT_INT, &p->pet_id, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 28, SQLDT_INT, &p->hom_id, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_SHORT, &p->hair, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p->hair_color, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p->clothes_color, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT, &p->weapon, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p->shield, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT, &p->head_top, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_INT, &p->partner_id, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_INT, &p->father, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_INT, &p->mother, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 46, SQLDT_INT, &p->child, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_INT, &p->fame, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 48, SQLDT_SHORT, &p->rename, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 49, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 50, SQLDT_SHORT, &p->robe, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 29, SQLDT_INT, &p->ele_id, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 30, SQLDT_SHORT, &p->hair, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 31, SQLDT_SHORT, &p->hair_color, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 32, SQLDT_SHORT, &p->clothes_color, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 33, SQLDT_SHORT, &p->weapon, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 34, SQLDT_SHORT, &p->shield, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 35, SQLDT_SHORT, &p->head_top, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 36, SQLDT_SHORT, &p->head_mid, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 37, SQLDT_SHORT, &p->head_bottom, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 38, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 39, SQLDT_SHORT, &p->last_point.x, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 40, SQLDT_SHORT, &p->last_point.y, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 41, SQLDT_STRING, &save_map, sizeof(save_map), NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 42, SQLDT_SHORT, &p->save_point.x, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 43, SQLDT_SHORT, &p->save_point.y, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 44, SQLDT_INT, &p->partner_id, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 45, SQLDT_INT, &p->father, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 46, SQLDT_INT, &p->mother, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 47, SQLDT_INT, &p->child, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 48, SQLDT_INT, &p->fame, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 49, SQLDT_SHORT, &p->rename, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 50, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL)
|
||||
|| SQL_ERROR == SqlStmt_BindColumn(stmt, 51, SQLDT_SHORT, &p->robe, 0, NULL, NULL)
|
||||
)
|
||||
{
|
||||
SqlStmt_ShowDebug(stmt);
|
||||
|
164
src/char/int_elemental.c
Normal file
164
src/char/int_elemental.c
Normal file
@ -0,0 +1,164 @@
|
||||
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#include "../common/mmo.h"
|
||||
#include "../common/malloc.h"
|
||||
#include "../common/strlib.h"
|
||||
#include "../common/showmsg.h"
|
||||
#include "../common/socket.h"
|
||||
#include "../common/utils.h"
|
||||
#include "../common/sql.h"
|
||||
#include "char.h"
|
||||
#include "inter.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
bool mapif_elemental_save(struct s_elemental* ele) {
|
||||
bool flag = true;
|
||||
|
||||
if( ele->elemental_id == 0 ) { // Create new DB entry
|
||||
if( SQL_ERROR == Sql_Query(sql_handle,
|
||||
"INSERT INTO `elemental` (`char_id`,`class`,`mode`,`hp`,`sp`,`max_hp`,`max_sp`,`str`,`agi`,`vit`,`int`,`dex`,`luk`,`life_time`)"
|
||||
"VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%u')",
|
||||
ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->str, ele->agi, ele->vit, ele->int_, ele->dex, ele->luk, ele->life_time) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
flag = false;
|
||||
}
|
||||
else
|
||||
ele->elemental_id = (int)Sql_LastInsertId(sql_handle);
|
||||
} else if( SQL_ERROR == Sql_Query(sql_handle,
|
||||
"UPDATE `elemental` SET `char_id` = '%d', `class` = '%d', `mode` = '%d', `hp` = '%d', `sp` = '%d',"
|
||||
"`max_hp` = '%d', `max_sp` = '%d', `str` = '%d', `agi` = '%d', `vit` = '%d', `int` = '%d', `dex` = '%d',"
|
||||
"`luk` = '%d', `life_time` = '%u' WHERE `ele_id` = '%d'",
|
||||
ele->char_id, ele->class_, ele->mode, ele->hp, ele->sp, ele->max_hp, ele->max_sp, ele->str, ele->agi,
|
||||
ele->vit, ele->int_, ele->dex, ele->luk, ele->life_time, ele->elemental_id) )
|
||||
{ // Update DB entry
|
||||
Sql_ShowDebug(sql_handle);
|
||||
flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele) {
|
||||
char* data;
|
||||
|
||||
memset(ele, 0, sizeof(struct s_elemental));
|
||||
ele->elemental_id = ele_id;
|
||||
ele->char_id = char_id;
|
||||
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `class`, `mode`, `hp`, `sp`, `max_hp`, `max_sp`, `str`, `agi`, `vit`, `int`, `dex`,"
|
||||
"`luk`, `life_time` FROM `elemental` WHERE `ele_id` = '%d' AND `char_id` = '%d'",
|
||||
ele_id, char_id) ) {
|
||||
Sql_ShowDebug(sql_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
if( SQL_SUCCESS != Sql_NextRow(sql_handle) ) {
|
||||
Sql_FreeResult(sql_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
Sql_GetData(sql_handle, 0, &data, NULL); ele->class_ = atoi(data);
|
||||
Sql_GetData(sql_handle, 1, &data, NULL); ele->mode = atoi(data);
|
||||
Sql_GetData(sql_handle, 2, &data, NULL); ele->hp = atoi(data);
|
||||
Sql_GetData(sql_handle, 3, &data, NULL); ele->sp = atoi(data);
|
||||
Sql_GetData(sql_handle, 4, &data, NULL); ele->max_hp = atoi(data);
|
||||
Sql_GetData(sql_handle, 5, &data, NULL); ele->max_sp = atoi(data);
|
||||
Sql_GetData(sql_handle, 6, &data, NULL); ele->str = atoi(data);
|
||||
Sql_GetData(sql_handle, 7, &data, NULL); ele->agi = atoi(data);
|
||||
Sql_GetData(sql_handle, 8, &data, NULL); ele->vit = atoi(data);
|
||||
Sql_GetData(sql_handle, 9, &data, NULL); ele->int_ = atoi(data);
|
||||
Sql_GetData(sql_handle, 10, &data, NULL); ele->dex = atoi(data);
|
||||
Sql_GetData(sql_handle, 11, &data, NULL); ele->luk = atoi(data);
|
||||
Sql_GetData(sql_handle, 12, &data, NULL); ele->life_time = atoi(data);
|
||||
Sql_FreeResult(sql_handle);
|
||||
if( save_log )
|
||||
ShowInfo("Elemental loaded (%d - %d).\n", ele->elemental_id, ele->char_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mapif_elemental_delete(int ele_id) {
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `elemental` WHERE `ele_id` = '%d'", ele_id) ) {
|
||||
Sql_ShowDebug(sql_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef TXT_SQL_CONVERT
|
||||
|
||||
static void mapif_elemental_send(int fd, struct s_elemental *ele, unsigned char flag) {
|
||||
int size = sizeof(struct s_elemental) + 5;
|
||||
|
||||
WFIFOHEAD(fd,size);
|
||||
WFIFOW(fd,0) = 0x387c;
|
||||
WFIFOW(fd,2) = size;
|
||||
WFIFOB(fd,4) = flag;
|
||||
memcpy(WFIFOP(fd,5),ele,sizeof(struct s_elemental));
|
||||
WFIFOSET(fd,size);
|
||||
}
|
||||
|
||||
static void mapif_parse_elemental_create(int fd, struct s_elemental* ele) {
|
||||
bool result = mapif_elemental_save(ele);
|
||||
mapif_elemental_send(fd, ele, result);
|
||||
}
|
||||
|
||||
static void mapif_parse_elemental_load(int fd, int ele_id, int char_id) {
|
||||
struct s_elemental ele;
|
||||
bool result = mapif_elemental_load(ele_id, char_id, &ele);
|
||||
mapif_elemental_send(fd, &ele, result);
|
||||
}
|
||||
|
||||
static void mapif_elemental_deleted(int fd, unsigned char flag) {
|
||||
WFIFOHEAD(fd,3);
|
||||
WFIFOW(fd,0) = 0x387d;
|
||||
WFIFOB(fd,2) = flag;
|
||||
WFIFOSET(fd,3);
|
||||
}
|
||||
|
||||
static void mapif_parse_elemental_delete(int fd, int ele_id) {
|
||||
bool result = mapif_elemental_delete(ele_id);
|
||||
mapif_elemental_deleted(fd, result);
|
||||
}
|
||||
|
||||
static void mapif_elemental_saved(int fd, unsigned char flag) {
|
||||
WFIFOHEAD(fd,3);
|
||||
WFIFOW(fd,0) = 0x387e;
|
||||
WFIFOB(fd,2) = flag;
|
||||
WFIFOSET(fd,3);
|
||||
}
|
||||
|
||||
static void mapif_parse_elemental_save(int fd, struct s_elemental* ele) {
|
||||
bool result = mapif_elemental_save(ele);
|
||||
mapif_elemental_saved(fd, result);
|
||||
}
|
||||
|
||||
int inter_elemental_sql_init(void) {
|
||||
return 0;
|
||||
}
|
||||
void inter_elemental_sql_final(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Inter Packets
|
||||
*------------------------------------------*/
|
||||
int inter_elemental_parse_frommap(int fd) {
|
||||
unsigned short cmd = RFIFOW(fd,0);
|
||||
|
||||
switch( cmd ) {
|
||||
case 0x307c: mapif_parse_elemental_create(fd, (struct s_elemental*)RFIFOP(fd,4)); break;
|
||||
case 0x307d: mapif_parse_elemental_load(fd, (int)RFIFOL(fd,2), (int)RFIFOL(fd,6)); break;
|
||||
case 0x307e: mapif_parse_elemental_delete(fd, (int)RFIFOL(fd,2)); break;
|
||||
case 0x307f: mapif_parse_elemental_save(fd, (struct s_elemental*)RFIFOP(fd,4)); break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif //TXT_SQL_CONVERT
|
15
src/char/int_elemental.h
Normal file
15
src/char/int_elemental.h
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#ifndef _INT_ELEMENTAL_SQL_H_
|
||||
#define _INT_ELEMENTAL_SQL_H_
|
||||
|
||||
struct s_elemental;
|
||||
|
||||
int inter_elemental_sql_init(void);
|
||||
void inter_elemental_sql_final(void);
|
||||
int inter_elemental_parse_frommap(int fd);
|
||||
|
||||
bool mapif_elemental_delete(int ele_id);
|
||||
|
||||
#endif /* _INT_ELEMENTAL_SQL_H_ */
|
@ -19,6 +19,7 @@
|
||||
#include "int_mail.h"
|
||||
#include "int_auction.h"
|
||||
#include "int_quest.h"
|
||||
#include "int_elemental.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -50,7 +51,7 @@ int inter_recv_packet_length[] = {
|
||||
-1, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040-
|
||||
-1,-1,10,10, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus]
|
||||
6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish]
|
||||
-1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3070- Mercenary packets [Zephyrus]
|
||||
-1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil]
|
||||
48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080-
|
||||
-1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator]
|
||||
};
|
||||
@ -295,6 +296,7 @@ int inter_init_sql(const char *file)
|
||||
inter_pet_sql_init();
|
||||
inter_homunculus_sql_init();
|
||||
inter_mercenary_sql_init();
|
||||
inter_elemental_sql_init();
|
||||
inter_accreg_sql_init();
|
||||
inter_mail_sql_init();
|
||||
inter_auction_sql_init();
|
||||
@ -313,6 +315,7 @@ void inter_final(void)
|
||||
inter_pet_sql_final();
|
||||
inter_homunculus_sql_final();
|
||||
inter_mercenary_sql_final();
|
||||
inter_elemental_sql_init();
|
||||
inter_mail_sql_final();
|
||||
inter_auction_sql_final();
|
||||
|
||||
@ -723,6 +726,7 @@ int inter_parse_frommap(int fd)
|
||||
|| inter_pet_parse_frommap(fd)
|
||||
|| inter_homunculus_parse_frommap(fd)
|
||||
|| inter_mercenary_parse_frommap(fd)
|
||||
|| inter_elemental_parse_frommap(fd)
|
||||
|| inter_mail_parse_frommap(fd)
|
||||
|| inter_auction_parse_frommap(fd)
|
||||
|| inter_quest_parse_frommap(fd)
|
||||
|
@ -154,6 +154,14 @@
|
||||
#define MAX_MERCSKILL 40
|
||||
#define MAX_MERCENARY_CLASS 44
|
||||
|
||||
//Elemental System
|
||||
#define MAX_ELEMENTALSKILL 42
|
||||
#define EL_SKILLBASE 8401
|
||||
#define MAX_ELESKILLTREE 3
|
||||
#define MAX_ELEMENTAL_CLASS 12
|
||||
#define EL_CLASS_BASE 2114
|
||||
#define EL_CLASS_MAX (EL_CLASS_BASE+MAX_ELEMENTAL_CLASS-1)
|
||||
|
||||
enum item_types {
|
||||
IT_HEALING = 0,
|
||||
IT_UNKNOWN, //1
|
||||
@ -292,6 +300,15 @@ struct s_mercenary {
|
||||
unsigned int life_time;
|
||||
};
|
||||
|
||||
struct s_elemental {
|
||||
int elemental_id;
|
||||
int char_id;
|
||||
short class_;
|
||||
int mode;
|
||||
int hp, sp, max_hp, max_sp, str, agi, vit, int_, dex, luk;
|
||||
int life_time;
|
||||
};
|
||||
|
||||
struct s_friend {
|
||||
int account_id;
|
||||
int char_id;
|
||||
@ -324,7 +341,7 @@ struct mmo_charstatus {
|
||||
short manner;
|
||||
unsigned char karma;
|
||||
short hair,hair_color,clothes_color;
|
||||
int party_id,guild_id,pet_id,hom_id,mer_id;
|
||||
int party_id,guild_id,pet_id,hom_id,mer_id,ele_id;
|
||||
int fame;
|
||||
|
||||
// Mercenary Guilds Rank
|
||||
|
@ -31,7 +31,7 @@ MAP_OBJ = map.o chrif.o clif.o pc.o status.o npc.o \
|
||||
storage.o skill.o atcommand.o battle.o battleground.o \
|
||||
intif.o trade.o party.o vending.o guild.o pet.o \
|
||||
log.o mail.o date.o unit.o homunculus.o mercenary.o quest.o instance.o \
|
||||
buyingstore.o searchstore.o duel.o pc_groups.o
|
||||
buyingstore.o searchstore.o duel.o pc_groups.o elemental.o
|
||||
MAP_SQL_OBJ = $(MAP_OBJ:%=obj_sql/%) \
|
||||
obj_sql/mapreg_sql.o
|
||||
MAP_H = map.h chrif.h clif.h pc.h status.h npc.h \
|
||||
@ -41,7 +41,7 @@ MAP_H = map.h chrif.h clif.h pc.h status.h npc.h \
|
||||
log.h mail.h date.h unit.h homunculus.h mercenary.h quest.h instance.h mapreg.h \
|
||||
buyingstore.h searchstore.h duel.h pc_groups.h \
|
||||
config/core.h config/renewal.h config/secure.h config/const.h \
|
||||
config/classes/general.h config/classes/swordsman.h
|
||||
config/classes/general.h config/classes/swordsman.h elemental.h
|
||||
|
||||
HAVE_MYSQL=@HAVE_MYSQL@
|
||||
ifeq ($(HAVE_MYSQL),yes)
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "homunculus.h"
|
||||
#include "mail.h"
|
||||
#include "mercenary.h"
|
||||
#include "elemental.h"
|
||||
#include "party.h"
|
||||
#include "guild.h"
|
||||
#include "script.h"
|
||||
@ -3764,6 +3765,7 @@ ACMD_FUNC(reloadmobdb)
|
||||
read_petdb();
|
||||
merc_reload();
|
||||
read_mercenarydb();
|
||||
reload_elementaldb();
|
||||
clif_displaymessage(fd, msg_txt(98)); // Monster database has been reloaded.
|
||||
|
||||
return 0;
|
||||
@ -3777,6 +3779,7 @@ ACMD_FUNC(reloadskilldb)
|
||||
nullpo_retr(-1, sd);
|
||||
skill_reload();
|
||||
merc_skill_reload();
|
||||
reload_elemental_skilldb();
|
||||
read_mercenary_skilldb();
|
||||
clif_displaymessage(fd, msg_txt(99)); // Skill database has been reloaded.
|
||||
|
||||
|
248
src/map/battle.c
248
src/map/battle.c
@ -18,6 +18,7 @@
|
||||
#include "skill.h"
|
||||
#include "homunculus.h"
|
||||
#include "mercenary.h"
|
||||
#include "elemental.h"
|
||||
#include "mob.h"
|
||||
#include "itemdb.h"
|
||||
#include "clif.h"
|
||||
@ -103,6 +104,7 @@ int battle_gettarget(struct block_list* bl)
|
||||
case BL_PET: return ((struct pet_data*)bl)->target_id;
|
||||
case BL_HOM: return ((struct homun_data*)bl)->ud.target;
|
||||
case BL_MER: return ((struct mercenary_data*)bl)->ud.target;
|
||||
case BL_ELEM: return ((struct elemental_data*)bl)->ud.target;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -299,8 +301,7 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
|
||||
}
|
||||
|
||||
ratio = attr_fix_table[def_lv-1][atk_elem][def_type];
|
||||
if (sc && sc->count)
|
||||
{
|
||||
if (sc && sc->count) {
|
||||
if(sc->data[SC_VOLCANO] && atk_elem == ELE_FIRE)
|
||||
ratio += enchant_eff[sc->data[SC_VOLCANO]->val1-1];
|
||||
if(sc->data[SC_VIOLENTGALE] && atk_elem == ELE_WIND)
|
||||
@ -308,8 +309,27 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
|
||||
if(sc->data[SC_DELUGE] && atk_elem == ELE_WATER)
|
||||
ratio += enchant_eff[sc->data[SC_DELUGE]->val1-1];
|
||||
}
|
||||
if( atk_elem == ELE_FIRE && tsc && tsc->count && tsc->data[SC_SPIDERWEB] )
|
||||
{
|
||||
if( target && target->type == BL_SKILL ) {
|
||||
if( atk_elem == ELE_FIRE && battle_getcurrentskill(target) == GN_WALLOFTHORN ) {
|
||||
struct skill_unit *su = (struct skill_unit*)target;
|
||||
struct skill_unit_group *sg;
|
||||
struct block_list *src;
|
||||
int x,y;
|
||||
|
||||
if( !su || !su->alive || (sg = su->group) == NULL || !sg || sg->val3 == -1 ||
|
||||
(src = map_id2bl(su->val2)) == NULL || status_isdead(src) )
|
||||
return 0;
|
||||
|
||||
if( sg->unit_id != UNT_FIREWALL ) {
|
||||
x = sg->val3 >> 16;
|
||||
y = sg->val3 & 0xffff;
|
||||
skill_unitsetting(src,su->group->skill_id,su->group->skill_lv,x,y,1);
|
||||
sg->val3 = -1;
|
||||
sg->limit = DIFF_TICK(gettick(),sg->tick)+300;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( atk_elem == ELE_FIRE && tsc && tsc->count && tsc->data[SC_SPIDERWEB] ){
|
||||
tsc->data[SC_SPIDERWEB]->val1 = 0; // free to move now
|
||||
if( tsc->data[SC_SPIDERWEB]->val2-- > 0 )
|
||||
damage <<= 1; // double damage
|
||||
@ -932,6 +952,8 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int
|
||||
case W_DAGGER:
|
||||
if((skill = pc_checkskill(sd,SM_SWORD)) > 0)
|
||||
damage += (skill * 4);
|
||||
if((skill = pc_checkskill(sd,GN_TRAINING_SWORD)) > 0)
|
||||
damage += skill * 10;
|
||||
break;
|
||||
case W_2HSWORD:
|
||||
#ifdef RENEWAL
|
||||
@ -1486,15 +1508,27 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
|
||||
if(sd && pc_checkskill(sd,AS_SONICACCEL)>0)
|
||||
hitrate += hitrate * 50 / 100;
|
||||
break;
|
||||
case MC_CARTREVOLUTION:
|
||||
case GN_CART_TORNADO:
|
||||
case GN_CARTCANNON:
|
||||
if( sd && pc_checkskill(sd, GN_REMODELING_CART) )
|
||||
hitrate += pc_checkskill(sd, GN_REMODELING_CART) * 4;
|
||||
break;
|
||||
case GC_VENOMPRESSURE:
|
||||
hitrate += 10 + 4 * skill_lv;
|
||||
break;
|
||||
}
|
||||
|
||||
// Weaponry Research hidden bonus
|
||||
if (sd && (skill = pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
|
||||
hitrate += hitrate * ( 2 * skill ) / 100;
|
||||
|
||||
if( sd ) {
|
||||
// Weaponry Research hidden bonus
|
||||
if ((skill = pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
|
||||
hitrate += hitrate * ( 2 * skill ) / 100;
|
||||
|
||||
if( (sd->status.weapon == W_1HSWORD || sd->status.weapon == W_DAGGER) &&
|
||||
(skill = pc_checkskill(sd, GN_TRAINING_SWORD))>0 )
|
||||
hitrate += 3 * skill;
|
||||
}
|
||||
|
||||
hitrate = cap_value(hitrate, battle_config.min_hitrate, battle_config.max_hitrate);
|
||||
|
||||
if(rnd()%100 >= hitrate)
|
||||
@ -2238,6 +2272,76 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
|
||||
case WM_SOUND_OF_DESTRUCTION:
|
||||
skillratio += 400;
|
||||
break;
|
||||
case GN_CART_TORNADO:
|
||||
if( sd )
|
||||
skillratio += 50 * skill_lv + pc_checkskill(sd, GN_REMODELING_CART) * 100 - 100;
|
||||
if( status_get_lv(src) > 100 ) skillratio += skillratio * (status_get_lv(src) - 100) / 200; // Base level bonus.
|
||||
if( sc && sc->data[SC_GN_CARTBOOST] )
|
||||
skillratio += 10 * sc->data[SC_GN_CARTBOOST]->val1;
|
||||
break;
|
||||
case GN_CARTCANNON:
|
||||
if( sd ) skillratio += 250 + 50 * skill_lv + pc_checkskill(sd, GN_REMODELING_CART) * (sstatus->int_ / 2);
|
||||
if( sc && sc->data[SC_GN_CARTBOOST] )
|
||||
skillratio += 10 * sc->data[SC_GN_CARTBOOST]->val1;
|
||||
break;
|
||||
case GN_SPORE_EXPLOSION:
|
||||
skillratio += 200 + 100 * skill_lv;
|
||||
break;
|
||||
case GN_CRAZYWEED_ATK:
|
||||
skillratio += 400 + 100 * skill_lv;
|
||||
break;
|
||||
case GN_SLINGITEM_RANGEMELEEATK:
|
||||
if( sd ) {
|
||||
switch( sd->itemid ) {
|
||||
case 13260: // Apple Bomob
|
||||
case 13261: // Coconut Bomb
|
||||
case 13262: // Melon Bomb
|
||||
case 13263: // Pinapple Bomb
|
||||
skillratio += 400; // Unconfirded
|
||||
break;
|
||||
case 13264: // Banana Bomb 2000%
|
||||
skillratio += 1900;
|
||||
break;
|
||||
case 13265: skillratio -= 75; break; // Black Lump 25%
|
||||
case 13266: skillratio -= 25; break; // Hard Black Lump 75%
|
||||
case 13267: skillratio += 100; break; // Extremely Hard Black Lump 200%
|
||||
}
|
||||
} else
|
||||
skillratio += 300; // Bombs
|
||||
break;
|
||||
case SO_VARETYR_SPEAR: //Assumed Formula.
|
||||
skillratio += -100 + 200 * ( sd ? pc_checkskill(sd, SA_LIGHTNINGLOADER) : 1 );
|
||||
if( sc && sc->data[SC_BLAST_OPTION] )
|
||||
skillratio += skillratio * sc->data[SC_BLAST_OPTION]->val2 / 100;
|
||||
break;
|
||||
// Physical Elemantal Spirits Attack Skills
|
||||
case EL_CIRCLE_OF_FIRE:
|
||||
case EL_FIRE_BOMB_ATK:
|
||||
case EL_STONE_RAIN:
|
||||
skillratio += 200;
|
||||
break;
|
||||
case EL_FIRE_WAVE_ATK:
|
||||
skillratio += 500;
|
||||
break;
|
||||
case EL_TIDAL_WEAPON:
|
||||
skillratio += 1400;
|
||||
break;
|
||||
case EL_WIND_SLASH:
|
||||
skillratio += 100;
|
||||
break;
|
||||
case EL_HURRICANE:
|
||||
skillratio += 600;
|
||||
break;
|
||||
case EL_TYPOON_MIS:
|
||||
case EL_WATER_SCREW_ATK:
|
||||
skillratio += 900;
|
||||
break;
|
||||
case EL_STONE_HAMMER:
|
||||
skillratio += 400;
|
||||
break;
|
||||
case EL_ROCK_CRUSHER:
|
||||
skillratio += 700;
|
||||
break;
|
||||
}
|
||||
|
||||
ATK_RATE(skillratio);
|
||||
@ -2920,7 +3024,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
|
||||
struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag)
|
||||
{
|
||||
int i, nk;
|
||||
short s_ele;
|
||||
short s_ele = 0;
|
||||
unsigned int skillratio = 100; //Skill dmg modifiers.
|
||||
|
||||
struct map_session_data *sd, *tsd;
|
||||
@ -2954,16 +3058,38 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
sd = BL_CAST(BL_PC, src);
|
||||
tsd = BL_CAST(BL_PC, target);
|
||||
|
||||
//Initialize variables that will be used afterwards
|
||||
s_ele = skill_get_ele(skill_num, skill_lv);
|
||||
if( skill_num == SO_PSYCHIC_WAVE ) {
|
||||
struct status_change *sc = status_get_sc(src);
|
||||
if( sc && sc->count && ( sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] ||
|
||||
sc->data[SC_BLAST_OPTION] || sc->data[SC_CURSED_SOIL_OPTION] ) ) {
|
||||
if( sc->data[SC_HEATER_OPTION] ) s_ele = sc->data[SC_HEATER_OPTION]->val4;
|
||||
else if( sc->data[SC_COOLER_OPTION] ) s_ele = sc->data[SC_COOLER_OPTION]->val4;
|
||||
else if( sc->data[SC_BLAST_OPTION] ) s_ele = sc->data[SC_BLAST_OPTION]->val3;
|
||||
else if( sc->data[SC_CURSED_SOIL_OPTION] ) s_ele = sc->data[SC_CURSED_SOIL_OPTION]->val4;
|
||||
} else {
|
||||
//#HALP# I didn't get a clue on how to do this without unnecessary adding a overhead of status_change on every call while this is a per-skill case.
|
||||
//, - so i duplicated this code. make yourself comfortable to fix if you have any better ideas.
|
||||
//Initialize variables that will be used afterwards
|
||||
s_ele = skill_get_ele(skill_num, skill_lv);
|
||||
|
||||
if (s_ele == -1) // pl=-1 : the skill takes the weapon's element
|
||||
s_ele = sstatus->rhw.ele;
|
||||
else if (s_ele == -2) //Use status element
|
||||
s_ele = status_get_attack_sc_element(src,status_get_sc(src));
|
||||
else if( s_ele == -3 ) //Use random element
|
||||
s_ele = rnd()%ELE_MAX;
|
||||
}
|
||||
} else {
|
||||
//Initialize variables that will be used afterwards
|
||||
s_ele = skill_get_ele(skill_num, skill_lv);
|
||||
|
||||
if (s_ele == -1) // pl=-1 : the skill takes the weapon's element
|
||||
s_ele = sstatus->rhw.ele;
|
||||
else if (s_ele == -2) //Use status element
|
||||
s_ele = status_get_attack_sc_element(src,status_get_sc(src));
|
||||
else if( s_ele == -3 ) //Use random element
|
||||
s_ele = rnd()%ELE_MAX;
|
||||
|
||||
if (s_ele == -1) // pl=-1 : the skill takes the weapon's element
|
||||
s_ele = sstatus->rhw.ele;
|
||||
else if (s_ele == -2) //Use status element
|
||||
s_ele = status_get_attack_sc_element(src,status_get_sc(src));
|
||||
else if( s_ele == -3 ) //Use random element
|
||||
s_ele = rnd()%ELE_MAX;
|
||||
}
|
||||
//Set miscellaneous data that needs be filled
|
||||
if(sd) {
|
||||
sd->state.arrow_atk = 0;
|
||||
@ -3334,6 +3460,24 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
else
|
||||
skillratio += 110 + 20 * skill_lv;
|
||||
break;
|
||||
// Magical Elemental Spirits Attack Skills
|
||||
case EL_FIRE_MANTLE:
|
||||
case EL_WATER_SCREW:
|
||||
skillratio += 900;
|
||||
break;
|
||||
case EL_FIRE_ARROW:
|
||||
case EL_ROCK_CRUSHER_ATK:
|
||||
skillratio += 200;
|
||||
break;
|
||||
case EL_FIRE_BOMB:
|
||||
case EL_ICE_NEEDLE:
|
||||
case EL_HURRICANE_ATK:
|
||||
skillratio += 400;
|
||||
break;
|
||||
case EL_FIRE_WAVE:
|
||||
case EL_TYPOON_MIS_ATK:
|
||||
skillratio += 1100;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
@ -3493,6 +3637,13 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
ad.damage=battle_calc_gvg_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
|
||||
else if( map[target->m].flag.battleground )
|
||||
ad.damage=battle_calc_bg_damage(src,target,ad.damage,ad.div_,skill_num,skill_lv,ad.flag);
|
||||
|
||||
|
||||
if( skill_num == SO_VARETYR_SPEAR ) { // Physical damage.
|
||||
struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
|
||||
ad.damage += wd.damage;
|
||||
}
|
||||
|
||||
return ad;
|
||||
}
|
||||
|
||||
@ -3675,7 +3826,15 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
if (sd) md.damage = md.damage + status_get_hp(src);
|
||||
status_set_sp(src, 0, 0);
|
||||
break;
|
||||
|
||||
case GN_THORNS_TRAP:
|
||||
md.damage = 100 + 200 * skill_lv + sstatus->int_;
|
||||
break;
|
||||
case GN_BLOOD_SUCKER:
|
||||
md.damage = 200 + 100 * skill_lv + sstatus->int_;
|
||||
break;
|
||||
case GN_HELLS_PLANT_ATK:
|
||||
md.damage = sstatus->int_ * 4 * skill_lv * (10 / (10 - pc_checkskill(sd,AM_CANNIBALIZE)));//Need accurate official formula. [Rytech]
|
||||
break;
|
||||
}
|
||||
|
||||
if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets
|
||||
@ -4168,24 +4327,38 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
map_freeblock_lock();
|
||||
|
||||
battle_delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion);
|
||||
if( tsc ) {
|
||||
if( tsc->data[SC_DEVOTION] ) {
|
||||
struct status_change_entry *sce = tsc->data[SC_DEVOTION];
|
||||
struct block_list *d_bl = map_id2bl(sce->val1);
|
||||
|
||||
if( tsc && tsc->data[SC_DEVOTION] )
|
||||
{
|
||||
struct status_change_entry *sce = tsc->data[SC_DEVOTION];
|
||||
struct block_list *d_bl = map_id2bl(sce->val1);
|
||||
|
||||
if( d_bl && (
|
||||
(d_bl->type == BL_MER && ((TBL_MER*)d_bl)->master && ((TBL_MER*)d_bl)->master->bl.id == target->id) ||
|
||||
(d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == target->id)
|
||||
) && check_distance_bl(target, d_bl, sce->val3) )
|
||||
{
|
||||
clif_damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, 0, 0);
|
||||
status_fix_damage(NULL, d_bl, damage, 0);
|
||||
}
|
||||
else
|
||||
status_change_end(target, SC_DEVOTION, INVALID_TIMER);
|
||||
if( d_bl && (
|
||||
(d_bl->type == BL_MER && ((TBL_MER*)d_bl)->master && ((TBL_MER*)d_bl)->master->bl.id == target->id) ||
|
||||
(d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == target->id)
|
||||
) && check_distance_bl(target, d_bl, sce->val3) )
|
||||
{
|
||||
clif_damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, 0, 0);
|
||||
status_fix_damage(NULL, d_bl, damage, 0);
|
||||
}
|
||||
else
|
||||
status_change_end(target, SC_DEVOTION, INVALID_TIMER);
|
||||
} else if( tsc->data[SC_CIRCLE_OF_FIRE_OPTION] && (wd.flag&BF_SHORT) && target->type == BL_PC ) {
|
||||
struct elemental_data *ed = ((TBL_PC*)target)->ed;
|
||||
if( ed ) {
|
||||
clif_skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, 6);
|
||||
skill_attack(BF_MAGIC,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag);
|
||||
}
|
||||
} else if( tsc->data[SC_WATER_SCREEN_OPTION] && tsc->data[SC_WATER_SCREEN_OPTION]->val1 ) {
|
||||
struct block_list *e_bl = map_id2bl(tsc->data[SC_WATER_SCREEN_OPTION]->val1);
|
||||
if( e_bl && !status_isdead(e_bl) ) {
|
||||
clif_damage(e_bl,e_bl,tick,wd.amotion,wd.dmotion,damage,wd.div_,wd.type,wd.damage2);
|
||||
status_damage(target,e_bl,damage,0,0,0);
|
||||
// Just show damage in target.
|
||||
clif_damage(src, target, tick, wd.amotion, wd.dmotion, damage, wd.div_, wd.type, wd.damage2 );
|
||||
return ATK_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sc && sc->data[SC_AUTOSPELL] && rnd()%100 < sc->data[SC_AUTOSPELL]->val4) {
|
||||
int sp = 0;
|
||||
int skillid = sc->data[SC_AUTOSPELL]->val2;
|
||||
@ -4314,6 +4487,10 @@ struct block_list* battle_get_master(struct block_list *src)
|
||||
if (((TBL_MER*)src)->master)
|
||||
src = (struct block_list*)((TBL_MER*)src)->master;
|
||||
break;
|
||||
case BL_ELEM:
|
||||
if (((TBL_ELEM*)src)->master)
|
||||
src = (struct block_list*)((TBL_ELEM*)src)->master;
|
||||
break;
|
||||
case BL_SKILL:
|
||||
if (((TBL_SKILL*)src)->group && ((TBL_SKILL*)src)->group->src_id)
|
||||
src = map_id2bl(((TBL_SKILL*)src)->group->src_id);
|
||||
@ -4409,6 +4586,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
|
||||
//Valid targets with no special checks here.
|
||||
case BL_MER:
|
||||
case BL_HOM:
|
||||
case BL_ELEM:
|
||||
break;
|
||||
//All else not specified is an invalid target.
|
||||
default:
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "homunculus.h"
|
||||
#include "instance.h"
|
||||
#include "mercenary.h"
|
||||
#include "elemental.h"
|
||||
#include "chrif.h"
|
||||
#include "quest.h"
|
||||
#include "storage.h"
|
||||
@ -307,6 +308,8 @@ int chrif_save(struct map_session_data *sd, int flag)
|
||||
merc_save(sd->hd);
|
||||
if( sd->md && mercenary_get_lifetime(sd->md) > 0 )
|
||||
mercenary_save(sd->md);
|
||||
if( sd->ed && elemental_get_lifetime(sd->ed) > 0 )
|
||||
elemental_save(sd->ed);
|
||||
if( sd->save_quest )
|
||||
intif_quest_save(sd);
|
||||
|
||||
|
305
src/map/clif.c
305
src/map/clif.c
@ -36,6 +36,7 @@
|
||||
#include "homunculus.h"
|
||||
#include "instance.h"
|
||||
#include "mercenary.h"
|
||||
#include "elemental.h"
|
||||
#include "log.h"
|
||||
#include "clif.h"
|
||||
#include "mail.h"
|
||||
@ -273,7 +274,7 @@ static inline unsigned char clif_bl_type(struct block_list *bl) {
|
||||
case BL_PET: return pcdb_checkid(status_get_viewdata(bl)->class_)?0x0:0x7; //NPC_PET_TYPE
|
||||
case BL_HOM: return 0x8; //NPC_HOM_TYPE
|
||||
case BL_MER: return 0x9; //NPC_MERSOL_TYPE
|
||||
// case BL_ELEM: return 0xA; //NPC_ELEMENTAL_TYPE
|
||||
case BL_ELEM: return 0xa; //NPC_ELEMENTAL_TYPE
|
||||
default: return 0x1; //NPC_TYPE
|
||||
}
|
||||
}
|
||||
@ -5193,44 +5194,60 @@ void clif_skill_produce_mix_list(struct map_session_data *sd, int skillid , int
|
||||
/// 4 = GN_MIX_COOKING
|
||||
/// 5 = GN_MAKEBOMB
|
||||
/// 6 = GN_S_PHARMACY
|
||||
void clif_cooking_list(struct map_session_data *sd, int trigger)
|
||||
void clif_cooking_list(struct map_session_data *sd, int trigger, int skill_id, int qty, int list_type)
|
||||
{
|
||||
int fd;
|
||||
int i, c;
|
||||
int view;
|
||||
|
||||
|
||||
nullpo_retv(sd);
|
||||
fd = sd->fd;
|
||||
|
||||
WFIFOHEAD(fd, 6 + 2*MAX_SKILL_PRODUCE_DB);
|
||||
|
||||
WFIFOHEAD(fd, 6 + 2 * MAX_SKILL_PRODUCE_DB);
|
||||
WFIFOW(fd,0) = 0x25a;
|
||||
WFIFOW(fd,4) = 1; // list type
|
||||
|
||||
WFIFOW(fd,4) = list_type; // list type
|
||||
|
||||
c = 0;
|
||||
for( i = 0; i < MAX_SKILL_PRODUCE_DB; i++ )
|
||||
{
|
||||
if( !skill_can_produce_mix(sd,skill_produce_db[i].nameid,trigger, 1) )
|
||||
for( i = 0; i < MAX_SKILL_PRODUCE_DB; i++ ) {
|
||||
if( !skill_can_produce_mix(sd,skill_produce_db[i].nameid,trigger, qty) )
|
||||
continue;
|
||||
|
||||
|
||||
if( (view = itemdb_viewid(skill_produce_db[i].nameid)) > 0 )
|
||||
WFIFOW(fd, 6+2*c)= view;
|
||||
WFIFOW(fd, 6 + 2 * c) = view;
|
||||
else
|
||||
WFIFOW(fd, 6+2*c)= skill_produce_db[i].nameid;
|
||||
|
||||
WFIFOW(fd, 6 + 2 * c) = skill_produce_db[i].nameid;
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
WFIFOW(fd,2) = 6 + 2*c;
|
||||
WFIFOSET(fd,WFIFOW(fd,2));
|
||||
|
||||
//TODO: replace with proper solution
|
||||
if( c > 0 )
|
||||
{
|
||||
sd->menuskill_id = AM_PHARMACY;
|
||||
|
||||
if( skill_id == AM_PHARMACY ) { // Only send it while Cooking else check for c.
|
||||
WFIFOW(fd,2) = 6 + 2 * c;
|
||||
WFIFOSET(fd,WFIFOW(fd,2));
|
||||
}
|
||||
|
||||
if( c > 0 ) {
|
||||
sd->menuskill_id = skill_id;
|
||||
sd->menuskill_val = trigger;
|
||||
if( skill_id != AM_PHARMACY ) {
|
||||
sd->menuskill_val2 = qty; // amount.
|
||||
WFIFOW(fd,2) = 6 + 2 * c;
|
||||
WFIFOSET(fd,WFIFOW(fd,2));
|
||||
}
|
||||
} else {
|
||||
clif_menuskill_clear(sd);
|
||||
if( skill_id != AM_PHARMACY ) { // AM_PHARMACY is used to Cooking.
|
||||
// It fails.
|
||||
#if PACKETVER >= 20090922
|
||||
clif_msg_skill(sd,skill_id,0x625);
|
||||
#else
|
||||
WFIFOW(fd,2) = 6 + 2 * c;
|
||||
WFIFOSET(fd,WFIFOW(fd,2));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Notifies clients of a status change.
|
||||
/// 0196 <index>.W <id>.L <state>.B (ZC_MSG_STATE_CHANGE) [used for ending status changes and starting them on non-pc units (when needed)]
|
||||
/// 043f <index>.W <id>.L <state>.B <remain msec>.L { <val>.L }*3 (ZC_MSG_STATE_CHANGE2) [used exclusively for starting statuses on pcs]
|
||||
@ -8107,11 +8124,12 @@ void clif_refresh(struct map_session_data *sd)
|
||||
clif_refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
|
||||
if(merc_is_hom_active(sd->hd))
|
||||
clif_send_homdata(sd,SP_ACK,0);
|
||||
if( sd->md )
|
||||
{
|
||||
if( sd->md ) {
|
||||
clif_mercenary_info(sd);
|
||||
clif_mercenary_skillblock(sd);
|
||||
}
|
||||
if( sd->ed )
|
||||
clif_elemental_info(sd);
|
||||
map_foreachinrange(clif_getareachar,&sd->bl,AREA_SIZE,BL_ALL,sd);
|
||||
clif_weather_check(sd);
|
||||
if( sd->chatID )
|
||||
@ -8255,6 +8273,9 @@ void clif_charnameack (int fd, struct block_list *bl)
|
||||
// memcpy(WBUFP(buf,6), (struct chat*)->title, NAME_LENGTH);
|
||||
// break;
|
||||
return;
|
||||
case BL_ELEM:
|
||||
memcpy(WBUFP(buf,6), ((TBL_ELEM*)bl)->db->name, NAME_LENGTH);
|
||||
break;
|
||||
default:
|
||||
ShowError("clif_charnameack: bad type %d(%d)\n", bl->type, bl->id);
|
||||
return;
|
||||
@ -9082,14 +9103,22 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
||||
skill_unit_move(&sd->hd->bl,gettick(),1); // apply land skills immediately
|
||||
}
|
||||
|
||||
if( sd->md )
|
||||
{
|
||||
if( sd->md ) {
|
||||
map_addblock(&sd->md->bl);
|
||||
clif_spawn(&sd->md->bl);
|
||||
clif_mercenary_info(sd);
|
||||
clif_mercenary_skillblock(sd);
|
||||
}
|
||||
|
||||
if( sd->ed ) {
|
||||
map_addblock(&sd->ed->bl);
|
||||
clif_spawn(&sd->ed->bl);
|
||||
clif_elemental_info(sd);
|
||||
clif_elemental_updatestatus(sd,SP_HP);
|
||||
clif_hpmeter_single(sd->fd,sd->ed->bl.id,sd->ed->battle_status.hp,sd->ed->battle_status.matk_max);
|
||||
clif_elemental_updatestatus(sd,SP_SP);
|
||||
}
|
||||
|
||||
if(sd->state.connect_new) {
|
||||
int lv;
|
||||
sd->state.connect_new = 0;
|
||||
@ -10587,15 +10616,13 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
|
||||
if( sd->sc.data[SC_BASILICA] && (skillnum != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) )
|
||||
return; // On basilica only caster can use Basilica again to stop it.
|
||||
|
||||
if( sd->menuskill_id )
|
||||
{
|
||||
if( sd->menuskill_id == SA_TAMINGMONSTER )
|
||||
sd->menuskill_id = sd->menuskill_val = 0; //Cancel pet capture.
|
||||
else if( sd->menuskill_id != SA_AUTOSPELL )
|
||||
if( sd->menuskill_id ) {
|
||||
if( sd->menuskill_id == SA_TAMINGMONSTER ) {
|
||||
clif_menuskill_clear(sd); //Cancel pet capture.
|
||||
} else if( sd->menuskill_id != SA_AUTOSPELL )
|
||||
return; //Can't use skills while a menu is open.
|
||||
}
|
||||
if( sd->skillitem == skillnum )
|
||||
{
|
||||
if( sd->skillitem == skillnum ) {
|
||||
if( skilllv != sd->skillitemlv )
|
||||
skilllv = sd->skillitemlv;
|
||||
if( !(tmp&INF_SELF_SKILL) )
|
||||
@ -10606,15 +10633,12 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
|
||||
|
||||
sd->skillitem = sd->skillitemlv = 0;
|
||||
|
||||
if( skillnum >= GD_SKILLBASE )
|
||||
{
|
||||
if( skillnum >= GD_SKILLBASE ) {
|
||||
if( sd->state.gmaster_flag )
|
||||
skilllv = guild_checkskill(sd->state.gmaster_flag, skillnum);
|
||||
else
|
||||
skilllv = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
tmp = pc_checkskill(sd, skillnum);
|
||||
if( skilllv > tmp )
|
||||
skilllv = tmp;
|
||||
@ -10661,10 +10685,8 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, sho
|
||||
if( sd->ud.skilltimer != INVALID_TIMER )
|
||||
return;
|
||||
|
||||
if( DIFF_TICK(tick, sd->ud.canact_tick) < 0 )
|
||||
{
|
||||
if( sd->skillitem != skillnum )
|
||||
{
|
||||
if( DIFF_TICK(tick, sd->ud.canact_tick) < 0 ) {
|
||||
if( sd->skillitem != skillnum ) {
|
||||
clif_skill_fail(sd, skillnum, USESKILL_FAIL_SKILLINTERVAL, 0);
|
||||
return;
|
||||
}
|
||||
@ -10676,28 +10698,23 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, sho
|
||||
if( sd->sc.data[SC_BASILICA] && (skillnum != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) )
|
||||
return; // On basilica only caster can use Basilica again to stop it.
|
||||
|
||||
if( sd->menuskill_id )
|
||||
{
|
||||
if( sd->menuskill_id == SA_TAMINGMONSTER )
|
||||
sd->menuskill_id = sd->menuskill_val = 0; //Cancel pet capture.
|
||||
else if( sd->menuskill_id != SA_AUTOSPELL )
|
||||
if( sd->menuskill_id ) {
|
||||
if( sd->menuskill_id == SA_TAMINGMONSTER ) {
|
||||
clif_menuskill_clear(sd); //Cancel pet capture.
|
||||
} else if( sd->menuskill_id != SA_AUTOSPELL )
|
||||
return; //Can't use skills while a menu is open.
|
||||
}
|
||||
|
||||
pc_delinvincibletimer(sd);
|
||||
|
||||
if( sd->skillitem == skillnum )
|
||||
{
|
||||
if( sd->skillitem == skillnum ) {
|
||||
if( skilllv != sd->skillitemlv )
|
||||
skilllv = sd->skillitemlv;
|
||||
unit_skilluse_pos(&sd->bl, x, y, skillnum, skilllv);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int lv;
|
||||
sd->skillitem = sd->skillitemlv = 0;
|
||||
if( (lv = pc_checkskill(sd, skillnum)) > 0 )
|
||||
{
|
||||
if( (lv = pc_checkskill(sd, skillnum)) > 0 ) {
|
||||
if( skilllv > lv )
|
||||
skilllv = lv;
|
||||
unit_skilluse_pos(&sd->bl, x, y, skillnum,skilllv);
|
||||
@ -10759,9 +10776,8 @@ void clif_parse_UseSkillMap(int fd, struct map_session_data* sd)
|
||||
if(skill_num != sd->menuskill_id)
|
||||
return;
|
||||
|
||||
if( pc_cant_act(sd) )
|
||||
{
|
||||
sd->menuskill_id = sd->menuskill_val = 0;
|
||||
if( pc_cant_act(sd) ) {
|
||||
clif_menuskill_clear(sd);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -10795,12 +10811,12 @@ void clif_parse_ProduceMix(int fd,struct map_session_data *sd)
|
||||
if (pc_istrading(sd)) {
|
||||
//Make it fail to avoid shop exploits where you sell something different than you see.
|
||||
clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
return;
|
||||
}
|
||||
if( skill_can_produce_mix(sd,RFIFOW(fd,2),sd->menuskill_val, 1) )
|
||||
skill_produce_mix(sd,0,RFIFOW(fd,2),RFIFOW(fd,4),RFIFOW(fd,6),RFIFOW(fd,8), 1);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
}
|
||||
|
||||
|
||||
@ -10813,24 +10829,22 @@ void clif_parse_ProduceMix(int fd,struct map_session_data *sd)
|
||||
/// 4 = GN_MIX_COOKING
|
||||
/// 5 = GN_MAKEBOMB
|
||||
/// 6 = GN_S_PHARMACY
|
||||
void clif_parse_Cooking(int fd,struct map_session_data *sd)
|
||||
{
|
||||
//int type = RFIFOW(fd,2);
|
||||
void clif_parse_Cooking(int fd,struct map_session_data *sd) {
|
||||
int type = RFIFOW(fd,2);
|
||||
int nameid = RFIFOW(fd,4);
|
||||
|
||||
if( sd->menuskill_id != AM_PHARMACY ) {
|
||||
int amount = sd->menuskill_val2?sd->menuskill_val2:1;
|
||||
if( type == 6 && sd->menuskill_id != GN_MIX_COOKING && sd->menuskill_id != GN_S_PHARMACY )
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (pc_istrading(sd)) {
|
||||
//Make it fail to avoid shop exploits where you sell something different than you see.
|
||||
clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
return;
|
||||
}
|
||||
if( skill_can_produce_mix(sd,nameid,sd->menuskill_val, 1) )
|
||||
skill_produce_mix(sd,0,nameid,0,0,0,1);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
if( skill_can_produce_mix(sd,nameid,sd->menuskill_val, amount) )
|
||||
skill_produce_mix(sd,sd->menuskill_id,nameid,0,0,0,amount);
|
||||
clif_menuskill_clear(sd);
|
||||
}
|
||||
|
||||
|
||||
@ -10843,11 +10857,11 @@ void clif_parse_RepairItem(int fd, struct map_session_data *sd)
|
||||
if (pc_istrading(sd)) {
|
||||
//Make it fail to avoid shop exploits where you sell something different than you see.
|
||||
clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
return;
|
||||
}
|
||||
skill_repairweapon(sd,RFIFOW(fd,2));
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
}
|
||||
|
||||
|
||||
@ -10862,12 +10876,12 @@ void clif_parse_WeaponRefine(int fd, struct map_session_data *sd)
|
||||
if (pc_istrading(sd)) {
|
||||
//Make it fail to avoid shop exploits where you sell something different than you see.
|
||||
clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
return;
|
||||
}
|
||||
idx = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
|
||||
skill_weaponrefine(sd, idx-2);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
}
|
||||
|
||||
|
||||
@ -10952,13 +10966,12 @@ void clif_parse_ItemIdentify(int fd,struct map_session_data *sd)
|
||||
|
||||
if (sd->menuskill_id != MC_IDENTIFY)
|
||||
return;
|
||||
if( idx == -1 )
|
||||
{// cancel pressed
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
if( idx == -1 ) {// cancel pressed
|
||||
clif_menuskill_clear(sd);
|
||||
return;
|
||||
}
|
||||
skill_identify(sd,idx-2);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
}
|
||||
|
||||
|
||||
@ -10969,7 +10982,7 @@ void clif_parse_SelectArrow(int fd,struct map_session_data *sd)
|
||||
if (pc_istrading(sd)) {
|
||||
//Make it fail to avoid shop exploits where you sell something different than you see.
|
||||
clif_skill_fail(sd,sd->ud.skillid,USESKILL_FAIL_LEVEL,0);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
return;
|
||||
}
|
||||
switch( sd->menuskill_id ) {
|
||||
@ -10990,7 +11003,7 @@ void clif_parse_SelectArrow(int fd,struct map_session_data *sd)
|
||||
break;
|
||||
}
|
||||
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
}
|
||||
|
||||
|
||||
@ -11001,7 +11014,7 @@ void clif_parse_AutoSpell(int fd,struct map_session_data *sd)
|
||||
if (sd->menuskill_id != SA_AUTOSPELL)
|
||||
return;
|
||||
skill_autospell(sd,RFIFOL(fd,2));
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
}
|
||||
|
||||
|
||||
@ -12074,7 +12087,7 @@ void clif_parse_SelectEgg(int fd, struct map_session_data *sd)
|
||||
return;
|
||||
}
|
||||
pet_select_egg(sd,RFIFOW(fd,2)-2);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
}
|
||||
|
||||
|
||||
@ -13038,7 +13051,7 @@ void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd)
|
||||
// clif_misceffect2(&sd->bl, 0x1b0);
|
||||
// clif_misceffect2(&sd->bl, 0x21f);
|
||||
clif_feel_info(sd, i, 0);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
}
|
||||
|
||||
|
||||
@ -15051,6 +15064,94 @@ void clif_parse_LessEffect(int fd, struct map_session_data* sd)
|
||||
sd->state.lesseffect = ( isLess != 0 );
|
||||
}
|
||||
|
||||
/// S 07e4 <length>.w <option>.l <val>.l {<index>.w <amount>.w).4b*
|
||||
void clif_parse_ItemListWindowSelected(int fd, struct map_session_data* sd) {
|
||||
int n = (RFIFOW(fd,2)-12) / 4;
|
||||
int type = RFIFOL(fd,4);
|
||||
int flag = RFIFOL(fd,8); // Button clicked: 0 = Cancel, 1 = OK
|
||||
unsigned short* item_list = (unsigned short*)RFIFOP(fd,12);
|
||||
|
||||
if( sd->state.trading || sd->npc_shopid )
|
||||
return;
|
||||
|
||||
if( flag == 0 || n == 0) {
|
||||
clif_menuskill_clear(sd);
|
||||
return; // Canceled by player.
|
||||
}
|
||||
|
||||
if( sd->menuskill_id != SO_EL_ANALYSIS && sd->menuskill_id != GN_CHANGEMATERIAL ) {
|
||||
clif_menuskill_clear(sd);
|
||||
return; // Prevent hacking.
|
||||
}
|
||||
|
||||
switch( type ) {
|
||||
case 0: // Change Material
|
||||
skill_changematerial(sd,n,item_list);
|
||||
break;
|
||||
case 1: // Level 1: Pure to Rough
|
||||
case 2: // Level 2: Rough to Pure
|
||||
skill_elementalanalysis(sd,n,type,item_list);
|
||||
break;
|
||||
}
|
||||
clif_menuskill_clear(sd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Elemental System
|
||||
*==========================================*/
|
||||
void clif_elemental_updatestatus(struct map_session_data *sd, int type) {
|
||||
struct elemental_data *ed;
|
||||
struct status_data *status;
|
||||
int fd;
|
||||
|
||||
if( sd == NULL || (ed = sd->ed) == NULL )
|
||||
return;
|
||||
|
||||
fd = sd->fd;
|
||||
status = &ed->battle_status;
|
||||
WFIFOHEAD(fd,8);
|
||||
WFIFOW(fd,0) = 0x81e;
|
||||
WFIFOW(fd,2) = type;
|
||||
switch( type ) {
|
||||
case SP_HP:
|
||||
WFIFOL(fd,4) = status->hp;
|
||||
break;
|
||||
case SP_MAXHP:
|
||||
WFIFOL(fd,4) = status->max_hp;
|
||||
break;
|
||||
case SP_SP:
|
||||
WFIFOL(fd,4) = status->sp;
|
||||
break;
|
||||
case SP_MAXSP:
|
||||
WFIFOL(fd,4) = status->max_sp;
|
||||
break;
|
||||
}
|
||||
WFIFOSET(fd,8);
|
||||
}
|
||||
|
||||
void clif_elemental_info(struct map_session_data *sd) {
|
||||
int fd;
|
||||
struct elemental_data *ed;
|
||||
struct status_data *status;
|
||||
|
||||
if( sd == NULL || (ed = sd->ed) == NULL )
|
||||
return;
|
||||
|
||||
fd = sd->fd;
|
||||
status = &ed->battle_status;
|
||||
|
||||
WFIFOHEAD(fd,22);
|
||||
WFIFOW(fd, 0) = 0x81d;
|
||||
WFIFOL(fd, 2) = ed->bl.id;
|
||||
WFIFOL(fd, 6) = status->hp;
|
||||
WFIFOL(fd,10) = status->max_hp;
|
||||
WFIFOL(fd,14) = status->sp;
|
||||
WFIFOL(fd,18) = status->max_sp;
|
||||
WFIFOSET(fd,22);
|
||||
}
|
||||
|
||||
|
||||
/// Buying Store System
|
||||
///
|
||||
@ -15762,6 +15863,35 @@ int clif_autoshadowspell_list(struct map_session_data *sd) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*===========================================
|
||||
* Skill list for Four Elemental Analysis
|
||||
* and Change Material skills.
|
||||
*------------------------------------------*/
|
||||
int clif_skill_itemlistwindow( struct map_session_data *sd, int skill_id, int skill_lv )
|
||||
{
|
||||
#if PACKETVER >= 20090922
|
||||
int fd;
|
||||
|
||||
nullpo_ret(sd);
|
||||
|
||||
sd->menuskill_id = skill_id; // To prevent hacking.
|
||||
sd->menuskill_val = skill_lv;
|
||||
|
||||
if( skill_id == GN_CHANGEMATERIAL )
|
||||
skill_lv = 0; // Changematerial
|
||||
|
||||
fd = sd->fd;
|
||||
WFIFOHEAD(fd,packet_len(0x7e3));
|
||||
WFIFOW(fd,0) = 0x7e3;
|
||||
WFIFOL(fd,2) = skill_lv;
|
||||
WFIFOL(fd,4) = 0;
|
||||
WFIFOSET(fd,packet_len(0x7e3));
|
||||
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
/**
|
||||
* Sends a new status without a tick (currently used by the new mounts)
|
||||
**/
|
||||
@ -15826,11 +15956,11 @@ void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd) {
|
||||
|
||||
if( pc_istrading(sd) ) {
|
||||
clif_skill_fail(sd,sd->ud.skillid,0,0);
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
return;
|
||||
}
|
||||
skill_select_menu(sd,RFIFOL(fd,2),RFIFOW(fd,6));
|
||||
sd->menuskill_val = sd->menuskill_id = 0;
|
||||
clif_menuskill_clear(sd);
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
@ -16202,13 +16332,13 @@ static int packetdb_readdb(void)
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
//#0x07C0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
#if PACKETVER < 20090617
|
||||
6, 2, -1, 4, 4, 4, 4, 8, 8,254, 6, 8, 6, 54, 30, 54,
|
||||
#else // 0x7d9 changed
|
||||
6, 2, -1, 4, 4, 4, 4, 8, 8,268, 6, 8, 6, 54, 30, 54,
|
||||
#endif
|
||||
0, 15, 8, 0, 0, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0,
|
||||
0, 15, 8, 6, -1, 8, 8, 32, -1, 5, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 14, -1, -1, -1, 8, 25, 0, 0, 26, 0,
|
||||
//#0x0800
|
||||
#if PACKETVER < 20091229
|
||||
@ -16406,6 +16536,7 @@ static int packetdb_readdb(void)
|
||||
{clif_parse_mercenary_action,"mermenu"},
|
||||
{clif_parse_progressbar,"progressbar"},
|
||||
{clif_parse_SkillSelectMenu,"skillselectmenu"},
|
||||
{clif_parse_ItemListWindowSelected,"itemlistwindowselected"},
|
||||
#if PACKETVER >= 20091229
|
||||
{clif_parse_PartyBookingRegisterReq,"bookingregreq"},
|
||||
{clif_parse_PartyBookingSearchReq,"bookingsearchreq"},
|
||||
|
@ -429,7 +429,7 @@ void clif_skill_warppoint(struct map_session_data* sd, short skill_num, short sk
|
||||
void clif_skill_memomessage(struct map_session_data* sd, int type);
|
||||
void clif_skill_teleportmessage(struct map_session_data *sd, int type);
|
||||
void clif_skill_produce_mix_list(struct map_session_data *sd, int skillid, int trigger);
|
||||
void clif_cooking_list(struct map_session_data *sd, int trigger);
|
||||
void clif_cooking_list(struct map_session_data *sd, int trigger, int skill_id, int qty, int list_type);
|
||||
|
||||
void clif_produceeffect(struct map_session_data* sd,int flag,int nameid);
|
||||
|
||||
@ -714,35 +714,27 @@ void clif_search_store_info_click_ack(struct map_session_data* sd, short x, shor
|
||||
**/
|
||||
void clif_msgtable(int fd, int line);
|
||||
void clif_msgtable_num(int fd, int line, int num);
|
||||
/**
|
||||
* Elemental Converter List
|
||||
**/
|
||||
|
||||
int clif_elementalconverter_list(struct map_session_data *sd);
|
||||
/**
|
||||
* Rune Knight
|
||||
**/
|
||||
|
||||
void clif_millenniumshield(struct map_session_data *sd, short shields );
|
||||
/**
|
||||
* Warlock
|
||||
**/
|
||||
|
||||
int clif_spellbook_list(struct map_session_data *sd);
|
||||
/**
|
||||
* Mechanic
|
||||
**/
|
||||
|
||||
int clif_magicdecoy_list(struct map_session_data *sd, int skill_lv, short x, short y);
|
||||
/**
|
||||
* Guilotine Cross
|
||||
**/
|
||||
|
||||
int clif_poison_list(struct map_session_data *sd, int skill_lv);
|
||||
/**
|
||||
* Shadow Chaser
|
||||
**/
|
||||
|
||||
int clif_autoshadowspell_list(struct map_session_data *sd);
|
||||
/**
|
||||
* New Mounts
|
||||
**/
|
||||
|
||||
int clif_status_load_notick(struct block_list *bl,int type,int flag,int val1, int val2, int val3);
|
||||
int clif_status_load_single(int fd, int id,int type,int flag,int val1, int val2, int val3);
|
||||
|
||||
|
||||
int clif_skill_itemlistwindow( struct map_session_data *sd, int skill_id, int skill_lv );
|
||||
void clif_elemental_info(struct map_session_data *sd);
|
||||
void clif_elemental_updatestatus(struct map_session_data *sd, int type);
|
||||
|
||||
/**
|
||||
* Color Table
|
||||
**/
|
||||
@ -753,4 +745,7 @@ enum clif_colors {
|
||||
};
|
||||
unsigned long color_table[COLOR_MAX];
|
||||
int clif_colormes(struct map_session_data * sd, enum clif_colors color, const char* msg);
|
||||
|
||||
#define clif_menuskill_clear(sd) (sd)->menuskill_id = (sd)->menuskill_val = (sd)->menuskill_val2 = 0;
|
||||
|
||||
#endif /* _CLIF_H_ */
|
||||
|
825
src/map/elemental.c
Normal file
825
src/map/elemental.c
Normal file
@ -0,0 +1,825 @@
|
||||
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#include "../common/cbasetypes.h"
|
||||
#include "../common/malloc.h"
|
||||
#include "../common/socket.h"
|
||||
#include "../common/timer.h"
|
||||
#include "../common/nullpo.h"
|
||||
#include "../common/mmo.h"
|
||||
#include "../common/showmsg.h"
|
||||
#include "../common/utils.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "clif.h"
|
||||
#include "chrif.h"
|
||||
#include "intif.h"
|
||||
#include "itemdb.h"
|
||||
#include "map.h"
|
||||
#include "pc.h"
|
||||
#include "status.h"
|
||||
#include "skill.h"
|
||||
#include "mob.h"
|
||||
#include "pet.h"
|
||||
#include "battle.h"
|
||||
#include "party.h"
|
||||
#include "guild.h"
|
||||
#include "atcommand.h"
|
||||
#include "script.h"
|
||||
#include "npc.h"
|
||||
#include "trade.h"
|
||||
#include "unit.h"
|
||||
#include "elemental.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
struct s_elemental_db elemental_db[MAX_ELEMENTAL_CLASS]; // Elemental Database
|
||||
|
||||
int elemental_search_index(int class_) {
|
||||
int i;
|
||||
ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, elemental_db[i].class_ == class_);
|
||||
return (i == MAX_ELEMENTAL_CLASS)?-1:i;
|
||||
}
|
||||
|
||||
bool elemental_class(int class_) {
|
||||
return (bool)(elemental_search_index(class_) > -1);
|
||||
}
|
||||
|
||||
struct view_data * elemental_get_viewdata(int class_) {
|
||||
int i = elemental_search_index(class_);
|
||||
if( i < 0 )
|
||||
return 0;
|
||||
|
||||
return &elemental_db[i].vd;
|
||||
}
|
||||
|
||||
int elemental_create(struct map_session_data *sd, int class_, unsigned int lifetime) {
|
||||
struct s_elemental ele;
|
||||
struct s_elemental_db *db;
|
||||
int i;
|
||||
|
||||
nullpo_retr(1,sd);
|
||||
|
||||
if( (i = elemental_search_index(class_)) < 0 )
|
||||
return 0;
|
||||
|
||||
db = &elemental_db[i];
|
||||
memset(&ele,0,sizeof(struct s_elemental));
|
||||
|
||||
ele.char_id = sd->status.char_id;
|
||||
ele.class_ = class_;
|
||||
ele.mode = EL_MODE_PASSIVE; // Initial mode
|
||||
ele.hp = db->status.max_hp;
|
||||
ele.sp = db->status.max_sp;
|
||||
ele.life_time = lifetime;
|
||||
|
||||
// Request Char Server to create this elemental
|
||||
intif_elemental_create(&ele);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int elemental_get_lifetime(struct elemental_data *ed) {
|
||||
const struct TimerData * td;
|
||||
if( ed == NULL || ed->summon_timer == INVALID_TIMER )
|
||||
return 0;
|
||||
|
||||
td = get_timer(ed->summon_timer);
|
||||
return (td != NULL) ? DIFF_TICK(td->tick, gettick()) : 0;
|
||||
}
|
||||
|
||||
int elemental_save(struct elemental_data *ed) {
|
||||
ed->elemental.hp = ed->battle_status.hp;
|
||||
ed->elemental.sp = ed->battle_status.sp;
|
||||
ed->elemental.life_time = elemental_get_lifetime(ed);
|
||||
|
||||
intif_elemental_save(&ed->elemental);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int elemental_summon_end(int tid, unsigned int tick, int id, intptr data) {
|
||||
struct map_session_data *sd;
|
||||
struct elemental_data *ed;
|
||||
|
||||
if( (sd = map_id2sd(id)) == NULL )
|
||||
return 1;
|
||||
if( (ed = sd->ed) == NULL )
|
||||
return 1;
|
||||
|
||||
if( ed->summon_timer != tid ) {
|
||||
ShowError("elemental_summon_end %d != %d.\n", ed->summon_timer, tid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ed->summon_timer = INVALID_TIMER;
|
||||
elemental_delete(ed, 0); // Elemental's summon time is over.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void elemental_summon_stop(struct elemental_data *ed) {
|
||||
nullpo_retv(ed);
|
||||
if( ed->summon_timer != INVALID_TIMER )
|
||||
delete_timer(ed->summon_timer, elemental_summon_end);
|
||||
ed->summon_timer = INVALID_TIMER;
|
||||
}
|
||||
|
||||
int elemental_delete(struct elemental_data *ed, int reply) {
|
||||
struct map_session_data *sd;
|
||||
|
||||
nullpo_ret(ed);
|
||||
|
||||
sd = ed->master;
|
||||
ed->elemental.life_time = 0;
|
||||
|
||||
elemental_clean_effect(ed);
|
||||
elemental_summon_stop(ed);
|
||||
|
||||
if( !sd )
|
||||
return unit_free(&ed->bl, 0);
|
||||
|
||||
sd->ed = NULL;
|
||||
sd->status.ele_id = 0;
|
||||
|
||||
return unit_remove_map(&ed->bl, 0);
|
||||
}
|
||||
|
||||
void elemental_summon_init(struct elemental_data *ed) {
|
||||
if( ed->summon_timer == INVALID_TIMER )
|
||||
ed->summon_timer = add_timer(gettick() + ed->elemental.life_time, elemental_summon_end, ed->master->bl.id, 0);
|
||||
|
||||
ed->regen.state.block = 0;
|
||||
}
|
||||
|
||||
int elemental_data_received(struct s_elemental *ele, bool flag) {
|
||||
struct map_session_data *sd;
|
||||
struct elemental_data *ed;
|
||||
struct s_elemental_db *db;
|
||||
int i = elemental_search_index(ele->class_);
|
||||
|
||||
if( (sd = map_charid2sd(ele->char_id)) == NULL )
|
||||
return 0;
|
||||
|
||||
if( !flag || i < 0 ) { // Not created - loaded - DB info
|
||||
sd->status.ele_id = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
db = &elemental_db[i];
|
||||
if( !sd->ed ) { // Initialize it after first summon.
|
||||
sd->ed = ed = (struct elemental_data*)aCalloc(1,sizeof(struct elemental_data));
|
||||
ed->bl.type = BL_ELEM;
|
||||
ed->bl.id = npc_get_new_npc_id();
|
||||
ed->master = sd;
|
||||
ed->db = db;
|
||||
memcpy(&ed->elemental, ele, sizeof(struct s_elemental));
|
||||
status_set_viewdata(&ed->bl, ed->elemental.class_);
|
||||
ed->vd->head_mid = 10; // Why?
|
||||
status_change_init(&ed->bl);
|
||||
unit_dataset(&ed->bl);
|
||||
ed->ud.dir = sd->ud.dir;
|
||||
|
||||
ed->bl.m = sd->bl.m;
|
||||
ed->bl.x = sd->bl.x;
|
||||
ed->bl.y = sd->bl.y;
|
||||
unit_calc_pos(&ed->bl, sd->bl.x, sd->bl.y, sd->ud.dir);
|
||||
ed->bl.x = ed->ud.to_x;
|
||||
ed->bl.y = ed->ud.to_y;
|
||||
|
||||
map_addiddb(&ed->bl);
|
||||
status_calc_elemental(ed,1);
|
||||
ed->last_thinktime = gettick();
|
||||
ed->summon_timer = INVALID_TIMER;
|
||||
ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
|
||||
elemental_summon_init(ed);
|
||||
} else {
|
||||
memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental));
|
||||
ed = sd->ed;
|
||||
}
|
||||
|
||||
sd->status.ele_id = ele->elemental_id;
|
||||
ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode.
|
||||
|
||||
if( ed->bl.prev == NULL && sd->bl.prev != NULL ) {
|
||||
map_addblock(&ed->bl);
|
||||
clif_spawn(&ed->bl);
|
||||
clif_elemental_info(sd);
|
||||
clif_elemental_updatestatus(sd,SP_HP);
|
||||
clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.matk_max);
|
||||
clif_elemental_updatestatus(sd,SP_SP);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int elemental_clean_single_effect(struct elemental_data *ed, int skill_num) {
|
||||
struct block_list *bl;
|
||||
sc_type type = status_skill2sc(skill_num);
|
||||
|
||||
nullpo_ret(ed);
|
||||
|
||||
bl = battle_get_master(&ed->bl);
|
||||
|
||||
if( type ) {
|
||||
switch( type ) {
|
||||
// Just remove status change.
|
||||
case SC_PYROTECHNIC_OPTION:
|
||||
case SC_HEATER_OPTION:
|
||||
case SC_TROPIC_OPTION:
|
||||
case SC_FIRE_CLOAK_OPTION:
|
||||
case SC_AQUAPLAY_OPTION:
|
||||
case SC_WATER_SCREEN_OPTION:
|
||||
case SC_COOLER_OPTION:
|
||||
case SC_CHILLY_AIR_OPTION:
|
||||
case SC_GUST_OPTION:
|
||||
case SC_WIND_STEP_OPTION:
|
||||
case SC_BLAST_OPTION:
|
||||
case SC_WATER_DROP_OPTION:
|
||||
case SC_WIND_CURTAIN_OPTION:
|
||||
case SC_WILD_STORM_OPTION:
|
||||
case SC_PETROLOGY_OPTION:
|
||||
case SC_SOLID_SKIN_OPTION:
|
||||
case SC_CURSED_SOIL_OPTION:
|
||||
case SC_STONE_SHIELD_OPTION:
|
||||
case SC_UPHEAVAL_OPTION:
|
||||
case SC_CIRCLE_OF_FIRE_OPTION:
|
||||
case SC_TIDAL_WEAPON_OPTION:
|
||||
if( bl ) status_change_end(bl,type,-1); // Master
|
||||
status_change_end(&ed->bl,type-1,-1); // Elemental Spirit
|
||||
break;
|
||||
case SC_ZEPHYR:
|
||||
if( bl ) status_change_end(bl,type,-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( skill_get_unit_id(skill_num,0) )
|
||||
skill_clear_unitgroup(&ed->bl);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int elemental_clean_effect(struct elemental_data *ed) {
|
||||
struct map_session_data *sd;
|
||||
|
||||
nullpo_ret(ed);
|
||||
|
||||
// Elemental side
|
||||
status_change_end(&ed->bl, SC_TROPIC, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_HEATER, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_AQUAPLAY, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_COOLER, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_CHILLY_AIR, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_PYROTECHNIC, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_FIRE_CLOAK, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_WATER_DROP, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_WATER_SCREEN, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_GUST, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_WIND_STEP, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_BLAST, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_WIND_CURTAIN, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_WILD_STORM, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_PETROLOGY, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_SOLID_SKIN, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_CURSED_SOIL, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_STONE_SHIELD, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_UPHEAVAL, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_CIRCLE_OF_FIRE, INVALID_TIMER);
|
||||
status_change_end(&ed->bl, SC_TIDAL_WEAPON, INVALID_TIMER);
|
||||
|
||||
skill_clear_unitgroup(&ed->bl);
|
||||
|
||||
if( (sd = ed->master) == NULL )
|
||||
return 0;
|
||||
|
||||
// Master side
|
||||
status_change_end(&sd->bl, SC_TROPIC_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_HEATER_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_AQUAPLAY_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_COOLER_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_CHILLY_AIR_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_PYROTECHNIC_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_FIRE_CLOAK_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_WATER_DROP_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_WATER_SCREEN_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_GUST_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_WIND_STEP_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_BLAST_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_WATER_DROP_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_WIND_CURTAIN_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_WILD_STORM_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_ZEPHYR, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_WIND_STEP_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_PETROLOGY_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_SOLID_SKIN_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_CURSED_SOIL_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_STONE_SHIELD_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_UPHEAVAL_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_CIRCLE_OF_FIRE_OPTION, INVALID_TIMER);
|
||||
status_change_end(&sd->bl, SC_TIDAL_WEAPON_OPTION, INVALID_TIMER);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) {
|
||||
short skillnum, skilllv;
|
||||
int i;
|
||||
|
||||
nullpo_ret(ed);
|
||||
nullpo_ret(bl);
|
||||
|
||||
if( !ed->master )
|
||||
return 0;
|
||||
|
||||
if( ed->target_id )
|
||||
elemental_unlocktarget(ed); // Remove previous target.
|
||||
|
||||
ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&EL_SKILLMODE_AGGRESSIVE));
|
||||
if( i == MAX_ELESKILLTREE )
|
||||
return 0;
|
||||
|
||||
skillnum = ed->db->skill[i].id;
|
||||
skilllv = ed->db->skill[i].lv;
|
||||
|
||||
if( elemental_skillnotok(skillnum, ed) )
|
||||
return 0;
|
||||
|
||||
if( ed->ud.skilltimer != -1 )
|
||||
return 0;
|
||||
else if( DIFF_TICK(tick, ed->ud.canact_tick) < 0 )
|
||||
return 0;
|
||||
|
||||
ed->target_id = ed->ud.skilltarget = bl->id; // Set new target
|
||||
ed->last_thinktime = tick;
|
||||
|
||||
// Not in skill range.
|
||||
if( !battle_check_range(&ed->bl,bl,skill_get_range(skillnum,skilllv)) ) {
|
||||
// Try to walk to the target.
|
||||
if( !unit_walktobl(&ed->bl, bl, skill_get_range(skillnum,skilllv), 2) )
|
||||
elemental_unlocktarget(ed);
|
||||
else {
|
||||
// Walking, waiting to be in range. Client don't handle it, then we must handle it here.
|
||||
int walk_dist = distance_bl(&ed->bl,bl) - skill_get_range(skillnum,skilllv);
|
||||
ed->ud.skillid = skillnum;
|
||||
ed->ud.skilllv = skilllv;
|
||||
|
||||
if( skill_get_inf(skillnum) & INF_GROUND_SKILL )
|
||||
ed->ud.skilltimer = add_timer( tick+status_get_speed(&ed->bl)*walk_dist, skill_castend_pos, ed->bl.id, 0 );
|
||||
else
|
||||
ed->ud.skilltimer = add_timer( tick+status_get_speed(&ed->bl)*walk_dist, skill_castend_id, ed->bl.id, 0 );
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
//Otherwise, just cast the skill.
|
||||
if( skill_get_inf(skillnum) & INF_GROUND_SKILL )
|
||||
unit_skilluse_pos(&ed->bl, bl->x, bl->y, skillnum, skilllv);
|
||||
else
|
||||
unit_skilluse_id(&ed->bl, bl->id, skillnum, skilllv);
|
||||
|
||||
// Reset target.
|
||||
ed->target_id = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*===============================================================
|
||||
* Action that elemental perform after changing mode.
|
||||
* Activates one of the skills of the new mode.
|
||||
*-------------------------------------------------------------*/
|
||||
int elemental_change_mode_ack(struct elemental_data *ed, int mode) {
|
||||
struct block_list *bl = &ed->master->bl;
|
||||
short skillnum, skilllv;
|
||||
int i;
|
||||
|
||||
nullpo_ret(ed);
|
||||
|
||||
if( !bl )
|
||||
return 0;
|
||||
|
||||
// Select a skill.
|
||||
ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&mode));
|
||||
if( i == MAX_ELESKILLTREE )
|
||||
return 0;
|
||||
|
||||
skillnum = ed->db->skill[i].id;
|
||||
skilllv = ed->db->skill[i].lv;
|
||||
|
||||
if( elemental_skillnotok(skillnum, ed) )
|
||||
return 0;
|
||||
|
||||
if( ed->ud.skilltimer != -1 )
|
||||
return 0;
|
||||
else if( DIFF_TICK(gettick(), ed->ud.canact_tick) < 0 )
|
||||
return 0;
|
||||
|
||||
ed->target_id = bl->id; // Set new target
|
||||
ed->last_thinktime = gettick();
|
||||
|
||||
if( skill_get_inf(skillnum) & INF_GROUND_SKILL )
|
||||
unit_skilluse_pos(&ed->bl, bl->x, bl->y, skillnum, skilllv);
|
||||
else
|
||||
unit_skilluse_id(&ed->bl,bl->id,skillnum,skilllv);
|
||||
|
||||
ed->target_id = 0; // Reset target after casting the skill to avoid continious attack.
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*===============================================================
|
||||
* Change elemental mode.
|
||||
*-------------------------------------------------------------*/
|
||||
int elemental_change_mode(struct elemental_data *ed, int mode) {
|
||||
nullpo_ret(ed);
|
||||
|
||||
// Remove target
|
||||
elemental_unlocktarget(ed);
|
||||
|
||||
// Removes the effects of the previous mode.
|
||||
if(ed->elemental.mode != mode ) elemental_clean_effect(ed);
|
||||
|
||||
ed->battle_status.mode = ed->elemental.mode = mode;
|
||||
|
||||
// Normalize elemental mode to elemental skill mode.
|
||||
if( mode == EL_MODE_AGGRESSIVE ) mode = EL_SKILLMODE_AGGRESSIVE; // Aggressive spirit mode -> Aggressive spirit skill.
|
||||
else if( mode == EL_MODE_ASSIST ) mode = EL_SKILLMODE_ASSIST; // Assist spirit mode -> Assist spirit skill.
|
||||
else mode = EL_SKILLMODE_PASIVE; // Passive spirit mode -> Passive spirit skill.
|
||||
|
||||
// Use a skill inmediately after every change mode.
|
||||
if( mode != EL_SKILLMODE_AGGRESSIVE )
|
||||
elemental_change_mode_ack(ed,mode);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void elemental_damage(struct elemental_data *ed, struct block_list *src, int hp, int sp) {
|
||||
if( hp )
|
||||
clif_elemental_updatestatus(ed->master, SP_HP);
|
||||
if( sp )
|
||||
clif_elemental_updatestatus(ed->master, SP_SP);
|
||||
}
|
||||
|
||||
void elemental_heal(struct elemental_data *ed, int hp, int sp) {
|
||||
if( hp )
|
||||
clif_elemental_updatestatus(ed->master, SP_HP);
|
||||
if( sp )
|
||||
clif_elemental_updatestatus(ed->master, SP_SP);
|
||||
}
|
||||
|
||||
int elemental_dead(struct elemental_data *ed, struct block_list *src) {
|
||||
elemental_delete(ed, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int elemental_unlocktarget(struct elemental_data *ed) {
|
||||
nullpo_ret(ed);
|
||||
|
||||
ed->target_id = 0;
|
||||
elemental_stop_attack(ed);
|
||||
elemental_stop_walking(ed,1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int elemental_skillnotok(int skillid, struct elemental_data *ed) {
|
||||
int i = skill_get_index(skillid);
|
||||
nullpo_retr(1,ed);
|
||||
|
||||
if (i == 0)
|
||||
return 1; // invalid skill id
|
||||
|
||||
if( ed->blockskill[i] > 0 )
|
||||
return 1;
|
||||
|
||||
return skillnotok(skillid, ed->master);
|
||||
}
|
||||
|
||||
int elemental_set_target( struct map_session_data *sd, struct block_list *bl ) {
|
||||
struct elemental_data *ed = sd->ed;
|
||||
|
||||
nullpo_ret(ed);
|
||||
nullpo_ret(bl);
|
||||
|
||||
if( ed->bl.m != bl->m || !check_distance_bl(&ed->bl, bl, ed->db->range2) )
|
||||
return 0;
|
||||
|
||||
if( !status_check_skilluse(&ed->bl, bl, 0, 0) )
|
||||
return 0;
|
||||
|
||||
if( ed->target_id == 0 )
|
||||
ed->target_id = bl->id;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int elemental_ai_sub_timer_activesearch(struct block_list *bl, va_list ap) {
|
||||
struct elemental_data *ed;
|
||||
struct block_list **target;
|
||||
int dist;
|
||||
|
||||
nullpo_ret(bl);
|
||||
|
||||
ed = va_arg(ap,struct elemental_data *);
|
||||
target = va_arg(ap,struct block_list**);
|
||||
|
||||
//If can't seek yet, not an enemy, or you can't attack it, skip.
|
||||
if( (*target) == bl || !status_check_skilluse(&ed->bl, bl, 0, 0) )
|
||||
return 0;
|
||||
|
||||
if( battle_check_target(&ed->bl,bl,BCT_ENEMY) <= 0 )
|
||||
return 0;
|
||||
|
||||
switch( bl->type ) {
|
||||
case BL_PC:
|
||||
if( !map_flag_vs(ed->bl.m) )
|
||||
return 0;
|
||||
default:
|
||||
dist = distance_bl(&ed->bl, bl);
|
||||
if( ((*target) == NULL || !check_distance_bl(&ed->bl, *target, dist)) && battle_check_range(&ed->bl,bl,ed->db->range2) ) { //Pick closest target?
|
||||
(*target) = bl;
|
||||
ed->target_id = bl->id;
|
||||
ed->min_chase = dist + ed->db->range3;
|
||||
if( ed->min_chase > AREA_SIZE )
|
||||
ed->min_chase = AREA_SIZE;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, unsigned int tick) {
|
||||
struct block_list *target = NULL;
|
||||
int master_dist, view_range, mode;
|
||||
|
||||
nullpo_ret(ed);
|
||||
nullpo_ret(sd);
|
||||
|
||||
if( ed->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL )
|
||||
return 0;
|
||||
|
||||
if( DIFF_TICK(tick,ed->last_thinktime) < MIN_ELETHINKTIME )
|
||||
return 0;
|
||||
|
||||
ed->last_thinktime = tick;
|
||||
|
||||
if( ed->ud.skilltimer != -1 )
|
||||
return 0;
|
||||
|
||||
if( ed->ud.walktimer != -1 && ed->ud.walkpath.path_pos <= 2 )
|
||||
return 0; //No thinking when you just started to walk.
|
||||
|
||||
if(ed->ud.walkpath.path_pos < ed->ud.walkpath.path_len && ed->ud.target == sd->bl.id)
|
||||
return 0; //No thinking until be near the master.
|
||||
|
||||
if( ed->sc.count && ed->sc.data[SC_BLIND] )
|
||||
view_range = 3;
|
||||
else
|
||||
view_range = ed->db->range2;
|
||||
|
||||
mode = status_get_mode(&ed->bl);
|
||||
|
||||
master_dist = distance_bl(&sd->bl, &ed->bl);
|
||||
if( master_dist > AREA_SIZE ) { // Master out of vision range.
|
||||
elemental_unlocktarget(ed);
|
||||
unit_warp(&ed->bl,sd->bl.m,sd->bl.x,sd->bl.y,3);
|
||||
return 0;
|
||||
} else if( master_dist > MAX_ELEDISTANCE ) { // Master too far, chase.
|
||||
short x = sd->bl.x, y = sd->bl.y;
|
||||
if( ed->target_id )
|
||||
elemental_unlocktarget(ed);
|
||||
if( ed->ud.walktimer != -1 && ed->ud.target == sd->bl.id )
|
||||
return 0; //Already walking to him
|
||||
if( DIFF_TICK(tick, ed->ud.canmove_tick) < 0 )
|
||||
return 0; //Can't move yet.
|
||||
if( map_search_freecell(&ed->bl, sd->bl.m, &x, &y, MIN_ELEDISTANCE, MIN_ELEDISTANCE, 1)
|
||||
&& unit_walktoxy(&ed->bl, x, y, 0) )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( mode == EL_MODE_AGGRESSIVE ) {
|
||||
target = map_id2bl(ed->ud.target);
|
||||
|
||||
if( !target )
|
||||
map_foreachinrange(elemental_ai_sub_timer_activesearch, &ed->bl, ed->db->range2, BL_CHAR, ed, &target, status_get_mode(&ed->bl));
|
||||
|
||||
if( !target ) { //No targets available.
|
||||
elemental_unlocktarget(ed);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( battle_check_range(&ed->bl,target,ed->db->range2) && rand()%100 < 2 ) { // 2% chance to cast attack skill.
|
||||
if( elemental_action(ed,target,tick) )
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Attempt to attack.
|
||||
//At this point we know the target is attackable, we just gotta check if the range matches.
|
||||
if( ed->ud.target == target->id && ed->ud.attacktimer != -1 ) //Already locked.
|
||||
return 1;
|
||||
|
||||
if( battle_check_range(&ed->bl, target, ed->base_status.rhw.range) ) {//Target within range, engage
|
||||
unit_attack(&ed->bl,target->id,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Follow up if possible.
|
||||
if( !unit_walktobl(&ed->bl, target, ed->base_status.rhw.range, 2) )
|
||||
elemental_unlocktarget(ed);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int elemental_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) {
|
||||
unsigned int tick = va_arg(ap,unsigned int);
|
||||
if(sd->status.ele_id && sd->ed)
|
||||
elemental_ai_sub_timer(sd->ed,sd,tick);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int elemental_ai_timer(int tid, unsigned int tick, int id, intptr data) {
|
||||
map_foreachpc(elemental_ai_sub_foreachclient,tick);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_elementaldb(void) {
|
||||
FILE *fp;
|
||||
char line[1024], *p;
|
||||
char *str[26];
|
||||
int i, j = 0, k = 0, ele;
|
||||
struct s_elemental_db *db;
|
||||
struct status_data *status;
|
||||
|
||||
sprintf(line, "%s/%s", db_path, "elemental_db.txt");
|
||||
memset(elemental_db,0,sizeof(elemental_db));
|
||||
|
||||
fp = fopen(line, "r");
|
||||
if( !fp ) {
|
||||
ShowError("read_elementaldb : can't read elemental_db.txt\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while( fgets(line, sizeof(line), fp) && j < MAX_ELEMENTAL_CLASS ) {
|
||||
k++;
|
||||
if( line[0] == '/' && line[1] == '/' )
|
||||
continue;
|
||||
|
||||
i = 0;
|
||||
p = strtok(line, ",");
|
||||
while( p != NULL && i < 26 ) {
|
||||
str[i++] = p;
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
if( i < 26 ) {
|
||||
ShowError("read_elementaldb : Incorrect number of columns at elemental_db.txt line %d.\n", k);
|
||||
continue;
|
||||
}
|
||||
|
||||
db = &elemental_db[j];
|
||||
db->class_ = atoi(str[0]);
|
||||
strncpy(db->sprite, str[1], NAME_LENGTH);
|
||||
strncpy(db->name, str[2], NAME_LENGTH);
|
||||
db->lv = atoi(str[3]);
|
||||
|
||||
status = &db->status;
|
||||
db->vd.class_ = db->class_;
|
||||
|
||||
status->max_hp = atoi(str[4]);
|
||||
status->max_sp = atoi(str[5]);
|
||||
status->rhw.range = atoi(str[6]);
|
||||
status->rhw.atk = atoi(str[7]);
|
||||
status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
|
||||
status->def = atoi(str[9]);
|
||||
status->mdef = atoi(str[10]);
|
||||
status->str = atoi(str[11]);
|
||||
status->agi = atoi(str[12]);
|
||||
status->vit = atoi(str[13]);
|
||||
status->int_ = atoi(str[14]);
|
||||
status->dex = atoi(str[15]);
|
||||
status->luk = atoi(str[16]);
|
||||
db->range2 = atoi(str[17]);
|
||||
db->range3 = atoi(str[18]);
|
||||
status->size = atoi(str[19]);
|
||||
status->race = atoi(str[20]);
|
||||
|
||||
ele = atoi(str[21]);
|
||||
status->def_ele = ele%10;
|
||||
status->ele_lv = ele/20;
|
||||
if( status->def_ele >= ELE_MAX ) {
|
||||
ShowWarning("Elemental %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_MAX - 1);
|
||||
status->def_ele = ELE_NEUTRAL;
|
||||
}
|
||||
if( status->ele_lv < 1 || status->ele_lv > 4 ) {
|
||||
ShowWarning("Elemental %d has invalid element level %d (max is 4)\n", db->class_, status->ele_lv);
|
||||
status->ele_lv = 1;
|
||||
}
|
||||
|
||||
status->aspd_rate = 1000;
|
||||
status->speed = atoi(str[22]);
|
||||
status->adelay = atoi(str[23]);
|
||||
status->amotion = atoi(str[24]);
|
||||
status->dmotion = atoi(str[25]);
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' elementals in '"CL_WHITE"db/elemental_db.txt"CL_RESET"'.\n",j);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_elemental_skilldb(void) {
|
||||
FILE *fp;
|
||||
char line[1024], *p;
|
||||
char *str[4];
|
||||
struct s_elemental_db *db;
|
||||
int i, j = 0, k = 0, class_;
|
||||
int skillid, skilllv, skillmode;
|
||||
|
||||
sprintf(line, "%s/%s", db_path, "elemental_skill_db.txt");
|
||||
fp = fopen(line, "r");
|
||||
if( !fp ) {
|
||||
ShowError("read_elemental_skilldb : can't read elemental_skill_db.txt\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while( fgets(line, sizeof(line), fp) ) {
|
||||
k++;
|
||||
if( line[0] == '/' && line[1] == '/' )
|
||||
continue;
|
||||
|
||||
i = 0;
|
||||
p = strtok(line, ",");
|
||||
while( p != NULL && i < 4 ) {
|
||||
str[i++] = p;
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
if( i < 4 ) {
|
||||
ShowError("read_elemental_skilldb : Incorrect number of columns at elemental_skill_db.txt line %d.\n", k);
|
||||
continue;
|
||||
}
|
||||
|
||||
class_ = atoi(str[0]);
|
||||
ARR_FIND(0, MAX_ELEMENTAL_CLASS, i, class_ == elemental_db[i].class_);
|
||||
if( i == MAX_ELEMENTAL_CLASS ) {
|
||||
ShowError("read_elemental_skilldb : Class not found in elemental_db for skill entry, line %d.\n", k);
|
||||
continue;
|
||||
}
|
||||
|
||||
skillid = atoi(str[1]);
|
||||
if( skillid < EL_SKILLBASE || skillid >= EL_SKILLBASE + MAX_ELEMENTALSKILL ) {
|
||||
ShowError("read_elemental_skilldb : Skill out of range, line %d.\n", k);
|
||||
continue;
|
||||
}
|
||||
|
||||
db = &elemental_db[i];
|
||||
skilllv = atoi(str[2]);
|
||||
|
||||
skillmode = atoi(str[3]);
|
||||
if( skillmode < EL_SKILLMODE_PASIVE || skillmode > EL_SKILLMODE_AGGRESSIVE ) {
|
||||
ShowError("read_elemental_skilldb : Skillmode out of range, line %d.\n",k);
|
||||
skillmode = EL_SKILLMODE_PASIVE;
|
||||
continue;
|
||||
}
|
||||
ARR_FIND( 0, MAX_ELESKILLTREE, i, db->skill[i].id == 0 || db->skill[i].id == skillid );
|
||||
if( i == MAX_ELESKILLTREE ) {
|
||||
ShowWarning("Unable to load skill %d into Elemental %d's tree. Maximum number of skills per elemental has been reached.\n", skillid, class_);
|
||||
continue;
|
||||
}
|
||||
db->skill[i].id = skillid;
|
||||
db->skill[i].lv = skilllv;
|
||||
db->skill[i].mode = skillmode;
|
||||
j++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"db/elemental_skill_db.txt"CL_RESET"'.\n",j);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reload_elementaldb(void) {
|
||||
read_elementaldb();
|
||||
reload_elemental_skilldb();
|
||||
}
|
||||
|
||||
void reload_elemental_skilldb(void) {
|
||||
read_elemental_skilldb();
|
||||
}
|
||||
|
||||
int do_init_elemental(void) {
|
||||
read_elementaldb();
|
||||
read_elemental_skilldb();
|
||||
|
||||
add_timer_func_list(elemental_ai_timer,"elemental_ai_timer");
|
||||
add_timer_interval(gettick()+MIN_ELETHINKTIME,elemental_ai_timer,0,0,MIN_ELETHINKTIME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void do_final_elemental(void) {
|
||||
return;
|
||||
}
|
95
src/map/elemental.h
Normal file
95
src/map/elemental.h
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#ifndef _ELEMENTAL_H_
|
||||
#define _ELEMENTAL_H_
|
||||
|
||||
#include "status.h" // struct status_data, struct status_change
|
||||
#include "unit.h" // struct unit_data
|
||||
|
||||
#define MIN_ELETHINKTIME 100
|
||||
#define MIN_ELEDISTANCE 2
|
||||
#define MAX_ELEDISTANCE 6
|
||||
|
||||
#define EL_MODE_AGGRESSIVE (MD_CANMOVE|MD_AGGRESSIVE|MD_CANATTACK)
|
||||
#define EL_MODE_ASSIST (MD_CANMOVE|MD_ASSIST)
|
||||
#define EL_MODE_PASSIVE MD_CANMOVE
|
||||
|
||||
#define EL_SKILLMODE_PASIVE 0x1
|
||||
#define EL_SKILLMODE_ASSIST 0x2
|
||||
#define EL_SKILLMODE_AGGRESSIVE 0x4
|
||||
|
||||
struct elemental_skill {
|
||||
unsigned short id, lv;
|
||||
short mode;
|
||||
};
|
||||
|
||||
struct s_elemental_db {
|
||||
int class_;
|
||||
char sprite[NAME_LENGTH], name[NAME_LENGTH];
|
||||
unsigned short lv;
|
||||
short range2, range3;
|
||||
struct status_data status;
|
||||
struct view_data vd;
|
||||
struct elemental_skill skill[MAX_ELESKILLTREE];
|
||||
};
|
||||
|
||||
extern struct s_elemental_db elemental_db[MAX_ELEMENTAL_CLASS];
|
||||
|
||||
struct elemental_data {
|
||||
struct block_list bl;
|
||||
struct unit_data ud;
|
||||
struct view_data *vd;
|
||||
struct status_data base_status, battle_status;
|
||||
struct status_change sc;
|
||||
struct regen_data regen;
|
||||
|
||||
struct s_elemental_db *db;
|
||||
struct s_elemental elemental;
|
||||
char blockskill[MAX_SKILL];
|
||||
|
||||
struct map_session_data *master;
|
||||
int summon_timer;
|
||||
int skill_timer;
|
||||
|
||||
unsigned last_thinktime, last_linktime;
|
||||
short min_chase;
|
||||
int target_id, attacked_id;
|
||||
};
|
||||
|
||||
bool elemental_class(int class_);
|
||||
struct view_data * elemental_get_viewdata(int class_);
|
||||
|
||||
int elemental_create(struct map_session_data *sd, int class_, unsigned int lifetime);
|
||||
int elemental_data_received(struct s_elemental *ele, bool flag);
|
||||
int elemental_save(struct elemental_data *ed);
|
||||
|
||||
int elemental_change_mode_ack(struct elemental_data *ed, int mode);
|
||||
int elemental_change_mode(struct elemental_data *ed, int mode);
|
||||
|
||||
void elemental_damage(struct elemental_data *ed, struct block_list *src, int hp, int sp);
|
||||
void elemental_heal(struct elemental_data *ed, int hp, int sp);
|
||||
int elemental_dead(struct elemental_data *ed, struct block_list *src);
|
||||
|
||||
int elemental_delete(struct elemental_data *ed, int reply);
|
||||
void elemental_summon_stop(struct elemental_data *ed);
|
||||
|
||||
int elemental_get_lifetime(struct elemental_data *ed);
|
||||
|
||||
int elemental_unlocktarget(struct elemental_data *ed);
|
||||
int elemental_skillnotok(int skillid, struct elemental_data *ed);
|
||||
int elemental_set_target( struct map_session_data *sd, struct block_list *bl );
|
||||
int elemental_clean_single_effect(struct elemental_data *ed, int skill_num);
|
||||
int elemental_clean_effect(struct elemental_data *ed);
|
||||
int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick);
|
||||
|
||||
#define elemental_stop_walking(ed, type) unit_stop_walking(&(ed)->bl, type)
|
||||
#define elemental_stop_attack(ed) unit_stop_attack(&(ed)->bl)
|
||||
|
||||
int read_elemental_skilldb(void);
|
||||
void reload_elementaldb(void);
|
||||
void reload_elemental_skilldb(void);
|
||||
int do_init_elemental(void);
|
||||
void do_final_elemental(void);
|
||||
|
||||
#endif /* _ELEMENTAL_H_ */
|
@ -21,6 +21,7 @@
|
||||
#include "atcommand.h"
|
||||
#include "mercenary.h"
|
||||
#include "homunculus.h"
|
||||
#include "elemental.h"
|
||||
#include "mail.h"
|
||||
#include "quest.h"
|
||||
|
||||
@ -40,7 +41,7 @@ static const int packet_len_table[]={
|
||||
-1, 0, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840
|
||||
-1,-1, 7, 7, 7,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus]
|
||||
-1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish]
|
||||
-1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3870 Mercenaries [Zephyrus]
|
||||
-1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 3, 3, 0, //0x3870 Mercenaries [Zephyrus] / Elemental [pakpil]
|
||||
11,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880
|
||||
-1,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator]
|
||||
};
|
||||
@ -1988,6 +1989,94 @@ int intif_parse_mercenary_saved(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Elemental's System
|
||||
*------------------------------------------*/
|
||||
int intif_elemental_create(struct s_elemental *ele)
|
||||
{
|
||||
int size = sizeof(struct s_elemental) + 4;
|
||||
|
||||
if( CheckForCharServer() )
|
||||
return 0;
|
||||
|
||||
WFIFOHEAD(inter_fd,size);
|
||||
WFIFOW(inter_fd,0) = 0x307c;
|
||||
WFIFOW(inter_fd,2) = size;
|
||||
memcpy(WFIFOP(inter_fd,4), ele, sizeof(struct s_elemental));
|
||||
WFIFOSET(inter_fd,size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intif_parse_elemental_received(int fd)
|
||||
{
|
||||
int len = RFIFOW(fd,2) - 5;
|
||||
if( sizeof(struct s_elemental) != len )
|
||||
{
|
||||
if( battle_config.etc_log )
|
||||
ShowError("intif: create elemental data size error %d != %d\n", sizeof(struct s_elemental), len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
elemental_data_received((struct s_elemental*)RFIFOP(fd,5), RFIFOB(fd,4));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intif_elemental_request(int ele_id, int char_id)
|
||||
{
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
|
||||
WFIFOHEAD(inter_fd,10);
|
||||
WFIFOW(inter_fd,0) = 0x307d;
|
||||
WFIFOL(inter_fd,2) = ele_id;
|
||||
WFIFOL(inter_fd,6) = char_id;
|
||||
WFIFOSET(inter_fd,10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intif_elemental_delete(int ele_id)
|
||||
{
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
|
||||
WFIFOHEAD(inter_fd,6);
|
||||
WFIFOW(inter_fd,0) = 0x307e;
|
||||
WFIFOL(inter_fd,2) = ele_id;
|
||||
WFIFOSET(inter_fd,6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intif_parse_elemental_deleted(int fd)
|
||||
{
|
||||
if( RFIFOB(fd,2) != 1 )
|
||||
ShowError("Elemental data delete failure\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intif_elemental_save(struct s_elemental *ele)
|
||||
{
|
||||
int size = sizeof(struct s_elemental) + 4;
|
||||
|
||||
if( CheckForCharServer() )
|
||||
return 0;
|
||||
|
||||
WFIFOHEAD(inter_fd,size);
|
||||
WFIFOW(inter_fd,0) = 0x307f;
|
||||
WFIFOW(inter_fd,2) = size;
|
||||
memcpy(WFIFOP(inter_fd,4), ele, sizeof(struct s_elemental));
|
||||
WFIFOSET(inter_fd,size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intif_parse_elemental_saved(int fd)
|
||||
{
|
||||
if( RFIFOB(fd,2) != 1 )
|
||||
ShowError("Elemental data save failure\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// inter serverからの通信
|
||||
// エラーがあれば0(false)を返すこと
|
||||
@ -2076,7 +2165,11 @@ int intif_parse(int fd)
|
||||
case 0x3870: intif_parse_mercenary_received(fd); break;
|
||||
case 0x3871: intif_parse_mercenary_deleted(fd); break;
|
||||
case 0x3872: intif_parse_mercenary_saved(fd); break;
|
||||
|
||||
// Elemental System
|
||||
case 0x387c: intif_parse_elemental_received(fd); break;
|
||||
case 0x387d: intif_parse_elemental_deleted(fd); break;
|
||||
case 0x387e: intif_parse_elemental_saved(fd); break;
|
||||
|
||||
case 0x3880: intif_parse_CreatePet(fd); break;
|
||||
case 0x3881: intif_parse_RecvPetData(fd); break;
|
||||
case 0x3882: intif_parse_SavePetOk(fd); break;
|
||||
|
@ -11,6 +11,7 @@ struct guild_position;
|
||||
struct s_pet;
|
||||
struct s_homunculus;
|
||||
struct s_mercenary;
|
||||
struct s_elemental;
|
||||
struct mail_message;
|
||||
struct auction_data;
|
||||
|
||||
@ -97,6 +98,11 @@ int intif_Auction_register(struct auction_data *auction);
|
||||
int intif_Auction_cancel(int char_id, unsigned int auction_id);
|
||||
int intif_Auction_close(int char_id, unsigned int auction_id);
|
||||
int intif_Auction_bid(int char_id, const char* name, unsigned int auction_id, int bid);
|
||||
// ELEMENTAL SYSTEM
|
||||
int intif_elemental_create(struct s_elemental *ele);
|
||||
int intif_elemental_request(int ele_id, int char_id);
|
||||
int intif_elemental_delete(int ele_id);
|
||||
int intif_elemental_save(struct s_elemental *ele);
|
||||
|
||||
int CheckForCharServer(void);
|
||||
|
||||
|
@ -160,6 +160,7 @@ struct item_data* itemdb_exists(int nameid);
|
||||
#define itemdb_is_poison(n) (n >= 12717 && n <= 12724)
|
||||
#define itemid_isgemstone(id) ( (id) >= ITEMID_YELLOW_GEMSTONE && (id) <= ITEMID_BLUE_GEMSTONE )
|
||||
#define itemdb_iscashfood(id) ( (id) >= 12202 && (id) <= 12207 )
|
||||
#define itemdb_is_GNbomb(n) (n >= 13260 && n <= 13267)
|
||||
const char* itemdb_typename(int type);
|
||||
|
||||
int itemdb_group_bonus(struct map_session_data* sd, int itemid);
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "homunculus.h"
|
||||
#include "instance.h"
|
||||
#include "mercenary.h"
|
||||
#include "elemental.h"
|
||||
#include "atcommand.h"
|
||||
#include "log.h"
|
||||
#include "mail.h"
|
||||
@ -1722,8 +1723,14 @@ int map_quit(struct map_session_data *sd)
|
||||
|
||||
// Return loot to owner
|
||||
if( sd->pd ) pet_lootitem_drop(sd->pd, sd);
|
||||
|
||||
if( sd->state.storage_flag == 1 ) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit.
|
||||
|
||||
if( sd->ed ) {
|
||||
elemental_clean_effect(sd->ed);
|
||||
unit_remove_map(&sd->ed->bl,CLR_TELEPORT);
|
||||
}
|
||||
|
||||
unit_remove_map_pc(sd,CLR_TELEPORT);
|
||||
|
||||
if( map[sd->bl.m].instance_id )
|
||||
@ -3588,6 +3595,7 @@ void do_final(void)
|
||||
do_final_unit();
|
||||
do_final_battleground();
|
||||
do_final_duel();
|
||||
do_final_elemental();
|
||||
|
||||
map_db->destroy(map_db, map_db_final);
|
||||
|
||||
@ -3914,7 +3922,8 @@ int do_init(int argc, char *argv[])
|
||||
do_init_unit();
|
||||
do_init_battleground();
|
||||
do_init_duel();
|
||||
|
||||
do_init_elemental();
|
||||
|
||||
npc_event_do_oninit(); // npc‚ÌOnInitƒCƒxƒ“ƒg?<3F>s
|
||||
|
||||
if( console )
|
||||
|
@ -233,12 +233,13 @@ enum bl_type {
|
||||
BL_SKILL = 0x040,
|
||||
BL_NPC = 0x080,
|
||||
BL_CHAT = 0x100,
|
||||
|
||||
BL_ELEM = 0x200,
|
||||
|
||||
BL_ALL = 0xFFF,
|
||||
};
|
||||
|
||||
//For common mapforeach calls. Since pets cannot be affected, they aren't included here yet.
|
||||
#define BL_CHAR (BL_PC|BL_MOB|BL_HOM|BL_MER)
|
||||
#define BL_CHAR (BL_PC|BL_MOB|BL_HOM|BL_MER|BL_ELEM)
|
||||
|
||||
enum npc_subtype { WARP, SHOP, SCRIPT, CASHSHOP };
|
||||
|
||||
@ -738,6 +739,7 @@ typedef struct skill_unit TBL_SKILL;
|
||||
typedef struct pet_data TBL_PET;
|
||||
typedef struct homun_data TBL_HOM;
|
||||
typedef struct mercenary_data TBL_MER;
|
||||
typedef struct elemental_data TBL_ELEM;
|
||||
|
||||
#define BL_CAST(type_, bl) \
|
||||
( ((bl) == (struct block_list*)NULL || (bl)->type != (type_)) ? (T ## type_ *)NULL : (T ## type_ *)(bl) )
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "mob.h"
|
||||
#include "homunculus.h"
|
||||
#include "mercenary.h"
|
||||
#include "elemental.h"
|
||||
#include "guild.h"
|
||||
#include "itemdb.h"
|
||||
#include "skill.h"
|
||||
@ -1896,6 +1897,15 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
|
||||
md->attacked_id = src->id;
|
||||
break;
|
||||
}
|
||||
case BL_ELEM:
|
||||
{
|
||||
struct elemental_data *ele = (TBL_ELEM*)src;
|
||||
if( ele->master )
|
||||
char_id = ele->master->status.char_id;
|
||||
if( damage )
|
||||
md->attacked_id = src->id;
|
||||
break;
|
||||
}
|
||||
default: //For all unhandled types.
|
||||
md->attacked_id = src->id;
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "pc.h" // struct map_session_data
|
||||
#include "script.h" // set_var()
|
||||
|
||||
#include <pcre.h>
|
||||
#include "pcre.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
11
src/map/pc.c
11
src/map/pc.c
@ -29,6 +29,7 @@
|
||||
#include "homunculus.h"
|
||||
#include "instance.h"
|
||||
#include "mercenary.h"
|
||||
#include "elemental.h"
|
||||
#include "npc.h" // fake_nd
|
||||
#include "pet.h" // pet_unlocktarget()
|
||||
#include "party.h" // party_search()
|
||||
@ -1213,7 +1214,9 @@ int pc_reg_received(struct map_session_data *sd)
|
||||
intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
|
||||
if( sd->status.mer_id > 0 )
|
||||
intif_mercenary_request(sd->status.mer_id, sd->status.char_id);
|
||||
|
||||
if( sd->status.ele_id > 0 )
|
||||
intif_elemental_request(sd->status.ele_id, sd->status.char_id);
|
||||
|
||||
map_addiddb(&sd->bl);
|
||||
map_delnickdb(sd->status.char_id, sd->status.name);
|
||||
if (!chrif_auth_finished(sd))
|
||||
@ -6155,6 +6158,9 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h
|
||||
if( sd->status.pet_id > 0 && sd->pd && battle_config.pet_damage_support )
|
||||
pet_target_check(sd,src,1);
|
||||
|
||||
if( sd->status.ele_id > 0 )
|
||||
elemental_set_target(sd,src);
|
||||
|
||||
sd->canlog_tick = gettick();
|
||||
}
|
||||
|
||||
@ -6189,6 +6195,9 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
|
||||
if( sd->md )
|
||||
merc_delete(sd->md, 3); // Your mercenary soldier has ran away.
|
||||
|
||||
if( sd->ed )
|
||||
elemental_delete(sd->ed, 0);
|
||||
|
||||
// Leave duel if you die [LuzZza]
|
||||
if(battle_config.duel_autoleave_when_die) {
|
||||
if(sd->duel_group > 0)
|
||||
|
@ -205,7 +205,7 @@ struct map_session_data {
|
||||
short cook_mastery; // range: [0,1999] [Inkfish]
|
||||
unsigned char blockskill[MAX_SKILL];
|
||||
int cloneskill_id, reproduceskill_id;
|
||||
int menuskill_id, menuskill_val;
|
||||
int menuskill_id, menuskill_val, menuskill_val2;
|
||||
|
||||
int invincible_timer;
|
||||
unsigned int canlog_tick;
|
||||
@ -377,6 +377,7 @@ struct map_session_data {
|
||||
struct pet_data *pd;
|
||||
struct homun_data *hd; // [blackhole89]
|
||||
struct mercenary_data *md;
|
||||
struct elemental_data *ed;
|
||||
|
||||
struct{
|
||||
int m; //-1 - none, other: map index corresponding to map name.
|
||||
|
@ -7835,7 +7835,7 @@ BUILDIN_FUNC(cooking)
|
||||
return 0;
|
||||
|
||||
trigger=script_getnum(st,2);
|
||||
clif_cooking_list(sd, trigger);
|
||||
clif_cooking_list(sd, trigger, AM_PHARMACY, 1, 1);
|
||||
return 0;
|
||||
}
|
||||
/*==========================================
|
||||
|
2263
src/map/skill.c
2263
src/map/skill.c
File diff suppressed because it is too large
Load Diff
@ -1705,49 +1705,49 @@ enum {
|
||||
UNT_EVILLAND,
|
||||
UNT_DARK_RUNNER, //TODO
|
||||
UNT_DARK_TRANSFER, //TODO
|
||||
UNT_EPICLESIS, //TODO
|
||||
UNT_EARTHSTRAIN, //TODO
|
||||
UNT_MANHOLE, //TODO
|
||||
UNT_DIMENSIONDOOR, //TODO
|
||||
UNT_CHAOSPANIC, //TODO
|
||||
UNT_MAELSTROM, //TODO
|
||||
UNT_BLOODYLUST, //TODO
|
||||
UNT_FEINTBOMB, //TODO
|
||||
UNT_MAGENTATRAP, //TODO
|
||||
UNT_COBALTTRAP, //TODO
|
||||
UNT_MAIZETRAP, //TODO
|
||||
UNT_VERDURETRAP, //TODO
|
||||
UNT_FIRINGTRAP, //TODO
|
||||
UNT_ICEBOUNDTRAP, //TODO
|
||||
UNT_ELECTRICSHOCKER, //TODO
|
||||
UNT_CLUSTERBOMB, //TODO
|
||||
UNT_REVERBERATION, //TODO
|
||||
UNT_SEVERE_RAINSTORM, //TODO
|
||||
UNT_FIREWALK, //TODO
|
||||
UNT_ELECTRICWALK, //TODO
|
||||
UNT_NETHERWORLD, //TODO
|
||||
UNT_PSYCHIC_WAVE, //TODO
|
||||
UNT_CLOUD_KILL, //TODO
|
||||
UNT_POISONSMOKE, //TODO
|
||||
UNT_NEUTRALBARRIER, //TODO
|
||||
UNT_STEALTHFIELD, //TODO
|
||||
UNT_WARMER, //TODO
|
||||
UNT_THORNS_TRAP, //TODO
|
||||
UNT_WALLOFTHORN, //TODO
|
||||
UNT_DEMONIC_FIRE, //TODO
|
||||
UNT_FIRE_EXPANSION_SMOKE_POWDER, //TODO
|
||||
UNT_FIRE_EXPANSION_TEAR_GAS, //TODO
|
||||
UNT_HELLS_PLANT, //TODO
|
||||
UNT_VACUUM_EXTREME, //TODO
|
||||
UNT_BANDING, //TODO
|
||||
UNT_FIRE_MANTLE, //TODO
|
||||
UNT_WATER_BARRIER, //TODO
|
||||
UNT_ZEPHYR, //TODO
|
||||
UNT_POWER_OF_GAIA, //TODO
|
||||
UNT_FIRE_INSIGNIA, //TODO
|
||||
UNT_WATER_INSIGNIA, //TODO
|
||||
UNT_WIND_INSIGNIA, //TODO
|
||||
UNT_EARTH_INSIGNIA, //TODO
|
||||
UNT_EPICLESIS,
|
||||
UNT_EARTHSTRAIN,
|
||||
UNT_MANHOLE,
|
||||
UNT_DIMENSIONDOOR,
|
||||
UNT_CHAOSPANIC,
|
||||
UNT_MAELSTROM,
|
||||
UNT_BLOODYLUST,
|
||||
UNT_FEINTBOMB,
|
||||
UNT_MAGENTATRAP,
|
||||
UNT_COBALTTRAP,
|
||||
UNT_MAIZETRAP,
|
||||
UNT_VERDURETRAP,
|
||||
UNT_FIRINGTRAP,
|
||||
UNT_ICEBOUNDTRAP,
|
||||
UNT_ELECTRICSHOCKER,
|
||||
UNT_CLUSTERBOMB,
|
||||
UNT_REVERBERATION,
|
||||
UNT_SEVERE_RAINSTORM,
|
||||
UNT_FIREWALK,
|
||||
UNT_ELECTRICWALK,
|
||||
UNT_NETHERWORLD,
|
||||
UNT_PSYCHIC_WAVE,
|
||||
UNT_CLOUD_KILL,
|
||||
UNT_POISONSMOKE,
|
||||
UNT_NEUTRALBARRIER,
|
||||
UNT_STEALTHFIELD,
|
||||
UNT_WARMER,
|
||||
UNT_THORNS_TRAP,
|
||||
UNT_WALLOFTHORN,
|
||||
UNT_DEMONIC_FIRE,
|
||||
UNT_FIRE_EXPANSION_SMOKE_POWDER,
|
||||
UNT_FIRE_EXPANSION_TEAR_GAS,
|
||||
UNT_HELLS_PLANT,
|
||||
UNT_VACUUM_EXTREME,
|
||||
UNT_BANDING,
|
||||
UNT_FIRE_MANTLE,
|
||||
UNT_WATER_BARRIER,
|
||||
UNT_ZEPHYR,
|
||||
UNT_POWER_OF_GAIA,
|
||||
UNT_FIRE_INSIGNIA,
|
||||
UNT_WATER_INSIGNIA,
|
||||
UNT_WIND_INSIGNIA,
|
||||
UNT_EARTH_INSIGNIA,
|
||||
UNT_POISON_MIST,
|
||||
UNT_LAVA_SLIDE,
|
||||
UNT_VOLCANIC_ASH,
|
||||
@ -1823,4 +1823,9 @@ enum gx_poison {
|
||||
* Auto Shadow Spell (Shadow Chaser)
|
||||
**/
|
||||
int skill_select_menu(struct map_session_data *sd,int flag,int skill_id);
|
||||
|
||||
int skill_elementalanalysis(struct map_session_data *sd, int n, int type, unsigned short *item_list); // Sorcerer Four Elemental Analisys.
|
||||
int skill_changematerial(struct map_session_data *sd, int n, unsigned short *item_list); // Genetic Change Material.
|
||||
int skill_get_elemental_type(int skill_id, int skill_lv);
|
||||
|
||||
#endif /* _SKILL_H_ */
|
||||
|
475
src/map/status.c
475
src/map/status.c
@ -29,6 +29,7 @@
|
||||
#include "unit.h"
|
||||
#include "homunculus.h"
|
||||
#include "mercenary.h"
|
||||
#include "elemental.h"
|
||||
#include "vending.h"
|
||||
|
||||
#include <time.h>
|
||||
@ -645,28 +646,57 @@ void initChangeTables(void)
|
||||
set_sc( WM_MELODYOFSINK , SC_MELODYOFSINK , SI_MELODYOFSINK , SCB_BATK|SCB_MATK );
|
||||
set_sc( WM_BEYOND_OF_WARCRY , SC_BEYONDOFWARCRY , SI_WARCRYOFBEYOND , SCB_BATK|SCB_MATK );
|
||||
set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITEDHUMMINGVOICE, SI_UNLIMITEDHUMMINGVOICE, SCB_NONE );
|
||||
///**
|
||||
// * Sorcerer
|
||||
// **/
|
||||
//set_sc( SO_FIREWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
|
||||
//set_sc( SO_ELECTRICWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
|
||||
//set_sc( SO_SPELLFIST , SC_SPELLFIST , SI_SPELLFIST , SCB_NONE );
|
||||
//set_sc( SO_CLOUD_KILL , SC_POISON , SI_CLOUDKILL , SCB_NONE );
|
||||
//set_sc( SO_STRIKING , SC_STRIKING , SI_STRIKING , SCB_WATK|SCB_CRI );
|
||||
//set_sc( SO_WARMER , SC_WARMER , SI_WARMER , SCB_NONE );
|
||||
//set_sc( SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE );
|
||||
//set_sc( SO_ARRULLO , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE );
|
||||
///**
|
||||
// * Genetic
|
||||
// **/
|
||||
//set_sc( GN_CARTBOOST , SC_GN_CARTBOOST, SI_CARTSBOOST , SCB_SPEED );
|
||||
//set_sc( GN_THORNS_TRAP , SC_THORNSTRAP , SI_THORNTRAP , SCB_NONE );
|
||||
//set_sc( GN_BLOOD_SUCKER , SC_BLOODSUCKER , SI_BLOODSUCKER , SCB_NONE );
|
||||
//set_sc( GN_WALLOFTHORN , SC_STOP , SI_BLANK , SCB_NONE );
|
||||
//set_sc( GN_FIRE_EXPANSION_SMOKE_POWDER, SC_SMOKEPOWDER , SI_FIRE_EXPANSION_SMOKE_POWDER, SCB_NONE );
|
||||
//set_sc( GN_FIRE_EXPANSION_TEAR_GAS , SC_TEARGAS , SI_FIRE_EXPANSION_TEAR_GAS , SCB_NONE );
|
||||
//set_sc( GN_MANDRAGORA , SC_MANDRAGORA , SI_MANDRAGORA , SCB_INT );
|
||||
/**
|
||||
* Sorcerer
|
||||
**/
|
||||
set_sc( SO_FIREWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
|
||||
set_sc( SO_ELECTRICWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
|
||||
set_sc( SO_SPELLFIST , SC_SPELLFIST , SI_SPELLFIST , SCB_NONE );
|
||||
set_sc( SO_DIAMONDDUST , SC_CRYSTALIZE , SI_COLD , SCB_NONE );//Will add flags in major balance update 8 [Rytech]
|
||||
set_sc( SO_CLOUD_KILL , SC_POISON , SI_CLOUDKILL , SCB_NONE );
|
||||
set_sc( SO_STRIKING , SC_STRIKING , SI_STRIKING , SCB_WATK|SCB_CRI );
|
||||
set_sc( SO_WARMER , SC_WARMER , SI_WARMER , SCB_NONE );
|
||||
set_sc( SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE );
|
||||
set_sc( SO_ARRULLO , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE );
|
||||
/**
|
||||
* Genetic
|
||||
**/
|
||||
set_sc( GN_CARTBOOST , SC_GN_CARTBOOST, SI_CARTSBOOST , SCB_SPEED );
|
||||
set_sc( GN_THORNS_TRAP , SC_THORNSTRAP , SI_THORNTRAP , SCB_NONE );
|
||||
set_sc( GN_BLOOD_SUCKER , SC_BLOODSUCKER , SI_BLOODSUCKER , SCB_NONE );
|
||||
set_sc( GN_WALLOFTHORN , SC_STOP , SI_BLANK , SCB_NONE );
|
||||
set_sc( GN_FIRE_EXPANSION_SMOKE_POWDER, SC_SMOKEPOWDER , SI_FIRE_EXPANSION_SMOKE_POWDER, SCB_NONE );
|
||||
set_sc( GN_FIRE_EXPANSION_TEAR_GAS , SC_TEARGAS , SI_FIRE_EXPANSION_TEAR_GAS , SCB_NONE );
|
||||
set_sc( GN_MANDRAGORA , SC_MANDRAGORA , SI_MANDRAGORA , SCB_INT );
|
||||
|
||||
// Elemental Spirit summoner's 'side' status changes.
|
||||
set_sc( EL_CIRCLE_OF_FIRE , SC_CIRCLE_OF_FIRE_OPTION, SI_CIRCLE_OF_FIRE_OPTION, SCB_NONE );
|
||||
set_sc( EL_FIRE_CLOAK , SC_FIRE_CLOAK_OPTION , SI_FIRE_CLOAK_OPTION , SCB_ALL );
|
||||
set_sc( EL_WATER_SCREEN , SC_WATER_SCREEN_OPTION , SI_WATER_SCREEN_OPTION , SCB_NONE );
|
||||
set_sc( EL_WATER_DROP , SC_WATER_DROP_OPTION , SI_WATER_DROP_OPTION , SCB_ALL );
|
||||
set_sc( EL_WATER_BARRIER , SC_WATER_BARRIER , SI_WATER_BARRIER , SCB_MDEF|SCB_WATK|SCB_MATK|SCB_FLEE );
|
||||
set_sc( EL_WIND_STEP , SC_WIND_STEP_OPTION , SI_WIND_STEP_OPTION , SCB_SPEED|SCB_FLEE );
|
||||
set_sc( EL_WIND_CURTAIN , SC_WIND_CURTAIN_OPTION , SI_WIND_CURTAIN_OPTION , SCB_ALL );
|
||||
set_sc( EL_ZEPHYR , SC_ZEPHYR , SI_ZEPHYR , SCB_FLEE );
|
||||
set_sc( EL_SOLID_SKIN , SC_SOLID_SKIN_OPTION , SI_SOLID_SKIN_OPTION , SCB_DEF|SCB_MAXHP );
|
||||
set_sc( EL_STONE_SHIELD , SC_STONE_SHIELD_OPTION , SI_STONE_SHIELD_OPTION , SCB_ALL );
|
||||
set_sc( EL_POWER_OF_GAIA , SC_POWER_OF_GAIA , SI_POWER_OF_GAIA , SCB_MAXHP|SCB_DEF|SCB_SPEED );
|
||||
set_sc( EL_PYROTECHNIC , SC_PYROTECHNIC_OPTION , SI_PYROTECHNIC_OPTION , SCB_WATK );
|
||||
set_sc( EL_HEATER , SC_HEATER_OPTION , SI_HEATER_OPTION , SCB_WATK );
|
||||
set_sc( EL_TROPIC , SC_TROPIC_OPTION , SI_TROPIC_OPTION , SCB_WATK );
|
||||
set_sc( EL_AQUAPLAY , SC_AQUAPLAY_OPTION , SI_AQUAPLAY_OPTION , SCB_MATK );
|
||||
set_sc( EL_COOLER , SC_COOLER_OPTION , SI_COOLER_OPTION , SCB_MATK );
|
||||
set_sc( EL_CHILLY_AIR , SC_CHILLY_AIR_OPTION , SI_CHILLY_AIR_OPTION , SCB_MATK );
|
||||
set_sc( EL_GUST , SC_GUST_OPTION , SI_GUST_OPTION , SCB_NONE );
|
||||
set_sc( EL_BLAST , SC_BLAST_OPTION , SI_BLAST_OPTION , SCB_NONE );
|
||||
set_sc( EL_WILD_STORM , SC_WILD_STORM_OPTION , SI_WILD_STORM_OPTION , SCB_NONE );
|
||||
set_sc( EL_PETROLOGY , SC_PETROLOGY_OPTION , SI_PETROLOGY_OPTION , SCB_NONE );
|
||||
set_sc( EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SI_CURSED_SOIL_OPTION , SCB_NONE );
|
||||
set_sc( EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SI_UPHEAVAL_OPTION , SCB_NONE );
|
||||
set_sc( EL_TIDAL_WEAPON , SC_TIDAL_WEAPON_OPTION , SI_TIDAL_WEAPON_OPTION , SCB_ALL );
|
||||
set_sc( EL_ROCK_CRUSHER , SC_ROCK_CRUSHER , SI_ROCK_CRUSHER , SCB_DEF );
|
||||
set_sc( EL_ROCK_CRUSHER_ATK, SC_ROCK_CRUSHER_ATK , SI_ROCK_CRUSHER_ATK , SCB_SPEED );
|
||||
|
||||
// Storing the target job rather than simply SC_SPIRIT simplifies code later on.
|
||||
SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
|
||||
SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
|
||||
@ -882,11 +912,20 @@ void initChangeTables(void)
|
||||
StatusChangeFlagTable[SC_SIROMA_ICE_TEA] |= SCB_DEX;
|
||||
StatusChangeFlagTable[SC_DROCERA_HERB_STEAMED] |= SCB_AGI;
|
||||
StatusChangeFlagTable[SC_PUTTI_TAILS_NOODLES] |= SCB_LUK;
|
||||
StatusChangeFlagTable[SC_BOOST500] |= SCB_ASPD;
|
||||
StatusChangeFlagTable[SC_FULL_SWING_K] |= SCB_BATK;
|
||||
StatusChangeFlagTable[SC_MANA_PLUS] |= SCB_MATK;
|
||||
StatusChangeFlagTable[SC_MUSTLE_M] |= SCB_MAXHP;
|
||||
StatusChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP;
|
||||
StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
|
||||
StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
|
||||
StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
|
||||
|
||||
#ifdef RENEWAL_EDP
|
||||
// renewal EDP increases your atk and weapon atk
|
||||
StatusChangeFlagTable[SC_EDP] |= SCB_BATK|SCB_WATK;
|
||||
#endif
|
||||
|
||||
if( !battle_config.display_hallucination ) //Disable Hallucination.
|
||||
StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
|
||||
}
|
||||
@ -1077,6 +1116,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
|
||||
case BL_MOB: mob_damage((TBL_MOB*)target, src, hp); break;
|
||||
case BL_HOM: merc_damage((TBL_HOM*)target,src,hp,sp); break;
|
||||
case BL_MER: mercenary_damage((TBL_MER*)target,src,hp,sp); break;
|
||||
case BL_ELEM: elemental_damage((TBL_ELEM*)target,src,hp,sp); break;
|
||||
}
|
||||
|
||||
if( target->type == BL_PC && ((TBL_PC*)target)->disguise && src )
|
||||
@ -1102,6 +1142,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
|
||||
case BL_MOB: flag = mob_dead((TBL_MOB*)target, src, flag&4?3:0); break;
|
||||
case BL_HOM: flag = merc_hom_dead((TBL_HOM*)target,src); break;
|
||||
case BL_MER: flag = mercenary_dead((TBL_MER*)target,src); break;
|
||||
case BL_ELEM: flag = elemental_dead((TBL_ELEM*)target,src); break;
|
||||
default: //Unhandled case, do nothing to object.
|
||||
flag = 0;
|
||||
break;
|
||||
@ -1239,6 +1280,7 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
|
||||
case BL_MOB: mob_heal((TBL_MOB*)bl,hp); break;
|
||||
case BL_HOM: merc_hom_heal((TBL_HOM*)bl,hp,sp); break;
|
||||
case BL_MER: mercenary_heal((TBL_MER*)bl,hp,sp); break;
|
||||
case BL_ELEM: elemental_heal((TBL_ELEM*)bl,hp,sp); break;
|
||||
}
|
||||
|
||||
return hp+sp;
|
||||
@ -1378,6 +1420,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
|
||||
//on dead characters, said checks are left to skill.c [Skotlex]
|
||||
if (target && status_isdead(target))
|
||||
return 0;
|
||||
if( src && (sc = status_get_sc(src)) && sc->data[SC_CRYSTALIZE] )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (skill_num == PA_PRESSURE && flag && target) {
|
||||
@ -1394,12 +1438,11 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
|
||||
&& (src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_num))
|
||||
return 0;
|
||||
|
||||
if (src) sc = status_get_sc(src);
|
||||
if ( src ) sc = status_get_sc(src);
|
||||
|
||||
if(sc && sc->count)
|
||||
{
|
||||
if(sc->opt1 >0 && sc->opt1 != OPT1_BURNING && skill_num != SR_GENTLETOUCH_CURE)
|
||||
{ //Stuned/Frozen/etc
|
||||
if( sc && sc->count ) {
|
||||
|
||||
if( sc->opt1 >0 && sc->opt1 != OPT1_BURNING && skill_num != SR_GENTLETOUCH_CURE ) { //Stuned/Frozen/etc
|
||||
if (flag != 1) //Can't cast, casted stuff can't damage.
|
||||
return 0;
|
||||
if (!(skill_get_inf(skill_num)&INF_GROUND_SKILL))
|
||||
@ -1570,11 +1613,12 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
|
||||
return 0;
|
||||
case BL_HOM:
|
||||
case BL_MER:
|
||||
case BL_ELEM:
|
||||
if( target->type == BL_HOM && skill_num && battle_config.hom_setting&0x1 && skill_get_inf(skill_num)&INF_SUPPORT_SKILL && battle_get_master(target) != src )
|
||||
return 0; // Can't use support skills on Homunculus (only Master/Self)
|
||||
if( target->type == BL_MER && (skill_num == PR_ASPERSIO || (skill_num >= SA_FLAMELAUNCHER && skill_num <= SA_SEISMICWEAPON)) && battle_get_master(target) != src )
|
||||
return 0; // Can't use Weapon endow skills on Mercenary (only Master)
|
||||
if( target->type == BL_MER && skill_num == AM_POTIONPITCHER )
|
||||
if( skill_num == AM_POTIONPITCHER && ( target->type == BL_MER || target->type == BL_ELEM) )
|
||||
return 0; // Can't use Potion Pitcher on Mercenaries
|
||||
default:
|
||||
//Check for chase-walk/hiding/cloaking opponents.
|
||||
@ -2848,8 +2892,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
|
||||
}
|
||||
|
||||
if(sc->count){
|
||||
if(sc->data[SC_CONCENTRATE])
|
||||
{ //Update the card-bonus data
|
||||
if(sc->data[SC_CONCENTRATE]) { //Update the card-bonus data
|
||||
sc->data[SC_CONCENTRATE]->val3 = sd->param_bonus[1]; //Agi
|
||||
sc->data[SC_CONCENTRATE]->val4 = sd->param_bonus[4]; //Dex
|
||||
}
|
||||
@ -2869,20 +2912,38 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
|
||||
sd->subele[ELE_HOLY] += sc->data[SC_PROVIDENCE]->val2;
|
||||
sd->subrace[RC_DEMON] += sc->data[SC_PROVIDENCE]->val2;
|
||||
}
|
||||
if(sc->data[SC_ARMOR_ELEMENT])
|
||||
{ //This status change should grant card-type elemental resist.
|
||||
if(sc->data[SC_ARMOR_ELEMENT]) { //This status change should grant card-type elemental resist.
|
||||
sd->subele[ELE_WATER] += sc->data[SC_ARMOR_ELEMENT]->val1;
|
||||
sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_ELEMENT]->val2;
|
||||
sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_ELEMENT]->val3;
|
||||
sd->subele[ELE_WIND] += sc->data[SC_ARMOR_ELEMENT]->val4;
|
||||
}
|
||||
if(sc->data[SC_ARMOR_RESIST])
|
||||
{ // Undead Scroll
|
||||
if(sc->data[SC_ARMOR_RESIST]) { // Undead Scroll
|
||||
sd->subele[ELE_WATER] += sc->data[SC_ARMOR_RESIST]->val1;
|
||||
sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_RESIST]->val2;
|
||||
sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_RESIST]->val3;
|
||||
sd->subele[ELE_WIND] += sc->data[SC_ARMOR_RESIST]->val4;
|
||||
}
|
||||
if( sc->data[SC_FIRE_CLOAK_OPTION] ) {
|
||||
i = sc->data[SC_FIRE_CLOAK_OPTION]->val2;
|
||||
sd->subele[ELE_FIRE] += i;
|
||||
sd->subele[ELE_EARTH] -= i;
|
||||
}
|
||||
if( sc->data[SC_WATER_DROP_OPTION] ) {
|
||||
i = sc->data[SC_WATER_DROP_OPTION]->val2;
|
||||
sd->subele[ELE_WATER] += i;
|
||||
sd->subele[ELE_WIND] -= i;
|
||||
}
|
||||
if( sc->data[SC_WIND_CURTAIN_OPTION] ) {
|
||||
i = sc->data[SC_WIND_CURTAIN_OPTION]->val2;
|
||||
sd->subele[ELE_WIND] += i;
|
||||
sd->subele[ELE_WATER] -= i;
|
||||
}
|
||||
if( sc->data[SC_STONE_SHIELD_OPTION] ) {
|
||||
i = sc->data[SC_STONE_SHIELD_OPTION]->val2;
|
||||
sd->subele[ELE_EARTH] += i;
|
||||
sd->subele[ELE_FIRE] -= i;
|
||||
}
|
||||
}
|
||||
status_cpy(&sd->battle_status, status);
|
||||
|
||||
@ -3006,6 +3067,45 @@ int status_calc_homunculus_(struct homun_data *hd, bool first)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int status_calc_elemental_(struct elemental_data *ed, bool first) {
|
||||
struct status_data *status = &ed->base_status;
|
||||
struct s_elemental *ele = &ed->elemental;
|
||||
struct map_session_data *sd = ed->master;
|
||||
|
||||
if( !sd )
|
||||
return 0;
|
||||
|
||||
status->str = ele->str;
|
||||
status->agi = ele->agi;
|
||||
status->vit = ele->vit;
|
||||
status->dex = ele->dex;
|
||||
status->int_ = ele->int_;
|
||||
status->luk = ele->luk;
|
||||
|
||||
if( first ) {
|
||||
memcpy(status, &ed->db->status, sizeof(struct status_data));
|
||||
status->mode = MD_CANMOVE|MD_CANATTACK;
|
||||
status->max_hp += 4000 + 500 * pc_checkskill(sd,SO_EL_SYMPATHY);
|
||||
status->max_sp += 300 + 50 * pc_checkskill(sd,SO_EL_SYMPATHY);
|
||||
status->hp = status->max_hp;
|
||||
status->sp = status->max_sp;
|
||||
status->str += sd->base_status.str * 25 / 100;
|
||||
status->agi += sd->base_status.agi * 25 / 100;
|
||||
status->vit += sd->base_status.vit * 25 / 100;
|
||||
status->int_ += sd->base_status.int_ * 25 / 100;
|
||||
status->def += sd->base_status.dex * 25 / 100;
|
||||
status->luk += sd->base_status.luk * 25 / 100;
|
||||
|
||||
status_calc_misc(&ed->bl, status, ed->db->lv);
|
||||
memcpy(&ed->battle_status,status,sizeof(struct status_data));
|
||||
} else {
|
||||
status_calc_misc(&ed->bl, status, ed->db->lv);
|
||||
status_cpy(&ed->battle_status, status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned short status_calc_str(struct block_list *,struct status_change *,int);
|
||||
static unsigned short status_calc_agi(struct block_list *,struct status_change *,int);
|
||||
static unsigned short status_calc_vit(struct block_list *,struct status_change *,int);
|
||||
@ -3107,25 +3207,26 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
|
||||
sregen->sp = cap_value(val, 0, SHRT_MAX);
|
||||
}
|
||||
|
||||
if( bl->type == BL_HOM )
|
||||
{
|
||||
if( bl->type == BL_HOM ) {
|
||||
struct homun_data *hd = (TBL_HOM*)bl;
|
||||
if( (skill = merc_hom_checkskill(hd,HAMI_SKIN)) > 0 )
|
||||
{
|
||||
if( (skill = merc_hom_checkskill(hd,HAMI_SKIN)) > 0 ) {
|
||||
val = regen->hp*(100+5*skill)/100;
|
||||
regen->hp = cap_value(val, 1, SHRT_MAX);
|
||||
}
|
||||
if( (skill = merc_hom_checkskill(hd,HLIF_BRAIN)) > 0 )
|
||||
{
|
||||
if( (skill = merc_hom_checkskill(hd,HLIF_BRAIN)) > 0 ) {
|
||||
val = regen->sp*(100+3*skill)/100;
|
||||
regen->sp = cap_value(val, 1, SHRT_MAX);
|
||||
}
|
||||
}
|
||||
else if( bl->type == BL_MER )
|
||||
{
|
||||
} else if( bl->type == BL_MER ) {
|
||||
val = (status->max_hp * status->vit / 10000 + 1) * 6;
|
||||
regen->hp = cap_value(val, 1, SHRT_MAX);
|
||||
|
||||
val = (status->max_sp * (status->int_ + 10) / 750) + 1;
|
||||
regen->sp = cap_value(val, 1, SHRT_MAX);
|
||||
} else if( bl->type == BL_ELEM ) {
|
||||
val = (status->max_hp * status->vit / 10000 + 1) * 6;
|
||||
regen->hp = cap_value(val, 1, SHRT_MAX);
|
||||
|
||||
val = (status->max_sp * (status->int_ + 10) / 750) + 1;
|
||||
regen->sp = cap_value(val, 1, SHRT_MAX);
|
||||
}
|
||||
@ -3241,7 +3342,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
|
||||
if(flag&SCB_VIT) {
|
||||
status->vit = status_calc_vit(bl, sc, b_status->vit);
|
||||
flag|=SCB_DEF2|SCB_MDEF2;
|
||||
if( bl->type&(BL_PC|BL_HOM|BL_MER) )
|
||||
if( bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) )
|
||||
flag |= SCB_MAXHP;
|
||||
if( bl->type&BL_HOM )
|
||||
flag |= SCB_DEF;
|
||||
@ -3250,7 +3351,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
|
||||
if(flag&SCB_INT) {
|
||||
status->int_ = status_calc_int(bl, sc, b_status->int_);
|
||||
flag|=SCB_MATK|SCB_MDEF2;
|
||||
if( bl->type&(BL_PC|BL_HOM|BL_MER) )
|
||||
if( bl->type&(BL_PC|BL_HOM|BL_MER|BL_ELEM) )
|
||||
flag |= SCB_MAXSP;
|
||||
if( bl->type&BL_HOM )
|
||||
flag |= SCB_MDEF;
|
||||
@ -3582,15 +3683,14 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first)
|
||||
status = status_get_status_data(bl);
|
||||
memcpy(&b_status, status, sizeof(struct status_data));
|
||||
|
||||
if( flag&SCB_BASE )
|
||||
{// calculate the object's base status too
|
||||
switch( bl->type )
|
||||
{
|
||||
if( flag&SCB_BASE ) {// calculate the object's base status too
|
||||
switch( bl->type ) {
|
||||
case BL_PC: status_calc_pc_(BL_CAST(BL_PC,bl), first); break;
|
||||
case BL_MOB: status_calc_mob_(BL_CAST(BL_MOB,bl), first); break;
|
||||
case BL_PET: status_calc_pet_(BL_CAST(BL_PET,bl), first); break;
|
||||
case BL_HOM: status_calc_homunculus_(BL_CAST(BL_HOM,bl), first); break;
|
||||
case BL_MER: status_calc_mercenary_(BL_CAST(BL_MER,bl), first); break;
|
||||
case BL_ELEM: status_calc_elemental_(BL_CAST(BL_ELEM,bl), first); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3671,17 +3771,11 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first)
|
||||
clif_updatestatus(sd,SP_HP);
|
||||
if(b_status.sp != status->sp)
|
||||
clif_updatestatus(sd,SP_SP);
|
||||
}
|
||||
else
|
||||
if( bl->type == BL_HOM )
|
||||
{
|
||||
} else if( bl->type == BL_HOM ) {
|
||||
TBL_HOM* hd = BL_CAST(BL_HOM, bl);
|
||||
if( hd->master && memcmp(&b_status, status, sizeof(struct status_data)) != 0 )
|
||||
clif_hominfo(hd->master,hd,0);
|
||||
}
|
||||
else
|
||||
if( bl->type == BL_MER )
|
||||
{
|
||||
} else if( bl->type == BL_MER ) {
|
||||
TBL_MER* md = BL_CAST(BL_MER, bl);
|
||||
if( b_status.rhw.atk != status->rhw.atk || b_status.rhw.atk2 != status->rhw.atk2 )
|
||||
clif_mercenary_updatestatus(md->master, SP_ATK1);
|
||||
@ -3707,7 +3801,17 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first)
|
||||
clif_mercenary_updatestatus(md->master, SP_HP);
|
||||
if( b_status.sp != status->sp )
|
||||
clif_mercenary_updatestatus(md->master, SP_SP);
|
||||
}
|
||||
} else if( bl->type == BL_ELEM ) {
|
||||
TBL_ELEM* ed = BL_CAST(BL_ELEM, bl);
|
||||
if( b_status.max_hp != status->max_hp )
|
||||
clif_elemental_updatestatus(ed->master, SP_MAXHP);
|
||||
if( b_status.max_sp != status->max_sp )
|
||||
clif_elemental_updatestatus(ed->master, SP_MAXSP);
|
||||
if( b_status.hp != status->hp )
|
||||
clif_elemental_updatestatus(ed->master, SP_HP);
|
||||
if( b_status.sp != status->sp )
|
||||
clif_mercenary_updatestatus(ed->master, SP_SP);
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
@ -4641,6 +4745,10 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
|
||||
val = max( val, 75 );
|
||||
if( sc->data[SC_CLOAKINGEXCEED] )
|
||||
val = max( val, sc->data[SC_CLOAKINGEXCEED]->val3);
|
||||
if( sc->data[SC_HOVERING] )
|
||||
val = max( val, 10 );
|
||||
if( sc->data[SC_GN_CARTBOOST] )
|
||||
val = max( val, sc->data[SC_GN_CARTBOOST]->val2 );
|
||||
if( sc->data[SC_GT_REVITALIZE] )
|
||||
val = max( val, sc->data[SC_GT_REVITALIZE]->val2 );
|
||||
if( sc->data[SC_SWINGDANCE] )
|
||||
@ -5005,8 +5113,7 @@ static unsigned short status_calc_mode(struct block_list *bl, struct status_chan
|
||||
return cap_value(mode,0,USHRT_MAX);
|
||||
}
|
||||
|
||||
const char* status_get_name(struct block_list *bl)
|
||||
{
|
||||
const char* status_get_name(struct block_list *bl) {
|
||||
nullpo_ret(bl);
|
||||
switch (bl->type) {
|
||||
case BL_PC: return ((TBL_PC *)bl)->fakename[0] != '\0' ? ((TBL_PC*)bl)->fakename : ((TBL_PC*)bl)->status.name;
|
||||
@ -5022,17 +5129,16 @@ const char* status_get_name(struct block_list *bl)
|
||||
* 対象のClassを返す(汎用)
|
||||
* 戻りは整数で0以上
|
||||
*------------------------------------------*/
|
||||
int status_get_class(struct block_list *bl)
|
||||
{
|
||||
int status_get_class(struct block_list *bl) {
|
||||
nullpo_ret(bl);
|
||||
switch( bl->type )
|
||||
{
|
||||
case BL_PC: return ((TBL_PC*)bl)->status.class_;
|
||||
case BL_MOB: return ((TBL_MOB*)bl)->vd->class_; //Class used on all code should be the view class of the mob.
|
||||
case BL_PET: return ((TBL_PET*)bl)->pet.class_;
|
||||
case BL_HOM: return ((TBL_HOM*)bl)->homunculus.class_;
|
||||
case BL_MER: return ((TBL_MER*)bl)->mercenary.class_;
|
||||
case BL_NPC: return ((TBL_NPC*)bl)->class_;
|
||||
switch( bl->type ) {
|
||||
case BL_PC: return ((TBL_PC*)bl)->status.class_;
|
||||
case BL_MOB: return ((TBL_MOB*)bl)->vd->class_; //Class used on all code should be the view class of the mob.
|
||||
case BL_PET: return ((TBL_PET*)bl)->pet.class_;
|
||||
case BL_HOM: return ((TBL_HOM*)bl)->homunculus.class_;
|
||||
case BL_MER: return ((TBL_MER*)bl)->mercenary.class_;
|
||||
case BL_NPC: return ((TBL_NPC*)bl)->class_;
|
||||
case BL_ELEM: return ((TBL_ELEM*)bl)->elemental.class_;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -5040,8 +5146,7 @@ int status_get_class(struct block_list *bl)
|
||||
* 対象のレベルを返す(汎用)
|
||||
* 戻りは整数で0以上
|
||||
*------------------------------------------*/
|
||||
int status_get_lv(struct block_list *bl)
|
||||
{
|
||||
int status_get_lv(struct block_list *bl) {
|
||||
nullpo_ret(bl);
|
||||
switch (bl->type) {
|
||||
case BL_PC: return ((TBL_PC*)bl)->status.base_level;
|
||||
@ -5049,6 +5154,7 @@ int status_get_lv(struct block_list *bl)
|
||||
case BL_PET: return ((TBL_PET*)bl)->pet.level;
|
||||
case BL_HOM: return ((TBL_HOM*)bl)->homunculus.level;
|
||||
case BL_MER: return ((TBL_MER*)bl)->db->lv;
|
||||
case BL_ELEM: return ((TBL_ELEM*)bl)->db->lv;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -5060,6 +5166,7 @@ struct regen_data *status_get_regen_data(struct block_list *bl)
|
||||
case BL_PC: return &((TBL_PC*)bl)->regen;
|
||||
case BL_HOM: return &((TBL_HOM*)bl)->regen;
|
||||
case BL_MER: return &((TBL_MER*)bl)->regen;
|
||||
case BL_ELEM: return &((TBL_ELEM*)bl)->regen;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -5075,6 +5182,7 @@ struct status_data *status_get_status_data(struct block_list *bl)
|
||||
case BL_PET: return &((TBL_PET*)bl)->status;
|
||||
case BL_HOM: return &((TBL_HOM*)bl)->battle_status;
|
||||
case BL_MER: return &((TBL_MER*)bl)->battle_status;
|
||||
case BL_ELEM: return &((TBL_ELEM*)bl)->battle_status;
|
||||
default:
|
||||
return &dummy_status;
|
||||
}
|
||||
@ -5089,6 +5197,7 @@ struct status_data *status_get_base_status(struct block_list *bl)
|
||||
case BL_PET: return &((TBL_PET*)bl)->db->status;
|
||||
case BL_HOM: return &((TBL_HOM*)bl)->base_status;
|
||||
case BL_MER: return &((TBL_MER*)bl)->base_status;
|
||||
case BL_ELEM: return &((TBL_ELEM*)bl)->base_status;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -5111,115 +5220,120 @@ unsigned short status_get_speed(struct block_list *bl)
|
||||
return status_get_status_data(bl)->speed;
|
||||
}
|
||||
|
||||
int status_get_party_id(struct block_list *bl)
|
||||
{
|
||||
int status_get_party_id(struct block_list *bl) {
|
||||
nullpo_ret(bl);
|
||||
switch (bl->type) {
|
||||
case BL_PC:
|
||||
return ((TBL_PC*)bl)->status.party_id;
|
||||
case BL_PET:
|
||||
if (((TBL_PET*)bl)->msd)
|
||||
return ((TBL_PET*)bl)->msd->status.party_id;
|
||||
break;
|
||||
case BL_MOB:
|
||||
{
|
||||
struct mob_data *md=(TBL_MOB*)bl;
|
||||
if( md->master_id>0 )
|
||||
{
|
||||
struct map_session_data *msd;
|
||||
if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
|
||||
return msd->status.party_id;
|
||||
return -md->master_id;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BL_HOM:
|
||||
if (((TBL_HOM*)bl)->master)
|
||||
return ((TBL_HOM*)bl)->master->status.party_id;
|
||||
break;
|
||||
case BL_MER:
|
||||
if (((TBL_MER*)bl)->master)
|
||||
return ((TBL_MER*)bl)->master->status.party_id;
|
||||
break;
|
||||
case BL_SKILL:
|
||||
return ((TBL_SKILL*)bl)->group->party_id;
|
||||
case BL_PC:
|
||||
return ((TBL_PC*)bl)->status.party_id;
|
||||
case BL_PET:
|
||||
if (((TBL_PET*)bl)->msd)
|
||||
return ((TBL_PET*)bl)->msd->status.party_id;
|
||||
break;
|
||||
case BL_MOB: {
|
||||
struct mob_data *md=(TBL_MOB*)bl;
|
||||
if( md->master_id > 0 ) {
|
||||
struct map_session_data *msd;
|
||||
if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
|
||||
return msd->status.party_id;
|
||||
return -md->master_id;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BL_HOM:
|
||||
if (((TBL_HOM*)bl)->master)
|
||||
return ((TBL_HOM*)bl)->master->status.party_id;
|
||||
break;
|
||||
case BL_MER:
|
||||
if (((TBL_MER*)bl)->master)
|
||||
return ((TBL_MER*)bl)->master->status.party_id;
|
||||
break;
|
||||
case BL_SKILL:
|
||||
return ((TBL_SKILL*)bl)->group->party_id;
|
||||
case BL_ELEM:
|
||||
if (((TBL_ELEM*)bl)->master)
|
||||
return ((TBL_ELEM*)bl)->master->status.party_id;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int status_get_guild_id(struct block_list *bl)
|
||||
{
|
||||
int status_get_guild_id(struct block_list *bl) {
|
||||
nullpo_ret(bl);
|
||||
switch (bl->type) {
|
||||
case BL_PC:
|
||||
return ((TBL_PC*)bl)->status.guild_id;
|
||||
case BL_PET:
|
||||
if (((TBL_PET*)bl)->msd)
|
||||
return ((TBL_PET*)bl)->msd->status.guild_id;
|
||||
break;
|
||||
case BL_MOB:
|
||||
{
|
||||
struct map_session_data *msd;
|
||||
struct mob_data *md = (struct mob_data *)bl;
|
||||
if (md->guardian_data) //Guardian's guild [Skotlex]
|
||||
return md->guardian_data->guild_id;
|
||||
if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
|
||||
return msd->status.guild_id; //Alchemist's mobs [Skotlex]
|
||||
}
|
||||
break;
|
||||
case BL_HOM:
|
||||
if (((TBL_HOM*)bl)->master)
|
||||
return ((TBL_HOM*)bl)->master->status.guild_id;
|
||||
break;
|
||||
case BL_MER:
|
||||
if (((TBL_MER*)bl)->master)
|
||||
return ((TBL_MER*)bl)->master->status.guild_id;
|
||||
break;
|
||||
case BL_NPC:
|
||||
if (((TBL_NPC*)bl)->subtype == SCRIPT)
|
||||
return ((TBL_NPC*)bl)->u.scr.guild_id;
|
||||
break;
|
||||
case BL_SKILL:
|
||||
return ((TBL_SKILL*)bl)->group->guild_id;
|
||||
case BL_PC:
|
||||
return ((TBL_PC*)bl)->status.guild_id;
|
||||
case BL_PET:
|
||||
if (((TBL_PET*)bl)->msd)
|
||||
return ((TBL_PET*)bl)->msd->status.guild_id;
|
||||
break;
|
||||
case BL_MOB: {
|
||||
struct map_session_data *msd;
|
||||
struct mob_data *md = (struct mob_data *)bl;
|
||||
if (md->guardian_data) //Guardian's guild [Skotlex]
|
||||
return md->guardian_data->guild_id;
|
||||
if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
|
||||
return msd->status.guild_id; //Alchemist's mobs [Skotlex]
|
||||
}
|
||||
break;
|
||||
case BL_HOM:
|
||||
if (((TBL_HOM*)bl)->master)
|
||||
return ((TBL_HOM*)bl)->master->status.guild_id;
|
||||
break;
|
||||
case BL_MER:
|
||||
if (((TBL_MER*)bl)->master)
|
||||
return ((TBL_MER*)bl)->master->status.guild_id;
|
||||
break;
|
||||
case BL_NPC:
|
||||
if (((TBL_NPC*)bl)->subtype == SCRIPT)
|
||||
return ((TBL_NPC*)bl)->u.scr.guild_id;
|
||||
break;
|
||||
case BL_SKILL:
|
||||
return ((TBL_SKILL*)bl)->group->guild_id;
|
||||
case BL_ELEM:
|
||||
if (((TBL_ELEM*)bl)->master)
|
||||
return ((TBL_ELEM*)bl)->master->status.guild_id;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int status_get_emblem_id(struct block_list *bl)
|
||||
{
|
||||
int status_get_emblem_id(struct block_list *bl) {
|
||||
nullpo_ret(bl);
|
||||
switch (bl->type) {
|
||||
case BL_PC:
|
||||
return ((TBL_PC*)bl)->guild_emblem_id;
|
||||
case BL_PET:
|
||||
if (((TBL_PET*)bl)->msd)
|
||||
return ((TBL_PET*)bl)->msd->guild_emblem_id;
|
||||
break;
|
||||
case BL_MOB:
|
||||
{
|
||||
struct map_session_data *msd;
|
||||
struct mob_data *md = (struct mob_data *)bl;
|
||||
if (md->guardian_data) //Guardian's guild [Skotlex]
|
||||
return md->guardian_data->emblem_id;
|
||||
if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
|
||||
return msd->guild_emblem_id; //Alchemist's mobs [Skotlex]
|
||||
}
|
||||
break;
|
||||
case BL_HOM:
|
||||
if (((TBL_HOM*)bl)->master)
|
||||
return ((TBL_HOM*)bl)->master->guild_emblem_id;
|
||||
break;
|
||||
case BL_MER:
|
||||
if (((TBL_MER*)bl)->master)
|
||||
return ((TBL_MER*)bl)->master->guild_emblem_id;
|
||||
break;
|
||||
case BL_NPC:
|
||||
if (((TBL_NPC*)bl)->subtype == SCRIPT && ((TBL_NPC*)bl)->u.scr.guild_id > 0) {
|
||||
struct guild *g = guild_search(((TBL_NPC*)bl)->u.scr.guild_id);
|
||||
if (g)
|
||||
return g->emblem_id;
|
||||
}
|
||||
break;
|
||||
case BL_PC:
|
||||
return ((TBL_PC*)bl)->guild_emblem_id;
|
||||
case BL_PET:
|
||||
if (((TBL_PET*)bl)->msd)
|
||||
return ((TBL_PET*)bl)->msd->guild_emblem_id;
|
||||
break;
|
||||
case BL_MOB: {
|
||||
struct map_session_data *msd;
|
||||
struct mob_data *md = (struct mob_data *)bl;
|
||||
if (md->guardian_data) //Guardian's guild [Skotlex]
|
||||
return md->guardian_data->emblem_id;
|
||||
if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
|
||||
return msd->guild_emblem_id; //Alchemist's mobs [Skotlex]
|
||||
}
|
||||
break;
|
||||
case BL_HOM:
|
||||
if (((TBL_HOM*)bl)->master)
|
||||
return ((TBL_HOM*)bl)->master->guild_emblem_id;
|
||||
break;
|
||||
case BL_MER:
|
||||
if (((TBL_MER*)bl)->master)
|
||||
return ((TBL_MER*)bl)->master->guild_emblem_id;
|
||||
break;
|
||||
case BL_NPC:
|
||||
if (((TBL_NPC*)bl)->subtype == SCRIPT && ((TBL_NPC*)bl)->u.scr.guild_id > 0) {
|
||||
struct guild *g = guild_search(((TBL_NPC*)bl)->u.scr.guild_id);
|
||||
if (g)
|
||||
return g->emblem_id;
|
||||
}
|
||||
break;
|
||||
case BL_ELEM:
|
||||
if (((TBL_ELEM*)bl)->master)
|
||||
return ((TBL_ELEM*)bl)->master->guild_emblem_id;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -5271,6 +5385,7 @@ struct view_data* status_get_viewdata(struct block_list *bl)
|
||||
case BL_NPC: return ((TBL_NPC*)bl)->vd;
|
||||
case BL_HOM: return ((TBL_HOM*)bl)->vd;
|
||||
case BL_MER: return ((TBL_MER*)bl)->vd;
|
||||
case BL_ELEM: return ((TBL_ELEM*)bl)->vd;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -5287,6 +5402,8 @@ void status_set_viewdata(struct block_list *bl, int class_)
|
||||
vd = merc_get_hom_viewdata(class_);
|
||||
else if (merc_class(class_))
|
||||
vd = merc_get_viewdata(class_);
|
||||
else if (elemental_class(class_))
|
||||
vd = elemental_get_viewdata(class_);
|
||||
else
|
||||
vd = NULL;
|
||||
|
||||
@ -5394,6 +5511,15 @@ void status_set_viewdata(struct block_list *bl, int class_)
|
||||
ShowError("status_set_viewdata (MERCENARY): No view data for class %d\n", class_);
|
||||
}
|
||||
break;
|
||||
case BL_ELEM:
|
||||
{
|
||||
struct elemental_data *ed = (struct elemental_data*)bl;
|
||||
if (vd)
|
||||
ed->vd = vd;
|
||||
else
|
||||
ShowError("status_set_viewdata (ELEMENTAL): No view data for class %d\n", class_);
|
||||
}
|
||||
break;
|
||||
}
|
||||
vd = status_get_viewdata(bl);
|
||||
if (vd && vd->cloth_color && (
|
||||
@ -5405,15 +5531,15 @@ void status_set_viewdata(struct block_list *bl, int class_)
|
||||
}
|
||||
|
||||
/// Returns the status_change data of bl or NULL if it doesn't exist.
|
||||
struct status_change *status_get_sc(struct block_list *bl)
|
||||
{
|
||||
struct status_change *status_get_sc(struct block_list *bl) {
|
||||
if( bl )
|
||||
switch (bl->type) {
|
||||
case BL_PC: return &((TBL_PC*)bl)->sc;
|
||||
case BL_MOB: return &((TBL_MOB*)bl)->sc;
|
||||
case BL_NPC: return &((TBL_NPC*)bl)->sc;
|
||||
case BL_HOM: return &((TBL_HOM*)bl)->sc;
|
||||
case BL_MER: return &((TBL_MER*)bl)->sc;
|
||||
case BL_PC: return &((TBL_PC*)bl)->sc;
|
||||
case BL_MOB: return &((TBL_MOB*)bl)->sc;
|
||||
case BL_NPC: return &((TBL_NPC*)bl)->sc;
|
||||
case BL_HOM: return &((TBL_HOM*)bl)->sc;
|
||||
case BL_MER: return &((TBL_MER*)bl)->sc;
|
||||
case BL_ELEM: return &((TBL_ELEM*)bl)->sc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -9336,8 +9462,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
|
||||
break;
|
||||
|
||||
case SC_BLOODSUCKER:
|
||||
if( --(sce->val4) >= 0 )
|
||||
{
|
||||
if( --(sce->val4) >= 0 ) {
|
||||
struct block_list *src = map_id2bl(sce->val2);
|
||||
int damage;
|
||||
if( !src || (src && (status_isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12)) )
|
||||
|
@ -592,6 +592,8 @@ typedef enum sc_type {
|
||||
SC_SOULCOLD, //510
|
||||
SC_HAWKEYES,
|
||||
SC_ODINS_POWER,
|
||||
|
||||
|
||||
SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
|
||||
} sc_type;
|
||||
|
||||
@ -1038,7 +1040,7 @@ enum si_type {
|
||||
SI_COLD = 437,
|
||||
SI_GLOOMYDAY = 438,
|
||||
SI_SONGOFMANA = 439,
|
||||
SI_CLOUD_KILL = 440,
|
||||
SI_CLOUDKILL = 440,
|
||||
SI_DANCEWITHWUG = 441,
|
||||
SI_RUSHWINDMILL = 442,
|
||||
SI_ECHOSONG = 443,
|
||||
@ -1059,10 +1061,10 @@ enum si_type {
|
||||
SI_FREEZE_SP = 458,
|
||||
SI_GN_TRAINING_SWORD = 459,
|
||||
SI_GN_REMODELING_CART = 460,
|
||||
SI_GN_CARTBOOST = 461,
|
||||
SI_CARTSBOOST = 461,
|
||||
SI_FIXEDCASTINGTM_REDUCE = 462,
|
||||
SI_THORNS_TRAP = 463,
|
||||
SI_BLOOD_SUCKER = 464,
|
||||
SI_THORNTRAP = 463,
|
||||
SI_BLOODSUCKER = 464,
|
||||
SI_SPORE_EXPLOSION = 465,
|
||||
SI_DEMONIC_FIRE = 466,
|
||||
SI_FIRE_EXPANSION_SMOKE_POWDER = 467,
|
||||
@ -1132,11 +1134,11 @@ enum si_type {
|
||||
SI_STONE_SHIELD = 531,
|
||||
SI_STONE_SHIELD_OPTION = 532,
|
||||
SI_POWER_OF_GAIA = 533,
|
||||
SI_EL_WAIT = 534,
|
||||
SI_EL_PASSIVE = 535,
|
||||
SI_EL_DEFENSIVE = 536,
|
||||
SI_EL_OFFENSIVE = 537,
|
||||
SI_EL_COST = 538,
|
||||
// SI_EL_WAIT = 534,
|
||||
// SI_EL_PASSIVE = 535,
|
||||
// SI_EL_DEFENSIVE = 536,
|
||||
// SI_EL_OFFENSIVE = 537,
|
||||
// SI_EL_COST = 538,
|
||||
SI_PYROTECHNIC = 539,
|
||||
SI_PYROTECHNIC_OPTION = 540,
|
||||
SI_HEATER = 541,
|
||||
@ -1671,6 +1673,7 @@ int status_change_clear_buffs(struct block_list* bl, int type);
|
||||
#define status_calc_pc(sd, first) status_calc_bl_(&(sd)->bl, SCB_ALL, first)
|
||||
#define status_calc_homunculus(hd, first) status_calc_bl_(&(hd)->bl, SCB_ALL, first)
|
||||
#define status_calc_mercenary(md, first) status_calc_bl_(&(md)->bl, SCB_ALL, first)
|
||||
#define status_calc_elemental(ed, first) status_calc_bl_(&(ed)->bl, SCB_ALL, first)
|
||||
|
||||
void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first);
|
||||
int status_calc_mob_(struct mob_data* md, bool first);
|
||||
@ -1678,6 +1681,7 @@ int status_calc_pet_(struct pet_data* pd, bool first);
|
||||
int status_calc_pc_(struct map_session_data* sd, bool first);
|
||||
int status_calc_homunculus_(struct homun_data *hd, bool first);
|
||||
int status_calc_mercenary_(struct mercenary_data *md, bool first);
|
||||
int status_calc_elemental_(struct elemental_data *ed, bool first);
|
||||
|
||||
void status_calc_misc(struct block_list *bl, struct status_data *status, int level);
|
||||
void status_calc_regen(struct block_list *bl, struct status_data *status, struct regen_data *regen);
|
||||
|
289
src/map/unit.c
289
src/map/unit.c
@ -16,6 +16,7 @@
|
||||
#include "homunculus.h"
|
||||
#include "instance.h"
|
||||
#include "mercenary.h"
|
||||
#include "elemental.h"
|
||||
#include "skill.h"
|
||||
#include "clif.h"
|
||||
#include "duel.h"
|
||||
@ -50,6 +51,7 @@ struct unit_data* unit_bl2ud(struct block_list *bl)
|
||||
if( bl->type == BL_NPC) return &((struct npc_data*)bl)->ud;
|
||||
if( bl->type == BL_HOM) return &((struct homun_data*)bl)->ud;
|
||||
if( bl->type == BL_MER) return &((struct mercenary_data*)bl)->ud;
|
||||
if( bl->type == BL_ELEM) return &((struct elemental_data*)bl)->ud;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2006,148 +2008,155 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
|
||||
skill_cleartimerskill(bl);
|
||||
}
|
||||
|
||||
switch( bl->type )
|
||||
{
|
||||
case BL_PC:
|
||||
{
|
||||
struct map_session_data *sd = (struct map_session_data*)bl;
|
||||
switch( bl->type ) {
|
||||
case BL_PC: {
|
||||
struct map_session_data *sd = (struct map_session_data*)bl;
|
||||
|
||||
//Leave/reject all invitations.
|
||||
if(sd->chatID)
|
||||
chat_leavechat(sd,0);
|
||||
if(sd->trade_partner)
|
||||
trade_tradecancel(sd);
|
||||
vending_closevending(sd);
|
||||
buyingstore_close(sd);
|
||||
searchstore_close(sd);
|
||||
if(sd->state.storage_flag == 1)
|
||||
storage_storage_quit(sd,0);
|
||||
else if (sd->state.storage_flag == 2)
|
||||
storage_guild_storage_quit(sd,0);
|
||||
sd->state.storage_flag = 0; //Force close it when being warped.
|
||||
if(sd->party_invite>0)
|
||||
party_reply_invite(sd,sd->party_invite,0);
|
||||
if(sd->guild_invite>0)
|
||||
guild_reply_invite(sd,sd->guild_invite,0);
|
||||
if(sd->guild_alliance>0)
|
||||
guild_reply_reqalliance(sd,sd->guild_alliance_account,0);
|
||||
if(sd->menuskill_id)
|
||||
sd->menuskill_id = sd->menuskill_val = 0;
|
||||
if( sd->touching_id )
|
||||
npc_touchnext_areanpc(sd,true);
|
||||
//Leave/reject all invitations.
|
||||
if(sd->chatID)
|
||||
chat_leavechat(sd,0);
|
||||
if(sd->trade_partner)
|
||||
trade_tradecancel(sd);
|
||||
vending_closevending(sd);
|
||||
buyingstore_close(sd);
|
||||
searchstore_close(sd);
|
||||
if(sd->state.storage_flag == 1)
|
||||
storage_storage_quit(sd,0);
|
||||
else if (sd->state.storage_flag == 2)
|
||||
storage_guild_storage_quit(sd,0);
|
||||
sd->state.storage_flag = 0; //Force close it when being warped.
|
||||
if(sd->party_invite>0)
|
||||
party_reply_invite(sd,sd->party_invite,0);
|
||||
if(sd->guild_invite>0)
|
||||
guild_reply_invite(sd,sd->guild_invite,0);
|
||||
if(sd->guild_alliance>0)
|
||||
guild_reply_reqalliance(sd,sd->guild_alliance_account,0);
|
||||
if(sd->menuskill_id)
|
||||
sd->menuskill_id = sd->menuskill_val = 0;
|
||||
if( sd->touching_id )
|
||||
npc_touchnext_areanpc(sd,true);
|
||||
|
||||
sd->npc_shopid = 0;
|
||||
sd->adopt_invite = 0;
|
||||
sd->npc_shopid = 0;
|
||||
sd->adopt_invite = 0;
|
||||
|
||||
if(sd->pvp_timer != INVALID_TIMER) {
|
||||
delete_timer(sd->pvp_timer,pc_calc_pvprank_timer);
|
||||
sd->pvp_timer = INVALID_TIMER;
|
||||
sd->pvp_rank = 0;
|
||||
}
|
||||
if(sd->duel_group > 0)
|
||||
duel_leave(sd->duel_group, sd);
|
||||
|
||||
if(pc_issit(sd)) {
|
||||
pc_setstand(sd);
|
||||
skill_sit(sd,0);
|
||||
}
|
||||
party_send_dot_remove(sd);//minimap dot fix [Kevin]
|
||||
guild_send_dot_remove(sd);
|
||||
bg_send_dot_remove(sd);
|
||||
|
||||
if( map[bl->m].users <= 0 || sd->state.debug_remove_map )
|
||||
{// this is only place where map users is decreased, if the mobs were removed too soon then this function was executed too many times [FlavioJS]
|
||||
if( sd->debug_file == NULL || !(sd->state.debug_remove_map) )
|
||||
{
|
||||
sd->debug_file = "";
|
||||
sd->debug_line = 0;
|
||||
sd->debug_func = "";
|
||||
if(sd->pvp_timer != INVALID_TIMER) {
|
||||
delete_timer(sd->pvp_timer,pc_calc_pvprank_timer);
|
||||
sd->pvp_timer = INVALID_TIMER;
|
||||
sd->pvp_rank = 0;
|
||||
}
|
||||
ShowDebug("unit_remove_map: unexpected state when removing player AID/CID:%d/%d"
|
||||
" (active=%d connect_new=%d rewarp=%d changemap=%d debug_remove_map=%d)"
|
||||
" from map=%s (users=%d)."
|
||||
" Previous call from %s:%d(%s), current call from %s:%d(%s)."
|
||||
" Please report this!!!\n",
|
||||
sd->status.account_id, sd->status.char_id,
|
||||
sd->state.active, sd->state.connect_new, sd->state.rewarp, sd->state.changemap, sd->state.debug_remove_map,
|
||||
map[bl->m].name, map[bl->m].users,
|
||||
sd->debug_file, sd->debug_line, sd->debug_func, file, line, func);
|
||||
}
|
||||
else
|
||||
if (--map[bl->m].users == 0 && battle_config.dynamic_mobs) //[Skotlex]
|
||||
map_removemobs(bl->m);
|
||||
if( !(sd->sc.option&OPTION_INVISIBLE) )
|
||||
{// decrement the number of active pvp players on the map
|
||||
--map[bl->m].users_pvp;
|
||||
}
|
||||
if( map[bl->m].instance_id )
|
||||
{
|
||||
instance[map[bl->m].instance_id].users--;
|
||||
instance_check_idle(map[bl->m].instance_id);
|
||||
}
|
||||
sd->state.debug_remove_map = 1; // temporary state to track double remove_map's [FlavioJS]
|
||||
sd->debug_file = file;
|
||||
sd->debug_line = line;
|
||||
sd->debug_func = func;
|
||||
if(sd->duel_group > 0)
|
||||
duel_leave(sd->duel_group, sd);
|
||||
|
||||
break;
|
||||
}
|
||||
case BL_MOB:
|
||||
{
|
||||
struct mob_data *md = (struct mob_data*)bl;
|
||||
// Drop previous target mob_slave_keep_target: no.
|
||||
if (!battle_config.mob_slave_keep_target)
|
||||
md->target_id=0;
|
||||
if(pc_issit(sd)) {
|
||||
pc_setstand(sd);
|
||||
skill_sit(sd,0);
|
||||
}
|
||||
party_send_dot_remove(sd);//minimap dot fix [Kevin]
|
||||
guild_send_dot_remove(sd);
|
||||
bg_send_dot_remove(sd);
|
||||
|
||||
md->attacked_id=0;
|
||||
md->state.skillstate= MSS_IDLE;
|
||||
if( map[bl->m].users <= 0 || sd->state.debug_remove_map )
|
||||
{// this is only place where map users is decreased, if the mobs were removed too soon then this function was executed too many times [FlavioJS]
|
||||
if( sd->debug_file == NULL || !(sd->state.debug_remove_map) )
|
||||
{
|
||||
sd->debug_file = "";
|
||||
sd->debug_line = 0;
|
||||
sd->debug_func = "";
|
||||
}
|
||||
ShowDebug("unit_remove_map: unexpected state when removing player AID/CID:%d/%d"
|
||||
" (active=%d connect_new=%d rewarp=%d changemap=%d debug_remove_map=%d)"
|
||||
" from map=%s (users=%d)."
|
||||
" Previous call from %s:%d(%s), current call from %s:%d(%s)."
|
||||
" Please report this!!!\n",
|
||||
sd->status.account_id, sd->status.char_id,
|
||||
sd->state.active, sd->state.connect_new, sd->state.rewarp, sd->state.changemap, sd->state.debug_remove_map,
|
||||
map[bl->m].name, map[bl->m].users,
|
||||
sd->debug_file, sd->debug_line, sd->debug_func, file, line, func);
|
||||
}
|
||||
else
|
||||
if (--map[bl->m].users == 0 && battle_config.dynamic_mobs) //[Skotlex]
|
||||
map_removemobs(bl->m);
|
||||
if( !(sd->sc.option&OPTION_INVISIBLE) )
|
||||
{// decrement the number of active pvp players on the map
|
||||
--map[bl->m].users_pvp;
|
||||
}
|
||||
if( map[bl->m].instance_id )
|
||||
{
|
||||
instance[map[bl->m].instance_id].users--;
|
||||
instance_check_idle(map[bl->m].instance_id);
|
||||
}
|
||||
sd->state.debug_remove_map = 1; // temporary state to track double remove_map's [FlavioJS]
|
||||
sd->debug_file = file;
|
||||
sd->debug_line = line;
|
||||
sd->debug_func = func;
|
||||
|
||||
break;
|
||||
}
|
||||
case BL_PET:
|
||||
{
|
||||
struct pet_data *pd = (struct pet_data*)bl;
|
||||
if( pd->pet.intimate <= 0 && !(pd->msd && !pd->msd->state.active) )
|
||||
{ //If logging out, this is deleted on unit_free
|
||||
clif_clearunit_area(bl,clrtype);
|
||||
map_delblock(bl);
|
||||
unit_free(bl,CLR_OUTSIGHT);
|
||||
map_freeblock_unlock();
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
case BL_MOB: {
|
||||
struct mob_data *md = (struct mob_data*)bl;
|
||||
// Drop previous target mob_slave_keep_target: no.
|
||||
if (!battle_config.mob_slave_keep_target)
|
||||
md->target_id=0;
|
||||
|
||||
break;
|
||||
}
|
||||
case BL_HOM:
|
||||
{
|
||||
struct homun_data *hd = (struct homun_data *)bl;
|
||||
ud->canact_tick = ud->canmove_tick; //It appears HOM do reset the can-act tick.
|
||||
if( !hd->homunculus.intimacy && !(hd->master && !hd->master->state.active) )
|
||||
{ //If logging out, this is deleted on unit_free
|
||||
clif_emotion(bl, E_SOB);
|
||||
clif_clearunit_area(bl,clrtype);
|
||||
map_delblock(bl);
|
||||
unit_free(bl,CLR_OUTSIGHT);
|
||||
map_freeblock_unlock();
|
||||
return 0;
|
||||
md->attacked_id=0;
|
||||
md->state.skillstate= MSS_IDLE;
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BL_MER:
|
||||
{
|
||||
struct mercenary_data *md = (struct mercenary_data *)bl;
|
||||
ud->canact_tick = ud->canmove_tick;
|
||||
if( mercenary_get_lifetime(md) <= 0 && !(md->master && !md->master->state.active) )
|
||||
{
|
||||
clif_clearunit_area(bl,clrtype);
|
||||
map_delblock(bl);
|
||||
unit_free(bl,CLR_OUTSIGHT);
|
||||
map_freeblock_unlock();
|
||||
return 0;
|
||||
case BL_PET: {
|
||||
struct pet_data *pd = (struct pet_data*)bl;
|
||||
if( pd->pet.intimate <= 0 && !(pd->msd && !pd->msd->state.active) )
|
||||
{ //If logging out, this is deleted on unit_free
|
||||
clif_clearunit_area(bl,clrtype);
|
||||
map_delblock(bl);
|
||||
unit_free(bl,CLR_OUTSIGHT);
|
||||
map_freeblock_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: ;// do nothing
|
||||
case BL_HOM: {
|
||||
struct homun_data *hd = (struct homun_data *)bl;
|
||||
ud->canact_tick = ud->canmove_tick; //It appears HOM do reset the can-act tick.
|
||||
if( !hd->homunculus.intimacy && !(hd->master && !hd->master->state.active) )
|
||||
{ //If logging out, this is deleted on unit_free
|
||||
clif_emotion(bl, E_SOB);
|
||||
clif_clearunit_area(bl,clrtype);
|
||||
map_delblock(bl);
|
||||
unit_free(bl,CLR_OUTSIGHT);
|
||||
map_freeblock_unlock();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BL_MER: {
|
||||
struct mercenary_data *md = (struct mercenary_data *)bl;
|
||||
ud->canact_tick = ud->canmove_tick;
|
||||
if( mercenary_get_lifetime(md) <= 0 && !(md->master && !md->master->state.active) )
|
||||
{
|
||||
clif_clearunit_area(bl,clrtype);
|
||||
map_delblock(bl);
|
||||
unit_free(bl,CLR_OUTSIGHT);
|
||||
map_freeblock_unlock();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BL_ELEM: {
|
||||
struct elemental_data *ed = (struct elemental_data *)bl;
|
||||
ud->canact_tick = ud->canmove_tick;
|
||||
if( elemental_get_lifetime(ed) <= 0 && !(ed->master && !ed->master->state.active) )
|
||||
{
|
||||
clif_clearunit_area(bl,clrtype);
|
||||
map_delblock(bl);
|
||||
unit_free(bl,0);
|
||||
map_freeblock_unlock();
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;// do nothing
|
||||
}
|
||||
/**
|
||||
* BL_MOB is handled by mob_dead unless the monster is not dead.
|
||||
@ -2391,6 +2400,24 @@ int unit_free(struct block_list *bl, clr_type clrtype)
|
||||
merc_contract_stop(md);
|
||||
break;
|
||||
}
|
||||
case BL_ELEM: {
|
||||
struct elemental_data *ed = (TBL_ELEM*)bl;
|
||||
struct map_session_data *sd = ed->master;
|
||||
if( clrtype >= 0 ) {
|
||||
if( elemental_get_lifetime(ed) > 0 )
|
||||
elemental_save(ed);
|
||||
else {
|
||||
intif_elemental_delete(ed->elemental.elemental_id);
|
||||
if( sd )
|
||||
sd->status.ele_id = 0;
|
||||
}
|
||||
}
|
||||
if( sd )
|
||||
sd->ed = NULL;
|
||||
|
||||
elemental_summon_stop(ed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
skill_clear_unitgroup(bl);
|
||||
|
@ -154,6 +154,7 @@
|
||||
<ClInclude Include="..\src\common\utils.h" />
|
||||
<ClInclude Include="..\src\char\char.h" />
|
||||
<ClInclude Include="..\src\char\int_auction.h" />
|
||||
<ClInclude Include="..\src\char\int_elemental.h" />
|
||||
<ClInclude Include="..\src\char\int_guild.h" />
|
||||
<ClInclude Include="..\src\char\int_homun.h" />
|
||||
<ClInclude Include="..\src\char\int_mail.h" />
|
||||
@ -187,6 +188,7 @@
|
||||
<ClCompile Include="..\src\common\utils.c" />
|
||||
<ClCompile Include="..\src\char\char.c" />
|
||||
<ClCompile Include="..\src\char\int_auction.c" />
|
||||
<ClCompile Include="..\src\char\int_elemental.c" />
|
||||
<ClCompile Include="..\src\char\int_guild.c" />
|
||||
<ClCompile Include="..\src\char\int_homun.c" />
|
||||
<ClCompile Include="..\src\char\int_mail.c" />
|
||||
|
@ -164,6 +164,7 @@
|
||||
<ClInclude Include="..\src\map\clif.h" />
|
||||
<ClInclude Include="..\src\map\date.h" />
|
||||
<ClInclude Include="..\src\map\duel.h" />
|
||||
<ClInclude Include="..\src\map\elemental.h" />
|
||||
<ClInclude Include="..\src\map\guild.h" />
|
||||
<ClInclude Include="..\src\map\intif.h" />
|
||||
<ClInclude Include="..\src\map\itemdb.h" />
|
||||
@ -231,6 +232,7 @@
|
||||
<ClCompile Include="..\src\map\clif.c" />
|
||||
<ClCompile Include="..\src\map\date.c" />
|
||||
<ClCompile Include="..\src\map\duel.c" />
|
||||
<ClCompile Include="..\src\map\elemental.c" />
|
||||
<ClCompile Include="..\src\map\guild.c" />
|
||||
<ClCompile Include="..\src\map\intif.c" />
|
||||
<ClCompile Include="..\src\map\itemdb.c" />
|
||||
|
@ -464,6 +464,14 @@
|
||||
RelativePath="..\src\char\int_mercenary.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\char\int_elemental.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\char\int_elemental.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\char\int_party.c"
|
||||
>
|
||||
|
@ -603,6 +603,14 @@
|
||||
RelativePath="..\src\map\mercenary.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\map\elemental.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\map\elemental.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\map\mob.c"
|
||||
>
|
||||
|
Loading…
x
Reference in New Issue
Block a user