Orn's and Albator's Homunculus system, finally, YAY!!
git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@7706 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
18d00eb924
commit
15dd140846
@ -4,6 +4,10 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
|
||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
|
||||
2006/07/17
|
||||
* Added Homunculus system, enjoy! [orn aka Nylou]
|
||||
- WARNING: This currently only works with the SQL version, as the TXT char-server
|
||||
has no code for it at the moment. You TXT server won't break, but the char-server
|
||||
will complain of an unknown packet if you try to get an Homunculus
|
||||
* Updated nomemo mapflags based on info from http://ro.doddlercon.com/images/memo.jpg [Poki#3]
|
||||
|
||||
2006/07/15
|
||||
|
@ -130,3 +130,12 @@ duel_time_interval: 60
|
||||
// NOTE: For this setting to make effect you have to use a server compiled with
|
||||
// Cell Stack Limit support (see src/map/map.h)
|
||||
cell_stack_limit: 1
|
||||
|
||||
|
||||
// Homunculus settings: I put them there at the moment, they will certainly get their own file later [DracoRPG]
|
||||
|
||||
// Intimacy needed to use Evolved Vanilmirth's Bio Explosion
|
||||
hvan_explosion_intimate: 45000
|
||||
|
||||
// Show stat growth to the owner when an Homunculus levels up
|
||||
homunculus_show_growth: 0
|
100
db/exp_homun.txt
Normal file
100
db/exp_homun.txt
Normal file
@ -0,0 +1,100 @@
|
||||
//Homunculus LvUp experience value table
|
||||
50
|
||||
110
|
||||
180
|
||||
260
|
||||
350
|
||||
630
|
||||
950
|
||||
1310
|
||||
1710
|
||||
2150
|
||||
3180
|
||||
4300
|
||||
5510
|
||||
6810
|
||||
8200
|
||||
10800
|
||||
13560
|
||||
16480
|
||||
19560
|
||||
22800
|
||||
28090
|
||||
33630
|
||||
39420
|
||||
45460
|
||||
51750
|
||||
6150
|
||||
70910
|
||||
81030
|
||||
91510
|
||||
102350
|
||||
117580
|
||||
133300
|
||||
149510
|
||||
166210
|
||||
183400
|
||||
206480
|
||||
230200
|
||||
254560
|
||||
279560
|
||||
305200
|
||||
338450
|
||||
372510
|
||||
407380
|
||||
443060
|
||||
479550
|
||||
525590
|
||||
572630
|
||||
620670
|
||||
669710
|
||||
719750
|
||||
781500
|
||||
844460
|
||||
908630
|
||||
974010
|
||||
1040600
|
||||
1121280
|
||||
1203400
|
||||
1286960
|
||||
1371960
|
||||
1458400
|
||||
1561530
|
||||
1666350
|
||||
1772860
|
||||
1881060
|
||||
1990950
|
||||
2120350
|
||||
2251710
|
||||
2385030
|
||||
2520310
|
||||
2657550
|
||||
2817340
|
||||
2979380
|
||||
3143670
|
||||
3310210
|
||||
3479000
|
||||
3673600
|
||||
3870760
|
||||
4070480
|
||||
4272760
|
||||
4477600
|
||||
4711730
|
||||
4948750
|
||||
5188660
|
||||
5431460
|
||||
5677150
|
||||
5955830
|
||||
6237750
|
||||
6522910
|
||||
6811310
|
||||
7102950
|
||||
7431500
|
||||
7763660
|
||||
8099430
|
||||
8438810
|
||||
8781800
|
||||
9165840
|
||||
9553880
|
||||
9945920
|
||||
0
|
73
db/homun_skill_tree.txt
Normal file
73
db/homun_skill_tree.txt
Normal file
@ -0,0 +1,73 @@
|
||||
//CLass,Skill-ID,MaxLV,Prerequisite Skill-ID-1,Prerequisite Skill-ID-1-Lv,PrereqSkill-ID-2,PrereqSkill-ID-2-Lv,PrereqSkill-ID-3,PrereqSkill-ID-3-Lv,PrereqSkill-ID-4,PrereqSkill-ID-4-Lv,PrereqSkill-ID-5,PrereqSkill-ID-5-Lv//CLASS_SKILLNAME#Skill Name#
|
||||
//Lif
|
||||
6001,8001,5,0,0,0,0,0,0,0,0,0,0 //HLIF_HEAL
|
||||
6001,8002,5,8001,3,0,0,0,0,0,0,0,0 //HLIF_AVOID
|
||||
6001,8003,5,8001,5,0,0,0,0,0,0,0,0 //HLIF_BRAIN
|
||||
//Amistr
|
||||
6002,8005,5,0,0,0,0,0,0,0,0,0,0 //HAMI_CASTLE
|
||||
6002,8006,5,8005,5,0,0,0,0,0,0,0,0 //HAMI_DEFENCE
|
||||
6002,8007,5,8006,3,0,0,0,0,0,0,0,0 //HAMI_SKIN
|
||||
//Filir
|
||||
6003,8009,5,0,0,0,0,0,0,0,0,0,0 //HFLI_MOON
|
||||
6003,8010,5,8009,3,0,0,0,0,0,0,0,0 //HFLI_FLEET
|
||||
6003,8011,5,8010,3,0,0,0,0,0,0,0,0 //HFLI_SPEED
|
||||
//Vanilmirth
|
||||
6004,8013,5,0,0,0,0,0,0,0,0,0,0 //HVAN_CAPRICE,
|
||||
6004,8014,5,8013,3,0,0,0,0,0,0,0,0 //HVAN_CHAOTIC
|
||||
6004,8015,5,8013,5,0,0,0,0,0,0,0,0 //HVAN_INSTRUCT
|
||||
//Lif2
|
||||
6005,8001,5,0,0,0,0,0,0,0,0,0,0 //HLIF_HEAL
|
||||
6005,8002,5,8001,3,0,0,0,0,0,0,0,0 //HLIF_AVOID
|
||||
6005,8003,5,8001,5,0,0,0,0,0,0,0,0 //HLIF_BRAIN
|
||||
//Amistr2
|
||||
6006,8005,5,0,0,0,0,0,0,0,0,0,0 //HAMI_CASTLE
|
||||
6006,8006,5,8005,5,0,0,0,0,0,0,0,0 //HAMI_DEFENCE
|
||||
6006,8007,5,8006,3,0,0,0,0,0,0,0,0 //HAMI_SKIN
|
||||
//Filir2
|
||||
6007,8009,5,0,0,0,0,0,0,0,0,0,0 //HFLI_MOON
|
||||
6007,8010,5,8009,3,0,0,0,0,0,0,0,0 //HFLI_FLEET
|
||||
6007,8011,5,8010,3,0,0,0,0,0,0,0,0 //HFLI_SPEED
|
||||
//Vanilmirth2
|
||||
6008,8013,5,0,0,0,0,0,0,0,0,0,0 //HVAN_CAPRICE,
|
||||
6008,8014,5,8013,3,0,0,0,0,0,0,0,0 //HVAN_CHAOTIC
|
||||
6008,8015,5,8013,5,0,0,0,0,0,0,0,0 //HVAN_INSTRUCT
|
||||
//Lif_H
|
||||
6009,8001,5,0,0,0,0,0,0,0,0,0,0 //HLIF_HEAL
|
||||
6009,8002,5,8001,3,0,0,0,0,0,0,0,0 //HLIF_AVOID
|
||||
6009,8003,5,8001,5,0,0,0,0,0,0,0,0 //HLIF_BRAIN
|
||||
6009,8004,3,0,0,0,0,0,0,0,0,0,0 //HLIF_CHANGE
|
||||
//Amistr_H
|
||||
6010,8005,5,0,0,0,0,0,0,0,0,0,0 //HAMI_CASTLE
|
||||
6010,8006,5,8005,5,0,0,0,0,0,0,0,0 //HAMI_DEFENCE
|
||||
6010,8007,5,8006,3,0,0,0,0,0,0,0,0 //HAMI_SKIN
|
||||
6010,8008,3,0,0,0,0,0,0,0,0,0,0 //HAMI_BLOODLUST
|
||||
//Filir_H
|
||||
6011,8009,5,0,0,0,0,0,0,0,0,0,0 //HFLI_MOON
|
||||
6011,8010,5,8009,3,0,0,0,0,0,0,0,0 //HFLI_FLEET
|
||||
6011,8011,5,8010,3,0,0,0,0,0,0,0,0 //HFLI_SPEED
|
||||
6011,8012,3,0,0,0,0,0,0,0,0,0,0 //HFLI_SBR44
|
||||
//Vanilmirth_H
|
||||
6012,8013,5,0,0,0,0,0,0,0,0,0,0 //HVAN_CAPRICE,
|
||||
6012,8014,5,8013,3,0,0,0,0,0,0,0,0 //HVAN_CHAOTIC
|
||||
6012,8015,5,8013,5,0,0,0,0,0,0,0,0 //HVAN_INSTRUCT
|
||||
6012,8016,3,0,0,0,0,0,0,0,0,0,0 //HVAN_EXPLOSION
|
||||
//Lif2_H
|
||||
6013,8001,5,0,0,0,0,0,0,0,0,0,0 //HLIF_HEAL
|
||||
6013,8002,5,8001,3,0,0,0,0,0,0,0,0 //HLIF_AVOID
|
||||
6013,8003,5,8001,5,0,0,0,0,0,0,0,0 //HLIF_BRAIN
|
||||
6013,8004,3,0,0,0,0,0,0,0,0,0,0 //HLIF_CHANGE
|
||||
//Amistr2_H
|
||||
6014,8005,5,0,0,0,0,0,0,0,0,0,0 //HAMI_CASTLE
|
||||
6014,8006,5,8005,5,0,0,0,0,0,0,0,0 //HAMI_DEFENCE
|
||||
6014,8007,5,8006,3,0,0,0,0,0,0,0,0 //HAMI_SKIN
|
||||
6014,8008,3,0,0,0,0,0,0,0,0,0,0 //HAMI_BLOODLUST
|
||||
//Filir2_H
|
||||
6015,8009,5,0,0,0,0,0,0,0,0,0,0 //HFLI_MOON
|
||||
6015,8010,5,8009,3,0,0,0,0,0,0,0,0 //HFLI_FLEET
|
||||
6015,8011,5,8010,3,0,0,0,0,0,0,0,0 //HFLI_SPEED
|
||||
6015,8012,3,0,0,0,0,0,0,0,0,0,0 //HFLI_SBR44
|
||||
//Vanilmirth2_H
|
||||
6016,8013,5,0,0,0,0,0,0,0,0,0,0 //HVAN_CAPRICE,
|
||||
6016,8014,5,8013,3,0,0,0,0,0,0,0,0 //HVAN_CHAOTIC
|
||||
6016,8015,5,8013,5,0,0,0,0,0,0,0,0 //HVAN_INSTRUCT
|
||||
6016,8016,3,0,0,0,0,0,0,0,0,0,0 //HVAN_EXPLOSION
|
17
db/homunculus_db.txt
Normal file
17
db/homunculus_db.txt
Normal file
@ -0,0 +1,17 @@
|
||||
//class,name,baseHP,baseSP,baseSTR,baseAGI,baseVIT,baseINT,baseDEX,baseLUK,baseIntimacy,baseHungry,hungryDelay,foodID,gminHP,gmaxHP,gminSP,gmaxSP,gminSTR,gmaxSTR,gminAGI,gmaxAGI,gminVIT,gmaxVIT,gminINT,gmaxINT,gminDEX,gmaxDEX,gminLUK,gmaxLUK,evol_class,baseASPD,size,race,element,accessID
|
||||
6001,Lif,150,40,17,20,15,35,24,12,21,32,60000,537,60,100,4,9,1,8,3,8,1,14,1,14,1,14,3,14,6009,700,0,0,0,0
|
||||
6002,Amistr,320,10,20,17,35,11,24,12,21,32,60000,912,80,130,1,4,3,14,3,12,1,14,1,2,2,8,3,10,6010,700,0,0,0,0
|
||||
6003,Filir,90,25,29,35,9,8,30,9,21,32,60000,910,45,75,3,6,1,14,1,20,1,1,2,8,1,14,3,10,6011,700,0,0,0,0
|
||||
6004,Vanilmirth,80,11,11,11,11,11,11,11,21,32,60000,911,30,150,0,7,1,20,1,20,1,20,1,20,1,20,3,20,6012,700,0,0,0,0
|
||||
6005,Lif2,150,40,17,20,15,35,24,12,21,32,60000,537,60,100,4,9,1,8,3,8,1,14,1,14,1,14,3,14,6013,700,0,0,0,0
|
||||
6006,Amistr2,320,10,20,17,35,11,24,12,21,32,60000,912,80,130,1,4,3,14,3,12,1,14,1,2,2,8,3,10,6014,700,0,0,0,0
|
||||
6007,Filir2,90,25,29,35,9,8,30,9,21,32,60000,910,45,75,3,6,1,14,1,20,1,1,2,8,1,14,3,10,6015,700,0,0,0,0
|
||||
6008,Vanilmirth2,80,11,11,11,11,11,11,11,21,32,60000,911,30,150,0,7,1,20,1,20,1,20,1,20,1,20,3,20,6016,700,0,0,0,0
|
||||
6009,Lif_H,150,40,17,20,15,35,24,12,21,32,60000,537,60,100,4,9,1,8,3,8,1,14,1,14,1,14,3,14,0,700,1,0,0,0
|
||||
6010,Amistr_H,320,10,20,17,35,11,24,12,21,32,60000,912,80,130,1,4,3,14,3,12,1,14,1,2,2,8,3,10,0,700,1,0,0,0
|
||||
6011,Filir_H,90,25,29,35,9,8,30,9,21,32,60000,910,45,75,3,6,1,14,1,20,1,1,2,8,1,14,3,10,0,700,1,0,0,0
|
||||
6012,Vanilmirth_H,80,11,11,11,11,11,11,11,21,32,60000,911,30,150,0,7,1,20,1,20,1,20,1,20,1,20,3,20,0,700,1,0,0,0
|
||||
6013,Lif2_H,150,40,17,20,15,35,24,12,21,32,60000,537,60,100,4,9,1,8,3,8,1,14,1,14,1,14,3,14,0,700,1,0,0,0
|
||||
6014,Amistr2_H,320,10,20,17,35,11,24,12,21,32,60000,912,80,130,1,4,3,14,3,12,1,14,1,2,2,8,3,10,0,700,1,0,0,0
|
||||
6015,Filir2_H,90,25,29,35,9,8,30,9,21,32,60000,910,45,75,3,6,1,14,1,20,1,1,2,8,1,14,3,10,0,700,1,0,0,0
|
||||
6016,Vanilmirth2_H,80,11,11,11,11,11,11,11,21,32,60000,911,30,150,0,7,1,20,1,20,1,20,1,20,1,20,3,20,0,700,1,0,0,0
|
@ -2433,7 +2433,7 @@
|
||||
12037,Lotto_Box_03,Lotto Box 03,2,,10,20,,,,,0xFFFFFFFF,7,2,,,,,,{ getitem rand(7381,7390),1; },{},{}
|
||||
12038,Lotto_Box_04,Lotto Box 04,2,,10,20,,,,,0xFFFFFFFF,7,2,,,,,,{ getitem groupranditem(IG_LottoBox),1; },{},{}
|
||||
12039,Lotto_Box_05,Lotto Box 05,2,,10,20,,,,,0xFFFFFFFF,7,2,,,,,,{ getitem rand(7542,7546),1; },{},{}
|
||||
12040,Philosopher's_Stone,Philosopher's Stone,2,,50000,300,,,,,0xFFFFFFFF,7,2,,,,,,{},{},{}
|
||||
12040,Philosopher's_Stone,Philosopher's Stone,2,,50000,300,,,,,0xFFFFFFFF,7,2,,,,,,{ homevolution ; },{},{}
|
||||
// Mixed Foods (+1 to +5)
|
||||
12041,Boiled_Down_Locust,Boiled Down Locust,0,2000,,60,,,,,0xFFFFFFFF,7,2,,,,,,{ sc_start SC_STRFood, 1200000, 1; percentheal 5,0; },{},{}
|
||||
12042,Seasoned_Webs,Seasoned Webs,0,4000,,500,,,,,0xFFFFFFFF,7,2,,,,,,{ sc_start SC_STRFood, 1200000, 2; percentheal 5,0; },{},{}
|
||||
|
@ -831,19 +831,19 @@
|
||||
1796,G_AUNOE,Aunoe,Aunoe,1,50,0,2,1,1,7,10,0,5,1,1,1,1,6,30,10,12,1,3,21,131,400,1872,672,480,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
|
||||
|
||||
//Homunculi (Don't uncomment) (Why? :P [Poki#3])
|
||||
//6001,LIF,Lif,Lif,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6002,AMISTR,Amistr,Amistr,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6003,FILIR,Filir,Filir,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6004,VANILMIRTH,Vanilmirth,Vanilmirth,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6005,LIF2,Lif,Lif,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6006,AMISTR2,Amistr,Amistr,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6007,FILIR2,Filir,Filir,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6008,VANILMIRTH2,Vanilmirth,Vanilmirth,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6009,LIF_H,Lif,Lif,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6010,AMISTR_H,Amistr,Amistr,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6011,FILIR_H,Filir,Filir,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6012,VANILMIRTH_H,Vanilmirth,Vanilmirth,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6013,LIF_H2,Lif,Lif,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6014,AMISTR_H2,Amistr,Amistr,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6015,FILIR_H2,Filir,Filir,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
//6016,VANILMIRTH_H2,Vanilmirth,Vanilmirth,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
6001,LIF,Lif,Lif,50,8010,708,465,94,1,170,325,48,21,1,94,48,129,99,90,10,12,1,0,60,145,300,1608,816,396,0,0,0,0,0,0,0,0,999,150,953,5500,912,220,757,61,1003,120,715,200,998,350,0,0,0,0,4072,5//1Lif
|
||||
6002,AMISTR,Amistr,Amistr,50,12022,255,465,94,1,208,416,83,12,1,89,84,25,76,75,10,12,1,0,60,145,300,1608,816,396,0,0,0,0,0,0,0,0,999,150,953,5500,912,220,757,61,1003,120,715,200,998,350,0,0,0,0,4072,5//1Amistr
|
||||
6003,FILIR,Filir,Filir,50,5820,515,3872,2695,1,200,401,18,23,1,129,19,95,111,69,10,12,1,0,80,145,250,1608,864,288,0,0,0,0,0,0,0,0,999,150,953,5500,912,220,757,61,1003,120,715,200,998,350,0,0,0,0,4072,5//1Filir
|
||||
6004,VANILMIRTH,Vanilmirth,Vanilmirth,50,9026,358,3872,2695,2,226,452,74,32,1,131,75,155,112,120,10,12,1,0,80,145,250,1264,864,288,0,0,0,0,0,0,0,0,7004,2000,7054,5500,1000,250,997,30,512,0,757,250,985,163,0,0,0,0,4072,5//1Vanilmirth
|
||||
6005,LIF2,Lif,Lif,50,8010,708,465,94,1,170,325,48,21,1,94,48,129,99,90,10,12,1,0,60,145,300,1608,816,396,0,0,0,0,0,0,0,0,999,150,953,5500,912,220,757,61,1003,120,715,200,998,350,0,0,0,0,4072,5//1Lif
|
||||
6006,AMISTR2,Amistr,Amistr,50,12022,255,465,94,1,208,416,83,12,1,89,84,25,76,75,10,12,1,0,80,145,200,1264,864,288,0,0,0,0,0,0,0,0,7004,2000,7054,5500,1000,250,997,30,512,0,757,250,985,163,0,0,0,0,4072,5//1Amistr
|
||||
6007,FILIR2,Filir,Filir,50,5820,515,3872,2695,1,200,401,18,23,1,129,19,95,111,69,10,12,1,0,80,145,200,1024,864,288,0,0,0,0,0,0,0,0,7004,2000,7054,5500,1000,250,997,30,512,0,757,250,985,163,0,0,0,0,4072,5//1Filir
|
||||
6008,VANILMIRTH2,Vanimirth,Vanilmirth,50,9026,358,3872,2695,2,226,452,74,32,1,131,75,155,112,120,10,12,1,0,80,145,150,1024,864,288,0,0,0,0,0,0,0,0,7004,2000,7054,5500,1000,250,997,30,512,0,757,250,985,163,0,0,0,0,4072,5//1Vanilmirth
|
||||
6009,LIF_H,Lif,Lif,50,8010,708,465,94,1,200,410,48,21,1,97,48,155,110,99,10,12,1,0,60,145,300,1608,816,396,0,0,0,0,0,0,0,0,999,150,953,5500,912,220,757,61,1003,120,715,200,998,350,0,0,0,0,4072,5//1Lif
|
||||
6010,AMISTR_H,Amistr,Amistr,50,12022,255,465,94,1,230,460,83,12,1,93,84,30,85,83,10,12,2,0,60,145,300,1608,816,396,0,0,0,0,0,0,0,0,999,150,953,5500,912,220,757,61,1003,120,715,200,998,350,0,0,0,0,4072,5//1Amistr
|
||||
6011,FILIR_H,Filir,Filir,50,5820,515,3872,2695,1,220,440,18,23,1,138,19,105,126,80,10,12,2,0,80,145,250,1608,864,288,0,0,0,0,0,0,0,0,7004,2000,7054,5500,1000,250,997,30,512,0,757,250,985,163,0,0,0,0,4072,5//1Filir
|
||||
6012,VANILMIRTH_H,Vanilmirth,Vanilmirth,50,9026,358,3872,2695,2,280,550,74,32,1,135,75,162,120,126,10,12,2,0,80,145,250,1264,864,288,0,0,0,0,0,0,0,0,7004,2000,7054,5500,1000,250,997,30,512,0,757,250,985,163,0,0,0,0,4072,5//1Vanilmirth
|
||||
6013,LIF_H2,Lif,Lif,50,8010,708,465,94,1,200,410,48,21,1,97,48,155,110,99,10,12,1,0,60,145,300,1608,816,396,0,0,0,0,0,0,0,0,999,150,953,5500,912,220,757,61,1003,120,715,200,998,350,0,0,0,0,4072,5//1Lif
|
||||
6014,AMISTR_H2,Amistr,Amistr,50,12022,255,465,94,1,230,460,83,12,1,93,84,30,85,83,10,12,2,0,80,145,200,1264,864,288,0,0,0,0,0,0,0,0,7004,2000,7054,5500,1000,250,997,30,512,0,757,250,985,163,0,0,0,0,4072,5//1Amistr
|
||||
6015,FILIR_H2,Filir,Filir,50,5820,515,3872,2695,1,220,440,18,23,1,138,19,105,126,80,10,12,2,0,80,145,200,1024,864,288,0,0,0,0,0,0,0,0,7004,2000,7054,5500,1000,250,997,30,512,0,757,250,985,163,0,0,0,0,4072,5//1Filir
|
||||
6016,VANILMIRTH_H2,Vanimirth,Vanilmirth,50,9026,358,3872,2695,2,280,550,74,32,1,135,75,162,120,126,10,12,2,0,80,145,150,1024,864,288,0,0,0,0,0,0,0,0,7004,2000,7054,5500,1000,250,997,30,512,0,757,250,985,163,0,0,0,0,4072,5//1Vanilmirth
|
||||
|
@ -676,9 +676,9 @@ packet_ver: 17
|
||||
0x022b,57
|
||||
0x022c,64
|
||||
0x022d,5
|
||||
0x0232,9
|
||||
0x0233,11
|
||||
0x0234,-1
|
||||
0x0232,9,hommoveto,6
|
||||
0x0233,11,homattack,0
|
||||
0x0234,6,hommovetomaster,0
|
||||
|
||||
//2005-06-28aSakexe by Sara
|
||||
packet_ver: 18
|
||||
@ -695,18 +695,22 @@ packet_ver: 18
|
||||
0x00f3,-1,globalmessage,2:4
|
||||
0x00f5,13,takeitem,9
|
||||
0x00f7,18,movefromkafra,11:14
|
||||
0x0112,4,homuseskillpoint,0
|
||||
0x0113,33,useskilltopos,12:15:18:31
|
||||
0x0116,12,dropitem,3:10
|
||||
0x0143,10,npcamountinput,2:6
|
||||
0x0190,24,actionrequest,11:23
|
||||
0x0193,2,closekafra,0
|
||||
0x20e,10
|
||||
//Homon Status
|
||||
0x22e,71
|
||||
//Start Homunculus?
|
||||
0x230,12
|
||||
//Homon Skill list
|
||||
0x235,115
|
||||
0x022d,5,hommenu,4 // Menu (1 = feed ; 2 = dead)
|
||||
0x022e,71 // Status
|
||||
0x022f,5 // Feeding reply
|
||||
0x0230,12 // Is Homunculus
|
||||
0x0231,26,changehomunculusname,0
|
||||
0x0232,9,hommoveto,6
|
||||
0x0233,11,homattack,0
|
||||
0x0234,6,hommovetomaster,0
|
||||
0x0235,115 // Skills
|
||||
0x237,2,rankingpk,0
|
||||
0x23d,-1
|
||||
0x23e,4
|
||||
|
@ -376,7 +376,13 @@
|
||||
//-- AM_CP_HELM
|
||||
237,2000,0,0,120000:240000:360000:480000:600000,0
|
||||
//==========================================
|
||||
|
||||
//-- AM_CALLHOMUNCULUS
|
||||
243,2000,0,0,0,0
|
||||
//-- AM_REST
|
||||
244,2000,0,0,0,0
|
||||
//-- AM_RESURRECTHOMUN
|
||||
247,2000,0,0,0,0
|
||||
//==========================================
|
||||
|
||||
//===== Crusader ===========================
|
||||
//-- CR_AUTOGUARD
|
||||
@ -959,6 +965,30 @@
|
||||
1019,2000,1000,0,1800000,0
|
||||
//==========================================
|
||||
|
||||
//==========================================
|
||||
//-- HLIF_HEAL
|
||||
8001,0,1000,0,0,1000
|
||||
//-- HLIF_AVOID
|
||||
8002,0,0,0,40000:35000:30000:25000:20000,0
|
||||
//-- HLIF_CHANGE
|
||||
8004,0,0,0,60000:180000:300000,600000:900000:1200000
|
||||
//-- HAMI_DEFENCE
|
||||
8006,0,0,0,40000:35000:30000:25000:20000,30000
|
||||
//-- HAMI_BLOODLUST
|
||||
8008,0,0,0,60000:180000:300000,300000:600000:900000
|
||||
//-- HFLI_MOON
|
||||
8009,0,0,1000,0,0
|
||||
//-- HFLI_FLEET
|
||||
8010,0,0,0,60000:55000:50000:45000:40000,60000:70000:80000:90000:120000
|
||||
//-- HFLI_SPEED
|
||||
8011,0,0,0,60000:55000:50000:45000:40000,60000:70000:80000:90000:120000
|
||||
//-- HVAN_CAPRICE
|
||||
8013,700:1400:2100:2800:3500,0,1000:1200:1400:1600:1800,0,1000:1200:1400:1600:1800
|
||||
//-- HVAN_CHAOTIC
|
||||
8014,0,0,1000,0,1000
|
||||
//-- HVAN_EXPLOSION
|
||||
8016,0,0,1000,0,0
|
||||
//==========================================
|
||||
|
||||
//===== Guild Skills =======================
|
||||
//-- GD_LEADERSHIP
|
||||
|
@ -263,8 +263,8 @@
|
||||
//240,0,0,0,0,0,0,5,0,no,0,0,0,none,0 //AM_CREATECREATURE#Life Creation#
|
||||
//241,0,0,0,0,0,0,5,0,no,0,0,0,none,0 //AM_CULTIVATION#Cultivation#
|
||||
//242,0,0,0,0,0,0,5,0,no,0,0,0,none,0 //AM_FLAMECONTROL#Flame Control#
|
||||
243,0,6,4,0,1,0,1,0,no,0,0,0,none,0 //AM_CALLHOMUN#Call Homunculus#
|
||||
244,0,6,4,0,1,0,1,0,no,0,0,0,none,0 //AM_REST#Peaceful Rest#
|
||||
243,0,0,4,0,1,0,1,0,no,0,0,0,none,0 //AM_CALLHOMUN#Call Homunculus#
|
||||
244,0,0,4,0,1,0,1,0,no,0,0,0,none,0 //AM_REST#Peaceful Rest#
|
||||
//245,0,0,0,0,0,0,10,0,no,0,0,0,none,0 //AM_DRILLMASTER#Drillmaster#
|
||||
//246,9,0,0,0,0,0,10,0,no,0,0,0,none,0 //AM_HEALHOMUN#Heal Homunculus#
|
||||
247,9,6,4,0,1,0,5,0,no,0,0,0,none,0 //AM_RESURRECTHOMUN#Ressurect Homunculus#
|
||||
@ -587,6 +587,24 @@
|
||||
1018,9,6,1,3,1,0,1,1,yes,0,1,0,magic,0 //SA_ELEMENTFIRE#Elemental Change Fire#
|
||||
1019,9,6,1,4,1,0,1,1,yes,0,1,0,magic,0 //SA_ELEMENTWIND#Elemental Change Wind#
|
||||
|
||||
//homunculus
|
||||
8001,9,6,16,0,1,0,5,1,no,0,0,0,magic,0 //HLIF_HEAL#Healing hand#
|
||||
8002,0,6,4,0,3,-1,5,1,no,0,0,0,none,0 //HLIF_AVOID
|
||||
8003,0,0,0,0,0,1,5,0,no,0,0,0,none,0 //HLIF_BRAIN
|
||||
8004,0,6,4,0,1,0,3,0,no,0,0,0,none,0 //HLIF_CHANGE
|
||||
8005,0,6,4,0,1,0,5,0,no,0,0,0,none,0 //HAMI_CASTLE
|
||||
8006,0,6,4,0,1,0,5,0,no,0,0,0,none,0 //HAMI_DEFENCE
|
||||
8007,0,0,0,0,1,0,5,0,no,0,0,0,none,0 //HAMI_SKIN
|
||||
8008,0,6,4,0,1,0,3,0,no,0,0,0,none,0 //HAMI_BLOODLUST
|
||||
8009,1,8,1,0,0,0,5,1:2:2:2:3,no,0,0,0,weapon,0 //HFLI_MOON
|
||||
8010,0,6,4,0,1,0,5,0,no,0,0,0,none,0 //HFLI_FLEET
|
||||
8011,0,6,4,0,1,0,5,0,yes,0,0,0,misc,0 //HFLI_SPEED
|
||||
8012,1,6,1,0,0,0,3,0,no,0,0,0,none,0 //HFLI_SBR44
|
||||
8013,9,6,1,0,0,0,5,1:2:3:4:5,no,0,0,0,magic,0 //HVAN_CAPRICE
|
||||
8014,0,6,4,0,1,0,5,0,no,0,0,0,none,0 //HVAN_CHAOTIC
|
||||
8015,0,0,0,0,1,0,5,0,no,0,0,0,none,0 //HVAN_INSTRUCT
|
||||
8016,0,6,4,-1,2,2,3,1,no,0,0,0,misc,0 //HVAN_EXPLOSION
|
||||
|
||||
//id,range,hit,inf,pl,nk,splash,max,list_num,castcancel,cast_defence_rate,inf2,maxcount,skill_type,blow_count
|
||||
10000,0,0,0,0,0,0,1,0,no,0,16,0,none,0 //GD_APPROVAL#Approval#
|
||||
10001,0,0,0,0,0,0,1,0,no,0,16,0,none,0 //GD_KAFRACONTRACT#Kafra Contract#
|
||||
|
@ -172,6 +172,10 @@
|
||||
236,0,0,25,0,0,0,99,0,0,none,0,7139,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //AM_CP_ARMOR#ケミカルア?マ?チャ?ジ#
|
||||
237,0,0,25,0,0,0,99,0,0,none,0,7139,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //AM_CP_HELM#ケミカルヘルムチャ?ジ#
|
||||
|
||||
243,0,0,10,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 //AM_CALLHOMUNCULUS
|
||||
244,0,0,50,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 //AM_REST
|
||||
247,0,0,74:68:62:56:50,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 //AM_RESURRECTHOMUN
|
||||
|
||||
249,0,0,12:14:16:18:20:22:24:26:28:30,0,0,0,99,0,0,shield,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //CR_AUTOGUARD#オ?トガ?ド#
|
||||
250,0,0,10,0,0,0,99,0,0,shield,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //CR_SHIELDCHARGE#シ?ルドチャ?ジ#
|
||||
251,0,0,12,0,0,0,99,0,0,shield,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //CR_SHIELDBOOMERANG#シ?ルドブ?メラン#
|
||||
@ -456,17 +460,29 @@
|
||||
10013,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 //GD_EMERGENCYCALL##
|
||||
|
||||
//Current SP values for Homunculi devs
|
||||
//AM_HEALHOMUN 12#14#16#18#20#22#24#26#28#30#
|
||||
//AM_RESURRECTHOMUN 74#68#62#56#50#
|
||||
//HLIF_HEAL 13#16#19#22#25#
|
||||
8001,0,0,13:16:19:22:25,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 //HLIF_HEAL
|
||||
//HLIF_AVOID 20#25#30#35#40#
|
||||
8002,0,0,20:25:30:35: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 //HLIF_AVOID
|
||||
//HLIF_CHANGE 1#1#1#
|
||||
8004,0,1,0,0,0,99,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //HLIF_CHANGE
|
||||
//HAMI_CASTLE 10#10#10#10#10#
|
||||
8005,0,0,10,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 //HAMI_CASTLE
|
||||
//HAMI_DEFENCE 20#25#30#35#40#
|
||||
8006,0,0,20:25:30:35: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 //HAMI_DEFENCE
|
||||
//HAMI_BLOODLUST 120#120#120#
|
||||
8008,0,0,120,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 //HAMI_BLOODLUST
|
||||
//HFLI_MOON 4#8#12#16#20#
|
||||
8009,0,0,4:8:12:16: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 //HFLI_MOON
|
||||
//HFLI_FLEET 30#40#50#60#70#
|
||||
8010,0,0,30:40:50:60: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 //HFLI_FLEET
|
||||
//HFLI_SPEED 30#40#50#60#70#
|
||||
8011,0,0,30:40:50:60: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 //HFLI_SPEED
|
||||
//HFLI_SBR44 1#1#1#
|
||||
8012,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 //HFLI_SBR44
|
||||
//HVAN_CAPRICE 22#24#26#28#30#
|
||||
8013,0,0,22:24:26:28:30,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 //HVAN_CAPRICE
|
||||
//HVAN_CHAOTIC 40#40#40#40#40#
|
||||
8014,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 //HVAN_CHAOTIC
|
||||
//HVAN_EXPLOSION 1#1#1#
|
||||
8016,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 //HVAN_EXPLOSION
|
||||
|
@ -1,21 +0,0 @@
|
||||
-- Table for the Homunculus.
|
||||
-- [blackhole89]
|
||||
|
||||
CREATE TABLE `homunculus` (
|
||||
`id` int(11) NOT NULL auto_increment,
|
||||
`char_id` int(11) unsigned NOT NULL default '0',
|
||||
`class` mediumint(9) unsigned NOT NULL default '0',
|
||||
`name` varchar(24) NOT NULL default '',
|
||||
`level` smallint(4) NOT NULL default '0',
|
||||
`exp` int(12) NOT NULL default '0',
|
||||
`hunger` tinyint(10) NOT NULL default '0',
|
||||
`hp` int(12) NOT NULL default '1',
|
||||
`sp` int(12) NOT NULL default '1',
|
||||
`skill1lv` smallint(4) NOT NULL default '0',
|
||||
`skill2lv` smallint(4) NOT NULL default '0',
|
||||
`skill3lv` smallint(4) NOT NULL default '0',
|
||||
`skill4lv` smallint(4) NOT NULL default '0',
|
||||
`skillpts` int(11) unsigned NOT NULL default '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `char_id` (`char_id`)
|
||||
)
|
1124
sql-files/main.sql
1124
sql-files/main.sql
File diff suppressed because it is too large
Load Diff
36
sql-files/upgrade_svn7706.sql
Normal file
36
sql-files/upgrade_svn7706.sql
Normal file
@ -0,0 +1,36 @@
|
||||
ALTER TABLE `char` ADD `homun_id` int(11) unsigned NOT NULL default '0' AFTER `pet_id`;
|
||||
|
||||
DROP TABLE IF EXISTS `homunculus`;
|
||||
CREATE TABLE `homunculus` (
|
||||
`homun_id` int(11) NOT NULL auto_increment,
|
||||
`char_id` int(11) NOT NULL,
|
||||
`class` mediumint(9) unsigned NOT NULL default '0',
|
||||
`name` varchar(24) NOT NULL default '',
|
||||
`level` smallint(4) NOT NULL default '0',
|
||||
`exp` int(12) NOT NULL default '0',
|
||||
`intimacy` int(12) NOT NULL default '0',
|
||||
`hunger` smallint(4) 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',
|
||||
`hp` int(12) NOT NULL default '1',
|
||||
`max_hp` int(12) NOT NULL default '1',
|
||||
`sp` int(12) NOT NULL default '1',
|
||||
`max_sp` int(12) NOT NULL default '1',
|
||||
`skill_point` smallint(4) unsigned NOT NULL default '0',
|
||||
`alive` tinyint(2) NOT NULL default '1',
|
||||
`rename_flag` tinyint(2) NOT NULL default '0',
|
||||
`vaporize` tinyint(2) NOT NULL default '0',
|
||||
PRIMARY KEY (`homun_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
|
||||
CREATE TABLE `skill_homunculus` (
|
||||
`homun_id` int(11) NOT NULL,
|
||||
`id` int(11) NOT NULL,
|
||||
`lv` smallint(6) NOT NULL,
|
||||
PRIMARY KEY (`homun_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
@ -10,7 +10,7 @@ COMMON_H = ../common/core.h ../common/socket.h ../common/timer.h ../common/mmo.h
|
||||
../common/malloc.h ../common/showmsg.h ../common/utils.h ../common/strlib.h \
|
||||
../common/graph.h ../common/grfio.h ../common/mapindex.h
|
||||
|
||||
char-server_sql: char.o inter.o int_party.o int_guild.o int_storage.o int_pet.o itemdb.o $(COMMON_OBJ)
|
||||
char-server_sql: char.o inter.o int_party.o int_guild.o int_storage.o int_pet.o int_homun.o itemdb.o $(COMMON_OBJ)
|
||||
$(CC) -o ../../$@ $^ $(LIB_S)
|
||||
|
||||
clean:
|
||||
@ -19,9 +19,10 @@ clean:
|
||||
# DO NOT DELETE
|
||||
|
||||
char.o: char.c char.h ../common/strlib.h itemdb.h ../common/showmsg.h
|
||||
inter.o: inter.c inter.h int_party.h int_guild.h int_storage.h int_pet.h ../common/mmo.h char.h ../common/socket.h ../common/showmsg.h
|
||||
inter.o: inter.c inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h ../common/mmo.h char.h ../common/socket.h ../common/showmsg.h
|
||||
int_party.o: int_party.c int_party.h inter.h ../common/mmo.h char.h ../common/socket.h ../common/timer.h ../common/db.h ../common/showmsg.h
|
||||
int_guild.o: int_guild.c int_guild.h inter.h ../common/mmo.h char.h ../common/socket.h ../common/db.h ../common/showmsg.h
|
||||
int_storage.o: int_storage.c int_storage.h char.h itemdb.h ../common/showmsg.h
|
||||
int_pet.o: int_pet.c int_pet.h inter.h char.h ../common/mmo.h ../common/socket.h ../common/db.h ../common/showmsg.h
|
||||
itemdb.o: itemdb.c itemdb.h ../common/db.h ../common/mmo.h ../common/showmsg.h
|
||||
int_homun.o: int_homun.c int_homun.h inter.h char.h ../common/mmo.h ../common/socket.h ../common/db.h ../common/showmsg.h
|
||||
itemdb.o: itemdb.c itemdb.h ../common/db.h ../common/mmo.h ../common/showmsg.h
|
@ -491,7 +491,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',"
|
||||
"`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d'," //[orn] add homun_id (homunculus id)
|
||||
"`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'"
|
||||
" WHERE `account_id`='%d' AND `char_id` = '%d'",
|
||||
@ -499,7 +499,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->option, p->party_id, p->guild_id, p->pet_id, p->hom_id, //[orn] add homun_id (homunculus 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,
|
||||
@ -956,7 +956,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p){
|
||||
|
||||
sprintf(tmp_sql, "SELECT `option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_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`"
|
||||
"`last_map`,`last_x`,`last_y`,`save_map`,`save_x`,`save_y`, `partner_id`, `father`, `mother`, `child`, `fame`, `homun_id`" //[orn] homun_id
|
||||
"FROM `%s` WHERE `char_id` = '%d'",char_db, char_id); // TBR
|
||||
if (mysql_query(&mysql_handle, tmp_sql)) {
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
@ -977,6 +977,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus *p){
|
||||
p->save_point.map = mapindex_name2id(sql_row[17]); p->save_point.x = atoi(sql_row[18]); p->save_point.y = atoi(sql_row[19]);
|
||||
p->partner_id = atoi(sql_row[20]); p->father = atoi(sql_row[21]); p->mother = atoi(sql_row[22]); p->child = atoi(sql_row[23]);
|
||||
p->fame = atoi(sql_row[24]);
|
||||
p->hom_id = atoi(sql_row[25]); //[orn] homunculus id
|
||||
|
||||
strcat (t_msg, " status2");
|
||||
} else
|
||||
@ -3036,7 +3037,7 @@ int parse_frommap(int fd) {
|
||||
}
|
||||
|
||||
// no inter server packet. no char server packet -> disconnect
|
||||
ShowError("Unknown packet 0x%04x from map server, disconnecting.\n", RFIFOW(fd,0));
|
||||
ShowError("Unknown packet 0x%04x ( %s ) from map server, disconnecting.\n", RFIFOW(fd,0), (char*)RFIFOP(fd,0));
|
||||
session[fd]->eof = 1;
|
||||
return 0;
|
||||
}
|
||||
|
300
src/char_sql/int_homun.c
Normal file
300
src/char_sql/int_homun.c
Normal file
@ -0,0 +1,300 @@
|
||||
// Homunculus saving by Albator and Orn for eAthena.
|
||||
// GNU/GPL rulez !
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "char.h"
|
||||
#include "../common/strlib.h"
|
||||
#include "../common/showmsg.h"
|
||||
|
||||
struct s_homunculus *homun_pt;
|
||||
|
||||
#ifndef SQL_DEBUG
|
||||
|
||||
#define mysql_query(_x, _y) mysql_real_query(_x, _y, strlen(_y)) //supports ' in names and runs faster [Kevin]
|
||||
|
||||
#else
|
||||
|
||||
#define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int inter_homunculus_sql_init(void){
|
||||
//memory alloc
|
||||
homun_pt = (struct s_homunculus*)aCalloc(sizeof(struct s_homunculus), 1);
|
||||
return 0;
|
||||
}
|
||||
void inter_homunculus_sql_final(void){
|
||||
if (homun_pt) aFree(homun_pt);
|
||||
return;
|
||||
}
|
||||
|
||||
int mapif_saved_homunculus(int fd, short flag)
|
||||
{
|
||||
WFIFOW(fd,0) = 0x3892;
|
||||
if(flag==1)
|
||||
WFIFOB(fd,2) = 1;
|
||||
else
|
||||
WFIFOB(fd,2) = 0;
|
||||
WFIFOSET(fd, 3);
|
||||
return 0;
|
||||
}
|
||||
int mapif_info_homunculus(int fd, int account_id, struct s_homunculus *hd)
|
||||
{
|
||||
WFIFOW(fd,0) = 0x3891;
|
||||
WFIFOW(fd,2) = sizeof(struct s_homunculus)+9;
|
||||
WFIFOL(fd,4) = account_id;
|
||||
WFIFOB(fd,8) = 1; // account loaded with success
|
||||
|
||||
memcpy(WFIFOP(fd,9), hd, sizeof(struct s_homunculus));
|
||||
WFIFOSET(fd, sizeof(struct s_homunculus)+9);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mapif_homunculus_deleted(int fd, int flag)
|
||||
{
|
||||
WFIFOW(fd, 0) = 0x3893;
|
||||
if(flag == 1)
|
||||
WFIFOB(fd,2) = 1; // Homunculus deleted
|
||||
else
|
||||
WFIFOB(fd,2) = 0; /* Fail /!\ */
|
||||
|
||||
WFIFOSET(fd, 3);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
int mapif_homunculus_created(int fd, int account_id, struct s_homunculus *sh, short flag)
|
||||
{
|
||||
WFIFOW(fd, 0) =0x3890;
|
||||
WFIFOL(fd,2) = account_id;
|
||||
WFIFOL(fd,6) = sh->char_id;
|
||||
if(flag==1){
|
||||
WFIFOW(fd, 10)=1;
|
||||
WFIFOL(fd,12) = sh->hom_id;
|
||||
}
|
||||
else{
|
||||
WFIFOW(fd, 10)=0;
|
||||
WFIFOL(fd,12) = 0;
|
||||
}
|
||||
WFIFOSET(fd, 16);
|
||||
|
||||
return 0;
|
||||
}
|
||||
void init_homun_skills(struct s_homunculus *hd)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<MAX_HOMUNSKILL;i++)
|
||||
hd->hskill[i].id = hd->hskill[i].lv = hd->hskill[i].flag = 0;
|
||||
}
|
||||
|
||||
// Save/Update Homunculus Skills
|
||||
int mapif_save_homunculus_skills(struct s_homunculus *hd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAX_HOMUNSKILL; i++)
|
||||
{
|
||||
if(hd->hskill[i].id != 0 && hd->hskill[i].lv != 0 )
|
||||
{
|
||||
sprintf(tmp_sql,"REPLACE INTO `skill_homunculus` (`homun_id`, `id`, `lv`) VALUES (%d, %d, %d)",
|
||||
hd->hom_id, hd->hskill[i].id, hd->hskill[i].lv);
|
||||
|
||||
if(mysql_query(&mysql_handle, tmp_sql)){
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int mapif_save_homunculus(int fd, int account_id, struct s_homunculus *hd)
|
||||
{
|
||||
int flag =1;
|
||||
|
||||
if(hd->hom_id==0) // new homunculus
|
||||
{
|
||||
ShowInfo("New homunculus name : %s\n",hd->name);
|
||||
|
||||
sprintf(tmp_sql, "INSERT INTO `homunculus` "
|
||||
"(`char_id`, `class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `alive`, `rename_flag`, `vaporize`) "
|
||||
"VALUES ('%d', '%d', '%s', '%d', '%lu', '%lu', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')",
|
||||
hd->char_id, hd->class_,hd->name,hd->level,hd->exp,hd->intimacy,hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
|
||||
hd->hp,hd->max_hp,hd->sp,hd->max_sp, hd->skillpts, hd->alive, hd->rename_flag, hd->vaporize);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(tmp_sql, "UPDATE `homunculus` SET `char_id`='%d', `class`='%d',`name`='%s',`level`='%d',`exp`='%lu',`intimacy`='%lu',`hunger`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `alive`='%d', `rename_flag`='%d', `vaporize`='%d', `str`='%d' WHERE `homun_id`='%d'",
|
||||
hd->char_id, hd->class_,hd->name,hd->level,hd->exp,hd->intimacy,hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
|
||||
hd->hp,hd->max_hp,hd->sp,hd->max_sp, hd->skillpts, hd->alive, hd->rename_flag, hd->vaporize);
|
||||
}
|
||||
|
||||
if(mysql_query(&mysql_handle, tmp_sql)){
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
if(hd->hom_id==0 && flag!=0)
|
||||
hd->hom_id = (int)mysql_insert_id(&mysql_handle); // new homunculus
|
||||
else
|
||||
{
|
||||
flag = mapif_save_homunculus_skills(hd);
|
||||
mapif_saved_homunculus(fd, flag);
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Load an homunculus
|
||||
int mapif_load_homunculus(int fd){
|
||||
int i;
|
||||
memset(homun_pt, 0, sizeof(struct s_homunculus));
|
||||
|
||||
sprintf(tmp_sql,"SELECT `homun_id`,`char_id`,`class`,`name`,`level`,`exp`,`intimacy`,`hunger`,, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`alive`,`rename_flag`, `vaporize` FROM `homunculus` WHERE `homun_id`='%lu'", RFIFOL(fd,6));
|
||||
if(mysql_query(&mysql_handle, tmp_sql) ) {
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
|
||||
|
||||
return 0;
|
||||
}
|
||||
sql_res = mysql_store_result(&mysql_handle) ;
|
||||
if (sql_res!=NULL && mysql_num_rows(sql_res)>0) {
|
||||
sql_row = mysql_fetch_row(sql_res);
|
||||
|
||||
homun_pt->hom_id = RFIFOL(fd,6) ; //RFIFOL(fd,2);
|
||||
homun_pt->class_ = atoi(sql_row[2]);
|
||||
memcpy(homun_pt->name, sql_row[3],NAME_LENGTH-1);
|
||||
homun_pt->char_id = atoi(sql_row[1]);
|
||||
homun_pt->level = atoi(sql_row[4]);
|
||||
homun_pt->exp = atoi(sql_row[5]);
|
||||
homun_pt->intimacy = atoi(sql_row[6]);
|
||||
homun_pt->hunger = atoi(sql_row[7]);
|
||||
homun_pt->str = atoi(sql_row[8]);
|
||||
homun_pt->agi = atoi(sql_row[9]);
|
||||
homun_pt->vit = atoi(sql_row[10]);
|
||||
homun_pt->int_ = atoi(sql_row[11]);
|
||||
homun_pt->dex = atoi(sql_row[12]);
|
||||
homun_pt->luk = atoi(sql_row[13]);
|
||||
homun_pt->hp = atoi(sql_row[14]);
|
||||
homun_pt->max_hp = atoi(sql_row[15]);
|
||||
homun_pt->sp = atoi(sql_row[16]);
|
||||
homun_pt->max_sp = atoi(sql_row[17]);
|
||||
homun_pt->skillpts = atoi(sql_row[18]);
|
||||
homun_pt->alive = atoi(sql_row[19]);
|
||||
homun_pt->rename_flag = atoi(sql_row[20]);
|
||||
homun_pt->vaporize = atoi(sql_row[21]);
|
||||
}
|
||||
if(homun_pt->hunger < 0)
|
||||
homun_pt->hunger = 0;
|
||||
else if(homun_pt->hunger > 100)
|
||||
homun_pt->hunger = 100;
|
||||
if(homun_pt->intimacy < 0)
|
||||
homun_pt->intimacy = 0;
|
||||
else if(homun_pt->intimacy > 100000)
|
||||
homun_pt->intimacy = 100000;
|
||||
|
||||
mysql_free_result(sql_res);
|
||||
|
||||
// Load Homunculus Skill
|
||||
init_homun_skills(homun_pt); //bousille homun_pt !!!
|
||||
|
||||
sprintf(tmp_sql,"SELECT `id`,`lv` FROM `skill_homunculus` WHERE `homun_id`=%d",homun_pt->hom_id);
|
||||
if(mysql_query(&mysql_handle, tmp_sql) ) {
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
|
||||
return 0;
|
||||
}
|
||||
sql_res = mysql_store_result(&mysql_handle);
|
||||
if(sql_res){
|
||||
while((sql_row = mysql_fetch_row(sql_res))){
|
||||
i = (atoi(sql_row[0])-HM_SKILLBASE-1);
|
||||
homun_pt->hskill[i].id = atoi(sql_row[0]);
|
||||
homun_pt->hskill[i].lv = atoi(sql_row[1]);
|
||||
}
|
||||
}
|
||||
|
||||
mysql_free_result(sql_res);
|
||||
|
||||
ShowInfo("Homunculus loaded (%d - %s).\n", homun_pt->hom_id, homun_pt->name);
|
||||
return mapif_info_homunculus(fd, RFIFOL(fd,2), homun_pt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int mapif_delete_homunculus(int fd)
|
||||
{
|
||||
sprintf(tmp_sql, "DELETE FROM `homunculus` WHERE `homun_id` = '%lu'", RFIFOL(fd,2));
|
||||
if(mysql_query(&mysql_handle, tmp_sql)){
|
||||
ShowSQL("DB error - %s\n",mysql_error(&mysql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
|
||||
return mapif_homunculus_deleted(fd, 0);
|
||||
}
|
||||
|
||||
return mapif_homunculus_deleted(fd, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int mapif_parse_CreateHomunculus(int fd)
|
||||
{
|
||||
memset(homun_pt, 0, sizeof(struct s_homunculus));
|
||||
|
||||
/* Data from packet */
|
||||
homun_pt->char_id = RFIFOL(fd,6);
|
||||
homun_pt->class_ = RFIFOW(fd,10);
|
||||
homun_pt->max_hp = RFIFOL(fd,12);
|
||||
homun_pt->max_sp = RFIFOL(fd,16);
|
||||
memcpy(homun_pt->name, (char*)RFIFOP(fd, 20), NAME_LENGTH-1);
|
||||
homun_pt->str = RFIFOL(fd,44);
|
||||
homun_pt->agi = RFIFOL(fd,48);
|
||||
homun_pt->vit = RFIFOL(fd,52);
|
||||
homun_pt->int_ = RFIFOL(fd,56);
|
||||
homun_pt->dex = RFIFOL(fd,60);
|
||||
homun_pt->luk = RFIFOL(fd,64);
|
||||
|
||||
/* Const data for each creation*/
|
||||
homun_pt->hom_id = 0;
|
||||
homun_pt->exp =0;
|
||||
homun_pt->hp = 10 ;
|
||||
homun_pt->sp = 0 ;
|
||||
homun_pt->rename_flag = 0;
|
||||
homun_pt->skillpts =0;
|
||||
homun_pt->hunger = 32;
|
||||
homun_pt->level=1;
|
||||
homun_pt->intimacy = 21;
|
||||
|
||||
// Save in sql db
|
||||
if(mapif_save_homunculus(fd,RFIFOL(fd,2), homun_pt))
|
||||
return mapif_homunculus_created(fd, RFIFOL(fd,2), homun_pt, 1); // send homun_id
|
||||
else
|
||||
return mapif_homunculus_created(fd, RFIFOL(fd,2), homun_pt, 0); // fail
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int inter_homunculus_parse_frommap(int fd){
|
||||
switch(RFIFOW(fd, 0)){
|
||||
case 0x3090: mapif_parse_CreateHomunculus(fd); break;
|
||||
case 0x3091: mapif_load_homunculus(fd); break;
|
||||
case 0x3092: mapif_save_homunculus(fd, RFIFOL(fd,6), (struct s_homunculus*) RFIFOP(fd, 10)); break;
|
||||
case 0x3093: mapif_delete_homunculus(fd); break; // doesn't need to be parse, very simple packet...
|
||||
// rename homunculus is just like save... Map server check the rename flag before, send the save packet
|
||||
// case 0x3094: mapif_parse_rename_homunculus(fd); break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
14
src/char_sql/int_homun.h
Normal file
14
src/char_sql/int_homun.h
Normal file
@ -0,0 +1,14 @@
|
||||
// Homunculus saving by Albator and Orn for eAthena.
|
||||
// GNU/GPL rulez !
|
||||
|
||||
#ifndef _INT_HOMUN_H_
|
||||
#define _INT_HOMUN_H_
|
||||
|
||||
int inter_homunculus_sql_init(void);
|
||||
void inter_homunculus_sql_final(void);
|
||||
int mapif_save_homunculus(struct s_homunculus *hd);
|
||||
int mapif_load_homunculus(int fd);
|
||||
int mapif_delete_homunculus(int fd);
|
||||
int inter_homunculus_parse_frommap(int fd);
|
||||
|
||||
#endif
|
@ -15,6 +15,7 @@
|
||||
#include "int_guild.h"
|
||||
#include "int_storage.h"
|
||||
#include "int_pet.h"
|
||||
#include "int_homun.h" //albator
|
||||
|
||||
#define WISDATA_TTL (60*1000) // Wisデータの生存時間(60秒)
|
||||
#define WISDELLIST_MAX 256 // Wisデータ削除リストの要素数
|
||||
@ -79,6 +80,10 @@ int inter_recv_packet_length[]={
|
||||
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,
|
||||
48,14,-1, 6, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3080-0x308f
|
||||
// 44,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3090 - 0x309f Homunculus packets [albator]
|
||||
68,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3090 - 0x309f Homunculus packets [albator]
|
||||
|
||||
|
||||
};
|
||||
|
||||
struct WisData {
|
||||
@ -362,6 +367,7 @@ int inter_init(const char *file)
|
||||
inter_party_sql_init();
|
||||
|
||||
inter_pet_sql_init();
|
||||
inter_homunculus_sql_init(); // albator
|
||||
inter_accreg_sql_init();
|
||||
|
||||
//printf ("interserver timer initializing : %d sec...\n",autosave_interval);
|
||||
@ -419,6 +425,7 @@ void inter_final(void) {
|
||||
inter_storage_sql_final();
|
||||
inter_party_sql_final();
|
||||
inter_pet_sql_final();
|
||||
inter_homunculus_sql_final(); //[orn]
|
||||
|
||||
if (accreg_pt) aFree(accreg_pt);
|
||||
return;
|
||||
@ -753,7 +760,7 @@ int inter_parse_frommap(int fd)
|
||||
int cmd=RFIFOW(fd,0);
|
||||
int len=0;
|
||||
|
||||
// inter鯖管轄かを調べる
|
||||
// interŽIŠÇŠ<EFBFBD>‚©‚𒲂ׂ
|
||||
if(cmd < 0x3000 || cmd >= 0x3000 + (sizeof(inter_recv_packet_length)/
|
||||
sizeof(inter_recv_packet_length[0]) ) )
|
||||
return 0;
|
||||
@ -781,6 +788,8 @@ int inter_parse_frommap(int fd)
|
||||
break;
|
||||
if(inter_pet_parse_frommap(fd))
|
||||
break;
|
||||
if(inter_homunculus_parse_frommap(fd)) //albator
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,11 @@
|
||||
|
||||
#define CHAR_CONF_NAME "conf/char_athena.conf"
|
||||
|
||||
//Base Homun skill.
|
||||
#define HM_SKILLBASE 8000
|
||||
#define MAX_HOMUNSKILL 16
|
||||
#define MAX_HOMUNCULUS_CLASS 16 //[orn]
|
||||
|
||||
struct item {
|
||||
int id;
|
||||
short nameid;
|
||||
@ -163,6 +168,29 @@ struct s_pet {
|
||||
char incuvate;
|
||||
};
|
||||
|
||||
struct s_homunculus { //[orn]
|
||||
char name[NAME_LENGTH];
|
||||
int hom_id;
|
||||
int char_id;
|
||||
short class_;
|
||||
int hp,max_hp,sp,max_sp;
|
||||
short alive; //albator
|
||||
unsigned long intimacy; //[orn]
|
||||
short hunger;
|
||||
struct skill hskill[MAX_HOMUNSKILL]; //albator
|
||||
short skillpts;
|
||||
short level;
|
||||
unsigned long exp;
|
||||
short rename_flag;
|
||||
short vaporize; //albator
|
||||
int str ;
|
||||
int agi ;
|
||||
int vit ;
|
||||
int int_ ;
|
||||
int dex ;
|
||||
int luk ;
|
||||
};
|
||||
|
||||
struct friend {
|
||||
int account_id;
|
||||
int char_id;
|
||||
@ -188,6 +216,7 @@ struct mmo_charstatus {
|
||||
unsigned char karma;
|
||||
short hair,hair_color,clothes_color;
|
||||
int party_id,guild_id,pet_id;
|
||||
int hom_id; //[orn]
|
||||
int fame;
|
||||
|
||||
short weapon,shield;
|
||||
@ -385,9 +414,6 @@ enum {
|
||||
GD_DEVELOPMENT=10014,
|
||||
};
|
||||
|
||||
//Base Homun skill.
|
||||
#define HM_SKILLBASE 8001
|
||||
#define MAX_HOMUNSKILL 16
|
||||
|
||||
//These mark the ID of the jobs, as expected by the client. [Skotlex]
|
||||
enum {
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "skill.h"
|
||||
#include "mob.h"
|
||||
#include "pet.h"
|
||||
#include "mercenary.h" //[orn]
|
||||
#include "battle.h"
|
||||
#include "party.h"
|
||||
#include "guild.h"
|
||||
@ -298,6 +299,13 @@ ACMD_FUNC(commands); // [Skotlex]
|
||||
ACMD_FUNC(noask); //LuzZza
|
||||
ACMD_FUNC(request); //[Skotlex]
|
||||
|
||||
ACMD_FUNC(homlevel); //[orn]
|
||||
ACMD_FUNC(homevolution); //[orn]
|
||||
ACMD_FUNC(makehomun); //[orn]
|
||||
ACMD_FUNC(homfriendly); //[orn]
|
||||
ACMD_FUNC(homhungry); //[orn]
|
||||
ACMD_FUNC(homtalk); //[orn]
|
||||
|
||||
/*==========================================
|
||||
*AtCommandInfo atcommand_info[]<EFBFBD>\‘¢‘̂̒è‹`
|
||||
*------------------------------------------
|
||||
@ -616,6 +624,13 @@ static AtCommandInfo atcommand_info[] = {
|
||||
{ AtCommand_NoAsk, "@noask", 1, atcommand_noask }, // [LuzZza]
|
||||
{ AtCommand_Request, "@request", 20, atcommand_request }, // [Skotlex]
|
||||
|
||||
{ AtCommand_HomLevel, "@homlvup", 60, atcommand_homlevel },
|
||||
{ AtCommand_HomEvolution, "@homevolution", 60, atcommand_homevolution },
|
||||
{ AtCommand_MakeHomun, "@makehomun", 60, atcommand_makehomun },
|
||||
{ AtCommand_HomFriendly, "@homfriendly", 60, atcommand_homfriendly },
|
||||
{ AtCommand_HomHungry, "@homhungry", 60, atcommand_homhungry },
|
||||
{ AtCommand_HomTalk, "@homtalk", 0, atcommand_homtalk },
|
||||
|
||||
// add new commands before this line
|
||||
{ AtCommand_Unknown, NULL, 1, NULL }
|
||||
};
|
||||
@ -9425,6 +9440,160 @@ int atcommand_mobinfo(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* homunculus level up [orn]
|
||||
*------------------------------------------
|
||||
*/
|
||||
int atcommand_homlevel(
|
||||
const int fd, struct map_session_data* sd,
|
||||
const char* command, const char* message)
|
||||
{
|
||||
int level = 0, i = 0;
|
||||
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
if (!message || !*message)
|
||||
return -1;
|
||||
|
||||
if ( sd->status.hom_id == 0 || !sd->homunculus.alive || sd->homunculus.vaporize )
|
||||
return 1 ;
|
||||
|
||||
level = atoi(message);
|
||||
if ( ( level + sd->homunculus.level ) > MAX_LEVEL )
|
||||
level = MAX_LEVEL - sd->homunculus.level ;
|
||||
if (level >= 1) {
|
||||
for (i = 1; i <= level ; i++){
|
||||
merc_hom_levelup(sd->hd) ;
|
||||
}
|
||||
clif_misceffect2(&sd->hd->bl,568) ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* homunculus evolution H [orn]
|
||||
*------------------------------------------
|
||||
*/
|
||||
int atcommand_homevolution(
|
||||
const int fd, struct map_session_data* sd,
|
||||
const char* command, const char* message)
|
||||
{
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
if (sd->hd && sd->hd->homunculusDB->evo_class)
|
||||
{
|
||||
merc_hom_evolution(sd->hd) ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* call choosen homunculus [orn]
|
||||
*------------------------------------------
|
||||
*/
|
||||
int
|
||||
atcommand_makehomun(
|
||||
const int fd, struct map_session_data* sd,
|
||||
const char* command, const char* message)
|
||||
{
|
||||
int homunid;
|
||||
nullpo_retr(-1, sd);
|
||||
if(sscanf(message, "%d", &homunid)<1)
|
||||
return -1;
|
||||
if( homunid < 6001 || homunid > 6016 )
|
||||
return -1;
|
||||
if(sd->status.hom_id == 0)
|
||||
{
|
||||
merc_create_homunculus(sd,homunid);
|
||||
}
|
||||
else
|
||||
{
|
||||
clif_displaymessage(fd,msg_txt(144));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* modify homunculus intimacy [orn]
|
||||
*------------------------------------------
|
||||
*/
|
||||
int atcommand_homfriendly(
|
||||
const int fd, struct map_session_data* sd,
|
||||
const char* command, const char* message)
|
||||
{
|
||||
int friendly = 0;
|
||||
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
if (!message || !*message)
|
||||
return -1;
|
||||
|
||||
friendly = atoi(message);
|
||||
if (sd->status.hom_id > 0 && sd->hd) {
|
||||
if (friendly > 0 && friendly <= 1000) {
|
||||
sd->homunculus.intimacy = friendly * 100 ;
|
||||
clif_send_homdata(sd,SP_INTIMATE,friendly);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* modify homunculus hunger [orn]
|
||||
*------------------------------------------
|
||||
*/
|
||||
int atcommand_homhungry(
|
||||
const int fd, struct map_session_data* sd,
|
||||
const char* command, const char* message)
|
||||
{
|
||||
int hungry = 0;
|
||||
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
if (!message || !*message)
|
||||
return -1;
|
||||
|
||||
hungry = atoi(message);
|
||||
if (sd->status.hom_id > 0 && sd->hd) {
|
||||
if (hungry >= 0 && hungry <= 100) {
|
||||
sd->homunculus.hunger = hungry;
|
||||
clif_send_homdata(sd,SP_HUNGRY,sd->homunculus.hunger);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* modify homunculus hunger [orn]
|
||||
*------------------------------------------
|
||||
*/
|
||||
int atcommand_homtalk(
|
||||
const int fd, struct map_session_data* sd,
|
||||
const char* command, const char* message)
|
||||
{
|
||||
char mes[100],temp[100];
|
||||
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
if(!sd->status.hom_id || !sd->hd || !sd->homunculus.alive )
|
||||
return -1;
|
||||
|
||||
if (sscanf(message, "%99[^\n]", mes) < 1)
|
||||
return -1;
|
||||
|
||||
snprintf(temp, sizeof temp ,"%s : %s",sd->homunculus.name,mes);
|
||||
clif_message(&sd->hd->bl, temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Show Items DB Info v 1.0
|
||||
* originally by [Lupus] eAthena
|
||||
|
@ -271,6 +271,12 @@ enum AtCommandType {
|
||||
AtCommand_Commands, // [Skotlex]
|
||||
AtCommand_NoAsk, // [LuzZza]
|
||||
AtCommand_Request, // [Skotlex], supposedly taken from Freya (heard the command was there, but I haven't seen the code yet)
|
||||
AtCommand_HomLevel, //[orn]
|
||||
AtCommand_HomEvolution, //[orn]
|
||||
AtCommand_MakeHomun, //[orn]
|
||||
AtCommand_HomFriendly, //[orn]
|
||||
AtCommand_HomHungry, //[orn]
|
||||
AtCommand_HomTalk, //[orn]
|
||||
// end <- Ahem, guys, don't place AtCommands after AtCommand_Unknown! [Skotlex]
|
||||
AtCommand_Unknown,
|
||||
AtCommand_MAX
|
||||
|
@ -761,6 +761,7 @@ static struct Damage battle_calc_weapon_attack(
|
||||
short i;
|
||||
|
||||
struct map_session_data *sd, *tsd;
|
||||
struct homun_data *hd; //[orn]
|
||||
struct Damage wd;
|
||||
struct status_change *sc = status_get_sc(src);
|
||||
struct status_change *tsc = status_get_sc(target);
|
||||
@ -813,6 +814,7 @@ static struct Damage battle_calc_weapon_attack(
|
||||
|
||||
BL_CAST(BL_PC, src, sd);
|
||||
BL_CAST(BL_PC, target, tsd);
|
||||
BL_CAST(BL_HOMUNCULUS, src, hd); //[orn]
|
||||
|
||||
if(sd) {
|
||||
if (sd->skillblown[0].id != 0)
|
||||
@ -1029,6 +1031,7 @@ static struct Damage battle_calc_weapon_attack(
|
||||
case NPC_MENTALBREAKER:
|
||||
case GS_GROUNDDRIFT:
|
||||
case NJ_TATAMIGAESHI:
|
||||
case HVAN_EXPLOSION: //[orn]
|
||||
flag.hit = 1;
|
||||
break;
|
||||
case CR_SHIELDBOOMERANG:
|
||||
@ -1177,6 +1180,14 @@ static struct Damage battle_calc_weapon_attack(
|
||||
ATK_ADD(sd->inventory_data[index]->weight/10);
|
||||
break;
|
||||
}
|
||||
case HFLI_SBR44: //[orn]
|
||||
if(hd){
|
||||
wd.damage = hd->master->homunculus.intimacy ;
|
||||
wd.damage2 = hd->master->homunculus.intimacy ;
|
||||
hd->master->homunculus.intimacy = 200;
|
||||
clif_send_homdata(hd->master,0x100,hd->master->homunculus.intimacy/100);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
i = (flag.cri?1:0)|(flag.arrow?2:0)|(skill_num == HW_MAGICCRASHER?4:0)|(skill_num == MO_EXTREMITYFIST?8:0);
|
||||
@ -1499,6 +1510,12 @@ static struct Damage battle_calc_weapon_attack(
|
||||
case MO_BALKYOUNG:
|
||||
skillratio += 200;
|
||||
break;
|
||||
case HFLI_MOON: //[orn]
|
||||
skillratio += ( 110 * (skill_lv + 1) ) - 100 ;
|
||||
skillratio /= wd.div_ ;
|
||||
break;
|
||||
case HFLI_SBR44: //[orn]
|
||||
skillratio += 100 * skill_lv ;
|
||||
}
|
||||
|
||||
ATK_RATE(skillratio);
|
||||
@ -2468,6 +2485,7 @@ struct Damage battle_calc_misc_attack(
|
||||
case CR_ACIDDEMONSTRATION:
|
||||
md.flag = (md.flag&~BF_RANGEMASK)|BF_LONG;
|
||||
break;
|
||||
case HVAN_EXPLOSION: //[orn]
|
||||
case NPC_SELFDESTRUCTION:
|
||||
case NPC_SMOKING:
|
||||
flag.elefix = flag.cardfix = 0;
|
||||
@ -2553,6 +2571,9 @@ struct Damage battle_calc_misc_attack(
|
||||
case GS_FLING:
|
||||
md.damage = sd?sd->status.job_level:status_get_lv(src);
|
||||
break;
|
||||
case HVAN_EXPLOSION: //[orn]
|
||||
md.damage = sstatus->hp * (50 + 50 * skill_lv) / 100 ;
|
||||
break ;
|
||||
}
|
||||
|
||||
damage_div_fix(md.damage, md.div_);
|
||||
@ -3619,6 +3640,7 @@ static const struct battle_data_short {
|
||||
{ "autospell_stacking", &battle_config.autospell_stacking },
|
||||
{ "override_mob_names", &battle_config.override_mob_names },
|
||||
{ "min_chat_delay", &battle_config.min_chat_delay },
|
||||
{ "homunculus_show_growth", &battle_config.homunculus_show_growth }, //[orn]
|
||||
};
|
||||
|
||||
static const struct battle_data_int {
|
||||
@ -3662,7 +3684,7 @@ static const struct battle_data_int {
|
||||
{ "max_heal", &battle_config.max_heal },
|
||||
{ "mob_remove_delay", &battle_config.mob_remove_delay },
|
||||
{ "sg_miracle_skill_duration", &battle_config.sg_miracle_skill_duration },
|
||||
|
||||
{ "hvan_explosion_intimate", &battle_config.hvan_explosion_intimate }, //[orn]
|
||||
};
|
||||
|
||||
int battle_set_value(char *w1, char *w2) {
|
||||
@ -4045,6 +4067,8 @@ void battle_set_defaults() {
|
||||
battle_config.autospell_stacking = 0;
|
||||
battle_config.override_mob_names = 0;
|
||||
battle_config.min_chat_delay = 0;
|
||||
battle_config.hvan_explosion_intimate = 45000; //[orn]
|
||||
battle_config.homunculus_show_growth = 0; //[orn]
|
||||
}
|
||||
|
||||
void battle_validate_conf() {
|
||||
@ -4257,6 +4281,9 @@ void battle_validate_conf() {
|
||||
if (battle_config.cell_stack_limit != 1)
|
||||
ShowWarning("Battle setting 'cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n");
|
||||
#endif
|
||||
|
||||
if(battle_config.hvan_explosion_intimate > 100000) //[orn]
|
||||
battle_config.hvan_explosion_intimate = 100000;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
|
@ -436,6 +436,8 @@ extern struct Battle_Config {
|
||||
unsigned short autospell_stacking; //Enables autospell cards to stack. [Skotlex]
|
||||
unsigned short override_mob_names; //Enables overriding spawn mob names with the mob_db names. [Skotlex]
|
||||
unsigned short min_chat_delay; //Minimum time between client messages. [Skotlex]
|
||||
unsigned int hvan_explosion_intimate ; // fix [albator]
|
||||
unsigned short homunculus_show_growth ; //[orn]
|
||||
|
||||
} battle_config;
|
||||
|
||||
|
@ -26,6 +26,7 @@ struct mmo_charstatus *charsave_loadchar(int charid){
|
||||
char *str_p;
|
||||
friends = 0;
|
||||
|
||||
ShowDebug("charsave_loadchar : charid = %d | hd->master->status.char_id = %d\n", charid) ;
|
||||
c = (struct mmo_charstatus *)aCalloc(1,sizeof(struct mmo_charstatus));
|
||||
|
||||
if(charid <= 0){
|
||||
@ -33,9 +34,9 @@ struct mmo_charstatus *charsave_loadchar(int charid){
|
||||
aFree(c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// add homun_id [albator]
|
||||
//Tested, Mysql 4.1.9+ has no problems with the long query, the buf is 65k big and the sql server needs for it 0.00009 secs on an athlon xp 2400+ WinXP (1GB Mem) .. [Sirius]
|
||||
sprintf(tmp_sql, "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`,`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` FROM `char` WHERE `char_id` = '%d'", charid);
|
||||
sprintf(tmp_sql, "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`,`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`, `homun_id` FROM `char` WHERE `char_id` = '%d'", charid);
|
||||
if(mysql_query(&charsql_handle, tmp_sql)){
|
||||
ShowSQL("DB error - %s\n",mysql_error(&charsql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
|
||||
@ -102,9 +103,10 @@ struct mmo_charstatus *charsave_loadchar(int charid){
|
||||
c->mother = atoi(charsql_row[44]);
|
||||
c->child = atoi(charsql_row[45]);
|
||||
c->fame = atoi(charsql_row[46]);
|
||||
|
||||
c->hom_id = atoi(charsql_row[47]); // albator
|
||||
mysql_free_result(charsql_res);
|
||||
|
||||
|
||||
//Check for '0' Savepoint / LastPoint
|
||||
if (c->last_point.x == 0 || c->last_point.y == 0 || c->last_point.map == 0){
|
||||
c->last_point.map = mapindex_name2id(MAP_PRONTERA);
|
||||
@ -237,8 +239,10 @@ struct mmo_charstatus *charsave_loadchar(int charid){
|
||||
c->global_reg_num = i;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//Shamelessly stolen from its_sparky (ie: thanks) and then assimilated by [Skotlex]
|
||||
//Friend list
|
||||
//Friend list
|
||||
sprintf(tmp_sql, "SELECT f.friend_account, f.friend_id, c.name FROM friends f LEFT JOIN `char` c ON f.friend_account=c.account_id AND f.friend_id=c.char_id WHERE f.char_id='%d'", charid);
|
||||
|
||||
if(mysql_query(&charsql_handle, tmp_sql)){
|
||||
@ -248,7 +252,7 @@ struct mmo_charstatus *charsave_loadchar(int charid){
|
||||
}
|
||||
else
|
||||
sql_res = mysql_store_result(&charsql_handle);
|
||||
|
||||
|
||||
if(sql_res)
|
||||
{
|
||||
for(i = 0; (sql_row = mysql_fetch_row(sql_res)) && i<MAX_FRIENDS; i++)
|
||||
@ -273,6 +277,7 @@ int charsave_savechar(int charid, struct mmo_charstatus *c){
|
||||
// char tmp_str[64];
|
||||
// char tmp_str2[512];
|
||||
//First save the 'char'
|
||||
ShowDebug("charsave_savechar : charid = %d | hd->master->status.char_id = %d\n", charid) ;
|
||||
sprintf(tmp_sql ,"UPDATE `char` SET `class`='%d', `base_level`='%d', `job_level`='%d',"
|
||||
"`base_exp`='%d', `job_exp`='%d', `zeny`='%d',"
|
||||
"`max_hp`='%d',`hp`='%d',`max_sp`='%d',`sp`='%d',`status_point`='%d',`skill_point`='%d',"
|
||||
@ -280,7 +285,7 @@ int charsave_savechar(int charid, struct mmo_charstatus *c){
|
||||
"`option`='%d',`karma`='%d',`manner`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',"
|
||||
"`hair`='%d',`hair_color`='%d',`clothes_color`='%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',"
|
||||
"`partner_id`='%d', `father`='%d', `mother`='%d', `child`='%d', `fame`='%d'"
|
||||
"`partner_id`='%d', `father`='%d', `mother`='%d', `child`='%d', `fame`='%d', `homun_id`='%d'"
|
||||
"WHERE `account_id`='%d' AND `char_id` = '%d'",
|
||||
c->class_, c->base_level, c->job_level,
|
||||
c->base_exp, c->job_exp, c->zeny,
|
||||
@ -291,7 +296,7 @@ int charsave_savechar(int charid, struct mmo_charstatus *c){
|
||||
c->weapon, c->shield, c->head_top, c->head_mid, c->head_bottom,
|
||||
mapindex_id2name(c->last_point.map), c->last_point.x, c->last_point.y,
|
||||
mapindex_id2name(c->save_point.map), c->save_point.x, c->save_point.y, c->partner_id, c->father, c->mother,
|
||||
c->child, c->fame, c->account_id, c->char_id
|
||||
c->child, c->fame, c->hom_id, c->account_id, c->char_id
|
||||
);
|
||||
if(mysql_query(&charsql_handle, tmp_sql)){
|
||||
ShowSQL("DB error - %s\n",mysql_error(&charsql_handle));
|
||||
@ -311,16 +316,16 @@ int charsave_savechar(int charid, struct mmo_charstatus *c){
|
||||
str_p += sprintf(str_p, "INSERT INTO `inventory` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`");
|
||||
for (j = 0; j < MAX_SLOTS; j++)
|
||||
str_p += sprintf(str_p, ", `card%d`", j);
|
||||
|
||||
|
||||
str_p += sprintf(str_p, ") VALUES ('%d', '%d', '%d', '%d', '%d', '%d', '%d'",
|
||||
charid, c->inventory[i].nameid, c->inventory[i].amount, c->inventory[i].equip,
|
||||
c->inventory[i].identify, c->inventory[i].refine, c->inventory[i].attribute);
|
||||
|
||||
for (j = 0; j < MAX_SLOTS; j++)
|
||||
str_p += sprintf(str_p, ", '%d'", c->inventory[i].card[j]);
|
||||
|
||||
|
||||
strcat(tmp_sql,")");
|
||||
|
||||
|
||||
if(mysql_query(&charsql_handle, tmp_sql)){
|
||||
ShowSQL("DB error - %s\n",mysql_error(&charsql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
|
||||
@ -340,16 +345,16 @@ int charsave_savechar(int charid, struct mmo_charstatus *c){
|
||||
str_p += sprintf(str_p, "INSERT INTO `cart_inventory` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`");
|
||||
for (j = 0; j < MAX_SLOTS; j++)
|
||||
str_p += sprintf(str_p, ", `card%d`", j);
|
||||
|
||||
|
||||
str_p += sprintf(str_p, ") VALUES ('%d', '%d', '%d', '%d', '%d', '%d', '%d'",
|
||||
charid, c->cart[i].nameid, c->cart[i].amount, c->cart[i].equip,
|
||||
c->cart[i].identify, c->cart[i].refine, c->cart[i].attribute);
|
||||
|
||||
for (j = 0; j < MAX_SLOTS; j++)
|
||||
str_p += sprintf(str_p, ", '%d'", c->cart[i].card[j]);
|
||||
|
||||
|
||||
strcat(tmp_sql,")");
|
||||
|
||||
|
||||
if(mysql_query(&charsql_handle, tmp_sql)){
|
||||
ShowSQL("DB error - %s\n",mysql_error(&charsql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
|
||||
@ -436,7 +441,7 @@ int charsave_savechar(int charid, struct mmo_charstatus *c){
|
||||
int charsave_load_scdata(int account_id, int char_id)
|
||||
{ //Loads character's sc_data
|
||||
struct map_session_data *sd;
|
||||
|
||||
|
||||
sd = map_id2sd(account_id);
|
||||
if (!sd)
|
||||
{
|
||||
@ -450,7 +455,7 @@ int charsave_load_scdata(int account_id, int char_id)
|
||||
}
|
||||
sprintf(tmp_sql, "SELECT `type`, `tick`, `val1`, `val2`, `val3`, `val4` FROM `sc_data`"
|
||||
"WHERE `account_id`='%d' AND `char_id`='%d'", account_id, char_id);
|
||||
|
||||
|
||||
if(mysql_query(&charsql_handle, tmp_sql)){
|
||||
ShowSQL("DB error - %s\n",mysql_error(&charsql_handle));
|
||||
ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
|
||||
@ -490,7 +495,7 @@ void charsave_save_scdata(int account_id, int char_id, struct status_change* sc_
|
||||
char *p = tmp_sql;
|
||||
|
||||
p += sprintf(p, "INSERT INTO `sc_data` (`account_id`, `char_id`, `type`, `tick`, `val1`, `val2`, `val3`, `val4`) VALUES ");
|
||||
|
||||
|
||||
for(i = 0; i < max_sc; i++)
|
||||
{
|
||||
if (sc_data->data[i].timer == -1)
|
||||
@ -498,10 +503,10 @@ void charsave_save_scdata(int account_id, int char_id, struct status_change* sc_
|
||||
timer = get_timer(sc_data->data[i].timer);
|
||||
if (timer == NULL || timer->func != status_change_timer || DIFF_TICK(timer->tick,tick) < 0)
|
||||
continue;
|
||||
|
||||
|
||||
p += sprintf(p, " ('%d','%d','%hu','%d','%d','%d','%d','%d'),", account_id, char_id,
|
||||
i, DIFF_TICK(timer->tick,tick), sc_data->data[i].val1, sc_data->data[i].val2, sc_data->data[i].val3, sc_data->data[i].val4);
|
||||
|
||||
|
||||
count++;
|
||||
}
|
||||
if (count > 0)
|
||||
|
@ -7,6 +7,11 @@
|
||||
#include "status.h"
|
||||
|
||||
#ifndef TXT_ONLY
|
||||
int charsave_loadHomunculus(int hom_id, struct homun_data *p);
|
||||
int charsave_saveHomunculus(struct homun_data *hd);
|
||||
int charsave_saveHomunculusSkills(struct homun_data *hd);
|
||||
int charsave_deleteHomunculus(struct homun_data *hd);
|
||||
|
||||
struct mmo_charstatus *charsave_loadchar(int charid);
|
||||
int charsave_savechar(int charid, struct mmo_charstatus *c);
|
||||
int charsave_load_scdata(int account_id, int char_id);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "npc.h"
|
||||
#include "pc.h"
|
||||
#include "status.h"
|
||||
#include "mercenary.h"
|
||||
#ifndef TXT_ONLY
|
||||
#include "charsave.h"
|
||||
#endif
|
||||
|
299
src/map/clif.c
299
src/map/clif.c
@ -41,6 +41,7 @@
|
||||
#include "guild.h"
|
||||
#include "vending.h"
|
||||
#include "pet.h"
|
||||
#include "mercenary.h" //[orn]
|
||||
#include "log.h"
|
||||
|
||||
#include "irc.h"
|
||||
@ -1449,93 +1450,89 @@ int clif_spawn(struct block_list *bl)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*==========================================
|
||||
* Homunculus [blackhole89]
|
||||
*------------------------------------------
|
||||
*/
|
||||
// Can somebody tell me why exactly I have commented this lot of stuff out?
|
||||
// acknowledge client it has a homunculus
|
||||
int clif_homunack(struct map_session_data *sd)
|
||||
{
|
||||
struct homun_data *hd = sd->hd;
|
||||
unsigned char buf[64];
|
||||
|
||||
nullpo_retr(0, sd);
|
||||
nullpo_retr(0, sd->hd);
|
||||
|
||||
//memset(buf,0,packet_len_table[0x230]);
|
||||
memset(buf,0,12); //not yet set that stuff
|
||||
WBUFW(buf,0)=0x230;
|
||||
WBUFL(buf,4)=hd->bl.id;
|
||||
ShowError("in clif_homunack~\n");
|
||||
clif_send(buf,/*packet_len_table[0x230]*/12,&sd->bl,SELF);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// homunculus stats et al
|
||||
int clif_homuninfo(struct map_session_data *sd)
|
||||
//[orn]
|
||||
int clif_hominfo(struct map_session_data *sd, int flag)
|
||||
{
|
||||
struct homun_data *hd = sd->hd;
|
||||
struct status_data *status;
|
||||
unsigned char buf[128];
|
||||
|
||||
nullpo_retr(0, hd);
|
||||
|
||||
// if ( sd->hd )
|
||||
// return 0 ;
|
||||
|
||||
status = &hd->battle_status;
|
||||
memset(buf,0,71); //packet_len_table[0x22e]);
|
||||
WBUFW(buf,0)=0x22e;
|
||||
memcpy(WBUFP(buf,2),hd->name,NAME_LENGTH);
|
||||
WBUFW(buf,27)=hd->level;
|
||||
WBUFW(buf,29)=hd->hunger_rate;
|
||||
WBUFL(buf,31)=0xFF; //intimacy, leave it as is
|
||||
WBUFW(buf,35)=status->batk;
|
||||
memcpy(WBUFP(buf,2),hd->master->homunculus.name,NAME_LENGTH);
|
||||
WBUFB(buf,26)=hd->master->homunculus.rename_flag * 2;
|
||||
WBUFW(buf,27)=hd->master->homunculus.level;
|
||||
WBUFW(buf,29)=hd->master->homunculus.hunger;
|
||||
WBUFW(buf,31)=(unsigned short) (hd->master->homunculus.intimacy / 100) ;
|
||||
WBUFW(buf,33)=0; // equip id
|
||||
WBUFW(buf,35)=status->rhw.atk2;
|
||||
WBUFW(buf,37)=status->matk_max;
|
||||
WBUFW(buf,39)=status->hit;
|
||||
WBUFW(buf,41)=status->cri/10; //crit is a +1 decimal value!
|
||||
WBUFW(buf,43)=status->def;
|
||||
WBUFW(buf,43)=status->def + status->vit ;
|
||||
WBUFW(buf,45)=status->mdef;
|
||||
WBUFW(buf,47)=status->flee;
|
||||
WBUFW(buf,49)=status->amotion;
|
||||
WBUFW(buf,49)=(flag)?0:status->amotion;
|
||||
WBUFW(buf,51)=status->hp;
|
||||
WBUFW(buf,53)=status->max_hp;
|
||||
WBUFW(buf,55)=status->sp;
|
||||
WBUFW(buf,57)=status->max_sp;
|
||||
WBUFL(buf,59)=hd->exp;
|
||||
WBUFL(buf,59)=hd->master->homunculus.exp;
|
||||
WBUFL(buf,63)=hd->exp_next;
|
||||
WBUFW(buf,67)=hd->skillpts;
|
||||
WBUFW(buf,69)=0x21;
|
||||
WBUFW(buf,67)=hd->master->homunculus.skillpts;
|
||||
WBUFW(buf,69)=hd->attackable;
|
||||
clif_send(buf,/*packet_len_table[0x22e]*/71,&sd->bl,SELF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// like skillinfoblock, just for homunculi.
|
||||
int clif_homunskillinfoblock(struct map_session_data *sd)
|
||||
{
|
||||
/*==========================================
|
||||
*
|
||||
*------------------------------------------
|
||||
*/
|
||||
void clif_send_homdata(struct map_session_data *sd, int type, int param) { //[orn]
|
||||
int fd;
|
||||
int i,c,len=4,id/*, inf2*/;
|
||||
nullpo_retv(sd);
|
||||
nullpo_retv(sd->hd);
|
||||
|
||||
fd=sd->fd;
|
||||
WFIFOW(fd,0)=0x230;
|
||||
WFIFOW(fd,2)=type;
|
||||
WFIFOL(fd,4)=sd->hd->bl.id;
|
||||
WFIFOL(fd,8)=param;
|
||||
WFIFOSET(fd,packet_len_table[0x230]);
|
||||
|
||||
return;
|
||||
}
|
||||
// like skillinfoblock, just for homunculi.
|
||||
int clif_homskillinfoblock(struct map_session_data *sd) { //[orn]
|
||||
int fd;
|
||||
int i,j,c,len=4,id/*, inf2*/;
|
||||
|
||||
nullpo_retr(0, sd);
|
||||
nullpo_retr(0, sd->hd);
|
||||
|
||||
if ( !sd->hd )
|
||||
return 0 ;
|
||||
|
||||
fd=sd->fd;
|
||||
WFIFOHEAD(fd, 4 * 37 + 4);
|
||||
WFIFOW(fd,0)=0x235;
|
||||
for ( i = c = 0; i < 4; i++){
|
||||
if( (id=sd->hd->hskill[i].id)!=0 ){
|
||||
WFIFOW(fd,len ) = id;
|
||||
WFIFOW(fd,len+2) = skill_get_inf(id-7300); // H. skills mapped to 700 and above
|
||||
WFIFOW(fd,len+4) = 0;
|
||||
WFIFOW(fd,len+6) = sd->hd->hskill[i].level;
|
||||
WFIFOW(fd,len+8) = skill_get_sp(id,sd->hd->hskill[i].level);
|
||||
WFIFOW(fd,len+10)= skill_get_range2(&sd->bl, id,sd->hd->hskill[i].level);
|
||||
strncpy(WFIFOP(fd,len+12), /*merc_skill_get_name(id)*/ "", NAME_LENGTH); // can somebody tell me what exactly that function was good for anyway
|
||||
/* inf2 = skill_get_inf2(id);
|
||||
if(((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) &&
|
||||
!(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL))) ||
|
||||
(battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill) )
|
||||
//WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_get_max(id) && sd->status.skill[i].flag ==0 )? 1:0;
|
||||
WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_tree_get_max(id, sd->status.class_) && sd->status.skill[i].flag ==0 )? 1:0;
|
||||
else */
|
||||
for ( i = c = 0; i < MAX_HOMUNSKILL; i++){
|
||||
if( (id = sd->homunculus.hskill[i].id) != 0 ){
|
||||
j = id - HM_SKILLBASE - 1 ;
|
||||
WFIFOW(fd,len ) = id ;
|
||||
WFIFOW(fd,len+2) = skill_get_inf(id) ;
|
||||
WFIFOW(fd,len+4) = 0 ;
|
||||
WFIFOW(fd,len+6) = sd->homunculus.hskill[j].lv ;
|
||||
WFIFOW(fd,len+8) = skill_get_sp(id,sd->homunculus.hskill[j].lv) ;
|
||||
WFIFOW(fd,len+10)= skill_get_range2(&sd->hd->bl, id,sd->homunculus.hskill[j].lv) ;
|
||||
strncpy(WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH) ;
|
||||
WFIFOB(fd,len+36) = 1;//0;
|
||||
len+=37;
|
||||
c++;
|
||||
@ -1547,49 +1544,146 @@ int clif_homunskillinfoblock(struct map_session_data *sd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clif_homskillup(struct map_session_data *sd, int skill_num) { //[orn]
|
||||
int range,fd,skillid;
|
||||
|
||||
nullpo_retv(sd);
|
||||
skillid = skill_num - HM_SKILLBASE ;
|
||||
|
||||
fd=sd->fd;
|
||||
WFIFOW(fd,0) = 0x10e;
|
||||
WFIFOW(fd,2) = skill_num;
|
||||
WFIFOW(fd,4) = sd->homunculus.hskill[skillid].lv;
|
||||
WFIFOW(fd,6) = skill_get_sp(skill_num,sd->homunculus.hskill[skillid].lv);
|
||||
range = skill_get_range(skill_num,sd->homunculus.hskill[skillid].lv);
|
||||
if(range < 0)
|
||||
range = status_get_range(&sd->bl) - (range + 1);
|
||||
WFIFOW(fd,8) = range;
|
||||
WFIFOB(fd,10) = (sd->homunculus.hskill[skillid].lv < skill_get_max(sd->homunculus.hskill[skillid].id)) ? 1 : 0;
|
||||
WFIFOSET(fd,packet_len_table[0x10e]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Request a Homunculus name change
|
||||
void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd) {
|
||||
void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd) { //[orn]
|
||||
RFIFOHEAD(fd);
|
||||
nullpo_retv(sd);
|
||||
nullpo_retv(sd->hd);
|
||||
memcpy(sd->hd->name,RFIFOP(fd,2),24);
|
||||
clif_homuninfo(sd);
|
||||
memcpy(sd->homunculus.name,RFIFOP(fd,2),24);
|
||||
sd->homunculus.rename_flag = 1 ;
|
||||
clif_hominfo(sd,0);
|
||||
clif_charnameack(sd->fd,&sd->hd->bl);
|
||||
}
|
||||
|
||||
// Somebody who is less lazy than me rename this to ReturnToMaster or something
|
||||
void clif_parse_QueryHomunPos(int fd, struct map_session_data *sd) {
|
||||
void clif_parse_HomMoveToMaster(int fd, struct map_session_data *sd) { //[orn]
|
||||
RFIFOHEAD(fd);
|
||||
nullpo_retv(sd);
|
||||
nullpo_retv(sd->hd);
|
||||
|
||||
if ( sd->hd && status_isdead(&sd->hd->bl) )
|
||||
return ;
|
||||
|
||||
unit_walktoxy(&sd->hd->bl, sd->bl.x,sd->bl.y-1, 0); //move to master
|
||||
//clif_homunposack(sd->hd);
|
||||
}
|
||||
|
||||
// player spend a skillpoint for homunculus
|
||||
void clif_parse_HomUseSKillPoint(int fd, struct map_session_data *sd) { //[orn]
|
||||
int skillid ;
|
||||
nullpo_retv(sd);
|
||||
nullpo_retv(sd->hd);
|
||||
|
||||
if ( !sd->hd )
|
||||
return ;
|
||||
skillid = RFIFOW(fd,2);
|
||||
|
||||
merc_hom_skillup(sd->hd, skillid);
|
||||
}
|
||||
|
||||
// Request a Homunculus move-to-position
|
||||
void clif_parse_HMoveTo(int fd,struct map_session_data *sd) {
|
||||
void clif_parse_HomMoveTo(int fd,struct map_session_data *sd) { //[orn]
|
||||
int x,y,cmd;
|
||||
|
||||
nullpo_retv(sd);
|
||||
nullpo_retv(sd->hd);
|
||||
|
||||
if ( sd->hd && status_isdead(&sd->hd->bl) )
|
||||
return ;
|
||||
|
||||
cmd = RFIFOW(fd,0);
|
||||
x = RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]) * 4 +
|
||||
(RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0] + 1) >> 6);
|
||||
y = ((RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]+1) & 0x3f) << 4) +
|
||||
(RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0] + 2) >> 4);
|
||||
|
||||
unit_walktoxy(&sd->hd->bl,x,y,0);
|
||||
unit_walktoxy(&(sd->hd->bl),x,y,0);
|
||||
}
|
||||
|
||||
// Request the Homunculus attacking a bl
|
||||
void clif_parse_HAttack(int fd,struct map_session_data *sd) {
|
||||
void clif_parse_HomAttack(int fd,struct map_session_data *sd) { //[orn]
|
||||
struct block_list *target;
|
||||
nullpo_retv(sd);
|
||||
nullpo_retv(sd->hd);
|
||||
|
||||
target=map_id2bl(RFIFOL(fd,6));
|
||||
|
||||
if ( sd->hd && target && ( status_isdead(&sd->hd->bl) || status_isdead(target) ) )
|
||||
return ;
|
||||
|
||||
if(sd->hd->bl.id != RFIFOL(fd,2)) return;
|
||||
|
||||
printf("unit_attack returned: %d\n",unit_attack(&sd->hd->bl,RFIFOL(fd,6),0));
|
||||
merc_stop_walking(sd->hd, 1);
|
||||
merc_stop_attack(sd->hd);
|
||||
if ( sd->hd && target ) {
|
||||
sd->hd->target_id = RFIFOL(fd,6) ;
|
||||
unit_attack(&sd->hd->bl,RFIFOL(fd,6),1) ;
|
||||
}
|
||||
}
|
||||
|
||||
void clif_parse_HomMenu(int fd, struct map_session_data *sd) { //[orn]
|
||||
int cmd;
|
||||
cmd = RFIFOW(fd,0);
|
||||
RFIFOHEAD(fd);
|
||||
if ( sd->hd && status_isdead(&sd->hd->bl) )
|
||||
return ;
|
||||
merc_menu(sd,RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]));
|
||||
}
|
||||
|
||||
int clif_hom_food(struct map_session_data *sd,int foodid,int fail) //[orn]
|
||||
{
|
||||
int fd;
|
||||
|
||||
nullpo_retr(0, sd);
|
||||
|
||||
fd=sd->fd;
|
||||
WFIFOHEAD(fd,packet_len_table[0x22f]);
|
||||
WFIFOW(fd,0)=0x22f;
|
||||
WFIFOB(fd,2)=fail;
|
||||
WFIFOW(fd,3)=foodid;
|
||||
WFIFOSET(fd,packet_len_table[0x22f]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* orn
|
||||
*------------------------------------------
|
||||
*/
|
||||
int clif_hwalkok(struct homun_data *hd)
|
||||
{
|
||||
int fd;
|
||||
|
||||
nullpo_retr(0, hd);
|
||||
|
||||
fd=hd->master->fd;
|
||||
WFIFOHEAD(fd, packet_len_table[0x87]);
|
||||
WFIFOW(fd,0)=0x87;
|
||||
WFIFOL(fd,2)=gettick();
|
||||
WFIFOPOS2(fd,6,hd->bl.x,hd->bl.y,hd->ud.to_x,hd->ud.to_y);
|
||||
WFIFOB(fd,11)=0x88;
|
||||
WFIFOSET(fd,packet_len_table[0x87]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
@ -7751,7 +7845,7 @@ int clif_charnameack (int fd, struct block_list *bl)
|
||||
break;
|
||||
//[blackhole89]
|
||||
case BL_HOMUNCULUS:
|
||||
memcpy(WBUFP(buf,6), ((struct homun_data*)bl)->name, NAME_LENGTH);
|
||||
memcpy(WBUFP(buf,6), ((struct homun_data*)bl)->master->homunculus.name, NAME_LENGTH);
|
||||
break;
|
||||
case BL_PET:
|
||||
memcpy(WBUFP(buf,6), ((struct pet_data*)bl)->name, NAME_LENGTH);
|
||||
@ -8210,10 +8304,11 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
||||
if(sd->hd && sd->hd->battle_status.hp) {
|
||||
map_addblock(&sd->hd->bl);
|
||||
clif_spawn(&sd->hd->bl);
|
||||
clif_homunack(sd);
|
||||
clif_homuninfo(sd);
|
||||
clif_homuninfo(sd); //for some reason, at least older clients want this sent twice
|
||||
clif_homunskillinfoblock(sd);
|
||||
// clif_homunack(sd);
|
||||
clif_hominfo(sd,1);
|
||||
clif_hominfo(sd,0); //for some reason, at least older clients want this sent twice
|
||||
clif_send_homdata(sd,0,0);
|
||||
clif_homskillinfoblock(sd);
|
||||
}
|
||||
|
||||
if(sd->state.connect_new) {
|
||||
@ -9612,6 +9707,9 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) {
|
||||
if (skillnotok(skillnum, sd))
|
||||
return;
|
||||
|
||||
if (sd->hd && skillnotok_hom(skillnum, sd->hd)) //[orn]
|
||||
return;
|
||||
|
||||
if (sd->bl.id != target_id &&
|
||||
!sd->state.skill_flag &&
|
||||
skill_get_inf(skillnum)&INF_SELF_SKILL)
|
||||
@ -9680,12 +9778,19 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) {
|
||||
if (skillnum >= GD_SKILLBASE && sd->state.gmaster_flag)
|
||||
skilllv = guild_checkskill(sd->state.gmaster_flag, skillnum);
|
||||
|
||||
if ((lv = pc_checkskill(sd, skillnum)) > 0) {
|
||||
if (skilllv > lv)
|
||||
skilllv = lv;
|
||||
unit_skilluse_id(&sd->bl, target_id, skillnum, skilllv);
|
||||
if (sd->state.skill_flag)
|
||||
sd->state.skill_flag = 0;
|
||||
if ( ( skillnum >= HM_SKILLBASE ) && sd->status.hom_id && sd->homunculus.alive && !sd->homunculus.vaporize ) { //[orn]
|
||||
if ( ( lv = merc_hom_checkskill(sd, skillnum) ) > 0 )
|
||||
if (skilllv > lv)
|
||||
skilllv = lv;
|
||||
unit_skilluse_id(&sd->hd->bl, target_id, skillnum, skilllv);
|
||||
} else {
|
||||
if ((lv = pc_checkskill(sd, skillnum)) > 0) {
|
||||
if (skilllv > lv)
|
||||
skilllv = lv;
|
||||
unit_skilluse_id(&sd->bl, target_id, skillnum, skilllv);
|
||||
if (sd->state.skill_flag)
|
||||
sd->state.skill_flag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11559,6 +11664,36 @@ int clif_parse(int fd) {
|
||||
|
||||
#if DUMP_ALL_PACKETS
|
||||
dump = 1;
|
||||
int i;
|
||||
FILE *fp;
|
||||
char packet_txt[256] = "save/packet.txt";
|
||||
time_t now;
|
||||
dump = 1;
|
||||
|
||||
if ((fp = fopen(packet_txt, "a")) == NULL) {
|
||||
ShowError("clif.c: cant write [%s] !!! data is lost !!!\n", packet_txt);
|
||||
return 1;
|
||||
} else {
|
||||
time(&now);
|
||||
if (sd && sd->state.auth) {
|
||||
if (sd->status.name != NULL)
|
||||
fprintf(fp, "%sPlayer with account ID %d (character ID %d, player name %s) sent packet:\n",
|
||||
asctime(localtime(&now)), sd->status.account_id, sd->status.char_id, sd->status.name);
|
||||
else
|
||||
fprintf(fp, "%sPlayer with account ID %d sent wrong packet:\n", asctime(localtime(&now)), sd->bl.id);
|
||||
} else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified)
|
||||
fprintf(fp, "%sPlayer with account ID %d sent wrong packet:\n", asctime(localtime(&now)), sd->bl.id);
|
||||
|
||||
fprintf(fp, "\tsession #%d, packet 0x%04x, length %d, version %d\n", fd, cmd, packet_len, packet_ver);
|
||||
fprintf(fp, "\t---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F");
|
||||
for(i = 0; i < packet_len; i++) {
|
||||
if ((i & 15) == 0)
|
||||
fprintf(fp, "\n\t%04X ", i);
|
||||
fprintf(fp, "%02X ", RFIFOB(fd,i));
|
||||
}
|
||||
fprintf(fp, "\n\n");
|
||||
fclose(fp);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sd && sd->state.auth == 1 && sd->state.waitingdisconnect == 1) { // 切断待ちの場合パケットを処理しない
|
||||
@ -11777,11 +11912,13 @@ static int packetdb_readdb(void)
|
||||
{clif_parse_FeelSaveOk,"feelsaveok"},
|
||||
{clif_parse_AdoptRequest,"adopt"},
|
||||
{clif_parse_debug,"debug"},
|
||||
//[blackhole89]
|
||||
//[blackhole89] //[orn]
|
||||
{clif_parse_ChangeHomunculusName,"changehomunculusname"},
|
||||
{clif_parse_QueryHomunPos,"queryhomunpos"},
|
||||
{clif_parse_HMoveTo,"hmoveto"},
|
||||
{clif_parse_HAttack,"hattack"},
|
||||
{clif_parse_HomMoveToMaster,"hommovetomaster"},
|
||||
{clif_parse_HomMoveTo,"hommoveto"},
|
||||
{clif_parse_HomAttack,"homattack"},
|
||||
{clif_parse_HomUseSKillPoint,"homuseskillpoint"},
|
||||
{clif_parse_HomMenu,"hommenu"},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
|
@ -354,9 +354,13 @@ void clif_mission_mob(struct map_session_data *sd, unsigned short mob_id, unsign
|
||||
|
||||
// [blackhole89]
|
||||
int clif_spawnhomun(struct homun_data *hd);
|
||||
int clif_homunack(struct map_session_data *sd);
|
||||
int clif_homuninfo(struct map_session_data *sd);
|
||||
int clif_homunskillinfoblock(struct map_session_data *sd);
|
||||
int clif_hominfo(struct map_session_data *sd, int flag);
|
||||
int clif_homskillinfoblock(struct map_session_data *sd);
|
||||
void clif_homskillup(struct map_session_data *sd, int skill_num) ; //[orn]
|
||||
int clif_hom_food(struct map_session_data *sd,int foodid,int fail); //[orn]
|
||||
void clif_send_homdata(struct map_session_data *sd, int type, int param); //[orn]
|
||||
int clif_hwalkok(struct homun_data *hd); //[orn]
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
170
src/map/intif.c
170
src/map/intif.c
@ -24,6 +24,7 @@
|
||||
#include "guild.h"
|
||||
#include "pet.h"
|
||||
#include "atcommand.h"
|
||||
#include "mercenary.h" //albator
|
||||
|
||||
static const int packet_len_table[]={
|
||||
-1,-1,27,-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3800-0x380f
|
||||
@ -35,6 +36,7 @@ static const int packet_len_table[]={
|
||||
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,
|
||||
11,-1, 7, 3, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880
|
||||
16,-1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x3890 Homunculus [albator]
|
||||
};
|
||||
|
||||
extern int char_fd; // inter serverのfdはchar_fdを使う
|
||||
@ -132,13 +134,13 @@ int intif_GMmessage(char* mes,int len,int flag)
|
||||
|
||||
// Send to the local players
|
||||
clif_GMmessage(NULL, mes, len, flag);
|
||||
|
||||
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
|
||||
|
||||
if (other_mapserver_count < 1)
|
||||
return 0; //No need to send.
|
||||
|
||||
|
||||
WFIFOHEAD(inter_fd,lp + len + 4);
|
||||
WFIFOW(inter_fd,0) = 0x3000;
|
||||
WFIFOW(inter_fd,2) = lp + len + 4;
|
||||
@ -156,13 +158,13 @@ int intif_announce(char* mes,int len, unsigned long color, int flag)
|
||||
clif_MainChatMessage(mes);
|
||||
else
|
||||
clif_announce(NULL, mes, len, color, flag);
|
||||
|
||||
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
|
||||
if (other_mapserver_count < 1)
|
||||
return 0; //No need to send.
|
||||
|
||||
|
||||
WFIFOHEAD(inter_fd, 8 + len);
|
||||
WFIFOW(inter_fd,0) = 0x3000;
|
||||
WFIFOW(inter_fd,2) = 8 + len;
|
||||
@ -182,8 +184,8 @@ int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int me
|
||||
{ //Character not found.
|
||||
clif_wis_end(sd->fd, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WFIFOHEAD(inter_fd,mes_len + 52);
|
||||
WFIFOW(inter_fd,0) = 0x3001;
|
||||
WFIFOW(inter_fd,2) = mes_len + 52;
|
||||
@ -236,7 +238,7 @@ int intif_wis_message_to_gm(char *Wisp_name, int min_gm_level, char *mes) {
|
||||
|
||||
int intif_regtostr(char* str, struct global_reg *reg, int qty) {
|
||||
int len =0, i;
|
||||
|
||||
|
||||
for (i = 0; i < qty; i++) {
|
||||
len+= sprintf(str+len, "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place.
|
||||
len+= sprintf(str+len, "%s", reg[i].value)+1;
|
||||
@ -252,7 +254,7 @@ int intif_saveregistry(struct map_session_data *sd, int type)
|
||||
|
||||
if (CheckForCharServer())
|
||||
return -1;
|
||||
|
||||
|
||||
switch (type) {
|
||||
case 3: //Character reg
|
||||
reg = sd->save_reg.global;
|
||||
@ -311,7 +313,7 @@ int intif_request_registry(struct map_session_data *sd, int flag)
|
||||
WFIFOW(inter_fd,0) = 0x3005;
|
||||
WFIFOL(inter_fd,2) = sd->status.account_id;
|
||||
WFIFOL(inter_fd,6) = sd->status.char_id;
|
||||
WFIFOB(inter_fd,10) = (flag&1?1:0); //Request Acc Reg 2
|
||||
WFIFOB(inter_fd,10) = (flag&1?1:0); //Request Acc Reg 2
|
||||
WFIFOB(inter_fd,11) = (flag&2?1:0); //Request Acc Reg
|
||||
WFIFOB(inter_fd,12) = (flag&4?1:0); //Request Char Reg
|
||||
WFIFOSET(inter_fd,13);
|
||||
@ -405,7 +407,7 @@ int intif_party_addmember(int party_id,struct party_member *member)
|
||||
{
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
|
||||
|
||||
WFIFOHEAD(inter_fd,42);
|
||||
WFIFOW(inter_fd,0)=0x3022;
|
||||
WFIFOW(inter_fd,2)=8+sizeof(struct party_member);
|
||||
@ -448,7 +450,7 @@ int intif_party_changemap(struct map_session_data *sd,int online)
|
||||
return 0;
|
||||
if(!sd)
|
||||
return 0;
|
||||
|
||||
|
||||
WFIFOHEAD(inter_fd,19);
|
||||
WFIFOW(inter_fd,0)=0x3025;
|
||||
WFIFOL(inter_fd,2)=sd->status.party_id;
|
||||
@ -776,6 +778,72 @@ int intif_guild_castle_datasave(int castle_id,int index, int value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Homunculus Packets send to Inter server [albator]
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
int intif_homunculus_create(int account_id, struct s_homunculus *sh)
|
||||
{
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
WFIFOHEAD(inter_fd, 44+NAME_LENGHT);
|
||||
WFIFOW(inter_fd, 0) = 0x3090;
|
||||
WFIFOL(inter_fd, 2) = account_id;
|
||||
WFIFOL(inter_fd, 6) = sh->char_id;
|
||||
WFIFOW(inter_fd, 10) = sh->class_;
|
||||
WFIFOL(inter_fd,12) = sh->max_hp;
|
||||
WFIFOL(inter_fd,16) = sh->max_sp;
|
||||
memcpy(WFIFOP(inter_fd,20), sh->name, NAME_LENGTH);
|
||||
WFIFOL(inter_fd,44) = sh->str;
|
||||
WFIFOL(inter_fd,48) = sh->agi;
|
||||
WFIFOL(inter_fd,52) = sh->vit;
|
||||
WFIFOL(inter_fd,56) = sh->int_;
|
||||
WFIFOL(inter_fd,60) = sh->dex;
|
||||
WFIFOL(inter_fd,64) = sh->luk;
|
||||
WFIFOSET(inter_fd, 44+NAME_LENGTH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intif_homunculus_requestload(int account_id, int homun_id)
|
||||
{
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
WFIFOHEAD(inter_fd, 10);
|
||||
WFIFOW(inter_fd,0) = 0x3091;
|
||||
WFIFOL(inter_fd,2) = account_id;
|
||||
WFIFOL(inter_fd,6) = homun_id;
|
||||
WFIFOSET(inter_fd, 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intif_homunculus_requestsave(int account_id, struct s_homunculus* sh)
|
||||
{
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
WFIFOHEAD(inter_fd, sizeof(struct s_homunculus)+10);
|
||||
WFIFOW(inter_fd,0) = 0x3092;
|
||||
WFIFOL(inter_fd,2) = sizeof(struct s_homunculus)+10;
|
||||
WFIFOL(inter_fd,6) = account_id;
|
||||
memcpy(WFIFOP(inter_fd,10),sh,sizeof(struct s_homunculus));
|
||||
WFIFOSET(inter_fd, sizeof(struct s_homunculus)+10);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int intif_homunculus_requestdelete(int homun_id)
|
||||
{
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
WFIFOHEAD(inter_fd, 6);
|
||||
WFIFOW(inter_fd, 0) = 0x3093;
|
||||
WFIFOL(inter_fd,2) = homun_id;
|
||||
WFIFOSET(inter_fd,6);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Packets receive from inter server
|
||||
|
||||
@ -881,9 +949,9 @@ int intif_parse_Registers(int fd) {
|
||||
|
||||
if (RFIFOB(fd,12) == 3 && sd->status.char_id != RFIFOL(fd,8))
|
||||
return 1; //Character registry from another character.
|
||||
|
||||
|
||||
flag = (sd->save_reg.global_num == -1 || sd->save_reg.account_num == -1 || sd->save_reg.account2_num == -1);
|
||||
|
||||
|
||||
switch (RFIFOB(fd,12)) {
|
||||
case 3: //Character Registry
|
||||
reg = sd->save_reg.global;
|
||||
@ -1370,6 +1438,74 @@ int intif_parse_RenamePetOk(int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Homunculus recv packets [albator]
|
||||
|
||||
int intif_parse_CreateHomunculus(int fd)
|
||||
{
|
||||
struct map_session_data *sd = NULL;
|
||||
RFIFOHEAD(fd);
|
||||
|
||||
if((sd=map_id2sd(RFIFOL(fd,2)))==NULL ||
|
||||
sd->status.char_id != RFIFOL(fd,6))
|
||||
return 0;
|
||||
|
||||
if(RFIFOW(fd,10)==1)
|
||||
{
|
||||
ShowInfo("Homunculus created successfully\n");
|
||||
sd->status.hom_id = sd->homunculus.hom_id = RFIFOL(fd,12);
|
||||
merc_hom_recv_data(RFIFOL(fd,2), &sd->homunculus, 1) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowError("intif_parse_CreateHomunculus: failed to create homunculus\n");
|
||||
clif_displaymessage(sd->fd, "[debug] fail to create homunculus"); // display error message..
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intif_parse_RecvHomunculusData(int fd)
|
||||
{
|
||||
struct s_homunculus sh;
|
||||
int len;
|
||||
|
||||
RFIFOHEAD(fd);
|
||||
len=RFIFOW(fd,2);
|
||||
|
||||
if(sizeof(struct s_homunculus)!=len-9) {
|
||||
if(battle_config.etc_log)
|
||||
ShowError("intif: homun data: data size error %d %d\n",sizeof(struct s_homunculus),len-9);
|
||||
}
|
||||
else{
|
||||
memcpy(&sh,RFIFOP(fd,9),sizeof(struct s_homunculus));
|
||||
merc_hom_recv_data(RFIFOL(fd,4),&sh,RFIFOB(fd,8));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int intif_parse_SaveHomunculusOk(int fd)
|
||||
{
|
||||
RFIFOHEAD(fd);
|
||||
if(RFIFOB(fd,2) != 1) {
|
||||
if(battle_config.error_log)
|
||||
ShowError("homunculus data save failure\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int intif_parse_DeleteHomunculusOk(int fd)
|
||||
{
|
||||
RFIFOHEAD(fd);
|
||||
if(RFIFOB(fd,2) != 1) {
|
||||
if(battle_config.error_log)
|
||||
ShowError("Homunculus data delete failure\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
// inter serverからの通信
|
||||
// エラーがあれば0(false)を返すこと
|
||||
@ -1398,7 +1534,7 @@ int intif_parse(int fd)
|
||||
}
|
||||
// 処理分岐
|
||||
switch(cmd){
|
||||
case 0x3800:
|
||||
case 0x3800:
|
||||
if (RFIFOL(fd,4) == 0xFF000000) //Normal announce.
|
||||
clif_GMmessage(NULL,(char *) RFIFOP(fd,8),packet_len-8,0);
|
||||
else if (RFIFOL(fd,4) == 0xFE000000) //Main chat message [LuzZza]
|
||||
@ -1445,6 +1581,10 @@ int intif_parse(int fd)
|
||||
case 0x3882: intif_parse_SavePetOk(fd); break;
|
||||
case 0x3883: intif_parse_DeletePetOk(fd); break;
|
||||
case 0x3884: intif_parse_RenamePetOk(fd); break;
|
||||
case 0x3890: intif_parse_CreateHomunculus(fd); break;
|
||||
case 0x3891: intif_parse_RecvHomunculusData(fd); break;
|
||||
case 0x3892: intif_parse_SaveHomunculusOk(fd); break;
|
||||
case 0x3893: intif_parse_DeleteHomunculusOk(fd); break;
|
||||
default:
|
||||
if(battle_config.error_log)
|
||||
ShowError("intif_parse : unknown packet %d %x\n",fd,RFIFOW(fd,0));
|
||||
|
@ -60,6 +60,13 @@ int intif_save_petdata(int account_id, struct s_pet *p);
|
||||
int intif_delete_petdata(int pet_id);
|
||||
int intif_rename_pet(struct map_session_data *sd, char *name);
|
||||
|
||||
|
||||
int intif_homunculus_create(int account_id, struct s_homunculus *sh);
|
||||
int intif_homunculus_requestload(int account_id, int homun_id);
|
||||
int intif_homunculus_requestsave(int account_id, struct s_homunculus* sh);
|
||||
int intif_homunculus_requestdelete(int homun_id);
|
||||
|
||||
|
||||
int CheckForCharServer(void);
|
||||
|
||||
#endif
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "script.h"
|
||||
#include "guild.h"
|
||||
#include "pet.h"
|
||||
#include "mercenary.h" //[orn]
|
||||
#include "atcommand.h"
|
||||
#include "charcommand.h"
|
||||
|
||||
@ -1664,6 +1665,8 @@ int map_quit(struct map_session_data *sd) {
|
||||
|
||||
sd->state.waitingdisconnect = 1;
|
||||
if (sd->pd) unit_free(&sd->pd->bl);
|
||||
if(sd->status.hom_id > 0 && sd->hd) //[orn]
|
||||
merc_hom_delete(sd->hd, 0) ;
|
||||
unit_free(&sd->bl);
|
||||
chrif_save(sd,1);
|
||||
} else { //Try to free some data, without saving anything (this could be invoked on map server change. [Skotlex]
|
||||
@ -3886,6 +3889,7 @@ int do_init(int argc, char *argv[]) {
|
||||
do_init_storage();
|
||||
do_init_skill();
|
||||
do_init_pet();
|
||||
do_init_merc(); //[orn]
|
||||
do_init_npc();
|
||||
do_init_unit();
|
||||
#ifndef TXT_ONLY /* mail system [Valaris] */
|
||||
|
@ -485,6 +485,7 @@ struct party_data {
|
||||
|
||||
struct npc_data;
|
||||
struct pet_db;
|
||||
struct homunculus_db; //[orn]
|
||||
struct item_data;
|
||||
struct square;
|
||||
|
||||
@ -747,6 +748,7 @@ struct map_session_data {
|
||||
struct s_pet pet;
|
||||
struct pet_data *pd;
|
||||
|
||||
struct s_homunculus homunculus ; //[orn]
|
||||
struct homun_data *hd; // [blackhole89]
|
||||
|
||||
struct{
|
||||
@ -932,26 +934,35 @@ struct homun_data {
|
||||
struct view_data *vd;
|
||||
struct status_data base_status, battle_status;
|
||||
struct status_change sc;
|
||||
|
||||
char name[NAME_LENGTH];
|
||||
int id;
|
||||
short class_;
|
||||
struct homunculus_db *homunculusDB; //[orn]
|
||||
|
||||
struct map_session_data *master; //pointer back to its master
|
||||
|
||||
short hunger_rate;
|
||||
int hungry_timer; //[orn]
|
||||
|
||||
struct {
|
||||
int id; //0 = none
|
||||
int level;
|
||||
} hskill[4]; //skills (max. 4 for now)
|
||||
|
||||
int target_id,attacked_id;
|
||||
short attackable;
|
||||
|
||||
short level;
|
||||
short regenhp,regensp;
|
||||
unsigned long exp,exp_next;
|
||||
short skillpts;
|
||||
int natural_heal_timer; //[orn]
|
||||
int hp_sub,sp_sub;
|
||||
int inchealhptick,inchealsptick;
|
||||
int nhealhp,nhealsp,nshealhp,nshealsp,nsshealhp,nsshealsp;
|
||||
short hp_loss_value;
|
||||
short sp_loss_value;
|
||||
short hp_loss_type;
|
||||
short sp_gain_value;
|
||||
short hp_gain_value;
|
||||
int hp_loss_tick;
|
||||
int sp_loss_tick;
|
||||
int hp_loss_rate;
|
||||
int sp_loss_rate;
|
||||
unsigned int canregen_tick;
|
||||
|
||||
|
||||
unsigned short regenhp,regensp;
|
||||
unsigned long exp_next;
|
||||
char blockskill[MAX_SKILL]; // [orn]
|
||||
};
|
||||
|
||||
struct pet_data {
|
||||
|
1221
src/map/mercenary.c
1221
src/map/mercenary.c
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,78 @@
|
||||
// Homunculus and future Mercenary system code go here [Celest]
|
||||
// implemented by [orn]
|
||||
struct homunculus_db {
|
||||
int class_ ;
|
||||
char name[NAME_LENGTH];
|
||||
int basemaxHP ;
|
||||
int basemaxSP ;
|
||||
int baseSTR ;
|
||||
int baseAGI ;
|
||||
int baseVIT ;
|
||||
int baseINT ;
|
||||
int baseDEX ;
|
||||
int baseLUK ;
|
||||
int foodID ;
|
||||
int baseIntimacy ;
|
||||
short baseHungry ;
|
||||
long hungryDelay ;
|
||||
int gminHP ;
|
||||
int gmaxHP ;
|
||||
int gminSP ;
|
||||
int gmaxSP ;
|
||||
int gminSTR ;
|
||||
int gmaxSTR ;
|
||||
int gminAGI ;
|
||||
int gmaxAGI ;
|
||||
int gminVIT ;
|
||||
int gmaxVIT ;
|
||||
int gminINT ;
|
||||
int gmaxINT ;
|
||||
int gminDEX ;
|
||||
int gmaxDEX ;
|
||||
int gminLUK ;
|
||||
int gmaxLUK ;
|
||||
int evo_class ;
|
||||
int baseASPD ;
|
||||
//short size ;
|
||||
//short race ;
|
||||
//short element ;
|
||||
unsigned char element, race, size; // albator
|
||||
int accessID ;
|
||||
};
|
||||
extern struct homunculus_db homuncumlus_db[MAX_HOMUNCULUS_CLASS];
|
||||
enum { HOMUNCULUS_CLASS, HOMUNCULUS_FOOD };
|
||||
enum {
|
||||
SP_ACK = 0x00,
|
||||
SP_INTIMATE = 0x100,
|
||||
SP_HUNGRY = 0x200
|
||||
};
|
||||
|
||||
int do_init_merc (void);
|
||||
int merc_hom_recv_data(int account_id, struct s_homunculus *sh, int flag); //albator
|
||||
void merc_load_sub(struct homun_data *hd, struct map_session_data *sd);
|
||||
void merc_load_exptables(void);
|
||||
char *merc_skill_get_name(int id);
|
||||
char *merc_hom_skill_get_name(int id);
|
||||
void merc_damage(struct homun_data *hd,struct block_list *src,int hp,int sp);
|
||||
int merc_dead(struct homun_data *hd, struct block_list *src);
|
||||
void merc_skillup(struct map_session_data *sd,short skillnum);
|
||||
int merc_gainexp(struct homun_data *hd,int exp);
|
||||
void merc_heal(struct homun_data *hd,int hp,int sp);
|
||||
int merc_hom_dead(struct homun_data *hd, struct block_list *src);
|
||||
void merc_hom_skillup(struct homun_data *hd,int skillnum);
|
||||
int merc_hom_calc_skilltree(struct map_session_data *sd) ;
|
||||
int merc_hom_checkskill(struct map_session_data *sd,int skill_id) ;
|
||||
int merc_hom_gainexp(struct homun_data *hd,int exp) ;
|
||||
int merc_hom_levelup(struct homun_data *hd) ;
|
||||
int merc_hom_evolution(struct homun_data *hd) ;
|
||||
int merc_hom_heal(struct homun_data *hd,int hp,int sp);
|
||||
int merc_hom_delete(struct homun_data *hd, int flag) ;
|
||||
int merc_hom_revive(struct map_session_data *sd, int per);
|
||||
void merc_save(struct homun_data *hd);
|
||||
void merc_load(struct map_session_data *sd);
|
||||
int merc_create_homunculus(struct map_session_data *sd,int id,int m,int x,int y);
|
||||
int merc_call_homunculus(struct map_session_data *sd);
|
||||
int merc_create_homunculus(struct map_session_data *sd, int class_);
|
||||
int search_homunculusDB_index(int key,int type);
|
||||
int merc_menu(struct map_session_data *sd,int menunum);
|
||||
int merc_hom_food(struct map_session_data *sd, struct homun_data *hd);
|
||||
int merc_hom_hungry_timer_delete(struct homun_data *hd);
|
||||
int merc_natural_heal_timer_delete(struct homun_data *hd);
|
||||
#define merc_checkoverhp(hd) (hd->battle_status.hp == hd->battle_status.max_hp)
|
||||
#define merc_checkoversp(hd) (hd->battle_status.sp == hd->battle_status.max_sp)
|
||||
#define merc_stop_walking(hd, type) { if((hd)->ud.walktimer != -1) unit_stop_walking(&(hd)->bl, type); }
|
||||
#define merc_stop_attack(hd) { if((hd)->ud.attacktimer != -1) unit_stop_attack(&(hd)->bl); hd->ud.target = 0; }
|
||||
int read_homunculusdb(void);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "pc.h"
|
||||
#include "status.h"
|
||||
#include "mob.h"
|
||||
#include "mercenary.h" //[orn]
|
||||
#include "guild.h"
|
||||
#include "itemdb.h"
|
||||
#include "skill.h"
|
||||
@ -761,6 +762,7 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist)
|
||||
*/
|
||||
static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
|
||||
{
|
||||
struct map_session_data *sd;
|
||||
struct mob_data *md;
|
||||
struct block_list **target;
|
||||
int dist;
|
||||
@ -783,9 +785,15 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
|
||||
switch (bl->type)
|
||||
{
|
||||
case BL_PC:
|
||||
{
|
||||
if (((TBL_PC*)bl)->state.gangsterparadise &&
|
||||
!(status_get_mode(&md->bl)&MD_BOSS))
|
||||
return 0; //Gangster paradise protection.
|
||||
sd = (TBL_PC*)bl; //[orn] monster target homunculus while hunting
|
||||
if (sd->hd && sd->homunculus.alive && (distance_bl(&md->bl, &sd->hd->bl ) < md->db->range2 ) ) //
|
||||
return 0; //Gangster paradise protection.
|
||||
}
|
||||
case BL_HOMUNCULUS: //[orn]
|
||||
case BL_MOB:
|
||||
if((dist=distance_bl(&md->bl, bl)) < md->db->range2 &&
|
||||
((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) &&
|
||||
@ -824,6 +832,7 @@ static int mob_ai_sub_hard_changechase(struct block_list *bl,va_list ap)
|
||||
switch (bl->type)
|
||||
{
|
||||
case BL_PC:
|
||||
case BL_HOMUNCULUS: //[orn]
|
||||
case BL_MOB:
|
||||
if(check_distance_bl(&md->bl, bl, md->status.rhw.range) &&
|
||||
battle_check_range (&md->bl, bl, md->status.rhw.range)
|
||||
@ -1167,13 +1176,13 @@ static int mob_ai_sub_hard(struct block_list *bl,va_list ap)
|
||||
(mode&MD_ANGRY && md->state.skillstate == MSS_FOLLOW)
|
||||
) {
|
||||
map_foreachinrange (mob_ai_sub_hard_activesearch, &md->bl,
|
||||
view_range, md->special_state.ai?BL_CHAR:BL_PC, md, &tbl);
|
||||
view_range, md->special_state.ai?BL_CHAR:BL_PC|BL_HOMUNCULUS, md, &tbl); //[orn]
|
||||
if(!tbl && mode&MD_ANGRY && !md->state.aggressive)
|
||||
md->state.aggressive = 1; //Restore angry state when no targets are visible.
|
||||
} else if (mode&MD_CHANGECHASE && (md->state.skillstate == MSS_RUSH || md->state.skillstate == MSS_FOLLOW)) {
|
||||
search_size = view_range<md->status.rhw.range ? view_range:md->status.rhw.range;
|
||||
map_foreachinrange (mob_ai_sub_hard_changechase, &md->bl,
|
||||
search_size, (md->special_state.ai?BL_CHAR:BL_PC), md, &tbl);
|
||||
search_size, (md->special_state.ai?BL_CHAR:BL_PC|BL_HOMUNCULUS), md, &tbl); //[orn]
|
||||
}
|
||||
|
||||
if (tbl)
|
||||
@ -1596,7 +1605,16 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
|
||||
case BL_PC:
|
||||
{
|
||||
struct map_session_data *sd = (TBL_PC*)src;
|
||||
id = sd->status.char_id;
|
||||
// id = sd->status.char_id;
|
||||
id = sd->bl.id; //[orn]
|
||||
if(rand()%1000 < 1000/md->attacked_players)
|
||||
md->attacked_id = src->id;
|
||||
break;
|
||||
}
|
||||
case BL_HOMUNCULUS: //[orn]
|
||||
{
|
||||
struct homun_data *hd = (TBL_HOMUNCULUS*)src;
|
||||
id = hd->bl.id;
|
||||
if(rand()%1000 < 1000/md->attacked_players)
|
||||
md->attacked_id = src->id;
|
||||
break;
|
||||
@ -1605,7 +1623,8 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
|
||||
{
|
||||
struct pet_data *pd = (TBL_PET*)src;
|
||||
if (battle_config.pet_attack_exp_to_master) {
|
||||
id = pd->msd->status.char_id;
|
||||
// id = pd->msd->status.char_id;
|
||||
id = pd->msd->bl.id; //[orn]
|
||||
damage=(damage*battle_config.pet_attack_exp_rate)/100; //Modify logged damage accordingly.
|
||||
}
|
||||
//Let mobs retaliate against the pet's master [Skotlex]
|
||||
@ -1618,7 +1637,8 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
|
||||
struct mob_data* md2 = (TBL_MOB*)src;
|
||||
if(md2->special_state.ai && md2->master_id) {
|
||||
struct map_session_data* msd = map_id2sd(md2->master_id);
|
||||
if (msd) id = msd->status.char_id;
|
||||
// if (msd) id = msd->status.char_id;
|
||||
if (msd) id = msd->bl.id; //[orn]
|
||||
}
|
||||
if(rand()%1000 < 1000/md->attacked_players)
|
||||
{ //Let players decide whether to retaliate versus the master or the mob. [Skotlex]
|
||||
@ -1670,8 +1690,9 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
|
||||
int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
{
|
||||
struct status_data *status;
|
||||
struct map_session_data *sd = NULL,*tmpsd[DAMAGELOG_SIZE],
|
||||
struct map_session_data *sd = NULL,/**tmpsd[DAMAGELOG_SIZE],*/
|
||||
*mvp_sd = NULL, *second_sd = NULL,*third_sd = NULL;
|
||||
struct block_list *tmpbl[DAMAGELOG_SIZE] ; //[orn]
|
||||
|
||||
struct {
|
||||
struct party_data *p;
|
||||
@ -1706,7 +1727,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
|
||||
map_freeblock_lock();
|
||||
|
||||
memset(tmpsd,0,sizeof(tmpsd));
|
||||
memset(tmpbl,0,sizeof(tmpbl));
|
||||
memset(pt,0,sizeof(pt));
|
||||
|
||||
if(src && src->type == BL_MOB)
|
||||
@ -1735,16 +1756,19 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
|
||||
for(temp=0,i=0,mvp_damage=0;i<DAMAGELOG_SIZE && md->dmglog[i].id;i++)
|
||||
{
|
||||
tmpsd[temp] = map_charid2sd(md->dmglog[i].id);
|
||||
if(tmpsd[temp] == NULL)
|
||||
tmpbl[temp] = (struct block_list*)map_id2bl(md->dmglog[i].id);
|
||||
if(tmpbl[temp] == NULL)
|
||||
continue;
|
||||
if(tmpsd[temp]->bl.m != md->bl.m || pc_isdead(tmpsd[temp]))
|
||||
if( (tmpbl[temp])->m != md->bl.m || status_isdead(tmpbl[temp]))
|
||||
continue;
|
||||
|
||||
if(mvp_damage<(unsigned int)md->dmglog[i].dmg){
|
||||
third_sd = second_sd;
|
||||
second_sd = mvp_sd;
|
||||
mvp_sd=tmpsd[temp];
|
||||
if ( (tmpbl[temp])->type == BL_HOMUNCULUS ) {
|
||||
mvp_sd = (struct map_session_data *) ((struct homun_data *)tmpbl[temp])->master ;
|
||||
} else
|
||||
mvp_sd=(struct map_session_data *)tmpbl[temp];
|
||||
mvp_damage=md->dmglog[i].dmg;
|
||||
}
|
||||
|
||||
@ -1758,7 +1782,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
(!map[md->bl.m].flag.nobaseexp || !map[md->bl.m].flag.nojobexp) //Gives Exp
|
||||
) { //Experience calculation.
|
||||
|
||||
for(i=0;i<DAMAGELOG_SIZE && tmpsd[i];i++){
|
||||
for(i=0;i<DAMAGELOG_SIZE && tmpbl[i];i++){
|
||||
int flag=1,zeny=0;
|
||||
unsigned int base_exp,job_exp;
|
||||
double per; //Your share of the mob's exp
|
||||
@ -1835,7 +1859,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
job_exp = 1;
|
||||
}
|
||||
|
||||
if((temp=tmpsd[i]->status.party_id)>0)
|
||||
if( (tmpbl[i]->type == BL_PC) && (temp = ((struct map_session_data *)tmpbl[i])->status.party_id )>0 ) //only pc have party [orn]
|
||||
{
|
||||
int j;
|
||||
for(j=0;j<pnum && pt[j].id!=temp;j++); //Locate party.
|
||||
@ -1866,11 +1890,22 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
flag=0;
|
||||
}
|
||||
}
|
||||
if(flag) {
|
||||
if(base_exp || job_exp)
|
||||
pc_gainexp(tmpsd[i], &md->bl, base_exp,job_exp);
|
||||
if(zeny) // zeny from mobs [Valaris]
|
||||
pc_getzeny(tmpsd[i], zeny);
|
||||
if(flag) { //homunculus aren't considered in party [orn]
|
||||
switch( (tmpbl[i])->type ) {
|
||||
case BL_PC:
|
||||
if(base_exp || job_exp)
|
||||
pc_gainexp((struct map_session_data *)tmpbl[i], &md->bl, base_exp,job_exp);
|
||||
if(zeny) // zeny from mobs [Valaris]
|
||||
pc_getzeny((struct map_session_data *)tmpbl[i], zeny);
|
||||
break ;
|
||||
case BL_HOMUNCULUS:
|
||||
if(base_exp)
|
||||
merc_hom_gainexp((struct homun_data *)tmpbl[i], base_exp);
|
||||
if(zeny) //homunculus give zeny to master
|
||||
pc_getzeny((struct map_session_data *)((struct homun_data *)tmpbl[i])->master, zeny);
|
||||
break ;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
26
src/map/pc.c
26
src/map/pc.c
@ -24,6 +24,7 @@
|
||||
#include "npc.h"
|
||||
#include "mob.h"
|
||||
#include "pet.h"
|
||||
#include "mercenary.h" //orn
|
||||
#include "itemdb.h"
|
||||
#include "script.h"
|
||||
#include "battle.h"
|
||||
@ -676,6 +677,10 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t
|
||||
if (sd->status.pet_id > 0)
|
||||
intif_request_petdata(sd->status.account_id, sd->status.char_id, sd->status.pet_id);
|
||||
|
||||
// Homunculus [albator]
|
||||
if (sd->status.hom_id > 0)
|
||||
intif_homunculus_requestload(sd->status.account_id, sd->status.hom_id);
|
||||
|
||||
// パ?ティ、ギルドデ?タの要求
|
||||
if (sd->status.party_id > 0 && party_search(sd->status.party_id) == NULL)
|
||||
party_request_info(sd->status.party_id);
|
||||
@ -3257,6 +3262,10 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
|
||||
unit_remove_map(&sd->pd->bl, clrtype);
|
||||
intif_save_petdata(sd->status.account_id,&sd->pet);
|
||||
}
|
||||
if(sd->status.hom_id > 0 && sd->hd) { //orn
|
||||
unit_remove_map(&sd->hd->bl, clrtype);
|
||||
intif_homunculus_requestsave(sd->status.account_id, &sd->homunculus);
|
||||
}
|
||||
chrif_save(sd,2);
|
||||
chrif_changemapserver(sd, mapindex, x, y, ip, (short)port);
|
||||
return 0;
|
||||
@ -3289,6 +3298,8 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
|
||||
unit_remove_map(&sd->bl, clrtype);
|
||||
if(sd->status.pet_id > 0 && sd->pd)
|
||||
unit_remove_map(&sd->pd->bl, clrtype);
|
||||
if(sd->status.hom_id > 0 && sd->hd) //orn
|
||||
unit_remove_map(&sd->hd->bl, clrtype);
|
||||
clif_changemap(sd,map[m].index,x,y); // [MouseJstr]
|
||||
} else if(sd->state.auth)
|
||||
//Tag player for rewarping after map-loading is done. [Skotlex]
|
||||
@ -3306,6 +3317,13 @@ int pc_setpos(struct map_session_data *sd,unsigned short mapindex,int x,int y,in
|
||||
sd->pd->ud.dir = sd->ud.dir;
|
||||
}
|
||||
|
||||
if(sd->status.hom_id > 0 && sd->hd ) { //orn
|
||||
sd->hd->bl.m = m;
|
||||
sd->hd->bl.x = sd->hd->ud.to_x = x;
|
||||
sd->hd->bl.y = sd->hd->ud.to_y = y;
|
||||
sd->hd->ud.dir = sd->ud.dir;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4717,6 +4735,14 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
|
||||
pet_unlocktarget(sd->pd);
|
||||
}
|
||||
|
||||
if(sd->status.hom_id > 0 && sd->hd) //orn
|
||||
{
|
||||
merc_stop_walking(sd->hd, 1) ;
|
||||
merc_stop_attack(sd->hd) ;
|
||||
merc_hom_delete(sd->hd,0);
|
||||
}
|
||||
|
||||
|
||||
// Leave duel if you die [LuzZza]
|
||||
if(battle_config.duel_autoleave_when_die) {
|
||||
if(sd->duel_group > 0)
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "mob.h"
|
||||
#include "npc.h"
|
||||
#include "pet.h"
|
||||
#include "mercenary.h" //[orn]
|
||||
#include "intif.h"
|
||||
#include "skill.h"
|
||||
#include "chat.h"
|
||||
@ -441,6 +442,7 @@ int buildin_getvariableofnpc(struct script_state *st);
|
||||
// [blackhole89] -->
|
||||
int buildin_warpportal(struct script_state *st);
|
||||
// <-- [blackhole89]
|
||||
int buildin_homunculus_evolution(struct script_state *st) ; //[orn]
|
||||
void push_val(struct script_stack *stack,int type,int val);
|
||||
int run_func(struct script_state *st);
|
||||
|
||||
@ -785,6 +787,7 @@ struct {
|
||||
// [blackhole89] -->
|
||||
{buildin_warpportal,"warpportal","iisii"},
|
||||
// <--- [blackhole89]
|
||||
{buildin_homunculus_evolution,"homevolution",""}, //[orn]
|
||||
{NULL,NULL,NULL},
|
||||
};
|
||||
|
||||
@ -6516,6 +6519,21 @@ int buildin_catchpet(struct script_state *st)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* [orn]
|
||||
*------------------------------------------
|
||||
*/
|
||||
int buildin_homunculus_evolution(struct script_state *st)
|
||||
{
|
||||
struct map_session_data *sd;
|
||||
sd=script_rid2sd(st);
|
||||
if ( sd->hd && sd->hd->homunculusDB->evo_class && sd->homunculus.intimacy > 91000 ) {
|
||||
return merc_hom_evolution(sd->hd) ;
|
||||
}
|
||||
clif_emotion(&sd->hd->bl, 4) ; //swt
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
*Œg‘Ñ—‘›z‰»‹@Žg—p
|
||||
*------------------------------------------
|
||||
@ -10388,7 +10406,7 @@ int buildin_rid2name(struct script_state *st){
|
||||
push_str(st->stack,C_CONSTSTR,((struct pet_data *)bl)->name);
|
||||
break;
|
||||
case BL_HOMUNCULUS:
|
||||
push_str(st->stack,C_CONSTSTR,((struct homun_data *)bl)->name);
|
||||
push_str(st->stack,C_CONSTSTR,((struct homun_data *)bl)->master->homunculus.name);
|
||||
break;
|
||||
default:
|
||||
ShowError("buildin_rid2name: BL type unknown.\n");
|
||||
@ -10810,7 +10828,7 @@ int buildin_unittalk(struct script_state *st)
|
||||
memcpy(message, ((TBL_NPC *)bl)->name, NAME_LENGTH);
|
||||
break;
|
||||
case BL_HOMUNCULUS:
|
||||
memcpy(message, ((TBL_HOMUNCULUS *)bl)->name, NAME_LENGTH);
|
||||
memcpy(message, ((TBL_HOMUNCULUS *)bl)->master->homunculus.name, NAME_LENGTH);
|
||||
break;
|
||||
case BL_PET:
|
||||
memcpy(message, ((TBL_PET *)bl)->name, NAME_LENGTH);
|
||||
|
382
src/map/skill.c
382
src/map/skill.c
@ -20,6 +20,7 @@
|
||||
#include "pc.h"
|
||||
#include "status.h"
|
||||
#include "pet.h"
|
||||
#include "mercenary.h" //[orn]
|
||||
#include "mob.h"
|
||||
#include "battle.h"
|
||||
#include "party.h"
|
||||
@ -706,6 +707,8 @@ const char* skill_get_name( int id ){
|
||||
return "UNKNOWN_SKILL";
|
||||
if (id >= GD_SKILLBASE)
|
||||
id = GD_SKILLRANGEMIN + id - GD_SKILLBASE;
|
||||
if (id >= HM_SKILLBASE) //[orn]
|
||||
id = HM_SKILLRANGEMIN + id - HM_SKILLBASE;
|
||||
if (id < 1 || id > MAX_SKILL_DB || skill_db[id].name==NULL)
|
||||
return "UNKNOWN_SKILL"; //Can't use skill_chk because we return a string.
|
||||
return skill_db[id].name;
|
||||
@ -809,6 +812,8 @@ int skill_calc_heal (struct block_list *bl, int skill_lv)
|
||||
if(bl->type == BL_PC && (skill = pc_checkskill((TBL_PC*)bl, HP_MEDITATIO)) > 0)
|
||||
heal += heal * skill * 2 / 100;
|
||||
|
||||
if(bl->type == BL_HOMUNCULUS && (skill = merc_hom_checkskill( ((TBL_HOMUNCULUS*)bl)->master, HLIF_BRAIN)) > 0) //[orn]
|
||||
heal += heal * skill * 2 / 100;
|
||||
return heal;
|
||||
}
|
||||
|
||||
@ -846,6 +851,8 @@ int skillnotok (int skillid, struct map_session_data *sd)
|
||||
|
||||
if (i >= GD_SKILLBASE)
|
||||
i = GD_SKILLRANGEMIN + i - GD_SKILLBASE;
|
||||
if (i >= HM_SKILLBASE) //[orn]
|
||||
i = HM_SKILLRANGEMIN + i - HM_SKILLBASE;
|
||||
|
||||
if (i > MAX_SKILL || i < 0)
|
||||
return 1;
|
||||
@ -919,6 +926,49 @@ int skillnotok (int skillid, struct map_session_data *sd)
|
||||
return (map[sd->bl.m].flag.noskill);
|
||||
}
|
||||
|
||||
// [orn] - skill ok to cast? and when? //homunculus
|
||||
int skillnotok_hom (int skillid, struct homun_data *hd)
|
||||
{
|
||||
int i = skillid;
|
||||
nullpo_retr (1, hd);
|
||||
//if (sd == 0)
|
||||
//return 0;
|
||||
//return 1;
|
||||
// I think it was meant to be "no skills allowed when not a valid sd"
|
||||
|
||||
if (skillid >= GD_SKILLRANGEMIN && skillid <= GD_SKILLRANGEMAX)
|
||||
return 1;
|
||||
|
||||
if (i >= GD_SKILLBASE)
|
||||
i = GD_SKILLRANGEMIN + i - GD_SKILLBASE;
|
||||
if (i >= HM_SKILLBASE) //[orn]
|
||||
i = HM_SKILLRANGEMIN + i - HM_SKILLBASE;
|
||||
|
||||
if (i > MAX_SKILL || i < 0)
|
||||
return 1;
|
||||
|
||||
if (hd->blockskill[i] > 0)
|
||||
return 1;
|
||||
|
||||
// Check skill restrictions [Celest]
|
||||
if(!map_flag_vs(hd->bl.m) && skill_get_nocast (skillid) & 1)
|
||||
return 1;
|
||||
if(map[hd->bl.m].flag.pvp) {
|
||||
if(!battle_config.pk_mode && skill_get_nocast (skillid) & 2)
|
||||
return 1;
|
||||
if(battle_config.pk_mode && skill_get_nocast (skillid) & 16)
|
||||
return 1;
|
||||
}
|
||||
if(map_flag_gvg(hd->bl.m) && skill_get_nocast (skillid) & 4)
|
||||
return 1;
|
||||
if(agit_flag && skill_get_nocast (skillid) & 8)
|
||||
return 1;
|
||||
if(map[hd->bl.m].flag.restricted && map[hd->bl.m].zone && skill_get_nocast (skillid) & (8*map[hd->bl.m].zone))
|
||||
return 1;
|
||||
|
||||
return (map[hd->bl.m].flag.noskill);
|
||||
}
|
||||
|
||||
/* スキルユニットの配置情報を返す */
|
||||
struct skill_unit_layout skill_unit_layout[MAX_SKILL_UNIT_LAYOUT];
|
||||
int firewall_unit_pos;
|
||||
@ -2263,6 +2313,99 @@ int skill_guildaura_sub (struct block_list *bl, va_list ap)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* [orn]
|
||||
* Checks that you have the requirements for casting a skill for homunculus.
|
||||
* Flag:
|
||||
* &1: finished casting the skill (invoke hp/sp/item consumption)
|
||||
* &2: picked menu entry (Warp Portal, Teleport and other menu based skills)
|
||||
*------------------------------------------
|
||||
*/
|
||||
static int skill_check_condition_hom (struct homun_data *hd, int skill, int lv, int type)
|
||||
{
|
||||
struct status_data *status;
|
||||
struct status_change *sc;
|
||||
int j,hp,sp,hp_rate,sp_rate,state,mhp ;
|
||||
|
||||
nullpo_retr(0, hd);
|
||||
|
||||
if (lv <= 0) return 0;
|
||||
|
||||
status = &hd->battle_status;
|
||||
sc = &hd->sc;
|
||||
if (!sc->count)
|
||||
sc = NULL;
|
||||
|
||||
// for the guild skills [celest]
|
||||
if (skill >= HM_SKILLBASE) //[orn]
|
||||
j = HM_SKILLRANGEMIN + skill - HM_SKILLBASE;
|
||||
else
|
||||
j = skill;
|
||||
if (j < 0 || j >= MAX_SKILL_DB)
|
||||
return 0;
|
||||
//Code speedup, rather than using skill_get_* over and over again.
|
||||
if (lv < 1 || lv > MAX_SKILL_LEVEL)
|
||||
return 0;
|
||||
hp = skill_db[j].hp[lv-1];
|
||||
sp = skill_db[j].sp[lv-1];
|
||||
hp_rate = skill_db[j].hp_rate[lv-1];
|
||||
sp_rate = skill_db[j].sp_rate[lv-1];
|
||||
state = skill_db[j].state;
|
||||
mhp = skill_db[j].mhp[lv-1];
|
||||
if(mhp > 0)
|
||||
hp += (status->max_hp * mhp)/100;
|
||||
if(hp_rate > 0)
|
||||
hp += (status->hp * hp_rate)/100;
|
||||
else
|
||||
hp += (status->max_hp * (-hp_rate))/100;
|
||||
if(sp_rate > 0)
|
||||
sp += (status->sp * sp_rate)/100;
|
||||
else
|
||||
sp += (status->max_sp * (-sp_rate))/100;
|
||||
|
||||
switch(skill) { // Check for cost reductions due to skills & SCs
|
||||
case HFLI_SBR44:
|
||||
if(hd->master->homunculus.intimacy < 200)
|
||||
return 0;
|
||||
break;
|
||||
case HVAN_EXPLOSION:
|
||||
if(hd->master->homunculus.intimacy < battle_config.hvan_explosion_intimate)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
if(!(type&2)){
|
||||
if( hp>0 && status->hp <= (unsigned int)hp) {
|
||||
clif_skill_fail(hd->master,skill,2,0);
|
||||
return 0;
|
||||
}
|
||||
if( sp>0 && status->sp < (unsigned int)sp) {
|
||||
clif_skill_fail(hd->master,skill,1,0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch(state) {
|
||||
case ST_MOVE_ENABLE:
|
||||
//Check only on begin casting. [Skotlex]
|
||||
if(!type && !unit_can_move(&hd->bl)) {
|
||||
clif_skill_fail(hd->master,skill,0,0);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(!(type&1))
|
||||
return 1;
|
||||
|
||||
if(type&2)
|
||||
return 1;
|
||||
|
||||
if(sp || hp)
|
||||
status_zap(&hd->bl, hp, sp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*=========================================================================
|
||||
* 範囲スキル使用処理小分けここから
|
||||
*/
|
||||
@ -2454,6 +2597,7 @@ static int skill_reveal_trap (struct block_list *bl, va_list ap)
|
||||
int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int skillid, int skilllv, unsigned int tick, int flag)
|
||||
{
|
||||
struct map_session_data *sd = NULL, *tsd = NULL;
|
||||
struct homun_data *hd = NULL ; //[orn]
|
||||
struct status_data *tstatus;
|
||||
struct status_change *sc;
|
||||
|
||||
@ -2472,6 +2616,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
|
||||
sd = (struct map_session_data *)src;
|
||||
if (bl->type == BL_PC)
|
||||
tsd = (struct map_session_data *)bl;
|
||||
if (bl->type == BL_HOMUNCULUS) //[orn]
|
||||
hd = (struct homun_data *)bl;
|
||||
|
||||
if (status_isdead(src) || (src != bl && status_isdead(bl)))
|
||||
return 1;
|
||||
@ -2568,6 +2714,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
|
||||
case TK_DOWNKICK:
|
||||
case TK_COUNTER:
|
||||
case ASC_BREAKER:
|
||||
case HFLI_MOON: //[orn]
|
||||
case HFLI_SBR44: //[orn]
|
||||
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
|
||||
break;
|
||||
|
||||
@ -2725,8 +2873,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
|
||||
skill_castend_damage_id);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SM_MAGNUM:
|
||||
if(flag&1)
|
||||
skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
|
||||
@ -2974,6 +3120,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
|
||||
case TF_THROWSTONE:
|
||||
case NPC_SMOKING:
|
||||
case NPC_SELFDESTRUCTION:
|
||||
case HVAN_EXPLOSION: //[orn]
|
||||
case GS_FLING:
|
||||
case NJ_ZENYNAGE:
|
||||
skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
|
||||
@ -3112,6 +3259,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
|
||||
int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, int skillid, int skilllv, unsigned int tick, int flag)
|
||||
{
|
||||
struct map_session_data *sd = NULL;
|
||||
struct homun_data *hd = NULL;
|
||||
struct map_session_data *dstsd = NULL;
|
||||
struct status_data *sstatus, *tstatus;
|
||||
struct status_change *tsc;
|
||||
@ -3129,6 +3277,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
|
||||
|
||||
if (src->type == BL_PC) {
|
||||
sd = (struct map_session_data *)src;
|
||||
} else if (src->type == BL_HOMUNCULUS) { //[orn]
|
||||
hd = (struct homun_data *)src;
|
||||
} else if (src->type == BL_MOB) {
|
||||
md = (struct mob_data *)src;
|
||||
}
|
||||
@ -3151,7 +3301,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
|
||||
|
||||
//Check for undead skills that convert a no-damage skill into a damage one. [Skotlex]
|
||||
switch (skillid) {
|
||||
case AL_HEAL:
|
||||
case HLIF_HEAL: //[orn]
|
||||
if ( !hd ) {
|
||||
clif_skill_fail(hd->master,skillid,0,0) ;
|
||||
break ;
|
||||
}
|
||||
case AL_HEAL:
|
||||
case ALL_RESURRECTION:
|
||||
case PR_ASPERSIO:
|
||||
if (battle_check_undead(tstatus->race,tstatus->def_ele)) {
|
||||
@ -3184,6 +3339,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
|
||||
map_freeblock_lock();
|
||||
switch(skillid)
|
||||
{
|
||||
case HLIF_HEAL: //[orn]
|
||||
case AL_HEAL: /* ヒール */
|
||||
{
|
||||
int heal = skill_calc_heal(src, skilllv);
|
||||
@ -3971,6 +4127,19 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
|
||||
skill_castend_damage_id);
|
||||
status_damage(src, src, sstatus->max_hp,0,0,1);
|
||||
break;
|
||||
case HVAN_EXPLOSION: //[orn]
|
||||
ShowDebug("skill_castend_nodamage_id : intimacy = %d\n", hd->master->homunculus.intimacy) ; //ORN DEBUG
|
||||
clif_skill_nodamage(src, src, skillid, -1, 1);
|
||||
map_foreachinrange(skill_area_sub, bl,
|
||||
skill_get_splash(skillid, skilllv), BL_CHAR,
|
||||
src, skillid, skilllv, tick, flag|BCT_ENEMY,
|
||||
skill_castend_damage_id);
|
||||
if(hd){
|
||||
hd->master->homunculus.intimacy = 200;
|
||||
clif_send_homdata(hd->master,0x100,hd->master->homunculus.intimacy/100);
|
||||
}
|
||||
status_damage(src, src, sstatus->max_hp,0,0,1);
|
||||
break;
|
||||
|
||||
/* パーティスキル */
|
||||
case AL_ANGELUS: /* エンジェラス */
|
||||
@ -5397,6 +5566,149 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
|
||||
pc_delspiritball(sd,1,0);
|
||||
}
|
||||
break;
|
||||
|
||||
case AM_CALLHOMUN: //[orn]
|
||||
{
|
||||
int i = 0;
|
||||
if (sd && (sd->status.hom_id == 0 || sd->homunculus.vaporize == 1)) {
|
||||
if (sd->status.hom_id == 0) {
|
||||
i = pc_search_inventory(sd,7142);
|
||||
if(i < 0) {
|
||||
clif_skill_fail(sd,skillid,0,0);
|
||||
break ;
|
||||
}
|
||||
pc_delitem(sd,i,1,0);
|
||||
}
|
||||
if (merc_call_homunculus(sd))
|
||||
break;
|
||||
}
|
||||
|
||||
clif_skill_fail(sd,skillid,0,0);
|
||||
break;
|
||||
}
|
||||
case AM_REST: //[orn]
|
||||
{
|
||||
if (sd && sd->hd && ( sd->hd->battle_status.hp >= (sd->hd->battle_status.max_hp * 80 / 100 ) ) ) {
|
||||
sd->homunculus.vaporize = 1;
|
||||
merc_hom_delete(sd->hd, 0) ;
|
||||
} else if ( sd )
|
||||
{
|
||||
clif_skill_fail(sd,skillid,0,0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case AM_RESURRECTHOMUN: //[orn]
|
||||
{
|
||||
if ( sd && sd->status.hom_id ) {
|
||||
if( map_flag_gvg(bl->m) )
|
||||
{ //No reviving in WoE grounds!
|
||||
clif_skill_fail(sd,skillid,0,0);
|
||||
break;
|
||||
}
|
||||
if ( sd->homunculus.alive == 0 ) {
|
||||
int per = 10 * skilllv;
|
||||
|
||||
if (merc_hom_revive(sd, per) )
|
||||
{
|
||||
clif_skill_nodamage(src,&sd->hd->bl,AM_RESURRECTHOMUN,skilllv,1);
|
||||
} else {
|
||||
clif_skill_fail(sd,skillid,0,0);
|
||||
}
|
||||
} else {
|
||||
clif_skill_fail(sd,skillid,0,0);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case HAMI_CASTLE: //[orn]
|
||||
{
|
||||
if(hd && rand()%100 < 20*skilllv)
|
||||
{
|
||||
int x,y;
|
||||
struct walkpath_data wpd;
|
||||
struct map_session_data *sd = hd->master;
|
||||
if( path_search(&wpd,hd->bl.m,hd->bl.x,hd->bl.y,sd->bl.x,sd->bl.y,0) != 0 ) {
|
||||
clif_skill_fail(sd,skillid,0,0);
|
||||
break;
|
||||
}
|
||||
|
||||
clif_skill_nodamage(&hd->bl,&sd->bl,skillid,skilllv,1);
|
||||
|
||||
x = hd->bl.x;
|
||||
y = hd->bl.y;
|
||||
|
||||
unit_movepos(&hd->bl,sd->bl.x,sd->bl.y,0,0);
|
||||
unit_movepos(&sd->bl,x,y,0,0);
|
||||
clif_fixpos(&hd->bl) ;
|
||||
clif_fixpos(&sd->bl) ;
|
||||
|
||||
map_foreachinarea(skill_chastle_mob_changetarget,hd->bl.m,
|
||||
hd->bl.x-AREA_SIZE,hd->bl.y-AREA_SIZE,
|
||||
hd->bl.x+AREA_SIZE,hd->bl.y+AREA_SIZE,
|
||||
BL_MOB,&hd->master->bl,&hd->bl);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HVAN_CHAOTIC: //[orn]
|
||||
{
|
||||
if(hd){
|
||||
//HOM,PC,MOB
|
||||
struct block_list* heal_target=NULL;
|
||||
int heal = skill_calc_heal( src, 1+rand()%skilllv );
|
||||
static const int per[10][2]={{20,50},{50,60},{25,75},{60,64},{34,67},
|
||||
{34,67},{34,67},{34,67},{34,67},{34,67}};
|
||||
int rnd = rand()%100;
|
||||
if(rnd<per[skilllv-1][0])
|
||||
{
|
||||
heal_target = &hd->bl;
|
||||
}else if(rnd<per[skilllv-1][1])
|
||||
{
|
||||
if(!status_isdead(&hd->master->bl))
|
||||
heal_target = &hd->master->bl;
|
||||
else
|
||||
heal_target = &hd->bl;
|
||||
}else{//MOB
|
||||
heal_target = map_id2bl(hd->target_id);
|
||||
if(heal_target==NULL)
|
||||
heal_target = &hd->bl;
|
||||
}
|
||||
clif_skill_nodamage(src,heal_target,AL_HEAL,heal,1);
|
||||
clif_skill_nodamage(src,heal_target,skillid,heal,1);
|
||||
status_heal(heal_target, heal, 0, 0);
|
||||
skill_blockmerc_start(hd, skillid, skill_get_time2(skillid,skilllv)) ;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HLIF_AVOID: //[orn]
|
||||
case HAMI_DEFENCE: //[orn]
|
||||
if ( hd ) {
|
||||
clif_skill_nodamage(src,&hd->master->bl,skillid,skilllv,
|
||||
sc_start(&hd->master->bl,type,100,skilllv,skill_get_time(skillid,skilllv))) ;
|
||||
}
|
||||
case HAMI_BLOODLUST: //[orn]
|
||||
case HFLI_FLEET: //[orn]
|
||||
case HFLI_SPEED: //[orn]
|
||||
if ( hd ) {
|
||||
clif_skill_nodamage(src,bl,skillid,skilllv,
|
||||
sc_start(&hd->bl,type,100,skilllv,skill_get_time(skillid,skilllv))) ;
|
||||
skill_blockmerc_start(hd, skillid, skill_get_time2(skillid,skilllv)) ;
|
||||
}
|
||||
else
|
||||
clif_skill_fail(hd->master,skillid,0,0);
|
||||
break;
|
||||
case HLIF_CHANGE: //[orn]
|
||||
if ( hd ) {
|
||||
clif_skill_nodamage(src,bl,skillid,skilllv,
|
||||
sc_start(&hd->bl,type,100,skilllv,skill_get_time(skillid,skilllv))) ;
|
||||
status_heal(&hd->bl, hd->master->homunculus.max_hp, 0, 0);
|
||||
skill_blockmerc_start(hd, skillid, skill_get_time2(skillid,skilllv)) ;
|
||||
}
|
||||
else
|
||||
clif_skill_fail(hd->master,skillid,0,0);
|
||||
break;
|
||||
|
||||
default:
|
||||
ShowWarning("skill_castend_nodamage_id: Unknown skill used:%d\n",skillid);
|
||||
@ -5421,6 +5733,7 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data)
|
||||
{
|
||||
struct block_list *target, *src = map_id2bl(id);
|
||||
struct map_session_data* sd = NULL;
|
||||
struct homun_data* hd = NULL; //[orn]
|
||||
struct mob_data* md = NULL;
|
||||
struct unit_data* ud = unit_bl2ud(src);
|
||||
struct status_change *sc;
|
||||
@ -5429,6 +5742,7 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data)
|
||||
nullpo_retr(0, ud);
|
||||
|
||||
BL_CAST( BL_PC, src, sd);
|
||||
BL_CAST( BL_HOMUNCULUS, src, hd); //[orn]
|
||||
BL_CAST( BL_MOB, src, md);
|
||||
|
||||
if( src->prev == NULL ) {
|
||||
@ -5538,6 +5852,9 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data)
|
||||
if(sd && !skill_check_condition(sd,ud->skillid, ud->skilllv,1)) /* 使用条件チェック */
|
||||
break;
|
||||
|
||||
if(hd && !skill_check_condition_hom(hd,ud->skillid, ud->skilllv,1)) //[orn]
|
||||
break;
|
||||
|
||||
if (ud->walktimer != -1 && ud->skillid != TK_RUN)
|
||||
unit_stop_walking(src,1);
|
||||
|
||||
@ -5585,12 +5902,14 @@ int skill_castend_pos (int tid, unsigned int tick, int id, int data)
|
||||
struct block_list* src = map_id2bl(id);
|
||||
int maxcount;
|
||||
struct map_session_data *sd = NULL;
|
||||
struct homun_data *hd = NULL; //[orn]
|
||||
struct unit_data *ud = unit_bl2ud(src);
|
||||
struct mob_data *md = NULL;
|
||||
|
||||
nullpo_retr(0, ud);
|
||||
|
||||
BL_CAST( BL_PC , src, sd);
|
||||
BL_CAST( BL_HOMUNCULUS , src, hd); //[orn]
|
||||
BL_CAST( BL_MOB, src, md);
|
||||
|
||||
if( src->prev == NULL ) {
|
||||
@ -5651,6 +5970,9 @@ int skill_castend_pos (int tid, unsigned int tick, int id, int data)
|
||||
if(sd && !skill_check_condition(sd,ud->skillid, ud->skilllv, 1)) /* 使用条件チェック */
|
||||
break;
|
||||
|
||||
if(hd && !skill_check_condition_hom(hd,ud->skillid, ud->skilllv, 1)) //[orn]
|
||||
break;
|
||||
|
||||
if(md) {
|
||||
md->last_thinktime=tick + (tid==-1?md->status.adelay:md->status.amotion);
|
||||
if(md->skillidx >= 0) {
|
||||
@ -7586,6 +7908,8 @@ int skill_check_condition (struct map_session_data *sd, int skill, int lv, int t
|
||||
// for the guild skills [celest]
|
||||
if (skill >= GD_SKILLBASE)
|
||||
j = GD_SKILLRANGEMIN + skill - GD_SKILLBASE;
|
||||
else if (skill >= HM_SKILLBASE) //[orn]
|
||||
j = HM_SKILLRANGEMIN + skill - HM_SKILLBASE;
|
||||
else
|
||||
j = skill;
|
||||
if (j < 0 || j >= MAX_SKILL_DB)
|
||||
@ -9034,6 +9358,23 @@ int skill_ganbatein (struct block_list *bl, va_list ap)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* キャスリングのターゲット変更
|
||||
*------------------------------------------
|
||||
*/
|
||||
int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap)
|
||||
{
|
||||
struct mob_data* md;
|
||||
struct block_list *from_bl;
|
||||
struct block_list *to_bl;
|
||||
nullpo_retr(0, md = (struct mob_data*)bl);
|
||||
nullpo_retr(0, from_bl = va_arg(ap,struct block_list *));
|
||||
nullpo_retr(0, to_bl = va_arg(ap,struct block_list *));
|
||||
if(md->target_id == from_bl->id)
|
||||
md->target_id = to_bl->id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* 指定範囲内でsrcに対して有効なターゲットのblの数を数える(foreachinarea)
|
||||
*------------------------------------------
|
||||
@ -10303,6 +10644,8 @@ int skill_blockpc_start(struct map_session_data *sd, int skillid, int tick)
|
||||
|
||||
if (skillid >= GD_SKILLBASE)
|
||||
skillid = GD_SKILLRANGEMIN + skillid - GD_SKILLBASE;
|
||||
if (skillid >= HM_SKILLBASE) //[orn]
|
||||
skillid = HM_SKILLRANGEMIN + skillid - HM_SKILLBASE;
|
||||
if (skillid < 1 || skillid > MAX_SKILL)
|
||||
return -1;
|
||||
|
||||
@ -10310,6 +10653,31 @@ int skill_blockpc_start(struct map_session_data *sd, int skillid, int tick)
|
||||
return add_timer(gettick()+tick,skill_blockpc_end,sd->bl.id,skillid);
|
||||
}
|
||||
|
||||
int skill_blockmerc_end (int tid, unsigned int tick, int id, int data) //[orn]
|
||||
{
|
||||
struct homun_data *hd = (TBL_HOMUNCULUS*) map_id2bl(id);
|
||||
if (data <= 0 || data >= MAX_SKILL)
|
||||
return 0;
|
||||
if (hd) hd->blockskill[data] = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int skill_blockmerc_start(struct homun_data *hd, int skillid, int tick) //[orn]
|
||||
{
|
||||
nullpo_retr (-1, hd);
|
||||
|
||||
if (skillid >= GD_SKILLBASE)
|
||||
skillid = GD_SKILLRANGEMIN + skillid - GD_SKILLBASE;
|
||||
if (skillid >= HM_SKILLBASE) //[orn]
|
||||
skillid = HM_SKILLRANGEMIN + skillid - HM_SKILLBASE;
|
||||
if (skillid < 1 || skillid > MAX_SKILL)
|
||||
return -1;
|
||||
|
||||
hd->blockskill[skillid] = 1;
|
||||
return add_timer(gettick()+tick,skill_blockmerc_end,hd->bl.id,skillid);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* 初期化系
|
||||
@ -10641,6 +11009,8 @@ int skill_readdb (void)
|
||||
}
|
||||
if (i >= GD_SKILLBASE)
|
||||
i = GD_SKILLRANGEMIN + i - GD_SKILLBASE;
|
||||
if (i >= HM_SKILLBASE) //[orn]
|
||||
i = HM_SKILLRANGEMIN + i - HM_SKILLBASE;
|
||||
if(i<=0 || i>MAX_SKILL_DB)
|
||||
continue;
|
||||
|
||||
@ -10697,6 +11067,8 @@ int skill_readdb (void)
|
||||
i=atoi(split[0]);
|
||||
if (i >= GD_SKILLBASE)
|
||||
i = GD_SKILLRANGEMIN + i - GD_SKILLBASE;
|
||||
if (i >= HM_SKILLBASE) //[orn]
|
||||
i = HM_SKILLRANGEMIN + i - HM_SKILLBASE;
|
||||
if(i<=0 || i>MAX_SKILL_DB)
|
||||
continue;
|
||||
|
||||
@ -10784,6 +11156,8 @@ int skill_readdb (void)
|
||||
i=atoi(split[0]);
|
||||
if (i >= GD_SKILLBASE)
|
||||
i = GD_SKILLRANGEMIN + i - GD_SKILLBASE;
|
||||
if (i >= HM_SKILLBASE) //[orn]
|
||||
i = HM_SKILLRANGEMIN + i - HM_SKILLBASE;
|
||||
if(i<=0 || i>MAX_SKILL_DB)
|
||||
continue;
|
||||
|
||||
@ -10816,6 +11190,8 @@ int skill_readdb (void)
|
||||
i=atoi(split[0]);
|
||||
if (i >= GD_SKILLBASE)
|
||||
i = GD_SKILLRANGEMIN + i - GD_SKILLBASE;
|
||||
if (i >= HM_SKILLBASE) //[orn]
|
||||
i = HM_SKILLRANGEMIN + i - HM_SKILLBASE;
|
||||
if(i<=0 || i>MAX_SKILL_DB)
|
||||
continue;
|
||||
skill_db[i].unit_id[0] = strtol(split[1],NULL,16);
|
||||
|
@ -237,6 +237,8 @@ int skill_check_cloaking(struct block_list *bl, struct status_change *sc);
|
||||
// ステ?タス異常
|
||||
int skill_enchant_elemental_end(struct block_list *bl, int type);
|
||||
int skillnotok(int skillid, struct map_session_data *sd);
|
||||
int skillnotok_hom (int skillid, struct homun_data *hd) ; //[orn]
|
||||
int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap); //[orn]
|
||||
|
||||
// アイテム作成
|
||||
int skill_can_produce_mix( struct map_session_data *sd, int nameid, int trigger, int qty);
|
||||
@ -250,6 +252,7 @@ int skill_castend_nodamage_id( struct block_list *src, struct block_list *bl,int
|
||||
int skill_castend_damage_id( struct block_list* src, struct block_list *bl,int skillid,int skilllv,unsigned int tick,int flag );
|
||||
int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skilllv,unsigned int tick,int flag);
|
||||
int skill_blockpc_start (struct map_session_data*,int,int); // [celest]
|
||||
int skill_blockmerc_start (struct homun_data*,int,int); //[orn]
|
||||
|
||||
// スキル攻?一括?理
|
||||
int skill_attack( int attack_type, struct block_list* src, struct block_list *dsrc,
|
||||
|
410
src/map/status.c
410
src/map/status.c
@ -54,13 +54,14 @@ int current_equip_item_index; //Contains inventory index of an equipped item. To
|
||||
int current_equip_card_id; //To prevent card-stacking (from jA) [Skotlex]
|
||||
//we need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only
|
||||
//to avoid cards exploits
|
||||
void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag); //[orn]
|
||||
|
||||
static void add_sc(int skill, int sc)
|
||||
{
|
||||
int sk = skill;
|
||||
if (sk > GD_SKILLBASE) sk = skill - GD_SKILLBASE + SC_GD_BASE;
|
||||
else
|
||||
if (sk > HM_SKILLBASE) sk = skill - HM_SKILLBASE + SC_HM_BASE;
|
||||
if (sk >= HM_SKILLBASE) sk = skill - HM_SKILLBASE + SC_HM_BASE;
|
||||
if (sk < 0 || sk >= MAX_SKILL) {
|
||||
if (battle_config.error_log)
|
||||
ShowError("add_sc: Unsupported skill id %d\n", skill);
|
||||
@ -374,6 +375,8 @@ void initChangeTables(void) {
|
||||
set_sc(HLIF_CHANGE, SC_CHANGE, SI_BLANK, SCB_INT);
|
||||
set_sc(HAMI_BLOODLUST, SC_BLOODLUST, SI_BLANK, SCB_BATK|SCB_WATK);
|
||||
set_sc(HFLI_FLEET, SC_FLEET, SI_BLANK, SCB_ASPD|SCB_BATK|SCB_WATK);
|
||||
set_sc(HFLI_SPEED, SC_SPEED, SI_BLANK, SCB_FLEE); //[orn]
|
||||
set_sc(HAMI_DEFENCE, SC_DEFENCE, SI_BLANK, SCB_DEF); //[orn]
|
||||
|
||||
set_sc(GD_LEADERSHIP, SC_GUILDAURA, SI_GUILDAURA, SCB_STR|SCB_AGI|SCB_VIT|SCB_DEX);
|
||||
set_sc(GD_BATTLEORDER, SC_BATTLEORDERS, SI_BATTLEORDERS, SCB_STR|SCB_INT|SCB_DEX);
|
||||
@ -452,7 +455,7 @@ int SkillStatusChangeTable(int skill)
|
||||
int sk = skill;
|
||||
if (sk > GD_SKILLBASE) sk = skill - GD_SKILLBASE + SC_GD_BASE;
|
||||
else
|
||||
if (sk > HM_SKILLBASE) sk = skill - HM_SKILLBASE + SC_HM_BASE;
|
||||
if (sk >= HM_SKILLBASE) sk = skill - HM_SKILLBASE + SC_HM_BASE;
|
||||
if (sk < 0 || sk >= MAX_SKILL) {
|
||||
if (battle_config.error_log)
|
||||
ShowError("add_sc: Unsupported skill id %d\n", skill);
|
||||
@ -501,8 +504,8 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
|
||||
struct status_data *status;
|
||||
struct status_change *sc;
|
||||
|
||||
if(sp && target->type != BL_PC)
|
||||
sp = 0; //Only players get SP damage.
|
||||
if(sp && target->type != BL_PC && target->type != BL_HOMUNCULUS) //[orn]
|
||||
sp = 0; //Only players and Homunculus get SP damage.
|
||||
|
||||
if (hp < 0) { //Assume absorbed damage.
|
||||
status_heal(target, -hp, 0, 1);
|
||||
@ -641,7 +644,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
|
||||
flag = pc_dead((TBL_PC*)target,src);
|
||||
break;
|
||||
case BL_HOMUNCULUS:
|
||||
flag = merc_dead((TBL_HOMUNCULUS*)target,src);
|
||||
flag = merc_hom_dead((TBL_HOMUNCULUS*)target,src);
|
||||
break;
|
||||
default: //Unhandled case, do nothing to object.
|
||||
flag = 0;
|
||||
@ -738,7 +741,7 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
|
||||
pc_heal((TBL_PC*)bl,hp,sp,flag&2?1:0);
|
||||
break;
|
||||
case BL_HOMUNCULUS:
|
||||
merc_heal((TBL_HOMUNCULUS*)bl,hp,sp);
|
||||
merc_hom_heal((TBL_HOMUNCULUS*)bl,hp,sp);
|
||||
break;
|
||||
}
|
||||
return hp+sp;
|
||||
@ -819,7 +822,9 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
|
||||
break;
|
||||
case BL_PC:
|
||||
pc_revive((TBL_PC*)bl, hp, sp);
|
||||
break;
|
||||
// case BL_HOMUNCULUS: //[orn]
|
||||
// merc_hom_revive((TBL_HOMUNCULUS*)bl, hp, sp);
|
||||
// break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1360,97 +1365,6 @@ int status_calc_pet(struct pet_data *pd, int first)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int status_calc_homunculus(struct homun_data *hd, int first)
|
||||
{
|
||||
struct status_data *status = &hd->base_status;
|
||||
int lv, i;
|
||||
/* very proprietary */
|
||||
lv=hd->level;
|
||||
memset(status, 0, sizeof(struct status_data));
|
||||
switch(hd->class_)
|
||||
{
|
||||
case 6001: //LIF ~ int,dex,vit
|
||||
status->str = 3+lv/7;
|
||||
status->agi = 3+2*lv/5;
|
||||
status->vit = 4+lv;
|
||||
status->int_ = 4+3*lv/4;
|
||||
status->dex = 4+2*lv/3;
|
||||
status->luk = 3+lv/4;
|
||||
for(i=8001;i<8005;++i)
|
||||
{
|
||||
hd->hskill[i-8001].id=i;
|
||||
//hd->hskill[i-8001].level=1;
|
||||
}
|
||||
break;
|
||||
case 6003: //FILIR ~ str,agi,dex
|
||||
status->str = 4+3*lv/4;
|
||||
status->agi = 4+2*lv/3;
|
||||
status->vit = 3+2*lv/5;
|
||||
status->int_ = 3+lv/4;
|
||||
status->dex = 4+lv;
|
||||
status->luk = 3+lv/7;
|
||||
for(i=8009;i<8013;++i)
|
||||
{
|
||||
hd->hskill[i-8009].id=i;
|
||||
//hd->hskill[i-8009].level=1;
|
||||
}
|
||||
break;
|
||||
case 6002: //AMISTR ~ str,vit,luk
|
||||
status->str = 4+lv;
|
||||
status->agi = 3+lv/4;
|
||||
status->vit = 3+3*lv/4;
|
||||
status->int_ = 3+lv/10;
|
||||
status->dex = 3+2*lv/5;
|
||||
status->luk = 4+2*lv/3;
|
||||
for(i=8005;i<8009;++i)
|
||||
{
|
||||
hd->hskill[i-8005].id=i;
|
||||
//hd->hskill[i-8005].level=1;
|
||||
}
|
||||
break;
|
||||
case 6004: //VANILMIRTH ~ int,dex,luk
|
||||
status->str = 3+lv/4;
|
||||
status->agi = 3+lv/7;
|
||||
status->vit = 3+2*lv/5;
|
||||
status->int_ = 4+lv;
|
||||
status->dex = 4+2*lv/3;
|
||||
status->luk = 4+3*lv/4;
|
||||
for(i=8013;i<8017;++i)
|
||||
{
|
||||
hd->hskill[i-8013].id=i;
|
||||
//hd->hskill[i-8013].level=1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (battle_config.error_log)
|
||||
ShowError("status_calc_homun: Unknown class %d\n", hd->class_);
|
||||
memcpy(status, &dummy_status, sizeof(struct status_data));
|
||||
break;
|
||||
}
|
||||
status->hp = 10; //Revive HP/SP?
|
||||
status->sp = 0;
|
||||
status->max_hp=500+lv*10+lv*lv;
|
||||
status->max_sp=300+lv*11+lv*lv*90/100;
|
||||
status->aspd_rate = 1000;
|
||||
status->speed=0x96;
|
||||
status->batk = status_base_atk(&hd->bl, status);
|
||||
status_calc_misc(status, hd->level);
|
||||
|
||||
// hp recovery
|
||||
hd->regenhp = 1 + (status->vit/5) + (status->max_hp/200);
|
||||
|
||||
// sp recovery
|
||||
hd->regensp = 1 + (status->int_/6) + (status->max_sp/100);
|
||||
if(status->int_ >= 120)
|
||||
hd->regensp += ((status->int_-120)>>1) + 4;
|
||||
|
||||
status->amotion = 1800 - (1800 * status->agi / 250 + 1800 * status->dex / 1000);
|
||||
status->amotion -= 200;
|
||||
status->dmotion=status->amotion;
|
||||
status_calc_bl(&hd->bl, SCB_ALL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned int status_base_pc_maxhp(struct map_session_data* sd, struct status_data *status)
|
||||
{
|
||||
unsigned int val;
|
||||
@ -2230,6 +2144,59 @@ int status_calc_pc(struct map_session_data* sd,int first)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int status_calc_homunculus(struct homun_data *hd, int first)
|
||||
{
|
||||
struct status_data b_status, *status;
|
||||
memcpy(&b_status, &hd->base_status, sizeof(struct status_data));
|
||||
status = &hd->base_status;
|
||||
|
||||
status->def_ele = b_status.def_ele = hd->homunculusDB->element ; //[orn]
|
||||
status->ele_lv = b_status.ele_lv = 1 ; //[orn]
|
||||
status->race = b_status.race = hd->homunculusDB->race ; //[orn]
|
||||
status->size = b_status.size = hd->homunculusDB->size ; //[orn]
|
||||
status->rhw.range = b_status.rhw.range = 1 + hd->homunculusDB->size ; //[orn]
|
||||
status->mode = b_status.mode = MD_CANMOVE|MD_CANATTACK|MD_ASSIST|MD_AGGRESSIVE|MD_CASTSENSOR; //[orn]
|
||||
status->speed = b_status.speed = DEFAULT_WALK_SPEED;
|
||||
status->aspd_rate = b_status.aspd_rate = 1000;
|
||||
|
||||
merc_hom_calc_skilltree(hd->master); //
|
||||
|
||||
status_cpy(&b_status, status);
|
||||
status_calc_misc(status, hd->master->homunculus.level);
|
||||
status_calc_bl(&hd->bl, SCB_ALL); //Status related changes.
|
||||
|
||||
if ( (b_status.str != status->str) ||
|
||||
(b_status.agi != status->agi) ||
|
||||
(b_status.vit != status->vit) ||
|
||||
(b_status.int_ != status->int_) ||
|
||||
(b_status.dex != status->dex) ||
|
||||
(b_status.luk != status->luk) ||
|
||||
(b_status.hit != status->hit) ||
|
||||
(b_status.flee != status->flee) ||
|
||||
(b_status.amotion != status->amotion) ||
|
||||
(b_status.rhw.atk != status->rhw.atk) ||
|
||||
(b_status.def != status->def) ||
|
||||
(b_status.rhw.atk2 != status->rhw.atk2) ||
|
||||
(b_status.def2 != status->def2) ||
|
||||
(b_status.flee2 != status->flee2) ||
|
||||
(b_status.cri != status->cri) ||
|
||||
(b_status.matk_max != status->matk_max) ||
|
||||
(b_status.matk_min != status->matk_min) ||
|
||||
(b_status.mdef != status->mdef) ||
|
||||
(b_status.mdef2 != status->mdef2) ||
|
||||
(b_status.rhw.range != status->rhw.range) ||
|
||||
(b_status.max_hp != status->max_hp) ||
|
||||
(b_status.max_sp != status->max_sp) ||
|
||||
(b_status.hp != status->hp) ||
|
||||
(b_status.sp != status->sp)
|
||||
)
|
||||
{
|
||||
clif_hominfo(hd->master,0) ;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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);
|
||||
@ -2552,12 +2519,210 @@ void status_calc_bl_sub_pc(struct map_session_data *sd, unsigned long flag)
|
||||
clif_updatestatus(sd,SP_MAXSP);
|
||||
}
|
||||
|
||||
//Calculates some attributes that depends on modified stats from status changes.
|
||||
void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag) //[orn]
|
||||
{
|
||||
struct status_data *status = &hd->battle_status, *b_status = &hd->base_status;
|
||||
int skill = 0;
|
||||
|
||||
if(flag&(SCB_MAXHP|SCB_VIT))
|
||||
{
|
||||
flag|=SCB_MAXHP; //Ensures client-side refresh
|
||||
|
||||
// Apply relative modifiers from equipment
|
||||
if(status->max_hp > (unsigned int)battle_config.max_hp)
|
||||
status->max_hp = battle_config.max_hp;
|
||||
else if(!status->max_hp)
|
||||
status->max_hp = 1;
|
||||
|
||||
// hp recovery
|
||||
hd->regenhp = 1 + (status->vit/5) + (status->max_hp/200);
|
||||
|
||||
if(hd->regenhp < 1) hd->regenhp = 1;
|
||||
|
||||
// Skill-related Adamantium Skin
|
||||
if((skill=merc_hom_checkskill(hd->master,HAMI_SKIN)) > 0) {
|
||||
status->max_hp = hd->master->homunculus.max_hp + skill * 2 * hd->master->homunculus.max_hp / 100 ;
|
||||
hd->regenhp += skill * 5 * hd->regenhp / 100 ;
|
||||
}
|
||||
|
||||
status->max_hp = status_calc_maxhp(&hd->bl, &hd->sc, status->max_hp);
|
||||
|
||||
}
|
||||
if(flag&SCB_DEF)
|
||||
{
|
||||
status->def = hd->master->homunculus.level / 10 + status->vit / 5 ;
|
||||
if(hd->sc.data[SC_DEFENCE].timer != -1)
|
||||
status->def += hd->sc.data[SC_DEFENCE].val2;
|
||||
if((skill=merc_hom_checkskill(hd->master,HAMI_SKIN)) > 0) {
|
||||
status->def += skill * 4 ;
|
||||
}
|
||||
}
|
||||
if(flag&(SCB_MAXSP|SCB_INT))
|
||||
{
|
||||
flag|=SCB_MAXSP;
|
||||
|
||||
// Skill-related Instruction Change
|
||||
if((skill = merc_hom_checkskill(hd->master,HVAN_INSTRUCT)) > 0) {
|
||||
if ( skill == 5 ) {
|
||||
status->int_ += 3 ;
|
||||
} else if ( skill == 1 ) {
|
||||
status->int_ += 1 ;
|
||||
} else {
|
||||
status->int_ += 2 ;
|
||||
}
|
||||
if ( skill > 3 ) {
|
||||
status->str += 4 ;
|
||||
} else if ( skill == 3 ) {
|
||||
status->str += 3 ;
|
||||
} else {
|
||||
status->str += 1 ;
|
||||
}
|
||||
}
|
||||
|
||||
if((skill = merc_hom_checkskill(hd->master,HLIF_BRAIN)) > 0) {
|
||||
status->max_sp = hd->master->homunculus.max_sp + skill * 2 * hd->master->homunculus.max_sp / 100 ;
|
||||
hd->regensp += skill * 3 * hd->regensp / 100 ;
|
||||
if ( skill == 5 ) {
|
||||
status->max_sp *= 103 / 100 ;
|
||||
} else if ( skill == 1 ) {
|
||||
status->max_sp *= 101 / 100 ;
|
||||
} else {
|
||||
status->max_sp *= 102 / 100 ;
|
||||
}
|
||||
}
|
||||
|
||||
status->mdef = hd->master->homunculus.level / 10 + status->int_ / 5 ;
|
||||
status->max_sp = status_calc_maxsp(&hd->bl, &hd->sc, status->max_sp);
|
||||
|
||||
if(status->max_sp > (unsigned int)battle_config.max_sp)
|
||||
status->max_sp = battle_config.max_sp;
|
||||
else if(!status->max_sp)
|
||||
status->max_sp = 1;
|
||||
|
||||
if(status->sp > status->max_sp) {
|
||||
status->sp = status->max_sp;
|
||||
}
|
||||
|
||||
// sp recovery
|
||||
hd->regensp = 1 + (status->int_/6) + (status->max_sp/100);
|
||||
if(status->int_ >= 120)
|
||||
hd->regensp += ((status->int_-120)>>1) + 4;
|
||||
|
||||
if(hd->regensp < 1) hd->regensp = 1;
|
||||
|
||||
}
|
||||
|
||||
if(flag&(SCB_BATK|SCB_WATK)) {
|
||||
status->rhw.atk = status->rhw.atk2 = status->str + ( status->str / 10 ) * ( status->str / 10 ) ;
|
||||
status->rhw.atk += status->dex ;
|
||||
if ( (status->str + hd->master->homunculus.level) > status->dex )
|
||||
status->rhw.atk2 += status->str + hd->master->homunculus.level ;
|
||||
else
|
||||
status->rhw.atk2 += status->dex ;
|
||||
|
||||
if(hd->sc.data[SC_FLEET].timer!=-1)
|
||||
status->rhw.atk2 += status->rhw.atk2 * hd->sc.data[SC_FLEET].val3/100;
|
||||
}
|
||||
|
||||
if(flag&SCB_MATK) {
|
||||
status->matk_min = status->int_+(status->int_/7)*(status->int_/7);
|
||||
status->matk_max = status->int_+(status->int_/5)*(status->int_/5);
|
||||
|
||||
status->matk_min = status_calc_matk(&hd->bl, &hd->sc, status->matk_min);
|
||||
status->matk_max = status_calc_matk(&hd->bl, &hd->sc, status->matk_max);
|
||||
|
||||
}
|
||||
|
||||
if(flag&SCB_HIT) {
|
||||
if(status->hit < 1) status->hit = 1;
|
||||
}
|
||||
|
||||
if(flag&SCB_FLEE) {
|
||||
if(status->flee < 1) status->flee = 1;
|
||||
}
|
||||
|
||||
if(flag&SCB_DEF2) {
|
||||
if(status->def2 < 1) status->def2 = 1;
|
||||
}
|
||||
|
||||
if(flag&SCB_MDEF2) {
|
||||
if(status->mdef2 < 1) status->mdef2 = 1;
|
||||
}
|
||||
|
||||
if(flag&SCB_SPEED) {
|
||||
if(status->speed < battle_config.max_walk_speed)
|
||||
status->speed = battle_config.max_walk_speed;
|
||||
}
|
||||
if(flag&(SCB_ASPD|SCB_AGI|SCB_DEX)) {
|
||||
flag|=SCB_ASPD;
|
||||
status->amotion = hd->homunculusDB->baseASPD - ((status->agi*4+status->dex)* hd->homunculusDB->baseASPD / 1000);
|
||||
|
||||
status->aspd_rate = status_calc_aspd_rate(&hd->bl, &hd->sc , b_status->aspd_rate);
|
||||
if(status->aspd_rate != 1000)
|
||||
status->amotion = status->amotion *status->aspd_rate/1000;
|
||||
|
||||
status->amotion = cap_value(status->amotion,battle_config.max_aspd,2000);
|
||||
|
||||
status->adelay = 2*status->amotion;
|
||||
}
|
||||
|
||||
if(flag&(SCB_AGI|SCB_DSPD)) {
|
||||
//Even though people insist this is too slow, packet data reports this is the actual real equation.
|
||||
skill = 800-status->agi*4;
|
||||
status->dmotion = cap_value(skill, 400, 800);
|
||||
|
||||
if(battle_config.pc_damage_delay_rate != 100)
|
||||
status->dmotion = status->dmotion*battle_config.pc_damage_delay_rate/100;
|
||||
status->dmotion = status_calc_dmotion(&hd->bl, &hd->sc, b_status->dmotion);
|
||||
}
|
||||
|
||||
if(flag&SCB_CRI)
|
||||
{
|
||||
if(status->cri < 10) status->cri = 10;
|
||||
}
|
||||
|
||||
if(flag&SCB_FLEE2) {
|
||||
if(status->flee2 < 10) status->flee2 = 10;
|
||||
}
|
||||
if (flag == SCB_ALL)
|
||||
return; //Refresh is done on invoking function (status_calc_hom)
|
||||
|
||||
if ( (flag&SCB_SPEED) ||
|
||||
(flag&SCB_STR) ||
|
||||
(flag&SCB_AGI) ||
|
||||
(flag&SCB_VIT) ||
|
||||
(flag&SCB_INT) ||
|
||||
(flag&SCB_DEX) ||
|
||||
(flag&SCB_LUK) ||
|
||||
(flag&SCB_HIT) ||
|
||||
(flag&SCB_FLEE) ||
|
||||
(flag&SCB_ASPD) ||
|
||||
(flag&(SCB_BATK|SCB_WATK)) ||
|
||||
(flag&SCB_DEF) ||
|
||||
(flag&SCB_WATK) ||
|
||||
(flag&SCB_DEF2) ||
|
||||
(flag&SCB_FLEE2) ||
|
||||
(flag&SCB_CRI) ||
|
||||
(flag&SCB_MATK) ||
|
||||
(flag&SCB_MDEF) ||
|
||||
(flag&SCB_MDEF2) ||
|
||||
(flag&SCB_RANGE) ||
|
||||
(flag&SCB_MAXHP) ||
|
||||
(flag&SCB_MAXSP)
|
||||
)
|
||||
{
|
||||
clif_hominfo(hd->master,0);
|
||||
}
|
||||
}
|
||||
|
||||
void status_calc_bl(struct block_list *bl, unsigned long flag)
|
||||
{
|
||||
struct status_data *b_status, *status;
|
||||
struct status_change *sc;
|
||||
int temp;
|
||||
TBL_PC *sd;
|
||||
TBL_HOMUNCULUS *hd;
|
||||
b_status = status_get_base_status(bl);
|
||||
status = status_get_status_data(bl);
|
||||
sc = status_get_sc(bl);
|
||||
@ -2566,6 +2731,7 @@ void status_calc_bl(struct block_list *bl, unsigned long flag)
|
||||
return;
|
||||
|
||||
BL_CAST(BL_PC,bl,sd);
|
||||
BL_CAST(BL_HOMUNCULUS,bl,hd);
|
||||
|
||||
if(sd && flag&SCB_PC)
|
||||
{ //Recalc everything.
|
||||
@ -2573,7 +2739,8 @@ void status_calc_bl(struct block_list *bl, unsigned long flag)
|
||||
return;
|
||||
}
|
||||
|
||||
if(!sd && (!sc || !sc->count)) { //No difference.
|
||||
// if(!sd && (!sc || !sc->count)) { //No difference.
|
||||
if( (!sd && !hd ) && (!sc || !sc->count)) { //No difference.
|
||||
status_cpy(status, b_status);
|
||||
return;
|
||||
}
|
||||
@ -2716,6 +2883,12 @@ void status_calc_bl(struct block_list *bl, unsigned long flag)
|
||||
return;
|
||||
}
|
||||
|
||||
if(hd) {
|
||||
//The remaining are handled quite different by homunculus, so use their own function.
|
||||
status_calc_bl_sub_hom(hd, flag);
|
||||
return;
|
||||
}
|
||||
|
||||
if(flag&SCB_MAXHP) {
|
||||
status->max_hp = status_calc_maxhp(bl, sc, b_status->max_hp);
|
||||
if (status->hp > status->max_hp) //FIXME: Should perhaps a status_zap should be issued?
|
||||
@ -2985,8 +3158,6 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
|
||||
batk += batk * 3;
|
||||
if(sc->data[SC_BLOODLUST].timer!=-1)
|
||||
batk += batk * sc->data[SC_BLOODLUST].val2/100;
|
||||
if(sc->data[SC_FLEET].timer!=-1)
|
||||
batk += batk * sc->data[SC_FLEET].val3/100;
|
||||
if(sc->data[SC_JOINTBEAT].timer!=-1 && sc->data[SC_JOINTBEAT].val2==4)
|
||||
batk -= batk * 25/100;
|
||||
if(sc->data[SC_CURSE].timer!=-1)
|
||||
@ -3032,8 +3203,6 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
|
||||
}
|
||||
if(sc->data[SC_BLOODLUST].timer!=-1)
|
||||
watk += watk * sc->data[SC_BLOODLUST].val2/100;
|
||||
if(sc->data[SC_FLEET].timer!=-1)
|
||||
watk += watk * sc->data[SC_FLEET].val3/100;
|
||||
if(sc->data[SC_CURSE].timer!=-1)
|
||||
watk -= watk * 25/100;
|
||||
if(sc->data[SC_STRIPWEAPON].timer!=-1)
|
||||
@ -3140,6 +3309,8 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
|
||||
flee += 30;
|
||||
if(sc->data[SC_GATLINGFEVER].timer!=-1)
|
||||
flee -= sc->data[SC_GATLINGFEVER].val1*5;
|
||||
if(sc->data[SC_SPEED].timer!=-1)
|
||||
flee += 10 + sc->data[SC_SPEED].val1 * 10 ;
|
||||
|
||||
return cap_value(flee,0,SHRT_MAX);
|
||||
}
|
||||
@ -3166,6 +3337,8 @@ static signed char status_calc_def(struct block_list *bl, struct status_change *
|
||||
return 100;
|
||||
if(sc->data[SC_SKA].timer != -1)
|
||||
return sc->data[SC_SKA].val3;
|
||||
if (sc->data[SC_DEFENCE].timer != -1) //[orn]
|
||||
def += sc->data[SC_DEFENCE].val2 ;
|
||||
if(sc->data[SC_STEELBODY].timer!=-1)
|
||||
return 90;
|
||||
if(sc->data[SC_DRUMBATTLE].timer!=-1)
|
||||
@ -3586,6 +3759,8 @@ int status_get_class(struct block_list *bl)
|
||||
return ((struct map_session_data *)bl)->status.class_;
|
||||
if(bl->type==BL_PET)
|
||||
return ((struct pet_data *)bl)->class_;
|
||||
if(bl->type==BL_HOMUNCULUS)
|
||||
return ((struct homun_data *)bl)->master->homunculus.class_;
|
||||
return 0;
|
||||
}
|
||||
/*==========================================
|
||||
@ -3603,7 +3778,7 @@ int status_get_lv(struct block_list *bl)
|
||||
if(bl->type==BL_PET)
|
||||
return ((TBL_PET*)bl)->msd->pet.level;
|
||||
if(bl->type==BL_HOMUNCULUS)
|
||||
return ((TBL_HOMUNCULUS*)bl)->level;
|
||||
return ((TBL_HOMUNCULUS*)bl)->master->homunculus.level;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3699,6 +3874,16 @@ int status_get_party_id(struct block_list *bl)
|
||||
}
|
||||
return 0; //No party.
|
||||
}
|
||||
if(bl->type==BL_HOMUNCULUS){ //[orn]
|
||||
struct homun_data *hd=(struct homun_data *)bl;
|
||||
if( hd->master->bl.id>0 )
|
||||
{
|
||||
if ( hd->master != NULL)
|
||||
return hd->master->status.party_id;
|
||||
return -1;
|
||||
}
|
||||
return 0; //No party.
|
||||
}
|
||||
if(bl->type==BL_SKILL)
|
||||
return ((struct skill_unit *)bl)->group->party_id;
|
||||
return 0;
|
||||
@ -3721,6 +3906,16 @@ int status_get_guild_id(struct block_list *bl)
|
||||
return msd->status.guild_id; //Alchemist's mobs [Skotlex]
|
||||
return 0; //No guild.
|
||||
}
|
||||
if(bl->type==BL_HOMUNCULUS){ //[orn]
|
||||
struct homun_data *hd=(struct homun_data *)bl;
|
||||
if( hd->master->bl.id>0 )
|
||||
{
|
||||
if ( hd->master != NULL)
|
||||
return hd->master->status.guild_id;
|
||||
return -1;
|
||||
}
|
||||
return 0; //No guild.
|
||||
}
|
||||
if (bl->type == BL_NPC && bl->subtype == SCRIPT)
|
||||
return ((TBL_NPC*)bl)->u.scr.guild_id;
|
||||
if(bl->type==BL_SKILL)
|
||||
@ -4133,6 +4328,7 @@ int status_get_sc_tick(struct block_list *bl, int type, int tick)
|
||||
int status_change_start(struct block_list *bl,int type,int rate,int val1,int val2,int val3,int val4,int tick,int flag)
|
||||
{
|
||||
struct map_session_data *sd = NULL;
|
||||
struct homun_data *hd = NULL;
|
||||
struct status_change* sc;
|
||||
struct status_data *status;
|
||||
int opt_flag , calc_flag, undead_flag;
|
||||
@ -4149,6 +4345,9 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
|
||||
case BL_PC:
|
||||
sd=(struct map_session_data *)bl;
|
||||
break;
|
||||
case BL_HOMUNCULUS:
|
||||
hd=(struct homun_data *)bl; //[orn]
|
||||
break;
|
||||
case BL_MOB:
|
||||
if (((struct mob_data*)bl)->class_ == MOBID_EMPERIUM && type != SC_SAFETYWALL)
|
||||
return 0; //Emperium can't be afflicted by status changes.
|
||||
@ -5188,6 +5387,9 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
|
||||
case SC_AVOID:
|
||||
val2 = 10*val1; //Speed change rate.
|
||||
break;
|
||||
case SC_DEFENCE:
|
||||
val2 = 2*val1; //Def bonus
|
||||
break;
|
||||
case SC_BLOODLUST:
|
||||
val2 = 20+10*val1; //Atk rate change.
|
||||
break;
|
||||
|
@ -253,6 +253,8 @@ enum {
|
||||
SC_CHANGE,
|
||||
SC_BLOODLUST,
|
||||
SC_FLEET,
|
||||
SC_SPEED, //[orn]
|
||||
SC_DEFENCE, //[orn]
|
||||
SC_INCAGIRATE,
|
||||
SC_INCDEXRATE,
|
||||
SC_MAX, //Automatically updated max, used in for's and at startup to check we are within bounds. [Skotlex]
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "pc.h"
|
||||
#include "mob.h"
|
||||
#include "pet.h"
|
||||
#include "mercenary.h" ///[orn]
|
||||
#include "skill.h"
|
||||
#include "clif.h"
|
||||
#include "npc.h"
|
||||
@ -38,6 +39,7 @@ struct unit_data* unit_bl2ud(struct block_list *bl) {
|
||||
if( bl->type == BL_MOB) return &((struct mob_data*)bl)->ud;
|
||||
if( bl->type == BL_PET) return &((struct pet_data*)bl)->ud;
|
||||
if( bl->type == BL_NPC) return &((struct npc_data*)bl)->ud;
|
||||
if( bl->type == BL_HOMUNCULUS) return &((struct homun_data*)bl)->ud; //[orn]
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -100,6 +102,7 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
|
||||
struct block_list *bl;
|
||||
struct map_session_data *sd = NULL;
|
||||
struct mob_data *md = NULL;
|
||||
struct homun_data *hd = NULL; //[orn]
|
||||
struct unit_data *ud = NULL;
|
||||
|
||||
bl=map_id2bl(id);
|
||||
@ -109,6 +112,8 @@ static int unit_walktoxy_timer(int tid,unsigned int tick,int id,int data)
|
||||
ud = &sd->ud;
|
||||
} else if( BL_CAST( BL_MOB, bl, md ) ) {
|
||||
ud = &md->ud;
|
||||
} else if( BL_CAST( BL_HOMUNCULUS, bl, hd ) ) { //[orn]
|
||||
ud = &hd->ud;
|
||||
} else
|
||||
ud = unit_bl2ud(bl);
|
||||
|
||||
@ -262,6 +267,9 @@ int unit_walktoxy( struct block_list *bl, int x, int y, int easy) {
|
||||
|
||||
nullpo_retr(0, bl);
|
||||
|
||||
if ( status_isdead(bl) ) //[orn]
|
||||
return 0;
|
||||
|
||||
ud = unit_bl2ud(bl);
|
||||
|
||||
if( ud == NULL) return 0;
|
||||
@ -707,6 +715,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int
|
||||
struct status_data *tstatus;
|
||||
struct status_change *sc;
|
||||
struct map_session_data *sd = NULL;
|
||||
struct homun_data *hd = NULL; //[orn]
|
||||
struct block_list * target = NULL;
|
||||
unsigned int tick = gettick();
|
||||
int temp;
|
||||
@ -717,6 +726,8 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int
|
||||
|
||||
if( BL_CAST( BL_PC, src, sd ) ) {
|
||||
ud = &sd->ud;
|
||||
} else if( BL_CAST( BL_HOMUNCULUS, src, hd ) ) { //[orn]
|
||||
ud = &hd->ud;
|
||||
} else
|
||||
ud = unit_bl2ud(src);
|
||||
|
||||
@ -1184,6 +1195,7 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t
|
||||
struct status_data *sstatus;
|
||||
struct map_session_data *sd = NULL;
|
||||
struct mob_data *md = NULL;
|
||||
struct homun_data *hd = NULL; //[orn]
|
||||
int range;
|
||||
|
||||
if((ud=unit_bl2ud(src))==NULL)
|
||||
@ -1195,6 +1207,7 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int t
|
||||
}
|
||||
BL_CAST( BL_PC , src, sd);
|
||||
BL_CAST( BL_MOB, src, md);
|
||||
BL_CAST( BL_HOMUNCULUS, src, hd); //[orn]
|
||||
ud->attacktimer=-1;
|
||||
target=map_id2bl(ud->target);
|
||||
|
||||
@ -1704,6 +1717,16 @@ int unit_free(struct block_list *bl) {
|
||||
}
|
||||
if(mob_is_clone(md->class_))
|
||||
mob_clone_delete(md->class_);
|
||||
} else if( bl->type == BL_HOMUNCULUS ) { //[orn]
|
||||
struct homun_data *hd = (struct homun_data*)bl;
|
||||
struct map_session_data *sd = hd->master;
|
||||
merc_hom_hungry_timer_delete(hd);
|
||||
merc_natural_heal_timer_delete(hd) ;
|
||||
if (sd) {
|
||||
// if(hd->intimacy > 0)
|
||||
// intif_save_mercdata(sd->status.account_id,&sd->hom);
|
||||
sd->hd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
skill_clear_unitgroup(bl);
|
||||
@ -1729,4 +1752,3 @@ int do_final_unit(void) {
|
||||
// nothing to do
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -160,6 +160,9 @@
|
||||
<File
|
||||
RelativePath="..\src\char_sql\int_guild.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\char_sql\int_homun.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\char_sql\int_party.c">
|
||||
</File>
|
||||
@ -242,6 +245,9 @@
|
||||
<File
|
||||
RelativePath="..\src\char_sql\int_guild.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\char_sql\int_homun.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\char_sql\int_party.h">
|
||||
</File>
|
||||
|
Loading…
x
Reference in New Issue
Block a user