summaryrefslogblamecommitdiff
path: root/src/map/clif.c
blob: 28a9e230fdbc0fe24f6b24a5899fa1a856995f80 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443










                                                           
                    




































                               
                  




                     

                 






































































































                                                                                                                                                                                                                                                                                                                   
 
                                                                                                
                                                                                                               
                                                                                                                                                                       

                                                                                                  
                                                                            
 

                                                                   



































































                                                                                                                 
                                                                                 








                                             
 











                                                                                                                                          
                                                                                         

















                                                     
 





                                                                                                                     
 



































                                                                                                                            
                                                                                                                

                                                                                                                        
                                                                    



                                                                                           

                                          
 
                                                            
                                                                                                                                           
 
                                                                                          
                                                                                          


















                                                                                                                  
                                   































                                                                                                                                  
                                                           













































                                                                                                                                              
                                                                                  










                                                                                                              
                                                                                                                         















































                                                                                                                                                                   
                                                                               









                                                                                                                               
                                               
















































                                                                                                                                                                   
                                                                               
































                                                                                            
                                               

















                                                                                                                             
                                               































                                                                 
                                               
































































                                                                                             
                                                      


















                                                      
 

                                                                                 
                                        
                                                                  






































                                                                                    



                                                                  
       



                                                                       


                  

                                    
      








                                                                                
 









                                                                                
       
         
 
                                                                                          
  






















                                                                                                
          
                




                                             


                                                                                           

                                        
                            
 


                                
 




                                                        


                                                       


























                                                         

                                 

                                                 
                                                
      


                                                      

























                                                         

                                 

                                                 
                                               
       
          



























                                                            


                                             
   

                                             


                                                                                                                 

                                        
 


                                
         




                                                        


                                                       












                                                   
                                         









                                                               
                  

                                                                


                                                                                        
                                                 

                                                
      
                                                      
 







                                                   
                  
















                                                                


                                                                                        
                                                 
 
                                               

          

                                                        

                           









                                                 
                                 




                                                        


                                                                                
                                         



                                       








                                                                                                   
                 
                                         
          
                                            


                                             
                                              

                                             


                                                                 
 
                            
 





                                                                
          
                  





                                             






                                                                        






                                                                 
                                                









                                                          
















































                                                              

                                              
                                                














                                                                                                                
                                                                   




                                                                 
                                                
                  

          


                  
                                      
  




                                                  

                          


                                           
                  






                                                                                               
       




                                                                                                
                  
                  
       
 
















                                                                       







                                                                                         

                                                     














                                                                                 
          

                  










                                                 
                                               

















                                             
                                               

                                
                                                                   









                                             
                                               



                                








                                                








                                                      
                                                                            

                                 
                                                                       

          

                  
 








                                             
 
















                                                                                         
 





















                                                                                 


                  
 





















                                                                                                    

                                                                                                                        



































































































                                                                                                                                             
                             


                                                          



                                                                  
































                                                                     
                                     




















































































                                                                                          
                                               























































                                                                         
                                           
















                                                                  
                                                
















                                                                                                         
                                                





















                                                                     
                                                





























































































































































































































































































































































































































































































                                                                                                                                   
                               
 
                            
 




                                                                          
 
















                                                              




                                                      
                               
 
                            
 




                                                                          
 
                  

















                                                                               
                           




























































                                                                                                      
                                                                                      







                                       
                                                                             




























































































































































                                                                                               

                                            
                              
                            


                                      


                                                    

























































                                                                                                      
                  





                                                       
                                                         

                                     


                                          

                                                                

                                                
















                                                                





























                                                                            






























                                                                              















                                                    

                                                                                             
                                                      
                                                                             
                                                      
                                                                             
                                                      
                                                                                
                                                       
                                                                              
                                                       
                                                                              

                                                       

                                                                                     





































                                                         
                                         

                   
                                                 


















                                                          
                                                 



















                                                        
                                               















                                                                                        



                                                   














                                                                          
                                              



























































































                                                                          
                                  

                            
                                

                              






                                                                    
                                        
                                                                
                                       


                                                                
                                                                













                                                                             
                                                      








                                                     
                                                      






























































                                                                                        
                                             

























































































































































































































































































































































































































































































                                                                                                            


                                                                
                                               

                                                  
                             
                                                                         
 

                                                       
 




                                                                                                                           

                                                                              
                 






                                                        
                                                                              
  

                              
                 

                                      
 

                                                  
 









                                                               
                 






                                                            

          

                                                                                          
 


























                                                                                                             
          


                                             
                         

                                             
                                        
  

                              


                                









                                                  
 





                                                            


                  




















                                                                                                                                               
                                  





                                                                                            
                                 
 







                                                                                                    
 










                                                           
 


















                                                                
          




                                                                                                                              








                                                                                     















                                                                                             



































                                                                                    
                                                                        





















































































                                                                                                                                                                   






                                                                        


                                              





                                             
                                       

                                             
                                                    
  
                                
                              









                                                       

                                                                         
                                        
                                                      


                                                                             
                          









                                                                                   
                                                                                           

                                                                     
                  
          

                                                     
                                                                                    
                                                             
          



                                             
                                

                                             
                                                   
  


                                           
 

















                                                                                 
          


                                                        
          






























































































































                                                                                                                                                               




                                                                  

































                                                                                 
                                                     
























                                                                                                       
                                  




                                                                                    
                                 
 


                                                                                          




                               

                              







                                                         













                                                                 


                               

                              







                                                         













                                                                 



                                                                                                                              
                                                                










                                                                                                       
                                  




                                                                                    
                                 
 


                                                                                          















                                                         













                                                                 


                                                                                                                              
                                                                
















                                                                       
                                                       




                                                         










                                                                 
                     



















                                                                                           



                                                                 
















                                                



                                                              
                 




































































                                                                                                                                                                   
                                                                                 














                                                                             
                                      



                                                                                                  




















































                                                                              
                                      


























                                                                                                                 
                                                                          



                            

                                                                            
















                                                                                       




                                                

































































































                                                                                                                                    


                                                  






































































































                                                                                            

                                





























                                                                             
                                                           











                                                          
                                       
























                                                                                    
                          













                                                                               
                                               






























































































































































                                                                                                                                                                           

                                                




















































                                                                                                                                                  

                                                    
              
                                                        




























































                                                                                                                        

                                            
























































































































































































































































































































































































































































































































































































































































                                                                                                                                     

















                                                              


























































































































































                                                                                                                                 




                                                                

















































                                                                                                 
                                             
                               




























































































                                                                              







                                               
                                    
































































                                                                   


                                         


















































































































                                                                       
                          





































































































































                                                                                         








































                                                                            



















































































































































































































































































                                                                                
                                                




                                                                                     
                                                                

































































































































































































































































































































































































































































                                                                                                



















































                                                                                    














































































































                                                                                                                          
                                                                                   



                                                 




                                                                         






                                                 
                                                               













                                                                  
                               

















                                                                          



                                                                   



















                                                                                                                                            
                               

























































































































                                                                                                                                    
                                   









































































































































































































































































                                                                                                                                                                                   






                                                                         

                                     
                                                        
          


                  






                                                               

               























                                                   







                                                                                       
                                         
 




                                          







                                               


                                        












                                                                                                          
                                    

                                  


                                                     

                                   
                                    



                                                                      
                                         






                                                                      



                                                                                          

                                                                          








                                                                                                                                           











                                                                                                             








                                                                


                                                                                                
 
                                                                                                 
                                                     











                                                                                                                            







                                                                                                  




                                                 
                                                               
                                                                               

                                
         


                                                                                             





                                                                                                       


                                                      



























                                                                                   
                               

                        
                                     

                        
                                                            




                                           
                            








                                                                                 
                                         







                                                                



                                                                   
                                                                                      













































































































                                                                                                                                                                                   
                                  






                                                                                                       







                                                                                                                      
                                                                                                                 



                                                                                                                                                                        
                                                                                                                   

                                
                                          
          






                                                                                                
                                                 
                       
                                         
 
                                                


                                                                                                                   
                                           
                                                                                                                                                                              
                                                          

                                                                                                                                                                     
                 

                                                                                              
                     

                                                                                                       

                                                       
                                                                                                                          
                     

                                                                                                      







                                                                                                                                                                             



                                                                    



                                                                                              

                        



                                                                                




                                                                   
                                                         

                                                                                      

                                    
                                            




                                                          
                                                                                                         
                                                                                                         




                                                                                  
                                                                                 












                                                                              
                                       



                                                                                                

                                                                                                                                            
                                                            
                                       


                          














































                                                                                                      


                               
                                                                  
                                        

                                                              
                             

                                        
                                                                  










































































                                                                                                                                     

                                                            
                        
         



                                                           



                          

                                











                                                                                                            
                                                                           
                                
                                                                                                  
                                                                       





                                                              
                                                                   


                                                                                                
                                                                                   
                                       




                                                                                                                          














                                                                                                     



























































                                                                                                                                                                                          



                                                                           
                                          

                                                                                           
                        







                                                                                                                                                                                     


                                                                    


                                                                                                        
                                                         
                  




                                                                                                      
                          

















                                                                           
                          









                                                                                         
 



                                                                                                                            



                                                                      

                                                                                                                       
                  
                                                          


























                                                                                                                                                      
                                                                                                         




































































                                                                                                                                       



                                                                                                                      





                                                                      


















                                                                       

                               
                        
 



                                                                              



                                                                                  



                                                           






                                                               
               





                                                 
 
                                                              
                        
         
                                                                        




                                                     








                                                                      






                                                                                        


                                                                         
                        
                               
                                                                                                


















                                                              



                                                     
                        
                 

                                                                                      




























                                                                                                

                               
                        
 
















                                                               




                                                                       





















                                                                       
                         
                                   

                                  




                                                   
                                                   
                          



                                                                                      

                                                                                                    
                          
                                                  




                                                            
 
                                               











                                                                    
                        
                                   

                                  




                                                   
                                                   
                          



                                                                                      

                                                                                                                               
                          
                                                  




                                                             
                                               







































































































































                                                                                                                        
                            









                                                                  
                              










                                                                    

                              


















































                                                                    


                               












                                                                                                               




                                                                                                                          
                                       

                                               
                                                              
                                                                   
                                                                     









                                                     
                                                                       
                        
         



                                                   
                               



                                                               
                                                                         


                                                      



                                                                                 










                                                                                                    

                                                                             










                                                                                               


                                                                                      


                                                              
                                                                                 






























                                                                                                                                  
                                     
                        
                                                     




                                                     
                                                                       
                        
         




                                                               
                                                                     




                                                              
                                                                            







                                                                     


                               













                                                                                       




                               















                                                                                       
                               

                        
                                                                     

                        





















                                                                
                                             
                        

                                
                                                                                                       
                                                        
                                                         


                                                                                        
                                                 








                                                                
                                                 
                        
                                
                                                                                                       
                                                        
                                                         


                                             
                                                 









                                                                    
                                                                   
                        
                                
                                                                                                       
                                                        
                                                         



                                                                         
                                                 













































































                                                                                                                         

                                             
                                           
                                                 







                                                                
                                                
                        

                                                                                               
                                                        
                                                         


                                             
                                                 







                                                              

                                              
                                          
                                                 
















































                                                                             
                                             





























                                                                              
                              




















                                                                                  
                              

















                                                                                  
                              














                                                                                      
                              


































































































                                                                                       





                                                                                           






























                                                                      
                              









                                                                           
                              

























































































































































                                                                                                                  





                                                                                   






























































                                                                            
                                                                            
                        
                                           
                                                 

























































































































                                                                                                                             

                                                            



                                                                                 

                                                                    
                                                           

                                                                                                   













































                                                                                                                     
                                                                



































































































































































































                                                                                                                                                                                                                                         
                                                                                                                
















                                                                                                                                                                                              
                                                                                   

                                                                                                  


















































































































































































































































                                                                                                                         

                                                                 










                                                                                                                 




                                                                              

























                                                                  

                                                                 










                                                                                                        




                                                                            

























                                                                 

                                                                 










                                                                                                        



                                                                            






































                                                                   















                                                                                       




                                                                                          
                                                 





                                                     
                                                                            


                                               

                                  















































































                                                                                                                                                                                      

                                                                                              










                                                             
                  



                                                                                                                  



                                                                                                                          
                  





























































































































































































































































































































































































                                                                                                                                                                          
                    
















































                                                                                                                                                                                       
                                                                 



                  
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder

#define DUMP_UNKNOWN_PACKET	0
#define DUMP_ALL_PACKETS	0

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>
#ifdef __WIN32
#define __USE_W32_SOCKETS
#include <windows.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include <time.h>

#include "../common/socket.h"
#include "../common/timer.h"
#include "../common/malloc.h"
#include "../common/version.h"
#include "../common/nullpo.h"
#include "../common/showmsg.h"

#include "map.h"
#include "chrif.h"
#include "clif.h"
#include "pc.h"
#include "status.h"
#include "npc.h"
#include "itemdb.h"
#include "chat.h"
#include "trade.h"
#include "storage.h"
#include "script.h"
#include "skill.h"
#include "atcommand.h"
#include "charcommand.h"
#include "intif.h"
#include "battle.h"
#include "mob.h"
#include "party.h"
#include "unit.h"
#include "guild.h"
#include "vending.h"
#include "pet.h"
#include "log.h"

#include "irc.h"

struct Clif_Config {
	int packet_db_ver;	//Preferred packet version.
	int connect_cmd[MAX_PACKET_VER + 1]; //Store the connect command for all versions. [Skotlex]
} clif_config;

struct packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB];

static const int packet_len_table[MAX_PACKET_DB] = {
   10,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
//#0x0040
    0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0, 55, 17,  3, 37,  46, -1, 23, -1,  3,108,  3,  2,
#if PACKETVER < 2
    3, 28, 19, 11,  3, -1,  9,  5,  52, 51, 56, 58, 41,  2,  6,  6,
#else	// 78-7b �T���ȍ~ lv99�G�t�F�N�g�p
    3, 28, 19, 11,  3, -1,  9,  5,  54, 53, 58, 60, 41,  2,  6,  6,
#endif
//#0x0080
    7,  3,  2,  2,  2,  5, 16, 12,  10,  7, 29,  2, -1, -1, -1,  0, // 0x8b changed to 2 (was 23)
    7, 22, 28,  2,  6, 30, -1, -1,   3, -1, -1,  5,  9, 17, 17,  6,
   23,  6,  6, -1, -1, -1, -1,  8,   7,  6,  7,  4,  7,  0, -1,  6,
    8,  8,  3,  3, -1,  6,  6, -1,   7,  6,  2,  5,  6, 44,  5,  3,
//#0x00C0
    7,  2,  6,  8,  6,  7, -1, -1,  -1, -1,  3,  3,  6,  3,  2, 27, // 0xcd change to 3 (was 6)
    3,  4,  4,  2, -1, -1,  3, -1,   6, 14,  3, -1, 28, 29, -1, -1,
   30, 30, 26,  2,  6, 26,  3,  3,   8, 19,  5,  2,  3,  2,  2,  2,
    3,  2,  6,  8, 21,  8,  8,  2,   2, 26,  3, -1,  6, 27, 30, 10,

//#0x0100
    2,  6,  6, 30, 79, 31, 10, 10,  -1, -1,  4,  6,  6,  2, 11, -1,
   10, 39,  4, 10, 31, 35, 10, 18,   2, 13, 15, 20, 68,  2,  3, 16,
    6, 14, -1, -1, 21,  8,  8,  8,   8,  8,  2,  2,  3,  4,  2, -1,
    6, 86,  6, -1, -1,  7, -1,  6,   3, 16,  4,  4,  4,  6, 24, 26,
//#0x0140
   22, 14,  6, 10, 23, 19,  6, 39,   8,  9,  6, 27, -1,  2,  6,  6,
  110,  6, -1, -1, -1, -1, -1,  6,  -1, 54, 66, 54, 90, 42,  6, 42,
   -1, -1, -1, -1, -1, 30, -1,  3,  14,  3, 30, 10, 43, 14,186,182,
   14, 30, 10,  3, -1,  6,106, -1,   4,  5,  4, -1,  6,  7, -1, -1,
//#0x0180
    6,  3,106, 10, 10, 34,  0,  6,   8,  4,  4,  4, 29, -1, 10,  6,
#if PACKETVER < 1
   90, 86, 24,  6, 30,102,  8,  4,   8,  4, 14, 10, -1,  6,  2,  6,
#else	// 196 comodo�ȍ~ ��ԕ\���A�C�R���p
   90, 86, 24,  6, 30,102,  9,  4,   8,  4, 14, 10, -1,  6,  2,  6,
#endif
    3,  3, 35,  5, 11, 26, -1,  4,   4,  6, 10, 12,  6, -1,  4,  4,
   11,  7, -1, 67, 12, 18,114,  6,   3,  6, 26, 26, 26, 26,  2,  3,
//#0x01C0,   Set 0x1d5=-1
    2, 14, 10, -1, 22, 22,  4,  2,  13, 97,  3,  9,  9, 30,  6, 28,
    8, 14, 10, 35,  6, -1,  4, 11,  54, 53, 60,  2, -1, 47, 33,  6,
   30,  8, 34, 14,  2,  6, 26,  2,  28, 81,  6, 10, 26,  2, -1, -1,
   -1, -1, 20, 10, 32,  9, 34, 14,   2,  6, 48, 56, -1,  4,  5, 10,
//#0x200
   26, -1,  26, 10, 18, 26, 11, 34,  14, 36, 10, 0,  0, -1, 32, 10, // 0x20c change to 0 (was 19)
   22,  0,  26, 26, 42, -1, -1,  2,   2,282,282,10, 10, -1, -1, 66,
   10, -1,  -1,  8, 10,  2,282, 18,  18, 15, 58, 57, 64, 5, 69,  5,
   12, 26,   9, 11, -1, -1, 10,  2, 282, 11,  4, 36, -1,-1,  4,  2,
   -1, -1,  -1, -1, -1,  3,  4,  8,  -1,  3, 70,  4,  8,12,  4, 10,
    3, 32,  -1,  3,  3,  5,  5,  8,   2,  3, -1, -1,  4,-1,  4
};

// local define
enum {
	ALL_CLIENT,
	ALL_SAMEMAP,
	AREA,
	AREA_WOS,
	AREA_WOC,
	AREA_WOSC,
	AREA_CHAT_WOC,
	CHAT,
	CHAT_WOS,
	CHAT_MAINCHAT,
	PARTY,
	PARTY_WOS,
	PARTY_SAMEMAP,
	PARTY_SAMEMAP_WOS,
	PARTY_AREA,
	PARTY_AREA_WOS,
	GUILD,
	GUILD_WOS,
	GUILD_SAMEMAP,	// [Valaris]
	GUILD_SAMEMAP_WOS,
	GUILD_AREA,
	GUILD_AREA_WOS,	// end additions [Valaris]
	SELF
};

//Converts item type in case of pet eggs.
#define itemtype(a) (a == 7)?4:a

#define WBUFPOS(p,pos,x,y) { unsigned char *__p = (p); __p+=(pos); __p[0] = (x)>>2; __p[1] = ((x)<<6) | (((y)>>4)&0x3f); __p[2] = (y)<<4; }
#define WBUFPOS2(p,pos,x0,y0,x1,y1) { unsigned char *__p = (p); __p+=(pos); __p[0] = (unsigned char)((x0)>>2); __p[1] = (unsigned char)(((x0)<<6) | (((y0)>>4)&0x3f)); __p[2] = (unsigned char)(((y0)<<4) | (((x1)>>6)&0x0f)); __p[3]=(unsigned char)(((x1)<<2) | (((y1)>>8)&0x03)); __p[4]=(unsigned char)(y1); }

#define WFIFOPOS(fd,pos,x,y) { WBUFPOS (WFIFOP(fd,pos),0,x,y); }
#define WFIFOPOS2(fd,pos,x0,y0,x1,y1) { WBUFPOS2(WFIFOP(fd,pos),0,x0,y0,x1,y1); }

//To make the assignation of the level based on limits clearer/easier. [Skotlex]
#define clif_setlevel(lv) (lv<battle_config.max_lv?lv:battle_config.max_lv-(lv<battle_config.aura_lv?1:0));

//Removed sd->npc_shopid because there is no packet sent from the client when you cancel a buy!
//Quick check to know if the player shouldn't be "busy" with something else to deny action requests. [Skotlex]
#define clif_cant_act(sd) (sd->npc_id || sd->vender_id || sd->chatID || (sd->sc.opt1 && sd->sc.opt1 != OPT1_STONEWAIT) || sd->trade_partner || sd->state.storage_flag)

// Checks if SD is in a trade/shop (where messing with the inventory can cause problems/exploits)
#define clif_trading(sd) (sd->npc_id || sd->vender_id || sd->trade_partner)

//To idenfity disguised characters.
#define disguised(bl) (bl->type==BL_PC && ((TBL_PC*)bl)->disguise)
static char map_ip_str[16];
static in_addr_t map_ip;
static in_addr_t bind_ip = INADDR_ANY;
static int map_port = 5121;
int map_fd;
char talkie_mes[MESSAGE_SIZE];

//These two will be used to verify the incoming player's validity.
//It helps identify their client packet version correctly. [Skotlex]
static int max_account_id = DEFAULT_MAX_ACCOUNT_ID;
static int max_char_id = DEFAULT_MAX_CHAR_ID;

int clif_parse (int fd);
static void clif_hpmeter_single(int fd, struct map_session_data *sd);

/*==========================================
 * map�I��ip�ݒ�
 *------------------------------------------
 */
void clif_setip(char *ip)
{
	memcpy(map_ip_str, ip, 16);
	map_ip = inet_addr(map_ip_str);
}

void clif_setbindip(char *ip)
{
	bind_ip = inet_addr(ip);
}

/*==========================================
 * map�I��port�ݒ�
 *------------------------------------------
 */
void clif_setport(int port)
{
	map_port = port;
}

/*==========================================
 * map�I��ip�ǂݏo��
 *------------------------------------------
 */
in_addr_t clif_getip(void)
{
	return map_ip;
}

/*==========================================
 * map�I��port�ǂݏo��
 *------------------------------------------
 */
int clif_getport(void)
{
	return map_port;
}

/*==========================================
 * Counts connected players.
 *------------------------------------------
 */
int clif_countusers(void)
{
	int users = 0, i;
	struct map_session_data *sd;

	for(i = 0; i < fd_max; i++) {
		if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) && sd->state.auth &&
				!(battle_config.hide_GM_session && pc_isGM(sd)))
			users++;
	}
	return users;
}

/*==========================================
 * �S�Ă�client�ɑ΂���func()���s
 *------------------------------------------
 */

int clif_foreachclient(int (*func)(struct map_session_data*, va_list),...) //recoded by sasuke, bug when player count gets higher [Kevin]
{
	int i;
	va_list ap;
	struct map_session_data *sd;

	va_start(ap,func);

	for(i = 0; i < fd_max; i++) {
		if ( session[i] ) {
			sd = (struct map_session_data*)session[i]->session_data;
			if ( sd && session[i]->func_parse == clif_parse &&
					sd->state.auth && !sd->state.waitingdisconnect )
				func(sd, ap);
		}
	}

	va_end(ap);
	return 0;
}

/*==========================================
 * clif_send��AREA*�w�莞�p
 *------------------------------------------
 */
int clif_send_sub(struct block_list *bl, va_list ap)
{
	struct block_list *src_bl;
	struct map_session_data *sd;
	unsigned char *buf;
	int len, type;

	nullpo_retr(0, bl);
	nullpo_retr(0, ap);
	nullpo_retr(0, sd = (struct map_session_data *)bl);

	if (!sd->fd) //Avoid attempting to send to disconnected chars (may prevent buffer overrun errors?) [Skotlex]
		return 0;

	buf = va_arg(ap,unsigned char*);
	len = va_arg(ap,int);
	nullpo_retr(0, src_bl = va_arg(ap,struct block_list*));
	type = va_arg(ap,int);

	switch(type) {
	case AREA_WOS:
		if (bl == src_bl)
			return 0;
		break;
	case AREA_WOC:
		if (sd->chatID || bl == src_bl)
			return 0;
		break;
	case AREA_WOSC:
		{
			struct map_session_data *ssd = (struct map_session_data *)src_bl;
			if ((ssd != 0) && (src_bl->type == BL_PC) && (sd->chatID != 0) && (sd->chatID == ssd->chatID))
				return 0;
		}
		break;
	}

	if (session[sd->fd] != NULL) {
		WFIFOHEAD(sd->fd, len);
		if (WFIFOP(sd->fd,0) == buf) {
			printf("WARNING: Invalid use of clif_send function\n");
			printf("         Packet x%4x use a WFIFO of a player instead of to use a buffer.\n", WBUFW(buf,0));
			printf("         Please correct your code.\n");
			// don't send to not move the pointer of the packet for next sessions in the loop
		} else {
			if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
				memcpy(WFIFOP(sd->fd,0), buf, len);
				//Check if hidden, better to modify the char's buffer than the
				//given buffer to prevent intravision affecting the packet as 
				//it's being received by everyone. [Skotlex]
				if ((sd->special_state.intravision || sd->sc.data[SC_INTRAVISION].timer != -1 )
						&& bl != src_bl && WFIFOW(sd->fd,0) == 0x0196)
				{	//New intravision method, just modify the status change/start packet. [Skotlex]
					switch (WFIFOW(sd->fd,2)) {
						case SI_HIDING:
						case SI_CLOAKING:
						case SI_CHASEWALK:
							WFIFOW(sd->fd,2) = SI_INTRAVISION;
					}
				}

				/* Previous implementation.
					if ((sd->special_state.intravision || sd->sc.data[SC_INTRAVISION].timer != -1 ) && bl != src_bl) {

					struct status_change *sc = status_get_sc(src_bl);
					if(sc && (sc->option&(OPTION_HIDE|OPTION_CLOAK)))
					{	//option�̏C��
						switch(((unsigned short*)buf)[0])
						{
							case 0x119:
								WFIFOW(sd->fd,10) &= ~(OPTION_HIDE|OPTION_CLOAK);
								break;
#if PACKETVER < 4
							case 0x78:
#else
							case 0x1da:
#endif
							case 0x7b:
							case 0x7c:
							case 0x1d8:
								WFIFOW(sd->fd,12) &=~(OPTION_HIDE|OPTION_CLOAK);
								break;
						}
					}
				}
				*/
				WFIFOSET(sd->fd,len);
			}
		}
	}

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
	int i;
	struct map_session_data *sd = NULL;
	struct party *p = NULL;
	struct guild *g = NULL;
	int x0 = 0, x1 = 0, y0 = 0, y1 = 0;

	if (type != ALL_CLIENT &&
		type != CHAT_MAINCHAT) {
		nullpo_retr(0, bl);
		if (bl->type == BL_PC) {
			sd = (struct map_session_data *)bl;
		}
	}

	switch(type) {
	case ALL_CLIENT: // �S�N���C�A���g�ɑ��M
		for (i = 0; i < fd_max; i++) {
			if (session[i] && (sd = (struct map_session_data *)session[i]->session_data) != NULL && sd->state.auth) {
				if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
					WFIFOHEAD(i, len);
					memcpy(WFIFOP(i,0), buf, len);
					WFIFOSET(i,len);
				}
			}
		}
		break;
	case ALL_SAMEMAP: // �����}�b�v�̑S�N���C�A���g�ɑ��M
		for(i = 0; i < fd_max; i++) {
			if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL &&
				sd->state.auth && sd->bl.m == bl->m) {
				if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
					WFIFOHEAD(i,len);
					memcpy(WFIFOP(i,0), buf, len);
					WFIFOSET(i,len);
				}
			}
		}
		break;
	case AREA:
	case AREA_WOS:
	case AREA_WOC:
	case AREA_WOSC:
		map_foreachinarea(clif_send_sub, bl->m, bl->x-AREA_SIZE, bl->y-AREA_SIZE, bl->x+AREA_SIZE, bl->y+AREA_SIZE,
			BL_PC, buf, len, bl, type);
		break;
	case AREA_CHAT_WOC:
		map_foreachinarea(clif_send_sub, bl->m, bl->x-(AREA_SIZE-5), bl->y-(AREA_SIZE-5),
			bl->x+(AREA_SIZE-5), bl->y+(AREA_SIZE-5), BL_PC, buf, len, bl, AREA_WOC);
		break;
	case CHAT:
	case CHAT_WOS:
		{
			struct chat_data *cd;
			if (sd) {
				cd = (struct chat_data*)map_id2bl(sd->chatID);
			} else if (bl->type == BL_CHAT) {
				cd = (struct chat_data*)bl;
			} else break;
			if (cd == NULL)
				break;
			for(i = 0; i < cd->users; i++) {
				if (type == CHAT_WOS && cd->usersd[i] == sd)
					continue;
				if (packet_db[cd->usersd[i]->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
					if (cd->usersd[i]->fd >0 && session[cd->usersd[i]->fd]) // Added check to see if session exists [PoW]
					{
						WFIFOHEAD(cd->usersd[i]->fd,len);
						memcpy(WFIFOP(cd->usersd[i]->fd,0), buf, len);
						WFIFOSET(cd->usersd[i]->fd,len);
					}
				}
			}
		}
		break;
	case CHAT_MAINCHAT: //[LuzZza]
		for(i=1; i<fd_max; i++) {
			if(session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL &&
				sd->state.mainchat && sd->fd) {
					WFIFOHEAD(sd->fd, len);								
					memcpy(WFIFOP(sd->fd,0), buf, len);
					WFIFOSET(sd->fd, len);								
			}
		}
		break;
	case PARTY_AREA:		// ������ʓ��̑S�p�[�e�B�[�����o�ɑ��M
	case PARTY_AREA_WOS:	// �����ȊO�̓�����ʓ��̑S�p�[�e�B�[�����o�ɑ��M
		x0 = bl->x - AREA_SIZE;
		y0 = bl->y - AREA_SIZE;
		x1 = bl->x + AREA_SIZE;
		y1 = bl->y + AREA_SIZE;
	case PARTY:				// �S�p�[�e�B�[�����o�ɑ��M
	case PARTY_WOS:			// �����ȊO�̑S�p�[�e�B�[�����o�ɑ��M
	case PARTY_SAMEMAP:		// �����}�b�v�̑S�p�[�e�B�[�����o�ɑ��M
	case PARTY_SAMEMAP_WOS:	// �����ȊO�̓����}�b�v�̑S�p�[�e�B�[�����o�ɑ��M
		if (sd && sd->status.party_id)
			p = party_search(sd->status.party_id);
			
		if (p) {
			for(i=0;i<MAX_PARTY;i++){
				if ((sd = p->member[i].sd) != NULL) {
					if (!sd->fd || session[sd->fd] == NULL || sd->state.auth == 0
						|| session[sd->fd]->session_data == NULL || sd->packet_ver > MAX_PACKET_VER)
						continue;
					
					if (sd->bl.id == bl->id && (type == PARTY_WOS || type == PARTY_SAMEMAP_WOS || type == PARTY_AREA_WOS))
						continue;
					
					if (type != PARTY && type != PARTY_WOS && bl->m != sd->bl.m) // �}�b�v�`�F�b�N
						continue;
					
					if ((type == PARTY_AREA || type == PARTY_AREA_WOS) &&
						(sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1))
						continue;
					
					if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
						WFIFOHEAD(sd->fd,len);
						memcpy(WFIFOP(sd->fd,0), buf, len);
						WFIFOSET(sd->fd,len);
					}
				}
			}
			if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
				break;
			for (i = 1; i < fd_max; i++){ // partyspy [Syrus22]
				if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->fd && sd->partyspy) {
					if (sd->partyspy == p->party_id) {
						if (sd->fd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
							WFIFOHEAD(sd->fd,len);
							memcpy(WFIFOP(sd->fd,0), buf, len);
							WFIFOSET(sd->fd,len);
						}
					}
				}
			}
		}
		break;
	case SELF:
		if (sd && sd->fd && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
			WFIFOHEAD(sd->fd,len);
			memcpy(WFIFOP(sd->fd,0), buf, len);
			WFIFOSET(sd->fd,len);
		}
		break;

// New definitions for guilds [Valaris] - Cleaned up and reorganized by [Skotlex]
	case GUILD_AREA:
	case GUILD_AREA_WOS:
		x0 = bl->x - AREA_SIZE;
		y0 = bl->y - AREA_SIZE;
		x1 = bl->x + AREA_SIZE;
		y1 = bl->y + AREA_SIZE;
	case GUILD_SAMEMAP:
	case GUILD_SAMEMAP_WOS:
	case GUILD:
	case GUILD_WOS:
		if (sd && sd->status.guild_id)
			g = guild_search(sd->status.guild_id);

		if (g) {
			for(i = 0; i < g->max_member; i++) {
				if ((sd = g->member[i].sd) != NULL) {
					if (!sd->fd || session[sd->fd] == NULL || sd->state.auth == 0
						|| session[sd->fd]->session_data == NULL || sd->packet_ver > MAX_PACKET_VER)
						continue;
					
					if (sd->bl.id == bl->id && (type == GUILD_WOS || type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS))
						continue;
					
					if (type != GUILD && type != GUILD_WOS && sd->bl.m != bl->m)
						continue;
					
					if ((type == GUILD_AREA || type == GUILD_AREA_WOS) &&
						(sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1))
						continue;

					if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
						WFIFOHEAD(sd->fd,len);
						memcpy(WFIFOP(sd->fd,0), buf, len);
						WFIFOSET(sd->fd,len);
					}
				}
			}
			if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
				break;
			for (i = 1; i < fd_max; i++){ // guildspy [Syrus22]
				if (session[i] && (sd = (struct map_session_data*)session[i]->session_data) != NULL && sd->state.auth && sd->fd && sd->guildspy) {
					if (sd->guildspy == g->guild_id) {
						if (packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
							WFIFOHEAD(sd->fd,len);
							memcpy(WFIFOP(sd->fd,0), buf, len);
							WFIFOSET(sd->fd,len);
						}
					}
				}
			}
		}
		break;
/*				End [Valaris]			*/

	default:
		if (battle_config.error_log)
			ShowError("clif_send: Unrecognized type %d\n",type);
		return -1;
	}

	return 0;
}

//
// �p�P�b�g����đ��M
//
/*==========================================
 *
 *------------------------------------------
 */
int clif_authok(struct map_session_data *sd) {
	int fd;

	if (!sd->fd)
		return 0;
	fd = sd->fd;

	WFIFOHEAD(fd, packet_len_table[0x73]);
	WFIFOW(fd, 0) = 0x73;
	WFIFOL(fd, 2) = gettick();
	WFIFOPOS(fd, 6, sd->bl.x, sd->bl.y);
	WFIFOB(fd, 9) = 5;
	WFIFOB(fd,10) = 5;
	WFIFOSET(fd,packet_len_table[0x73]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_authfail_fd(int fd, int type) {
	if (!fd || !session[fd] || session[fd]->func_parse != clif_parse) //clif_authfail should only be invoked on players!
		return 0;

	WFIFOHEAD(fd, packet_len_table[0x81]);
	WFIFOW(fd,0) = 0x81;
	WFIFOB(fd,2) = type;
	WFIFOSET(fd,packet_len_table[0x81]);
	clif_setwaitclose(fd);
	return 0;
}

/*==========================================
 * Used to know which is the max valid account/char id [Skotlex]
 *------------------------------------------
 */
void clif_updatemaxid(int account_id, int char_id)
{
	max_account_id = account_id;
	max_char_id = char_id;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_charselectok(int id) {
	struct map_session_data *sd;
	int fd;

	if ((sd = map_id2sd(id)) == NULL)
		return 1;

	if (!sd->fd)
		return 1;

	fd = sd->fd;
	WFIFOHEAD(fd, packet_len_table[0xb3]);
	WFIFOW(fd,0) = 0xb3;
	WFIFOB(fd,2) = 1;
	WFIFOSET(fd,packet_len_table[0xb3]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
static int clif_set009e(struct flooritem_data *fitem,unsigned char *buf) {
	int view;

	nullpo_retr(0, fitem);

	//009e <ID>.l <name ID>.w <identify flag>.B <X>.w <Y>.w <subX>.B <subY>.B <amount>.w
	WBUFW(buf, 0) = 0x9e;
	WBUFL(buf, 2) = fitem->bl.id;
	if ((view = itemdb_viewid(fitem->item_data.nameid)) > 0)
		WBUFW(buf, 6) = view;
	else
		WBUFW(buf, 6) = fitem->item_data.nameid;
	WBUFB(buf, 8) = fitem->item_data.identify;
	WBUFW(buf, 9) = fitem->bl.x;
	WBUFW(buf,11) = fitem->bl.y;
	WBUFB(buf,13) = fitem->subx;
	WBUFB(buf,14) = fitem->suby;
	WBUFW(buf,15) = fitem->item_data.amount;

	return packet_len_table[0x9e];
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_dropflooritem(struct flooritem_data *fitem) {
	unsigned char buf[64];

	nullpo_retr(0, fitem);

	if (fitem->item_data.nameid <= 0)
		return 0;
	clif_set009e(fitem, buf);
	clif_send(buf, packet_len_table[0x9e], &fitem->bl, AREA);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_clearflooritem(struct flooritem_data *fitem, int fd) {
	unsigned char buf[16];

	nullpo_retr(0, fitem);

	WBUFW(buf,0) = 0xa1;
	WBUFL(buf,2) = fitem->bl.id;

	if (fd == 0) {
		clif_send(buf, packet_len_table[0xa1], &fitem->bl, AREA);
	} else {
		WFIFOHEAD(fd,packet_len_table[0xa1]);
		memcpy(WFIFOP(fd,0), buf, 6);
		WFIFOSET(fd,packet_len_table[0xa1]);
	}

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_clearchar(struct block_list *bl, int type) {
	unsigned char buf[16];

	nullpo_retr(0, bl);

	WBUFW(buf,0) = 0x80;
	WBUFL(buf,2) = bl->id;
	WBUFB(buf,6) = type;

	clif_send(buf, packet_len_table[0x80], bl, type == 1 ? AREA : AREA_WOS);
	if(disguised(bl)) {
		WBUFL(buf,2) = -bl->id;
		clif_send(buf, packet_len_table[0x80], bl, SELF);
	}

	return 0;
}

static int clif_clearchar_delay_sub(int tid, unsigned int tick, int id, int data) {
	struct block_list *bl = (struct block_list *)id;

	clif_clearchar(bl,data);
	aFree(bl);
	return 0;
}

int clif_clearchar_delay(unsigned int tick, struct block_list *bl, int type) {
	struct block_list *tbl;
	tbl = aCalloc(1, sizeof (struct block_list));
	memcpy (tbl, bl, sizeof (struct block_list));
	add_timer(tick, clif_clearchar_delay_sub, (int)tbl, type);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_clearchar_id(int id, int type, int fd) {
	unsigned char buf[16];

	WBUFW(buf,0) = 0x80;
	WBUFL(buf,2) = id;
	WBUFB(buf,6) = type;
	WFIFOHEAD(fd, packet_len_table[0x80]);
	memcpy(WFIFOP(fd,0), buf, 7);
	WFIFOSET(fd, packet_len_table[0x80]);

	return 0;
}

void clif_get_weapon_view(TBL_PC* sd, short *rhand, short *lhand)
{
#if PACKETVER > 3
	struct item_data *id;
#endif
	if (sd->vd.class_ == JOB_XMAS || sd->vd.class_ == JOB_WEDDING)
	{
		*rhand = *lhand = 0;
		return;
	}

#if PACKETVER < 4
	*rhand = sd->status.weapon;
	*lhand = sd->status.shield;
#else
	if (sd->equip_index[9] >= 0 && sd->inventory_data[sd->equip_index[9]]) 
	{
		id = sd->inventory_data[sd->equip_index[9]];
		if (id->view_id > 0)
			*rhand = id->view_id;
		else
			*rhand = id->nameid;
	} else
		*rhand = 0;

	if (sd->equip_index[8] >= 0 && sd->equip_index[8] != sd->equip_index[9]
			&& sd->inventory_data[sd->equip_index[8]]) 
	{
		id = sd->inventory_data[sd->equip_index[8]];
		if (id->view_id > 0)
			*lhand = id->view_id;
		else
			*lhand = id->nameid;
	} else
		*lhand = 0;
#endif
}	

static void clif_get_guild_data(struct block_list *bl, long *guild_id, short *emblem_id) 
{
	//TODO: There has to be a way to clean this up.
	switch (bl->type) {
		case BL_PC:
			*guild_id = ((TBL_PC*)bl)->status.guild_id;
			*emblem_id = ((TBL_PC*)bl)->guild_emblem_id;
			break;
		case BL_MOB:
			if (((TBL_MOB*)bl)->guardian_data) {
				*guild_id =((TBL_MOB*)bl)->guardian_data->guild_id;
				*emblem_id =((TBL_MOB*)bl)->guardian_data->emblem_id;
			}
			break;
		case BL_NPC:
			if (bl->subtype == SCRIPT && ((TBL_NPC*)bl)->u.scr.guild_id > 0) {
				struct guild *g = guild_search(((TBL_NPC*)bl)->u.scr.guild_id);
				if (g) {
					*guild_id =g->guild_id;
					*emblem_id =g->emblem_id;
				}
			}
			break;
		default:
			*guild_id = status_get_guild_id(bl);
	}
	return;
}
/*==========================================
 *
 *------------------------------------------
 */
static int clif_set0078(struct block_list *bl, struct view_data *vd, unsigned char *buf) {
	struct status_change *sc;
	struct map_session_data *sd;
	long guild_id=0;
	unsigned short emblem_id=0, lv;
	unsigned short dir;

	nullpo_retr(0, bl);
	BL_CAST(BL_PC, bl, sd);
	sc = status_get_sc(bl);

	clif_get_guild_data(bl, &guild_id, &emblem_id);
	dir = unit_getdir(bl);
	lv = status_get_lv(bl);
	if(pcdb_checkid(vd->class_)) { 
#if PACKETVER > 3
		memset(buf,0,packet_len_table[0x1d8]);

		WBUFW(buf,0)=0x1d8;
		WBUFL(buf,2)=bl->id;
		WBUFW(buf,6)=status_get_speed(bl);
		if (sc) {
			WBUFW(buf,8)=sc->opt1;
			WBUFW(buf,10)=sc->opt2;
			WBUFW(buf,12)=sc->option;
			WBUFW(buf,42)=sc->opt3;
		}
		WBUFW(buf,14)=vd->class_;
		WBUFW(buf,16)=vd->hair_style;
		WBUFW(buf,18)=vd->weapon;
		WBUFW(buf,20)=vd->shield;
		WBUFW(buf,22)=vd->head_bottom;
		WBUFW(buf,24)=vd->head_top;
		WBUFW(buf,26)=vd->head_mid;
		WBUFW(buf,28)=vd->hair_color;
		WBUFW(buf,30)=vd->cloth_color;
		WBUFW(buf,32)=sd?sd->head_dir:dir;
		WBUFL(buf,34)=guild_id;
		WBUFL(buf,38)=emblem_id;
		if (sd) {
			WBUFW(buf,40)=sd->status.manner;
			WBUFB(buf,44)=sd->status.karma;
		}
		WBUFB(buf,45)=vd->sex;
		WBUFPOS(buf,46,bl->x,bl->y);
		WBUFB(buf,48)|=dir & 0x0f;
		WBUFB(buf,49)=5;
		WBUFB(buf,50)=5;
		WBUFB(buf,51)=vd->dead_sit;
		WBUFW(buf,52)=clif_setlevel(lv);
		return packet_len_table[0x1d8];
#else
		memset(buf,0,packet_len_table[0x78]);

		WBUFW(buf,0)=0x78;
		WBUFL(buf,2)=bl->id;
		WBUFW(buf,6)=status_get_speed(bl);
		if (sc) {
			WBUFW(buf,8)=sc->opt1;
			WBUFW(buf,10)=sc->opt2;
			WBUFW(buf,12)=sc->option;
		}
		WBUFW(buf,14)=vd->class_;
		WBUFW(buf,16)=vd->hair_style;
		WBUFW(buf,18)=vd->weapon;
		WBUFW(buf,20)=vd->head_bottom;
		WBUFW(buf,22)=vd->shield;
		WBUFW(buf,24)=vd->head_top;
		WBUFW(buf,26)=vd->head_mid;
		WBUFW(buf,28)=vd->hair_color;
		WBUFW(buf,30)=vd->cloth_color;
		WBUFW(buf,32)=sd?sd->head_dir:dir;
		WBUFL(buf,34)=guild_id;
		WBUFL(buf,38)=emblem_id;
		if (sd) {
			WBUFW(buf,42)=sd->status.manner;
			WBUFB(buf,44)=sd->status.karma;
		}
		WBUFB(buf,45)=vd->sex;
		WBUFPOS(buf,46,bl->x,bl->y);
		WBUFB(buf,48)|=dir&0x0f;
		WBUFB(buf,49)=5;
		WBUFB(buf,50)=5;
		WBUFB(buf,51)=vd->dead_sit;
		WBUFW(buf,52)=clif_setlevel(lv);
		return packet_len_table[0x78];
#endif
	}
	//Non-player sprites need just a few fields filled.
	memset(buf,0,packet_len_table[0x78]);

	WBUFW(buf,0)=0x78;
	WBUFL(buf,2)=bl->id;
	WBUFW(buf,6)=status_get_speed(bl);
	if (sc) {
		WBUFW(buf,8)=sc->opt1;
		WBUFW(buf,10)=sc->opt2;
		WBUFW(buf,12)=sc->option;
	}
	WBUFW(buf,14)=vd->class_;
	WBUFW(buf,16)=vd->hair_style;  //Required for pets.
	WBUFW(buf,22)=vd->shield;	//Pet armor
	if (bl->type == BL_NPC && vd->class_ == 722)
	{	//The hell, why flags work like this?
		WBUFL(buf,22)=emblem_id;
		WBUFL(buf,26)=guild_id;
	}
	WBUFW(buf,32)=dir;
	WBUFL(buf,34)=guild_id;
	WBUFL(buf,38)=emblem_id;
	WBUFPOS(buf,46,bl->x,bl->y);
	WBUFB(buf,48)|=dir&0x0f;
	WBUFB(buf,49)=5;
	WBUFB(buf,50)=5;
	WBUFW(buf,52)=clif_setlevel(lv);
	return packet_len_table[0x78];
}

/*==========================================
 *
 *------------------------------------------
 */
static int clif_set007b(struct block_list *bl, struct view_data *vd, struct unit_data *ud, unsigned char *buf) {
	struct status_change *sc;
	struct map_session_data *sd;
	long guild_id=0;
	unsigned short emblem_id=0, lv;

	nullpo_retr(0, bl);
	BL_CAST(BL_PC, bl, sd);
	sc = status_get_sc(bl);
	
	clif_get_guild_data(bl, &guild_id, &emblem_id);
	lv = status_get_lv(bl);
	
	if(pcdb_checkid(vd->class_)) { 
#if PACKETVER > 3
		memset(buf,0,packet_len_table[0x1da]);

		WBUFW(buf,0)=0x1da;
		WBUFL(buf,2)=bl->id;
		WBUFW(buf,6)=status_get_speed(bl);
		if (sc) {
			WBUFW(buf,8)=sc->opt1;
			WBUFW(buf,10)=sc->opt2;
			WBUFW(buf,12)=sc->option;
			WBUFW(buf,46)=sc->opt3;
		}
		WBUFW(buf,14)=vd->class_;
		WBUFW(buf,16)=vd->hair_style;
		WBUFW(buf,18)=vd->weapon;
		WBUFW(buf,20)=vd->shield;
		WBUFW(buf,22)=vd->head_bottom;
		WBUFL(buf,24)=gettick();
		WBUFW(buf,28)=vd->head_top;
		WBUFW(buf,30)=vd->head_mid;
		WBUFW(buf,32)=vd->hair_color;
		WBUFW(buf,34)=vd->cloth_color;
		WBUFW(buf,36)=sd?sd->head_dir:unit_getdir(bl);
		WBUFL(buf,38)=guild_id;
		WBUFW(buf,42)=emblem_id;
		if (sd) {
			WBUFW(buf,44)=sd->status.manner;
			WBUFB(buf,48)=sd->status.karma;
		}
		WBUFB(buf,49)=vd->sex;
		WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y);
		WBUFB(buf,55)=0x88; // Deals with acceleration in directions. [Valaris]
		WBUFB(buf,56)=5;
		WBUFB(buf,57)=5;
		WBUFW(buf,58)=clif_setlevel(lv);

		return packet_len_table[0x1da];
#else
		memset(buf,0,packet_len_table[0x7b]);

		WBUFW(buf,0)=0x7b;
		WBUFL(buf,2)=bl->id;
		WBUFW(buf,6)=status_get_speed(bl);
		if (sc) {
			WBUFW(buf,8)=sc->opt1;
			WBUFW(buf,10)=sc->opt2;
			WBUFW(buf,12)=sc->option;
			WBUFW(buf,46)=sc->opt3;
		}
		WBUFW(buf,14)=vd->class_;
		WBUFW(buf,16)=vd->hair_style;
		WBUFW(buf,18)=vd->weapon;
		WBUFW(buf,20)=vd->head_bottom;
		WBUFL(buf,22)=gettick();
		WBUFW(buf,26)=vd->shield;
		WBUFW(buf,28)=vd->head_top;
		WBUFW(buf,30)=vd->head_mid;
		WBUFW(buf,32)=vd->hair_color;
		WBUFW(buf,34)=vd->cloth_color;
		WBUFW(buf,36)=sd?sd->head_dir:unit_getdir(bl);
		WBUFL(buf,38)=guild_id;
		WBUFL(buf,42)=emblem_id;
		if (sd)
			WBUFB(buf,48)=sd->status.karma;
		WBUFB(buf,49)=vd->sex;
		WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y);
		WBUFB(buf,55)=0x88; // Deals with acceleration in directions. [Valaris]
		WBUFB(buf,56)=5;
		WBUFB(buf,57)=5;
		WBUFW(buf,58)=clif_setlevel(lv);

		return packet_len_table[0x7b];
#endif
	}
	//Non-player sprites only require a few fields.
	memset(buf,0,packet_len_table[0x7b]);

	WBUFW(buf,0)=0x7b;
	WBUFL(buf,2)=bl->id;
	WBUFW(buf,6)=status_get_speed(bl);
	if (sc) {
		WBUFW(buf,8)=sc->opt1;
		WBUFW(buf,10)=sc->opt2;
		WBUFW(buf,12)=sc->option;
		WBUFW(buf,46)=sc->opt3;
	}
	WBUFW(buf,14)=vd->class_;
	WBUFW(buf,16)=vd->hair_style; //For pets
	WBUFL(buf,22)=gettick();
	WBUFW(buf,26)=vd->shield;	//Pet armor
	WBUFW(buf,36)=unit_getdir(bl);
	WBUFL(buf,38)=guild_id;
	WBUFL(buf,42)=emblem_id;
	WBUFPOS2(buf,50,bl->x,bl->y,ud->to_x,ud->to_y);
	WBUFB(buf,55)=0x88; // Deals with acceleration in directions. [Valaris]
	WBUFB(buf,56)=5;
	WBUFB(buf,57)=5;
	WBUFW(buf,58)=clif_setlevel(lv);

	return packet_len_table[0x7b];
}

//Modifies the buffer for disguise characters and sends it to self.
//Flag = 0: change id to negative, buf will have disguise data.
//Flag = 1: change id to positive, class and option to make your own char invisible.
//Luckily, the offsets that need to be changed are the same in packets 0x78, 0x7b, 0x1d8 and 0x1da
static void clif_setdisguise(struct map_session_data *sd, unsigned char *buf,int len, int flag) {
	if (flag) {
		WBUFL(buf,2)=sd->bl.id;
		WBUFW(buf,12)=OPTION_INVISIBLE;
		WBUFW(buf,14)=sd->status.class_;
	} else {
		WBUFL(buf,2)=-sd->bl.id;
	}
	clif_send(buf, len, &sd->bl, SELF);
}

/*==========================================
 * �N���X�`�F���W type��Mob�̏ꍇ��1�ő���0�H
 *------------------------------------------
 */
int clif_class_change(struct block_list *bl,int class_,int type)
{
	unsigned char buf[16];

	nullpo_retr(0, bl);

	if(!pcdb_checkid(class_)) {
		WBUFW(buf,0)=0x1b0;
		WBUFL(buf,2)=bl->id;
		WBUFB(buf,6)=type;
		WBUFL(buf,7)=class_;
		clif_send(buf,packet_len_table[0x1b0],bl,AREA);
	}
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
static void clif_spiritball_single(int fd, struct map_session_data *sd)
{
	WFIFOHEAD(fd, packet_len_table[0x1e1]);
	WFIFOW(fd,0)=0x1e1;
	WFIFOL(fd,2)=sd->bl.id;
	WFIFOW(fd,6)=sd->spiritball;
	WFIFOSET(fd, packet_len_table[0x1e1]);
}

/*==========================================
 *
 *------------------------------------------
 */
static int clif_set0192(int fd, int m, int x, int y, int type) {
	WFIFOHEAD(fd, packet_len_table[0x192]);
	WFIFOW(fd,0) = 0x192;
	WFIFOW(fd,2) = x;
	WFIFOW(fd,4) = y;
	WFIFOW(fd,6) = type;
	memcpy(WFIFOP(fd,8),map[m].name,MAP_NAME_LENGTH);
	WFIFOSET(fd,packet_len_table[0x192]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
static void clif_weather_check(struct map_session_data *sd) {
	int m = sd->bl.m, fd = sd->fd;
	
	if (map[m].flag.snow
		|| map[m].flag.clouds
		|| map[m].flag.fog
		|| map[m].flag.fireworks
		|| map[m].flag.sakura
		|| map[m].flag.leaves
		|| map[m].flag.rain
		|| map[m].flag.clouds2)
	{
		WFIFOHEAD(fd, packet_len_table[0x7c]);
		WFIFOW(fd,0)=0x7c;
		WFIFOL(fd,2)=-10;
		WFIFOW(fd,6)=0;
		WFIFOW(fd,8)=0;
		WFIFOW(fd,10)=0;
		WFIFOW(fd,12)=OPTION_INVISIBLE;
		WFIFOW(fd,20)=100;
		WFIFOPOS(fd,36,sd->bl.x,sd->bl.y);
		WFIFOSET(fd,packet_len_table[0x7c]);

		if (map[m].flag.snow)
			clif_weather_sub(fd, 162);
		if (map[m].flag.clouds)
			clif_weather_sub(fd, 233);
		if (map[m].flag.clouds2)
			clif_weather_sub(fd, 516);
		if (map[m].flag.fog)
			clif_weather_sub(fd, 515);
		if (map[m].flag.fireworks) {
			clif_weather_sub(fd, 297);
			clif_weather_sub(fd, 299);
			clif_weather_sub(fd, 301);
		}
		if (map[m].flag.sakura)
			clif_weather_sub(fd, 163);
		if (map[m].flag.leaves)
			clif_weather_sub(fd, 333);
		if (map[m].flag.rain)
			clif_weather_sub(fd, 161);
	}
}

// new and improved weather display [Valaris]
int clif_weather_sub(int fd, int type) {
	WFIFOHEAD(fd, packet_len_table[0x1f3]);
	WFIFOW(fd,0) = 0x1f3;
	WFIFOL(fd,2) = -10;
	WFIFOL(fd,6) = type;
	WFIFOSET(fd,packet_len_table[0x1f3]);

	return 0;
}

int clif_weather(int m) {
	int i;

	struct map_session_data *sd=NULL;

	for(i = 0; i < fd_max; i++) {
		if (session[i] && (sd = session[i]->session_data) != NULL && sd->state.auth && sd->bl.m == m) {
			WFIFOHEAD(sd->fd, packet_len_table[0x80]);
			WFIFOW(sd->fd,0) = 0x80;
			WFIFOL(sd->fd,2) = -10;
			WFIFOB(sd->fd,6) = 0;
			WFIFOSET(sd->fd,packet_len_table[0x80]);

			clif_weather_check(sd);
		}
	}

	return 0;
}

int clif_spawn(struct block_list *bl)
{
	unsigned char buf[128];
	struct view_data *vd;
	nullpo_retr(0, bl);
	vd = status_get_viewdata(bl);
	if (!vd || vd->class_ == INVISIBLE_CLASS)
		return 0;

	if (pcdb_checkid(vd->class_))
	{	//Player spawn packet.
		clif_set0078(bl, vd, buf);
#if PACKETVER > 3
		if (WBUFW(buf,0)==0x78) {
			WBUFW(buf, 0) = 0x79;
			WBUFW(buf,51) = WBUFW(buf,52); //Lv is placed on offset 52
			clif_send(buf, packet_len_table[0x79], bl, AREA_WOS);
			if (disguised(bl))
				clif_setdisguise((TBL_PC*)bl, buf, packet_len_table[0x79], 0);
		} else {
#endif
			WBUFW(buf, 0) = 0x1d9;
			WBUFW(buf,51) = WBUFW(buf,52); //Lv is placed on offset 52
			clif_send(buf, packet_len_table[0x1d9], bl, AREA_WOS);
			if (disguised(bl))
				clif_setdisguise((TBL_PC*)bl, buf, packet_len_table[0x1d9], 0);
#if PACKETVER > 3
		}
#endif

	} else {	//Mob spawn packet.
		struct status_change *sc = status_get_sc(bl);
		WBUFW(buf,0)=0x7c;
		WBUFL(buf,2)=bl->id;
		WBUFW(buf,6)=status_get_speed(bl);
		WBUFW(buf,8)=sc?sc->opt1:0;
		WBUFW(buf,10)=sc?sc->opt2:0;
		WBUFW(buf,12)=sc?sc->option:0;
		WBUFW(buf,20)=vd->class_;
		WBUFPOS(buf,36,bl->x,bl->y);
		clif_send(buf,packet_len_table[0x7c],bl,AREA_WOS);
		if (disguised(bl)) {
			WBUFL(buf,2)=-bl->id;
			clif_send(buf,packet_len_table[0x7c],bl,SELF);
		}
	}
	
	if (vd->cloth_color)
		clif_refreshlook(bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,AREA_WOS);
		
	switch (bl->type)
	{
	case BL_PC:
		{
			TBL_PC *sd = ((TBL_PC*)bl);
			if (sd->spiritball > 0)
				clif_spiritball(sd);
			if(sd->state.size==2) // tiny/big players [Valaris]
				clif_specialeffect(bl,423,0);
			else if(sd->state.size==1)
				clif_specialeffect(bl,421,0);
		}
	break;
	case BL_MOB:
		{
			TBL_MOB *md = ((TBL_MOB*)bl);
			if(md->special_state.size==2) // tiny/big mobs [Valaris]
				clif_specialeffect(&md->bl,423,0);
			else if(md->special_state.size==1)
				clif_specialeffect(&md->bl,421,0);
		}
	break;
	}
	return 0;
}
/*==========================================
 *
 *------------------------------------------
 */
int clif_servertick(struct map_session_data *sd)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, packet_len_table[0x7f]);
	WFIFOW(fd,0)=0x7f;
	WFIFOL(fd,2)=sd->server_tick;
	WFIFOSET(fd,packet_len_table[0x7f]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_walkok(struct map_session_data *sd)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, packet_len_table[0x87]);
	WFIFOW(fd,0)=0x87;
	WFIFOL(fd,2)=gettick();
	WFIFOPOS2(fd,6,sd->bl.x,sd->bl.y,sd->ud.to_x,sd->ud.to_y);
	WFIFOB(fd,11)=0x88;
	WFIFOSET(fd,packet_len_table[0x87]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_movepc(struct map_session_data *sd) {
	unsigned char buf[256];

	nullpo_retr(0, sd);

	if (map[sd->bl.m].flag.snow
		|| map[sd->bl.m].flag.clouds
		|| map[sd->bl.m].flag.fog
		|| map[sd->bl.m].flag.fireworks
		|| map[sd->bl.m].flag.sakura
		|| map[sd->bl.m].flag.leaves
		|| map[sd->bl.m].flag.rain
		|| map[sd->bl.m].flag.clouds2
	) {
		memset(buf,0,packet_len_table[0x7b]);
		WBUFW(buf,0)=0x7b;
		WBUFL(buf,2)=-10;
		WBUFW(buf,6)=sd->speed;
		WBUFW(buf,8)=0;
		WBUFW(buf,10)=0;
		WBUFW(buf,12)=OPTION_INVISIBLE;
		WBUFW(buf,14)=100;
		WBUFL(buf,22)=gettick();
		WBUFPOS2(buf,50,sd->bl.x,sd->bl.y,sd->ud.to_x,sd->ud.to_y);
		WBUFB(buf,56)=5;
		WBUFB(buf,57)=5;
		clif_send(buf, packet_len_table[0x7b], &sd->bl, SELF);
	}

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_move(struct block_list *bl) {
	struct view_data *vd;
	struct unit_data *ud;
	unsigned char buf[256];
	int len;

	nullpo_retr(0, bl);
	
	vd = status_get_viewdata(bl);
	if (!vd || vd->class_ == INVISIBLE_CLASS)
		return 0;
	
	ud = unit_bl2ud(bl);
	nullpo_retr(0, ud);
	
	len = clif_set007b(bl,vd,ud,buf);
	clif_send(buf,len,bl,AREA_WOS);
	if (disguised(bl))
		clif_setdisguise((TBL_PC*)bl, buf, len, 0);
		
	//Stupid client that needs this resent every time someone walks :X
	if(vd->cloth_color)
		clif_refreshlook(bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,AREA_WOS);

	switch(bl->type)
	{
	case BL_PC:
		{
			TBL_PC *sd = ((TBL_PC*)bl);
			clif_movepc(sd);
			if(sd->state.size==2) // tiny/big players [Valaris]
				clif_specialeffect(&sd->bl,423,0);
			else if(sd->state.size==1)
				clif_specialeffect(&sd->bl,421,0);
		}
		break;
	case BL_MOB:
		{
			TBL_MOB *md = ((TBL_MOB*)bl);
			if(md->special_state.size==2) // tiny/big mobs [Valaris]
				clif_specialeffect(&md->bl,423,0);
			else if(md->special_state.size==1)
				clif_specialeffect(&md->bl,421,0);
		}
		break;
	}
	return 0;
}


/*==========================================
 * Delays the map_quit of a player after they are disconnected. [Skotlex]
 *------------------------------------------
 */
static int clif_delayquit(int tid, unsigned int tick, int id, int data) {
	struct map_session_data *sd = NULL;

	if (chrif_isconnect())
	{	//Remove player from map server
		if ((sd = map_id2sd(id)) != NULL && sd->fd == 0) //Should be a disconnected player.
			map_quit(sd);
	} else //Save later.
		add_timer(tick + 10000, clif_delayquit, id, 0);
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_quitsave(int fd,struct map_session_data *sd)
{
	if (chrif_isconnect() && (sd->state.waitingdisconnect || //Was already waiting to be disconnected.
		!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout))
		map_quit(sd);
	else if (sd->fd)
	{	//Disassociate session from player (session is deleted after this function was called)
		//And set a timer to delete this player later.
		session[fd]->session_data = NULL;
		sd->fd = 0;
		add_timer(gettick() + 10000, clif_delayquit, sd->bl.id, 0);
	}
}

/*==========================================
 *
 *------------------------------------------
 */
static int clif_waitclose(int tid, unsigned int tick, int id, int data) {
	if (session[id] && session[id]->func_parse == clif_parse) //Avoid disconnecting non-players, as pointed out by End of Exam [Skotlex]
		session[id]->eof = 1;

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_setwaitclose(int fd) {
	struct map_session_data *sd;

	// if player is not already in the game (double connection probably)
	if ((sd = (struct map_session_data*)session[fd]->session_data) == NULL) {
		// limited timer, just to send information.
		add_timer(gettick() + 1000, clif_waitclose, fd, 0);
	} else
		add_timer(gettick() + 5000, clif_waitclose, fd, 0);
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_changemap(struct map_session_data *sd, short map, int x, int y) {
	int fd;
	
	nullpo_retr(0, sd);

	fd = sd->fd;
	
	WFIFOHEAD(fd, packet_len_table[0x91]);
	WFIFOW(fd,0) = 0x91;
	memcpy(WFIFOP(fd,2), mapindex_id2name(map), MAP_NAME_LENGTH);
	WFIFOW(fd,18) = x;
	WFIFOW(fd,20) = y;
	WFIFOSET(fd, packet_len_table[0x91]);

	if(pc_isdead(sd)) // If player is dead, and is spawned (such as @refresh) send death packet. [Valaris]
		clif_clearchar_area(&sd->bl,1);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_changemapserver(struct map_session_data *sd, char *mapname, int x, int y, int ip, int port) {
	int fd;

	nullpo_retr(0, sd);

	fd = sd->fd;
	WFIFOHEAD(fd, packet_len_table[0x92]);
	WFIFOW(fd,0) = 0x92;
	//Better not trust the null-terminator is there. [Skotlex]
	memcpy(WFIFOP(fd,2), mapname, MAP_NAME_LENGTH);
	WFIFOB(fd,17) = 0;	//Null terminator for mapname
	WFIFOW(fd,18) = x;
	WFIFOW(fd,20) = y;
	WFIFOL(fd,22) = ip;
	WFIFOW(fd,26) = port;
	WFIFOSET(fd, packet_len_table[0x92]);
	
	return 0;
}

int clif_blown(struct block_list *bl) {
//Previous Aegis versions simply used clif_fixpos, but it seems clif_slide works better on current clients.
//	return clif_fixpos(bl);
	return clif_slide(bl, bl->x, bl->y);
	
}
/*==========================================
 *
 *------------------------------------------
 */
int clif_fixpos(struct block_list *bl) {
	unsigned char buf[16];

	nullpo_retr(0, bl);

	WBUFW(buf,0)=0x88;
	WBUFL(buf,2)=bl->id;
	WBUFW(buf,6)=bl->x;
	WBUFW(buf,8)=bl->y;
	clif_send(buf, packet_len_table[0x88], bl, AREA);
	if (disguised(bl)) {
		WBUFL(buf,2)=-bl->id;
		clif_send(buf, packet_len_table[0x88], bl, SELF);
	}
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_npcbuysell(struct map_session_data* sd, int id) {
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, packet_len_table[0xc4]);
	WFIFOW(fd,0)=0xc4;
	WFIFOL(fd,2)=id;
	WFIFOSET(fd,packet_len_table[0xc4]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_buylist(struct map_session_data *sd, struct npc_data *nd) {
	struct item_data *id;
	int fd,i,val;

	nullpo_retr(0, sd);
	nullpo_retr(0, nd);

	fd=sd->fd;
 	WFIFOHEAD(fd, 200 * 11 + 4);
	WFIFOW(fd,0)=0xc6;
	for(i=0;nd->u.shop_item[i].nameid > 0;i++){
		id = itemdb_search(nd->u.shop_item[i].nameid);
		val=nd->u.shop_item[i].value;
		WFIFOL(fd,4+i*11)=val;
		if (!id->flag.value_notdc)
			val=pc_modifybuyvalue(sd,val);
		WFIFOL(fd,8+i*11)=val;
		WFIFOB(fd,12+i*11)=itemtype(id->type);
		if (id->view_id > 0)
			WFIFOW(fd,13+i*11)=id->view_id;
		else
			WFIFOW(fd,13+i*11)=nd->u.shop_item[i].nameid;
	}
	WFIFOW(fd,2)=i*11+4;
	WFIFOSET(fd,WFIFOW(fd,2));

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_selllist(struct map_session_data *sd) {
	int fd,i,c=0,val;

	nullpo_retr(0, sd);

	fd=sd->fd;
        WFIFOHEAD(fd, MAX_INVENTORY * 10 + 4);
	WFIFOW(fd,0)=0xc7;
	for(i=0;i<MAX_INVENTORY;i++) {
		if(sd->status.inventory[i].nameid > 0 && sd->inventory_data[i]) {
			if (!itemdb_cansell(sd->status.inventory[i].nameid, pc_isGM(sd)))
				continue;

			val=sd->inventory_data[i]->value_sell;
			if (val < 0)
				continue;
			WFIFOW(fd,4+c*10)=i+2;
			WFIFOL(fd,6+c*10)=val;
			if (!sd->inventory_data[i]->flag.value_notoc)
				val=pc_modifysellvalue(sd,val);
			WFIFOL(fd,10+c*10)=val;
			c++;
		}
	}
	WFIFOW(fd,2)=c*10+4;
	WFIFOSET(fd,WFIFOW(fd,2));

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_scriptmes(struct map_session_data *sd, int npcid, char *mes) {
	int fd;
	int slen = strlen(mes) + 9;
	WFIFOHEAD(fd, slen);

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOW(fd,0)=0xb4;
	WFIFOW(fd,2)=slen;
	WFIFOL(fd,4)=npcid;
	strcpy((char*)WFIFOP(fd,8),mes);
	WFIFOSET(fd,WFIFOW(fd,2));

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_scriptnext(struct map_session_data *sd,int npcid) {
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, packet_len_table[0xb5]);
	WFIFOW(fd,0)=0xb5;
	WFIFOL(fd,2)=npcid;
	WFIFOSET(fd,packet_len_table[0xb5]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_scriptclose(struct map_session_data *sd, int npcid) {
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, packet_len_table[0xb6]);
	WFIFOW(fd,0)=0xb6;
	WFIFOL(fd,2)=npcid;
	WFIFOSET(fd,packet_len_table[0xb6]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_scriptmenu(struct map_session_data *sd, int npcid, char *mes) {
	int fd;
	int slen = strlen(mes) + 8;
	WFIFOHEAD(fd, slen);

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOW(fd,0)=0xb7;
	WFIFOW(fd,2)=slen;
	WFIFOL(fd,4)=npcid;
	strcpy((char*)WFIFOP(fd,8),mes);
	WFIFOSET(fd,WFIFOW(fd,2));

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_scriptinput(struct map_session_data *sd, int npcid) {
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
   WFIFOHEAD(fd, packet_len_table[0x142]);
	WFIFOW(fd,0)=0x142;
	WFIFOL(fd,2)=npcid;
	WFIFOSET(fd,packet_len_table[0x142]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_scriptinputstr(struct map_session_data *sd, int npcid) {
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, packet_len_table[0x1d4]);
	WFIFOW(fd,0)=0x1d4;
	WFIFOL(fd,2)=npcid;
	WFIFOSET(fd,packet_len_table[0x1d4]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_viewpoint(struct map_session_data *sd, int npc_id, int type, int x, int y, int id, int color) {
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, packet_len_table[0x144]);
	WFIFOW(fd,0)=0x144;
	WFIFOL(fd,2)=npc_id;
	WFIFOL(fd,6)=type;
	WFIFOL(fd,10)=x;
	WFIFOL(fd,14)=y;
	WFIFOB(fd,18)=id;
	WFIFOL(fd,19)=color;
	WFIFOSET(fd,packet_len_table[0x144]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_cutin(struct map_session_data *sd, char *image, int type) {
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, packet_len_table[0x1b3]);
	WFIFOW(fd,0)=0x1b3;
	strncpy((char*)WFIFOP(fd,2),image,64);
	WFIFOB(fd,66)=type;
	WFIFOSET(fd,packet_len_table[0x1b3]);

	return 0;
}

/*==========================================
 * Fills in card data from the given item and into the buffer. [Skotlex]
 *------------------------------------------
 */
static void clif_addcards(unsigned char* buf, struct item* item)
{
	int i=0,j;
	if (item == NULL) { //Blank data
		WBUFW(buf,0)=0;
		WBUFW(buf,2)=0;
		WBUFW(buf,4)=0;
		WBUFW(buf,6)=0;
		return;
	}
	if(item->card[0]==(short)0xff00) { //pet eggs
		WBUFW(buf,0)=0;
		WBUFW(buf,2)=0;
		WBUFW(buf,4)=0;
		WBUFW(buf,6)=item->card[3]; //Pet renamed flag.
		return;
	}
	if(item->card[0]==0x00ff || item->card[0]==0x00fe) { //Forged/created items
		WBUFW(buf,0)=item->card[0];
		WBUFW(buf,2)=item->card[1];
		WBUFW(buf,4)=item->card[2];
		WBUFW(buf,6)=item->card[3];
		return;
	}
	//Client only receives four cards.. so randomly send them a set of cards. [Skotlex]
	if (MAX_SLOTS > 4 && (j = itemdb_slot(item->nameid)) > 4)
		i = rand()%(j-3); //eg: 6 slots, possible i values: 0->3, 1->4, 2->5 => i = rand()%3;

	//Normal items.
	if (item->card[i] > 0 && (j=itemdb_viewid(item->card[i])) > 0)
		WBUFW(buf,0)=j;
	else
		WBUFW(buf,0)= item->card[i];

	if (item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0)
		WBUFW(buf,2)=j;
	else
		WBUFW(buf,2)=item->card[i];

	if (item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0)
		WBUFW(buf,4)=j;
	else
		WBUFW(buf,4)=item->card[i];

	if (item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0)
		WBUFW(buf,6)=j;
	else
		WBUFW(buf,6)=item->card[i];
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_additem(struct map_session_data *sd, int n, int amount, int fail) {
	int fd;
	unsigned char *buf;

	nullpo_retr(0, sd);

	fd = sd->fd;
	if (!session_isActive(fd))  //Sasuke-
		return 0;

	WFIFOHEAD(fd,packet_len_table[0xa0]);
	buf = WFIFOP(fd,0);
	if(fail) {
		WBUFW(buf,0)=0xa0;
		WBUFW(buf,2)=n+2;
		WBUFW(buf,4)=amount;
		WBUFW(buf,6)=0;
		WBUFB(buf,8)=0;
		WBUFB(buf,9)=0;
		WBUFB(buf,10)=0;
		WBUFW(buf,11)=0;
		WBUFW(buf,13)=0;
		WBUFW(buf,15)=0;
		WBUFW(buf,17)=0;
		WBUFW(buf,19)=0;
		WBUFB(buf,21)=0;
		WBUFB(buf,22)=fail;
	} else {
		if (n<0 || n>=MAX_INVENTORY || sd->status.inventory[n].nameid <=0 || sd->inventory_data[n] == NULL)
			return 1;

		WBUFW(buf,0)=0xa0;
		WBUFW(buf,2)=n+2;
		WBUFW(buf,4)=amount;
		if (sd->inventory_data[n]->view_id > 0)
			WBUFW(buf,6)=sd->inventory_data[n]->view_id;
		else
			WBUFW(buf,6)=sd->status.inventory[n].nameid;
		WBUFB(buf,8)=sd->status.inventory[n].identify;
		WBUFB(buf,9)=sd->status.inventory[n].attribute;
		WBUFB(buf,10)=sd->status.inventory[n].refine;
		clif_addcards(WBUFP(buf,11), &sd->status.inventory[n]);
		WBUFW(buf,19)=pc_equippoint(sd,n);
		WBUFB(buf,21)=itemtype(sd->inventory_data[n]->type);
		WBUFB(buf,22)=fail;
	}

	WFIFOSET(fd,packet_len_table[0xa0]);
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_delitem(struct map_session_data *sd,int n,int amount)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
        WFIFOHEAD(fd, packet_len_table[0xaf]);
	WFIFOW(fd,0)=0xaf;
	WFIFOW(fd,2)=n+2;
	WFIFOW(fd,4)=amount;

	WFIFOSET(fd,packet_len_table[0xaf]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_itemlist(struct map_session_data *sd)
{
	int i,n,fd,arrow=-1;
	unsigned char *buf;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, MAX_INVENTORY * 10 + 4);
	buf = WFIFOP(fd,0);
#if PACKETVER < 5
	WBUFW(buf,0)=0xa3;
	for(i=0,n=0;i<MAX_INVENTORY;i++){
		if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL || itemdb_isequip2(sd->inventory_data[i]))
			continue;
		WBUFW(buf,n*10+4)=i+2;
		if (sd->inventory_data[i]->view_id > 0)
			WBUFW(buf,n*10+6)=sd->inventory_data[i]->view_id;
		else
			WBUFW(buf,n*10+6)=sd->status.inventory[i].nameid;
		WBUFB(buf,n*10+8)=itemtype(sd->inventory_data[i]->type);
		WBUFB(buf,n*10+9)=sd->status.inventory[i].identify;
		WBUFW(buf,n*10+10)=sd->status.inventory[i].amount;
		if (sd->inventory_data[i]->equip == 0x8000) {
			WBUFW(buf,n*10+12)=0x8000;
			if (sd->status.inventory[i].equip)
				arrow=i;	// �‚��łɖ���`�F�b�N
		} else
			WBUFW(buf,n*10+12)=0;
		n++;
	}
	if (n) {
		WBUFW(buf,2)=4+n*10;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
#else
	WBUFW(buf,0)=0x1ee;
	for(i=0,n=0;i<MAX_INVENTORY;i++){
		if(sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL || itemdb_isequip2(sd->inventory_data[i]))
			continue;
		WBUFW(buf,n*18+4)=i+2;
		if(sd->inventory_data[i]->view_id > 0)
			WBUFW(buf,n*18+6)=sd->inventory_data[i]->view_id;
		else
			WBUFW(buf,n*18+6)=sd->status.inventory[i].nameid;
		WBUFB(buf,n*18+8)=itemtype(sd->inventory_data[i]->type);
		WBUFB(buf,n*18+9)=sd->status.inventory[i].identify;
		WBUFW(buf,n*18+10)=sd->status.inventory[i].amount;
		if (sd->inventory_data[i]->equip == 0x8000) {
			WBUFW(buf,n*18+12)=0x8000;
			if(sd->status.inventory[i].equip)
				arrow=i;	// �‚��łɖ���`�F�b�N
		} else
			WBUFW(buf,n*18+12)=0;
		clif_addcards(WBUFP(buf, n*18+14), &sd->status.inventory[i]);
		n++;
	}
	if (n) {
		WBUFW(buf,2)=4+n*18;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
#endif
	if(arrow >= 0)
		clif_arrowequip(sd,arrow);
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_equiplist(struct map_session_data *sd)
{
	int i,n,fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	if (!session_isActive(fd))
		return 0;
        WFIFOHEAD(fd, 4 + MAX_INVENTORY * 20);
	WFIFOW(fd,0)=0xa4;
	for(i=0,n=0;i<MAX_INVENTORY;i++){
		if(sd->status.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL || !itemdb_isequip2(sd->inventory_data[i]))
			continue;
		WFIFOW(fd,n*20+4)=i+2;
		if(sd->inventory_data[i]->view_id > 0)
			WFIFOW(fd,n*20+6)=sd->inventory_data[i]->view_id;
		else
			WFIFOW(fd,n*20+6)=sd->status.inventory[i].nameid;
		WFIFOB(fd,n*20+8)=itemtype(sd->inventory_data[i]->type);
		WFIFOB(fd,n*20+9)=sd->status.inventory[i].identify;
		WFIFOW(fd,n*20+10)=pc_equippoint(sd,i);
		WFIFOW(fd,n*20+12)=sd->status.inventory[i].equip;
		WFIFOB(fd,n*20+14)=sd->status.inventory[i].attribute;
		WFIFOB(fd,n*20+15)=sd->status.inventory[i].refine;
		clif_addcards(WFIFOP(fd, n*20+16), &sd->status.inventory[i]);
		n++;
	}
	if(n){
		WFIFOW(fd,2)=4+n*20;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
	return 0;
}

/*==========================================
 * �J�v������ɗa���Ă�����Օi&���W�i���X�g
 *------------------------------------------
 */
int clif_storageitemlist(struct map_session_data *sd,struct storage *stor)
{
	struct item_data *id;
	int i,n,fd;
	unsigned char *buf;

	nullpo_retr(0, sd);
	nullpo_retr(0, stor);

	fd=sd->fd;
	WFIFOHEAD(fd,MAX_STORAGE * 18 + 4);
	buf = WFIFOP(fd,0);
#if PACKETVER < 5
	WBUFW(buf,0)=0xa5;
	for(i=0,n=0;i<MAX_STORAGE;i++){
		if(stor->storage_[i].nameid<=0)
			continue;
		nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
		if(itemdb_isequip2(id))
			continue;

		WBUFW(buf,n*10+4)=i+1;
		if(id->view_id > 0)
			WBUFW(buf,n*10+6)=id->view_id;
		else
			WBUFW(buf,n*10+6)=stor->storage_[i].nameid;
		WBUFB(buf,n*10+8)=itemtype(id->type);
		WBUFB(buf,n*10+9)=stor->storage_[i].identify;
		WBUFW(buf,n*10+10)=stor->storage_[i].amount;
		WBUFW(buf,n*10+12)=0;
		n++;
	}
	if(n){
		WBUFW(buf,2)=4+n*10;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
#else
	WBUFW(buf,0)=0x1f0;
	for(i=0,n=0;i<MAX_STORAGE;i++){
		if(stor->storage_[i].nameid<=0)
			continue;
		nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
		if(itemdb_isequip2(id))
			continue;

		WBUFW(buf,n*18+4)=i+1;
		if(id->view_id > 0)
			WBUFW(buf,n*18+6)=id->view_id;
		else
			WBUFW(buf,n*18+6)=stor->storage_[i].nameid;
		WBUFB(buf,n*18+8)=itemtype(id->type);
		WBUFB(buf,n*18+9)=stor->storage_[i].identify;
		WBUFW(buf,n*18+10)=stor->storage_[i].amount;
		WBUFW(buf,n*18+12)=0;
		clif_addcards(WBUFP(buf,n*18+14), &stor->storage_[i]);
		n++;
	}
	if(n){
		WBUFW(buf,2)=4+n*18;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
#endif
	return 0;
}

/*==========================================
 * �J�v������ɗa���Ă��鑕�����X�g
 *------------------------------------------
 */
int clif_storageequiplist(struct map_session_data *sd,struct storage *stor)
{
	struct item_data *id;
	int i,n,fd;
	unsigned char *buf;

	nullpo_retr(0, sd);
	nullpo_retr(0, stor);

	fd=sd->fd;
	WFIFOHEAD(fd,MAX_STORAGE * 20 + 4);
	buf = WFIFOP(fd,0);
	WBUFW(buf,0)=0xa6;
	for(i=0,n=0;i<MAX_STORAGE;i++){
		if(stor->storage_[i].nameid<=0)
			continue;
		nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
		if(!itemdb_isequip2(id))
			continue;
		WBUFW(buf,n*20+4)=i+1;
		if(id->view_id > 0)
			WBUFW(buf,n*20+6)=id->view_id;
		else
			WBUFW(buf,n*20+6)=stor->storage_[i].nameid;
		WBUFB(buf,n*20+8)=itemtype(id->type);
		WBUFB(buf,n*20+9)=stor->storage_[i].identify;
		WBUFW(buf,n*20+10)=id->equip;
		WBUFW(buf,n*20+12)=stor->storage_[i].equip;
		WBUFB(buf,n*20+14)=stor->storage_[i].attribute;
		WBUFB(buf,n*20+15)=stor->storage_[i].refine;
		clif_addcards(WBUFP(buf, n*20+16), &stor->storage_[i]);
		n++;
	}
	if(n){
		WBUFW(buf,2)=4+n*20;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_guildstorageitemlist(struct map_session_data *sd,struct guild_storage *stor)
{
	struct item_data *id;
	int i,n,fd;
	unsigned char *buf;

	nullpo_retr(0, sd);
	nullpo_retr(0, stor);

	fd=sd->fd;
	WFIFOHEAD(fd, MAX_GUILD_STORAGE * 18 + 4);
	buf=WFIFOP(fd,0);

#if PACKETVER < 5
	WBUFW(buf,0)=0xa5;
	for(i=0,n=0;i<MAX_GUILD_STORAGE;i++){
		if(stor->storage_[i].nameid<=0)
			continue;
		nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
		if(itemdb_isequip2(id))
			continue;

		WBUFW(buf,n*10+4)=i+1;
		if(id->view_id > 0)
			WBUFW(buf,n*10+6)=id->view_id;
		else
			WBUFW(buf,n*10+6)=stor->storage_[i].nameid;
		WBUFB(buf,n*10+8)=itemtype(id->type);
		WBUFB(buf,n*10+9)=stor->storage_[i].identify;
		WBUFW(buf,n*10+10)=stor->storage_[i].amount;
		WBUFW(buf,n*10+12)=0;
		n++;
	}
	if(n){
		WBUFW(buf,2)=4+n*10;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
#else
	WBUFW(buf,0)=0x1f0;
	for(i=0,n=0;i<MAX_GUILD_STORAGE;i++){
		if(stor->storage_[i].nameid<=0)
			continue;
		nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
		if(itemdb_isequip2(id))
			continue;

		WBUFW(buf,n*18+4)=i+1;
		if(id->view_id > 0)
			WBUFW(buf,n*18+6)=id->view_id;
		else
			WBUFW(buf,n*18+6)=stor->storage_[i].nameid;
		WBUFB(buf,n*18+8)=itemtype(id->type);
		WBUFB(buf,n*18+9)=stor->storage_[i].identify;
		WBUFW(buf,n*18+10)=stor->storage_[i].amount;
		WBUFW(buf,n*18+12)=0;
		clif_addcards(WBUFP(buf,n*18+14), &stor->storage_[i]);
		n++;
	}
	if(n){
		WBUFW(buf,2)=4+n*18;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
#endif
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_guildstorageequiplist(struct map_session_data *sd,struct guild_storage *stor)
{
	struct item_data *id;
	int i,n,fd;
	unsigned char *buf;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, MAX_GUILD_STORAGE * 20 + 4);
	buf=WFIFOP(fd,0);

	WBUFW(buf,0)=0xa6;
	for(i=0,n=0;i<MAX_GUILD_STORAGE;i++){
		if(stor->storage_[i].nameid<=0)
			continue;
		nullpo_retr(0, id = itemdb_search(stor->storage_[i].nameid));
		if(!itemdb_isequip2(id))
			continue;
		WBUFW(buf,n*20+4)=i+1;
		if(id->view_id > 0)
			WBUFW(buf,n*20+6)=id->view_id;
		else
			WBUFW(buf,n*20+6)=stor->storage_[i].nameid;
		WBUFB(buf,n*20+8)=itemtype(id->type);
		WBUFB(buf,n*20+9)=stor->storage_[i].identify;
		WBUFW(buf,n*20+10)=id->equip;
		WBUFW(buf,n*20+12)=stor->storage_[i].equip;
		WBUFB(buf,n*20+14)=stor->storage_[i].attribute;
		WBUFB(buf,n*20+15)=stor->storage_[i].refine;
		clif_addcards(WBUFP(buf, n*20+16), &stor->storage_[i]);
		n++;
	}
	if(n){
		WBUFW(buf,2)=4+n*20;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
	return 0;
}

// Guild XY locators [Valaris]
int clif_guild_xy(struct map_session_data *sd)
{
	unsigned char buf[10];

	nullpo_retr(0, sd);

	WBUFW(buf,0)=0x1eb;
	WBUFL(buf,2)=sd->status.account_id;
	WBUFW(buf,6)=sd->bl.x;
	WBUFW(buf,8)=sd->bl.y;
	clif_send(buf,packet_len_table[0x1eb],&sd->bl,GUILD_SAMEMAP_WOS);

	return 0;
}

/*==========================================
 * Sends x/y dot to a single fd. [Skotlex]
 *------------------------------------------
 */

int clif_guild_xy_single(int fd, struct map_session_data *sd)
{
	WFIFOHEAD(fd,packet_len_table[0x1eb]);
	WFIFOW(fd,0)=0x1eb;
	WFIFOL(fd,2)=sd->status.account_id;
	WFIFOW(fd,6)=sd->bl.x;
	WFIFOW(fd,8)=sd->bl.y;
	WFIFOSET(fd,packet_len_table[0x1eb]);
	return 0;
}

// Guild XY locators [Valaris]
int clif_guild_xy_remove(struct map_session_data *sd)
{
	unsigned char buf[10];

	nullpo_retr(0, sd);

	WBUFW(buf,0)=0x1eb;
	WBUFL(buf,2)=sd->status.account_id;
	WBUFW(buf,6)=-1;
	WBUFW(buf,8)=-1;
	clif_send(buf,packet_len_table[0x1eb],&sd->bl,GUILD_SAMEMAP_WOS);

	return 0;
}

/*==========================================
 * �X�e�[�^�X�𑗂�‚���
 * �\����p�����͂��̒��Ōv�Z���đ���
 *------------------------------------------
 */
int clif_updatestatus(struct map_session_data *sd,int type)
{
	int fd,len=8;

	nullpo_retr(0, sd);

	fd=sd->fd;

	if ( !session_isActive(fd) ) // Invalid pointer fix, by sasuke [Kevin]
		return 0;
 
	WFIFOHEAD(fd, 14);
	WFIFOW(fd,0)=0xb0;
	WFIFOW(fd,2)=type;
	switch(type){
		// 00b0
	case SP_WEIGHT:
		pc_checkweighticon(sd);
		WFIFOW(fd,0)=0xb0;
		WFIFOW(fd,2)=type;	//Added this packet back, Temp fix to the slow motion [Lupus]
		WFIFOL(fd,4)=sd->weight;
		break;
	case SP_MAXWEIGHT:
		WFIFOL(fd,4)=sd->max_weight;
		break;
	case SP_SPEED:
		WFIFOL(fd,4)=sd->speed;
		break;
	case SP_BASELEVEL:
		WFIFOL(fd,4)=sd->status.base_level;
		break;
	case SP_JOBLEVEL:
		WFIFOL(fd,4)=sd->status.job_level;
		break;
	case SP_MANNER:
		WFIFOL(fd,4)=sd->status.manner;
		clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner);
		break;
	case SP_STATUSPOINT:
		WFIFOL(fd,4)=sd->status.status_point;
		break;
	case SP_SKILLPOINT:
		WFIFOL(fd,4)=sd->status.skill_point;
		break;
	case SP_HIT:
		WFIFOL(fd,4)=sd->hit;
		break;
	case SP_FLEE1:
		WFIFOL(fd,4)=sd->flee;
		break;
	case SP_FLEE2:
		WFIFOL(fd,4)=sd->flee2/10;
		break;
	case SP_MAXHP:
		WFIFOL(fd,4)=sd->status.max_hp;
		break;
	case SP_MAXSP:
		WFIFOL(fd,4)=sd->status.max_sp;
		break;
	case SP_HP:
		WFIFOL(fd,4)=sd->status.hp;
		if (sd->status.party_id)
			clif_party_hp(sd);
		if (battle_config.disp_hpmeter)
			clif_hpmeter(sd);
		break;
	case SP_SP:
		WFIFOL(fd,4)=sd->status.sp;
		break;
	case SP_ASPD:
		WFIFOL(fd,4)=sd->aspd;
		break;
	case SP_ATK1:
		WFIFOL(fd,4)=sd->base_atk+sd->right_weapon.watk+sd->left_weapon.watk;
		break;
	case SP_DEF1:
		WFIFOL(fd,4)=sd->def;
		break;
	case SP_MDEF1:
		WFIFOL(fd,4)=sd->mdef;
		break;
	case SP_ATK2:
		WFIFOL(fd,4)=sd->right_weapon.watk2 + sd->left_weapon.watk2;
		break;
	case SP_DEF2:
		WFIFOL(fd,4)=sd->def2;
		break;
	case SP_MDEF2:
		WFIFOL(fd,4)=sd->mdef2;
		break;
	case SP_CRITICAL:
		WFIFOL(fd,4)=sd->critical/10;
		break;
	case SP_MATK1:
		WFIFOL(fd,4)=sd->matk1;
		break;
	case SP_MATK2:
		WFIFOL(fd,4)=sd->matk2;
		break;


	case SP_ZENY:
		WFIFOW(fd,0)=0xb1;
		if(sd->status.zeny < 0)
			sd->status.zeny = 0;
		WFIFOL(fd,4)=sd->status.zeny;
		break;
	case SP_BASEEXP:
		WFIFOW(fd,0)=0xb1;
		WFIFOL(fd,4)=sd->status.base_exp;
		break;
	case SP_JOBEXP:
		WFIFOW(fd,0)=0xb1;
		WFIFOL(fd,4)=sd->status.job_exp;
		break;
	case SP_NEXTBASEEXP:
		WFIFOW(fd,0)=0xb1;
		WFIFOL(fd,4)=pc_nextbaseexp(sd);
		break;
	case SP_NEXTJOBEXP:
		WFIFOW(fd,0)=0xb1;
		WFIFOL(fd,4)=pc_nextjobexp(sd);
		break;

		// 00be �I��
	case SP_USTR:
	case SP_UAGI:
	case SP_UVIT:
	case SP_UINT:
	case SP_UDEX:
	case SP_ULUK:
		WFIFOW(fd,0)=0xbe;
		WFIFOB(fd,4)=pc_need_status_point(sd,type-SP_USTR+SP_STR);
		len=5;
		break;

		// 013a �I��
	case SP_ATTACKRANGE:
		WFIFOW(fd,0)=0x13a;
		WFIFOW(fd,2)=sd->attackrange;
		len=4;
		break;

		// 0141 �I��
	case SP_STR:
		WFIFOW(fd,0)=0x141;
		WFIFOL(fd,2)=type;
		WFIFOL(fd,6)=sd->status.str;
		WFIFOL(fd,10)=sd->paramb[0] + sd->parame[0];
		len=14;
		break;
	case SP_AGI:
		WFIFOW(fd,0)=0x141;
		WFIFOL(fd,2)=type;
		WFIFOL(fd,6)=sd->status.agi;
		WFIFOL(fd,10)=sd->paramb[1] + sd->parame[1];
		len=14;
		break;
	case SP_VIT:
		WFIFOW(fd,0)=0x141;
		WFIFOL(fd,2)=type;
		WFIFOL(fd,6)=sd->status.vit;
		WFIFOL(fd,10)=sd->paramb[2] + sd->parame[2];
		len=14;
		break;
	case SP_INT:
		WFIFOW(fd,0)=0x141;
		WFIFOL(fd,2)=type;
		WFIFOL(fd,6)=sd->status.int_;
		WFIFOL(fd,10)=sd->paramb[3] + sd->parame[3];
		len=14;
		break;
	case SP_DEX:
		WFIFOW(fd,0)=0x141;
		WFIFOL(fd,2)=type;
		WFIFOL(fd,6)=sd->status.dex;
		WFIFOL(fd,10)=sd->paramb[4] + sd->parame[4];
		len=14;
		break;
	case SP_LUK:
		WFIFOW(fd,0)=0x141;
		WFIFOL(fd,2)=type;
		WFIFOL(fd,6)=sd->status.luk;
		WFIFOL(fd,10)=sd->paramb[5] + sd->parame[5];
		len=14;
		break;

	case SP_CARTINFO:
		WFIFOW(fd,0)=0x121;
		WFIFOW(fd,2)=sd->cart_num;
		WFIFOW(fd,4)=sd->cart_max_num;
		WFIFOL(fd,6)=sd->cart_weight;
		WFIFOL(fd,10)=sd->cart_max_weight;
		len=14;
		break;

	default:
		if(battle_config.error_log)
			ShowError("clif_updatestatus : unrecognized type %d\n",type);
		return 1;
	}
	WFIFOSET(fd,len);

	return 0;
}
int clif_changestatus(struct block_list *bl,int type,int val)
{
	unsigned char buf[12];
	struct map_session_data *sd = NULL;

	nullpo_retr(0, bl);

	if(bl->type == BL_PC)
		sd = (struct map_session_data *)bl;

//printf("clif_changestatus id:%d type:%d val:%d\n",bl->id,type,val);
	if(sd){
		WBUFW(buf,0)=0x1ab;
		WBUFL(buf,2)=bl->id;
		WBUFW(buf,6)=type;
		switch(type){
		case SP_MANNER:
			WBUFL(buf,8)=val;
			break;
		default:
			if(battle_config.error_log)
				ShowError("clif_changestatus : unrecognized type %d.\n",type);
			return 1;
		}
		clif_send(buf,packet_len_table[0x1ab],bl,AREA_WOS);
	}
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_changelook(struct block_list *bl,int type,int val)
{
	unsigned char buf[32];
	struct map_session_data *sd = NULL;
	struct view_data *vd;
	nullpo_retr(0, bl);
	vd = status_get_viewdata(bl);
	nullpo_retr(0, vd);
	
	if(bl->type == BL_PC)
		sd = (struct map_session_data *)bl;

	switch(type) {
		case LOOK_WEAPON:
			if (sd) clif_get_weapon_view(sd, &vd->weapon, &vd->shield);
			else vd->weapon = val;
		break;
		case LOOK_SHIELD:
			if (sd) clif_get_weapon_view(sd, &vd->weapon, &vd->shield);
			else vd->shield = val;
		break;
		case LOOK_BASE:
			vd->class_ = val;
			if (vd->class_ == JOB_WEDDING || vd->class_ == JOB_XMAS)
				vd->weapon = vd->shield = 0;
			if (
				(vd->class_ == JOB_WEDDING && battle_config.wedding_ignorepalette) ||
				(vd->class_ == JOB_XMAS && battle_config.xmas_ignorepalette)
			)
				vd->cloth_color = 0;
		break;
		case LOOK_HAIR:
			vd->hair_style = val;
		break;
		case LOOK_HEAD_BOTTOM:
			vd->head_bottom = val;
		break;
		case LOOK_HEAD_TOP:
			vd->head_top = val;
		break;	
		case LOOK_HEAD_MID:
			vd->head_mid = val;
		break;
		case LOOK_HAIR_COLOR:
			vd->hair_color = val;
		break;
		case LOOK_CLOTHES_COLOR:
			if (
				(vd->class_ == JOB_WEDDING && battle_config.wedding_ignorepalette) ||
				(vd->class_ == JOB_XMAS && battle_config.xmas_ignorepalette)
			)
				val = 0;
			vd->cloth_color = val;
		break;
		case LOOK_SHOES:
#if PACKETVER > 3
			if (sd) {
				int n;
				if((n = sd->equip_index[2]) >= 0 && sd->inventory_data[n]) {
					if(sd->inventory_data[n]->view_id > 0)
						val = sd->inventory_data[n]->view_id;
					else
						val = sd->status.inventory[n].nameid;
					}
				val = 0;
			}
#endif
			//Shoes? No packet uses this....
		break;
	}
#if PACKETVER < 4
	WBUFW(buf,0)=0xc3;
	WBUFL(buf,2)=bl->id;
	WBUFB(buf,6)=type;
	WBUFB(buf,7)=val;
	clif_send(buf,packet_len_table[0xc3],bl,AREA);
#else
	if(type == LOOK_WEAPON || type == LOOK_SHIELD) {
		WBUFW(buf,0)=0x1d7;
		WBUFL(buf,2)=bl->id;
		WBUFB(buf,6)=LOOK_WEAPON;
		WBUFW(buf,7)=vd->weapon;
		WBUFW(buf,9)=vd->shield;
		clif_send(buf,packet_len_table[0x1d7],bl,AREA);
	}
	else if(type == LOOK_BASE && val > 255)
	{
		WBUFW(buf,0)=0x1d7;
		WBUFL(buf,2)=bl->id;
		WBUFB(buf,6)=type;
		WBUFW(buf,7)=val;
		WBUFW(buf,9)=0;
		clif_send(buf,packet_len_table[0x1d7],bl,AREA);
	} else {
		WBUFW(buf,0)=0xc3;
		WBUFL(buf,2)=bl->id;
		WBUFB(buf,6)=type;
		WBUFB(buf,7)=val;
		clif_send(buf,packet_len_table[0xc3],bl,AREA);
	}
#endif
	return 0;
}

//Sends a change-base-look packet required for traps as they are triggered.
void clif_changetraplook(struct block_list *bl,int val)
{
	unsigned char buf[32];
#if PACKETVER < 4
	WBUFW(buf,0)=0xc3;
	WBUFL(buf,2)=bl->id;
	WBUFB(buf,6)=LOOK_BASE;
	WBUFB(buf,7)=val;
	clif_send(buf,packet_len_table[0xc3],bl,AREA);
#else
	if (val > 255)
	{
		WBUFW(buf,0)=0x1d7;
		WBUFL(buf,2)=bl->id;
		WBUFB(buf,6)=LOOK_BASE;
		WBUFW(buf,7)=val;
		WBUFW(buf,9)=0;
		clif_send(buf,packet_len_table[0x1d7],bl,AREA);
	} else {
		WBUFW(buf,0)=0xc3;
		WBUFL(buf,2)=bl->id;
		WBUFB(buf,6)=LOOK_BASE;
		WBUFB(buf,7)=val;
		clif_send(buf,packet_len_table[0xc3],bl,AREA);
	}
#endif

	
}
//For the stupid cloth-dye bug. Resends the given view data
//to the area specified by bl.
void clif_refreshlook(struct block_list *bl,int id,int type,int val,int area)
{
	unsigned char buf[32];
#if PACKETVER < 4
	WBUFW(buf,0)=0xc3;
	WBUFL(buf,2)=id;
	WBUFB(buf,6)=type;
	WBUFB(buf,7)=val;
	clif_send(buf,packet_len_table[0xc3],bl,area);
#else
	if(type == LOOK_BASE && val > 255)
	{
		WBUFW(buf,0)=0x1d7;
		WBUFL(buf,2)=id;
		WBUFB(buf,6)=type;
		WBUFW(buf,7)=val;
		WBUFW(buf,9)=0;
		clif_send(buf,packet_len_table[0x1d7],bl,area);
	} else {
		WBUFW(buf,0)=0xc3;
		WBUFL(buf,2)=id;
		WBUFB(buf,6)=type;
		WBUFB(buf,7)=val;
		clif_send(buf,packet_len_table[0xc3],bl,area);
	}
#endif
	return;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_initialstatus(struct map_session_data *sd)
{
	int fd;
	unsigned char *buf;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xbd]);
	buf=WFIFOP(fd,0);

	WBUFW(buf,0)=0xbd;
	WBUFW(buf,2)=(sd->status.status_point > SHRT_MAX)? SHRT_MAX:sd->status.status_point;
	WBUFB(buf,4)=(sd->status.str > UCHAR_MAX)? UCHAR_MAX:sd->status.str;
	WBUFB(buf,5)=pc_need_status_point(sd,SP_STR);
	WBUFB(buf,6)=(sd->status.agi > UCHAR_MAX)? UCHAR_MAX:sd->status.agi;
	WBUFB(buf,7)=pc_need_status_point(sd,SP_AGI);
	WBUFB(buf,8)=(sd->status.vit > UCHAR_MAX)? UCHAR_MAX:sd->status.vit;
	WBUFB(buf,9)=pc_need_status_point(sd,SP_VIT);
	WBUFB(buf,10)=(sd->status.int_ > UCHAR_MAX)? UCHAR_MAX:sd->status.int_;
	WBUFB(buf,11)=pc_need_status_point(sd,SP_INT);
	WBUFB(buf,12)=(sd->status.dex > UCHAR_MAX)? UCHAR_MAX:sd->status.dex;
	WBUFB(buf,13)=pc_need_status_point(sd,SP_DEX);
	WBUFB(buf,14)=(sd->status.luk > UCHAR_MAX)? UCHAR_MAX:sd->status.luk;
	WBUFB(buf,15)=pc_need_status_point(sd,SP_LUK);

	WBUFW(buf,16) = sd->base_atk + sd->right_weapon.watk + sd->left_weapon.watk;
	WBUFW(buf,18) = sd->right_weapon.watk2 + sd->left_weapon.watk2; //atk bonus
	WBUFW(buf,20) = sd->matk1;
	WBUFW(buf,22) = sd->matk2;
	WBUFW(buf,24) = sd->def; // def
	WBUFW(buf,26) = sd->def2;
	WBUFW(buf,28) = sd->mdef; // mdef
	WBUFW(buf,30) = sd->mdef2;
	WBUFW(buf,32) = sd->hit;
	WBUFW(buf,34) = sd->flee;
	WBUFW(buf,36) = sd->flee2/10;
	WBUFW(buf,38) = sd->critical/10;
	WBUFW(buf,40) = sd->status.karma;
	WBUFW(buf,42) = sd->status.manner;

	WFIFOSET(fd,packet_len_table[0xbd]);

	clif_updatestatus(sd,SP_STR);
	clif_updatestatus(sd,SP_AGI);
	clif_updatestatus(sd,SP_VIT);
	clif_updatestatus(sd,SP_INT);
	clif_updatestatus(sd,SP_DEX);
	clif_updatestatus(sd,SP_LUK);

	clif_updatestatus(sd,SP_ATTACKRANGE);
	clif_updatestatus(sd,SP_ASPD);

	return 0;
}

/*==========================================
 *���
 *------------------------------------------
 */
int clif_arrowequip(struct map_session_data *sd,int val)
{
	int fd;

	nullpo_retr(0, sd);

	pc_stop_attack(sd); // [Valaris]

	fd=sd->fd;
	WFIFOHEAD(fd, packet_len_table[0x013c]);
	WFIFOW(fd,0)=0x013c;
	WFIFOW(fd,2)=val+2;//��̃A�C�e��ID

	WFIFOSET(fd,packet_len_table[0x013c]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_arrow_fail(struct map_session_data *sd,int type)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, packet_len_table[0x013b]);
	WFIFOW(fd,0)=0x013b;
	WFIFOW(fd,2)=type;

	WFIFOSET(fd,packet_len_table[0x013b]);

	return 0;
}

/*==========================================
 * �쐬�”\ ��X�g���M
 *------------------------------------------
 */
int clif_arrow_create_list(struct map_session_data *sd)
{
	int i, c, j;
	int fd;

	nullpo_retr(0, sd);

	fd = sd->fd;
	WFIFOHEAD(fd, MAX_SKILL_ARROW_DB*2+4);
	WFIFOW(fd,0) = 0x1ad;

	for (i = 0, c = 0; i < MAX_SKILL_ARROW_DB; i++) {
		if (skill_arrow_db[i].nameid > 0 &&
			(j = pc_search_inventory(sd, skill_arrow_db[i].nameid)) >= 0 &&
			!sd->status.inventory[j].equip)
		{
			if ((j = itemdb_viewid(skill_arrow_db[i].nameid)) > 0)
				WFIFOW(fd,c*2+4) = j;
			else
				WFIFOW(fd,c*2+4) = skill_arrow_db[i].nameid;
			c++;
		}
	}
	WFIFOW(fd,2) = c*2+4;
	WFIFOSET(fd, WFIFOW(fd,2));
	if (c > 0) {
		sd->menuskill_id = AC_MAKINGARROW;
		sd->menuskill_lv = c;
	}

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_statusupack(struct map_session_data *sd,int type,int ok,int val)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xbc]);
	WFIFOW(fd,0)=0xbc;
	WFIFOW(fd,2)=type;
	WFIFOB(fd,4)=ok;
	WFIFOB(fd,5)=val;
	WFIFOSET(fd,packet_len_table[0xbc]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xaa]);
	WFIFOW(fd,0)=0xaa;
	WFIFOW(fd,2)=n+2;
	WFIFOW(fd,4)=pos;
	WFIFOB(fd,6)=ok;
	WFIFOSET(fd,packet_len_table[0xaa]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xac]);
	WFIFOW(fd,0)=0xac;
	WFIFOW(fd,2)=n+2;
	WFIFOW(fd,4)=pos;
	WFIFOB(fd,6)=ok;
	WFIFOSET(fd,packet_len_table[0xac]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_misceffect(struct block_list* bl,int type)
{
	unsigned char buf[32];

	nullpo_retr(0, bl);

	WBUFW(buf,0) = 0x19b;
	WBUFL(buf,2) = bl->id;
	WBUFL(buf,6) = type;

	clif_send(buf,packet_len_table[0x19b],bl,AREA);

	return 0;
}
int clif_misceffect2(struct block_list *bl, int type) {
	unsigned char buf[24];

	nullpo_retr(0, bl);

	memset(buf, 0, packet_len_table[0x1f3]);

	WBUFW(buf,0) = 0x1f3;
	WBUFL(buf,2) = bl->id;
	WBUFL(buf,6) = type;

	clif_send(buf, packet_len_table[0x1f3], bl, AREA);

	return 0;

}
/*==========================================
 * �\���I�v�V�����ύX
 *------------------------------------------
 */
int clif_changeoption(struct block_list* bl)
{
	unsigned char buf[32];
	struct status_change *sc;

	nullpo_retr(0, bl);
	sc = status_get_sc(bl);

	WBUFW(buf,0) = 0x119;
	WBUFL(buf,2) = bl->id;
	WBUFW(buf,6) = sc?sc->opt1:0;
	WBUFW(buf,8) = sc?sc->opt2:0;
	WBUFW(buf,10) = sc?sc->option:0;
	WBUFB(buf,12) = 0;	// ??
	if(disguised(bl)) {
		clif_send(buf,packet_len_table[0x119],bl,AREA_WOS);
		WBUFL(buf,2) = -bl->id;
		clif_send(buf,packet_len_table[0x119],bl,SELF);
		WBUFL(buf,2) = bl->id;
		WBUFW(buf,10) = OPTION_INVISIBLE;
		clif_send(buf,packet_len_table[0x119],bl,SELF);
	} else
		clif_send(buf,packet_len_table[0x119],bl,AREA);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_useitemack(struct map_session_data *sd,int index,int amount,int ok)
{
	nullpo_retr(0, sd);

	if(!ok) {
		int fd=sd->fd;
  		WFIFOHEAD(fd,packet_len_table[0xa8]);
		WFIFOW(fd,0)=0xa8;
		WFIFOW(fd,2)=index+2;
		WFIFOW(fd,4)=amount;
		WFIFOB(fd,6)=ok;
		WFIFOSET(fd,packet_len_table[0xa8]);
	}
	else {
#if PACKETVER < 3
		int fd=sd->fd;
		WFIFOHEAD(fd,packet_len_table[0xa8]);
		WFIFOW(fd,0)=0xa8;
		WFIFOW(fd,2)=index+2;
		WFIFOW(fd,4)=amount;
		WFIFOB(fd,6)=ok;
		WFIFOSET(fd,packet_len_table[0xa8]);
#else
		unsigned char buf[32];

		WBUFW(buf,0)=0x1c8;
		WBUFW(buf,2)=index+2;
		if(sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0)
			WBUFW(buf,4)=sd->inventory_data[index]->view_id;
		else
			WBUFW(buf,4)=sd->status.inventory[index].nameid;
		WBUFL(buf,6)=sd->bl.id;
		WBUFW(buf,10)=amount;
		WBUFB(buf,12)=ok;
		clif_send(buf,packet_len_table[0x1c8],&sd->bl,AREA);
#endif
	}

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_createchat(struct map_session_data *sd,int fail)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xd6]);
	WFIFOW(fd,0)=0xd6;
	WFIFOB(fd,2)=fail;
	WFIFOSET(fd,packet_len_table[0xd6]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_dispchat(struct chat_data *cd,int fd)
{
	unsigned char buf[128];	// �ő�title(60�o�C�g)+17

	if(cd==NULL || *cd->owner==NULL)
		return 1;

	WBUFW(buf,0)=0xd7;
	WBUFW(buf,2)=strlen((const char*)cd->title)+17;
	WBUFL(buf,4)=(*cd->owner)->id;
	WBUFL(buf,8)=cd->bl.id;
	WBUFW(buf,12)=cd->limit;
	WBUFW(buf,14)=cd->users;
	WBUFB(buf,16)=cd->pub;
	strcpy((char*)WBUFP(buf,17),(const char*)cd->title);
	if(fd){
		WFIFOHEAD(fd, WBUFW(buf,2));
		memcpy(WFIFOP(fd,0),buf,WBUFW(buf,2));
		WFIFOSET(fd,WBUFW(buf,2));
	} else {
		clif_send(buf,WBUFW(buf,2),*cd->owner,AREA_WOSC);
	}

	return 0;
}

/*==========================================
 * chat�̏�ԕύX����
 * �O���̐l�p�Ɩ��߃R�[�h(d7->df)���Ⴄ����
 *------------------------------------------
 */
int clif_changechatstatus(struct chat_data *cd)
{
	unsigned char buf[128];	// �ő�title(60�o�C�g)+17

	if(cd==NULL || cd->usersd[0]==NULL)
		return 1;

	WBUFW(buf,0)=0xdf;
	WBUFW(buf,2)=strlen((char*)cd->title)+17;
	WBUFL(buf,4)=cd->usersd[0]->bl.id;
	WBUFL(buf,8)=cd->bl.id;
	WBUFW(buf,12)=cd->limit;
	WBUFW(buf,14)=cd->users;
	WBUFB(buf,16)=cd->pub;
	strcpy((char*)WBUFP(buf,17),(const char*)cd->title);
	clif_send(buf,WBUFW(buf,2),&cd->usersd[0]->bl,CHAT);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_clearchat(struct chat_data *cd,int fd)
{
	unsigned char buf[32];

	nullpo_retr(0, cd);

	WBUFW(buf,0)=0xd8;
	WBUFL(buf,2)=cd->bl.id;
	if(fd){
		WFIFOHEAD(fd,packet_len_table[0xd8]);
		memcpy(WFIFOP(fd,0),buf,packet_len_table[0xd8]);
		WFIFOSET(fd,packet_len_table[0xd8]);
	} else {
		clif_send(buf,packet_len_table[0xd8],*cd->owner,AREA_WOSC);
	}

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_joinchatfail(struct map_session_data *sd,int fail)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;

	WFIFOHEAD(fd,packet_len_table[0xda]);
	WFIFOW(fd,0)=0xda;
	WFIFOB(fd,2)=fail;
	WFIFOSET(fd,packet_len_table[0xda]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_joinchatok(struct map_session_data *sd,struct chat_data* cd)
{
	int fd;
	int i;

	nullpo_retr(0, sd);
	nullpo_retr(0, cd);

	fd = sd->fd;
	if (!session_isActive(fd))
		return 0;
	WFIFOHEAD(fd, 8 + (28*cd->users));
	WFIFOW(fd, 0) = 0xdb;
	WFIFOW(fd, 2) = 8 + (28*cd->users);
	WFIFOL(fd, 4) = cd->bl.id;
	for (i = 0; i < cd->users; i++) {
		WFIFOL(fd, 8+i*28) = (i!=0) || ((*cd->owner)->type == BL_NPC);
		memcpy(WFIFOP(fd, 8+i*28+4), cd->usersd[i]->status.name, NAME_LENGTH);
	}
	WFIFOSET(fd, WFIFOW(fd, 2));

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_addchat(struct chat_data* cd,struct map_session_data *sd)
{
	unsigned char buf[32];

	nullpo_retr(0, sd);
	nullpo_retr(0, cd);

	WBUFW(buf, 0) = 0x0dc;
	WBUFW(buf, 2) = cd->users;
	memcpy(WBUFP(buf, 4),sd->status.name,NAME_LENGTH);
	clif_send(buf,packet_len_table[0xdc],&sd->bl,CHAT_WOS);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_changechatowner(struct chat_data* cd,struct map_session_data *sd)
{
	unsigned char buf[64];

	nullpo_retr(0, sd);
	nullpo_retr(0, cd);

	WBUFW(buf, 0) = 0xe1;
	WBUFL(buf, 2) = 1;
	memcpy(WBUFP(buf,6),cd->usersd[0]->status.name,NAME_LENGTH);
	WBUFW(buf,30) = 0xe1;
	WBUFL(buf,32) = 0;
	memcpy(WBUFP(buf,36),sd->status.name,NAME_LENGTH);

	clif_send(buf,packet_len_table[0xe1]*2,&sd->bl,CHAT);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_leavechat(struct chat_data* cd,struct map_session_data *sd)
{
	unsigned char buf[32];

	nullpo_retr(0, sd);
	nullpo_retr(0, cd);

	WBUFW(buf, 0) = 0xdd;
	WBUFW(buf, 2) = cd->users-1;
	memcpy(WBUFP(buf,4),sd->status.name,NAME_LENGTH);
	WBUFB(buf,28) = 0;

	clif_send(buf,packet_len_table[0xdd],&sd->bl,CHAT);

	return 0;
}

/*==========================================
 * �������v����
 *------------------------------------------
 */
int clif_traderequest(struct map_session_data *sd,char *name)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;

	WFIFOHEAD(fd,packet_len_table[0xe5]);
	WFIFOW(fd,0)=0xe5;

	strcpy((char*)WFIFOP(fd,2),name);
	
	WFIFOSET(fd,packet_len_table[0xe5]);

	return 0;
}

/*==========================================
 * �������v������
 *------------------------------------------
 */
int clif_tradestart(struct map_session_data *sd,int type)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xe7]);
	WFIFOW(fd,0)=0xe7;
	WFIFOB(fd,2)=type;
	WFIFOSET(fd,packet_len_table[0xe7]);

	return 0;
}

/*==========================================
 * ���������̃A�C�e���lj�
 *------------------------------------------
 */
int clif_tradeadditem(struct map_session_data *sd,struct map_session_data *tsd,int index,int amount)
{
	int fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, tsd);

	fd=tsd->fd;
	WFIFOHEAD(fd,packet_len_table[0xe9]);
	WFIFOW(fd,0)=0xe9;
	WFIFOL(fd,2)=amount;
	if(index==0){
		WFIFOW(fd,6) = 0; // type id
		WFIFOB(fd,8) = 0; //identify flag
		WFIFOB(fd,9) = 0; // attribute
		WFIFOB(fd,10)= 0; //refine
		WFIFOW(fd,11)= 0; //card (4w)
		WFIFOW(fd,13)= 0; //card (4w)
		WFIFOW(fd,15)= 0; //card (4w)
		WFIFOW(fd,17)= 0; //card (4w)
	}
	else{
		index-=2; //index fix
		if(sd->inventory_data[index] && sd->inventory_data[index]->view_id > 0)
			WFIFOW(fd,6) = sd->inventory_data[index]->view_id;
		else
			WFIFOW(fd,6) = sd->status.inventory[index].nameid; // type id
		WFIFOB(fd,8) = sd->status.inventory[index].identify; //identify flag
		WFIFOB(fd,9) = sd->status.inventory[index].attribute; // attribute
		WFIFOB(fd,10)= sd->status.inventory[index].refine; //refine
		clif_addcards(WFIFOP(fd, 11), &sd->status.inventory[index]);
	}
	WFIFOSET(fd,packet_len_table[0xe9]);

	return 0;
}

/*==========================================
 * �A�C�e���lj�����/���s
 *------------------------------------------
 */
int clif_tradeitemok(struct map_session_data *sd,int index,int fail)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xea]);
	WFIFOW(fd,0)=0xea;
	WFIFOW(fd,2)=index;
	WFIFOB(fd,4)=fail;
	WFIFOSET(fd,packet_len_table[0xea]);

	return 0;
}

/*==========================================
 * ������ok����
 *------------------------------------------
 */
int clif_tradedeal_lock(struct map_session_data *sd,int fail)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xec]);
	WFIFOW(fd,0)=0xec;
	WFIFOB(fd,2)=fail; // 0=you 1=the other person
	WFIFOSET(fd,packet_len_table[0xec]);

	return 0;
}

/*==========================================
 * ���������L�����Z������܂���
 *------------------------------------------
 */
int clif_tradecancelled(struct map_session_data *sd)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xee]);
	WFIFOW(fd,0)=0xee;
	WFIFOSET(fd,packet_len_table[0xee]);

	return 0;
}

/*==========================================
 * ����������
 *------------------------------------------
 */
int clif_tradecompleted(struct map_session_data *sd,int fail)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xf0]);
	WFIFOW(fd,0)=0xf0;
	WFIFOB(fd,2)=fail;
	WFIFOSET(fd,packet_len_table[0xf0]);

	return 0;
}

/*==========================================
 * �J�v���q�ɂ̃A�C�e�������X�V
 *------------------------------------------
 */
int clif_updatestorageamount(struct map_session_data *sd,struct storage *stor)
{
	int fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, stor);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xf2]);
	WFIFOW(fd,0) = 0xf2;  // update storage amount
	WFIFOW(fd,2) = stor->storage_amount;  //items
	WFIFOW(fd,4) = MAX_STORAGE; //items max
	WFIFOSET(fd,packet_len_table[0xf2]);

	return 0;
}

/*==========================================
 * �J�v���q�ɂɃA�C�e����lj�����
 *------------------------------------------
 */
int clif_storageitemadded(struct map_session_data *sd,struct storage *stor,int index,int amount)
{
	int view,fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, stor);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xf4]);
	WFIFOW(fd,0) =0xf4; // Storage item added
	WFIFOW(fd,2) =index+1; // index
	WFIFOL(fd,4) =amount; // amount
	if((view = itemdb_viewid(stor->storage_[index].nameid)) > 0)
		WFIFOW(fd,8) =view;
	else
		WFIFOW(fd,8) =stor->storage_[index].nameid; // id
	WFIFOB(fd,10)=stor->storage_[index].identify; //identify flag
	WFIFOB(fd,11)=stor->storage_[index].attribute; // attribute
	WFIFOB(fd,12)=stor->storage_[index].refine; //refine
	clif_addcards(WFIFOP(fd,13), &stor->storage_[index]);
	WFIFOSET(fd,packet_len_table[0xf4]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_updateguildstorageamount(struct map_session_data *sd,struct guild_storage *stor)
{
	int fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, stor);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xf2]);
	WFIFOW(fd,0) = 0xf2;  // update storage amount
	WFIFOW(fd,2) = stor->storage_amount;  //items
	WFIFOW(fd,4) = MAX_GUILD_STORAGE; //items max
	WFIFOSET(fd,packet_len_table[0xf2]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_guildstorageitemadded(struct map_session_data *sd,struct guild_storage *stor,int index,int amount)
{
	int view,fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, stor);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xf4]);
	WFIFOW(fd,0) =0xf4; // Storage item added
	WFIFOW(fd,2) =index+1; // index
	WFIFOL(fd,4) =amount; // amount
	if((view = itemdb_viewid(stor->storage_[index].nameid)) > 0)
		WFIFOW(fd,8) =view;
	else
		WFIFOW(fd,8) =stor->storage_[index].nameid; // id
	WFIFOB(fd,10)=stor->storage_[index].identify; //identify flag
	WFIFOB(fd,11)=stor->storage_[index].attribute; // attribute
	WFIFOB(fd,12)=stor->storage_[index].refine; //refine
	clif_addcards(WFIFOP(fd,13), &stor->storage_[index]);
	WFIFOSET(fd,packet_len_table[0xf4]);

	return 0;
}

/*==========================================
 * �J�v���q�ɂ���A�C�e������苎��
 *------------------------------------------
 */
int clif_storageitemremoved(struct map_session_data *sd,int index,int amount)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xf6]);
	WFIFOW(fd,0)=0xf6; // Storage item removed
	WFIFOW(fd,2)=index+1;
	WFIFOL(fd,4)=amount;
	WFIFOSET(fd,packet_len_table[0xf6]);

	return 0;
}

/*==========================================
 * �J�v���q�ɂ�‚���
 *------------------------------------------
 */
int clif_storageclose(struct map_session_data *sd)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xf8]);
	WFIFOW(fd,0)=0xf8; // Storage Closed
	WFIFOSET(fd,packet_len_table[0xf8]);

	return 0;
}

//
// callback�n ?
//
/*==========================================
 * PC�\��
 *------------------------------------------
 */
void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* dstsd)
{
	int len;
	if(dstsd->chatID){
		struct chat_data *cd;
		cd=(struct chat_data*)map_id2bl(dstsd->chatID);
		if(cd && cd->usersd[0]==dstsd)
			clif_dispchat(cd,sd->fd);
	}
	if(dstsd->vender_id)
		clif_showvendingboard(&dstsd->bl,dstsd->message,sd->fd);

	if(dstsd->spiritball > 0)
		clif_spiritball_single(sd->fd, dstsd);

	if((sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting.
		(battle_config.disp_hpmeter && (len = pc_isGM(sd)) >= battle_config.disp_hpmeter && len >= pc_isGM(dstsd))
		)
		clif_hpmeter_single(sd->fd, dstsd);

	if(dstsd->status.manner < 0 && battle_config.manner_system)
		clif_changestatus(&dstsd->bl,SP_MANNER,dstsd->status.manner);
		
	// pvp circle for duel [LuzZza]
	/*
	if(dstsd->duel_group)
		clif_specialeffect(&dstsd->bl, 159, 4);
	*/

}
void clif_getareachar_char(struct map_session_data* sd,struct block_list *bl)
{
	struct unit_data *ud;
	struct view_data *vd;
	int len;
	
	vd = status_get_viewdata(bl);

	if (!vd || vd->class_ == INVISIBLE_CLASS)
		return;

	ud = unit_bl2ud(bl);
	if (ud && ud->walktimer != -1)
	{
#if PACKETVER < 4
		WFIFOHEAD(sd->fd, packet_len_table[0x7b]);
#else
		WFIFOHEAD(sd->fd, packet_len_table[0x1da]);
#endif
		len = clif_set007b(bl,vd,ud,WFIFOP(sd->fd,0));
		WFIFOSET(sd->fd,len);
	} else {
#if PACKETVER < 4
		WFIFOHEAD(sd->fd,packet_len_table[0x78]);
#else
		WFIFOHEAD(sd->fd,packet_len_table[0x1d8]);
#endif
		len = clif_set0078(bl,vd,WFIFOP(sd->fd,0));
		WFIFOSET(sd->fd,len);
	}

	if (vd->cloth_color)
		clif_refreshlook(&sd->bl,bl->id,LOOK_CLOTHES_COLOR,vd->cloth_color,SELF);

	switch (bl->type)
	{
	case BL_PC:
		{
			TBL_PC* tsd = (TBL_PC*)bl;
			clif_getareachar_pc(sd, tsd);
			if(tsd->state.size==2) // tiny/big players [Valaris]
				clif_specialeffect(bl,423,0);
			else if(tsd->state.size==1)
				clif_specialeffect(bl,421,0);
		}
		break;
	case BL_NPC:
		{
			if(((TBL_NPC*)bl)->chat_id)
				clif_dispchat((struct chat_data*)map_id2bl(((TBL_NPC*)bl)->chat_id),sd->fd);
		}
		break;
	case BL_MOB:
		{
			TBL_MOB* md = (TBL_MOB*)bl;
			if(md->special_state.size==2) // tiny/big mobs [Valaris]
				clif_specialeffect(bl,423,0);
			else if(md->special_state.size==1)
				clif_specialeffect(bl,421,0);
		}
		break;
	}
}

/*==========================================
 * Older fix pos packet.
 *------------------------------------------
 */
int clif_fixpos2(struct block_list* bl)
{
	struct unit_data *ud;
	struct view_data *vd;
	unsigned char buf[256];
	int len;

	nullpo_retr(0, bl);
	ud = unit_bl2ud(bl);
	vd = status_get_viewdata(bl);
	if (!vd || vd->class_ == INVISIBLE_CLASS)
		return 0;
	
	if(ud && ud->walktimer != -1)
		len = clif_set007b(bl,vd,ud,buf);
	else
		len = clif_set0078(bl,vd,buf);

	if (disguised(bl)) {
		clif_send(buf,len,bl,AREA_WOS);
		clif_setdisguise((TBL_PC*)bl, buf, len, 0);
		clif_setdisguise((TBL_PC*)bl, buf, len, 1);
	} else
		clif_send(buf,len,bl,AREA);
	return 0;
}

/*==========================================
 * Modifies the type of damage according to status changes [Skotlex]
 *------------------------------------------
 */
static int clif_calc_delay(struct block_list *dst, int type, int delay)
{
	if (type == 1 || type == 4 || type == 0x0a) //Type 1 is the crouching animation, type 4 are non-flinching attacks, 0x0a - crits. 
		return type;
	
	if (delay == 0)
		return 9; //Endure type attack (damage delay is 0)
	
	return type;
}
/*==========================================
 * �ʏ�U���G�t�F�N�g���_���[�W
 *------------------------------------------
 */
int clif_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,int type,int damage2)
{
	unsigned char buf[256];
	struct status_change *sc;

	nullpo_retr(0, src);
	nullpo_retr(0, dst);

	type = clif_calc_delay(dst, type, ddelay); //Type defaults to 0 for normal attacks.

	sc = status_get_sc(dst);

	if(sc && sc->count) {
		if(sc->data[SC_HALLUCINATION].timer != -1) {
			if(damage > 0)
				damage = damage*(5+sc->data[SC_HALLUCINATION].val1) + rand()%100;
			if(damage2 > 0)
				damage2 = damage2*(5+sc->data[SC_HALLUCINATION].val1) + rand()%100;
		}
	}

	WBUFW(buf,0)=0x8a;
	WBUFL(buf,2)=src->id;
	WBUFL(buf,6)=dst->id;
	WBUFL(buf,10)=tick;
	WBUFL(buf,14)=sdelay;
	WBUFL(buf,18)=ddelay;
	WBUFW(buf,22)=(damage > SHRT_MAX)?SHRT_MAX:damage;
	WBUFW(buf,24)=div;
	WBUFB(buf,26)=type;
	WBUFW(buf,27)=damage2;
	clif_send(buf,packet_len_table[0x8a],src,AREA);

	if(disguised(src)) {
		WBUFL(buf,2)=-src->id;
		if(damage > 0)
			WBUFW(buf,22)=-1;
		if(damage2 > 0)
			WBUFW(buf,27)=-1;
		clif_send(buf,packet_len_table[0x8a],src,SELF);
	}
	if (disguised(dst)) {
		WBUFL(buf,6)=-dst->id;
		if (disguised(src))
			WBUFL(buf,2)=src->id;
		else {
			if(damage > 0)
				WBUFW(buf,22)=-1;
			if(damage2 > 0)
				WBUFW(buf,27)=-1;
		}
		clif_send(buf,packet_len_table[0x8a],dst,SELF);
	}
	//Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex]
	if (type != 4 && type != 9 && damage+damage2 > 0) //Non-endure/Non-flinch attack, update walk delay.
		unit_walkdelay(dst, tick, sdelay, ddelay, div);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_getareachar_item(struct map_session_data* sd,struct flooritem_data* fitem)
{
	int view,fd;
	fd=sd->fd;
	//009d <ID>.l <item ID>.w <identify flag>.B <X>.w <Y>.w <amount>.w <subX>.B <subY>.B
	WFIFOHEAD(fd,packet_len_table[0x9d]);

	WFIFOW(fd,0)=0x9d;
	WFIFOL(fd,2)=fitem->bl.id;
	if((view = itemdb_viewid(fitem->item_data.nameid)) > 0)
		WFIFOW(fd,6)=view;
	else
		WFIFOW(fd,6)=fitem->item_data.nameid;
	WFIFOB(fd,8)=fitem->item_data.identify;
	WFIFOW(fd,9)=fitem->bl.x;
	WFIFOW(fd,11)=fitem->bl.y;
	WFIFOW(fd,13)=fitem->item_data.amount;
	WFIFOB(fd,15)=fitem->subx;
	WFIFOB(fd,16)=fitem->suby;
	WFIFOSET(fd,packet_len_table[0x9d]);
}
/*==========================================
 * �ꏊ�X�L���G�t�F�N�g�����E�ɓ���
 *------------------------------------------
 */
int clif_getareachar_skillunit(struct map_session_data *sd,struct skill_unit *unit)
{
	int fd;
	struct block_list *bl;

	nullpo_retr(0, unit);

	fd=sd->fd;
	bl=map_id2bl(unit->group->src_id);
#if PACKETVER < 3
	WFIFOHEAD(fd,packet_len_table[0x11f]);
	memset(WFIFOP(fd,0),0,packet_len_table[0x11f]);
	WFIFOW(fd, 0)=0x11f;
	WFIFOL(fd, 2)=unit->bl.id;
	WFIFOL(fd, 6)=unit->group->src_id;
	WFIFOW(fd,10)=unit->bl.x;
	WFIFOW(fd,12)=unit->bl.y;
	WFIFOB(fd,14)=unit->group->unit_id;
	WFIFOB(fd,15)=0;
	WFIFOSET(fd,packet_len_table[0x11f]);
#else
	WFIFOHEAD(fd,packet_len_table[0x1c9]);
	memset(WFIFOP(fd,0),0,packet_len_table[0x1c9]);
	WFIFOW(fd, 0)=0x1c9;
	WFIFOL(fd, 2)=unit->bl.id;
	WFIFOL(fd, 6)=unit->group->src_id;
	WFIFOW(fd,10)=unit->bl.x;
	WFIFOW(fd,12)=unit->bl.y;
	WFIFOB(fd,14)=unit->group->unit_id;
	WFIFOB(fd,15)=1;
	if(unit->group->unit_id==UNT_GRAFFITI)	{ // Graffiti [Valaris]
		WFIFOB(fd,16)=1;
		memcpy(WFIFOP(fd,17),unit->group->valstr,MESSAGE_SIZE);
	} else {
		WFIFOL(fd,15+1)=0;						//1-4���ׂ�����Œ�
		WFIFOL(fd,15+5)=0;						//5-8���ׂ�����Œ�
												//9-12�}�b�v���Ƃň���77-80�Ƃ͂܂��Ⴄ4�o�C�g�̂��Ȃ�傫�Ȑ���
		WFIFOL(fd,15+13)=unit->bl.y - 0x12;		//13-16���j�b�g��Y���W-18���ۂ�(Y:17��FF FF FF FF)
		WFIFOL(fd,15+17)=0x004f37dd;			//17-20���ׂ�����Œ�
		WFIFOL(fd,15+21)=0x0012f674;			//21-24���ׂ�����Œ�
		WFIFOL(fd,15+25)=0x0012f664;			//25-28���ׂ�����Œ�
		WFIFOL(fd,15+29)=0x0012f654;			//29-32���ׂ�����Œ�
		WFIFOL(fd,15+33)=0x77527bbc;			//33-36���ׂ�����Œ�
												//37-39
		WFIFOB(fd,15+40)=0x2d;					//40���ׂ�����Œ�
		WFIFOL(fd,15+41)=0;						//41-44���ׂ�����0�Œ�
		WFIFOL(fd,15+45)=0;						//45-48���ׂ�����0�Œ�
		WFIFOL(fd,15+49)=0;						//49-52���ׂ�����0�Œ�
		WFIFOL(fd,15+53)=0x0048d919;			//53-56���ׂ�����Œ�
		WFIFOL(fd,15+57)=0x0000003e;			//57-60���ׂ�����Œ�
		WFIFOL(fd,15+61)=0x0012f66c;			//61-64���ׂ�����Œ�
												//65-68
												//69-72
		if(bl) WFIFOL(fd,15+73)=bl->y;			//73-76�p�҂�Y���W
		WFIFOL(fd,15+77)=unit->bl.m;			//77-80�}�b�vID���Ȃ��H���Ȃ�2�o�C�g�ő��肻���Ȑ���
		WFIFOB(fd,15+81)=0xaa;					//81�I�[����0xaa
	}

	WFIFOSET(fd,packet_len_table[0x1c9]);
#endif
	if(unit->group->skill_id == WZ_ICEWALL)
		clif_set0192(fd,unit->bl.m,unit->bl.x,unit->bl.y,5);

	return 0;
}
/*==========================================
 * �ꏊ�X�L���G�t�F�N�g�����E���������
 *------------------------------------------
 */
int clif_clearchar_skillunit(struct skill_unit *unit,int fd)
{
	nullpo_retr(0, unit);

	WFIFOHEAD(fd,packet_len_table[0x120]);
	WFIFOW(fd, 0)=0x120;
	WFIFOL(fd, 2)=unit->bl.id;
	WFIFOSET(fd,packet_len_table[0x120]);
	if(unit->group && unit->group->skill_id == WZ_ICEWALL)
		clif_set0192(fd,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_01ac(struct block_list *bl)
{
	unsigned char buf[32];

	nullpo_retr(0, bl);

	WBUFW(buf, 0) = 0x1ac;
	WBUFL(buf, 2) = bl->id;

	clif_send(buf,packet_len_table[0x1ac],bl,AREA);
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
 int clif_getareachar(struct block_list* bl,va_list ap)
{
	struct map_session_data *sd;

	nullpo_retr(0, bl);
	nullpo_retr(0, ap);

	sd=va_arg(ap,struct map_session_data*);

	if (sd == NULL || session[sd->fd] == NULL)
		return 0;

	switch(bl->type){
	case BL_ITEM:
		clif_getareachar_item(sd,(struct flooritem_data*) bl);
		break;
	case BL_SKILL:
		clif_getareachar_skillunit(sd,(struct skill_unit *)bl);
		break;
	default:
		if(&sd->bl == bl)
			break;
		clif_getareachar_char(sd,bl);
		break;
	}
	return 0;
}

/*==========================================
 * tbl has gone out of view-size of bl
 *------------------------------------------
 */
int clif_outsight(struct block_list *bl,va_list ap)
{
	struct block_list *tbl;
	struct view_data *vd;
	TBL_PC *sd, *tsd;
	tbl=va_arg(ap,struct block_list*);
	if(bl == tbl) return 0;
	BL_CAST(BL_PC, bl, sd);
	BL_CAST(BL_PC, tbl, tsd);

	if (tsd && tsd->fd)
	{	//tsd has lost sight of the bl object.
		switch(bl->type){
		case BL_PC:
			if (((TBL_PC*)bl)->vd.class_ != INVISIBLE_CLASS)
				clif_clearchar_id(bl->id,0,tsd->fd);
			if(sd->chatID){
				struct chat_data *cd;
				cd=(struct chat_data*)map_id2bl(sd->chatID);
				if(cd->usersd[0]==sd)
					clif_dispchat(cd,tsd->fd);
			}
			if(sd->vender_id)
				clif_closevendingboard(bl,tsd->fd);
			break;
		case BL_ITEM:
			clif_clearflooritem((struct flooritem_data*)bl,tsd->fd);
			break;
		case BL_SKILL:
			clif_clearchar_skillunit((struct skill_unit *)bl,tsd->fd);
			break;
		default:
			if ((vd=status_get_viewdata(bl)) && vd->class_ != INVISIBLE_CLASS)
				clif_clearchar_id(bl->id,0,tsd->fd);
			break;
		}
	}
	if (sd && sd->fd)
	{	//sd is watching tbl go out of view.
		if ((vd=status_get_viewdata(tbl)) && vd->class_ != INVISIBLE_CLASS)
			clif_clearchar_id(tbl->id,0,sd->fd);
	}
	return 0;
}

/*==========================================
 * tbl has come into view of bl
 *------------------------------------------
 */
int clif_insight(struct block_list *bl,va_list ap)
{
	struct block_list *tbl;
	TBL_PC *sd, *tsd;
	tbl=va_arg(ap,struct block_list*);

	if (bl == tbl) return 0;
	
	BL_CAST(BL_PC, bl, sd);
	BL_CAST(BL_PC, tbl, tsd);

	if (tsd && tsd->fd)
	{	//Tell tsd that bl entered into his view
		switch(bl->type){
		case BL_ITEM:
			clif_getareachar_item(tsd,(struct flooritem_data*)bl);
			break;
		case BL_SKILL:
			clif_getareachar_skillunit(tsd,(struct skill_unit *)bl);
			break;
		default:
			clif_getareachar_char(tsd,bl);
			break;
		}
	}
	if (sd && sd->fd)
	{	//Tell sd that tbl walked into his view
		clif_getareachar_char(sd,tbl);
	}
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_skillinfo(struct map_session_data *sd,int skillid,int type,int range)
{
	int fd,id, inf2;

	nullpo_retr(0, sd);

	fd=sd->fd;
	if( (id=sd->status.skill[skillid].id) <= 0 )
		return 0;
	WFIFOHEAD(fd,packet_len_table[0x147]);
	WFIFOW(fd,0)=0x147;
	WFIFOW(fd,2) = id;
	if(type < 0)
		WFIFOW(fd,4) = skill_get_inf(id);
	else
		WFIFOW(fd,4) = type;
	WFIFOW(fd,6) = 0;
	WFIFOW(fd,8) = sd->status.skill[skillid].lv;
	WFIFOW(fd,10) = skill_get_sp(id,sd->status.skill[skillid].lv);
	if(range < 0)
		range = skill_get_range2(&sd->bl, id,sd->status.skill[skillid].lv);

	WFIFOW(fd,12)= range;
	strncpy(WFIFOP(fd,14), skill_get_name(id), NAME_LENGTH);
	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,38)= (sd->status.skill[skillid].lv < skill_get_max(id) && sd->status.skill[skillid].flag ==0 )? 1:0;
		WFIFOB(fd,38)= (sd->status.skill[skillid].lv < skill_tree_get_max(id, sd->status.class_) && sd->status.skill[skillid].flag ==0 )? 1:0;
	else
		WFIFOB(fd,38) = 0;
	WFIFOSET(fd,packet_len_table[0x147]);

	return 0;
}

/*==========================================
 * �X�L�����X�g�𑗐M����
 *------------------------------------------
 */
int clif_skillinfoblock(struct map_session_data *sd)
{
	int fd;
	int i,c,len=4,id, inf2;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd, MAX_SKILL * 37 + 4);
	WFIFOW(fd,0)=0x10f;
	for ( i = c = 0; i < MAX_SKILL; i++){
		if( (id=sd->status.skill[i].id)!=0 ){
			WFIFOW(fd,len  ) = id;
			WFIFOW(fd,len+2) = skill_get_inf(id);
			WFIFOW(fd,len+4) = 0;
			WFIFOW(fd,len+6) = sd->status.skill[i].lv;
			WFIFOW(fd,len+8) = skill_get_sp(id,sd->status.skill[i].lv);
			WFIFOW(fd,len+10)= skill_get_range2(&sd->bl, id,sd->status.skill[i].lv);
			strncpy(WFIFOP(fd,len+12), skill_get_name(id), NAME_LENGTH);
			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
				WFIFOB(fd,len+36) = 0;
			len+=37;
			c++;
		}
	}
	WFIFOW(fd,2)=len;
	WFIFOSET(fd,len);

	return 0;
}

/*==========================================
 * �X�L������U��ʒm
 *------------------------------------------
 */
int clif_skillup(struct map_session_data *sd,int skill_num)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x10e]);
	WFIFOW(fd,0) = 0x10e;
	WFIFOW(fd,2) = skill_num;
	WFIFOW(fd,4) = sd->status.skill[skill_num].lv;
	WFIFOW(fd,6) = skill_get_sp(skill_num,sd->status.skill[skill_num].lv);
	WFIFOW(fd,8) = skill_get_range2(&sd->bl,skill_num,sd->status.skill[skill_num].lv);
	//WFIFOB(fd,10) = (sd->status.skill[skill_num].lv < skill_get_max(sd->status.skill[skill_num].id)) ? 1 : 0;
	WFIFOB(fd,10) = (sd->status.skill[skill_num].lv < skill_tree_get_max(sd->status.skill[skill_num].id, sd->status.class_)) ? 1 : 0;
	WFIFOSET(fd,packet_len_table[0x10e]);

	return 0;
}

/*==========================================
 * �X�L���r���G�t�F�N�g�𑗐M����
 *------------------------------------------
 */
int clif_skillcasting(struct block_list* bl,
	int src_id,int dst_id,int dst_x,int dst_y,int skill_num,int casttime)
{
	int pl = skill_get_pl(skill_num);
	unsigned char buf[32];
	WBUFW(buf,0) = 0x13e;
	WBUFL(buf,2) = src_id;
	WBUFL(buf,6) = dst_id;
	WBUFW(buf,10) = dst_x;
	WBUFW(buf,12) = dst_y;
	WBUFW(buf,14) = skill_num;
	WBUFL(buf,16) = pl<0?0:pl; //Avoid sending negatives as element [Skotlex]
	WBUFL(buf,20) = casttime;
	clif_send(buf,packet_len_table[0x13e], bl, AREA);
	if (disguised(bl)) {
		WBUFL(buf,2) = -src_id;
		WBUFL(buf,20) = 0;
		clif_send(buf,packet_len_table[0x13e], bl, SELF);
	}

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_skillcastcancel(struct block_list* bl)
{
	unsigned char buf[16];

	nullpo_retr(0, bl);

	WBUFW(buf,0) = 0x1b9;
	WBUFL(buf,2) = bl->id;
	clif_send(buf,packet_len_table[0x1b9], bl, AREA);

	return 0;
}

/*==========================================
 * �X�L���r�����s
 *------------------------------------------
 */
int clif_skill_fail(struct map_session_data *sd,int skill_id,int type,int btype)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;

	// reset all variables [celest]
	// Should be handled now by the unit_* code.
	sd->skillitem = sd->skillitemlv = -1;

	if(type==0x4 && !sd->state.showdelay)
		return 0;

	WFIFOHEAD(fd,packet_len_table[0x110]);
	WFIFOW(fd,0) = 0x110;
	WFIFOW(fd,2) = skill_id;
	WFIFOW(fd,4) = btype;
	WFIFOW(fd,6) = 0;
	WFIFOB(fd,8) = 0;
	WFIFOB(fd,9) = type;
	WFIFOSET(fd,packet_len_table[0x110]);

	return 0;
}

/*==========================================
 * �X�L���U���G�t�F�N�g���_���[�W
 *------------------------------------------
 */
int clif_skill_damage(struct block_list *src,struct block_list *dst,
	unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type)
{
	unsigned char buf[64];
	struct status_change *sc;

	nullpo_retr(0, src);
	nullpo_retr(0, dst);
	
	type = clif_calc_delay(dst, (type>0)?type:skill_get_hit(skill_id), ddelay);
	sc = status_get_sc(dst);

	if(sc && sc->count) {
		if(sc->data[SC_HALLUCINATION].timer != -1 && damage > 0)
			damage = damage*(5+sc->data[SC_HALLUCINATION].val1) + rand()%100;
	}

#if PACKETVER < 3
	WBUFW(buf,0)=0x114;
	WBUFW(buf,2)=skill_id;
	WBUFL(buf,4)=src->id;
	WBUFL(buf,8)=dst->id;
	WBUFL(buf,12)=tick;
	WBUFL(buf,16)=sdelay;
	WBUFL(buf,20)=ddelay;
	WBUFW(buf,24)=damage;
	WBUFW(buf,26)=skill_lv;
	WBUFW(buf,28)=div;
	WBUFB(buf,30)=type;
	clif_send(buf,packet_len_table[0x114],src,AREA);
	if(disguised(src)) {
		WBUFL(buf,4)=-src->id;
		if(damage > 0)
			WBUFW(buf,24)=-1;
		clif_send(buf,packet_len_table[0x114],src,SELF);
	}
	if (disguised(dst)) {
		WBUFL(buf,8)=-dst->id;
		if (disguised(src))
			WBUFL(buf,4)=src->id;
		else if(damage > 0)
			WBUFW(buf,24)=-1;
		clif_send(buf,packet_len_table[0x114],dst,SELF);
	}
#else
	WBUFW(buf,0)=0x1de;
	WBUFW(buf,2)=skill_id;
	WBUFL(buf,4)=src->id;
	WBUFL(buf,8)=dst->id;
	WBUFL(buf,12)=tick;
	WBUFL(buf,16)=sdelay;
	WBUFL(buf,20)=ddelay;
	WBUFL(buf,24)=damage;
	WBUFW(buf,28)=skill_lv;
	WBUFW(buf,30)=div;
	WBUFB(buf,32)=type;
	clif_send(buf,packet_len_table[0x1de],src,AREA);
	if(disguised(src)) {
		WBUFL(buf,4)=-src->id;
		if(damage > 0)
			WBUFW(buf,24)=-1;
		clif_send(buf,packet_len_table[0x1de],src,SELF);
	}
	if (disguised(dst)) {
		WBUFL(buf,8)=-dst->id;
		if (disguised(src))
			WBUFL(buf,4)=src->id;
		else if(damage > 0)
			WBUFW(buf,24)=-1;
		clif_send(buf,packet_len_table[0x1de],dst,SELF);
	}
#endif

	//Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex]
	if (type != 4 && type != 9 && damage > 0) //Non-endure/Non-flinch attack, update walk delay.
		unit_walkdelay(dst, tick, sdelay, ddelay, div);
	return 0;
}

/*==========================================
 * ������΂��X�L���U���G�t�F�N�g���_���[�W
 *------------------------------------------
 */
int clif_skill_damage2(struct block_list *src,struct block_list *dst,
	unsigned int tick,int sdelay,int ddelay,int damage,int div,int skill_id,int skill_lv,int type)
{
	unsigned char buf[64];
	struct status_change *sc;

	nullpo_retr(0, src);
	nullpo_retr(0, dst);

	type = clif_calc_delay(dst, (type>0)?type:skill_get_hit(skill_id), ddelay);
	sc = status_get_sc(dst);

	if(sc && sc->count) {
		if(sc->data[SC_HALLUCINATION].timer != -1 && damage > 0)
			damage = damage*(5+sc->data[SC_HALLUCINATION].val1) + rand()%100;
	}

	WBUFW(buf,0)=0x115;
	WBUFW(buf,2)=skill_id;
	WBUFL(buf,4)=src->id;
	WBUFL(buf,8)=dst->id;
	WBUFL(buf,12)=tick;
	WBUFL(buf,16)=sdelay;
	WBUFL(buf,20)=ddelay;
	WBUFW(buf,24)=dst->x;
	WBUFW(buf,26)=dst->y;
	WBUFW(buf,28)=damage;
	WBUFW(buf,30)=skill_lv;
	WBUFW(buf,32)=div;
	WBUFB(buf,34)=type;
	clif_send(buf,packet_len_table[0x115],src,AREA);
	if(disguised(src)) {
		WBUFL(buf,4)=-src->id;
		if(damage > 0)
			WBUFW(buf,28)=-1;
		clif_send(buf,packet_len_table[0x115],src,SELF);
	}
	if (disguised(dst)) {
		WBUFL(buf,8)=-dst->id;
		if (disguised(src))
			WBUFL(buf,4)=src->id;
		else if(damage > 0)
			WBUFW(buf,28)=-1;
		clif_send(buf,packet_len_table[0x115],dst,SELF);
	}

	//Because the damage delay must be synced with the client, here is where the can-walk tick must be updated. [Skotlex]
	if (type != 4 && type != 9 && damage > 0) //Non-endure/Non-flinch attack, update walk delay.
		unit_walkdelay(dst, tick, sdelay, ddelay, div);
	return 0;
}

/*==========================================
 * �x��/�񕜃X�L���G�t�F�N�g
 *------------------------------------------
 */
int clif_skill_nodamage(struct block_list *src,struct block_list *dst,
	int skill_id,int heal,int fail)
{
	unsigned char buf[32];

	nullpo_retr(0, src);
	nullpo_retr(0, dst);

	WBUFW(buf,0)=0x11a;
	WBUFW(buf,2)=skill_id;
	WBUFW(buf,4)=(heal > SHRT_MAX)? SHRT_MAX:heal;
	WBUFL(buf,6)=dst->id;
	WBUFL(buf,10)=src->id;
	WBUFB(buf,14)=fail;
	clif_send(buf,packet_len_table[0x11a],src,AREA);

	if(disguised(src)) {
		WBUFL(buf,10)=-src->id;
		clif_send(buf,packet_len_table[0x115],src,SELF);
	}
	if (disguised(dst)) {
		WBUFL(buf,6)=-dst->id;
		if (disguised(src))
			WBUFL(buf,10)=src->id;
		clif_send(buf,packet_len_table[0x115],dst,SELF);
	}

	return fail;
}

/*==========================================
 * �ꏊ�X�L���G�t�F�N�g
 *------------------------------------------
 */
int clif_skill_poseffect(struct block_list *src,int skill_id,int val,int x,int y,int tick)
{
	unsigned char buf[32];

	nullpo_retr(0, src);

	WBUFW(buf,0)=0x117;
	WBUFW(buf,2)=skill_id;
	WBUFL(buf,4)=src->id;
	WBUFW(buf,8)=val;
	WBUFW(buf,10)=x;
	WBUFW(buf,12)=y;
	WBUFL(buf,14)=tick;
	clif_send(buf,packet_len_table[0x117],src,AREA);
	if(disguised(src)) {
		WBUFL(buf,4)=-src->id;
		clif_send(buf,packet_len_table[0x117],src,SELF);
	}

	return 0;
}

/*==========================================
 * �ꏊ�X�L���G�t�F�N�g�\��
 *------------------------------------------
 */
int clif_skill_setunit(struct skill_unit *unit)
{
	unsigned char buf[128];
	struct block_list *bl;

	nullpo_retr(0, unit);

	bl=map_id2bl(unit->group->src_id);

// These are invisible client-side, but are necessary because
// otherwise the client will not know who caused the attack.
//	if (unit->group->unit_id == UNT_ATTACK_SKILLS)
//		return 0;
		
#if PACKETVER < 3
	memset(WBUFP(buf, 0),0,packet_len_table[0x11f]);
	WBUFW(buf, 0)=0x11f;
	WBUFL(buf, 2)=unit->bl.id;
	WBUFL(buf, 6)=unit->group->src_id;
	WBUFW(buf,10)=unit->bl.x;
	WBUFW(buf,12)=unit->bl.y;
	WBUFB(buf,14)=unit->group->unit_id;
	WBUFB(buf,15)=0;
	clif_send(buf,packet_len_table[0x11f],&unit->bl,AREA);
#else
		memset(WBUFP(buf, 0),0,packet_len_table[0x1c9]);
		WBUFW(buf, 0)=0x1c9;
		WBUFL(buf, 2)=unit->bl.id;
		WBUFL(buf, 6)=unit->group->src_id;
		WBUFW(buf,10)=unit->bl.x;
		WBUFW(buf,12)=unit->bl.y;
		WBUFB(buf,14)=unit->group->unit_id;
		WBUFB(buf,15)=1;
		if(unit->group->unit_id==0xb0)	{ // Graffiti [Valaris]
			WBUFB(buf,16)=1;
			memcpy(WBUFP(buf,17),unit->group->valstr,MESSAGE_SIZE);
		} else {
			WBUFL(buf,15+1)=0;						//1-4���ׂ�����Œ�
			WBUFL(buf,15+5)=0;						//5-8���ׂ�����Œ�
												//9-12�}�b�v���Ƃň���77-80�Ƃ͂܂��Ⴄ4�o�C�g�̂��Ȃ�傫�Ȑ���
			WBUFL(buf,15+13)=unit->bl.y - 0x12;		//13-16���j�b�g��Y���W-18���ۂ�(Y:17��FF FF FF FF)
			WBUFL(buf,15+17)=0x004f37dd;			//17-20���ׂ�����Œ�(0x1b2��0x004fdbdd������)
			WBUFL(buf,15+21)=0x0012f674;			//21-24���ׂ�����Œ�
			WBUFL(buf,15+25)=0x0012f664;			//25-28���ׂ�����Œ�
			WBUFL(buf,15+29)=0x0012f654;			//29-32���ׂ�����Œ�
			WBUFL(buf,15+33)=0x77527bbc;			//33-36���ׂ�����Œ�
												//37-39
			WBUFB(buf,15+40)=0x2d;					//40���ׂ�����Œ�
			WBUFL(buf,15+41)=0;						//41-44���ׂ�����0�Œ�
			WBUFL(buf,15+45)=0;						//45-48���ׂ�����0�Œ�
			WBUFL(buf,15+49)=0;						//49-52���ׂ�����0�Œ�
			WBUFL(buf,15+53)=0x0048d919;			//53-56���ׂ�����Œ�(0x01b2��0x00495119������)
			WBUFL(buf,15+57)=0x0000003e;			//57-60���ׂ�����Œ�
			WBUFL(buf,15+61)=0x0012f66c;			//61-64���ׂ�����Œ�
												//65-68
												//69-72
			if(bl) WBUFL(buf,15+73)=bl->y;			//73-76�p�҂�Y���W
				WBUFL(buf,15+77)=unit->bl.m;			//77-80�}�b�vID���Ȃ��H���Ȃ�2�o�C�g�ő��肻���Ȑ���
			WBUFB(buf,15+81)=0xaa;					//81�I�[����0xaa
		}
		clif_send(buf,packet_len_table[0x1c9],&unit->bl,AREA);
#endif
	return 0;
}
/*==========================================
 * �ꏊ�X�L���G�t�F�N�g�폜
 *------------------------------------------
 */
int clif_skill_delunit(struct skill_unit *unit)
{
	unsigned char buf[16];

	nullpo_retr(0, unit);

	WBUFW(buf, 0)=0x120;
	WBUFL(buf, 2)=unit->bl.id;
	clif_send(buf,packet_len_table[0x120],&unit->bl,AREA);
	return 0;
}
/*==========================================
 * ���[�v�ꏊ�I��
 *------------------------------------------
 */
int clif_skill_warppoint(struct map_session_data *sd,int skill_num,int skill_lv,
	const char *map1,const char *map2,const char *map3,const char *map4)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x11c]);
	WFIFOW(fd,0)=0x11c;
	WFIFOW(fd,2)=skill_num;
	strncpy((char*)WFIFOP(fd, 4),map1,MAP_NAME_LENGTH);
	strncpy((char*)WFIFOP(fd,20),map2,MAP_NAME_LENGTH);
	strncpy((char*)WFIFOP(fd,36),map3,MAP_NAME_LENGTH);
	strncpy((char*)WFIFOP(fd,52),map4,MAP_NAME_LENGTH);
	WFIFOSET(fd,packet_len_table[0x11c]);
	sd->menuskill_id = skill_num;
	if (skill_num == AL_WARP)
		sd->menuskill_lv = (sd->ud.skillx<<16)|sd->ud.skilly; //Store warp position here.
	else
		sd->menuskill_lv = skill_lv;
	return 0;
}
/*==========================================
 * ��������
 *------------------------------------------
 */
int clif_skill_memo(struct map_session_data *sd,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;

	WFIFOHEAD(fd,packet_len_table[0x11e]);
	WFIFOW(fd,0)=0x11e;
	WFIFOB(fd,2)=flag;
	WFIFOSET(fd,packet_len_table[0x11e]);
	return 0;
}
int clif_skill_teleportmessage(struct map_session_data *sd,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x189]);
	WFIFOW(fd,0)=0x189;
	WFIFOW(fd,2)=flag;
	WFIFOSET(fd,packet_len_table[0x189]);
	return 0;
}

/*==========================================
 * �����X�^�[���
 *------------------------------------------
 */
int clif_skill_estimation(struct map_session_data *sd,struct block_list *dst)
{
	struct mob_data *md;
	unsigned char buf[64];
	int i;//, fix;

	nullpo_retr(0, sd);
	nullpo_retr(0, dst);

	if(dst->type!=BL_MOB )
		return 0;
	if((md=(struct mob_data *)dst) == NULL)
		return 0;

	WBUFW(buf, 0)=0x18c;
	WBUFW(buf, 2)=md->vd->class_;
	WBUFW(buf, 4)=md->level;
	WBUFW(buf, 6)=md->db->size;
	WBUFL(buf, 8)=md->hp;
	WBUFW(buf,12)= (battle_config.estimation_type&1?status_get_def(&md->bl):0)
		+(battle_config.estimation_type&2?status_get_def2(&md->bl):0);
	WBUFW(buf,14)=md->db->race;
	WBUFW(buf,16)= (battle_config.estimation_type&1?status_get_mdef(&md->bl):0)
  		+(battle_config.estimation_type&2?status_get_mdef2(&md->bl) - (md->db->vit>>1):0);
	WBUFW(buf,18)=status_get_elem_type(&md->bl);
	for(i=0;i<9;i++)
		WBUFB(buf,20+i)= (unsigned char)battle_attr_fix(NULL,dst,100,i+1,md->def_ele);
//		The following caps negative attributes to 0 since the client displays them as 255-fix. [Skotlex]
//		WBUFB(buf,20+i)= (unsigned char)((fix=battle_attr_fix(NULL,dst,100,i+1,md->def_ele))<0?0:fix);

	if(sd->status.party_id>0)
		clif_send(buf,packet_len_table[0x18c],&sd->bl,PARTY_AREA);
	else{
		WFIFOHEAD(sd->fd,packet_len_table[0x18c]);
		memcpy(WFIFOP(sd->fd,0),buf,packet_len_table[0x18c]);
		WFIFOSET(sd->fd,packet_len_table[0x18c]);
	}
	return 0;
}
/*==========================================
 * �A�C�e�������”\���X�g
 *------------------------------------------
 */
int clif_skill_produce_mix_list(struct map_session_data *sd, int trigger)
{
	int i,c,view,fd;
	nullpo_retr(0, sd);

	if(sd->menuskill_id == AM_PHARMACY)
		return 0; //Avoid resending the menu twice or more times...
	fd=sd->fd;
	WFIFOHEAD(fd, MAX_SKILL_PRODUCE_DB * 8 + 8);
	WFIFOW(fd, 0)=0x18d;

	for(i=0,c=0;i<MAX_SKILL_PRODUCE_DB;i++){
		if( skill_can_produce_mix(sd,skill_produce_db[i].nameid,trigger, 1) ){
			if((view = itemdb_viewid(skill_produce_db[i].nameid)) > 0)
				WFIFOW(fd,c*8+ 4)= view;
			else
				WFIFOW(fd,c*8+ 4)= skill_produce_db[i].nameid;
			WFIFOW(fd,c*8+ 6)= 0x0012;
			WFIFOL(fd,c*8+ 8)= sd->status.char_id;
			c++;
		}
	}
	WFIFOW(fd, 2)=c*8+8;
	WFIFOSET(fd,WFIFOW(fd,2));
	if(c > 0) {
		sd->menuskill_id = AM_PHARMACY;
		sd->menuskill_lv = trigger;
		return 1;
	}
	return 0;
}

/*==========================================
 * Sends a status change packet to the object only, used for loading status changes. [Skotlex]
 *------------------------------------------
 */
int clif_status_load(struct block_list *bl,int type, int flag)
{
	int fd;
	if (type == SI_BLANK)  //It shows nothing on the client...
		return 0;
	
	if (bl->type != BL_PC)
		return 0;

	fd = ((struct map_session_data*)bl)->fd;
	
	WFIFOHEAD(fd,packet_len_table[0x196]);
	WFIFOW(fd,0)=0x0196;
	WFIFOW(fd,2)=type;
	WFIFOL(fd,4)=bl->id;
	WFIFOB(fd,8)=flag; //Status start
	WFIFOSET(fd, packet_len_table[0x196]);
	return 0;
}
/*==========================================
 * ��Ԉُ�A�C�R��/���b�Z�[�W�\��
 *------------------------------------------
 */
int clif_status_change(struct block_list *bl,int type,int flag)
{
	unsigned char buf[16];

	if (type == SI_BLANK)  //It shows nothing on the client...
		return 0;
	
	nullpo_retr(0, bl);

	WBUFW(buf,0)=0x0196;
	WBUFW(buf,2)=type;
	WBUFL(buf,4)=bl->id;
	WBUFB(buf,8)=flag;
	clif_send(buf,packet_len_table[0x196],bl,AREA);
	return 0;
}

/*==========================================
 * Send message (modified by [Yor])
 *------------------------------------------
 */
int clif_displaymessage(const int fd, char* mes)
{
	// invalid pointer?
	nullpo_retr(-1, mes);
	
	//Console [Wizputer] //Scrapped, as these are shared by disconnected players =X [Skotlex]
	if (fd == 0)
		return 0;
	else {
		int len_mes = strlen(mes);

		if (len_mes > 0) { // don't send a void message (it's not displaying on the client chat). @help can send void line.
                        WFIFOHEAD(fd, 5 + len_mes);
			WFIFOW(fd,0) = 0x8e;
			WFIFOW(fd,2) = 5 + len_mes; // 4 + len + NULL teminate
			memcpy(WFIFOP(fd,4), mes, len_mes + 1);
			WFIFOSET(fd, 5 + len_mes);
		}
	}

	return 0;
}

/*==========================================
 * �V�̐��𑗐M����
 *------------------------------------------
 */
int clif_GMmessage(struct block_list *bl, char* mes, int len, int flag)
{
	unsigned char *buf;
	int lp;

	lp = (flag & 0x10) ? 8 : 4;
	buf = (unsigned char*)aCallocA(len + lp + 8, sizeof(unsigned char));

	WBUFW(buf,0) = 0x9a;
	WBUFW(buf,2) = len + lp;
	WBUFL(buf,4) = 0x65756c62;
	memcpy(WBUFP(buf,lp), mes, len);
	flag &= 0x07;
	clif_send(buf, WBUFW(buf,2), bl,
	          (flag == 1) ? ALL_SAMEMAP :
	          (flag == 2) ? AREA :
	          (flag == 3) ? SELF :
	          ALL_CLIENT);
	if(buf) aFree(buf);

	if(use_irc && irc_announce_flag && !flag)
		irc_announce(mes);

	return 0;
}

/*==========================================
 * �O���[�o�����b�Z�[�W
 *------------------------------------------
 */
void clif_GlobalMessage(struct block_list *bl,char *message)
{
	char buf[100];
	int len;

	nullpo_retv(bl);

	if(!message)
		return;

	len = strlen(message)+1;

	WBUFW(buf,0)=0x8d;
	WBUFW(buf,2)=len+8;
	WBUFL(buf,4)=bl->id;
	strncpy((char *) WBUFP(buf,8),message,len);
	clif_send((unsigned char *) buf,WBUFW(buf,2),bl,AREA_CHAT_WOC);
}

/*==========================================
 * Send main chat message [LuzZza]
 *------------------------------------------
 */
void clif_MainChatMessage(char* message) {

	char buf[100];
	int len;
	
	if(!message)
		return;
		
	len = strlen(message)+1;
	
	WBUFW(buf,0)=0x8d;
	WBUFW(buf,2)=len+8;
	WBUFL(buf,4)=0;
	strncpy((char *) WBUFP(buf,8),message,len);
	clif_send((unsigned char *) buf,WBUFW(buf,2),NULL,CHAT_MAINCHAT);
}

/*==========================================
 * Does an announce message in the given color. 
 *------------------------------------------
 */
int clif_announce(struct block_list *bl, char* mes, int len, unsigned long color, int flag)
{
	unsigned char *buf;
	buf = (unsigned char*)aCallocA(len + 16, sizeof(unsigned char));
	WBUFW(buf,0) = 0x1c3;
	WBUFW(buf,2) = len + 16;
	WBUFL(buf,4) = color;
	WBUFW(buf,8) = 0x190; //Font style? Type?
	WBUFW(buf,10) = 0x0c;  //12? Font size?
	WBUFL(buf,12) = 0;	//Unknown!
	memcpy(WBUFP(buf,16), mes, len);
	
	flag &= 0x07;
	clif_send(buf, WBUFW(buf,2), bl,
	          (flag == 1) ? ALL_SAMEMAP :
	          (flag == 2) ? AREA :
	          (flag == 3) ? SELF :
	          ALL_CLIENT);

	if(buf) aFree(buf);
	return 0;
}
/*==========================================
 * HPSP�񕜃G�t�F�N�g�𑗐M����
 *------------------------------------------
 */
int clif_heal(int fd,int type,int val)
{
	WFIFOHEAD(fd,packet_len_table[0x13d]);
	WFIFOW(fd,0)=0x13d;
	WFIFOW(fd,2)=type;
	WFIFOW(fd,4)=val;
	WFIFOSET(fd,packet_len_table[0x13d]);

	return 0;
}

/*==========================================
 * ��������
 *------------------------------------------
 */
int clif_resurrection(struct block_list *bl,int type)
{
	unsigned char buf[16];

	nullpo_retr(0, bl);

	WBUFW(buf,0)=0x148;
	WBUFL(buf,2)=bl->id;
	WBUFW(buf,6)=type;

	clif_send(buf,packet_len_table[0x148],bl,type==1 ? AREA : AREA_WOS);
	if (disguised(bl))
		clif_spawn(bl);

	return 0;
}

/*==========================================
 * PVP�����H�i���j
 *------------------------------------------
 */
int clif_set0199(int fd,int type)
{
	WFIFOHEAD(fd,packet_len_table[0x199]);
	WFIFOW(fd,0)=0x199;
	WFIFOW(fd,2)=type;
	WFIFOSET(fd,packet_len_table[0x199]);

	return 0;
}

/*==========================================
 * PVP�����H(��)
 *------------------------------------------
 */
int clif_pvpset(struct map_session_data *sd,int pvprank,int pvpnum,int type)
{
	nullpo_retr(0, sd);

	if(map[sd->bl.m].flag.nopvp)
		return 0;

	if(type == 2) {
		WFIFOHEAD(sd->fd,packet_len_table[0x19a]);
		WFIFOW(sd->fd,0) = 0x19a;
		WFIFOL(sd->fd,2) = sd->bl.id;
		if(pvprank<=0)
			pc_calc_pvprank(sd);
		WFIFOL(sd->fd,6) = pvprank;
		WFIFOL(sd->fd,10) = pvpnum;
		WFIFOSET(sd->fd,packet_len_table[0x19a]);
	} else {
		unsigned char buf[32];

		WBUFW(buf,0) = 0x19a;
		WBUFL(buf,2) = sd->bl.id;
		if(sd->sc.option&0x46)
		// WTF? a -1 to an unsigned value...
			WBUFL(buf,6) = 0xFFFFFFFF;
		else
			if(pvprank<=0)
				pc_calc_pvprank(sd);
			WBUFL(buf,6) = pvprank;
		WBUFL(buf,10) = pvpnum;
		if(!type)
			clif_send(buf,packet_len_table[0x19a],&sd->bl,AREA);
		else
			clif_send(buf,packet_len_table[0x19a],&sd->bl,ALL_SAMEMAP);
	}

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_send0199(int map,int type)
{
	struct block_list bl;
	unsigned char buf[16];

	bl.type = BL_NUL;
	bl.m = map;
	WBUFW(buf,0)=0x199;
	WBUFW(buf,2)=type;
	clif_send(buf,packet_len_table[0x199],&bl,ALL_SAMEMAP);

	return 0;
}

/*==========================================
 * ���B�G�t�F�N�g�𑗐M����
 *------------------------------------------
 */
int clif_refine(int fd,struct map_session_data *sd,int fail,int index,int val)
{
	WFIFOHEAD(fd,packet_len_table[0x188]);
	WFIFOW(fd,0)=0x188;
	WFIFOW(fd,2)=fail;
	WFIFOW(fd,4)=index+2;
	WFIFOW(fd,6)=val;
	WFIFOSET(fd,packet_len_table[0x188]);

	return 0;
}

/*==========================================
 * Wisp/page is transmitted to the destination player
 *------------------------------------------
 */
int clif_wis_message(int fd, char *nick, char *mes, int mes_len) // R 0097 <len>.w <nick>.24B <message>.?B
{
//	printf("clif_wis_message(%d, %s, %s)\n", fd, nick, mes);

	WFIFOHEAD(fd, mes_len + NAME_LENGTH + 4);
	WFIFOW(fd,0) = 0x97;
	WFIFOW(fd,2) = mes_len + NAME_LENGTH + 4;
	memcpy(WFIFOP(fd,4), nick, NAME_LENGTH);
	memcpy(WFIFOP(fd,28), mes, mes_len);
	WFIFOSET(fd,WFIFOW(fd,2));
	return 0;
}

/*==========================================
 * The transmission result of Wisp/page is transmitted to the source player
 *------------------------------------------
 */
int clif_wis_end(int fd, int flag) // R 0098 <type>.B: 0: success to send wisper, 1: target character is not loged in, 2: ignored by target, 3: everyone ignored by target
{
	WFIFOHEAD(fd,packet_len_table[0x98]);
	WFIFOW(fd,0) = 0x98;
	WFIFOW(fd,2) = flag;
	WFIFOSET(fd,packet_len_table[0x98]);
	return 0;
}

/*==========================================
 * �L����ID���O�������ʂ𑗐M����
 *------------------------------------------
 */
int clif_solved_charname(struct map_session_data *sd,int char_id)
{
	char *p= map_charid2nick(char_id);
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	if(p!=NULL){
                WFIFOHEAD(fd,packet_len_table[0x194]);
		WFIFOW(fd,0)=0x194;
		WFIFOL(fd,2)=char_id;
		memcpy(WFIFOP(fd,6), p, NAME_LENGTH);
		WFIFOSET(fd,packet_len_table[0x194]);
	}else{
		map_reqchariddb(sd,char_id);
		chrif_searchcharid(char_id);
	}
	return 0;
}

/*==========================================
 * �J�[�h�̑}���”\���X�g��Ԃ�
 *------------------------------------------
 */
int clif_use_card(struct map_session_data *sd,int idx)
{
	int i,c,ep;
	int fd=sd->fd;

	nullpo_retr(0, sd);
	if (idx < 0 || idx >= MAX_INVENTORY) //Crash-fix from bad packets.
		return 0;

	if (!sd->inventory_data[idx] || sd->inventory_data[idx]->type != 6)
		return 0; //Avoid parsing invalid item indexes (no card/no item)
			
	ep=sd->inventory_data[idx]->equip;
	WFIFOHEAD(fd,MAX_INVENTORY * 2 + 4);
	WFIFOW(fd,0)=0x017b;

	for(i=c=0;i<MAX_INVENTORY;i++){
		int j;

		if(sd->inventory_data[i] == NULL)
			continue;
		if(sd->inventory_data[i]->type!=4 && sd->inventory_data[i]->type!=5)	// ����h���Ȃ�
			continue;
		if(sd->status.inventory[i].card[0]==0x00ff || sd->status.inventory[i].card[0]==(short)0xff00 || sd->status.inventory[i].card[0]==0x00fe)
			continue;
		if(sd->status.inventory[i].identify==0 )	// ���Ӓ�
			continue;

		if((sd->inventory_data[i]->equip&ep)==0)	// ���������Ⴄ
			continue;
		if(sd->inventory_data[i]->type==4 && ep==32)	// ���J�[�h�Ɨ��蕐��
			continue;
		for(j=0;j<sd->inventory_data[i]->slot;j++){
			if( sd->status.inventory[i].card[j]==0 )
				break;
		}
		if(j==sd->inventory_data[i]->slot)	// ���łɃJ�[�h����t
			continue;

		WFIFOW(fd,4+c*2)=i+2;
		c++;
	}
	WFIFOW(fd,2)=4+c*2;
	WFIFOSET(fd,WFIFOW(fd,2));

	return 0;
}
/*==========================================
 * �J�[�h�̑}���I��
 *------------------------------------------
 */
int clif_insert_card(struct map_session_data *sd,int idx_equip,int idx_card,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x17d]);
	WFIFOW(fd,0)=0x17d;
	WFIFOW(fd,2)=idx_equip+2;
	WFIFOW(fd,4)=idx_card+2;
	WFIFOB(fd,6)=flag;
	WFIFOSET(fd,packet_len_table[0x17d]);
	return 0;
}

/*==========================================
 * �Ӓ�”\�A�C�e�����X�g���M
 *------------------------------------------
 */
int clif_item_identify_list(struct map_session_data *sd)
{
	int i,c;
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;

	WFIFOHEAD(fd,MAX_INVENTORY * 2 + 4);
	WFIFOW(fd,0)=0x177;
	for(i=c=0;i<MAX_INVENTORY;i++){
		if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].identify!=1){
			WFIFOW(fd,c*2+4)=i+2;
			c++;
		}
	}
	if(c > 0) {
		WFIFOW(fd,2)=c*2+4;
		WFIFOSET(fd,WFIFOW(fd,2));
		sd->menuskill_id = MC_IDENTIFY;
		sd->menuskill_lv = c;
	}
	return 0;
}

/*==========================================
 * �Ӓ茋��
 *------------------------------------------
 */
int clif_item_identified(struct map_session_data *sd,int idx,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x179]);
	WFIFOW(fd, 0)=0x179;
	WFIFOW(fd, 2)=idx+2;
	WFIFOB(fd, 4)=flag;
	WFIFOSET(fd,packet_len_table[0x179]);
	return 0;
}

/*==========================================
 * �C���”\�A�C�e�����X�g���M
 *------------------------------------------
 */
int clif_item_repair_list(struct map_session_data *sd,struct map_session_data *dstsd)
{
	int i,c;
	int fd;
	int nameid;

	nullpo_retr(0, sd);
	nullpo_retr(0, dstsd);

	fd=sd->fd;

	WFIFOHEAD(fd, MAX_INVENTORY * 13 + 4);
	WFIFOW(fd,0)=0x1fc;
	for(i=c=0;i<MAX_INVENTORY;i++){
		if((nameid=dstsd->status.inventory[i].nameid) > 0 && dstsd->status.inventory[i].attribute!=0){// && skill_can_repair(sd,nameid)){
			WFIFOW(fd,c*13+4) = i;
			WFIFOW(fd,c*13+6) = nameid;
			WFIFOL(fd,c*13+8) = sd->status.char_id;
			WFIFOL(fd,c*13+12)= dstsd->status.char_id;
			WFIFOB(fd,c*13+16)= c;
			c++;
		}
	}
	if(c > 0) {
		WFIFOW(fd,2)=c*13+4;
		WFIFOSET(fd,WFIFOW(fd,2));
		sd->menuskill_id = BS_REPAIRWEAPON;
		sd->menuskill_lv = dstsd->bl.id;
	}else
		clif_skill_fail(sd,sd->ud.skillid,0,0);

	return 0;
}
int clif_item_repaireffect(struct map_session_data *sd,int nameid,int flag)
{
	int view,fd;

	nullpo_retr(0, sd);
	fd=sd->fd;

	WFIFOHEAD(fd,packet_len_table[0x1fe]);
	WFIFOW(fd, 0)=0x1fe;
	if((view = itemdb_viewid(nameid)) > 0)
		WFIFOW(fd, 2)=view;
	else
		WFIFOW(fd, 2)=nameid;
	WFIFOB(fd, 4)=flag;
	WFIFOSET(fd,packet_len_table[0x1fe]);

	return 0;
}

/*==========================================
 * Weapon Refining - Taken from jAthena
 *------------------------------------------
 */
int clif_item_refine_list(struct map_session_data *sd)
{
	int i,c;
	int fd;
	int skilllv;
	int wlv;
	int refine_item[5];

	nullpo_retr(0, sd);

	skilllv = pc_checkskill(sd,WS_WEAPONREFINE);

	fd=sd->fd;

	refine_item[0] = -1;
	refine_item[1] = pc_search_inventory(sd,1010);
	refine_item[2] = pc_search_inventory(sd,1011);
	refine_item[3] = refine_item[4] = pc_search_inventory(sd,984);

	WFIFOHEAD(fd, MAX_INVENTORY * 13 + 4);
	WFIFOW(fd,0)=0x221;
	for(i=c=0;i<MAX_INVENTORY;i++){
		if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].refine < skilllv &&
			sd->status.inventory[i].identify==1 && (wlv=itemdb_wlv(sd->status.inventory[i].nameid)) >=1 &&
			refine_item[wlv]!=-1 && !(sd->status.inventory[i].equip&0x0022)){
			WFIFOW(fd,c*13+ 4)=i+2;
			WFIFOW(fd,c*13+ 6)=sd->status.inventory[i].nameid;
			WFIFOW(fd,c*13+ 8)=0; //TODO: Wonder what are these for? Perhaps ID of weapon's crafter if any?
			WFIFOW(fd,c*13+10)=0;
			WFIFOB(fd,c*13+12)=c;
			c++;
		}
	}
	WFIFOW(fd,2)=c*13+4;
	WFIFOSET(fd,WFIFOW(fd,2));
	sd->menuskill_id = WS_WEAPONREFINE;
	sd->menuskill_lv = skilllv;

	return 0;
}

/*==========================================
 * �A�C�e���ɂ��ꎞ�I�ȃX�L������
 *------------------------------------------
 */
int clif_item_skill(struct map_session_data *sd,int skillid,int skilllv,const char *name)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x147]);
	WFIFOW(fd, 0)=0x147;
	WFIFOW(fd, 2)=skillid;
	WFIFOW(fd, 4)=skill_get_inf(skillid);
	WFIFOW(fd, 6)=0;
	WFIFOW(fd, 8)=skilllv;
	WFIFOW(fd,10)=skill_get_sp(skillid,skilllv);
	WFIFOW(fd,12)=skill_get_range2(&sd->bl, skillid,skilllv);
	strncpy((char*)WFIFOP(fd,14),name,NAME_LENGTH);
	WFIFOB(fd,38)=0;
	WFIFOSET(fd,packet_len_table[0x147]);
	return 0;
}

/*==========================================
 * �J�[�g�ɃA�C�e���lj�
 *------------------------------------------
 */
int clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail)
{
	int view,fd;
	unsigned char *buf;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x124]);
	buf=WFIFOP(fd,0);
	if(n<0 || n>=MAX_CART || sd->status.cart[n].nameid<=0)
		return 1;

	WBUFW(buf,0)=0x124;
	WBUFW(buf,2)=n+2;
	WBUFL(buf,4)=amount;
	if((view = itemdb_viewid(sd->status.cart[n].nameid)) > 0)
		WBUFW(buf,8)=view;
	else
		WBUFW(buf,8)=sd->status.cart[n].nameid;
	WBUFB(buf,10)=sd->status.cart[n].identify;
	WBUFB(buf,11)=sd->status.cart[n].attribute;
	WBUFB(buf,12)=sd->status.cart[n].refine;
	clif_addcards(WBUFP(buf,13), &sd->status.cart[n]);
	WFIFOSET(fd,packet_len_table[0x124]);
	return 0;
}

/*==========================================
 * �J�[�g����A�C�e���폜
 *------------------------------------------
 */
int clif_cart_delitem(struct map_session_data *sd,int n,int amount)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;

	WFIFOHEAD(fd,packet_len_table[0x125]);
	WFIFOW(fd,0)=0x125;
	WFIFOW(fd,2)=n+2;
	WFIFOL(fd,4)=amount;

	WFIFOSET(fd,packet_len_table[0x125]);

	return 0;
}

/*==========================================
 * �J�[�g�̃A�C�e�����X�g
 *------------------------------------------
 */
int clif_cart_itemlist(struct map_session_data *sd)
{
	struct item_data *id;
	int i,n,fd;
	unsigned char *buf;

	nullpo_retr(0, sd);

	fd=sd->fd;
        WFIFOHEAD(fd, MAX_CART * 18 + 4);
	buf = WFIFOP(fd,0);
#if PACKETVER < 5
	for(i=0,n=0;i<MAX_CART;i++){
		if(sd->status.cart[i].nameid<=0)
			continue;
		id = itemdb_search(sd->status.cart[i].nameid);
		if(itemdb_isequip2(id))
			continue;
		WBUFW(buf,n*10+4)=i+2;
		if(id->view_id > 0)
			WBUFW(buf,n*10+6)=id->view_id;
		else
			WBUFW(buf,n*10+6)=sd->status.cart[i].nameid;
		WBUFB(buf,n*10+8)=itemtype(id->type);
		WBUFB(buf,n*10+9)=sd->status.cart[i].identify;
		WBUFW(buf,n*10+10)=sd->status.cart[i].amount;
		WBUFW(buf,n*10+12)=0;
		n++;
	}
	if(n){
		WBUFW(buf,0)=0x123;
		WBUFW(buf,2)=4+n*10;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
#else
	for(i=0,n=0;i<MAX_CART;i++){
		if(sd->status.cart[i].nameid<=0)
			continue;
		id = itemdb_search(sd->status.cart[i].nameid);
		if(itemdb_isequip2(id))
			continue;
		WBUFW(buf,n*18+4)=i+2;
		if(id->view_id > 0)
			WBUFW(buf,n*18+6)=id->view_id;
		else
			WBUFW(buf,n*18+6)=sd->status.cart[i].nameid;
		WBUFB(buf,n*18+8)=itemtype(id->type);
		WBUFB(buf,n*18+9)=sd->status.cart[i].identify;
		WBUFW(buf,n*18+10)=sd->status.cart[i].amount;
		WBUFW(buf,n*18+12)=0; //Here goes the equip location, which seems unnecessary to fill for the cart data.
		clif_addcards(WBUFP(buf,n*18+14), &sd->status.cart[i]);
		n++;
	}
	if(n){
		WBUFW(buf,0)=0x1ef;
		WBUFW(buf,2)=4+n*18;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
#endif
	return 0;
}

/*==========================================
 * �J�[�g�̑����i���X�g
 *------------------------------------------
 */
int clif_cart_equiplist(struct map_session_data *sd)
{
	struct item_data *id;
	int i,n,fd;
	unsigned char *buf;

	nullpo_retr(0, sd);

	fd=sd->fd;
        WFIFOHEAD(fd, MAX_INVENTORY * 20 + 4);
	buf = WFIFOP(fd,0);

	for(i=0,n=0;i<MAX_INVENTORY;i++){
		if(sd->status.cart[i].nameid<=0)
			continue;
		id = itemdb_search(sd->status.cart[i].nameid);
		if(!itemdb_isequip2(id))
			continue;
		WBUFW(buf,n*20+4)=i+2;
		if(id->view_id > 0)
			WBUFW(buf,n*20+6)=id->view_id;
		else
			WBUFW(buf,n*20+6)=sd->status.cart[i].nameid;
		WBUFB(buf,n*20+8)=itemtype(id->type);
		WBUFB(buf,n*20+9)=sd->status.cart[i].identify;
		WBUFW(buf,n*20+10)=id->equip;
		WBUFW(buf,n*20+12)=sd->status.cart[i].equip;
		WBUFB(buf,n*20+14)=sd->status.cart[i].attribute;
		WBUFB(buf,n*20+15)=sd->status.cart[i].refine;
		clif_addcards(WBUFP(buf, n*20+16), &sd->status.cart[i]);
		n++;
	}
	if(n){
		WBUFW(buf,0)=0x122;
		WBUFW(buf,2)=4+n*20;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
	return 0;
}

/*==========================================
 * �I�X�J��
 *------------------------------------------
 */
int clif_openvendingreq(struct map_session_data *sd,int num)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x12d]);
	WFIFOW(fd,0)=0x12d;
	WFIFOW(fd,2)=num;
	WFIFOSET(fd,packet_len_table[0x12d]);

	return 0;
}

/*==========================================
 * �I�X�Ŕ•\��
 *------------------------------------------
 */
int clif_showvendingboard(struct block_list* bl,char *message,int fd)
{
	unsigned char buf[128];

	nullpo_retr(0, bl);

	WBUFW(buf,0)=0x131;
	WBUFL(buf,2)=bl->id;
	strncpy((char*)WBUFP(buf,6),message,80);
	if(fd){
		WFIFOHEAD(fd,packet_len_table[0x131]);
		memcpy(WFIFOP(fd,0),buf,packet_len_table[0x131]);
		WFIFOSET(fd,packet_len_table[0x131]);
	}else{
		clif_send(buf,packet_len_table[0x131],bl,AREA_WOS);
	}
	return 0;
}

/*==========================================
 * �I�X�Ŕ���
 *------------------------------------------
 */
int clif_closevendingboard(struct block_list* bl,int fd)
{
	unsigned char buf[16];

	nullpo_retr(0, bl);

	WBUFW(buf,0)=0x132;
	WBUFL(buf,2)=bl->id;
	if(fd){
		WFIFOHEAD(fd,packet_len_table[0x132]);
		memcpy(WFIFOP(fd,0),buf,packet_len_table[0x132]);
		WFIFOSET(fd,packet_len_table[0x132]);
	}else{
		clif_send(buf,packet_len_table[0x132],bl,AREA_WOS);
	}

	return 0;
}
/*==========================================
 * �I�X�A�C�e�����X�g
 *------------------------------------------
 */
int clif_vendinglist(struct map_session_data *sd,int id,struct vending *vending)
{
	struct item_data *data;
	int i,n,index,fd;
	struct map_session_data *vsd;
	unsigned char *buf;

	nullpo_retr(0, sd);
	nullpo_retr(0, vending);
	nullpo_retr(0, vsd=map_id2sd(id));

	fd=sd->fd;
        WFIFOHEAD(fd, 8+vsd->vend_num*22);
	buf = WFIFOP(fd,0);
	for(i=0,n=0;i<vsd->vend_num;i++){
		if(vending[i].amount<=0)
			continue;
		WBUFL(buf,8+n*22)=vending[i].value;
		WBUFW(buf,12+n*22)=vending[i].amount;
		WBUFW(buf,14+n*22)=(index=vending[i].index)+2;
		if(vsd->status.cart[index].nameid <= 0 || vsd->status.cart[index].amount <= 0)
			continue;
		data = itemdb_search(vsd->status.cart[index].nameid);
		WBUFB(buf,16+n*22)=itemtype(data->type);
		if(data->view_id > 0)
			WBUFW(buf,17+n*22)=data->view_id;
		else
			WBUFW(buf,17+n*22)=vsd->status.cart[index].nameid;
		WBUFB(buf,19+n*22)=vsd->status.cart[index].identify;
		WBUFB(buf,20+n*22)=vsd->status.cart[index].attribute;
		WBUFB(buf,21+n*22)=vsd->status.cart[index].refine;
		clif_addcards(WBUFP(buf, 22+n*22), &vsd->status.cart[index]);
		n++;
	}
	if(n > 0){
		WBUFW(buf,0)=0x133;
		WBUFW(buf,2)=8+n*22;
		WBUFL(buf,4)=id;
		WFIFOSET(fd,WFIFOW(fd,2));
	}

	return 0;
}

/*==========================================
 * �I�X�A�C�e���w�����s
 *------------------------------------------
*/
int clif_buyvending(struct map_session_data *sd,int index,int amount,int fail)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x135]);
	WFIFOW(fd,0)=0x135;
	WFIFOW(fd,2)=index+2;
	WFIFOW(fd,4)=amount;
	WFIFOB(fd,6)=fail;
	WFIFOSET(fd,packet_len_table[0x135]);

	return 0;
}

/*==========================================
 * �I�X�J�ݐ���
 *------------------------------------------
*/
int clif_openvending(struct map_session_data *sd,int id,struct vending *vending)
{
	struct item_data *data;
	int i,n,index,fd;
	unsigned char *buf;

	nullpo_retr(0, sd);

	fd=sd->fd;
        WFIFOHEAD(fd, 8+sd->vend_num*22);
	buf = WFIFOP(fd,0);
	for(i=0,n=0;i<sd->vend_num;i++){
		if (sd->vend_num > 2+pc_checkskill(sd,MC_VENDING)) return 0;
		WBUFL(buf,8+n*22)=vending[i].value;
		WBUFW(buf,12+n*22)=(index=vending[i].index)+2;
		WBUFW(buf,14+n*22)=vending[i].amount;
		if(sd->status.cart[index].nameid <= 0 || sd->status.cart[index].amount <= 0 || sd->status.cart[index].identify==0 ||
			sd->status.cart[index].attribute==1) // Prevent unidentified and broken items from being sold [Valaris]
			continue;
		data = itemdb_search(sd->status.cart[index].nameid);
		WBUFB(buf,16+n*22)=itemtype(data->type);
		if(data->view_id > 0)
			WBUFW(buf,17+n*22)=data->view_id;
		else
			WBUFW(buf,17+n*22)=sd->status.cart[index].nameid;
		WBUFB(buf,19+n*22)=sd->status.cart[index].identify;
		WBUFB(buf,20+n*22)=sd->status.cart[index].attribute;
		WBUFB(buf,21+n*22)=sd->status.cart[index].refine;
		clif_addcards(WBUFP(buf, 22+n*22), &sd->status.cart[index]);
		n++;
	}
	if(n > 0){
		WBUFW(buf,0)=0x136;
		WBUFW(buf,2)=8+n*22;
		WBUFL(buf,4)=id;
		WFIFOSET(fd,WFIFOW(fd,2));
	}
	return n;
}

/*==========================================
 * �I�X�A�C�e���̔���
 *------------------------------------------
*/
int clif_vendingreport(struct map_session_data *sd,int index,int amount)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x137]);
	WFIFOW(fd,0)=0x137;
	WFIFOW(fd,2)=index+2;
	WFIFOW(fd,4)=amount;
	WFIFOSET(fd,packet_len_table[0x137]);

	return 0;
}
/*==========================================
 * �p�[�e�B�쐬����
 *------------------------------------------
 */
int clif_party_created(struct map_session_data *sd,int flag)
{
	int fd;

	// printf("clif_party_message(%s, %d, %s)\n", p->name, account_id, mes);

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xfa]);
	WFIFOW(fd,0)=0xfa;
	WFIFOB(fd,2)=flag;
	WFIFOSET(fd,packet_len_table[0xfa]);
	return 0;
}

int clif_party_main_info(struct party *p, int fd)
{
	struct map_session_data *sd;
	int i;
	unsigned char buf[96];
	
	for (i=0; i<MAX_PARTY && !p->member[i].leader; i++);
	if (i >= MAX_PARTY) return 0; //Should never happen...
	sd = p->member[i].sd;
	WBUFW(buf,0)=0x1e9;
	WBUFL(buf,2)= p->member[i].account_id;
	WBUFL(buf,6)= 0; //We don't know yet what this long is about.
	WBUFW(buf,10)=sd?sd->bl.x:0;
	WBUFW(buf,12)=sd?sd->bl.y:0;
	WBUFB(buf,14)=(p->member[i].online)?0:1;	//This byte is also unconfirmed...
	memcpy(WBUFP(buf,15), p->name, NAME_LENGTH);
	memcpy(WBUFP(buf,39), p->member[i].name, NAME_LENGTH);
	memcpy(WBUFP(buf,63), mapindex_id2name(p->member[i].map), MAP_NAME_LENGTH);
	WBUFB(buf,79) = (p->item&1)?1:0;
	WBUFB(buf,80) = (p->item&2)?1:0;
	if(fd>=0){
		WFIFOHEAD(fd,packet_len_table[0x1e9]);
		memcpy(WFIFOP(fd,0),buf,packet_len_table[0x1e9]);
		WFIFOSET(fd,packet_len_table[0x1e9]);
		return 1;
	}
	if (!sd) {
		for (i=0; i<MAX_PARTY && !p->member[i].sd; i++)
		if (i >= MAX_PARTY) return 0; //Should never happen...
		sd=p->member[i].sd;
	}
	clif_send(buf,packet_len_table[0x1e9],&sd->bl,PARTY);
	return 1;
}

/*==========================================
 * �p�[�e�B��񑗐M
 *------------------------------------------
 */
int clif_party_info(struct party *p,int fd)
{
	unsigned char buf[1024];
	int i,c;
	struct map_session_data *sd=NULL;

	nullpo_retr(0, p);

	WBUFW(buf,0)=0xfb;
	memcpy(WBUFP(buf,4),p->name,NAME_LENGTH);
	for(i=c=0;i<MAX_PARTY;i++){
		struct party_member *m=&p->member[i];
		if(m->account_id>0){
			if(sd==NULL) sd=m->sd;
			WBUFL(buf,28+c*46)=m->account_id;
			memcpy(WBUFP(buf,28+c*46+ 4),m->name,NAME_LENGTH);
			memcpy(WBUFP(buf,28+c*46+28),mapindex_id2name(m->map),MAP_NAME_LENGTH);
			WBUFB(buf,28+c*46+44)=(m->leader)?0:1;
			WBUFB(buf,28+c*46+45)=(m->online)?0:1;
			c++;
		}
	}
	WBUFW(buf,2)=28+c*46;
	if(fd>=0){	// fd���ݒ肳��Ă�Ȃ炻��ɑ���
		WFIFOHEAD(fd, 28+c*46);
		memcpy(WFIFOP(fd,0),buf,WBUFW(buf,2));
		WFIFOSET(fd,WFIFOW(fd,2));
		return 9;
	}
	if(sd!=NULL)
		clif_send(buf,WBUFW(buf,2),&sd->bl,PARTY);
	return 0;
}
/*==========================================
 * �p�[�e�B���U
 *------------------------------------------
 */
int clif_party_invite(struct map_session_data *sd,struct map_session_data *tsd)
{
	int fd;
	struct party *p;

	nullpo_retr(0, sd);
	nullpo_retr(0, tsd);

	fd=tsd->fd;

	if( (p=party_search(sd->status.party_id))==NULL )
		return 0;

	WFIFOHEAD(fd,packet_len_table[0xfe]);
	WFIFOW(fd,0)=0xfe;
	WFIFOL(fd,2)=sd->status.account_id;
	memcpy(WFIFOP(fd,6),p->name,NAME_LENGTH);
	WFIFOSET(fd,packet_len_table[0xfe]);
	return 0;
}

/*==========================================
 * �p�[�e�B���U����
 *------------------------------------------
 */
int clif_party_inviteack(struct map_session_data *sd,char *nick,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xfd]);
	WFIFOW(fd,0)=0xfd;
	memcpy(WFIFOP(fd,2),nick,NAME_LENGTH);
	WFIFOB(fd,26)=flag;
	WFIFOSET(fd,packet_len_table[0xfd]);
	return 0;
}

/*==========================================
 * �p�[�e�B�ݒ著�M
 * flag & 0x001=exp�ύX�~�X
 *        0x010=item�ύX�~�X
 *        0x100=��l�ɂ̂ݑ��M
 *------------------------------------------
 */
int clif_party_option(struct party *p,struct map_session_data *sd,int flag)
{
	unsigned char buf[16];

	nullpo_retr(0, p);

//	if(battle_config.etc_log)
//		printf("clif_party_option: %d %d %d\n",p->exp,p->item,flag);
	if(sd==NULL && flag==0){
		int i;
		for(i=0;i<MAX_PARTY;i++)
			if((sd=map_id2sd(p->member[i].account_id))!=NULL)
				break;
	}
	if(sd==NULL)
		return 0;
	WBUFW(buf,0)=0x101;
	WBUFW(buf,2)=((flag&0x01)?2:p->exp);
	WBUFW(buf,4)=0; //NOTE: We don't know yet what this is for, it is NOT for item share rules, though. [Skotlex]
	if(flag==0)
		clif_send(buf,packet_len_table[0x101],&sd->bl,PARTY);
	else {
		WFIFOHEAD(sd->fd,packet_len_table[0x101]);
		memcpy(WFIFOP(sd->fd,0),buf,packet_len_table[0x101]);
		WFIFOSET(sd->fd,packet_len_table[0x101]);
	}
	return 0;
}
/*==========================================
 * �p�[�e�B�E�ށi�E�ޑO�ɌĂԂ��Ɓj
 *------------------------------------------
 */
int clif_party_leaved(struct party *p,struct map_session_data *sd,int account_id,char *name,int flag)
{
	unsigned char buf[64];
	int i;

	nullpo_retr(0, p);

	WBUFW(buf,0)=0x105;
	WBUFL(buf,2)=account_id;
	memcpy(WBUFP(buf,6),name,NAME_LENGTH);
	WBUFB(buf,30)=flag&0x0f;

	if((flag&0xf0)==0){
		if(sd==NULL)
			for(i=0;i<MAX_PARTY;i++)
				if((sd=p->member[i].sd)!=NULL)
					break;
		if (sd!=NULL)
			clif_send(buf,packet_len_table[0x105],&sd->bl,PARTY);
	} else if (sd!=NULL) {
		WFIFOHEAD(sd->fd,packet_len_table[0x105]);
		memcpy(WFIFOP(sd->fd,0),buf,packet_len_table[0x105]);
		WFIFOSET(sd->fd,packet_len_table[0x105]);
	}
	return 0;
}
/*==========================================
 * �p�[�e�B���b�Z�[�W���M
 *------------------------------------------
 */
int clif_party_message(struct party *p,int account_id,char *mes,int len)
{
	struct map_session_data *sd;
	int i;

	nullpo_retr(0, p);

	for(i=0;i<MAX_PARTY;i++){
		if((sd=p->member[i].sd)!=NULL)
			break;
	}
	if(sd!=NULL){
		unsigned char buf[1024];
		WBUFW(buf,0)=0x109;
		WBUFW(buf,2)=len+8;
		WBUFL(buf,4)=account_id;
		memcpy(WBUFP(buf,8),mes,len);
		clif_send(buf,len+8,&sd->bl,PARTY);
	}
	return 0;
}
/*==========================================
 * �p�[�e�B���W�ʒm
 *------------------------------------------
 */
int clif_party_xy(struct map_session_data *sd)
{
	unsigned char buf[16];

	nullpo_retr(0, sd);

	WBUFW(buf,0)=0x107;
	WBUFL(buf,2)=sd->status.account_id;
	WBUFW(buf,6)=sd->bl.x;
	WBUFW(buf,8)=sd->bl.y;
	clif_send(buf,packet_len_table[0x107],&sd->bl,PARTY_SAMEMAP_WOS);
	
	return 0;
}

/*==========================================
 * Sends x/y dot to a single fd. [Skotlex]
 *------------------------------------------
 */

int clif_party_xy_single(int fd, struct map_session_data *sd)
{
	WFIFOHEAD(fd,packet_len_table[0x107]);
	WFIFOW(fd,0)=0x107;
	WFIFOL(fd,2)=sd->status.account_id;
	WFIFOW(fd,6)=sd->bl.x;
	WFIFOW(fd,8)=sd->bl.y;
	WFIFOSET(fd,packet_len_table[0x107]);
	return 0;
}


/*==========================================
 * �p�[�e�BHP�ʒm
 *------------------------------------------
 */
int clif_party_hp(struct map_session_data *sd)
{
	unsigned char buf[16];

	nullpo_retr(0, sd);

	WBUFW(buf,0)=0x106;
	WBUFL(buf,2)=sd->status.account_id;
	WBUFW(buf,6)=(sd->status.hp > 0x7fff)? 0x7fff:sd->status.hp;
	WBUFW(buf,8)=(sd->status.max_hp > 0x7fff)? 0x7fff:sd->status.max_hp;
	clif_send(buf,packet_len_table[0x106],&sd->bl,PARTY_AREA_WOS);
	return 0;
}

/*==========================================
 * Sends HP bar to a single fd. [Skotlex]
 *------------------------------------------
 */
static void clif_hpmeter_single(int fd, struct map_session_data *sd)
{
	WFIFOHEAD(fd,packet_len_table[0x106]);
	WFIFOW(fd,0) = 0x106;
	WFIFOL(fd,2) = sd->status.account_id;
	WFIFOW(fd,6) = (sd->status.hp > 0x7fff) ? 0x7fff : sd->status.hp;
	WFIFOW(fd,8) = (sd->status.max_hp > 0x7fff) ? 0x7fff : sd->status.max_hp;
	WFIFOSET (fd, packet_len_table[0x106]);
}

/*==========================================
 * GM�֏ꏊ��HP�ʒm
 *------------------------------------------
 */
int clif_hpmeter(struct map_session_data *sd)
{
	struct map_session_data *sd2;
	unsigned char buf[16];
	int i, x0, y0, x1, y1;
	int level;

	nullpo_retr(0, sd);

	x0 = sd->bl.x - AREA_SIZE;
	y0 = sd->bl.y - AREA_SIZE;
	x1 = sd->bl.x + AREA_SIZE;
	y1 = sd->bl.y + AREA_SIZE;

	WBUFW(buf,0) = 0x106;
	WBUFL(buf,2) = sd->status.account_id;
	WBUFW(buf,6) = (sd->status.hp > 0x7fff) ? 0x7fff : sd->status.hp;
	WBUFW(buf,8) = (sd->status.max_hp > 0x7fff) ? 0x7fff : sd->status.max_hp;
	for (i = 0; i < fd_max; i++) {
		if (session[i] && (sd2 = (struct map_session_data*)session[i]->session_data) &&  sd != sd2 && sd2->state.auth) {
			if (sd2->bl.m != sd->bl.m || 
				sd2->bl.x < x0 || sd2->bl.y < y0 ||
				sd2->bl.x > x1 || sd2->bl.y > y1 ||
				(level = pc_isGM(sd2)) < battle_config.disp_hpmeter ||
				level < pc_isGM(sd))
				continue;
			WFIFOHEAD (i, packet_len_table[0x106]);
			memcpy (WFIFOP(i,0), buf, packet_len_table[0x106]);
			WFIFOSET (i, packet_len_table[0x106]);
		}
	}

	return 0;
}

/*==========================================
 * �p�[�e�B�ꏊ�ړ��i���g�p�j
 *------------------------------------------
 */
int clif_party_move(struct party *p,struct map_session_data *sd,int online)
{
	unsigned char buf[128];

	nullpo_retr(0, sd);
	nullpo_retr(0, p);

	WBUFW(buf, 0)=0x104;
	WBUFL(buf, 2)=sd->status.account_id;
	WBUFL(buf, 6)=0;
	WBUFW(buf,10)=sd->bl.x;
	WBUFW(buf,12)=sd->bl.y;
	WBUFB(buf,14)=!online;
	memcpy(WBUFP(buf,15),p->name, NAME_LENGTH);
	memcpy(WBUFP(buf,39),sd->status.name, NAME_LENGTH);
	memcpy(WBUFP(buf,63),map[sd->bl.m].name, MAP_NAME_LENGTH);
	clif_send(buf,packet_len_table[0x104],&sd->bl,PARTY);
	return 0;
}
/*==========================================
 * �U�����邽�߂Ɉړ����K�v
 *------------------------------------------
 */
int clif_movetoattack(struct map_session_data *sd,struct block_list *bl)
{
	int fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, bl);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x139]);
	WFIFOW(fd, 0)=0x139;
	WFIFOL(fd, 2)=bl->id;
	WFIFOW(fd, 6)=bl->x;
	WFIFOW(fd, 8)=bl->y;
	WFIFOW(fd,10)=sd->bl.x;
	WFIFOW(fd,12)=sd->bl.y;
	WFIFOW(fd,14)=sd->attackrange;
	WFIFOSET(fd,packet_len_table[0x139]);
	return 0;
}
/*==========================================
 * �����G�t�F�N�g
 *------------------------------------------
 */
int clif_produceeffect(struct map_session_data *sd,int flag,int nameid)
{
	int view,fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	// ���O�̓o�^�Ƒ��M���ɂ��Ă���
	if( map_charid2nick(sd->status.char_id)==NULL )
		map_addchariddb(sd->status.char_id,sd->status.name);
	clif_solved_charname(sd,sd->status.char_id);

	WFIFOHEAD(fd,packet_len_table[0x18f]);
	WFIFOW(fd, 0)=0x18f;
	WFIFOW(fd, 2)=flag;
	if((view = itemdb_viewid(nameid)) > 0)
		WFIFOW(fd, 4)=view;
	else
		WFIFOW(fd, 4)=nameid;
	WFIFOSET(fd,packet_len_table[0x18f]);
	return 0;
}

// pet
int clif_catch_process(struct map_session_data *sd)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x19e]);
	WFIFOW(fd,0)=0x19e;
	WFIFOSET(fd,packet_len_table[0x19e]);
	sd->menuskill_id = SA_TAMINGMONSTER;
	if (sd->ud.skillid == SA_TAMINGMONSTER)
		sd->menuskill_lv = 0;	//Free catch
	else
		sd->menuskill_lv = sd->itemid;	//Consume catch
	return 0;
}

int clif_pet_rulet(struct map_session_data *sd,int data)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x1a0]);
	WFIFOW(fd,0)=0x1a0;
	WFIFOB(fd,2)=data;
	WFIFOSET(fd,packet_len_table[0x1a0]);

	return 0;
}

/*==========================================
 * pet�����X�g�쐬
 *------------------------------------------
 */
int clif_sendegg(struct map_session_data *sd)
{
	//R 01a6 <len>.w <index>.w*
	int i,n=0,fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	if (battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m))
	{	//Disable pet hatching in GvG grounds during Guild Wars [Skotlex]
		clif_displaymessage(fd, "Pets are not allowed in Guild Wars.");
		return 0;
	}
	WFIFOHEAD(fd, MAX_INVENTORY * 2 + 4);
	WFIFOW(fd,0)=0x1a6;
	if(sd->status.pet_id <= 0) {
		for(i=0,n=0;i<MAX_INVENTORY;i++){
			if(sd->status.inventory[i].nameid<=0 || sd->inventory_data[i] == NULL ||
			   sd->inventory_data[i]->type!=7 ||
			   sd->status.inventory[i].amount<=0)
				continue;
			WFIFOW(fd,n*2+4)=i+2;
			n++;
		}
	}
	WFIFOW(fd,2)=4+n*2;
	WFIFOSET(fd,WFIFOW(fd,2));

	sd->menuskill_id = SA_TAMINGMONSTER;
	sd->menuskill_lv = -1;
	return 0;
}

int clif_send_petdata(struct map_session_data *sd,int type,int param)
{
	int fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, sd->pd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x1a4]);
	WFIFOW(fd,0)=0x1a4;
	WFIFOB(fd,2)=type;
	WFIFOL(fd,3)=sd->pd->bl.id;
	WFIFOL(fd,7)=param;
	WFIFOSET(fd,packet_len_table[0x1a4]);

	return 0;
}

int clif_send_petstatus(struct map_session_data *sd)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x1a2]);
	WFIFOW(fd,0)=0x1a2;
	memcpy(WFIFOP(fd,2),sd->pet.name,NAME_LENGTH);
	WFIFOB(fd,26)=(battle_config.pet_rename == 1)? 0:sd->pet.rename_flag;
	WFIFOW(fd,27)=sd->pet.level;
	WFIFOW(fd,29)=sd->pet.hungry;
	WFIFOW(fd,31)=sd->pet.intimate;
	WFIFOW(fd,33)=sd->pet.equip;
	WFIFOSET(fd,packet_len_table[0x1a2]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_pet_emotion(struct pet_data *pd,int param)
{
	unsigned char buf[16];
	struct map_session_data *sd;

	nullpo_retr(0, pd);
	nullpo_retr(0, sd = pd->msd);

	memset(buf,0,packet_len_table[0x1aa]);

	WBUFW(buf,0)=0x1aa;
	WBUFL(buf,2)=pd->bl.id;
	if(param >= 100 && sd->petDB->talk_convert_class) {
		if(sd->petDB->talk_convert_class < 0)
			return 0;
		else if(sd->petDB->talk_convert_class > 0) {
			param -= (pd->class_ - 100)*100;
			param += (sd->petDB->talk_convert_class - 100)*100;
		}
	}
	WBUFL(buf,6)=param;

	clif_send(buf,packet_len_table[0x1aa],&pd->bl,AREA);

	return 0;
}

int clif_pet_performance(struct block_list *bl,int param)
{
	unsigned char buf[16];

	nullpo_retr(0, bl);

	memset(buf,0,packet_len_table[0x1a4]);

	WBUFW(buf,0)=0x1a4;
	WBUFB(buf,2)=4;
	WBUFL(buf,3)=bl->id;
	WBUFL(buf,7)=param;

	clif_send(buf,packet_len_table[0x1a4],bl,AREA);

	return 0;
}

int clif_pet_equip(struct pet_data *pd,int nameid)
{
	unsigned char buf[16];

	nullpo_retr(0, pd);

	memset(buf,0,packet_len_table[0x1a4]);

	WBUFW(buf,0)=0x1a4;
	WBUFB(buf,2)=3;
	WBUFL(buf,3)=pd->bl.id;
	WBUFL(buf,7)=pd->vd.shield;
	clif_send(buf,packet_len_table[0x1a4],&pd->bl,AREA);

	return 0;
}

int clif_pet_food(struct map_session_data *sd,int foodid,int fail)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x1a3]);
	WFIFOW(fd,0)=0x1a3;
	WFIFOB(fd,2)=fail;
	WFIFOW(fd,3)=foodid;
	WFIFOSET(fd,packet_len_table[0x1a3]);

	return 0;
}

/*==========================================
 * �I�[�g�X�y�� ���X�g���M
 *------------------------------------------
 */
int clif_autospell(struct map_session_data *sd,int skilllv)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x1cd]);
	WFIFOW(fd, 0)=0x1cd;

	if(skilllv>0 && pc_checkskill(sd,MG_NAPALMBEAT)>0)
		WFIFOL(fd,2)= MG_NAPALMBEAT;
	else
		WFIFOL(fd,2)= 0x00000000;
	if(skilllv>1 && pc_checkskill(sd,MG_COLDBOLT)>0)
		WFIFOL(fd,6)= MG_COLDBOLT;
	else
		WFIFOL(fd,6)= 0x00000000;
	if(skilllv>1 && pc_checkskill(sd,MG_FIREBOLT)>0)
		WFIFOL(fd,10)= MG_FIREBOLT;
	else
		WFIFOL(fd,10)= 0x00000000;
	if(skilllv>1 && pc_checkskill(sd,MG_LIGHTNINGBOLT)>0)
		WFIFOL(fd,14)= MG_LIGHTNINGBOLT;
	else
		WFIFOL(fd,14)= 0x00000000;
	if(skilllv>4 && pc_checkskill(sd,MG_SOULSTRIKE)>0)
		WFIFOL(fd,18)= MG_SOULSTRIKE;
	else
		WFIFOL(fd,18)= 0x00000000;
	if(skilllv>7 && pc_checkskill(sd,MG_FIREBALL)>0)
		WFIFOL(fd,22)= MG_FIREBALL;
	else
		WFIFOL(fd,22)= 0x00000000;
	if(skilllv>9 && pc_checkskill(sd,MG_FROSTDIVER)>0)
		WFIFOL(fd,26)= MG_FROSTDIVER;
	else
		WFIFOL(fd,26)= 0x00000000;

	WFIFOSET(fd,packet_len_table[0x1cd]);
	sd->menuskill_id = SA_AUTOSPELL;
	sd->menuskill_lv = skilllv;
	
	return 0;
}

/*==========================================
 * �f�B�{�[�V�����̐‚���
 *------------------------------------------
 */
int clif_devotion(struct map_session_data *sd)
{
	unsigned char buf[56];
	int i,n;

	nullpo_retr(0, sd);

	WBUFW(buf,0)=0x1cf;
	WBUFL(buf,2)=sd->bl.id;
	for(i=0,n=0;i<5;i++) {
		if (!sd->devotion[i])
			continue;
		WBUFL(buf,6+4*n)=sd->devotion[i];
		n++;
	}
	for(;n<5;n++)
		WBUFL(buf,6+4*n)=0;
		
	WBUFB(buf,26)=8;
	WBUFB(buf,27)=0;

	clif_send(buf,packet_len_table[0x1cf],&sd->bl,AREA);
	return 0;
}

int clif_marionette(struct block_list *src, struct block_list *target)
{
	unsigned char buf[56];
	int n;

	WBUFW(buf,0)=0x1cf;
	WBUFL(buf,2)=src->id;
	for(n=0;n<5;n++)
		WBUFL(buf,6+4*n)=0;
	if (target) //The target goes on the second slot.
		WBUFL(buf,6+4) = target->id;
	WBUFB(buf,26)=8;
	WBUFB(buf,27)=0;

	clif_send(buf,packet_len_table[0x1cf],src,AREA);
	return 0;
}

/*==========================================
 * ����
 *------------------------------------------
 */
int clif_spiritball(struct map_session_data *sd)
{
	unsigned char buf[16];

	nullpo_retr(0, sd);

	WBUFW(buf,0)=0x1d0;
	WBUFL(buf,2)=sd->bl.id;
	WBUFW(buf,6)=sd->spiritball;
	clif_send(buf,packet_len_table[0x1d0],&sd->bl,AREA);
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_combo_delay(struct block_list *bl,int wait)
{
	unsigned char buf[32];

	nullpo_retr(0, bl);

	WBUFW(buf,0)=0x1d2;
	WBUFL(buf,2)=bl->id;
	WBUFL(buf,6)=wait;
	clif_send(buf,packet_len_table[0x1d2],bl,AREA);

	return 0;
}
/*==========================================
 *���n���
 *------------------------------------------
 */
int clif_bladestop(struct block_list *src,struct block_list *dst,
	int _bool)
{
	unsigned char buf[32];

	nullpo_retr(0, src);
	nullpo_retr(0, dst);

	WBUFW(buf,0)=0x1d1;
	WBUFL(buf,2)=src->id;
	WBUFL(buf,6)=dst->id;
	WBUFL(buf,10)=_bool;

	clif_send(buf,packet_len_table[0x1d1],src,AREA);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_changemapcell(int m,int x,int y,int cell_type,int type)
{
	struct block_list bl;
	unsigned char buf[32];

	bl.type = BL_NUL;
	bl.m = m;
	bl.x = x;
	bl.y = y;
	WBUFW(buf,0) = 0x192;
	WBUFW(buf,2) = x;
	WBUFW(buf,4) = y;
	WBUFW(buf,6) = cell_type;
	memcpy(WBUFP(buf,8),map[m].name,MAP_NAME_LENGTH);
	if(!type)
		clif_send(buf,packet_len_table[0x192],&bl,AREA);
	else
		clif_send(buf,packet_len_table[0x192],&bl,ALL_SAMEMAP);

	return 0;
}

/*==========================================
 * MVP�G�t�F�N�g
 *------------------------------------------
 */
int clif_mvp_effect(struct map_session_data *sd)
{
	unsigned char buf[16];

	nullpo_retr(0, sd);

	WBUFW(buf,0)=0x10c;
	WBUFL(buf,2)=sd->bl.id;
	clif_send(buf,packet_len_table[0x10c],&sd->bl,AREA);
	return 0;
}
/*==========================================
 * MVP�A�C�e������
 *------------------------------------------
 */
int clif_mvp_item(struct map_session_data *sd,int nameid)
{
	int view,fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x10a]);
	WFIFOW(fd,0)=0x10a;
	if((view = itemdb_viewid(nameid)) > 0)
		WFIFOW(fd,2)=view;
	else
		WFIFOW(fd,2)=nameid;
	WFIFOSET(fd,packet_len_table[0x10a]);
	return 0;
}
/*==========================================
 * MVP�o���l����
 *------------------------------------------
 */
int clif_mvp_exp(struct map_session_data *sd,int exp)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x10b]);
	WFIFOW(fd,0)=0x10b;
	WFIFOL(fd,2)=exp;
	WFIFOSET(fd,packet_len_table[0x10b]);
	return 0;
}

/*==========================================
 * �M���h�쐬�”ےʒm
 *------------------------------------------
 */
int clif_guild_created(struct map_session_data *sd,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x167]);
	WFIFOW(fd,0)=0x167;
	WFIFOB(fd,2)=flag;
	WFIFOSET(fd,packet_len_table[0x167]);
	return 0;
}
/*==========================================
 * �M���h�����ʒm
 *------------------------------------------
 */
int clif_guild_belonginfo(struct map_session_data *sd,struct guild *g)
{
	int ps,fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, g);

	fd=sd->fd;
	ps=guild_getposition(sd,g);

	WFIFOHEAD(fd,packet_len_table[0x16c]);
	memset(WFIFOP(fd,0),0,packet_len_table[0x16c]);
	WFIFOW(fd,0)=0x16c;
	WFIFOL(fd,2)=g->guild_id;
	WFIFOL(fd,6)=g->emblem_id;
	WFIFOL(fd,10)=g->position[ps].mode;
	memcpy(WFIFOP(fd,19),g->name,NAME_LENGTH);
	WFIFOSET(fd,packet_len_table[0x16c]);
	return 0;
}
/*==========================================
 * �M���h�����o���O�C���ʒm
 *------------------------------------------
 */
int clif_guild_memberlogin_notice(struct guild *g,int idx,int flag)
{
	unsigned char buf[64];

	nullpo_retr(0, g);

	// printf("clif_guild_message(%s, %d, %s)\n", g->name, account_id, mes);

	WBUFW(buf, 0)=0x16d;
	WBUFL(buf, 2)=g->member[idx].account_id;
	WBUFL(buf, 6)=g->member[idx].char_id;
	WBUFL(buf,10)=flag;
	if(g->member[idx].sd==NULL){
		struct map_session_data *sd=guild_getavailablesd(g);
		if(sd!=NULL)
			clif_send(buf,packet_len_table[0x16d],&sd->bl,GUILD);
	}else
		clif_send(buf,packet_len_table[0x16d],&g->member[idx].sd->bl,GUILD_WOS);
	return 0;
}

// Function `clif_guild_memberlogin_notice` sends info about
// logins and logouts of a guild member to the rest members.
// But at the 1st time (after a player login or map changing)
// the client won't show the message.
// So I suggest use this function for sending "first-time-info"
// to some player on entering the game or changing location. 
// At next time the client would always show the message.
// The function sends all the statuses in the single packet 
// to economize traffic. [LuzZza]
int clif_guild_send_onlineinfo(struct map_session_data *sd) {

	struct guild *g;
	char buf[14*128];
	int i, count=0, p_len;
	
	nullpo_retr(0, sd);

	p_len = packet_len_table[0x16d];

	if(!(g = guild_search(sd->status.guild_id)))
		return 0;
	
	for(i=0; i<g->max_member; i++) {

		if(g->member[i].account_id > 0 &&
			g->member[i].account_id != sd->status.account_id) {

			WBUFW(buf,count*p_len) = 0x16d;
			WBUFL(buf,count*p_len+2) = g->member[i].account_id;
			WBUFL(buf,count*p_len+6) = g->member[i].char_id;
			WBUFL(buf,count*p_len+10) = g->member[i].online;
			count++;
		}
	}
	
	clif_send(buf,p_len*count,&sd->bl,SELF);

	return 0;
}

/*==========================================
 * �M���h�}�X�^�[�ʒm(14d�ւ̉���)
 *------------------------------------------
 */
int clif_guild_masterormember(struct map_session_data *sd)
{
	int type=0x57,fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	if(sd->state.gmaster_flag)
		type=0xd7;
	WFIFOHEAD(fd,packet_len_table[0x14e]);
	WFIFOW(fd,0)=0x14e;
	WFIFOL(fd,2)=type;
	WFIFOSET(fd,packet_len_table[0x14e]);
	return 0;
}
/*==========================================
 * Basic Info (Territories [Valaris])
 *------------------------------------------
 */
int clif_guild_basicinfo(struct map_session_data *sd)
{
	int fd,i,t=0;
	struct guild *g;
	struct guild_castle *gc=NULL;

	nullpo_retr(0, sd);

	fd=sd->fd;
	g=guild_search(sd->status.guild_id);
	if(g==NULL)
		return 0;

	WFIFOHEAD(fd,packet_len_table[0x1b6]);
	WFIFOW(fd, 0)=0x1b6;//0x150;
	WFIFOL(fd, 2)=g->guild_id;
	WFIFOL(fd, 6)=g->guild_lv;
	WFIFOL(fd,10)=g->connect_member;
	WFIFOL(fd,14)=g->max_member;
	WFIFOL(fd,18)=g->average_lv;
	WFIFOL(fd,22)=g->exp;
	WFIFOL(fd,26)=g->next_exp;
	WFIFOL(fd,30)=0;	// ��[
	WFIFOL(fd,34)=0;	// VW�i���i�̈����H�F�����O���t���E�j
	WFIFOL(fd,38)=0;	// RF�i���`�̓x�����H�F�����O���t�㉺�j
	WFIFOL(fd,42)=0;	// �l���H
	memcpy(WFIFOP(fd,46),g->name, NAME_LENGTH);
	memcpy(WFIFOP(fd,70),g->master, NAME_LENGTH);

	for(i=0;i<MAX_GUILDCASTLE;i++){
		gc=guild_castle_search(i);
		if(!gc) continue;
			if(g->guild_id == gc->guild_id)	t++;
	}
	if (t>=0 && t<=MAX_GUILDCASTLE) //(0=None, 1..24 = N of Casles) [Lupus]
		strncpy((char*)WFIFOP(fd,94),msg_txt(300+t),20);
	else
		strncpy((char*)WFIFOP(fd,94),msg_txt(299),20);

	WFIFOSET(fd,packet_len_table[WFIFOW(fd,0)]);
	clif_guild_emblem(sd,g);	// Guild emblem vanish fix [Valaris]
	return 0;
}

/*==========================================
 * �M���h����/�G�Ώ��
 *------------------------------------------
 */
int clif_guild_allianceinfo(struct map_session_data *sd)
{
	int fd,i,c;
	struct guild *g;

	nullpo_retr(0, sd);

	fd=sd->fd;
	g=guild_search(sd->status.guild_id);
	if(g==NULL)
		return 0;
	WFIFOHEAD(fd, MAX_GUILDALLIANCE * 32 + 4);
	WFIFOW(fd, 0)=0x14c;
	for(i=c=0;i<MAX_GUILDALLIANCE;i++){
		struct guild_alliance *a=&g->alliance[i];
		if(a->guild_id>0){
			WFIFOL(fd,c*32+4)=a->opposition;
			WFIFOL(fd,c*32+8)=a->guild_id;
			memcpy(WFIFOP(fd,c*32+12),a->name,NAME_LENGTH);
			c++;
		}
	}
	WFIFOW(fd, 2)=c*32+4;
	WFIFOSET(fd,WFIFOW(fd,2));
	return 0;
}

/*==========================================
 * �M���h�����o�[���X�g
 *------------------------------------------
 */
int clif_guild_memberlist(struct map_session_data *sd)
{
	int fd;
	int i,c;
	struct guild *g;

	nullpo_retr(0, sd);

	fd=sd->fd;
	if (!fd)
		return 0;
	g=guild_search(sd->status.guild_id);
	if(g==NULL)
		return 0;

	WFIFOHEAD(fd, g->max_member * 104 + 4);
	WFIFOW(fd, 0)=0x154;
	for(i=0,c=0;i<g->max_member;i++){
		struct guild_member *m=&g->member[i];
		if(m->account_id==0)
			continue;
		WFIFOL(fd,c*104+ 4)=m->account_id;
		WFIFOL(fd,c*104+ 8)=m->char_id;
		WFIFOW(fd,c*104+12)=m->hair;
		WFIFOW(fd,c*104+14)=m->hair_color;
		WFIFOW(fd,c*104+16)=m->gender;
		WFIFOW(fd,c*104+18)=m->class_;
		WFIFOW(fd,c*104+20)=m->lv;
		WFIFOL(fd,c*104+22)=m->exp;
		WFIFOL(fd,c*104+26)=m->online;
		WFIFOL(fd,c*104+30)=m->position;
		memset(WFIFOP(fd,c*104+34),0,50);	// �����H
		memcpy(WFIFOP(fd,c*104+84),m->name,NAME_LENGTH);
		c++;
	}
	WFIFOW(fd, 2)=c*104+4;
	WFIFOSET(fd,WFIFOW(fd,2));
	return 0;
}
/*==========================================
 * �M���h��E�����X�g
 *------------------------------------------
 */
int clif_guild_positionnamelist(struct map_session_data *sd)
{
	int i,fd;
	struct guild *g;

	nullpo_retr(0, sd);

	fd=sd->fd;
	g=guild_search(sd->status.guild_id);
	if(g==NULL)
		return 0;
	WFIFOHEAD(fd, MAX_GUILDPOSITION * 28 + 4);
	WFIFOW(fd, 0)=0x166;
	for(i=0;i<MAX_GUILDPOSITION;i++){
		WFIFOL(fd,i*28+4)=i;
		memcpy(WFIFOP(fd,i*28+8),g->position[i].name,NAME_LENGTH);
	}
	WFIFOW(fd,2)=i*28+4;
	WFIFOSET(fd,WFIFOW(fd,2));
	return 0;
}
/*==========================================
 * �M���h��E��񃊃X�g
 *------------------------------------------
 */
int clif_guild_positioninfolist(struct map_session_data *sd)
{
	int i,fd;
	struct guild *g;

	nullpo_retr(0, sd);

	fd=sd->fd;
	g=guild_search(sd->status.guild_id);
	if(g==NULL)
		return 0;
	WFIFOHEAD(fd, MAX_GUILDPOSITION * 16 + 4);
	WFIFOW(fd, 0)=0x160;
	for(i=0;i<MAX_GUILDPOSITION;i++){
		struct guild_position *p=&g->position[i];
		WFIFOL(fd,i*16+ 4)=i;
		WFIFOL(fd,i*16+ 8)=p->mode;
		WFIFOL(fd,i*16+12)=i;
		WFIFOL(fd,i*16+16)=p->exp_mode;
	}
	WFIFOW(fd, 2)=i*16+4;
	WFIFOSET(fd,WFIFOW(fd,2));
	return 0;
}
/*==========================================
 * �M���h��E�ύX�ʒm
 *------------------------------------------
 */
int clif_guild_positionchanged(struct guild *g,int idx)
{
	struct map_session_data *sd;
	unsigned char buf[128];

	nullpo_retr(0, g);

	WBUFW(buf, 0)=0x174;
	WBUFW(buf, 2)=44;
	WBUFL(buf, 4)=idx;
	WBUFL(buf, 8)=g->position[idx].mode;
	WBUFL(buf,12)=idx;
	WBUFL(buf,16)=g->position[idx].exp_mode;
	memcpy(WBUFP(buf,20),g->position[idx].name,NAME_LENGTH);
	if( (sd=guild_getavailablesd(g))!=NULL )
		clif_send(buf,WBUFW(buf,2),&sd->bl,GUILD);
	return 0;
}
/*==========================================
 * �M���h�����o�ύX�ʒm
 *------------------------------------------
 */
int clif_guild_memberpositionchanged(struct guild *g,int idx)
{
	struct map_session_data *sd;
	unsigned char buf[64];

	nullpo_retr(0, g);

	WBUFW(buf, 0)=0x156;
	WBUFW(buf, 2)=16;
	WBUFL(buf, 4)=g->member[idx].account_id;
	WBUFL(buf, 8)=g->member[idx].char_id;
	WBUFL(buf,12)=g->member[idx].position;
	if( (sd=guild_getavailablesd(g))!=NULL )
		clif_send(buf,WBUFW(buf,2),&sd->bl,GUILD);
	return 0;
}
/*==========================================
 * �M���h�G���u�������M
 *------------------------------------------
 */
int clif_guild_emblem(struct map_session_data *sd,struct guild *g)
{
	int fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, g);

	fd=sd->fd;

	if(g->emblem_len<=0)
		return 0;
	WFIFOHEAD(fd,g->emblem_len+12);
	WFIFOW(fd,0)=0x152;
	WFIFOW(fd,2)=g->emblem_len+12;
	WFIFOL(fd,4)=g->guild_id;
	WFIFOL(fd,8)=g->emblem_id;
	memcpy(WFIFOP(fd,12),g->emblem_data,g->emblem_len);
	WFIFOSET(fd,WFIFOW(fd,2));
	return 0;
}
/*==========================================
 * �M���h�X�L�����M
 *------------------------------------------
 */
int clif_guild_skillinfo(struct map_session_data *sd)
{
	int fd;
	int i,id,c,up=1;
	struct guild *g;

	nullpo_retr(0, sd);

	fd=sd->fd;
	g=guild_search(sd->status.guild_id);
	if(g==NULL)
		return 0;
	WFIFOHEAD(fd, MAX_GUILDSKILL * 37 + 6);
	WFIFOW(fd,0)=0x0162;
	WFIFOW(fd,4)=g->skill_point;
	for(i=c=0;i<MAX_GUILDSKILL;i++){
		if(g->skill[i].id>0 && guild_check_skill_require(g,g->skill[i].id)){
			WFIFOW(fd,c*37+ 6) = id = g->skill[i].id;
			WFIFOW(fd,c*37+ 8) = skill_get_inf(id);
			WFIFOW(fd,c*37+10) = 0;
			WFIFOW(fd,c*37+12) = g->skill[i].lv;
			WFIFOW(fd,c*37+14) = skill_get_sp(id,g->skill[i].lv);
			WFIFOW(fd,c*37+16) = skill_get_range(id,g->skill[i].lv);
			memset(WFIFOP(fd,c*37+18),0,24);
			if(g->skill[i].lv < guild_skill_get_max(id) && (sd == g->member[0].sd))
				up = 1;
			else
				up = 0;
			WFIFOB(fd,c*37+42)= up;
			c++;
		}
	}
	WFIFOW(fd,2)=c*37+6;
	WFIFOSET(fd,WFIFOW(fd,2));
	return 0;
}
/*==========================================
 * �M���h���m���M
 *------------------------------------------
 */
int clif_guild_notice(struct map_session_data *sd,struct guild *g)
{
	int fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, g);

	fd = sd->fd;

	if ( !session_isActive(fd) )  //null pointer right here [Kevin]
		return 0;
 
	if (fd <= 0)
		return 0;
	if(*g->mes1==0 && *g->mes2==0)
		return 0;
	WFIFOHEAD(fd,packet_len_table[0x16f]);
	WFIFOW(fd,0)=0x16f;
	memcpy(WFIFOP(fd,2),g->mes1,60);
	memcpy(WFIFOP(fd,62),g->mes2,120);
	WFIFOSET(fd,packet_len_table[0x16f]);
	return 0;
}

/*==========================================
 * �M���h�����o���U
 *------------------------------------------
 */
int clif_guild_invite(struct map_session_data *sd,struct guild *g)
{
	int fd;

	nullpo_retr(0, sd);
	nullpo_retr(0, g);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x16a]);
	WFIFOW(fd,0)=0x16a;
	WFIFOL(fd,2)=g->guild_id;
	memcpy(WFIFOP(fd,6),g->name,NAME_LENGTH);
	WFIFOSET(fd,packet_len_table[0x16a]);
	return 0;
}
/*==========================================
 * �M���h�����o���U����
 *------------------------------------------
 */
int clif_guild_inviteack(struct map_session_data *sd,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x169]);
	WFIFOW(fd,0)=0x169;
	WFIFOB(fd,2)=flag;
	WFIFOSET(fd,packet_len_table[0x169]);
	return 0;
}
/*==========================================
 * �M���h�����o�E�ޒʒm
 *------------------------------------------
 */
int clif_guild_leave(struct map_session_data *sd,const char *name,const char *mes)
{
	unsigned char buf[128];

	nullpo_retr(0, sd);

	WBUFW(buf, 0)=0x15a;
	memcpy(WBUFP(buf, 2),name,NAME_LENGTH);
	memcpy(WBUFP(buf,26),mes,40);
	clif_send(buf,packet_len_table[0x15a],&sd->bl,GUILD);
	return 0;
}
/*==========================================
 * �M���h�����o�Ǖ��ʒm
 *------------------------------------------
 */
int clif_guild_explusion(struct map_session_data *sd,const char *name,const char *mes,
	int account_id)
{
	unsigned char buf[128];

	nullpo_retr(0, sd);

	WBUFW(buf, 0)=0x15c;
	memcpy(WBUFP(buf, 2),name,NAME_LENGTH);
	memcpy(WBUFP(buf,26),mes,40);
	memcpy(WBUFP(buf,66),"dummy",NAME_LENGTH);
	clif_send(buf,packet_len_table[0x15c],&sd->bl,GUILD);
	return 0;
}
/*==========================================
 * �M���h�Ǖ������o���X�g
 *------------------------------------------
 */
int clif_guild_explusionlist(struct map_session_data *sd)
{
	int fd;
	int i,c;
	struct guild *g;

	nullpo_retr(0, sd);

	fd=sd->fd;
	g=guild_search(sd->status.guild_id);
	if(g==NULL)
		return 0;
	WFIFOHEAD(fd,MAX_GUILDEXPLUSION * 88 + 4);
	WFIFOW(fd,0)=0x163;
	for(i=c=0;i<MAX_GUILDEXPLUSION;i++){
		struct guild_explusion *e=&g->explusion[i];
		if(e->account_id>0){
			memcpy(WFIFOP(fd,c*88+ 4),e->name,NAME_LENGTH);
			memcpy(WFIFOP(fd,c*88+28),e->acc,24);
			memcpy(WFIFOP(fd,c*88+52),e->mes,44);
			c++;
		}
	}
	WFIFOW(fd,2)=c*88+4;
	WFIFOSET(fd,WFIFOW(fd,2));
	return 0;
}

/*==========================================
 * �M���h��b
 *------------------------------------------
 */
int clif_guild_message(struct guild *g,int account_id,const char *mes,int len)
{
	struct map_session_data *sd;
	unsigned char *buf;

	buf = (unsigned char*)aCallocA(len + 4, sizeof(unsigned char));

	WBUFW(buf, 0) = 0x17f;
	WBUFW(buf, 2) = len + 4;
	memcpy(WBUFP(buf,4), mes, len);

	if ((sd = guild_getavailablesd(g)) != NULL)
		clif_send(buf, WBUFW(buf,2), &sd->bl, GUILD);

	if(buf) aFree(buf);

	return 0;
}
/*==========================================
 * �M���h�X�L������U��ʒm
 *------------------------------------------
 */
int clif_guild_skillup(struct map_session_data *sd,int skill_num,int lv)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,11);
	WFIFOW(fd,0) = 0x10e;
	WFIFOW(fd,2) = skill_num;
	WFIFOW(fd,4) = lv;
	WFIFOW(fd,6) = skill_get_sp(skill_num,lv);
	WFIFOW(fd,8) = skill_get_range(skill_num,lv);
	WFIFOB(fd,10) = 1;
	WFIFOSET(fd,11);
	return 0;
}
/*==========================================
 * �M���h�����v��
 *------------------------------------------
 */
int clif_guild_reqalliance(struct map_session_data *sd,int account_id,const char *name)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x171]);
	WFIFOW(fd,0)=0x171;
	WFIFOL(fd,2)=account_id;
	memcpy(WFIFOP(fd,6),name,NAME_LENGTH);
	WFIFOSET(fd,packet_len_table[0x171]);
	return 0;
}
/*==========================================
 * �M���h��������
 *------------------------------------------
 */
int clif_guild_allianceack(struct map_session_data *sd,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x173]);
	WFIFOW(fd,0)=0x173;
	WFIFOL(fd,2)=flag;
	WFIFOSET(fd,packet_len_table[0x173]);
	return 0;
}
/*==========================================
 * �M���h�֌W�����ʒm
 *------------------------------------------
 */
int clif_guild_delalliance(struct map_session_data *sd,int guild_id,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd = sd->fd;
	if (fd <= 0)
		return 0;
	WFIFOHEAD(fd,packet_len_table[0x184]);
	WFIFOW(fd,0)=0x184;
	WFIFOL(fd,2)=guild_id;
	WFIFOL(fd,6)=flag;
	WFIFOSET(fd,packet_len_table[0x184]);
	return 0;
}
/*==========================================
 * �M���h�G�Ό���
 *------------------------------------------
 */
int clif_guild_oppositionack(struct map_session_data *sd,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x181]);
	WFIFOW(fd,0)=0x181;
	WFIFOB(fd,2)=flag;
	WFIFOSET(fd,packet_len_table[0x181]);
	return 0;
}
/*==========================================
 * �M���h�֌W�lj�
 *------------------------------------------
 */
/*int clif_guild_allianceadded(struct guild *g,int idx)
{
	unsigned char buf[64];
	WBUFW(fd,0)=0x185;
	WBUFL(fd,2)=g->alliance[idx].opposition;
	WBUFL(fd,6)=g->alliance[idx].guild_id;
	memcpy(WBUFP(fd,10),g->alliance[idx].name,NAME_LENGTH);
	clif_send(buf,packet_len_table[0x185],guild_getavailablesd(g),GUILD);
	return 0;
}*/

/*==========================================
 * �M���h���U�ʒm
 *------------------------------------------
 */
int clif_guild_broken(struct map_session_data *sd,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x15e]);
	WFIFOW(fd,0)=0x15e;
	WFIFOL(fd,2)=flag;
	WFIFOSET(fd,packet_len_table[0x15e]);
	return 0;
}

/*==========================================
 * �G���[�V����
 *------------------------------------------
 */
void clif_emotion(struct block_list *bl,int type)
{
	unsigned char buf[8];

	nullpo_retv(bl);

	WBUFW(buf,0)=0xc0;
	WBUFL(buf,2)=bl->id;
	WBUFB(buf,6)=type;
	clif_send(buf,packet_len_table[0xc0],bl,AREA);
}

/*==========================================
 * �g�[�L�[�{�b�N�X
 *------------------------------------------
 */
void clif_talkiebox(struct block_list *bl,char* talkie)
{
	unsigned char buf[86];

	nullpo_retv(bl);

	WBUFW(buf,0)=0x191;
	WBUFL(buf,2)=bl->id;
	memcpy(WBUFP(buf,6),talkie,MESSAGE_SIZE);
	clif_send(buf,packet_len_table[0x191],bl,AREA);
}

/*==========================================
 * �����G�t�F�N�g
 *------------------------------------------
 */
void clif_wedding_effect(struct block_list *bl) {
	unsigned char buf[6];

	nullpo_retv(bl);

	WBUFW(buf,0) = 0x1ea;
	WBUFL(buf,2) = bl->id;
	clif_send(buf, packet_len_table[0x1ea], bl, AREA);
}
/*==========================================
 * ���Ȃ��Ɉ��������g�p�����O����
 *------------------------------------------

void clif_callpartner(struct map_session_data *sd)
{
	unsigned char buf[26];
	char *p;

	nullpo_retv(sd);

	if(sd->status.partner_id){
		WBUFW(buf,0)=0x1e6;
		p = map_charid2nick(sd->status.partner_id);
		if(p){
			memcpy(WBUFP(buf,2),p,NAME_LENGTH);
		}else{
			map_reqchariddb(sd,sd->status.partner_id);
			chrif_searchcharid(sd->status.partner_id);
			WBUFB(buf,2) = 0;
		}
		clif_send(buf,packet_len_table[0x1e6],&sd->bl,AREA);
	}
	return;
}
*/
/*==========================================
 * Adopt baby [Celest]
 *------------------------------------------
 */
void clif_adopt_process(struct map_session_data *sd)
{
	int fd;
	nullpo_retv(sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x1f8]);
	WFIFOW(fd,0)=0x1f8;
	WFIFOSET(fd,packet_len_table[0x1f8]);
}
/*==========================================
 * Marry [DracoRPG]
 *------------------------------------------
 */
void clif_marriage_process(struct map_session_data *sd)
{
	int fd;
	nullpo_retv(sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x1e4]);
	WFIFOW(fd,0)=0x1e4;
	WFIFOSET(fd,packet_len_table[0x1e4]);
}


/*==========================================
 * Notice of divorce
 *------------------------------------------
 */
void clif_divorced(struct map_session_data *sd, char *name)
{
	int fd;
	nullpo_retv(sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x205]);
	WFIFOW(fd,0)=0x205;
	memcpy(WFIFOP(fd,2), name, NAME_LENGTH);
	WFIFOSET(fd, packet_len_table[0x205]);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_ReqAdopt(int fd, struct map_session_data *sd) {
	nullpo_retv(sd);

	WFIFOHEAD(fd,packet_len_table[0x1f6]);
	WFIFOW(fd,0)=0x1f6;
	WFIFOSET(fd, packet_len_table[0x1f6]);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_ReqMarriage(int fd, struct map_session_data *sd) {
	nullpo_retv(sd);

	WFIFOHEAD(fd,packet_len_table[0x1e2]);
	WFIFOW(fd,0)=0x1e2;
	WFIFOSET(fd, packet_len_table[0x1e2]);
}

/*==========================================
 * ����
 *------------------------------------------
 */
void clif_sitting(struct map_session_data *sd)
{
	unsigned char buf[64];

	nullpo_retv(sd);

	WBUFW(buf, 0) = 0x8a;
	WBUFL(buf, 2) = sd->bl.id;
	WBUFB(buf,26) = 2;
	clif_send(buf, packet_len_table[0x8a], &sd->bl, AREA);
}

/*==========================================
 *
 *------------------------------------------
 */
int clif_disp_onlyself(struct map_session_data *sd, char *mes, int len)
{
	unsigned char *buf;

	nullpo_retr(0, sd);

	buf = (unsigned char*)aCallocA(len + 5, sizeof(unsigned char));

	WBUFW(buf, 0) = 0x17f;
	WBUFW(buf, 2) = len + 5;
	memcpy(WBUFP(buf,4), mes, len);

	clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);

	if(buf) aFree(buf);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */

int clif_GM_kickack(struct map_session_data *sd, int id)
{
	int fd;

	nullpo_retr(0, sd);

	fd = sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xcd]);
	WFIFOW(fd,0) = 0xcd;
	WFIFOL(fd,2) = id;
	WFIFOSET(fd, packet_len_table[0xcd]);
	return 0;
}

void clif_parse_QuitGame(int fd,struct map_session_data *sd);

int clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd,int type)
{
	nullpo_retr(0, tsd);

	if(type)
		clif_GM_kickack(sd,tsd->status.account_id);
	WFIFOHEAD(tsd->fd,packet_len_table[0x18b]);
	WFIFOW(tsd->fd,0) = 0x18b;
	WFIFOW(tsd->fd,2) = 0;
	WFIFOSET(tsd->fd,packet_len_table[0x18b]);

	if (tsd->fd)
	{
		ShowDebug("clif_GM_kick: Disconnecting session #%d\n", tsd->fd);
		clif_setwaitclose(tsd->fd);
	} else { //Player has no session attached, delete it right away. [Skotlex]
		map_quit(tsd);
	}

	return 0;
}

int clif_GM_silence(struct map_session_data *sd, struct map_session_data *tsd, int type)
{
	int fd;
	
	nullpo_retr(0, sd);
	nullpo_retr(0, tsd);

	fd = tsd->fd;
	if (fd <= 0)
		return 0;
	WFIFOHEAD(fd,packet_len_table[0x14b]);
	WFIFOW(fd,0) = 0x14b;
	WFIFOB(fd,2) = 0;
	memcpy(WFIFOP(fd,3), sd->status.name, NAME_LENGTH);
	WFIFOSET(fd, packet_len_table[0x14b]);

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */

int clif_timedout(struct map_session_data *sd)
{
	nullpo_retr(0, sd);

	ShowInfo("%sCharacter with Account ID '"CL_WHITE"%d"CL_RESET"' timed out.\n", (pc_isGM(sd))?"GM ":"", sd->bl.id);
	clif_authfail_fd(sd->fd,3); // Even if player is not on we still send anyway
	clif_setwaitclose(sd->fd); // Set session to EOF
	return 0;
}

/*==========================================
 * Wis���ۋ��‰���
 *------------------------------------------
 */
int clif_wisexin(struct map_session_data *sd,int type,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xd1]);
	WFIFOW(fd,0)=0xd1;
	WFIFOB(fd,2)=type;
	WFIFOB(fd,3)=flag;
	WFIFOSET(fd,packet_len_table[0xd1]);

	return 0;
}
/*==========================================
 * Wis�S���ۋ��‰���
 *------------------------------------------
 */
int clif_wisall(struct map_session_data *sd,int type,int flag)
{
	int fd;

	nullpo_retr(0, sd);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0xd2]);
	WFIFOW(fd,0)=0xd2;
	WFIFOB(fd,2)=type;
	WFIFOB(fd,3)=flag;
	WFIFOSET(fd,packet_len_table[0xd2]);

	return 0;
}
/*==========================================
 * �T�E���h�G�t�F�N�g
 *------------------------------------------
 */
void clif_soundeffect(struct map_session_data *sd,struct block_list *bl,char *name,int type)
{
	int fd;

	nullpo_retv(sd);
	nullpo_retv(bl);

	fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x1d3]);
	WFIFOW(fd,0)=0x1d3;
	memcpy(WFIFOP(fd,2),name,NAME_LENGTH);
	WFIFOB(fd,26)=type;
	WFIFOL(fd,27)=0;
	WFIFOL(fd,31)=bl->id;
	WFIFOSET(fd,packet_len_table[0x1d3]);

	return;
}

int clif_soundeffectall(struct block_list *bl, char *name, int type, int coverage)
{
	unsigned char buf[40];
	memset(buf, 0, packet_len_table[0x1d3]);

	if(coverage < 0 || coverage > 22){
		ShowError("clif_soundeffectall: undefined coverage.\n");
		return 0;
	}

	nullpo_retr(0, bl);

	WBUFW(buf,0)=0x1d3;
	memcpy(WBUFP(buf,2), name, NAME_LENGTH);
	WBUFB(buf,26)=type;
	WBUFL(buf,27)=0;
	WBUFL(buf,31)=bl->id;
	clif_send(buf, packet_len_table[0x1d3], bl, coverage);

	return 0;
}

// displaying special effects (npcs, weather, etc) [Valaris]
int clif_specialeffect(struct block_list *bl, int type, int flag)
{
	unsigned char buf[24];

	nullpo_retr(0, bl);

	memset(buf, 0, packet_len_table[0x1f3]);

	WBUFW(buf,0) = 0x1f3;
	WBUFL(buf,2) = bl->id;
	WBUFL(buf,6) = type;

	switch (flag) {
	case 4:
		clif_send(buf, packet_len_table[0x1f3], bl, AREA_WOS);
		break;
	case 3:
		clif_send(buf, packet_len_table[0x1f3], bl, ALL_CLIENT);
		break;
	case 2:
		clif_send(buf, packet_len_table[0x1f3], bl, ALL_SAMEMAP);
		break;
	case 1:
		clif_send(buf, packet_len_table[0x1f3], bl, SELF);
		break;
	default:
		clif_send(buf, packet_len_table[0x1f3], bl, AREA);
	}
	if (disguised(bl)) {
		WBUFL(buf,2) = -bl->id;
		clif_send(buf, packet_len_table[0x1f3], bl, SELF);
	}
	return 0;
}

// refresh the client's screen, getting rid of any effects
int clif_refresh(struct map_session_data *sd) {
	nullpo_retr(-1, sd);
	clif_changemap(sd,sd->mapindex,sd->bl.x,sd->bl.y);
	map_foreachinarea(clif_getareachar,sd->bl.m,sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,BL_ALL,sd);
	return 0;
}

// updates the object's (bl) name on client
int clif_charnameack (int fd, struct block_list *bl)
{
	unsigned char buf[103];
	int cmd = 0x95;

	nullpo_retr(0, bl);

	WBUFW(buf,0) = cmd;
	WBUFL(buf,2) = bl->id;

	switch(bl->type) {
	case BL_PC:
		{
			struct map_session_data *ssd = (struct map_session_data *)bl;
			struct party *p = NULL;
			struct guild *g = NULL;
			
			nullpo_retr(0, ssd);

			if (strlen(ssd->fakename)>1) {
				memcpy(WBUFP(buf,6), ssd->fakename, NAME_LENGTH);
				break;
			}
			memcpy(WBUFP(buf,6), ssd->status.name, NAME_LENGTH);
			
			if (ssd->status.party_id > 0)
				p = party_search(ssd->status.party_id);

			if (ssd->status.guild_id > 0)
				g = guild_search(ssd->status.guild_id);

			if (p == NULL && g == NULL)
				break;
			
			WBUFW(buf, 0) = cmd = 0x195;
			if (p)
				memcpy(WBUFP(buf,30), p->name, NAME_LENGTH);
			else
				WBUFB(buf,30) = 0;
			
			if (g)
			{
				int i, ps = -1;
				for(i = 0; i < g->max_member; i++) {
					if (g->member[i].account_id == ssd->status.account_id &&
						g->member[i].char_id == ssd->status.char_id )
						{
							ps = g->member[i].position;
							break;
						}
					}
				if (ps >= 0 && ps < MAX_GUILDPOSITION)
				{
					memcpy(WBUFP(buf,54), g->name,NAME_LENGTH);
					memcpy(WBUFP(buf,78), g->position[ps].name, NAME_LENGTH);
				} else { //Assume no guild.
					WBUFB(buf,54) = 0;
					WBUFB(buf,78) = 0;
				}
			} else {
				WBUFB(buf,54) = 0;
				WBUFB(buf,78) = 0;
			}
		}
		break;
	case BL_PET:
		memcpy(WBUFP(buf,6), ((struct pet_data*)bl)->name, NAME_LENGTH);
		break;
	case BL_NPC:
		memcpy(WBUFP(buf,6), ((struct npc_data*)bl)->name, NAME_LENGTH);
		break;
	case BL_MOB:
		{
			struct mob_data *md = (struct mob_data *)bl;
			nullpo_retr(0, md);

			memcpy(WBUFP(buf,6), md->name, NAME_LENGTH);
			if (md->guardian_data && md->guardian_data->guild_id) {
				WBUFW(buf, 0) = cmd = 0x195;
				WBUFB(buf,30) = 0;
				memcpy(WBUFP(buf,54), md->guardian_data->guild_name, NAME_LENGTH);
				memcpy(WBUFP(buf,78), md->guardian_data->castle->castle_name, NAME_LENGTH);
			} else if (battle_config.show_mob_hp == 1) {
				char mobhp[50];
				WBUFW(buf, 0) = cmd = 0x195;
				sprintf(mobhp, "HP: %d/%d", md->hp, md->max_hp);
				//Even thought mobhp ain't a name, we send it as one so the client
				//can parse it. [Skotlex]
				memcpy(WBUFP(buf,30), mobhp, NAME_LENGTH);
				WBUFB(buf,54) = 0;
				memcpy(WBUFP(buf,78), mobhp, NAME_LENGTH);
			}
		}
		break;
	case BL_CHAT:	//FIXME: Clients DO request this... what should be done about it? The chat's title may not fit... [Skotlex]
//		memcpy(WBUFP(buf,6), (struct chat*)->title, NAME_LENGTH);
//		break;
		return 0;
	default:
		if (battle_config.error_log)
			ShowError("clif_parse_GetCharNameRequest : bad type %d(%d)\n", bl->type, bl->id);
		return 0;
	}

	// if no receipient specified just update nearby clients
	if (fd == 0)
		clif_send(buf, packet_len_table[cmd], bl, AREA);
	else {
		WFIFOHEAD(fd, packet_len_table[cmd]);
		memcpy(WFIFOP(fd, 0), buf, packet_len_table[cmd]);
		WFIFOSET(fd, packet_len_table[cmd]);
	}

	return 0;
}

//Used to update when a char leaves a party/guild. [Skotlex]
//Needed because when you send a 0x95 packet, the client will not remove the cached party/guild info that is not sent.
int clif_charnameupdate (struct map_session_data *ssd)
{
	unsigned char buf[103];
	int cmd = 0x195;
	struct party *p = NULL;
	struct guild *g = NULL;

	nullpo_retr(0, ssd);

	if (strlen(ssd->fakename)>1)
		return 0; //No need to update as the party/guild was not displayed anyway.

	WBUFW(buf,0) = cmd;
	WBUFL(buf,2) = ssd->bl.id;

	memcpy(WBUFP(buf,6), ssd->status.name, NAME_LENGTH);
			
	if (ssd->status.party_id > 0)
		p = party_search(ssd->status.party_id);

	if (ssd->status.guild_id > 0)
		g = guild_search(ssd->status.guild_id);

	if (p)
		memcpy(WBUFP(buf,30), p->name, NAME_LENGTH);
	else
		WBUFB(buf,30) = 0;
			
	if (g)
	{
		int i, ps = -1;
		for(i = 0; i < g->max_member; i++) {
			if (g->member[i].account_id == ssd->status.account_id &&
				g->member[i].char_id == ssd->status.char_id )
				{
					ps = g->member[i].position;
					break;
				}
			}
		if (ps >= 0 && ps < MAX_GUILDPOSITION)
		{
			memcpy(WBUFP(buf,54), g->name,NAME_LENGTH);
			memcpy(WBUFP(buf,78), g->position[ps].name, NAME_LENGTH);
		} else { //Assume no guild.
			WBUFB(buf,54) = 0;
			WBUFB(buf,78) = 0;
		}
	} else {
		WBUFB(buf,54) = 0;
		WBUFB(buf,78) = 0;
	}

	// Update nearby clients
	clif_send(buf, packet_len_table[cmd], &ssd->bl, AREA);
	return 0;
}

int clif_slide(struct block_list *bl, int x, int y){
	unsigned char buf[10];

	nullpo_retr(0, bl);

	WBUFW(buf, 0) = 0x01ff;
	WBUFL(buf, 2) = bl->id;
	WBUFW(buf, 6) = x;
	WBUFW(buf, 8) = y;

	clif_send(buf, packet_len_table[0x1ff], bl, AREA);
	return 0;
}

/*------------------------------------------
 * @me command by lordalfa, rewritten implementation by Skotlex
 *------------------------------------------
*/
int clif_disp_overhead(struct map_session_data *sd, char* mes)
{
	unsigned char buf[256]; //This should be more than sufficient, the theorical max is MESSAGE_SIZE+NAME_LENGTH + 8 (pads and extra inserted crap)
	int len_mes = strlen(mes)+1; //Account for \0

	if (len_mes + 8 >= 256) {
		if (battle_config.error_log)
			ShowError("clif_disp_overhead: Message too long (length %d)\n", len_mes);
		len_mes = 247; //Trunk it to avoid problems.
	}
	// send message to others
	WBUFW(buf,0) = 0x8d;
	WBUFW(buf,2) = len_mes + 8; // len of message + 8 (command+len+id)
	WBUFL(buf,4) = sd->bl.id;
	memcpy(WBUFP(buf,8), mes, len_mes);
	clif_send(buf, WBUFW(buf,2), &sd->bl, AREA_CHAT_WOC);

	// send back message to the speaker
	WBUFW(buf,0) = 0x8e;
	WBUFW(buf, 2) = len_mes + 4;
	memcpy(WBUFP(buf,4), mes, len_mes);  
	clif_send(buf, WBUFW(buf,2), &sd->bl, SELF);

	return 0;
}

/*==========================
 * Minimap fix [Kevin]
 * Remove dot from minimap 
 *--------------------------
*/
int clif_party_xy_remove(struct map_session_data *sd)
{
	unsigned char buf[16];
	nullpo_retr(0, sd);
	WBUFW(buf,0)=0x107;
	WBUFL(buf,2)=sd->status.account_id;
	WBUFW(buf,6)=-1;
	WBUFW(buf,8)=-1;
	clif_send(buf,packet_len_table[0x107],&sd->bl,PARTY_SAMEMAP_WOS);
	return 0;
}

/*==========================================
 * Info about Star Glaldiator save map [Komurka]
 *------------------------------------------
 */
void clif_feel_info(struct map_session_data *sd, int feel_level)
{
	int fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x20e]);
	WFIFOW(fd,0)=0x20e;
	memcpy(WFIFOP(fd,2),mapindex_id2name(sd->feel_map[feel_level].index), MAP_NAME_LENGTH);
	WFIFOL(fd,26)=sd->bl.id;
	WFIFOW(fd,30)=0x100+feel_level;
	WFIFOSET(fd, packet_len_table[0x20e]);
}

/*==========================================
 * Info about Star Glaldiator hate mob [Komurka]
 *------------------------------------------
 */
void clif_hate_mob(struct map_session_data *sd, int skilllv,int mob_id)
{
	int fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x20e]);
	WFIFOW(fd,0)=0x20e;
	if (pcdb_checkid(mob_id))
		strncpy(WFIFOP(fd,2),job_name(mob_id), NAME_LENGTH);
	else if (mobdb_checkid(mob_id))
		strncpy(WFIFOP(fd,2),mob_db(mob_id)->jname, NAME_LENGTH);
	else //Really shouldn't happen...
		memset(WFIFOP(fd,2), 0, NAME_LENGTH);
	WFIFOL(fd,26)=sd->bl.id;
	WFIFOW(fd,30)=0xa00+skilllv-1;
	WFIFOSET(fd, packet_len_table[0x20e]);
}

/*==========================================
 * Info about TaeKwon Do TK_MISSION mob [Skotlex]
 *------------------------------------------
 */
void clif_mission_mob(struct map_session_data *sd, unsigned short mob_id, unsigned short progress)
{
	int fd=sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x20e]);
	WFIFOW(fd,0)=0x20e;
	strncpy(WFIFOP(fd,2),mob_db(mob_id)->jname, NAME_LENGTH);
	WFIFOL(fd,26)=mob_id;
	WFIFOW(fd,30)=0x1400+progress; //Message to display
	WFIFOSET(fd, packet_len_table[0x20e]);
}

// ---------------------
// clif_guess_PacketVer
// ---------------------
// Parses a WantToConnection packet to try to identify which is the packet version used. [Skotlex]
static int clif_guess_PacketVer(int fd, int get_previous)
{
	static int packet_ver = -1;
	int cmd, packet_len, value; //Value is used to temporarily store account/char_id/sex
	RFIFOHEAD(fd);
	
	if (get_previous) //For quick reruns, since the normal code flow is to fetch this once to identify the packet version, then again in the wanttoconnect function. [Skotlex]
		return packet_ver;

	//By default, start searching on the default one. 
	packet_ver = clif_config.packet_db_ver;
	cmd = RFIFOW(fd,0);
	packet_len = RFIFOREST(fd);
	
	if (
		cmd == clif_config.connect_cmd[packet_ver] &&
		packet_len == packet_db[packet_ver][cmd].len &&
		((value = RFIFOB(fd, packet_db[packet_ver][cmd].pos[4])) == 0 ||	value == 1) &&
		(value = RFIFOL(fd, packet_db[packet_ver][cmd].pos[0])) > 700000 && //Account ID is valid
		 value <= max_account_id &&
		(value = RFIFOL(fd, packet_db[packet_ver][cmd].pos[1])) > 0 &&	//Char ID is valid
		 value <= max_char_id &&
		(int)RFIFOL(fd, packet_db[packet_ver][cmd].pos[2]) > 0	//Login 1 is a positive value (?)
		)
		return clif_config.packet_db_ver; //Default packet version found.
	
	for (packet_ver = MAX_PACKET_VER; packet_ver > 0; packet_ver--)
	{	//Start guessing the version, giving priority to the newer ones. [Skotlex]
		if (cmd != clif_config.connect_cmd[packet_ver] ||	//it is not a wanttoconnection for this version.
			packet_len != packet_db[packet_ver][cmd].len)	//The size of the wantoconnection packet does not matches.
			continue;
	
		if (
			(value = RFIFOL(fd, packet_db[packet_ver][cmd].pos[0])) < 700000 || value > max_account_id
			|| (value = RFIFOL(fd, packet_db[packet_ver][cmd].pos[1])) < 1 || value > max_char_id
			//What is login 1? In my tests it is a very very high value.
			|| (int)RFIFOL(fd, packet_db[packet_ver][cmd].pos[2]) < 1
			//This check seems redundant, all wanttoconnection packets have the gender on the very 
			//last byte of the packet.
			|| (value = RFIFOB(fd, packet_db[packet_ver][cmd].pos[4])) < 0 || value > 1
		)
			continue;
		
		return packet_ver; //This is our best guess.
	}
	packet_ver = -1;
	return -1;
}

// ------------
// clif_parse_*
// ------------
// �p�P�b�g�ǂݎ���ĐF�X����
/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
{
	struct map_session_data *old_sd;
	int cmd, account_id, char_id, login_id1, sex;
	unsigned int client_tick; //The client tick is a tick, therefore it needs be unsigned. [Skotlex]
	int packet_ver;	// 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 (by [Yor])
	RFIFOHEAD(fd);

	if (sd) {
		if (battle_config.error_log)
			ShowError("clif_parse_WantToConnection : invalid request (character already logged in)?\n");
		return;
	}

	packet_ver = clif_guess_PacketVer(fd, 1);
	cmd = RFIFOW(fd,0);
	
	if (packet_ver > 0)
	{
		account_id	= RFIFOL(fd, packet_db[packet_ver][cmd].pos[0]);
		char_id		= RFIFOL(fd, packet_db[packet_ver][cmd].pos[1]);
		login_id1	= RFIFOL(fd, packet_db[packet_ver][cmd].pos[2]);
		client_tick	= RFIFOL(fd, packet_db[packet_ver][cmd].pos[3]);
		sex			= RFIFOB(fd, packet_db[packet_ver][cmd].pos[4]);
			
		if ((old_sd = map_id2sd(account_id)) != NULL)
		{	// if same account already connected, we disconnect the 2 sessions
			//Check for characters with no connection (includes those that are using autotrade) [durf],[Skotlex]
			if (!old_sd->fd)
				map_quit(old_sd);
			else 
				clif_authfail_fd(old_sd->fd, 2); // same id
			clif_authfail_fd(fd, 8); // still recognizes last connection
		} else {
			sd = (struct map_session_data*)aCalloc(1, sizeof(struct map_session_data));

			sd->fd = fd;
			sd->packet_ver = packet_ver;
			session[fd]->session_data = sd;

			pc_setnewpc(sd, account_id, char_id, login_id1, client_tick, sex, fd);
			WFIFOHEAD(fd,4);
			WFIFOL(fd,0) = sd->bl.id;
			WFIFOSET(fd,4);

			chrif_authreq(sd);
		}
	}
	return;
}

static int clif_nighttimer(int tid, unsigned int tick, int id, int data)
{
	TBL_PC *sd;
	sd=map_id2sd(id);
	if (!sd) return 0;

	//Check if character didn't instant-warped after logging in.
	if (sd->bl.prev!=NULL) {
		sd->state.night = 1;
 		clif_status_load(&sd->bl, SI_NIGHT, 1);
	}
	return 0;
}

/*==========================================
 * 007d �N���C�A���g���}�b�v�ǂݍ��݊���
 * map�N�����ɕK�v�ȃf�[�^��S�đ���‚���
 *------------------------------------------
 */
void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
{
	int i;
	
	if(sd->bl.prev != NULL)
		return;

	if(sd->npc_id) npc_event_dequeue(sd);
	clif_skillinfoblock(sd);
	pc_checkitem(sd);

	// loadendack��
	// next exp
	clif_updatestatus(sd,SP_NEXTBASEEXP);
	clif_updatestatus(sd,SP_NEXTJOBEXP);
	// skill point
	clif_updatestatus(sd,SP_SKILLPOINT);
	// item
	clif_itemlist(sd);
	clif_equiplist(sd);
	// cart
	if(pc_iscarton(sd)){
		clif_cart_itemlist(sd);
		clif_cart_equiplist(sd);
		clif_updatestatus(sd,SP_CARTINFO);
	}
	// param all
	clif_initialstatus(sd);
	if(battle_config.pc_invincible_time > 0) {
		if(map_flag_gvg(sd->bl.m))
			pc_setinvincibletimer(sd,battle_config.pc_invincible_time<<1);
		else
			pc_setinvincibletimer(sd,battle_config.pc_invincible_time);
	}

	map_addblock(&sd->bl);	// �u���b�N�o�^
	clif_spawn(&sd->bl);	// spawn

	// party
	party_send_movemap(sd);
	// guild
	guild_send_memberinfoshort(sd,1);

	// weight max , now
	clif_updatestatus(sd,SP_MAXWEIGHT);
	clif_updatestatus(sd,SP_WEIGHT);

	// Show hp after displacement [LuzZza]
	if(sd->status.party_id)
	    clif_party_hp(sd);

	//[LuzZza]
	clif_guild_send_onlineinfo(sd);

	// pvp
	//if(sd->pvp_timer!=-1 && !battle_config.pk_mode) /PVP Client crash fix* Removed timer deletion
	//	delete_timer(sd->pvp_timer,pc_calc_pvprank_timer);
	if(map[sd->bl.m].flag.pvp){
		if(!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris]
			if (sd->pvp_timer == -1)
				sd->pvp_timer=add_timer(gettick()+200,pc_calc_pvprank_timer,sd->bl.id,0);
			sd->pvp_rank=0;
			sd->pvp_lastusers=0;
			sd->pvp_point=5;
			sd->pvp_won=0;
			sd->pvp_lost=0;
		}
		clif_set0199(fd,1);
	} else {
		sd->pvp_timer=-1;
		// set flag, if it's a duel [LuzZza]
		if(sd->duel_group)
			clif_set0199(fd, 1);
	}
	if(map_flag_gvg(sd->bl.m))
		clif_set0199(fd,3);

	// pet
	if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 0) {
		map_addblock(&sd->pd->bl);
		clif_spawn(&sd->pd->bl);
		clif_send_petdata(sd,0,0);
		clif_send_petdata(sd,5,battle_config.pet_hair_style);
		clif_send_petstatus(sd);
	}

	if(sd->state.connect_new) {
		sd->state.connect_new = 0;
		//Delayed night effect on log-on fix for the glow-issue. Thanks to Larry.
		if (night_flag && map[sd->bl.m].flag.nightenabled)
			add_timer(gettick()+1000,clif_nighttimer,sd->bl.id,0);

//		if(sd->status.class_ != sd->vd.class_)
//			clif_changelook(&sd->bl,LOOK_BASE,sd->vd.class_);
		if(sd->status.pet_id > 0 && sd->pd && sd->pet.intimate > 900)
			clif_pet_emotion(sd->pd,(sd->pd->class_ - 100)*100 + 50 + pet_hungry_val(sd));

/*						Stop players from spawning inside castles [Valaris]					*/
		{
			struct guild_castle *gc=guild_mapname2gc(map[sd->bl.m].name);
			if (gc)
				pc_setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,2);
			}
	} else
	//New 'night' effect by dynamix [Skotlex]
	if (night_flag && map[sd->bl.m].flag.nightenabled)
	{	//Display night.
		if (sd->state.night) //It must be resent because otherwise players get this annoying aura...
			clif_status_load(&sd->bl, SI_NIGHT, 0);
		else
			sd->state.night = 1;
		clif_status_load(&sd->bl, SI_NIGHT, 1);
	} else if (sd->state.night) { //Clear night display.
		sd->state.night = 0;
		clif_status_load(&sd->bl, SI_NIGHT, 0);
	}

	// view equipment item
#if PACKETVER < 4
	clif_changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon);
	clif_changelook(&sd->bl,LOOK_SHIELD,sd->status.shield);
#else
	clif_changelook(&sd->bl,LOOK_WEAPON,0);
#endif

	if(sd->vd.cloth_color)
		clif_refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);

	if(battle_config.muting_players && sd->status.manner < 0 && battle_config.manner_system)
		sc_start(&sd->bl,SC_NOCHAT,100,0,0);

// Lance
	if (script_config.event_script_type == 0) {
		struct npc_data *npc;
		if ((npc = npc_name2id(script_config.loadmap_event_name))) {  
			run_script(npc->u.scr.script,0,sd->bl.id,npc->bl.id);
			ShowStatus("Event '"CL_WHITE"%s"CL_RESET"' executed.\n", script_config.loadmap_event_name);
		}
	} else {
		ShowStatus("%d '"CL_WHITE"%s"CL_RESET"' events executed.\n",
			npc_event_doall_id(script_config.loadmap_event_name, sd->bl.id), script_config.loadmap_event_name);
	}
	if ((i = pc_checkskill(sd,SG_KNOWLEDGE)) > 0) {
		if(sd->bl.m == sd->feel_map[0].m
			|| sd->bl.m == sd->feel_map[1].m
			|| sd->bl.m == sd->feel_map[2].m)
			sc_start(&sd->bl, SC_KNOWLEDGE, 100, i, skill_get_time(SG_KNOWLEDGE, i));
	}

	if (
	    pc_checkskill(sd,SG_SUN_COMFORT)  ||
	    pc_checkskill(sd,SG_MOON_COMFORT) ||
	    pc_checkskill(sd,SG_STAR_COMFORT))
		status_calc_pc(sd,0);
	
	if (pc_checkskill(sd, SG_DEVIL) && !pc_nextjobexp(sd))
		clif_status_load(&sd->bl, SI_DEVIL, 1);  //blindness [Komurka]

	clif_weather_check(sd);
	
	map_foreachinarea(clif_getareachar,sd->bl.m,
		sd->bl.x-AREA_SIZE,sd->bl.y-AREA_SIZE,sd->bl.x+AREA_SIZE,sd->bl.y+AREA_SIZE,
		BL_ALL,sd);
	
	// For automatic triggering of NPCs after map loading (so you don't need to walk 1 step first)
	if (map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNPC))
		npc_touch_areanpc(sd,sd->bl.m,sd->bl.x,sd->bl.y);
	else
		sd->areanpc_id = 0;

	if (pc_isdead(sd)) //In case you warped dead.
		clif_clearchar_area(&sd->bl, 1);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_TickSend(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);

	sd->client_tick=RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
	sd->server_tick = gettick();
	clif_servertick(sd);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_WalkToXY(int fd, struct map_session_data *sd) {
	int x, y;
	int cmd;
	RFIFOHEAD(fd);

	if (pc_isdead(sd)) {
		clif_clearchar_area(&sd->bl, 1);
		return;
	}

	if (clif_cant_act(sd))
		return;

	if (!unit_can_move(&sd->bl))
		return;

	if(sd->sc.count && sd->sc.data[SC_RUN].timer != -1)
		return;

	if (sd->invincible_timer != -1)
		pc_delinvincibletimer(sd);

	pc_stop_attack(sd);

	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);
	//Set last idle time... [Skotlex]
	sd->idletime = last_tick;

	unit_walktoxy(&sd->bl, x, y, 0);

}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_QuitGame(int fd, struct map_session_data *sd) {
	WFIFOHEAD(fd,packet_len_table[0x18b]);
	WFIFOW(fd,0) = 0x18b;

	/*	Rovert's prevent logout option fixed [Valaris]	*/
	if (sd->sc.data[SC_CLOAKING].timer==-1 && sd->sc.data[SC_HIDING].timer==-1 &&
		(!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
	) {
		clif_setwaitclose(fd);
		WFIFOW(fd,2)=0;
	} else {
		WFIFOW(fd,2)=1;
	}
	WFIFOSET(fd,packet_len_table[0x18b]);
}


/*==========================================
 *
 *------------------------------------------
 */
void check_fake_id(int fd, struct map_session_data *sd, int target_id) {
	// if player asks for the fake player (only bot and modified client can see a hiden player)
/*	if (target_id == server_char_id) {
		char message_to_gm[strlen(msg_txt(536)) + strlen(msg_txt(540)) + strlen(msg_txt(507)) + strlen(msg_txt(508))];
		sprintf(message_to_gm, msg_txt(536), sd->status.name, sd->status.account_id); // Character '%s' (account: %d) try to use a bot (it tries to detect a fake player).
		intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message_to_gm);
		// if we block people
		if (battle_config.ban_bot < 0) {
			chrif_char_ask_name(-1, sd->status.name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block
			clif_setwaitclose(sd->fd); // forced to disconnect because of the hack
			// message about the ban
			sprintf(message_to_gm, msg_txt(540)); //  This player has been definitivly blocked.
		// if we ban people
		} else if (battle_config.ban_bot > 0) {
			chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, 0, battle_config.ban_bot, 0); // type: 2 - ban (year, month, day, hour, minute, second)
			clif_setwaitclose(sd->fd); // forced to disconnect because of the hack
			// message about the ban
			sprintf(message_to_gm, msg_txt(507), battle_config.ban_bot); //  This player has been banned for %d minute(s).
		} else { // impossible to display: we don't send fake player if battle_config.ban_bot is == 0
			// message about the ban
			sprintf(message_to_gm, msg_txt(508)); //  This player hasn't been banned (Ban option is disabled).
		}
		intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message_to_gm);
		// send this info cause the bot ask until get an answer, damn spam
		memset(WPACKETP(0), 0, packet_len_table[0x95]);
		WPACKETW(0) = 0x95;
		WPACKETL(2) = server_char_id;
		strncpy(WPACKETP(6), sd->status.name, 24);
		SENDPACKET(fd, packet_len_table[0x95]);
		// take fake player out of screen
		WPACKETW(0) = 0x80;
		WPACKETL(2) = server_char_id;
		WPACKETB(6) = 0;
		SENDPACKET(fd, packet_len_table[0x80]);
		// take fake mob out of screen
		WPACKETW(0) = 0x80;
		WPACKETL(2) = server_fake_mob_id;
		WPACKETB(6) = 0;
		SENDPACKET(fd, packet_len_table[0x80]);
	}

	// if player asks for the fake mob (only bot and modified client can see a hiden mob)
	if (target_id == server_fake_mob_id) {
		int fake_mob;
		char message_to_gm[strlen(msg_txt(537)) + strlen(msg_txt(540)) + strlen(msg_txt(507)) + strlen(msg_txt(508))];
		sprintf(message_to_gm, msg_txt(537), sd->status.name, sd->status.account_id); // Character '%s' (account: %d) try to use a bot (it tries to detect a fake mob).
		intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message_to_gm);
		// if we block people
		if (battle_config.ban_bot < 0) {
			chrif_char_ask_name(-1, sd->status.name, 1, 0, 0, 0, 0, 0, 0); // type: 1 - block
			clif_setwaitclose(sd->fd); // forced to disconnect because of the hack
			// message about the ban
			sprintf(message_to_gm, msg_txt(540)); //  This player has been definitivly blocked.
		// if we ban people
		} else if (battle_config.ban_bot > 0) {
			chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, 0, battle_config.ban_bot, 0); // type: 2 - ban (year, month, day, hour, minute, second)
			clif_setwaitclose(sd->fd); // forced to disconnect because of the hack
			// message about the ban
			sprintf(message_to_gm, msg_txt(507), battle_config.ban_bot); //  This player has been banned for %d minute(s).
		} else { // impossible to display: we don't send fake player if battle_config.ban_bot is == 0
			// message about the ban
			sprintf(message_to_gm, msg_txt(508)); //  This player hasn't been banned (Ban option is disabled).
		}
		intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, message_to_gm);
		// send this info cause the bot ask until get an answer, damn spam
		memset(WPACKETP(0), 0, packet_len_table[0x95]);
		WPACKETW(0) = 0x95;
		WPACKETL(2) = server_fake_mob_id;
		fake_mob = fake_mob_list[(sd->bl.m + sd->fd + sd->status.char_id) % (sizeof(fake_mob_list) / sizeof(fake_mob_list[0]))]; // never same mob
		if (!mobdb_checkid(fake_mob))
			fake_mob = 1002; // poring (default)
		strncpy(WPACKETP(6), mob_db[fake_mob].name, 24);
		SENDPACKET(fd, packet_len_table[0x95]);
		// take fake mob out of screen
		WPACKETW(0) = 0x80;
		WPACKETL(2) = server_fake_mob_id;
		WPACKETB(6) = 0;
		SENDPACKET(fd, packet_len_table[0x80]);
		// take fake player out of screen
		WPACKETW(0) = 0x80;
		WPACKETL(2) = server_char_id;
		WPACKETB(6) = 0;
		SENDPACKET(fd, packet_len_table[0x80]);
	}
*/
	return;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) {
	int account_id;
	struct block_list* bl;
	struct status_change *sc;
	RFIFOHEAD(fd);
	
	account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
	if(account_id<0) // for disguises [Valaris]
		account_id-=account_id*2;

	//Is this possible? Lagged clients could request names of already gone mobs/players. [Skotlex]
	if ((bl = map_id2bl(account_id)) != NULL) {	
		sc = status_get_sc(bl);
		if (sc && (
			(sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) && !sd->special_state.intravision) ||
			sc->option&OPTION_INVISIBLE)
		) {
			//Asked name of invisible player, this shouldn't be possible!
			//Possible bot? Thanks to veider and qspirit
			//FIXME: Still isn't perfected as clients keep asking for this on legitimate situations.
    			unsigned char gm_msg[256];
    			sprintf(gm_msg, "Hack on NameRequest: character '%s' (account: %d) requests name of invisible chars.", sd->status.name, sd->status.account_id);
				ShowWarning(gm_msg);
			    // information is sended to all online GM
			  //  intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, gm_msg);
			return;
		}
		clif_charnameack(fd, bl);
	}
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_GlobalMessage(int fd, struct map_session_data *sd) { // S 008c <len>.w <str>.?B
	unsigned char *message, *buf, buf2[128];
	RFIFOHEAD(fd);
	WFIFOHEAD(fd, RFIFOW(fd,2) + 4);

	message = (unsigned char*)RFIFOP(fd,4);
	if (strlen(message) < strlen(sd->status.name) || //If the incoming string is too short...
		strncmp(message, sd->status.name, strlen(sd->status.name)) != 0) //Or the name does not matches...
	{
		unsigned char gm_msg[256];
		ShowWarning("Hack on global message: character '%s' (account: %d), use an other name to send a (normal) message.\n", sd->status.name, sd->status.account_id);
		// information is sended to all online GM
		sprintf(gm_msg, "Hack on global message (normal message): character '%s' (account: %d) uses another name.", sd->status.name, sd->status.account_id);
		intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, gm_msg);
		
		if (strlen(message) == 0)
			strcpy(gm_msg, " This player sends a void name and a void message.");
		else
			snprintf(gm_msg, 255, " This player sends (name:message): '%128s'.", message);
		intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, gm_msg);
		// message about the ban
		if (battle_config.ban_spoof_namer > 0)
			sprintf(gm_msg, " This player has been banned for %d minute(s).", battle_config.ban_spoof_namer);
		else
			sprintf(gm_msg, " This player hasn't been banned (Ban option is disabled).");
		intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, gm_msg);

		// if we ban people
		if (battle_config.ban_spoof_namer > 0) {
			chrif_char_ask_name(-1, sd->status.name, 2, 0, 0, 0, 0, battle_config.ban_spoof_namer, 0); // type: 2 - ban (year, month, day, hour, minute, second)
			clif_setwaitclose(fd); // forced to disconnect because of the hack
		}
		else
			session[fd]->eof = 1; //Disconnect them too, bad packets can cause problems down the road. [Skotlex]
		return;
	}
	
	if ((is_atcommand(fd, sd, message, 0) != AtCommand_None) ||
		(is_charcommand(fd, sd, message,0) != CharCommand_None))
		return;
	if (sd->sc.count &&
		(sd->sc.data[SC_BERSERK].timer != -1 || sd->sc.data[SC_NOCHAT].timer != -1 ))
		return;

	if (RFIFOW(fd,2)+4 < 128)
		buf = buf2; //Use a static buffer.
	else
		buf = (unsigned char*)aCallocA(RFIFOW(fd,2) + 4, sizeof(char));

	// send message to others
	WBUFW(buf,0) = 0x8d;
	WBUFW(buf,2) = RFIFOW(fd,2) + 4; // len of message - 4 + 8
	WBUFL(buf,4) = sd->bl.id;
	memcpy(WBUFP(buf,8), message, RFIFOW(fd,2) - 4);
	clif_send(buf, WBUFW(buf,2), &sd->bl, sd->chatID ? CHAT_WOS : AREA_CHAT_WOC);

	if(buf != buf2) aFree(buf);

	// send back message to the speaker
	memcpy(WFIFOP(fd,0), RFIFOP(fd,0), RFIFOW(fd,2));
	WFIFOW(fd,0) = 0x8e;
	WFIFOSET(fd, WFIFOW(fd,2));

#ifdef PCRE_SUPPORT
	map_foreachinrange(npc_chat_sub, &sd->bl, AREA_SIZE, BL_NPC, message, strlen(message), &sd->bl);
	map_foreachinrange(mob_chat_sub, &sd->bl, AREA_SIZE, BL_MOB, message, strlen(message), &sd->bl);
#endif

	// Celest
	if ((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) { //Super Novice.
		int next = pc_nextbaseexp(sd);
		if (next > 0 && (sd->status.base_exp * 1000 / next)% 100 == 0) {
			switch (sd->state.snovice_flag) {
			case 0:
				if (strstr(message, msg_txt(504)))
					sd->state.snovice_flag++;
				break;
			case 1:
				sprintf(buf2, msg_txt(505), sd->status.name);
				if (strstr(message, buf2))
					sd->state.snovice_flag++;
				break;
			case 2:
				if (strstr(message, msg_txt(506)))
					sd->state.snovice_flag++;
				break;
			case 3:
				if (skillnotok(MO_EXPLOSIONSPIRITS,sd))
					break; //Do not override the noskill mapflag. [Skotlex]
				clif_skill_nodamage(&sd->bl,&sd->bl,MO_EXPLOSIONSPIRITS,-1,
					sc_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS],100,
						17,skill_get_time(MO_EXPLOSIONSPIRITS,1))); //Lv17-> +50 critical (noted by Poki) [Skotlex]
				sd->state.snovice_flag = 0;
				break;
			}
		}
	}
	return;
}

int clif_message(struct block_list *bl, char* msg)
{
	unsigned short msg_len = strlen(msg) + 1;
	unsigned char buf[256];

	nullpo_retr(0, bl);

	WBUFW(buf, 0) = 0x8d;
	WBUFW(buf, 2) = msg_len + 8;
	WBUFL(buf, 4) = bl->id;
	memcpy(WBUFP(buf, 8), msg, msg_len);

	clif_send(buf, WBUFW(buf,2), bl, AREA_CHAT_WOC);	// by Gengar

	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_MapMove(int fd, struct map_session_data *sd) {
// /m /mapmove (as @rura GM command)
	char output[30]; // 17+4+4=26, 30 max.
	char map_name[MAP_NAME_LENGTH]; //Err... map names are 15+'\0' in size, not 16+'\0' [Skotlex]
	RFIFOHEAD(fd);

	if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
	    (pc_isGM(sd) >= get_atcommand_level(AtCommand_MapMove))) {
		memcpy(map_name, RFIFOP(fd,2), MAP_NAME_LENGTH-1);
		map_name[MAP_NAME_LENGTH-1]='\0';
		sprintf(output, "%s %d %d", map_name, RFIFOW(fd,18), RFIFOW(fd,20));
		atcommand_rura(fd, sd, "@rura", output);
	}

	return;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_changed_dir(struct block_list *bl) {
	unsigned char buf[64];

	WBUFW(buf,0) = 0x9c;
	WBUFL(buf,2) = bl->id;
	WBUFW(buf,6) = bl->type==BL_PC?((TBL_PC*)bl)->head_dir:0;
	WBUFB(buf,8) = unit_getdir(bl);

	clif_send(buf, packet_len_table[0x9c], bl, AREA_WOS);
	if (disguised(bl)) {
		WBUFL(buf,2) = -bl->id;
		WBUFW(buf,6) = 0;
		clif_send(buf, packet_len_table[0x9c], bl, SELF);
	}

	return;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_ChangeDir(int fd, struct map_session_data *sd) {
	unsigned char headdir, dir;
	RFIFOHEAD(fd);

	headdir = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
	dir = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
	pc_setdir(sd, dir, headdir);

	clif_changed_dir(&sd->bl);
	return;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_Emotion(int fd, struct map_session_data *sd) {
	unsigned char buf[64];
	RFIFOHEAD(fd);

	if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 2) {
		if (RFIFOB(fd,2) == 34) {// prevent use of the mute emote [Valaris]
			clif_skill_fail(sd, 1, 0, 1);
			return;
		}
		// fix flood of emotion icon (ro-proxy): flood only the hacker player
		if (sd->emotionlasttime >= time(NULL)) {
			sd->emotionlasttime = time(NULL) + 1; // not more than 1 per second (using /commands the client can spam it)
			clif_skill_fail(sd, 1, 0, 1);
			return;
		}
		sd->emotionlasttime = time(NULL) + 1; // not more than 1 per second (using /commands the client can spam it)
		
		WBUFW(buf,0) = 0xc0;
		WBUFL(buf,2) = sd->bl.id;
		WBUFB(buf,6) = RFIFOB(fd,2);
		clif_send(buf, packet_len_table[0xc0], &sd->bl, AREA);
	} else
		clif_skill_fail(sd, 1, 0, 1);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_HowManyConnections(int fd, struct map_session_data *sd) {
	WFIFOHEAD(fd,packet_len_table[0xc2]);
	WFIFOW(fd,0) = 0xc2;
	WFIFOL(fd,2) = map_getusers();
	WFIFOSET(fd,packet_len_table[0xc2]);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_ActionRequest(int fd, struct map_session_data *sd) {
	unsigned int tick;
	unsigned char buf[64];
	int action_type, target_id;
	RFIFOHEAD(fd);

	if (pc_isdead(sd)) {
		clif_clearchar_area(&sd->bl, 1);
		return;
	}

	if (clif_cant_act(sd) || sd->sc.option&OPTION_HIDE)
		return;
	
	if (sd->sc.count &&
		(sd->sc.data[SC_TRICKDEAD].timer != -1 ||
	 	sd->sc.data[SC_AUTOCOUNTER].timer != -1 ||
		sd->sc.data[SC_BLADESTOP].timer != -1))
		return;

	tick = gettick();

	pc_stop_walking(sd, 1);
	pc_stop_attack(sd);

	target_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
	action_type = RFIFOB(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
	//Regardless of what they have to do, they have just requested an action, no longer idle. [Skotlex]
	sd->idletime = last_tick;

	if(target_id<0) // for disguises [Valaris]
		target_id-=(target_id*2);
		
	switch(action_type) {
	case 0x00: // once attack
	case 0x07: // continuous attack
		if(sd->vd.class_ ==JOB_WEDDING || sd->vd.class_==JOB_XMAS)
			return;
		if (!battle_config.sdelay_attack_enable && pc_checkskill(sd, SA_FREECAST) <= 0) {
			if (DIFF_TICK(tick, sd->ud.canact_tick) < 0) {
				clif_skill_fail(sd, 1, 4, 0);
				return;
			}
		}
		if (sd->invincible_timer != -1)
			pc_delinvincibletimer(sd);
		unit_attack(&sd->bl, target_id, action_type != 0);
		break;
	case 0x02: // sitdown
		if (battle_config.basic_skill_check == 0 || pc_checkskill(sd, NV_BASIC) >= 3) {
			if (sd->ud.skilltimer != -1) //No sitting while casting :P
				break;
			if (sd->sc.count && (
				sd->sc.data[SC_DANCING].timer != -1 ||
				(sd->sc.data[SC_GRAVITATION].timer != -1 && sd->sc.data[SC_GRAVITATION].val3 == BCT_SELF)
			)) //No sitting during these states neither.
			break;
			pc_setsit(sd);
			skill_gangsterparadise(sd, 1); // �M�����O�X�^�[�p���_�C�X�ݒ� fixed Valaris
			skill_rest(sd, 1); // TK_HPTIME sitting down mode [Dralnu]
			clif_sitting(sd);
		} else
			clif_skill_fail(sd, 1, 0, 2);
		break;
	case 0x03: // standup
		pc_setstand(sd);
		skill_gangsterparadise(sd, 0); // �M�����O�X�^�[�p���_�C�X���� fixed Valaris
		skill_rest(sd, 0); // TK_HPTIME standing up mode [Dralnu]
		WBUFW(buf, 0) = 0x8a;
		WBUFL(buf, 2) = sd->bl.id;
		WBUFB(buf,26) = 3;
		clif_send(buf, packet_len_table[0x8a], &sd->bl, AREA);
		break;
	}
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_Restart(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);

	switch(RFIFOB(fd,2)) {
	case 0x00:
		if (pc_isdead(sd)) {
			pc_setstand(sd);
			pc_setrestartvalue(sd, 3);
			pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, 2);
		}
		// in case the player's status somehow wasn't updated yet [Celest]
		else if (sd->status.hp <= 0)
			pc_setdead(sd);
		break;
	case 0x01:
		/*	Rovert's Prevent logout option - Fixed [Valaris]	*/
		if (!battle_config.prevent_logout || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout)
		{
			//map_quit(sd);	//A clif_quitsave is sent inmediately after this, so no need to quit yet. [Skotlex]
			chrif_charselectreq(sd);
		} else {
                        WFIFOHEAD(fd,packet_len_table[0x18b]);
			WFIFOW(fd,0)=0x18b;
			WFIFOW(fd,2)=1;

			WFIFOSET(fd,packet_len_table[0x018b]);
		}
		break;
	}
}

/*==========================================
 * Transmission of a wisp (S 0096 <len>.w <nick>.24B <message>.?B)
 *------------------------------------------
 */
void clif_parse_Wis(int fd, struct map_session_data *sd) { // S 0096 <len>.w <nick>.24B <message>.?B // rewritten by [Yor]
	char *gm_command;
	struct map_session_data *dstsd;
	int i=0;
	struct npc_data *npc;
	char split_data[10][50];
	int j=0,k=0;
	char *whisper_tmp;    
	char output[256];  
	RFIFOHEAD(fd);

	//printf("clif_parse_Wis: message: '%s'.\n", RFIFOP(fd,28));

	gm_command = (char*)aCallocA(strlen((const char*)RFIFOP(fd,28)) + 28, sizeof(char)); // 24+3+(RFIFOW(fd,2)-28)+1 or 24+3+(strlen(RFIFOP(fd,28))+1 (size can be wrong with hacker)

	sprintf(gm_command, "%s : %s", sd->status.name, RFIFOP(fd,28));
	if ((is_charcommand(fd, sd, gm_command, 0) != CharCommand_None) ||
		(is_atcommand(fd, sd, gm_command, 0) != AtCommand_None)) {
		if(gm_command) aFree(gm_command);
		return;
	}
	if(gm_command) aFree(gm_command);
	if (sd->sc.count &&
		(sd->sc.data[SC_BERSERK].timer!=-1 || sd->sc.data[SC_NOCHAT].timer != -1))
		return;

	//Chat Logging type 'W' / Whisper
	if(log_config.chat&1 //we log everything then
		|| ( log_config.chat&2 //if Whisper bit is on
		&& ( !agit_flag || !(log_config.chat&16) ))) //if WOE ONLY flag is off or AGIT is OFF
		log_chat("W", 0, sd->status.char_id, sd->status.account_id, (char*)mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, (char*)RFIFOP(fd, 4), (char*)RFIFOP(fd, 28));


	//-------------------------------------------------------//
	//   Lordalfa - Paperboy - To whisper NPC commands       //
	//-------------------------------------------------------//
	whisper_tmp = (char*) RFIFOP(fd,4);
	if (whisper_tmp[0] && (strncasecmp(whisper_tmp,"NPC:",4) == 0) && (strlen(whisper_tmp) >4))   {
		whisper_tmp += 4; //Skip the NPC: string part.
		if ((npc = npc_name2id(whisper_tmp)))	
		{
			whisper_tmp=(char *)aCallocA(strlen((char *)(RFIFOP(fd,28)))+1,sizeof(char));
			whisper_tmp[0]=0;
		   
			sprintf(whisper_tmp, "%s", (const char*)RFIFOP(fd,28));  
			for( j=0;whisper_tmp[j]!='\0';j++)
			{
				if(whisper_tmp[j]!='#')
				{
					split_data[i][j-k]=whisper_tmp[j];
				}
				else
				{
					split_data[i][j-k]='\0';
					k=j+1;
					i++;
				}
			} // Splits the message using '#' as separators
			split_data[i][j-k]='\0';
			
			aFree(whisper_tmp);
			whisper_tmp=(char *)aCallocA(15,sizeof(char));
			whisper_tmp[0]=0;
			
			for (j=0;j<=10;j++)
			{
				sprintf(whisper_tmp, "@whispervar%d$", j);
				set_var(sd,whisper_tmp,(char *) split_data[j]);        
			}//You don't need to zero them, just reset them [Kevin]
			
			aFree(whisper_tmp);
			whisper_tmp=(char *)aCallocA(strlen(npc->name)+18,sizeof(char));
			whisper_tmp[0]=0;
			
			sprintf(whisper_tmp, "%s::OnWhisperGlobal", npc->name);
			npc_event(sd,whisper_tmp,0); // Calls the NPC label 

			aFree(whisper_tmp); //I rewrote it a little to use memory allocation, a bit more stable =P  [Kevin]
			return;     
		} //should have just removed the one below that was a my bad =P
	}		
	
	// Main chat [LuzZza]
	if(strcmpi((const char*)RFIFOP(fd,4), main_chat_nick) == 0) {
		if(!sd->state.mainchat) {
			clif_displaymessage(fd, msg_txt(388)); // You should enable main chat with "@main on" command.
			return;
		}
		if (sd->sc.data[SC_NOCHAT].timer != -1) {
			clif_displaymessage(fd, msg_txt(387));
			return;
		}
		sprintf(output, msg_txt(386), sd->status.name, (char *)RFIFOP(fd,28));
		intif_announce(output, strlen(output) + 1, 0xFE000000, 0);
		return;
	}

	// searching destination character
	dstsd = map_nick2sd((char*)RFIFOP(fd,4));
	// player is not on this map-server
	if (dstsd == NULL ||
	// At this point, don't send wisp/page if it's not exactly the same name, because (example)
	// if there are 'Test' player on an other map-server and 'test' player on this map-server,
	// and if we ask for 'Test', we must not contact 'test' player
	// so, we send information to inter-server, which is the only one which decide (and copy correct name).
	    strcmp(dstsd->status.name, (const char*)RFIFOP(fd,4)) != 0) // not exactly same name
		// send message to inter-server
		intif_wis_message(sd, (char*)RFIFOP(fd,4), (char*)RFIFOP(fd,28), RFIFOW(fd,2)-28);
	// player is on this map-server
	else {
		// if you send to your self, don't send anything to others
		if (dstsd->fd == fd) // but, normaly, it's impossible!
			clif_wis_message(fd, wisp_server_name, "You can not page yourself. Sorry.", strlen("You can not page yourself. Sorry.") + 1);
		// otherwise, send message and answer immediatly
		else {
			if (dstsd->ignoreAll == 1) {
				if (dstsd->sc.option & OPTION_INVISIBLE && pc_isGM(sd) < pc_isGM(dstsd))
					clif_wis_end(fd, 1); // 1: target character is not loged in
				else
					clif_wis_end(fd, 3); // 3: everyone ignored by target
			} else {
				// if player ignore the source character
				for(i = 0; i < MAX_IGNORE_LIST; i++)
					if (strcmp(dstsd->ignore[i].name, sd->status.name) == 0) {
						clif_wis_end(fd, 2);	// 2: ignored by target
						break;
					}
				// if source player not found in ignore list
				if (i == MAX_IGNORE_LIST) {
					if(strlen(dstsd->away_message) > 0) { // Send away automessage [LuzZza]
						//(Automessage has been sent)
						sprintf(output, "%s %s", (char*)RFIFOP(fd,28),msg_txt(543));
						clif_wis_message(dstsd->fd, sd->status.name, output, strlen(output) + 1);
						clif_wis_end(fd, 0); // 0: success to send wisper
						if(dstsd->state.autotrade)
							//"Away [AT] - \"%s\""
							sprintf(output, msg_txt(544), dstsd->away_message);
						else
							//"Away - \"%s\""
							sprintf(output, msg_txt(545), dstsd->away_message);
						clif_wis_message(fd, dstsd->status.name, output, strlen(output) + 1);
					} else { // Normal message
						clif_wis_message(dstsd->fd, sd->status.name, (char*)RFIFOP(fd,28), RFIFOW(fd,2) - 28);
						clif_wis_end(fd, 0); // 0: success to send wisper
					}
				}
			}
		}
	}

	return;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_GMmessage(int fd, struct map_session_data *sd) {
// /b
	RFIFOHEAD(fd);
	if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
	    (pc_isGM(sd) >= get_atcommand_level(AtCommand_Broadcast)))
		intif_GMmessage((char*)RFIFOP(fd,4), RFIFOW(fd,2)-4, 0);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_TakeItem(int fd, struct map_session_data *sd) {
	struct flooritem_data *fitem;
	int map_object_id;
	RFIFOHEAD(fd);

	map_object_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
	
	fitem = (struct flooritem_data*)map_id2bl(map_object_id);

	if (pc_isdead(sd)) {
		clif_clearchar_area(&sd->bl, 1);
		return;
	}

	if (fitem == NULL || fitem->bl.type != BL_ITEM || fitem->bl.m != sd->bl.m)
		return;
	
	if (clif_cant_act(sd))
		return;
	
	if(pc_iscloaking(sd) || pc_ischasewalk(sd)) //Disable cloaking/chasewalking characters from looting [Skotlex]
		return;
	if(sd->sc.count && (
		sd->sc.data[SC_TRICKDEAD].timer != -1 || //���񂾂ӂ�
		sd->sc.data[SC_BLADESTOP].timer != -1 || //���n���
		sd->sc.data[SC_NOCHAT].timer!=-1 )	//��b�֎~
	) {
		clif_additem(sd,0,0,6); // send fail packet! [Valaris]
		return;
	}

	pc_takeitem(sd, fitem);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_DropItem(int fd, struct map_session_data *sd) {
	int item_index, item_amount;
	RFIFOHEAD(fd);

	if (pc_isdead(sd)) {
		clif_clearchar_area(&sd->bl, 1);
		return;
	}

	if (clif_cant_act(sd))
		return;

	if (sd->sc.count && (
		sd->sc.data[SC_AUTOCOUNTER].timer != -1 || //�I�[�g�J�E���^�[
		sd->sc.data[SC_BLADESTOP].timer != -1//���n���
	))
		return;

	item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
	item_amount = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
	if (!pc_dropitem(sd, item_index, item_amount))
	//Because the client does not likes being ignored.
		clif_delitem(sd, item_index,0);

}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_UseItem(int fd, struct map_session_data *sd) {
	int n;
	RFIFOHEAD(fd);

	if (pc_isdead(sd)) {
		clif_clearchar_area(&sd->bl, 1);
		return;
	}

	if (sd->sc.opt1 > 0 && sd->sc.opt1 != OPT1_STONEWAIT)
		return;
	
	//This flag enables you to use items while in an NPC. [Skotlex]
	if (sd->npc_id) {
		if (sd->npc_id != sd->npc_item_flag)
			return;
	} else
	if (clif_trading(sd))
		return;
	
	if (sd->sc.count && (
		sd->sc.data[SC_TRICKDEAD].timer != -1 || //���񂾂ӂ�
		sd->sc.data[SC_BLADESTOP].timer != -1 || //���n���
		sd->sc.data[SC_BERSERK].timer!=-1 ||	//�o�[�T�[�N
		sd->sc.data[SC_NOCHAT].timer!=-1 ||
		sd->sc.data[SC_GRAVITATION].timer!=-1	//��b�֎~
	))
		return;

	if (sd->invincible_timer != -1)
		pc_delinvincibletimer(sd);

	//Whether the item is used or not is irrelevant, the char ain't idle. [Skotlex]
	sd->idletime = last_tick;
	n = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
	
	if(n <0 || n >= MAX_INVENTORY)
		return;
	if (!pc_useitem(sd,n))
		clif_useitemack(sd,n,0,0); //Send an empty ack packet or the client gets stuck.
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_EquipItem(int fd,struct map_session_data *sd)
{
	int index;
	RFIFOHEAD(fd);

	if(pc_isdead(sd)) {
		clif_clearchar_area(&sd->bl,1);
		return;
	}
	index = RFIFOW(fd,2)-2; 
	if (index < 0 || index >= MAX_INVENTORY)
		return; //Out of bounds check.
	
	if(sd->npc_id) {
		if (sd->npc_id != sd->npc_item_flag)
			return;
	} else if (clif_cant_act(sd))
		return;
		
	if(sd->sc.data[SC_BLADESTOP].timer!=-1 || sd->sc.data[SC_BERSERK].timer!=-1 )
		return;

	if(sd->status.inventory[index].identify != 1) {		// ���Ӓ�
		clif_equipitemack(sd,index,0,0);	// fail
		return;
	}
	//�y�b�g�p�����ł��邩�Ȃ���
	if(sd->inventory_data[index]) {
		if(sd->inventory_data[index]->type != 8){
			if(sd->inventory_data[index]->type == 10)
				RFIFOW(fd,4)=0x8000;	// ��𖳗���葕���ł���悤�Ɂi�|�|�G
			pc_equipitem(sd,index,RFIFOW(fd,4));
		} else
			pet_equipitem(sd,index);
	}
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_UnequipItem(int fd,struct map_session_data *sd)
{
	int index;
	RFIFOHEAD(fd);

	if(pc_isdead(sd)) {
		clif_clearchar_area(&sd->bl,1);
		return;
	}

	if (clif_cant_act(sd))
		return;

	index = RFIFOW(fd,2)-2;

	pc_unequipitem(sd,index,1);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);

	if(pc_isdead(sd)) {
		clif_clearchar_area(&sd->bl,1);
		return;
	}

	if (clif_cant_act(sd))
		return;
	//Clicked on a negative ID? Player disguised as NPC! [Skotlex]
	if (RFIFOL(fd,2) < 0)
		return;
	npc_click(sd,RFIFOL(fd,2));
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_NpcBuySellSelected(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	if (sd->trade_partner != 0)
		return;
	npc_buysellsel(sd,RFIFOL(fd,2),RFIFOB(fd,6));
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_NpcBuyListSend(int fd,struct map_session_data *sd)
{
	int fail=0,n, i;
	unsigned short *item_list;
	unsigned char npc_ev[51];
	struct npc_data *nd;
	RFIFOHEAD(fd);

	n = (RFIFOW(fd,2)-4) /4;
	item_list = (unsigned short*)RFIFOP(fd,4);

	if (sd->trade_partner || !sd->npc_shopid){
		fail = 1;
	}else{
		if((nd = ((struct npc_data *)map_id2bl(sd->npc_shopid))->master_nd)){
			sprintf(npc_ev, "%s::OnBuyItem", nd->exname);
			for(i=0;i<n;i++){
				setd_sub(sd, "@bought_nameid", i, (void *)((int)item_list[i*2+1]));
				setd_sub(sd, "@bought_quantity", i, (void *)((int)item_list[i*2]));
			}
			npc_event(sd, npc_ev, 0);
			fail = 0;
		}else{
			fail = npc_buylist(sd,n,item_list);
		}
	}

	sd->npc_shopid = 0; //Clear shop data.
	WFIFOHEAD(fd,packet_len_table[0xca]);
	WFIFOW(fd,0)=0xca;
	WFIFOB(fd,2)=fail;
	WFIFOSET(fd,packet_len_table[0xca]);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_NpcSellListSend(int fd,struct map_session_data *sd)
{
	int fail=0,n,i;
	unsigned short *item_list;
	unsigned char npc_ev[51];
	struct npc_data *nd;
	RFIFOHEAD(fd);

	n = (RFIFOW(fd,2)-4) /4;
	item_list = (unsigned short*)RFIFOP(fd,4);

	if (sd->trade_partner || !sd->npc_shopid){
		fail = 1;
	}else{
		if((nd = ((struct npc_data *)map_id2bl(sd->npc_shopid))->master_nd)){
			sprintf(npc_ev, "%s::OnSellItem", nd->exname);
			for(i=0;i<n;i++){
				setd_sub(sd, "@sold_nameid", i, (void *)((int)sd->status.inventory[item_list[i*2]-2].nameid));
				setd_sub(sd, "@sold_quantity", i, (void *)((int)item_list[i*2+1]));
			}
			npc_event(sd, npc_ev, 0);
			fail = 0;
		}else{
			fail = npc_selllist(sd,n,item_list);
		}
	}
	sd->npc_shopid = 0; //Clear shop data.

	WFIFOHEAD(fd,packet_len_table[0xcb]);
	WFIFOW(fd,0)=0xcb;
	WFIFOB(fd,2)=fail;
	WFIFOSET(fd,packet_len_table[0xcb]);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_CreateChatRoom(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	if(battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 4){
		chat_createchat(sd,RFIFOW(fd,4),RFIFOB(fd,6),(char*)RFIFOP(fd,7),(char*)RFIFOP(fd,15),RFIFOW(fd,2)-15);
	} else
		clif_skill_fail(sd,1,0,3);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_ChatAddMember(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	chat_joinchat(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6));
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_ChatRoomStatusChange(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	chat_changechatstatus(sd,RFIFOW(fd,4),RFIFOB(fd,6),(char*)RFIFOP(fd,7),(char*)RFIFOP(fd,15),RFIFOW(fd,2)-15);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_ChangeChatOwner(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	chat_changechatowner(sd,(char*)RFIFOP(fd,6));
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_KickFromChat(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	chat_kickchat(sd,(char*)RFIFOP(fd,2));
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_ChatLeave(int fd,struct map_session_data *sd)
{
	chat_leavechat(sd);
}

/*==========================================
 * ����v���𑊎�ɑ���
 *------------------------------------------
 */
void clif_parse_TradeRequest(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);

	if(battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 1){
		trade_traderequest(sd,RFIFOL(sd->fd,2));
	} else
		clif_skill_fail(sd,1,0,0);
}

/*==========================================
 * ����v��
 *------------------------------------------
 */
void clif_parse_TradeAck(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	trade_tradeack(sd,RFIFOB(sd->fd,2));
}

/*==========================================
 * �A�C�e���lj�
 *------------------------------------------
 */
void clif_parse_TradeAddItem(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	trade_tradeadditem(sd,RFIFOW(sd->fd,2),RFIFOL(sd->fd,4));
}

/*==========================================
 * �A�C�e���lj�����(ok����)
 *------------------------------------------
 */
void clif_parse_TradeOk(int fd,struct map_session_data *sd)
{
	trade_tradeok(sd);
}

/*==========================================
 * ����L�����Z��
 *------------------------------------------
 */
void clif_parse_TradeCancel(int fd,struct map_session_data *sd)
{
	trade_tradecancel(sd);
}

/*==========================================
 * �������(trade����)
 *------------------------------------------
 */
void clif_parse_TradeCommit(int fd,struct map_session_data *sd)
{
	trade_tradecommit(sd);
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_StopAttack(int fd,struct map_session_data *sd)
{
	pc_stop_attack(sd);
}

/*==========================================
 * �J�[�g�փA�C�e�����ڂ�
 *------------------------------------------
 */
void clif_parse_PutItemToCart(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);

	if (clif_trading(sd))
		return;
	pc_putitemtocart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4));
}
/*==========================================
 * �J�[�g����A�C�e�����o��
 *------------------------------------------
 */
void clif_parse_GetItemFromCart(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);

	if (clif_trading(sd))
		return;
	pc_getitemfromcart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4));
}

/*==========================================
 * �t���i(��,�y�R,�J�[�g)���͂���
 *------------------------------------------
 */
void clif_parse_RemoveOption(int fd,struct map_session_data *sd)
{
	pc_setoption(sd,0);
}

/*==========================================
 * �`�F���W�J�[�g
 *------------------------------------------
 */
void clif_parse_ChangeCart(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	pc_setcart(sd,RFIFOW(fd,2));
}

/*==========================================
 * �X�e�[�^�X�A�b�v
 *------------------------------------------
 */
void clif_parse_StatusUp(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	pc_statusup(sd,RFIFOW(fd,2));
}

/*==========================================
 * �X�L�����x���A�b�v
 *------------------------------------------
 */
void clif_parse_SkillUp(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	pc_skillup(sd,RFIFOW(fd,2));
}

/*==========================================
 * �X�L���g�p�iID�w��j
 *------------------------------------------
 */
void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) {
	int skillnum, skilllv, lv, target_id;
	unsigned int tick = gettick();
	RFIFOHEAD(fd);

	if (clif_cant_act(sd))
		return;
	if (pc_issit(sd))
		return;

	skilllv = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
	if (skilllv < 1) skilllv = 1; //No clue, I have seen the client do this with guild skills :/ [Skotlex]
	skillnum = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
	target_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[2]);

	//Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
	sd->idletime = last_tick;
	
	if (skillnotok(skillnum, sd))
		return;

	if (sd->bl.id != target_id &&
		!sd->state.skill_flag &&
		skill_get_inf(skillnum)&INF_SELF_SKILL)
		target_id = sd->bl.id; //What good is it to mess up the target in self skills? Wished I knew... [Skotlex]
	
	if (sd->ud.skilltimer != -1) {
		if (skillnum != SA_CASTCANCEL)
			return;
	} else if (DIFF_TICK(tick, sd->ud.canact_tick) < 0 &&
		// allow monk combos to ignore this delay [celest]
		!(sd->sc.count && sd->sc.data[SC_COMBO].timer!=-1 &&
		(skillnum == MO_EXTREMITYFIST ||
		skillnum == MO_CHAINCOMBO ||
		skillnum == MO_COMBOFINISH ||
		skillnum == CH_PALMSTRIKE ||
		skillnum == CH_TIGERFIST ||
		skillnum == CH_CHAINCRUSH))) {
		clif_skill_fail(sd, skillnum, 4, 0);
		return;
	}

	if (sd->vd.class_ == JOB_WEDDING || sd->vd.class_ == JOB_XMAS)
		return;
	
	if (sd->invincible_timer != -1)
		pc_delinvincibletimer(sd);
	
	if(target_id<0) // for disguises [Valaris]
		target_id*=-1;
		
	if (sd->skillitem >= 0 && sd->skillitem == skillnum) {
		if (skilllv != sd->skillitemlv)
			skilllv = sd->skillitemlv;
		unit_skilluse_id(&sd->bl, target_id, skillnum, skilllv);
	} else {
		sd->skillitem = sd->skillitemlv = -1;
		if (skillnum == MO_EXTREMITYFIST) {
			if ((sd->sc.data[SC_COMBO].timer == -1 ||
				(sd->sc.data[SC_COMBO].val1 != MO_COMBOFINISH &&
				sd->sc.data[SC_COMBO].val1 != CH_TIGERFIST &&
				sd->sc.data[SC_COMBO].val1 != CH_CHAINCRUSH))) {
				if (!sd->state.skill_flag ) {
					sd->state.skill_flag = 1;
					clif_skillinfo(sd, MO_EXTREMITYFIST, INF_ATTACK_SKILL, -1);
					return;
				} else if (sd->bl.id == target_id) {
					clif_skillinfo(sd, MO_EXTREMITYFIST, INF_ATTACK_SKILL, -1);
					return;
				}
			}
		}
		if (skillnum == TK_JUMPKICK) {
			if (sd->sc.data[SC_COMBO].timer == -1 ||
				sd->sc.data[SC_COMBO].val1 != TK_JUMPKICK) {
				if (!sd->state.skill_flag ) {
					sd->state.skill_flag = 1;
					clif_skillinfo(sd, TK_JUMPKICK, INF_ATTACK_SKILL, -1);
					return;
				} else if (sd->bl.id == target_id) {
					clif_skillinfo(sd, TK_JUMPKICK, INF_ATTACK_SKILL, -1);
					return;
				}
			}
		}

		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;
		}
	}
}

/*==========================================
 * �X�L���g�p�i�ꏊ�w��j
 *------------------------------------------
 */
void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, int skilllv, int skillnum, int x, int y, int skillmoreinfo)
{
	int lv;
	unsigned int tick = gettick();
	RFIFOHEAD(fd);

	//Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
	sd->idletime = last_tick;

	if (skillnotok(skillnum, sd))
		return;

	if (skillmoreinfo != -1) {
		if (pc_issit(sd)) {
			clif_skill_fail(sd, skillnum, 0, 0);
			return;
		}
		memcpy(talkie_mes, RFIFOP(fd,skillmoreinfo), MESSAGE_SIZE);
		talkie_mes[MESSAGE_SIZE-1] = '\0'; //Overflow protection [Skotlex]
	}

	if (sd->ud.skilltimer != -1)
		return;
	if (DIFF_TICK(tick, sd->ud.canact_tick) < 0)
	{
		clif_skill_fail(sd, skillnum, 4, 0);
		return;
	}

	if (sd->vd.class_ == JOB_WEDDING || sd->vd.class_ == JOB_XMAS)
		return;
	
	if (sd->invincible_timer != -1)
		pc_delinvincibletimer(sd);
	if (sd->skillitem >= 0 && sd->skillitem == skillnum) {
		if (skilllv != sd->skillitemlv)
			skilllv = sd->skillitemlv;
		unit_skilluse_pos(&sd->bl, x, y, skillnum, skilllv);
	} else {
		sd->skillitem = sd->skillitemlv = -1;
		if ((lv = pc_checkskill(sd, skillnum)) > 0) {
			if (skilllv > lv)
				skilllv = lv;
			unit_skilluse_pos(&sd->bl, x, y, skillnum,skilllv);
		}
	}
}


void clif_parse_UseSkillToPos(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);

	if (clif_cant_act(sd))
		return;
	if (pc_issit(sd))
		return;

	clif_parse_UseSkillToPosSub(fd, sd,
		RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]), //skill lv
		RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]), //skill num
		RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[2]), //pos x
		RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[3]), //pos y
		-1	//Skill more info.
	);
}

void clif_parse_UseSkillToPosMoreInfo(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);

	if (clif_cant_act(sd))
		return;
	if (pc_issit(sd))
		return;
	
	clif_parse_UseSkillToPosSub(fd, sd,
		RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]), //Skill lv
		RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]), //Skill num
		RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[2]), //pos x
		RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[3]), //pos y
		packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[4] //skill more info
	);
}
/*==========================================
 * �X�L���g�p�imap�w��j
 *------------------------------------------
 */
void clif_parse_UseSkillMap(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);

	if (clif_cant_act(sd))
		return;

	if (sd->vd.class_==JOB_WEDDING || sd->vd.class_ == JOB_XMAS)
		return;
	
	if(sd->invincible_timer != -1)
		pc_delinvincibletimer(sd);

	skill_castend_map(sd,RFIFOW(fd,2),(char*)RFIFOP(fd,4));
}
/*==========================================
 * �����v��
 *------------------------------------------
 */
void clif_parse_RequestMemo(int fd,struct map_session_data *sd)
{
	if (!pc_isdead(sd))
		pc_memo(sd,-1);
}
/*==========================================
 * �A�C�e������
 *------------------------------------------
 */
void clif_parse_ProduceMix(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);

	if (sd->menuskill_id !=	AM_PHARMACY)
		return;

	if (clif_trading(sd)) {
		//Make it fail to avoid shop exploits where you sell something different than you see.
		clif_skill_fail(sd,sd->ud.skillid,0,0);
		sd->menuskill_lv = sd->menuskill_id = 0;
		return;
	}
	skill_produce_mix(sd,0,RFIFOW(fd,2),RFIFOW(fd,4),RFIFOW(fd,6),RFIFOW(fd,8), 1);
	sd->menuskill_lv = sd->menuskill_id = 0;
}
/*==========================================
 * ����C��
 *------------------------------------------
 */
void clif_parse_RepairItem(int fd, struct map_session_data *sd)
{
	RFIFOHEAD(fd);

	if (sd->menuskill_id != BS_REPAIRWEAPON)
		return;
	if (clif_trading(sd)) {
		//Make it fail to avoid shop exploits where you sell something different than you see.
		clif_skill_fail(sd,sd->ud.skillid,0,0);
		sd->menuskill_lv = sd->menuskill_id = 0;
		return;
	}
	skill_repairweapon(sd,RFIFOW(fd,2));
	sd->menuskill_lv = sd->menuskill_id = 0;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_WeaponRefine(int fd, struct map_session_data *sd) {
	int idx;
	RFIFOHEAD(fd);

	if (sd->menuskill_id != WS_WEAPONREFINE) //Packet exploit?
		return;
	if (clif_trading(sd)) {
		//Make it fail to avoid shop exploits where you sell something different than you see.
		clif_skill_fail(sd,sd->ud.skillid,0,0);
		sd->menuskill_lv = sd->menuskill_id = 0;
		return;
	}
	idx = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
	skill_weaponrefine(sd, idx-2);
	sd->menuskill_lv = sd->menuskill_id = 0;
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_NpcSelectMenu(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);

	sd->npc_menu=RFIFOB(fd,6);
	npc_scriptcont(sd,RFIFOL(fd,2));
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_NpcNextClicked(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
#ifdef __WIN32
	//For some extraordinarily eerie reason that noone has figured out yet, 
	//windows native compiles NEED this nullpo_retv or the function is not found!
	nullpo_retv(sd);
#endif
	npc_scriptcont(sd,RFIFOL(fd,2));
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_NpcAmountInput(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
#define RFIFOL_(fd,pos) (*(int*)(session[fd]->rdata+session[fd]->rdata_pos+(pos)))
	//Input Value overflow Exploit FIX
	sd->npc_amount=RFIFOL_(fd,6); //fixed by Lupus. npc_amount is (int) but was RFIFOL changing it to (unsigned int)
#undef RFIFOL_

	npc_scriptcont(sd,RFIFOL(fd,2));
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_NpcStringInput(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);

	if(RFIFOW(fd,2)-7 >= sizeof(sd->npc_str)){
		ShowWarning("clif: input string too long !\n");
		memcpy(sd->npc_str,RFIFOP(fd,8),sizeof(sd->npc_str));
		sd->npc_str[sizeof(sd->npc_str)-1]=0;
	} else
		strcpy(sd->npc_str,(char*)RFIFOP(fd,8));
	npc_scriptcont(sd,RFIFOL(fd,4));
}

/*==========================================
 *
 *------------------------------------------
 */
void clif_parse_NpcCloseClicked(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	npc_scriptcont(sd,RFIFOL(fd,2));
}

/*==========================================
 * �A�C�e���Ӓ�
 *------------------------------------------
 */
void clif_parse_ItemIdentify(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	if (sd->menuskill_id != MC_IDENTIFY)
		return;
	skill_identify(sd,RFIFOW(fd,2)-2);
	sd->menuskill_lv = sd->menuskill_id = 0;
}
/*==========================================
 * ��쐬
 *------------------------------------------
 */
void clif_parse_SelectArrow(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	if (sd->menuskill_id != AC_MAKINGARROW)
		return;
	if (clif_trading(sd)) {
	//Make it fail to avoid shop exploits where you sell something different than you see.
		clif_skill_fail(sd,sd->ud.skillid,0,0);
		sd->menuskill_lv = sd->menuskill_id = 0;
		return;
	}
	skill_arrow_create(sd,RFIFOW(fd,2));
	sd->menuskill_lv = sd->menuskill_id = 0;
}
/*==========================================
 * �I�[�g�X�y����M
 *------------------------------------------
 */
void clif_parse_AutoSpell(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	if (sd->menuskill_id != SA_AUTOSPELL)
		return;
	skill_autospell(sd,RFIFOW(fd,2));
	sd->menuskill_lv = sd->menuskill_id = 0;
}
/*==========================================
 * �J�[�h�g�p
 *------------------------------------------
 */
void clif_parse_UseCard(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	if (sd->trade_partner != 0)
		return;
	clif_use_card(sd,RFIFOW(fd,2)-2);
}
/*==========================================
 * �J�[�h�}�������I��
 *------------------------------------------
 */
void clif_parse_InsertCard(int fd,struct map_session_data *sd)
{
	RFIFOHEAD(fd);
	if (sd->trade_partner != 0)
		return;
	pc_insert_card(sd,RFIFOW(fd,2)-2,RFIFOW(fd,4)-2);
}

/*==========================================
 * 0193 �L����ID���O����
 *------------------------------------------
 */
void clif_parse_SolveCharName(int fd, struct map_session_data *sd) {
	int char_id;
	RFIFOHEAD(fd);

	char_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]);
	clif_solved_charname(sd, char_id);
}

/*==========================================
 * 0197 /resetskill /resetstate
 *------------------------------------------
 */
void clif_parse_ResetChar(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
		pc_isGM(sd) >= get_atcommand_level(AtCommand_ResetState)) {
		switch(RFIFOW(fd,2)){
		case 0:
			pc_resetstate(sd);
			break;
		case 1:
			pc_resetskill(sd,1);
			break;
		}
	}
}

/*==========================================
 * 019c /lb��
 *------------------------------------------
 */
void clif_parse_LGMmessage(int fd, struct map_session_data *sd) {
	unsigned char buf[512];
	RFIFOHEAD(fd);

	if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
	    (pc_isGM(sd) >= get_atcommand_level(AtCommand_LocalBroadcast))) {
		WBUFW(buf,0) = 0x9a;
		WBUFW(buf,2) = RFIFOW(fd,2);
		memcpy(WBUFP(buf,4), RFIFOP(fd,4), RFIFOW(fd,2) - 4);
		clif_send(buf, RFIFOW(fd,2), &sd->bl, ALL_SAMEMAP);
	}
}

/*==========================================
 * �J�v���q�ɂ֓����
 *------------------------------------------
 */
void clif_parse_MoveToKafra(int fd, struct map_session_data *sd) {
	int item_index, item_amount;
	RFIFOHEAD(fd);

	if (clif_trading(sd))
		return;
	
	item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-2;
	item_amount = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);
	if (item_index < 0 || item_index >= MAX_INVENTORY)
		return;

	if (sd->state.storage_flag == 1)
		storage_storageadd(sd, item_index, item_amount);
	else if (sd->state.storage_flag == 2)
		storage_guild_storageadd(sd, item_index, item_amount);
}

/*==========================================
 * �J�v���q�ɂ���o��
 *------------------------------------------
 */
void clif_parse_MoveFromKafra(int fd,struct map_session_data *sd) {
	int item_index, item_amount;
	RFIFOHEAD(fd);

	if (clif_trading(sd))
		return;
	
	item_index = RFIFOW(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0])-1;
	item_amount = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[1]);

	if (sd->state.storage_flag == 1)
		storage_storageget(sd, item_index, item_amount);
	else if(sd->state.storage_flag == 2)
		storage_guild_storageget(sd, item_index, item_amount);
}

/*==========================================
 * �J�v���q�ɂփJ�[�g��������
 *------------------------------------------
 */
void clif_parse_MoveToKafraFromCart(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);

	if (clif_trading(sd))
		return;

	if (sd->state.storage_flag == 1)
		storage_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
	else	if (sd->state.storage_flag == 2)
		storage_guild_storageaddfromcart(sd, RFIFOW(fd,2) - 2, RFIFOL(fd,4));
}

/*==========================================
 * �J�v���q�ɂ���o��
 *------------------------------------------
 */
void clif_parse_MoveFromKafraToCart(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);

	if (clif_trading(sd))
		return;
	if (sd->state.storage_flag == 1)
		storage_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
	else if (sd->state.storage_flag == 2)
		storage_guild_storagegettocart(sd, RFIFOW(fd,2)-1, RFIFOL(fd,4));
}

/*==========================================
 * �J�v���q�ɂ�‚���
 *------------------------------------------
 */
void clif_parse_CloseKafra(int fd, struct map_session_data *sd) {
	if (sd->state.storage_flag == 1)
		storage_storageclose(sd);
	else if (sd->state.storage_flag == 2)
		storage_guild_storageclose(sd);
}

/*==========================================
 * �p�[�e�B�����
 *------------------------------------------
 */
void clif_parse_CreateParty(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	if (battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 7) {
		party_create(sd,(char*)RFIFOP(fd,2),0,0);
	} else
		clif_skill_fail(sd,1,0,4);
}

/*==========================================
 * �p�[�e�B�����
 *------------------------------------------
 */
void clif_parse_CreateParty2(int fd, struct map_session_data *sd) {
	if (battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 7){
		RFIFOHEAD(fd);
		party_create(sd,(char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOB(fd,27));
	} else
		clif_skill_fail(sd,1,0,4);
}

/*==========================================
 * �p�[�e�B�Ɋ��U
 *------------------------------------------
 */
void clif_parse_PartyInvite(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	party_invite(sd, RFIFOL(fd,2));
}

/*==========================================
 * �p�[�e�B���U�ԓ�
 *------------------------------------------
 */
void clif_parse_ReplyPartyInvite(int fd,struct map_session_data *sd) {
	RFIFOHEAD(fd);
	if(battle_config.basic_skill_check == 0 || pc_checkskill(sd,NV_BASIC) >= 5){
		party_reply_invite(sd,RFIFOL(fd,2),RFIFOL(fd,6));
	} else {
		party_reply_invite(sd,RFIFOL(fd,2),-1);
		clif_skill_fail(sd,1,0,4);
	}
}

/*==========================================
 * �p�[�e�B�E�ޗv��
 *------------------------------------------
 */
void clif_parse_LeaveParty(int fd, struct map_session_data *sd) {
	party_leave(sd);
}

/*==========================================
 * �p�[�e�B�����v��
 *------------------------------------------
 */
void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	party_removemember(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6));
}

/*==========================================
 * �p�[�e�B�ݒ�ύX�v��
 *------------------------------------------
 */
void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	party_changeoption(sd, RFIFOW(fd,2), RFIFOW(fd,4));
}

/*==========================================
 * �p�[�e�B���b�Z�[�W���M�v��
 *------------------------------------------
 */
void clif_parse_PartyMessage(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);

	if (is_charcommand(fd, sd, (char*)RFIFOP(fd,4), 0) != CharCommand_None ||
		is_atcommand(fd, sd, (char*)RFIFOP(fd,4), 0) != AtCommand_None)
		return;
	if	(sd->sc.count && (
			sd->sc.data[SC_BERSERK].timer!=-1 ||	//�o�[�T�[�N���͉�b���s��
			sd->sc.data[SC_NOCHAT].timer!=-1		//�`���b�g�֎~
		))
		return;

	party_send_message(sd, (char*)RFIFOP(fd,4), RFIFOW(fd,2)-4);
}

/*==========================================
 * �I�X��
 *------------------------------------------
 */
void clif_parse_CloseVending(int fd, struct map_session_data *sd) {
	vending_closevending(sd);
}

/*==========================================
 * �I�X�A�C�e�����X�g�v��
 *------------------------------------------
 */
void clif_parse_VendingListReq(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);

	vending_vendinglistreq(sd,RFIFOL(fd,2));
	if(sd->npc_id)
		npc_event_dequeue(sd);
}

/*==========================================
 * �I�X�A�C�e���w��
 *------------------------------------------
 */
void clif_parse_PurchaseReq(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	if (clif_trading(sd))
		return;
	vending_purchasereq(sd, RFIFOW(fd,2), RFIFOL(fd,4), RFIFOP(fd,8));
}

/*==========================================
 * �I�X�J��
 *------------------------------------------
 */
void clif_parse_OpenVending(int fd,struct map_session_data *sd) {
	RFIFOHEAD(fd);
	if (clif_trading(sd))
		return;
	vending_openvending(sd, RFIFOW(fd,2), (char*)RFIFOP(fd,4), RFIFOB(fd,84), RFIFOP(fd,85));
}

/*==========================================
 * �M���h�����
 *------------------------------------------
 */
void clif_parse_CreateGuild(int fd,struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_create(sd, (char*)RFIFOP(fd,6));
}

/*==========================================
 * �M���h�}�X�^�[���ǂ����m�F
 *------------------------------------------
 */
void clif_parse_GuildCheckMaster(int fd, struct map_session_data *sd) {
	clif_guild_masterormember(sd);
}

/*==========================================
 * �M���h���v��
 *------------------------------------------
 */
void clif_parse_GuildRequestInfo(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	switch(RFIFOL(fd,2)){
	case 0:	// �M���h��{���A�����G�Ώ��
		clif_guild_basicinfo(sd);
		clif_guild_allianceinfo(sd);
		break;
	case 1:	// �����o�[���X�g�A��E�����X�g
		clif_guild_positionnamelist(sd);
		clif_guild_memberlist(sd);
		break;
	case 2:	// ��E�����X�g�A��E��񃊃X�g
		clif_guild_positionnamelist(sd);
		clif_guild_positioninfolist(sd);
		break;
	case 3:	// �X�L�����X�g
		clif_guild_skillinfo(sd);
		break;
	case 4:	// �Ǖ����X�g
		clif_guild_explusionlist(sd);
		break;
	default:
		if (battle_config.error_log)
			ShowError("clif: guild request info: unknown type %d\n", RFIFOL(fd,2));
		break;
	}
}

/*==========================================
 * �M���h��E�ύX
 *------------------------------------------
 */
void clif_parse_GuildChangePositionInfo(int fd, struct map_session_data *sd) {
	int i;
	RFIFOHEAD(fd);

	for(i = 4; i < RFIFOW(fd,2); i += 40 ){
		guild_change_position(sd, RFIFOL(fd,i), RFIFOL(fd,i+4), RFIFOL(fd,i+12), (char*)RFIFOP(fd,i+16));
	}
}

/*==========================================
 * �M���h�����o��E�ύX
 *------------------------------------------
 */
void clif_parse_GuildChangeMemberPosition(int fd, struct map_session_data *sd) {
	int i;
	RFIFOHEAD(fd);

	for(i=4;i<RFIFOW(fd,2);i+=12){
		guild_change_memberposition(sd->status.guild_id,
			RFIFOL(fd,i),RFIFOL(fd,i+4),RFIFOL(fd,i+8));
	}
}

/*==========================================
 * �M���h�G���u�����v��
 *------------------------------------------
 */
void clif_parse_GuildRequestEmblem(int fd,struct map_session_data *sd) {
	struct guild *g;
	RFIFOHEAD(fd);
	g=guild_search(RFIFOL(fd,2));
	if(g!=NULL)
		clif_guild_emblem(sd,g);
}

/*==========================================
 * �M���h�G���u�����ύX
 *------------------------------------------
 */
void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_change_emblem(sd,RFIFOW(fd,2)-4,(char*)RFIFOP(fd,4));
}

/*==========================================
 * �M���h���m�ύX
 *------------------------------------------
 */
void clif_parse_GuildChangeNotice(int fd,struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_change_notice(sd,RFIFOL(fd,2),(char*)RFIFOP(fd,6),(char*)RFIFOP(fd,66));
}

/*==========================================
 * �M���h���U
 *------------------------------------------
 */
void clif_parse_GuildInvite(int fd,struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_invite(sd,RFIFOL(fd,2));
}

/*==========================================
 * �M���h���U�ԐM
 *------------------------------------------
 */
void clif_parse_GuildReplyInvite(int fd,struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_reply_invite(sd,RFIFOL(fd,2),RFIFOB(fd,6));
}

/*==========================================
 * �M���h�E��
 *------------------------------------------
 */
void clif_parse_GuildLeave(int fd,struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_leave(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14));
}

/*==========================================
 * �M���h�Ǖ�
 *------------------------------------------
 */
void clif_parse_GuildExplusion(int fd,struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_explusion(sd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),(char*)RFIFOP(fd,14));
}

/*==========================================
 * �M���h��b
 *------------------------------------------
 */
void clif_parse_GuildMessage(int fd,struct map_session_data *sd) {
	RFIFOHEAD(fd);

	if (is_charcommand(fd, sd, (char*)RFIFOP(fd, 4), 0) != CharCommand_None ||
		is_atcommand(fd, sd, (char*)RFIFOP(fd, 4), 0) != AtCommand_None)
		return;
	if (sd->sc.count && (
		sd->sc.data[SC_BERSERK].timer!=-1 ||	//�o�[�T�[�N���͉�b���s��
		sd->sc.data[SC_NOCHAT].timer!=-1		//�`���b�g�֎~
	))
		return;

	guild_send_message(sd, (char*)RFIFOP(fd,4), RFIFOW(fd,2)-4);
}

/*==========================================
 * �M���h�����v��
 *------------------------------------------
 */
void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_reqalliance(sd,RFIFOL(fd,2));
}

/*==========================================
 * �M���h�����v���ԐM
 *------------------------------------------
 */
void clif_parse_GuildReplyAlliance(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_reply_reqalliance(sd,RFIFOL(fd,2),RFIFOL(fd,6));
}

/*==========================================
 * �M���h�֌W����
 *------------------------------------------
 */
void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_delalliance(sd,RFIFOL(fd,2),RFIFOL(fd,6));
}

/*==========================================
 * �M���h�G��
 *------------------------------------------
 */
void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_opposition(sd,RFIFOL(fd,2));
}

/*==========================================
 * �M���h���U
 *------------------------------------------
 */
void clif_parse_GuildBreak(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	guild_break(sd,(char*)RFIFOP(fd,2));
}

// pet
void clif_parse_PetMenu(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	pet_menu(sd,RFIFOB(fd,2));
}

void clif_parse_CatchPet(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	pet_catch_process2(sd,RFIFOL(fd,2));
}

void clif_parse_SelectEgg(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	if (sd->menuskill_id != SA_TAMINGMONSTER || sd->menuskill_lv != -1)
		return;
	pet_select_egg(sd,RFIFOW(fd,2)-2);
	sd->menuskill_lv = sd->menuskill_id = 0;
}

void clif_parse_SendEmotion(int fd, struct map_session_data *sd) {
	if(sd->pd) {
		RFIFOHEAD(fd);
		clif_pet_emotion(sd->pd,RFIFOL(fd,2));
	}
}

void clif_parse_ChangePetName(int fd, struct map_session_data *sd) {
	RFIFOHEAD(fd);
	pet_change_name(sd,(char*)RFIFOP(fd,2));
}

// Kick (right click menu for GM "(name) force to quit")
void clif_parse_GMKick(int fd, struct map_session_data *sd) {
	struct block_list *target;
	int tid;

	RFIFOHEAD(fd);
	tid = RFIFOL(fd,2);

	if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
	    (pc_isGM(sd) >= get_atcommand_level(AtCommand_Kick))) {
		target = map_id2bl(tid);
		if (target) {
			if (target->type == BL_PC) {
				struct map_session_data *tsd = (struct map_session_data *)target;
				if (pc_isGM(sd) > pc_isGM(tsd))
					clif_GM_kick(sd, tsd, 1);
				else
					clif_GM_kickack(sd, 0);
			} else if (target->type == BL_MOB) {
				struct mob_data *md = (struct mob_data *)target;
				sd->state.attack_type = 0;
				mob_damage(&sd->bl, md, md->hp, 2);
			} else
				clif_GM_kickack(sd, 0);
		} else
			clif_GM_kickack(sd, 0);
	}
}

/*==========================================
 * /shift
 *------------------------------------------
 */
void clif_parse_Shift(int fd, struct map_session_data *sd) {	// Rewriten by [Yor]
	char player_name[NAME_LENGTH+1];

	memset(player_name, '\0', sizeof(player_name));

	if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
	    (pc_isGM(sd) >= get_atcommand_level(AtCommand_JumpTo))) {
          RFIFOHEAD(fd);
          memcpy(player_name, RFIFOP(fd,2), NAME_LENGTH);
          atcommand_jumpto(fd, sd, "@jumpto", player_name); // as @jumpto
	}

	return;
}

/*==========================================
 * /recall
 *------------------------------------------
 */
void clif_parse_Recall(int fd, struct map_session_data *sd) {	// Added by RoVeRT
	char player_name[25];

	memset(player_name, '\0', sizeof(player_name));

	if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
	    (pc_isGM(sd) >= get_atcommand_level(AtCommand_Recall))) {
		RFIFOHEAD(fd);
		memcpy(player_name, RFIFOP(fd,2), NAME_LENGTH);
		atcommand_recall(fd, sd, "@recall", player_name); // as @recall
	}

	return;
}

/*==========================================
 * /monster /item rewriten by [Yor]
 *------------------------------------------
 */
void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) {
	char monster_item_name[NAME_LENGTH+10]; //Additional space is for logging, eg: "@monster Poring"
	int level;

	memset(monster_item_name, '\0', sizeof(monster_item_name));

	if (battle_config.atc_gmonly == 0 || pc_isGM(sd)) {
		RFIFOHEAD(fd);
		memcpy(monster_item_name, RFIFOP(fd,2), NAME_LENGTH);

		if (mobdb_searchname(monster_item_name) != 0) {
			if (pc_isGM(sd) >= (level =get_atcommand_level(AtCommand_Monster)))
			{
				atcommand_monster(fd, sd, "@spawn", monster_item_name); // as @spawn
				if(log_config.gm && level >= log_config.gm)
				{	//Log action. [Skotlex]
					snprintf(monster_item_name, sizeof(monster_item_name)-1, "@spawn %s", RFIFOP(fd,2));
					log_atcommand(sd, monster_item_name);
				}
			}
		} else if (itemdb_searchname(monster_item_name) != NULL) {
			if (pc_isGM(sd) >= (level = get_atcommand_level(AtCommand_Item)))
			{
				atcommand_item(fd, sd, "@item", monster_item_name); // as @item
				if(log_config.gm && level >= log_config.gm)
				{	//Log action. [Skotlex]
					snprintf(monster_item_name, sizeof(monster_item_name)-1, "@item %s", RFIFOP(fd,2));
					log_atcommand(sd, monster_item_name);
				}
			}
		}
	}
}

void clif_parse_GMHide(int fd, struct map_session_data *sd) {	// Modified by [Yor]
	if ((battle_config.atc_gmonly == 0 || pc_isGM(sd)) &&
	    (pc_isGM(sd) >= get_atcommand_level(AtCommand_Hide))) {
		if (sd->sc.option & OPTION_INVISIBLE) {
			sd->sc.option &= ~OPTION_INVISIBLE;
			if (sd->disguise)
				status_set_viewdata(&sd->bl, sd->disguise);
			else
				status_set_viewdata(&sd->bl, sd->status.class_);
			clif_displaymessage(fd, "Invisible: Off.");
		} else {
			sd->sc.option |= OPTION_INVISIBLE;
			//Experimental hidden mode, changes your view class to invisible [Skotlex]
			sd->vd.class_ = INVISIBLE_CLASS;
			clif_displaymessage(fd, "Invisible: On.");
		}
		clif_changeoption(&sd->bl);
	}
}

/*==========================================
 * GM�ɂ��`���b�g�֎~���ԕt�^
 *------------------------------------------
 */
void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd)
{
	int type, limit, level;
	struct block_list *bl;
	struct map_session_data *dstsd;

	if(!battle_config.muting_players) {
		clif_displaymessage(fd, "Muting is disabled.");
		return;
	}

	RFIFOHEAD(fd);
	bl = map_id2bl(RFIFOL(fd,2));
	if (!bl || bl->type != BL_PC)
		return;
	nullpo_retv(dstsd =(struct map_session_data *)bl);

	type = RFIFOB(fd,6);
	limit = RFIFOW(fd,7);
	if (type == 0)
		limit = 0 - limit;

	//Temporarily disable chars from muting themselves due to the mysterious "DON'T USE BOT!" message. [Skotlex]
	//Also, if type is 2 and the ids don't match, this is a crafted hacked packet!
	//So for now, type 2is just totally disabled.
	if (type == 2/*&& sd->bl.id != dstsd->bl.id*/)
		return;
	
	if (
		((level = pc_isGM(sd)) > pc_isGM(dstsd) && level >= get_atcommand_level(AtCommand_Mute))
		|| (type == 2 && !level)) {
		clif_GM_silence(sd, dstsd, ((type == 2) ? 1 : type));
		if (battle_config.manner_system)
		{
			dstsd->status.manner -= limit;
			if(dstsd->status.manner < 0)
				sc_start(bl,SC_NOCHAT,100,0,0);
			else
			{
				dstsd->status.manner = 0;
				status_change_end(bl,SC_NOCHAT,-1);
			}
		}
		ShowDebug("GMReqNoChat: name:%s type:%d limit:%d manner:%d\n", dstsd->status.name, type, limit, dstsd->status.manner);
	}

	return;
}
/*==========================================
 * GM�ɂ��`���b�g�֎~���ԎQ�Ɓi�H�j
 *------------------------------------------
 */
void clif_parse_GMReqNoChatCount(int fd, struct map_session_data *sd)
{
	int tid;
	RFIFOHEAD(fd);
	tid = RFIFOL(fd,2);

	WFIFOHEAD(fd,packet_len_table[0x1e0]);
	WFIFOW(fd,0) = 0x1e0;
	WFIFOL(fd,2) = tid;
	sprintf((char*)WFIFOP(fd,6),"%d",tid);
//	memcpy(WFIFOP(fd,6), "TESTNAME", 24);
	WFIFOSET(fd, packet_len_table[0x1e0]);

	return;
}

void clif_parse_PMIgnore(int fd, struct map_session_data *sd) {	// Rewritten by [Yor]
	char output[512];
	char *nick; // S 00cf <nick>.24B <type>.B: 00 (/ex nick) deny speech from nick, 01 (/in nick) allow speech from nick
	int i, pos;
	RFIFOHEAD(fd);

	memset(output, '\0', sizeof(output));

	nick = (char*)RFIFOP(fd,2); // speed up
	RFIFOB(fd,NAME_LENGTH+1) = '\0'; // to be sure that the player name have at maximum 23 characters (nick range: [2]->[26])
	//printf("Ignore: char '%s' state: %d\n", nick, RFIFOB(fd,26));

	WFIFOHEAD(fd,packet_len_table[0xd1]);
	WFIFOW(fd,0) = 0x0d1; // R 00d1 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail
	WFIFOB(fd,2) = RFIFOB(fd,26);
	// do nothing only if nick can not exist
	if (strlen(nick) < 4) {
		WFIFOB(fd,3) = 1; // fail
		WFIFOSET(fd, packet_len_table[0x0d1]);
		if (RFIFOB(fd,26) == 0) // type
			clif_wis_message(fd, wisp_server_name, "It's impossible to block this player.", strlen("It's impossible to block this player.") + 1);
		else
			clif_wis_message(fd, wisp_server_name, "It's impossible to unblock this player.", strlen("It's impossible to unblock this player.") + 1);
		return;
	// name can exist
	} else {
		// deny action (we add nick only if it's not already exist
		if (RFIFOB(fd,26) == 0) { // type
			pos = -1;
			for(i = 0; i < MAX_IGNORE_LIST; i++) {
				if (strcmp(sd->ignore[i].name, nick) == 0) {
					WFIFOB(fd,3) = 1; // fail
					WFIFOSET(fd, packet_len_table[0x0d1]);
					clif_wis_message(fd, wisp_server_name, "This player is already blocked.", strlen("This player is already blocked.") + 1);
					if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people.
						sprintf(output, "Character '%s' (account: %d) has tried AGAIN to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name);
						intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output);
					}
					return;
				} else if (pos == -1 && sd->ignore[i].name[0] == '\0')
					pos = i;
			}
			// if a position is found and name not found, we add it in the list
			if (pos != -1) {
				memcpy(sd->ignore[pos].name, nick, NAME_LENGTH-1);
				WFIFOB(fd,3) = 0; // success
				WFIFOSET(fd, packet_len_table[0x0d1]);
				if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people.
					sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name);
					intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output);
					// send something to be inform and force bot to ignore twice... If GM receiving block + block again, it's a bot :)
					clif_wis_message(fd, wisp_server_name, "Add me in your ignore list, doesn't block my wisps.", strlen("Add me in your ignore list, doesn't block my wisps.") + 1);
				}
			} else {
				WFIFOB(fd,3) = 1; // fail
				WFIFOSET(fd, packet_len_table[0x0d1]);
				clif_wis_message(fd, wisp_server_name, "You can not block more people.", strlen("You can not block more people.") + 1);
				if (strcmp(wisp_server_name, nick) == 0) { // to found possible bot users who automaticaly ignore people.
					sprintf(output, "Character '%s' (account: %d) has tried to block wisps from '%s' (wisp name of the server). Bot user?", sd->status.name, sd->status.account_id, wisp_server_name);
					intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, output);
				}
			}
		// allow action (we remove all same nicks if they exist)
		} else {
			pos = -1;
			for(i = 0; i < MAX_IGNORE_LIST; i++)
				if (strcmp(sd->ignore[i].name, nick) == 0) {
					memset(sd->ignore[i].name, 0, sizeof(sd->ignore[i].name));
					if (pos == -1) {
						WFIFOB(fd,3) = 0; // success
						WFIFOSET(fd, packet_len_table[0x0d1]);
						pos = i; // don't break, to remove ALL same nick
					}
				}
			if (pos == -1) {
				WFIFOB(fd,3) = 1; // fail
				WFIFOSET(fd, packet_len_table[0x0d1]);
				clif_wis_message(fd, wisp_server_name, "This player is not blocked by you.", strlen("This player is not blocked by you.") + 1);
			}
		}
	}

//	for(i = 0; i < MAX_IGNORE_LIST; i++) // for debug only
//		if (sd->ignore[i].name[0] != '\0')
//			printf("Ignored player: '%s'\n", sd->ignore[i].name);

	return;
}

void clif_parse_PMIgnoreAll(int fd, struct map_session_data *sd) { // Rewritten by [Yor]
	//printf("Ignore all: state: %d\n", RFIFOB(fd,2));
	RFIFOHEAD(fd);
	if (RFIFOB(fd,2) == 0) {// S 00d0 <type>len.B: 00 (/exall) deny all speech, 01 (/inall) allow all speech
                WFIFOHEAD(fd,packet_len_table[0xd2]);
		WFIFOW(fd,0) = 0x0d2; // R 00d2 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail
		WFIFOB(fd,2) = 0;
		if (sd->ignoreAll == 0) {
			sd->ignoreAll = 1;
			WFIFOB(fd,3) = 0; // success
			WFIFOSET(fd, packet_len_table[0x0d2]);
		} else {
			WFIFOB(fd,3) = 1; // fail
			WFIFOSET(fd, packet_len_table[0x0d2]);
			clif_wis_message(fd, wisp_server_name, "You already block everyone.", strlen("You already block everyone.") + 1);
		}
	} else {
                WFIFOHEAD(fd,packet_len_table[0xd2]);
		WFIFOW(fd,0) = 0x0d2; // R 00d2 <type>.B <fail>.B: type: 0: deny, 1: allow, fail: 0: success, 1: fail
		WFIFOB(fd,2) = 1;
		if (sd->ignoreAll == 1) {
			sd->ignoreAll = 0;
			WFIFOB(fd,3) = 0; // success
			WFIFOSET(fd, packet_len_table[0x0d2]);
		} else {
			WFIFOB(fd,3) = 1; // fail
			WFIFOSET(fd, packet_len_table[0x0d2]);
			clif_wis_message(fd, wisp_server_name, "You already allow everyone.", strlen("You already allow everyone.") + 1);
		}
	}

	return;
}

/*==========================================
 * Wis���ۃ��X�g
 *------------------------------------------
 */
 int pstrcmp(const void *a, const void *b)
{
	return strcmp((char *)a, (char *)b);
}
void clif_parse_PMIgnoreList(int fd,struct map_session_data *sd)
{
	int i,j=0,count=0;

	qsort (sd->ignore[0].name, MAX_IGNORE_LIST, sizeof(sd->ignore[0].name), pstrcmp);
	for(i = 0; i < MAX_IGNORE_LIST; i++){	//���g������̂𐔂���
		if(sd->ignore[i].name[0] != 0)
			count++;
	}
	WFIFOHEAD(fd, 4 + (NAME_LENGTH * count));
	WFIFOW(fd,0) = 0xd4;
	WFIFOW(fd,2) = 4 + (NAME_LENGTH * count);
	for(i = 0; i < MAX_IGNORE_LIST; i++){
		if(sd->ignore[i].name[0] != 0){
			memcpy(WFIFOP(fd, 4 + j * 24),sd->ignore[i].name, NAME_LENGTH);
			j++;
		}
	}
	WFIFOSET(fd, WFIFOW(fd,2));
	if(count >= MAX_IGNORE_LIST)	//���^���Ȃ�Ō��1�‚�����
		sd->ignore[MAX_IGNORE_LIST - 1].name[0] = 0;

	return;
}

/*==========================================
 * �X�p�m�r��/doridori�ɂ��SPR2�{
 *------------------------------------------
 */
void clif_parse_NoviceDoriDori(int fd, struct map_session_data *sd) {
	int level;
	sd->doridori_counter = 1;
	if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON
		&& sd->state.rest && (level = pc_checkskill(sd,TK_SPTIME)))
		sc_start(&sd->bl,SkillStatusChangeTable[TK_SPTIME],100,level,skill_get_time(TK_SPTIME, level));
	return;
}
/*==========================================
 * �X�p�m�r�̔����g��
 *------------------------------------------
 */
void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd)
{
	if(sd){
		int nextbaseexp=pc_nextbaseexp(sd);
		if (battle_config.etc_log){
			if(nextbaseexp != 0)
				ShowInfo("SuperNovice explosionspirits!! %d %d %d %d\n",sd->bl.id,sd->status.class_,sd->status.base_exp,(int)((double)1000*sd->status.base_exp/nextbaseexp));
			else
				ShowInfo("SuperNovice explosionspirits!! %d %d %d 000\n",sd->bl.id,sd->status.class_,sd->status.base_exp);
		}
		if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_exp > 0 && nextbaseexp > 0 && (int)((double)1000*sd->status.base_exp/nextbaseexp)%100==0){
			clif_skill_nodamage(&sd->bl,&sd->bl,MO_EXPLOSIONSPIRITS,5,
				sc_start(&sd->bl,SkillStatusChangeTable[MO_EXPLOSIONSPIRITS],100,
					5,skill_get_time(MO_EXPLOSIONSPIRITS,5)));
		}
	}
	return;
}

// random notes:
// 0x214: monster/player info ?

/*==========================================
 * Friends List
 *------------------------------------------
 */
void clif_friendslist_toggle(struct map_session_data *sd,int account_id, int char_id, int online)
{	//Toggles a single friend online/offline [Skotlex]
	int i;

	//Seek friend.
	for (i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id &&
		(sd->status.friends[i].char_id != char_id || sd->status.friends[i].account_id != account_id); i++);

	if(i == MAX_FRIENDS || sd->status.friends[i].char_id == 0)
		return; //Not found

	WFIFOHEAD(sd->fd,packet_len_table[0x206]);
	WFIFOW(sd->fd, 0) = 0x206;
	WFIFOL(sd->fd, 2) = sd->status.friends[i].account_id;
	WFIFOL(sd->fd, 6) = sd->status.friends[i].char_id;
	WFIFOB(sd->fd,10) = !online; //Yeah, a 1 here means "logged off", go figure... 
	
	WFIFOSET(sd->fd, packet_len_table[0x206]);
}

//Subfunction called from clif_foreachclient to toggle friends on/off [Skotlex]
int clif_friendslist_toggle_sub(struct map_session_data *sd,va_list ap)
{
	int account_id, char_id, online;
	account_id = va_arg(ap, int);
	char_id = va_arg(ap, int);
	online = va_arg(ap, int);
	clif_friendslist_toggle(sd, account_id, char_id, online);
	return 0;
}

//For sending the whole friends list.
void clif_friendslist_send(struct map_session_data *sd) {
	int i = 0, n;
	
	// Send friends list
	WFIFOHEAD(sd->fd, MAX_FRIENDS * 32 + 4);
	WFIFOW(sd->fd, 0) = 0x201;
	for(i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++)
	{
		WFIFOL(sd->fd, 4 + 32 * i + 0) = sd->status.friends[i].account_id;
		WFIFOL(sd->fd, 4 + 32 * i + 4) = sd->status.friends[i].char_id;
		memcpy(WFIFOP(sd->fd, 4 + 32 * i + 8), &sd->status.friends[i].name, NAME_LENGTH);
	}

	WFIFOW(sd->fd,2) = 4 + 32 * i;
	WFIFOSET(sd->fd, WFIFOW(sd->fd,2));

	for (n = 0; n < i; n++)
	{	//Sending the online players
		if (map_charid2sd(sd->status.friends[n].char_id))
			clif_friendslist_toggle(sd, sd->status.friends[n].account_id, sd->status.friends[n].char_id, 1);
	}
}


// Status for adding friend - 0: successfull 1: not exist/rejected 2: over limit
void clif_friendslist_reqack(struct map_session_data *sd, struct map_session_data *f_sd, int type)
{
	int fd;
	nullpo_retv(sd);

	fd = sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x209]);
	WFIFOW(fd,0) = 0x209;
	WFIFOW(fd,2) = type;
	if (f_sd)
	{
		WFIFOW(fd,4) = f_sd->status.account_id;
		WFIFOW(fd,8) = f_sd->status.char_id;
		memcpy(WFIFOP(fd, 12), f_sd->status.name,NAME_LENGTH);
	}
	WFIFOSET(fd, packet_len_table[0x209]);
}

void clif_parse_FriendsListAdd(int fd, struct map_session_data *sd) {
	struct map_session_data *f_sd;
	int i, f_fd;
	RFIFOHEAD(fd);

	f_sd = map_nick2sd((char*)RFIFOP(fd,2));

	// Friend doesn't exist (no player with this name)
	if (f_sd == NULL) {
		clif_displaymessage(fd, msg_txt(3));
		return;
	}

	// Friend already exists
	for (i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id != 0; i++) {
		if (sd->status.friends[i].char_id == f_sd->status.char_id) {
			clif_displaymessage(fd, "Friend already exists.");
			return;
		}
	}

	if (i == MAX_FRIENDS) {
		//No space, list full.
		clif_friendslist_reqack(sd, f_sd, 2);
		return;
	}
		
	f_fd = f_sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x207]);
	WFIFOW(f_fd,0) = 0x207;
	WFIFOL(f_fd,2) = sd->status.account_id;
	WFIFOL(f_fd,6) = sd->status.char_id;
	memcpy(WFIFOP(f_fd,10), sd->status.name, NAME_LENGTH);
	WFIFOSET(f_fd, packet_len_table[0x207]);

	return;
}

void clif_parse_FriendsListReply(int fd, struct map_session_data *sd) {
	//<W: id> <L: Player 1 chara ID> <L: Player 1 AID> <B: Response>
	struct map_session_data *f_sd;
	int char_id, account_id;
	char reply;
	RFIFOHEAD(fd);

	account_id = RFIFOL(fd,2);
	char_id = RFIFOL(fd,6);
	reply = RFIFOB(fd,10);
	//printf ("reply: %d %d %d\n", char_id, id, reply);

	f_sd = map_id2sd(account_id); //The account id is the same as the bl.id of players.
	if (f_sd == NULL)
		return;
		
	if (reply == 0)
		clif_friendslist_reqack(f_sd, sd, 1);
	else {
		int i;
		// Find an empty slot
		for (i = 0; i < MAX_FRIENDS; i++)
			if (f_sd->status.friends[i].char_id == 0)
				break;
		if (i == MAX_FRIENDS) {
			clif_friendslist_reqack(f_sd, sd, 2);
			return;
		}

		f_sd->status.friends[i].account_id = sd->status.account_id;
		f_sd->status.friends[i].char_id = sd->status.char_id;
		memcpy(f_sd->status.friends[i].name, sd->status.name, NAME_LENGTH);
		clif_friendslist_reqack(f_sd, sd, 0);

//		clif_friendslist_send(sd); //This is not needed anymore.
	}

	return;
}

void clif_parse_FriendsListRemove(int fd, struct map_session_data *sd) {
	// 0x203 </o> <ID to be removed W 4B>
	int account_id, char_id;
	int i, j;
	RFIFOHEAD(fd);

	account_id = RFIFOL(fd,2);
	char_id = RFIFOL(fd,6);

	// Search friend
	for (i = 0; i < MAX_FRIENDS &&
		(sd->status.friends[i].char_id != char_id || sd->status.friends[i].account_id != account_id); i++);

	if (i == MAX_FRIENDS) {
		clif_displaymessage(fd, "Name not found in list.");
		return;
	}
		
	// move all chars down
	for(j = i + 1; j < MAX_FRIENDS; j++)
		memcpy(&sd->status.friends[j-1], &sd->status.friends[j], sizeof(sd->status.friends[0]));

	memset(&sd->status.friends[MAX_FRIENDS-1], 0, sizeof(sd->status.friends[MAX_FRIENDS-1]));
	clif_displaymessage(fd, "Friend removed");
	
	WFIFOHEAD(fd,packet_len_table[0x20a]);
	WFIFOW(fd,0) = 0x20a;
	WFIFOL(fd,2) = account_id;
	WFIFOL(fd,6) = char_id;
	WFIFOSET(fd, packet_len_table[0x20a]);
//	clif_friendslist_send(sd); //This is not needed anymore.

	return;
}

/*==========================================
 * /killall
 *------------------------------------------
 */
void clif_parse_GMKillAll(int fd,struct map_session_data *sd)
{
	char message[50];

	strncpy(message,sd->status.name, NAME_LENGTH);
	is_atcommand(fd, sd, strcat(message," : @kickall"),0);

	return;
}

/*==========================================
 * /pvpinfo
 *------------------------------------------
 */
void clif_parse_PVPInfo(int fd,struct map_session_data *sd)
{
	WFIFOHEAD(fd,packet_len_table[0x210]);
	WFIFOW(fd,0) = 0x210;
	//WFIFOL(fd,2) = 0;	// not sure what for yet
	//WFIFOL(fd,6) = 0;
	WFIFOL(fd,10) = sd->pvp_won;	// times won
	WFIFOL(fd,14) = sd->pvp_lost;	// times lost
	WFIFOL(fd,18) = sd->pvp_point;
	WFIFOSET(fd, packet_len_table[0x210]);

	return;
}

/*==========================================
 * /blacksmith
 *------------------------------------------
 */
void clif_parse_Blacksmith(int fd,struct map_session_data *sd)
{
	int i;
	char *name;

	WFIFOHEAD(fd,packet_len_table[0x219]);
	WFIFOW(fd,0) = 0x219;
	//Packet size limits this list to 10 elements. [Skotlex]
	for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) {
		if (smith_fame_list[i].id > 0) {
			if (strcmp(smith_fame_list[i].name, "-") == 0 &&
				(name = map_charid2nick(smith_fame_list[i].id)) != NULL)
			{
				strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), name, NAME_LENGTH);
			} else
				strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), smith_fame_list[i].name, NAME_LENGTH);
		} else
			strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), "None", 5);
		WFIFOL(fd, 242 + i * 4) = smith_fame_list[i].fame;
	}
	for(;i < 10; i++) { //In case the MAX is less than 10.
		strncpy((char *)(WFIFOP(fd, 2 + 24 * i)), "Unavailable", 12);
		WFIFOL(fd, 242 + i * 4) = 0;
	}

	WFIFOSET(fd, packet_len_table[0x219]);
}

int clif_fame_blacksmith(struct map_session_data *sd, int points)
{
	int fd = sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x21b]);
	WFIFOW(fd,0) = 0x21b;
	WFIFOL(fd,2) = points;
	WFIFOL(fd,6) = sd->status.fame;
	WFIFOSET(fd, packet_len_table[0x21b]);

	return 0;
}

/*==========================================
 * /alchemist
 *------------------------------------------
 */
void clif_parse_Alchemist(int fd,struct map_session_data *sd)
{
	int i;
	char *name;

	WFIFOHEAD(fd,packet_len_table[0x21a]);
	WFIFOW(fd,0) = 0x21a;
	//Packet size limits this list to 10 elements. [Skotlex]
	for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) {
		if (chemist_fame_list[i].id > 0) {
			if (strcmp(chemist_fame_list[i].name, "-") == 0 &&
				(name = map_charid2nick(chemist_fame_list[i].id)) != NULL)
			{
				memcpy(WFIFOP(fd, 2 + 24 * i), name, NAME_LENGTH);
			} else
				memcpy(WFIFOP(fd, 2 + 24 * i), chemist_fame_list[i].name, NAME_LENGTH);
		} else
			memcpy(WFIFOP(fd, 2 + 24 * i), "None", NAME_LENGTH);
		WFIFOL(fd, 242 + i * 4) = chemist_fame_list[i].fame;
	}
	for(;i < 10; i++) { //In case the MAX is less than 10.
		memcpy(WFIFOP(fd, 2 + 24 * i), "Unavailable", NAME_LENGTH);
		WFIFOL(fd, 242 + i * 4) = 0;
	}

	WFIFOSET(fd, packet_len_table[0x21a]);
}

int clif_fame_alchemist(struct map_session_data *sd, int points)
{
	int fd = sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x21c]);
	WFIFOW(fd,0) = 0x21c;
	WFIFOL(fd,2) = points;
	WFIFOL(fd,6) = sd->status.fame;
	WFIFOSET(fd, packet_len_table[0x21c]);
	
	return 0;
}

/*==========================================
 * /taekwon
 *------------------------------------------
 */
void clif_parse_Taekwon(int fd,struct map_session_data *sd)
{
	int i;
	char *name;

	WFIFOHEAD(fd,packet_len_table[0x226]);
	WFIFOW(fd,0) = 0x226;
	//Packet size limits this list to 10 elements. [Skotlex]
	for (i = 0; i < 10 && i < MAX_FAME_LIST; i++) {
		if (taekwon_fame_list[i].id > 0) {
			if (strcmp(taekwon_fame_list[i].name, "-") == 0 &&
				(name = map_charid2nick(taekwon_fame_list[i].id)) != NULL)
			{
				memcpy(WFIFOP(fd, 2 + 24 * i), name, NAME_LENGTH);
			} else
				memcpy(WFIFOP(fd, 2 + 24 * i), taekwon_fame_list[i].name, NAME_LENGTH);
		} else
			memcpy(WFIFOP(fd, 2 + 24 * i), "None", NAME_LENGTH);
		WFIFOL(fd, 242 + i * 4) = taekwon_fame_list[i].fame;
	}
	for(;i < 10; i++) { //In case the MAX is less than 10.
		memcpy(WFIFOP(fd, 2 + 24 * i), "Unavailable", NAME_LENGTH);
		WFIFOL(fd, 242 + i * 4) = 0;
	}
	WFIFOSET(fd, packet_len_table[0x226]);
}

int clif_fame_taekwon(struct map_session_data *sd, int points)
{
	int fd = sd->fd;
	WFIFOHEAD(fd,packet_len_table[0x224]);
	WFIFOW(fd,0) = 0x224;
	WFIFOL(fd,2) = points;
	WFIFOL(fd,6) = sd->status.fame;
	WFIFOSET(fd, packet_len_table[0x224]);
	
	return 0;
}

/*==========================================
 * PK Ranking table?
 *------------------------------------------
 */
void clif_parse_RankingPk(int fd,struct map_session_data *sd)
{
	int i;

	WFIFOHEAD(fd,packet_len_table[0x238]);
	WFIFOW(fd,0) = 0x238;
	for(i=0;i<10;i++){
		memcpy(WFIFOP(fd,i*24+2), "Unknown", NAME_LENGTH);
		WFIFOL(fd,i*4+242) = 0;
	}
	WFIFOSET(fd, packet_len_table[0x238]);
	return;
}

/*==========================================
 * SG Feel save OK [Komurka]
 *------------------------------------------
 */
void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd)
{
	char feel_var[3][NAME_LENGTH] = {"PC_FEEL_SUN","PC_FEEL_MOON","PC_FEEL_STAR"};
	int i;
	if (sd->menuskill_id != SG_FEEL)
		return;
	i = sd->menuskill_lv-1;
	if (i<0 || i > 2) return; //Bug?
	sd->feel_map[i].index = map[sd->bl.m].index;
	sd->feel_map[i].m = sd->bl.m;
	pc_setglobalreg(sd,feel_var[i],map[sd->bl.m].index);
	
	WFIFOHEAD(fd,packet_len_table[0x20e]);
	WFIFOW(fd,0)=0x20e;
	memcpy(WFIFOP(fd,2),map[sd->bl.m].name, MAP_NAME_LENGTH);
	WFIFOL(fd,26)=sd->bl.id;
	WFIFOW(fd,30)=i;
	WFIFOSET(fd, packet_len_table[0x20e]);
	
	if (sd->bl.m == sd->feel_map[i].m && 
		(i = pc_checkskill(sd,SG_KNOWLEDGE)) > 0)
		sc_start(&sd->bl, SC_KNOWLEDGE, 100, i, skill_get_time(SG_KNOWLEDGE, i));

	sd->menuskill_lv = sd->menuskill_id = 0;
}

/*==========================================
 * Question about Star Glaldiator save map [Komurka]
 *------------------------------------------
 */
void clif_parse_ReqFeel(int fd, struct map_session_data *sd, int skilllv) {
	WFIFOHEAD(fd,packet_len_table[0x253]);
	WFIFOW(fd,0)=0x253;
	WFIFOSET(fd, packet_len_table[0x253]);
	sd->menuskill_id=SG_FEEL;
	sd->menuskill_lv=skilllv;
}

/*==========================================
 * �p�P�b�g�f�o�b�O
 *------------------------------------------
 */
void clif_parse_debug(int fd,struct map_session_data *sd)
{
	int i, cmd, len;
	RFIFOHEAD(fd);

	cmd = RFIFOW(fd,0);
	len = sd?packet_db[sd->packet_ver][cmd].len:RFIFOREST(fd); //With no session, just read the remaining in the buffer.
	ShowDebug("packet debug 0x%4X\n",cmd);
	printf("---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F");
	for(i=0;i<len;i++){
		if((i&15)==0)
			printf("\n%04X ",i);
		printf("%02X ",RFIFOB(fd,i));
	}
	printf("\n");
}

/*==========================================
 * �N���C�A���g����̃p�P�b�g���
 * socket.c��do_parsepacket����Ăяo�����
 *------------------------------------------
 */
int clif_parse(int fd) {
	int packet_len = 0, cmd, packet_ver, dump = 0;
	struct map_session_data *sd;
	RFIFOHEAD(fd);

	if (fd <= 0)
	{	//Just in case, there are some checks for this later down below anyway which should be removed. [Skotlex]
		ShowError("clif_parse: Received invalid session %d\n", fd);
		return 0;
	}

	sd = (struct map_session_data*)session[fd]->session_data;

	// �ڑ����؂�Ă�̂Ō�n��
	if (!chrif_isconnect() && kick_on_disconnect)
	{
		ShowInfo("Closing session #%d (Not connected to Char server)\n", fd);
		if (sd && sd->state.auth)
			clif_quitsave(fd, sd); // the function doesn't send to inter-server/char-server if it is not connected [Yor]
		do_close(fd);
		return 0;
	} else
	if (session[fd]->eof) {
		if (sd && sd->state.autotrade) {
			//Disassociate character from the socket connection.
			session[fd]->session_data = NULL;
			sd->fd = 0;
			ShowInfo("%sCharacter '"CL_WHITE"%s"CL_RESET"' logged off (using @autotrade).\n", (pc_isGM(sd))?"GM ":"",sd->status.name); // Player logout display [Valaris]
		} else if (sd && sd->state.auth) {
			clif_quitsave(fd, sd); // the function doesn't send to inter-server/char-server if it is not connected [Yor]
			if (sd->status.name != NULL)
				ShowInfo("%sCharacter '"CL_WHITE"%s"CL_RESET"' logged off.\n", (pc_isGM(sd))?"GM ":"",sd->status.name); // Player logout display [Valaris]
			else
				ShowInfo("%sCharacter with Account ID '"CL_WHITE"%d"CL_RESET"' logged off.\n", (pc_isGM(sd))?"GM ":"", sd->bl.id); // Player logout display [Yor]
		} else {
			unsigned char *ip = (unsigned char *) &session[fd]->client_addr.sin_addr;
			ShowInfo("Player not identified with IP '"CL_WHITE"%d.%d.%d.%d"CL_RESET"' logged off.\n", ip[0],ip[1],ip[2],ip[3]);
		}
		do_close(fd);
		return 0;
	}

	if (RFIFOREST(fd) < 2)
		return 0;

//	printf("clif_parse: connection #%d, packet: 0x%x (with being read: %d bytes).\n", fd, RFIFOW(fd,0), RFIFOREST(fd));

	cmd = RFIFOW(fd,0);

	// �Ǘ��p�p�P�b�g����
	if (cmd >= 30000) {
		switch(cmd) {
		case 0x7530: { //Why are we letting people know which version we are running?
			WFIFOHEAD(fd, 10);
			WFIFOW(fd,0) = 0x7531;
			WFIFOB(fd,2) = ATHENA_MAJOR_VERSION;
			WFIFOB(fd,3) = ATHENA_MINOR_VERSION;
			WFIFOB(fd,4) = ATHENA_REVISION;
			WFIFOB(fd,5) = ATHENA_RELEASE_FLAG;
			WFIFOB(fd,6) = ATHENA_OFFICIAL_FLAG;
			WFIFOB(fd,7) = ATHENA_SERVER_MAP;
			WFIFOW(fd,8) = ATHENA_MOD_VERSION;
			WFIFOSET(fd,10);
			RFIFOSKIP(fd,2);
			break;
		}
		case 0x7532: // �ڑ��̐ؒf
			ShowWarning("clif_parse: session #%d disconnected for sending packet 0x04%x\n", fd, cmd);
			session[fd]->eof=1;
			break;
		default:
			ShowWarning("Unknown incoming packet (command: 0x%04x, session: %d), disconnecting.\n", cmd, fd);
			session[fd]->eof=1;
			break;
		}
		return 0;
	}

	// get packet version before to parse
	packet_ver = 0;
	if (sd) {
		packet_ver = sd->packet_ver;
		if (packet_ver < 0 || packet_ver > MAX_PACKET_VER) {	// This should never happen unless we have some corrupted memory issues :X [Skotlex]
			session[fd]->eof = 1;
			return 0;
		}
	} else {
		// check authentification packet to know packet version
		packet_ver = clif_guess_PacketVer(fd, 0);
		// check if version is accepted
		if (packet_ver < 5 ||	// reject really old client versions
			(packet_ver <= 9 && (battle_config.packet_ver_flag & 1) == 0) ||	// older than 6sept04
			(packet_ver > 9 && (battle_config.packet_ver_flag & 1<<(packet_ver-9)) == 0) ||
			packet_ver > MAX_PACKET_VER)	// no packet version support yet
		{
			ShowInfo("clif_parse: Disconnecting session #%d for not having latest client version (has version %d).\n", fd, packet_ver);
			WFIFOHEAD(fd, 23);
			WFIFOW(fd,0) = 0x6a;
			WFIFOB(fd,2) = 5; // 05 = Game's EXE is not the latest version
			WFIFOSET(fd,23);
			packet_len = RFIFOREST(fd);
			RFIFOSKIP(fd, packet_len);
			clif_setwaitclose(fd);
			if (session[fd]->func_send)  //socket.c doesn't wants to send the data when left on it's own... [Skotlex]
				session[fd]->func_send(fd);
			return 0;
		}
	}

	// �Q�[���p�ȊO�p�P�b�g���A�F�؂��I����O��0072�ȊO��������A�ؒf����
	if (cmd >= MAX_PACKET_DB || packet_db[packet_ver][cmd].len == 0) {	// if packet is not inside these values: session is incorrect?? or auth packet is unknown
		ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x, %d bytes received), disconnecting session #%d.\n", cmd, RFIFOREST(fd), fd);
		session[fd]->eof = 1;
		return 0;
	}

	// �p�P�b�g�����v�Z
	packet_len = packet_db[packet_ver][cmd].len;
	if (packet_len == -1) {
		if (RFIFOREST(fd) < 4)
			return 0; // �•ϒ��p�P�b�g�Œ����̏��܂Ńf�[�^�����ĂȂ�

		packet_len = RFIFOW(fd,2);
		if (packet_len < 4 || packet_len > 32768) {
			ShowWarning("clif_parse: Packet 0x%04x specifies invalid packet_len (%d), disconnecting session #%d.\n", cmd, packet_len, fd);
			session[fd]->eof =1;
			return 0;
		}
	}
	if ((int)RFIFOREST(fd) < packet_len)
		return 0; // �܂�1�p�P�b�g���f�[�^�������ĂȂ�

	#if DUMP_ALL_PACKETS
		dump = 1;
	#endif

	if (sd && sd->state.auth == 1 && sd->state.waitingdisconnect == 1) { // �ؒf�҂��̏ꍇ�p�P�b�g���������Ȃ�

	} else if (packet_db[packet_ver][cmd].func) {
		if (sd
			|| packet_db[packet_ver][cmd].func == clif_parse_WantToConnection
			|| packet_db[packet_ver][cmd].func == clif_parse_debug
		)	//Only execute the function when there's an sd (except for debug/wanttoconnect packets)
			packet_db[packet_ver][cmd].func(fd, sd);
	} else {
		// �s���ȃp�P�b�g
		if (battle_config.error_log) {
#if DUMP_UNKNOWN_PACKET
			{
				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 wrong 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, "\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 (dump) {
		int i;
		if (fd)
			ShowDebug("\nclif_parse: session #%d, packet 0x%04x, length %d, version %d\n", fd, cmd, packet_len, packet_ver);
		printf("---- 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)
				printf("\n%04X ",i);
			printf("%02X ", RFIFOB(fd,i));
		}
		printf("\n");
		if (sd && sd->state.auth) {
			if (sd->status.name != NULL)
				printf("\nAccount ID %d, character ID %d, player name %s.\n",
			       sd->status.account_id, sd->status.char_id, sd->status.name);
			else
				printf("\nAccount ID %d.\n", sd->bl.id);
		} else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified)
			printf("\nAccount ID %d.\n", sd->bl.id);
	}

	RFIFOSKIP(fd, packet_len);

	return 0;
}

/*==========================================
 * �p�P�b�g�f�[�^�x�[�X�ǂݍ���
 *------------------------------------------
 */
static int packetdb_readdb(void)
{
	FILE *fp;
	char line[1024];
	int ln=0;
	int cmd,i,j,k,packet_ver;
	char *str[64],*p,*str2[64],*p2,w1[64],w2[64];

	struct {
		void (*func)(int, struct map_session_data *);
		char *name;
	} clif_parse_func[]={
		{clif_parse_WantToConnection,"wanttoconnection"},
		{clif_parse_LoadEndAck,"loadendack"},
		{clif_parse_TickSend,"ticksend"},
		{clif_parse_WalkToXY,"walktoxy"},
		{clif_parse_QuitGame,"quitgame"},
		{clif_parse_GetCharNameRequest,"getcharnamerequest"},
		{clif_parse_GlobalMessage,"globalmessage"},
		{clif_parse_MapMove,"mapmove"},
		{clif_parse_ChangeDir,"changedir"},
		{clif_parse_Emotion,"emotion"},
		{clif_parse_HowManyConnections,"howmanyconnections"},
		{clif_parse_ActionRequest,"actionrequest"},
		{clif_parse_Restart,"restart"},
		{clif_parse_Wis,"wis"},
		{clif_parse_GMmessage,"gmmessage"},
		{clif_parse_TakeItem,"takeitem"},
		{clif_parse_DropItem,"dropitem"},
		{clif_parse_UseItem,"useitem"},
		{clif_parse_EquipItem,"equipitem"},
		{clif_parse_UnequipItem,"unequipitem"},
		{clif_parse_NpcClicked,"npcclicked"},
		{clif_parse_NpcBuySellSelected,"npcbuysellselected"},
		{clif_parse_NpcBuyListSend,"npcbuylistsend"},
		{clif_parse_NpcSellListSend,"npcselllistsend"},
		{clif_parse_CreateChatRoom,"createchatroom"},
		{clif_parse_ChatAddMember,"chataddmember"},
		{clif_parse_ChatRoomStatusChange,"chatroomstatuschange"},
		{clif_parse_ChangeChatOwner,"changechatowner"},
		{clif_parse_KickFromChat,"kickfromchat"},
		{clif_parse_ChatLeave,"chatleave"},
		{clif_parse_TradeRequest,"traderequest"},
		{clif_parse_TradeAck,"tradeack"},
		{clif_parse_TradeAddItem,"tradeadditem"},
		{clif_parse_TradeOk,"tradeok"},
		{clif_parse_TradeCancel,"tradecancel"},
		{clif_parse_TradeCommit,"tradecommit"},
		{clif_parse_StopAttack,"stopattack"},
		{clif_parse_PutItemToCart,"putitemtocart"},
		{clif_parse_GetItemFromCart,"getitemfromcart"},
		{clif_parse_RemoveOption,"removeoption"},
		{clif_parse_ChangeCart,"changecart"},
		{clif_parse_StatusUp,"statusup"},
		{clif_parse_SkillUp,"skillup"},
		{clif_parse_UseSkillToId,"useskilltoid"},
		{clif_parse_UseSkillToPos,"useskilltopos"},
		{clif_parse_UseSkillToPosMoreInfo,"useskilltoposinfo"},
		{clif_parse_UseSkillMap,"useskillmap"},
		{clif_parse_RequestMemo,"requestmemo"},
		{clif_parse_ProduceMix,"producemix"},
		{clif_parse_NpcSelectMenu,"npcselectmenu"},
		{clif_parse_NpcNextClicked,"npcnextclicked"},
		{clif_parse_NpcAmountInput,"npcamountinput"},
		{clif_parse_NpcStringInput,"npcstringinput"},
		{clif_parse_NpcCloseClicked,"npccloseclicked"},
		{clif_parse_ItemIdentify,"itemidentify"},
		{clif_parse_SelectArrow,"selectarrow"},
		{clif_parse_AutoSpell,"autospell"},
		{clif_parse_UseCard,"usecard"},
		{clif_parse_InsertCard,"insertcard"},
		{clif_parse_RepairItem,"repairitem"},
		{clif_parse_WeaponRefine,"weaponrefine"},
		{clif_parse_SolveCharName,"solvecharname"},
		{clif_parse_ResetChar,"resetchar"},
		{clif_parse_LGMmessage,"lgmmessage"},
		{clif_parse_MoveToKafra,"movetokafra"},
		{clif_parse_MoveFromKafra,"movefromkafra"},
		{clif_parse_MoveToKafraFromCart,"movetokafrafromcart"},
		{clif_parse_MoveFromKafraToCart,"movefromkafratocart"},
		{clif_parse_CloseKafra,"closekafra"},
		{clif_parse_CreateParty,"createparty"},
		{clif_parse_CreateParty2,"createparty2"},
		{clif_parse_PartyInvite,"partyinvite"},
		{clif_parse_ReplyPartyInvite,"replypartyinvite"},
		{clif_parse_LeaveParty,"leaveparty"},
		{clif_parse_RemovePartyMember,"removepartymember"},
		{clif_parse_PartyChangeOption,"partychangeoption"},
		{clif_parse_PartyMessage,"partymessage"},
		{clif_parse_CloseVending,"closevending"},
		{clif_parse_VendingListReq,"vendinglistreq"},
		{clif_parse_PurchaseReq,"purchasereq"},
		{clif_parse_OpenVending,"openvending"},
		{clif_parse_CreateGuild,"createguild"},
		{clif_parse_GuildCheckMaster,"guildcheckmaster"},
		{clif_parse_GuildRequestInfo,"guildrequestinfo"},
		{clif_parse_GuildChangePositionInfo,"guildchangepositioninfo"},
		{clif_parse_GuildChangeMemberPosition,"guildchangememberposition"},
		{clif_parse_GuildRequestEmblem,"guildrequestemblem"},
		{clif_parse_GuildChangeEmblem,"guildchangeemblem"},
		{clif_parse_GuildChangeNotice,"guildchangenotice"},
		{clif_parse_GuildInvite,"guildinvite"},
		{clif_parse_GuildReplyInvite,"guildreplyinvite"},
		{clif_parse_GuildLeave,"guildleave"},
		{clif_parse_GuildExplusion,"guildexplusion"},
		{clif_parse_GuildMessage,"guildmessage"},
		{clif_parse_GuildRequestAlliance,"guildrequestalliance"},
		{clif_parse_GuildReplyAlliance,"guildreplyalliance"},
		{clif_parse_GuildDelAlliance,"guilddelalliance"},
		{clif_parse_GuildOpposition,"guildopposition"},
		{clif_parse_GuildBreak,"guildbreak"},
		{clif_parse_PetMenu,"petmenu"},
		{clif_parse_CatchPet,"catchpet"},
		{clif_parse_SelectEgg,"selectegg"},
		{clif_parse_SendEmotion,"sendemotion"},
		{clif_parse_ChangePetName,"changepetname"},
		{clif_parse_GMKick,"gmkick"},
		{clif_parse_GMHide,"gmhide"},
		{clif_parse_GMReqNoChat,"gmreqnochat"},
		{clif_parse_GMReqNoChatCount,"gmreqnochatcount"},
		{clif_parse_NoviceDoriDori,"sndoridori"},
		{clif_parse_NoviceExplosionSpirits,"snexplosionspirits"},
		{clif_parse_PMIgnore,"wisexin"},
		{clif_parse_PMIgnoreList,"wisexlist"},
		{clif_parse_PMIgnoreAll,"wisall"},
		{clif_parse_FriendsListAdd,"friendslistadd"},
		{clif_parse_FriendsListRemove,"friendslistremove"},
		{clif_parse_FriendsListReply,"friendslistreply"},
		{clif_parse_GMKillAll,"killall"},
		{clif_parse_Recall,"summon"},
		{clif_parse_GM_Monster_Item,"itemmonster"},
		{clif_parse_Shift,"shift"},
		{clif_parse_Blacksmith,"blacksmith"},
		{clif_parse_Alchemist,"alchemist"},
		{clif_parse_Taekwon,"taekwon"},
		{clif_parse_RankingPk,"rankingpk"},
		{clif_parse_FeelSaveOk,"feelsaveok"},
		{clif_parse_debug,"debug"},

		{NULL,NULL}
	};

	sprintf(line, "%s/packet_db.txt", db_path);
	if( (fp=fopen(line,"r"))==NULL ){
		ShowFatalError("can't read %s\n", line);
		exit(1);
	}

	clif_config.packet_db_ver = MAX_PACKET_VER;
	packet_ver = MAX_PACKET_VER;	// read into packet_db's version by default
	while(fgets(line,1020,fp)){
		if(line[0]=='/' && line[1]=='/')
			continue;
		if (sscanf(line,"%[^:]: %[^\r\n]",w1,w2) == 2) {
			if(strcmpi(w1,"packet_ver")==0) {
				int prev_ver = packet_ver;
				packet_ver = atoi(w2);
				if (packet_ver > MAX_PACKET_VER)
				{	//Check to avoid overflowing. [Skotlex]
					ShowWarning("The packet_db table only has support up to version %d\n", MAX_PACKET_VER);
					break;
				}
				// copy from previous version into new version and continue
				// - indicating all following packets should be read into the newer version
				memcpy(&packet_db[packet_ver], &packet_db[prev_ver], sizeof(packet_db[0]));
				continue;
			} else if(strcmpi(w1,"packet_db_ver")==0) {
				//This is the preferred version.
				if(strcmpi(w2,"default")==0)
					clif_config.packet_db_ver = MAX_PACKET_VER;
				else {
					// to manually set the packet DB version
					clif_config.packet_db_ver = atoi(w2);
					// check for invalid version
					if (clif_config.packet_db_ver > MAX_PACKET_VER ||
						clif_config.packet_db_ver < 0)
						clif_config.packet_db_ver = MAX_PACKET_VER;
				}
				continue;
			}
		}

		memset(str,0,sizeof(str));
		for(j=0,p=line;j<4 && p;j++){
			str[j]=p;
			p=strchr(p,',');
			if(p) *p++=0;
		}
		if(str[0]==NULL)
			continue;
		cmd=strtol(str[0],(char **)NULL,0);
		if(cmd<=0 || cmd>=MAX_PACKET_DB)
			continue;
		if(str[1]==NULL){
			ShowError("packet_db: packet len error\n");
			continue;
		}
		k = atoi(str[1]);
		packet_db[packet_ver][cmd].len = k;

		if(str[2]==NULL){
			packet_db[packet_ver][cmd].func = NULL;
			ln++;
			continue;
		}
		for(j=0;j<sizeof(clif_parse_func)/sizeof(clif_parse_func[0]);j++){
			if(clif_parse_func[j].name != NULL &&
				strcmp(str[2],clif_parse_func[j].name)==0)
			{
				if (packet_db[packet_ver][cmd].func != clif_parse_func[j].func)
				{	//If we are updating a function, we need to zero up the previous one. [Skotlex]
					for(i=0;i<MAX_PACKET_DB;i++){
						if (packet_db[packet_ver][i].func == clif_parse_func[j].func)
						{	
							memset(&packet_db[packet_ver][i], 0, sizeof(struct packet_db));
							break;
						}
					}
				}
				packet_db[packet_ver][cmd].func = clif_parse_func[j].func;
				break;
			}
		}
		// set the identifying cmd for the packet_db version
		if (strcmp(str[2],"wanttoconnection")==0)
			clif_config.connect_cmd[packet_ver] = cmd;
			
		if(str[3]==NULL){
			ShowError("packet_db: packet error\n");
			exit(1);
		}
		for(j=0,p2=str[3];p2;j++){
			str2[j]=p2;
			p2=strchr(p2,':');
			if(p2) *p2++=0;
			k = atoi(str2[j]);
			// if (packet_db[packet_ver][cmd].pos[j] != k && clif_config.prefer_packet_db)	// not used for now
			packet_db[packet_ver][cmd].pos[j] = k;
		}

		ln++;
//		if(packet_db[clif_config.packet_db_ver][cmd].len > 2 /* && packet_db[cmd].pos[0] == 0 */)
//			printf("packet_db ver %d: %d 0x%x %d %s %p\n",packet_ver,ln,cmd,packet_db[packet_ver][cmd].len,str[2],packet_db[packet_ver][cmd].func);
	}
	fclose(fp);
	if (!clif_config.connect_cmd[clif_config.packet_db_ver])
	{	//Locate the nearest version that we still support. [Skotlex]
		for(j = clif_config.packet_db_ver; j >= 0 && !clif_config.connect_cmd[j]; j--);
		
		clif_config.packet_db_ver = j?j:MAX_PACKET_VER;
	}
	ShowStatus("Done reading packet database from '"CL_WHITE"%s"CL_RESET"'. Using default packet version: "CL_WHITE"%d"CL_RESET".\n", "packet_db.txt", clif_config.packet_db_ver);
	return 0;
}

/*==========================================
 *
 *------------------------------------------
 */
int do_init_clif(void) {
#ifndef __WIN32
	int i;
#endif
	
	clif_config.packet_db_ver = -1; // the main packet version of the DB
	memset(clif_config.connect_cmd, 0, sizeof(clif_config.connect_cmd)); //The default connect command will be determined after reading the packet_db [Skotlex]

	memset(packet_db,0,sizeof(packet_db));
	//Using the packet_db file is the only way to set up packets now [Skotlex]
	packetdb_readdb();

	set_defaultparse(clif_parse);
#ifdef __WIN32
	//if (!make_listen_port(map_port)) {
	if (!make_listen_bind(bind_ip,map_port)) {
		ShowFatalError("cant bind game port\n");
		exit(1);
	}
#else
	for(i = 0; i < 10; i++) {
		//if (make_listen_port(map_port))
		if (make_listen_bind(bind_ip,map_port))
			break;
		sleep(20);
	}
	if (i == 10) {
		ShowFatalError("cant bind game port\n");
		exit(1);
	}
#endif

	add_timer_func_list(clif_waitclose, "clif_waitclose");
	add_timer_func_list(clif_clearchar_delay_sub, "clif_clearchar_delay_sub");
	add_timer_func_list(clif_delayquit, "clif_delayquit");
	add_timer_func_list(clif_nighttimer, "clif_nighttimer");

	return 0;
}