summaryrefslogblamecommitdiff
path: root/src/map/status.c
blob: 3e36817c530d3153be38680d50ddf78cb1200c47 (plain) (tree)
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023


























                                                           


                                                                                                                    


















                                                                                                                      
                              


                                                     























                                                                                     
                                                                             



























































































































































































































                                                                                         



                                                               

                                                                
                                                          


                                                                           
                                                                  



                                                                           
  
 






















                                                                                                      
                                             


                                       
                                                                                                           

                          








                                                                                               















                                                                                                          
                                          
         
                              

                          
                            

                     



                                                                                                                               


                                  

                                                             










                                                                                                                                                                                          
                                                                                             
                                                                                                                         





                                                                                                                      


                                          
                                                              



                                                                                                        
                                                                                                           




                                                                                                        
                              
          
                                                                                                  

                                                                             

                                                                                                       
                                                                              




                                                                           

                                     
                 
                                                                              
                                  
                                                                                  
                                  
                                                                                                                                                           


                                  


                                                                                  
                 



                                              






                                                                                         
                                                  




                                                                                                               







                                                                                                                                          
                                            
                  
                                                                                                    



































































































                                                                                                                                             
                                                               
                         
                                                                  





































                                                                                                             

                        




























































































































































































































































































































































                                                                                                                                                                                       


                                                                                                                                         


                                                                

                                                                



                                            

                                                                        





















                                                                                             

                                                          






                                                           

                                                                                                    
                                                               


















                                                                                                   











                                                                   

                                                                                               





























                                                                   
                                                             







































                                                                                                                  

                                                          

                                                                                                           
                                                                                           

                                                                                                           
                                                                                          

































































































                                                                                                            
                                                              
                              
                                                                        


































                                                                                                     
                                                              




































                                                                                             
                                                                                                                                        










                                                                                                      
                                                               
                                                                                                                  
                                                                                                                
                                                                                  

                                                                             

                                                             
                                                                                                    























                                                                                                                                                                  
                                                                           












































                                                                                                                                        

                                                                                   


                                                          
                                                          

                                                 


















































                                                                                                                                        


                                                                                   





                                                          
                                               

















































                                                                                                                    


                                                                       


















                                                         










                                                                         
                  


                                                                           




                                                                                                               
                                                 
                                                                 
                                                 


















                                                                 
                                                                                 

                                            
                                                                           





































                                                                                                                                                          
                                                                                                 


                                               
                                                                      


























                                                                                                                

                                                                                                          
                                                                          










                                                         
                                  
                             









                                                               
                                  
                                                     
                                  
                                                 
                                                                            
                                                       


                                                                                            
                                                                







                                                    
                                  
                             









                                                               
                                  





                                                                                  






                                                    
                                  
                             









                                                               
                                  

                                                                           






                                                     
                                  
                              









                                                                
                                   
                                                       


                                                                                            
                                                                 
                  

                                                                          






                                                    
                                  
                             









                                                               
                                  


                                                                                  


                                                                                            
                                                                







                                                    
                                  
                             









                                                               
                                  
                                                  







                                                      
                                  
                              













                                                                              
                                          
                                                                                       
                                               
                                                 
                                               
                                                      
                                               






                                                      
                                  
                              

















                                                                                  
                                          

                                                                                                             
                                                 
                                               

                                                                            





                                                      
                                  
                              












                                                                             






                                                              
                                  
                                  









                                                                        







                                                    
                                  
                             















                                                                       







                                                      
                                  
                              















                                                                                      
                                                                                                  
                                                        
                                    
                                                     
                                               
                                                   
                                               
                                                 









                                                                                                                                             
                                  
                               
                                
 


                                                               






                                                    
                                  
                             
                                
 

                                                   
                                  
                                                   
                                    
                                                     
                                   
                                                                 
                                   








                                                                            
                                              



                                                                                                                 






                                                      
                                  
                              
                                
 

                                                   
                                  
                                                        
                                  
                                                       
                                                                                                 




                                                                              
                                               
                                               
                                               


                                                                            
                                   

                                                           
                                                       
                                                                








                                                       
                                  
                              
                                
 

                                                   
                                  
                                                   
                                    
                                                     
                                   
                                                                 
                                                             

                                                          






                                                        
                                  
                               
                                
 

                                                   
                                  

                                                                               






                                                        







































                                                                                                      
                                                         

                                                                   
                  






                                                                                                        





                                                                






                                                                                            
                                                 






























                                                                                                                                                                                 
                                                 

                                                                   
                  


                                                                                                       





                                                        












                                                                                     





                                                        








                                                                           
































                                                                                                                     
                                                                           

                                                                          
                                                                                                                  
                                                                                            



                                                                                                                                           






























































































































































































































































































































































































































































































































































































































































































































































                                                                                                                                                                          
                                  

                            
                                














                                                                               
                                                                                                                                         







                                                                                     
                                                     


                             
                              
                                                                
                                   
                                                                                
                                   

                                                                    












                                                                                       


                                                                            
                                  
                                                                                
                                  
                                                                              
                                  
                                                                                
                                  
                                                                                
                                  
                                                                                
                                  
                                                         
                                  
                                                        






























































































                                                                                              
                                                                                                   






                                                                                     
                                                              























































                                                                                                                                                         





                                                                                


                  
                                                           


                               
                                                    
                            
                                                            

                     
 

                                                       


                                                       
                                  
                            



























                                                                             


                      
                                                                 


                             

                                                                              
                       

                           
                                                                             
                       



                                                                             
                      

                         
                      
                                                                             
                       
                       
                                                                             

                       
                                                                             
                       

                                                                          

          





                                                                          
         



                                                       
                                                                                  
                                                             
                                                                                        

          





                                                              
                       

  



                                                                  


                                                                   













                                                                                   
                                                         

                                                                   
                                                        
                       
                                                                                           
                                                          


                                                                   
                                                                               



                                                                                     
                                                       

                                                                  

                                                                            

                                  

                                                                                           


                                                         
                                                                                              

                               

                                                                                        
                                                        

                                                                        
                                    



                                                                               
                                                        

                       


















                                                                                       
  


                                             
                                        




                                                         
                                  

                                             
                                                                                                                       

                                            
                                  
                                                                                                   

                            




                                      








                                                                                                       

          




                                                                                               
 

                             
                                                  







                                                                                                           



                                            




                                                    

                                          
                                
                               
                                                            

                                                      
                               
                              


                                                                                                 
                               








                                                                         




                                                          














































                                                                                                                                      
          
 














                                                                   
                                          


                  

                                        
                                










                                                                            
                                      








                                                                                                                              
                                                                        













                                                               


                                                                         

          





                                                           














                                                                              
                                                                                
                                                                                                          
                                                                                             




                                                               
                                                                


                                                                         
                                       
                                                                
                                                                         
                                                               
                                                                        
                                                                
                                                                         
                                                                  
                                                                           
                                                                   
                                                                            
                                                              
                                                                       
                                                            









                                                                                                     
                                                               
                                                                         
                                                               
                                                                         
                                                               
                                                                         
                                                               
                                                                         

                                       
                                                                              
                                                                 









                                                                                                







                                                                                     









                                                                                                  
                                                              




                                                                              


                                                                           
                                                                                     
                                                                         
                                                                                   
                                                                         
                                                                   
                                                                            
                                                            
                                                                     
                                                                  
                                                                           
                                                               
                                                                        
                                                                
                                                                         
                                                                                    
                                                                       
                                                                                      
                                                                      
                                                                                   









                                                                       


                                                                                   
                                                                           
                                                                       
                                                                       
                                                                 
                                                                           
                                      
                                     
                                                              
























                                                                             
                                                                                                









                                                                       



                                                                                                           

                               

                                                                     
                                                                                   
                                                                         
                                                                   
                                                                            
                                                            
                                                                     
                                                                  
                                                                           
                                                               
                                                                        
                                                                
                                                                         
                                                             
                                                                      
                                                                                    
                                                                       
                                                                                      
                                                                      
                                                                                   

















                                                                                















                                                                                 






                                                                           
                  

                                                                                
      
                                                                
       




                                                                                                      














                                                                   

                                       
                                  


                                               

                                                                   
                                      
                                                                                































                                                                                          











                                                                                          

                                                                                                     



                                                                            



                                            
                                  


                                      


                                                           



                                                                             


















































                                                                                                           
                                                                                                                             














                                                                                                                              
                                                                                                                            



                                          



















                                                                                                                           
                                                                                                                                                


                                                               














                                                                                    






                                                                        





                                                                     
                                                         




                                                                   

                                                 
                          






















                                                                                             






































                                                                            
                                                                      


                                                                                                             









                                                                                                                           



                               
                                                          
                                                                         


                                                                   
                                                                









                                                                                            


                                                                                                            
                                                                                                                                    
                                                                                                    
                                                                                   

                                                                                                                                                                  











































                                                                                                                       







                                                                                             






















                                                                                                                      
                                                                 


















                                                                                   
                                                               

























                                      



                                                                
                                 


                                       








                                                                               
                                                                                           
                                                                           
                                    
                                                                             










































                                                                                         


                                                         
                              
                               


                                                                              



                                                                       
                                                         














                                                              
                               





                                                                                                                                           

                                 
                      
                       

                                
                              
                               
                                             
                                                           
                             
                                                                           
                               
                       



                                 
                                                         

                                                                      
                                                  

                                      
                                                       
                               
























































                                                                                      
                                

                                                   
                                  
                                                    

                                   
                                                                     

                               
                                                    

                                
                                                     

                                 
                                                      

                                
                                                     

                                      
                                                           

                                
                                                     
                               

                                      




                                          
                                               
 



                                    
                          
                                          

                                                                      












                                                                                                    






                                                        
                                  

               


                                                




                                                                                         
                                              

                                                                                              



                                              
                                                          
                                                                                                                         


                                                                              

                  



                                   













                                                                  
                                  
                                       

                            


                                
                                            
                                                                                                     






                                                                 
 
                                                                                        

                                                                                
                                                                                

                                           

                                         























































































































                                                                                                              

                                                                                             

                                                                                                
                                                                                                                                                                             


                                               
                                                                                                        










                                                                                         
                                                                                                                                     





                                                                                     
                                                                                                      


                                                                                                                      
                                                                                       


                                                                                  
                                                                                
                                                                                       
                                                                               




                                                                                      
                                                                                                                             
                                                                                              

                                                                                                                             
 

                                                                                                                                                     




                                                                      

                                                                   
                                          

                                                                                                                    
                                          

                                                                                                                                            
                                                                                          
                                                                                     
                                                  
                                                                                                                                               


                                                                                               
                                                                                                                                      

                                                                                       
                                                                    













                                                                                                         
                                                                                               

                                                                                 
                                                                                                                                       




                                               



                                                                                                                                       
                                                                   
                                                                                                                                  





                                                                                                             

                                                                                                                               
                                                                                    
                                                                                                                                        



                                        
                                                         













                                                                                                              


                                                                                                      
                                                                                           






                                                                                                
                                                                                         







                                                                     
                                                                               







                                                                               
                                                                    
                                                       


                                                                                                                         




                                                                            
                                                                    


                                                                            
                                                                                                             



                                       
                        




                                                                              
                              
                               
                                      






                                      
                                                            


                                      
                                                                     


                                      
                                                        



                                      
                                                    


                                       
                                                     



                                               
                                                                        


                                       
                                                     


                                                                                 
                                                       


                                      
                                                      


                                      
                                                      


                                      
                                                            


                                      
                                                      






                                                                          
                                        

                                                                             
                                        

                                                                           
                                        
                               


                                                                          
                                                            
                                        


                                                                
                                         

                                                               
                                         

                                                               
                                          


                                                                              
                                           

                                                                     
                                           

                                                    
                                           









                                                                                                      
                  











                                                                      
                                  







                                                       
                                              

                            
                                                  
 
                                          
                                            
                                                                                              




                                                                 

                                             










                                                             

                                                                                              





                                  
                                                           
                                                             
                                                           


                                                                                     
                                                                                                                                                          
                                                                                                                        
                                  

                                                                                                      






                                                                    

                                                                                        


                                                                     
                                                                                    










                                                                        


                                                                                                     
 

                                                                                    










                                                                                              
                                                                                                                  





                                            
                                                

                                                                         
                                                  
                                                                                                    




                                                               
                                                                                            

                                                                                   
                                                                                                       



                                  

                                                              
                                                                                                          




                                  


                                                 
                                                  


                                                                                                      

                                  
                                                        
                                                        
                                                                                          










                                                                                 
                                                                                                      







                                                                                                      
                                                                                          
                                 
                                                                      
                                                         
                                                                                   


                                                                  
                                                                                   
                  
                                                                   
                  
                                                                                                            






                                                                                       
                                                                                    
















                                                                               
                                                           










                                                                             
                                                                                                                    





















                                                       

                                                                                                   





                                                    


                                                        
                                                             



























                                                                                                                           
                                                                                                              




                                                                                                         

                                                                              
                                                        
                                                                          

                                                       
                          



                                                                            





                                                                                                                                                                   

                                                                                                                         
                          
                                                                                                                









                                                                                                                  
                                                                                            













                                                                                                     
                                                                                                               





                                          
                                                       
                                       
                                                                         

                                                 

                                                          








                                                                      
                                                                                 
                                                                     

                                                                   







                                                                          
                                                     
                                    

                                                                  







                                                                             

                                                                          









                                                                         
                                                                                 

                                                                    
                                                                  












                                                                          
                                              










                                                                
                                        






                                           
                                             

                                      

                               







                                                                 




                                                                         


                                     





                                                                                                                                                                               



                              
                                                                                                                         

                                                                                                                           
                                                                                   



                                            








                                                                      
                                                                                                     
                                                                                                                   



                              



                                                                                                                                   








                                                      

                                                     










                                                                                                                 
                                            






                                                        

                                                      

                                                           
                                            


                                                    
                                                   
                                                           
                                              
                                                      
                                                  
                                                          
                                                 
                                                         
                                              
                                                      
                                                 
                                                         
                                               
                                                       
                                          
                                                  
                                            
                                                    
                                                 
                                                         
                                                 
                                                         
                                                
                                                        
                                               
































































































































































                                                                                                                                      
                            



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

#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>

#include "pc.h"
#include "map.h"
#include "pet.h"
#include "mob.h"
#include "clif.h"
#include "guild.h"
#include "skill.h"
#include "itemdb.h"
#include "battle.h"
#include "chrif.h"
#include "status.h"

#include "timer.h"
#include "nullpo.h"
#include "script.h"
#include "showmsg.h"

int SkillStatusChangeTable[MAX_SKILL]; //Stores the status that should be associated to this skill.
int StatusIconChangeTable[SC_MAX]; //Stores the icon that should be associated to this status change.
int StatusSkillChangeTable[SC_MAX]; //Stores the skill that should be considered associated to this status change. 

static int max_weight_base[MAX_PC_CLASS];
static int hp_coefficient[MAX_PC_CLASS];
static int hp_coefficient2[MAX_PC_CLASS];
static int hp_sigma_val[MAX_PC_CLASS][MAX_LEVEL];
static int sp_coefficient[MAX_PC_CLASS];
static int aspd_base[MAX_PC_CLASS][20];
#define MAX_REFINE_BONUS 5
static int refinebonus[MAX_REFINE_BONUS][3];	// ���B�{�[�i�X�e�[�u��(refine_db.txt)
int percentrefinery[5][MAX_REFINE+1];	// ���B������(refine_db.txt)
static int atkmods[3][20];	// ����ATK�T�C�Y�C��(size_fix.txt)
static char job_bonus[MAX_PC_CLASS][MAX_LEVEL];

int current_equip_item_index; //Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus]
//we need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only
//to avoid cards exploits

//Initializes the StatusIconChangeTable variable. May seem somewhat slower than directly defining the array,
//but it is much less prone to errors. [Skotlex]
void initChangeTables(void) {
	int i;
	for (i = 0; i < SC_MAX; i++)
		StatusIconChangeTable[i] = SI_BLANK;
	for (i = 0; i < MAX_SKILL; i++)
		SkillStatusChangeTable[i] = -1;
	memset(StatusSkillChangeTable, 0, sizeof(StatusSkillChangeTable));

	//First we define the skill for common ailments. These are used in 
	//skill_additional_effect through sc cards. [Skotlex]
	StatusSkillChangeTable[SC_STONE] =     MG_STONECURSE;
	StatusSkillChangeTable[SC_FREEZE] =    MG_FROSTDIVER;
	StatusSkillChangeTable[SC_STUN] =      NPC_STUNATTACK;
	StatusSkillChangeTable[SC_SLEEP] =     NPC_SLEEPATTACK;
	StatusSkillChangeTable[SC_POISON] =    NPC_POISON;
	StatusSkillChangeTable[SC_CURSE] =     NPC_CURSEATTACK;
	StatusSkillChangeTable[SC_SILENCE] =   NPC_SILENCEATTACK;
	StatusSkillChangeTable[SC_CONFUSION] = DC_WINKCHARM;
	StatusSkillChangeTable[SC_BLIND] =     NPC_BLINDATTACK;
	StatusSkillChangeTable[SC_BLEEDING] =  LK_HEADCRUSH;
	StatusSkillChangeTable[SC_DPOISON] =   NPC_POISON;

#define set_sc(skill, sc, icon) \
	if (SkillStatusChangeTable[skill]==-1) SkillStatusChangeTable[skill] = sc; \
	if (StatusSkillChangeTable[sc]==0) StatusSkillChangeTable[sc] = skill; \
	if (StatusIconChangeTable[sc]==SI_BLANK) StatusIconChangeTable[sc] = icon; 
	
	set_sc(SM_BASH,                 SC_STUN,                SI_BLANK);
	set_sc(SM_PROVOKE,              SC_PROVOKE,             SI_PROVOKE);
	set_sc(SM_MAGNUM,               SC_WATK_ELEMENT,        SI_BLANK);
	set_sc(SM_ENDURE,               SC_ENDURE,              SI_ENDURE);
	set_sc(MG_SIGHT,                SC_SIGHT,               SI_BLANK);
	set_sc(MG_SAFETYWALL,           SC_SAFETYWALL,          SI_BLANK);
	set_sc(MG_FROSTDIVER,           SC_FREEZE,              SI_BLANK);
	set_sc(MG_STONECURSE,           SC_STONE,               SI_BLANK);
	set_sc(AL_RUWACH,               SC_RUWACH,              SI_BLANK);
	set_sc(AL_INCAGI,               SC_INCREASEAGI,         SI_INCREASEAGI);
	set_sc(AL_DECAGI,               SC_DECREASEAGI,         SI_DECREASEAGI);
	set_sc(AL_CRUCIS,               SC_SIGNUMCRUCIS,        SI_SIGNUMCRUCIS);
	set_sc(AL_ANGELUS,              SC_ANGELUS,             SI_ANGELUS);
	set_sc(AL_BLESSING,             SC_BLESSING,            SI_BLESSING);
	set_sc(AC_CONCENTRATION,        SC_CONCENTRATE,         SI_CONCENTRATE);
	set_sc(TF_HIDING,               SC_HIDING,              SI_HIDING);
	set_sc(TF_POISON,               SC_POISON,              SI_BLANK);
	set_sc(KN_TWOHANDQUICKEN,       SC_TWOHANDQUICKEN,      SI_TWOHANDQUICKEN);
	set_sc(KN_AUTOCOUNTER,          SC_AUTOCOUNTER,         SI_BLANK);
	set_sc(PR_IMPOSITIO,            SC_IMPOSITIO,           SI_IMPOSITIO);
	set_sc(PR_SUFFRAGIUM,           SC_SUFFRAGIUM,          SI_SUFFRAGIUM);
	set_sc(PR_ASPERSIO,             SC_ASPERSIO,            SI_ASPERSIO);
	set_sc(PR_BENEDICTIO,           SC_BENEDICTIO,          SI_BENEDICTIO);
	set_sc(PR_SLOWPOISON,           SC_SLOWPOISON,          SI_SLOWPOISON);
	set_sc(PR_KYRIE,                SC_KYRIE,	              SI_KYRIE);
	set_sc(PR_MAGNIFICAT,           SC_MAGNIFICAT,          SI_MAGNIFICAT);
	set_sc(PR_GLORIA,               SC_GLORIA,              SI_GLORIA);
	set_sc(PR_LEXDIVINA,            SC_SILENCE,	           SI_BLANK);
	set_sc(PR_LEXAETERNA,           SC_AETERNA,             SI_AETERNA);
	set_sc(WZ_METEOR,               SC_STUN,                SI_BLANK);
	set_sc(WZ_VERMILION,            SC_BLIND,               SI_BLANK);
	set_sc(WZ_FROSTNOVA,            SC_FREEZE,              SI_BLANK);
	set_sc(WZ_STORMGUST,            SC_FREEZE,              SI_BLANK);
	set_sc(WZ_QUAGMIRE,             SC_QUAGMIRE,            SI_QUAGMIRE);
	set_sc(BS_ADRENALINE,           SC_ADRENALINE,          SI_ADRENALINE);
	set_sc(BS_WEAPONPERFECT,        SC_WEAPONPERFECTION,    SI_WEAPONPERFECTION);
	set_sc(BS_OVERTHRUST,           SC_OVERTHRUST,          SI_OVERTHRUST);
	set_sc(BS_MAXIMIZE,             SC_MAXIMIZEPOWER,       SI_MAXIMIZEPOWER);
	set_sc(HT_LANDMINE,             SC_STUN,                SI_BLANK);
	set_sc(HT_SANDMAN,              SC_SLEEP,               SI_BLANK);
	set_sc(HT_FLASHER,              SC_BLIND,               SI_BLANK);
	set_sc(HT_FREEZINGTRAP,         SC_FREEZE,              SI_BLANK);
	set_sc(AS_CLOAKING,             SC_CLOAKING,	           SI_CLOAKING);
	set_sc(AS_SONICBLOW,            SC_STUN,	              SI_BLANK);
	set_sc(AS_GRIMTOOTH,            SC_SLOWDOWN,            SI_BLANK);
	set_sc(AS_ENCHANTPOISON,        SC_ENCPOISON,	        SI_ENCPOISON);
	set_sc(AS_POISONREACT,          SC_POISONREACT,         SI_POISONREACT);
	set_sc(AS_VENOMDUST,            SC_POISON,              SI_BLANK);
	set_sc(AS_SPLASHER,             SC_SPLASHER,            SI_BLANK);
	set_sc(NV_TRICKDEAD,            SC_TRICKDEAD,           SI_TRICKDEAD);
	set_sc(SM_AUTOBERSERK,          SC_AUTOBERSERK,         SI_BLANK);
	set_sc(TF_SPRINKLESAND,         SC_BLIND,               SI_BLANK);
	set_sc(TF_THROWSTONE,           SC_STUN,                SI_BLANK);
	set_sc(MC_LOUD,                 SC_LOUD,                SI_LOUD);
	set_sc(MG_ENERGYCOAT,           SC_ENERGYCOAT,          SI_ENERGYCOAT);
	set_sc(NPC_POISON,              SC_POISON,              SI_BLANK);
	set_sc(NPC_BLINDATTACK,         SC_BLIND,               SI_BLANK);
	set_sc(NPC_SILENCEATTACK,       SC_SILENCE,             SI_BLANK);
	set_sc(NPC_STUNATTACK,          SC_STUN,                SI_BLANK);
	set_sc(NPC_PETRIFYATTACK,       SC_STONE,               SI_BLANK);
	set_sc(NPC_CURSEATTACK,         SC_CURSE,               SI_BLANK);
	set_sc(NPC_SLEEPATTACK,         SC_SLEEP,               SI_BLANK);
	set_sc(NPC_KEEPING,             SC_KEEPING,             SI_BLANK);
	set_sc(NPC_DARKBLESSING,        SC_COMA,                SI_BLANK);
	set_sc(NPC_BARRIER,             SC_BARRIER,             SI_BLANK);
	set_sc(NPC_LICK,                SC_STUN,                SI_BLANK);
	set_sc(NPC_HALLUCINATION,       SC_HALLUCINATION,       SI_HALLUCINATION);
	set_sc(NPC_REBIRTH,             SC_KAIZEL,              SI_KAIZEL);
	set_sc(RG_RAID,                 SC_STUN,                SI_BLANK);
	set_sc(RG_STRIPWEAPON,          SC_STRIPWEAPON,         SI_STRIPWEAPON);
	set_sc(RG_STRIPSHIELD,          SC_STRIPSHIELD,         SI_STRIPSHIELD);
	set_sc(RG_STRIPARMOR,           SC_STRIPARMOR,          SI_STRIPARMOR);
	set_sc(RG_STRIPHELM,            SC_STRIPHELM,           SI_STRIPHELM);
	set_sc(AM_ACIDTERROR,           SC_BLEEDING,            SI_BLEEDING);
	set_sc(AM_CP_WEAPON,            SC_CP_WEAPON,           SI_CP_WEAPON);
	set_sc(AM_CP_SHIELD,            SC_CP_SHIELD,           SI_CP_SHIELD);
	set_sc(AM_CP_ARMOR,             SC_CP_ARMOR,            SI_CP_ARMOR);
	set_sc(AM_CP_HELM,              SC_CP_HELM,             SI_CP_HELM);
	set_sc(CR_AUTOGUARD,            SC_AUTOGUARD,           SI_AUTOGUARD);
	set_sc(CR_SHIELDCHARGE,         SC_STUN,                SI_AUTOGUARD);
	set_sc(CR_REFLECTSHIELD,        SC_REFLECTSHIELD,       SI_REFLECTSHIELD);
	set_sc(CR_HOLYCROSS,            SC_BLIND,               SI_BLANK);
	set_sc(CR_GRANDCROSS,           SC_BLIND,               SI_BLANK);
	set_sc(CR_DEVOTION,             SC_DEVOTION,            SI_DEVOTION);
	set_sc(CR_PROVIDENCE,           SC_PROVIDENCE,          SI_PROVIDENCE);
	set_sc(CR_DEFENDER,             SC_DEFENDER,            SI_DEFENDER);
	set_sc(CR_SPEARQUICKEN,         SC_SPEARSQUICKEN,       SI_SPEARQUICKEN);
	set_sc(MO_STEELBODY,            SC_STEELBODY,           SI_STEELBODY);
	set_sc(MO_BLADESTOP,            SC_BLADESTOP_WAIT,      SI_BLANK);
	set_sc(MO_EXPLOSIONSPIRITS,     SC_EXPLOSIONSPIRITS,    SI_EXPLOSIONSPIRITS);
	set_sc(MO_EXTREMITYFIST,        SC_EXTREMITYFIST,       SI_BLANK);
	set_sc(SA_MAGICROD,             SC_MAGICROD,            SI_BLANK);
	set_sc(SA_AUTOSPELL,            SC_AUTOSPELL,           SI_AUTOSPELL);
	set_sc(SA_FLAMELAUNCHER,        SC_FIREWEAPON,          SI_FIREWEAPON);
	set_sc(SA_FROSTWEAPON,          SC_WATERWEAPON,         SI_WATERWEAPON);
	set_sc(SA_LIGHTNINGLOADER,      SC_WINDWEAPON,          SI_WINDWEAPON);
	set_sc(SA_SEISMICWEAPON,        SC_EARTHWEAPON,         SI_EARTHWEAPON);
	set_sc(SA_VOLCANO,              SC_VOLCANO,             SI_BLANK);
	set_sc(SA_DELUGE,               SC_DELUGE,              SI_BLANK);
	set_sc(SA_VIOLENTGALE,          SC_VIOLENTGALE,         SI_BLANK);
	set_sc(SA_LANDPROTECTOR,        SC_LANDPROTECTOR,       SI_BLANK);
	set_sc(SA_REVERSEORCISH,        SC_ORCISH,              SI_BLANK);
	set_sc(SA_COMA,                 SC_COMA,                SI_BLANK);
	set_sc(BD_LULLABY,              SC_LULLABY,             SI_BLANK);
	set_sc(BD_RICHMANKIM,           SC_RICHMANKIM,          SI_BLANK);
	set_sc(BD_ETERNALCHAOS,         SC_ETERNALCHAOS,        SI_BLANK);
	set_sc(BD_DRUMBATTLEFIELD,      SC_DRUMBATTLE,          SI_BLANK);
	set_sc(BD_RINGNIBELUNGEN,       SC_NIBELUNGEN,          SI_BLANK);
	set_sc(BD_ROKISWEIL,            SC_ROKISWEIL,           SI_BLANK);
	set_sc(BD_INTOABYSS,            SC_INTOABYSS,           SI_BLANK);
	set_sc(BD_SIEGFRIED,            SC_SIEGFRIED,           SI_BLANK);
	set_sc(BA_FROSTJOKE,            SC_FREEZE,              SI_BLANK);
	set_sc(BA_WHISTLE,              SC_WHISTLE,             SI_BLANK);
	set_sc(BA_ASSASSINCROSS,        SC_ASSNCROS,            SI_BLANK);
	set_sc(BA_POEMBRAGI,            SC_POEMBRAGI,           SI_BLANK);
	set_sc(BA_APPLEIDUN,            SC_APPLEIDUN,           SI_BLANK);
	set_sc(DC_UGLYDANCE,            SC_UGLYDANCE,           SI_BLANK);
	set_sc(DC_SCREAM,               SC_STUN,                SI_BLANK);
	set_sc(DC_HUMMING,              SC_HUMMING,             SI_BLANK);
	set_sc(DC_DONTFORGETME,         SC_DONTFORGETME,        SI_BLANK);
	set_sc(DC_FORTUNEKISS,          SC_FORTUNE,             SI_BLANK);
	set_sc(DC_SERVICEFORYOU,        SC_SERVICE4U,           SI_BLANK);
	set_sc(NPC_DARKCROSS,           SC_BLIND,               SI_BLANK);
	set_sc(NPC_GRANDDARKNESS,       SC_BLIND,               SI_BLANK);
	set_sc(NPC_STOP,                SC_STOP,                SI_BLANK);
	set_sc(NPC_BREAKWEAPON,         SC_BROKENWEAPON,        SI_BROKENWEAPON);
	set_sc(NPC_BREAKARMOR,          SC_BROKENARMOR,         SI_BROKENARMOR);
	set_sc(LK_AURABLADE,            SC_AURABLADE,           SI_AURABLADE);
	set_sc(LK_PARRYING,             SC_PARRYING,            SI_PARRYING);
	set_sc(LK_CONCENTRATION,        SC_CONCENTRATION,       SI_CONCENTRATION);
	set_sc(LK_TENSIONRELAX,         SC_TENSIONRELAX,        SI_TENSIONRELAX);
	set_sc(LK_BERSERK,              SC_BERSERK,             SI_BERSERK);
	set_sc(LK_FURY,                 SC_FURY,                SI_FURY);
	set_sc(HP_ASSUMPTIO,            SC_ASSUMPTIO,           SI_ASSUMPTIO);
	set_sc(HP_BASILICA,             SC_BASILICA,            SI_BLANK);
	set_sc(HW_MAGICPOWER,           SC_MAGICPOWER,          SI_MAGICPOWER);
	set_sc(PA_SACRIFICE,            SC_SACRIFICE,           SI_BLANK);
	set_sc(PA_GOSPEL,               SC_GOSPEL,              SI_BLANK);
	set_sc(CH_TIGERFIST,            SC_STOP,                SI_BLANK);
	set_sc(ASC_EDP,                 SC_EDP,                 SI_EDP);
	set_sc(SN_SIGHT,                SC_TRUESIGHT,           SI_TRUESIGHT);
	set_sc(SN_WINDWALK,             SC_WINDWALK,            SI_WINDWALK);
	set_sc(WS_MELTDOWN,             SC_MELTDOWN,            SI_MELTDOWN);
	set_sc(WS_CARTBOOST,            SC_CARTBOOST,           SI_CARTBOOST);
	set_sc(ST_CHASEWALK,            SC_CHASEWALK,           SI_CHASEWALK);
	set_sc(ST_REJECTSWORD,          SC_REJECTSWORD,         SI_REJECTSWORD);
	set_sc(ST_REJECTSWORD,          SC_AUTOCOUNTER,         SI_BLANK);
	set_sc(CG_MOONLIT,              SC_MOONLIT,             SI_MOONLIT);
	set_sc(CG_MARIONETTE,           SC_MARIONETTE,          SI_MARIONETTE);
	set_sc(CG_MARIONETTE,           SC_MARIONETTE2,         SI_MARIONETTE2);
	set_sc(LK_SPIRALPIERCE,         SC_STOP,                SI_BLANK);
	set_sc(LK_HEADCRUSH,            SC_BLEEDING,            SI_BLEEDING);
	set_sc(LK_JOINTBEAT,            SC_JOINTBEAT,           SI_BLANK);
	set_sc(HW_NAPALMVULCAN,         SC_CURSE,               SI_BLANK);
	set_sc(PF_MINDBREAKER,          SC_MINDBREAKER,         SI_BLANK);
	set_sc(PF_MEMORIZE,             SC_MEMORIZE,            SI_BLANK);
	set_sc(PF_FOGWALL,              SC_FOGWALL,             SI_BLANK);
	set_sc(PF_SPIDERWEB,            SC_SPIDERWEB,           SI_BLANK);
	set_sc(WE_BABY,                 SC_BABY,                SI_BLANK);
	set_sc(TK_RUN,                  SC_RUN,                 SI_BLANK);
	set_sc(TK_RUN,                  SC_SPURT,               SI_SPURT);
	set_sc(TK_READYSTORM,           SC_READYSTORM,          SI_READYSTORM);
	set_sc(TK_READYDOWN,            SC_READYDOWN,           SI_READYDOWN);
	set_sc(TK_DOWNKICK,             SC_STUN,                SI_BLANK);
	set_sc(TK_READYTURN,            SC_READYTURN,           SI_READYTURN);
	set_sc(TK_READYCOUNTER,         SC_READYCOUNTER,        SI_READYCOUNTER);
	set_sc(TK_DODGE,                SC_DODGE,               SI_DODGE);
	set_sc(TK_SPTIME,               SC_TKDORI,              SI_BLANK);
	set_sc(TK_SEVENWIND,            SC_GHOSTWEAPON,         SI_GHOSTWEAPON);
	set_sc(TK_SEVENWIND,            SC_SHADOWWEAPON,        SI_SHADOWWEAPON);
	set_sc(SG_SUN_WARM,             SC_WARM,                SI_WARM);
	set_sc(SG_MOON_WARM,            SC_WARM,                SI_WARM);
	set_sc(SG_STAR_WARM,            SC_WARM,                SI_WARM);
	set_sc(SG_SUN_COMFORT,          SC_SUN_COMFORT,         SI_SUN_COMFORT);
	set_sc(SG_MOON_COMFORT,         SC_MOON_COMFORT,        SI_MOON_COMFORT);
	set_sc(SG_STAR_COMFORT,         SC_STAR_COMFORT,        SI_STAR_COMFORT);
	set_sc(SG_FUSION,               SC_FUSION,              SI_BLANK);
	set_sc(BS_ADRENALINE2,          SC_ADRENALINE2,         SI_ADRENALINE2);
	set_sc(SL_KAIZEL,               SC_KAIZEL,              SI_KAIZEL);
	set_sc(SL_KAAHI,                SC_KAAHI,               SI_KAAHI);
	set_sc(SL_KAUPE,                SC_KAUPE,               SI_KAUPE);
	set_sc(SL_KAITE,                SC_KAITE,               SI_KAITE);
	set_sc(SL_STUN,                 SC_STUN,                SI_BLANK);
	set_sc(SL_SWOO,                 SC_SWOO,                SI_BLANK);
	set_sc(SL_SKE,                  SC_SKE,                 SI_BLANK);
	set_sc(SL_SKA,                  SC_SKA,                 SI_BLANK);
	set_sc(ST_PRESERVE,             SC_PRESERVE,            SI_PRESERVE);
	set_sc(PF_DOUBLECASTING,        SC_DOUBLECAST,          SI_DOUBLECAST);
	set_sc(HW_GRAVITATION,          SC_GRAVITATION,         SI_BLANK);
	set_sc(WS_CARTTERMINATION,      SC_STUN,                SI_BLANK);
	set_sc(WS_OVERTHRUSTMAX,        SC_MAXOVERTHRUST,       SI_MAXOVERTHRUST);
	set_sc(CG_LONGINGFREEDOM,       SC_LONGING,             SI_BLANK);
	set_sc(CG_HERMODE,              SC_HERMODE,             SI_BLANK);
	set_sc(SL_HIGH,                 SC_SPIRIT,              SI_SPIRIT);
	set_sc(KN_ONEHAND,              SC_ONEHAND,             SI_ONEHAND);
	set_sc(CR_SHRINK,               SC_SHRINK,              SI_SHRINK);
	set_sc(RG_CLOSECONFINE,         SC_CLOSECONFINE2,       SI_CLOSECONFINE2);
	set_sc(RG_CLOSECONFINE,         SC_CLOSECONFINE,        SI_CLOSECONFINE);
	set_sc(WZ_SIGHTBLASTER,         SC_SIGHTBLASTER,        SI_SIGHTBLASTER);
	set_sc(DC_WINKCHARM,            SC_WINKCHARM,           SI_WINKCHARM);
	set_sc(MO_BALKYOUNG,            SC_STUN,                SI_BLANK);

  	// Storing the target job rather than simply SC_SPIRIT simplifies code later on.
	SkillStatusChangeTable[SL_ALCHEMIST] =   MAPID_ALCHEMIST,
	SkillStatusChangeTable[SL_MONK] =        MAPID_MONK,
	SkillStatusChangeTable[SL_STAR] =        MAPID_STAR_GLADIATOR,
	SkillStatusChangeTable[SL_SAGE] =        MAPID_SAGE,
	SkillStatusChangeTable[SL_CRUSADER] =    MAPID_CRUSADER,
	SkillStatusChangeTable[SL_SUPERNOVICE] = MAPID_SUPER_NOVICE,
	SkillStatusChangeTable[SL_KNIGHT] =      MAPID_KNIGHT,
	SkillStatusChangeTable[SL_WIZARD] =      MAPID_WIZARD,
	SkillStatusChangeTable[SL_PRIEST] =      MAPID_PRIEST,
	SkillStatusChangeTable[SL_BARDDANCER] =  MAPID_BARDDANCER,
	SkillStatusChangeTable[SL_ROGUE] =       MAPID_ROGUE,
	SkillStatusChangeTable[SL_ASSASIN] =     MAPID_ASSASSIN,
	SkillStatusChangeTable[SL_BLACKSMITH] =  MAPID_BLACKSMITH,
	SkillStatusChangeTable[SL_HUNTER] =      MAPID_HUNTER,
	SkillStatusChangeTable[SL_SOULLINKER] =  MAPID_SOUL_LINKER,

	//Status that don't have a skill associated.
	StatusIconChangeTable[SC_WEIGHT50 ] =   SI_WEIGHT50;
	StatusIconChangeTable[SC_WEIGHT90] =    SI_WEIGHT90;
	StatusIconChangeTable[SC_ASPDPOTION0] = SI_ASPDPOTION;
	StatusIconChangeTable[SC_ASPDPOTION1] = SI_ASPDPOTION;
	StatusIconChangeTable[SC_ASPDPOTION2] = SI_ASPDPOTION;
	StatusIconChangeTable[SC_ASPDPOTION3] = SI_ASPDPOTION;
	StatusIconChangeTable[SC_SPEEDUP0] =    SI_SPEEDPOTION;
	StatusIconChangeTable[SC_SPEEDUP1] =    SI_SPEEDPOTION;
	StatusIconChangeTable[SC_MIRACLE] =    SI_SPIRIT;
	
	//Guild skills don't fit due to their range being beyond MAX_SKILL
	StatusIconChangeTable[SC_GUILDAURA] =    SI_GUILDAURA;
	StatusIconChangeTable[SC_BATTLEORDERS] = SI_BATTLEORDERS;
#undef set_sc

	if (!battle_config.display_hallucination) //Disable Hallucination.
		StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
}

/*==========================================
 * ���B�{�[�i�X
 *------------------------------------------
 */
int status_getrefinebonus(int lv,int type)
{
	if (lv >= 0 && lv < 5 && type >= 0 && type < 3)
		return refinebonus[lv][type];
	return 0;
}

/*==========================================
 * Checks whether the src can use the skill on the target,
 * taking into account status/option of both source/target. [Skotlex]
 * flag: 1 to indicate this call is done after the casting (target already selected)
 * src MAY be null to indicate we shouldn't check it, this is a ground-based skill attack.
 * target MAY Be null, in which case the checks are only to see 
 * whether the source can cast or not the skill on the ground.
 *------------------------------------------
 */
int status_check_skilluse(struct block_list *src, struct block_list *target, int skill_num, int flag)
{
	int mode, race, hide_flag;
	struct status_change *sc=NULL, *tsc;

	if (src && status_isdead(src))
		return 0;
	if (target && status_isdead(target) && skill_num != ALL_RESURRECTION && skill_num != PR_REDEMPTIO)
		return 0;
	
	if (skill_num == PA_PRESSURE && flag) {
	//Once Gloria Domini has been casted, there's nothing you can do to stop it. [Skotlex]
	//- Except hiding from it.
		tsc = target?status_get_sc(target):NULL;
		if(tsc && tsc->option&OPTION_HIDE)
			return 0;
		return 1;
	}

	mode = src?status_get_mode(src):MD_CANATTACK;
	
	if (!skill_num && !(mode&MD_CANATTACK))
		return 0; //This mode is only needed for melee attacking.
	
	if (((src && map_getcell(src->m,src->x,src->y,CELL_CHKBASILICA)) ||
		(target && target != src && map_getcell(target->m,target->x,target->y,CELL_CHKBASILICA)))
		&& !(mode&MD_BOSS))
	{	//Basilica Check
		if (!skill_num) return 0;
		race = skill_get_inf(skill_num);
		if (race&INF_ATTACK_SKILL)
			return 0;
		if (race&INF_GROUND_SKILL && skill_get_unit_target(skill_num)&BCT_ENEMY)
			return 0;
	}	
	if (src) sc = status_get_sc(src);
	
	if(sc && sc->opt1 >0)
		return 0;
	
	if(sc && sc->count)
	{
		if (
			(sc->data[SC_TRICKDEAD].timer != -1 && skill_num != NV_TRICKDEAD)
			|| (sc->data[SC_AUTOCOUNTER].timer != -1 && skill_num != KN_AUTOCOUNTER)
			|| (sc->data[SC_GOSPEL].timer != -1 && sc->data[SC_GOSPEL].val4 == BCT_SELF && skill_num != PA_GOSPEL)
			|| sc->data[SC_GRAVITATION].timer != -1
		)
			return 0;

		if (sc->data[SC_BLADESTOP].timer != -1) {
			switch (sc->data[SC_BLADESTOP].val1)
			{
				case 1: return 0;
				case 2: if (skill_num != MO_FINGEROFFENSIVE) return 0; break;
				case 3: if (skill_num != MO_FINGEROFFENSIVE && skill_num != MO_INVESTIGATE) return 0; break;
				case 4: if (skill_num != MO_FINGEROFFENSIVE && skill_num != MO_INVESTIGATE && skill_num != MO_CHAINCOMBO) return 0; break;
				case 5: if (skill_num != MO_FINGEROFFENSIVE && skill_num != MO_INVESTIGATE && skill_num != MO_CHAINCOMBO && skill_num!=MO_EXTREMITYFIST) return 0; break;
				default: return 0;
			}
		}
		if (skill_num)
		{	//Skills blocked through status changes...
			if ((sc->data[SC_VOLCANO].timer != -1 && skill_num == WZ_ICEWALL) ||
				(sc->data[SC_ROKISWEIL].timer != -1 && skill_num != BD_ADAPTATION && !(mode&MD_BOSS)) ||
				(sc->data[SC_MARIONETTE].timer != -1 && skill_num != CG_MARIONETTE) ||
				(sc->data[SC_MARIONETTE2].timer != -1 && skill_num == CG_MARIONETTE) ||
				(sc->data[SC_HERMODE].timer != -1 && skill_get_inf(skill_num) & INF_SUPPORT_SKILL) ||
				sc->data[SC_SILENCE].timer != -1 || sc->data[SC_STEELBODY].timer != -1 ||
				sc->data[SC_BERSERK].timer != -1 || sc->data[SC_SKA].timer != -1 ||
				sc->data[SC_NOCHAT].timer != -1
			)
				return 0;

			if (sc->data[SC_DANCING].timer != -1)
			{
				if (skill_num != BD_ADAPTATION && skill_num != CG_LONGINGFREEDOM
					&& skill_num != BA_MUSICALSTRIKE && skill_num != DC_THROWARROW)
					return 0;
				if (sc->data[SC_DANCING].val1 == CG_HERMODE && skill_num == BD_ADAPTATION)
					return 0;	//Can't amp out of Wand of Hermode :/ [Skotlex]
			}
		}
	}

	if (sc && sc->option)
	{
		if (sc->option&OPTION_HIDE && skill_num != TF_HIDING && skill_num != AS_GRIMTOOTH
			&& skill_num != RG_BACKSTAP && skill_num != RG_RAID)
			return 0;
//		if (sc->option&OPTION_CLOAK && skill_num == TF_HIDING)
//			return 0; //Latest reports indicate Hiding is usable while Cloaking. [Skotlex]
		if (sc->option&OPTION_CHASEWALK && skill_num != ST_CHASEWALK)
			return 0;
	}
	if (target == NULL || target == src) //No further checking needed.
		return 1;

	tsc = status_get_sc(target);
	if(tsc && tsc->count)
	{	
		if (!(mode & MD_BOSS) && tsc->data[SC_TRICKDEAD].timer != -1)
			return 0;
		if(skill_num == WZ_STORMGUST && tsc->data[SC_FREEZE].timer != -1)
			return 0;
		if(skill_num == PR_LEXAETERNA && (tsc->data[SC_FREEZE].timer != -1 || (tsc->data[SC_STONE].timer != -1 && tsc->data[SC_STONE].val2 == 0)))
			return 0;
	}

	race = src?status_get_race(src):0; 
	//If targetting, cloak+hide protect you, otherwise only hiding does.
	hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK);
		
 	//You cannot hide from ground skills.
	if(skill_get_pl(skill_num) == 2)
		hide_flag &= ~OPTION_HIDE;
	
	switch (target->type)
	{
	case BL_PC:
		{
			struct map_session_data *sd = (struct map_session_data*) target;
			if (pc_isinvisible(sd))
				return 0;
			if (tsc->option&hide_flag
				&& (sd->state.perfect_hiding || !(race == 4 || race == 6 || mode&MD_DETECTOR))
				&& !(mode&MD_BOSS))
				return 0;
		}
		break;
	case BL_ITEM:	//Allow targetting of items to pick'em up (or in the case of mobs, to loot them).
		//TODO: Would be nice if this could be used to judge whether the player can or not pick up the item it targets. [Skotlex]
		if (mode&MD_LOOTER)
			return 1;
		else
			return 0;
	default:
		//Check for chase-walk/hiding/cloaking opponents.
		if (tsc && !(mode&MD_BOSS))
		{
			if (tsc->option&hide_flag && !(race == 4 || race == 6 || mode&MD_DETECTOR))
				return 0;
		}
	}
	return 1;
}

//Skotlex: Calculates the stats of the given pet.
int status_calc_pet(struct map_session_data *sd, int first)
{
	struct pet_data *pd;
	
	nullpo_retr(0, sd);
	if (sd->status.pet_id == 0 || sd->pd == NULL)
		return 1;

	pd = sd->pd;
	
	if (battle_config.pet_lv_rate && pd->status)
	{
		sd->pet.level = sd->status.base_level*battle_config.pet_lv_rate/100;
		if (sd->pet.level < 0)
			sd->pet.level = 1;
		if (pd->status->level != sd->pet.level || first)
		{
			if (!first) //Lv Up animation
				clif_misceffect(&pd->bl, 0);
			pd->status->level = sd->pet.level;
			pd->status->atk1 = (pd->db->atk1*pd->status->level)/pd->db->lv;
			pd->status->atk2 = (pd->db->atk2*pd->status->level)/pd->db->lv;
			pd->status->str = (pd->db->str*pd->status->level)/pd->db->lv;
			pd->status->agi = (pd->db->agi*pd->status->level)/pd->db->lv;
			pd->status->vit = (pd->db->vit*pd->status->level)/pd->db->lv;
			pd->status->int_ = (pd->db->int_*pd->status->level)/pd->db->lv;
			pd->status->dex = (pd->db->dex*pd->status->level)/pd->db->lv;
			pd->status->luk = (pd->db->luk*pd->status->level)/pd->db->lv;
		
			if (pd->status->atk1 > battle_config.pet_max_atk1) pd->status->atk1 = battle_config.pet_max_atk1;
			if (pd->status->atk2 > battle_config.pet_max_atk2) pd->status->atk2 = battle_config.pet_max_atk2;

			if (pd->status->str > battle_config.pet_max_stats) pd->status->str = battle_config.pet_max_stats;
			else if (pd->status->str < 1) pd->status->str = 1;
			if (pd->status->agi > battle_config.pet_max_stats) pd->status->agi = battle_config.pet_max_stats;
			else if (pd->status->agi < 1) pd->status->agi = 1;
			if (pd->status->vit > battle_config.pet_max_stats) pd->status->vit = battle_config.pet_max_stats;
			else if (pd->status->vit < 1) pd->status->vit = 1;
			if (pd->status->int_ > battle_config.pet_max_stats) pd->status->int_ = battle_config.pet_max_stats;
			else if (pd->status->int_ < 1) pd->status->int_ = 1;
			if (pd->status->dex > battle_config.pet_max_stats) pd->status->dex = battle_config.pet_max_stats;
			else if (pd->status->dex < 1) pd->status->dex = 1;
			if (pd->status->luk > battle_config.pet_max_stats) pd->status->luk = battle_config.pet_max_stats;
			else if (pd->status->luk < 1) pd->status->luk = 1;

			if (!first)	//Not done the first time because the pet is not visible yet
				clif_send_petstatus(sd);
		}
	}
	//Support rate modifier (1000 = 100%)
	pd->rate_fix = 1000*(sd->pet.intimate - battle_config.pet_support_min_friendly)/(1000- battle_config.pet_support_min_friendly) +500;
	if(battle_config.pet_support_rate != 100)
		pd->rate_fix = pd->rate_fix*battle_config.pet_support_rate/100;
	return 0;
}	

/*==========================================
 * �p�����[�^�v�Z
 * first==0�̎��A�v�Z�Ώۂ̃p�����[�^���Ăяo���O����
 * �� �������ꍇ������send���邪�A
 * �\���I�ɕω��������p�����[�^�͎��O��send����悤��
 *------------------------------------------
 */

int status_calc_pc(struct map_session_data* sd,int first)
{
	static int calculating = 0; //Check for recursive call preemption. [Skotlex]
	int b_speed,b_max_hp,b_max_sp,b_hp,b_sp,b_weight,b_max_weight,b_paramb[6],b_parame[6],b_hit,b_flee;
	int b_aspd,b_watk,b_def,b_watk2,b_def2,b_flee2,b_critical,b_attackrange,b_matk1,b_matk2,b_mdef,b_mdef2,b_class;
	int b_base_atk;
	struct skill b_skill[MAX_SKILL];
	int i,bl,index;
	int skill,wele,wele_,def_ele,refinedef=0;
	int pele=0,pdef_ele=0;
	int str,dstr,dex;

	nullpo_retr(0, sd);
	if (++calculating > 10) //Too many recursive calls to status_calc_pc!
		return -1;
	
	b_speed = sd->speed;
	b_max_hp = sd->status.max_hp;
	b_max_sp = sd->status.max_sp;
	b_hp = sd->status.hp;
	b_sp = sd->status.sp;
	b_weight = sd->weight;
	b_max_weight = sd->max_weight;
	memcpy(b_paramb,&sd->paramb,sizeof(b_paramb));
	memcpy(b_parame,&sd->paramc,sizeof(b_parame));
	memcpy(b_skill,&sd->status.skill,sizeof(b_skill));
	b_hit = sd->hit;
	b_flee = sd->flee;
	b_aspd = sd->aspd;
	b_watk = sd->right_weapon.watk + sd->left_weapon.watk;
	b_def = sd->def;
	b_watk2 = sd->right_weapon.watk2 + sd->left_weapon.watk2;
	b_def2 = sd->def2;
	b_flee2 = sd->flee2;
	b_critical = sd->critical;
	b_attackrange = sd->attackrange;
	b_matk1 = sd->matk1;
	b_matk2 = sd->matk2;
	b_mdef = sd->mdef;
	b_mdef2 = sd->mdef2;
	b_class = sd->view_class;
	sd->view_class = sd->status.class_;
	b_base_atk = sd->base_atk;

	pc_calc_skilltree(sd);	// �X�L���c��?�̌v�Z
	
	sd->max_weight = max_weight_base[sd->status.class_]+sd->status.str*300;

	if(first&1) {
		sd->weight=0;
		for(i=0;i<MAX_INVENTORY;i++){
			if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL)
				continue;
			sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount;
		}
		sd->cart_max_weight=battle_config.max_cart_weight;
		sd->cart_weight=0;
		sd->cart_max_num=MAX_CART;
		sd->cart_num=0;
		for(i=0;i<MAX_CART;i++){
			if(sd->status.cart[i].nameid==0)
				continue;
			sd->cart_weight+=itemdb_weight(sd->status.cart[i].nameid)*sd->status.cart[i].amount;
			sd->cart_num++;
		}
	}

	// these are not zeroed. [zzo]

	sd->speed = DEFAULT_WALK_SPEED;
	sd->hprate=100;
	sd->sprate=100;
	sd->castrate=100;
	sd->delayrate=100;
	sd->dsprate=100;
	sd->aspd_rate = 100;
	sd->speed_rate = 100;
	sd->hprecov_rate = 100;
	sd->sprecov_rate = 100;
	sd->atk_rate = sd->matk_rate = 100;
	sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
	sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
	sd->speed_add_rate = sd->aspd_add_rate = 100;

	// zeroed arays, order follows the order in map.h.
	// add new arrays to the end of zeroed area in map.h (see comments) and size here. [zzo]
	memset (sd->paramb, 0, sizeof(sd->paramb)
		+ sizeof(sd->parame)
		+ sizeof(sd->subele)
		+ sizeof(sd->subrace)
		+ sizeof(sd->subrace2)
		+ sizeof(sd->subsize)
		+ sizeof(sd->addeff)
		+ sizeof(sd->addeff2)
		+ sizeof(sd->reseff)
		+ sizeof(sd->weapon_coma_ele)
		+ sizeof(sd->weapon_coma_race)
		+ sizeof(sd->weapon_atk)
		+ sizeof(sd->weapon_atk_rate)
		+ sizeof(sd->arrow_addele) 
		+ sizeof(sd->arrow_addrace)
		+ sizeof(sd->arrow_addsize)
		+ sizeof(sd->arrow_addeff)
		+ sizeof(sd->arrow_addeff2)
		+ sizeof(sd->magic_addele)
		+ sizeof(sd->magic_addrace)
		+ sizeof(sd->magic_addsize)
		+ sizeof(sd->critaddrace)
		+ sizeof(sd->expaddrace)
		+ sizeof(sd->itemhealrate)
		+ sizeof(sd->addeff3)
		+ sizeof(sd->addeff3_type)
		+ sizeof(sd->sp_gain_race)
		+ sizeof(sd->unequip_losehp)
		+ sizeof(sd->unequip_losesp)
		);


	memset (&sd->right_weapon.watk, 0, sizeof(sd->right_weapon) - sizeof(sd->right_weapon.atkmods));
	memset (&sd->left_weapon.watk, 0, sizeof(sd->left_weapon) - sizeof(sd->left_weapon.atkmods));

	memset(&sd->special_state,0,sizeof(sd->special_state));

	sd->status.max_hp = 0;
	sd->status.max_sp = 0;

	//zero up structures...
	memset(&sd->autospell,0,sizeof(sd->autospell)
		+ sizeof(sd->autospell2)
		+ sizeof(sd->skillatk)
		+ sizeof(sd->skillblown)
		+ sizeof(sd->add_def)
		+ sizeof(sd->add_mdef)
		+ sizeof(sd->add_dmg)
		+ sizeof(sd->add_mdmg)
		+ sizeof(sd->add_drop)
	);
	
	// vars zeroing. ints, shorts, chars. in that order.
	memset (&sd->hit, 0, sizeof(sd->hit)
		+ sizeof(sd->flee)
		+ sizeof(sd->flee2)
		+ sizeof(sd->critical)
		+ sizeof(sd->aspd)
		+ sizeof(sd->def)
		+ sizeof(sd->mdef)
		+ sizeof(sd->def2)
		+ sizeof(sd->mdef2)
		+ sizeof(sd->def_ele)
		+ sizeof(sd->matk1)
		+ sizeof(sd->matk2)
		+ sizeof(sd->base_atk)
		+ sizeof(sd->arrow_atk)
		+ sizeof(sd->arrow_ele)
		+ sizeof(sd->arrow_cri)
		+ sizeof(sd->arrow_hit)
		+ sizeof(sd->arrow_range)
		+ sizeof(sd->nhealhp)
		+ sizeof(sd->nhealsp)
		+ sizeof(sd->nshealhp)
		+ sizeof(sd->nshealsp)
		+ sizeof(sd->nsshealhp)
		+ sizeof(sd->nsshealsp)
		+ sizeof(sd->critical_def)
		+ sizeof(sd->double_rate)
		+ sizeof(sd->long_attack_atk_rate)
		+ sizeof(sd->near_attack_def_rate)
		+ sizeof(sd->long_attack_def_rate)
		+ sizeof(sd->magic_def_rate)
		+ sizeof(sd->misc_def_rate)
		+ sizeof(sd->ignore_mdef_ele)
		+ sizeof(sd->ignore_mdef_race)
		+ sizeof(sd->perfect_hit)
		+ sizeof(sd->perfect_hit_add)
		+ sizeof(sd->get_zeny_rate)
		+ sizeof(sd->get_zeny_num)
		+ sizeof(sd->double_add_rate)
		+ sizeof(sd->short_weapon_damage_return)
		+ sizeof(sd->long_weapon_damage_return)
		+ sizeof(sd->magic_damage_return)
		+ sizeof(sd->random_attack_increase_add)
		+ sizeof(sd->random_attack_increase_per)
		+ sizeof(sd->break_weapon_rate)
		+ sizeof(sd->break_armor_rate)
		+ sizeof(sd->crit_atk_rate)
		+ sizeof(sd->hp_loss_rate)
		+ sizeof(sd->sp_loss_rate)
		+ sizeof(sd->classchange)
		+ sizeof(sd->setitem_hash)
		+ sizeof(sd->setitem_hash2)
		// shorts
		+ sizeof(sd->attackrange)
		+ sizeof(sd->attackrange_)
		+ sizeof(sd->splash_range)
		+ sizeof(sd->splash_add_range)
		+ sizeof(sd->add_steal_rate)
		+ sizeof(sd->hp_loss_value)
		+ sizeof(sd->sp_loss_value)
		+ sizeof(sd->hp_loss_type)
		+ sizeof(sd->sp_drain_type)
		+ sizeof(sd->hp_gain_value)
		+ sizeof(sd->sp_gain_value)
		+ sizeof(sd->add_drop_count)
		+ sizeof(sd->unbreakable)
		+ sizeof(sd->unbreakable_equip)
		+ sizeof(sd->unstripable_equip)
		+ sizeof(sd->no_regen)
		+ sizeof(sd->add_def_count)
		+ sizeof(sd->add_mdef_count)
		+ sizeof(sd->add_dmg_count)
		+ sizeof(sd->add_mdmg_count)
		);

	if(!sd->state.disguised && sd->disguise) {
		pc_stop_walking(sd,0);
		clif_clearchar(&sd->bl, 0);
		sd->disguise=0;
		clif_changeoption(&sd->bl);
		clif_spawnpc(sd);
	}

	for(i=0;i<10;i++) {
		current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
		if(index < 0)
			continue;
		if(i == 9 && sd->equip_index[8] == index)
			continue;
		if(i == 5 && sd->equip_index[4] == index)
			continue;
		if(i == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index))
			continue;

		if(sd->inventory_data[index]) {
			if(sd->inventory_data[index]->type == 4) { // Weapon cards
				if(sd->status.inventory[index].card[0]!=0x00ff && sd->status.inventory[index].card[0]!=0x00fe && sd->status.inventory[index].card[0]!=(short)0xff00) {
					int j;
					for(j=0;j<sd->inventory_data[index]->slot;j++){	// �J?�h
						int c=sd->status.inventory[index].card[j];
						if(c>0){
							if(i == 8 && sd->status.inventory[index].equip == 0x20)
								sd->state.lr_flag = 1;
							run_script(itemdb_equipscript(c),0,sd->bl.id,0);
							sd->state.lr_flag = 0;
							if (!calculating) //Abort, run_script retriggered status_calc_pc. [Skotlex]
								return 1;
						}
					}
				}
			}
			else if(sd->inventory_data[index]->type==5){ // Non-weapon equipment cards
				if(sd->status.inventory[index].card[0]!=0x00ff && sd->status.inventory[index].card[0]!=0x00fe && sd->status.inventory[index].card[0]!=(short)0xff00) {
					int j;
					for(j=0;j<sd->inventory_data[index]->slot;j++){	// �J?�h
						int c=sd->status.inventory[index].card[j];
						if(c>0) {
							run_script(itemdb_equipscript(c),0,sd->bl.id,0);
							if (!calculating) //Abort, run_script retriggered status_calc_pc. [Skotlex]
								return 1;
						}
					}
				}
			}
		}
	}
	wele = sd->right_weapon.atk_ele;
	wele_ = sd->left_weapon.atk_ele;
	def_ele = sd->def_ele;

	if(sd->status.pet_id > 0) { // Pet
		struct pet_data *pd=sd->pd;
		if((pd && battle_config.pet_status_support) && (!battle_config.pet_equip_required || pd->equip > 0)) {
			if(sd->pet.intimate > 0 && pd->state.skillbonus == 1 && pd->bonus) { //Skotlex: Readjusted for pets
				pc_bonus(sd,pd->bonus->type, pd->bonus->val);
			}
			pele = sd->right_weapon.atk_ele;
			pdef_ele = sd->def_ele;
			sd->right_weapon.atk_ele = sd->def_ele = 0;
		}
	}
	memcpy(sd->paramcard,sd->parame,sizeof(sd->paramcard));

	// ?���i�ɂ��X�e?�^�X?���͂�����?�s
	for(i=0;i<10;i++) {
		current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus]
		if(index < 0)
			continue;
		if(i == 9 && sd->equip_index[8] == index)
			continue;
		if(i == 5 && sd->equip_index[4] == index)
			continue;
		if(i == 6 && (sd->equip_index[5] == index || sd->equip_index[4] == index))
			continue;
		if(sd->inventory_data[index]) {
			sd->def += sd->inventory_data[index]->def;
			if(sd->inventory_data[index]->type == 4) {
				int r,wlv = sd->inventory_data[index]->wlv;
				if (wlv >= MAX_REFINE_BONUS) 
					wlv = MAX_REFINE_BONUS - 1;
				if(i == 8 && sd->status.inventory[index].equip == 0x20) { // Left-hand weapon
					sd->left_weapon.watk += sd->inventory_data[index]->atk;
					sd->left_weapon.watk2 = (r=sd->status.inventory[index].refine)*	// ��?�U?��
						refinebonus[wlv][0];
					if( (r-=refinebonus[wlv][2])>0 )	// ��?��?�{?�i�X
						sd->left_weapon.overrefine = r*refinebonus[wlv][1];

					if(sd->status.inventory[index].card[0]==0x00ff){	// Forged weapon
						sd->left_weapon.star = (sd->status.inventory[index].card[1]>>8);	// ���̂�����
						if(sd->left_weapon.star >= 15) sd->left_weapon.star = 40; // 3 Star Crumbs now give +40 dmg
						if (pc_istop10fame( MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) ,MAPID_BLACKSMITH))
							sd->left_weapon.star += 10;
						wele_= (sd->status.inventory[index].card[1]&0x0f);	// ? ��
					}
					sd->attackrange_ += sd->inventory_data[index]->range;
					sd->state.lr_flag = 1;
					run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
					sd->state.lr_flag = 0;
					if (!calculating) //Abort, run_script retriggered status_calc_pc. [Skotlex]
						return 1;
				}
				else {	// Right-hand weapon
					sd->right_weapon.watk += sd->inventory_data[index]->atk;
					sd->right_weapon.watk2 += (r=sd->status.inventory[index].refine)*	// ��?�U?��
						refinebonus[wlv][0];
					if( (r-=refinebonus[wlv][2])>0 )	// ��?��?�{?�i�X
						sd->right_weapon.overrefine += r*refinebonus[wlv][1];

					if(sd->status.inventory[index].card[0]==0x00ff){	// Forged weapon
						sd->right_weapon.star += (sd->status.inventory[index].card[1]>>8);	// ���̂�����
						if(sd->right_weapon.star >= 15) sd->right_weapon.star = 40; // 3 Star Crumbs now give +40 dmg
						if (pc_istop10fame( MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) ,MAPID_BLACKSMITH))
							sd->right_weapon.star += 10;
						wele = (sd->status.inventory[index].card[1]&0x0f);	// ? ��
					}
					sd->attackrange += sd->inventory_data[index]->range;
					run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
					if (!calculating) //Abort, run_script retriggered status_calc_pc. [Skotlex]
						return 1;
				}
			}
			else if(sd->inventory_data[index]->type == 5) {
				sd->right_weapon.watk += sd->inventory_data[index]->atk;
				refinedef += sd->status.inventory[index].refine*refinebonus[0][0];
				run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
				if (!calculating) //Abort, run_script retriggered status_calc_pc. [Skotlex]
					return 1;
			}
		}
	}

	if(sd->equip_index[10] >= 0){ // ��
		index = sd->equip_index[10];
		if(sd->inventory_data[index]){		// Arrows
			sd->state.lr_flag = 2;
			run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
			sd->state.lr_flag = 0;
			sd->arrow_atk += sd->inventory_data[index]->atk;
		}
	}
	sd->def += (refinedef+50)/100;

	if(sd->attackrange < 1) sd->attackrange = 1;
	if(sd->attackrange_ < 1) sd->attackrange_ = 1;
	if(sd->attackrange < sd->attackrange_)
		sd->attackrange = sd->attackrange_;
	if(sd->status.weapon == 11)
		sd->attackrange += sd->arrow_range;
	if(wele > 0)
		sd->right_weapon.atk_ele = wele;
	if(wele_ > 0)
		sd->left_weapon.atk_ele = wele_;
	if(def_ele > 0)
		sd->def_ele = def_ele;
	if(battle_config.pet_status_support) {
		if(pele > 0 && !sd->right_weapon.atk_ele)
			sd->right_weapon.atk_ele = pele;
		if(pdef_ele > 0 && !sd->def_ele)
			sd->def_ele = pdef_ele;
	}
	sd->double_rate += sd->double_add_rate;
	sd->perfect_hit += sd->perfect_hit_add;
	sd->splash_range += sd->splash_add_range;
	if(sd->aspd_add_rate != 100)	
		sd->aspd_rate += sd->aspd_add_rate-100;
	if(sd->speed_add_rate != 100)	
		sd->speed_rate += sd->speed_add_rate-100;

	// Damage modifiers from weapon type
	sd->right_weapon.atkmods[0] = atkmods[0][sd->weapontype1];
	sd->right_weapon.atkmods[1] = atkmods[1][sd->weapontype1];
	sd->right_weapon.atkmods[2] = atkmods[2][sd->weapontype1];
	sd->left_weapon.atkmods[0] = atkmods[0][sd->weapontype2];
	sd->left_weapon.atkmods[1] = atkmods[1][sd->weapontype2];
	sd->left_weapon.atkmods[2] = atkmods[2][sd->weapontype2];

// ----- STATS CALCULATION -----

	// Job bonuses
	for(i=0;i<(int)sd->status.job_level && i<MAX_LEVEL;i++){
		if(job_bonus[sd->status.class_][i])
			sd->paramb[job_bonus[sd->status.class_][i]-1]++;
	}

	// If a Super Novice has never died and is at least joblv 70, he gets all stats +10
	if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->die_counter == 0 && sd->status.job_level >= 70){
		sd->paramb[0] += 10;
		sd->paramb[1] += 10;
		sd->paramb[2] += 10;
		sd->paramb[3] += 10;
		sd->paramb[4] += 10;
		sd->paramb[5] += 10;
	}

	// Absolute modifiers from passive skills
	if(pc_checkskill(sd,BS_HILTBINDING)>0)
		sd->paramb[0] ++;
	if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0)
		sd->paramb[3] += (skill+1)/2; // +1 INT / 2 lv
	if((skill=pc_checkskill(sd,AC_OWL))>0)
		sd->paramb[4] += skill;

	// Improve Concentration adds a percentage of base stat + job bonus + equipment bonus, but not from card bonus nor status change bonus
	if(sd->sc.count && sd->sc.data[SC_CONCENTRATE].timer!=-1 && sd->sc.data[SC_QUAGMIRE].timer == -1){
		sd->paramb[1] += (sd->status.agi+sd->paramb[1]+sd->parame[1]-sd->paramcard[1])*(2+sd->sc.data[SC_CONCENTRATE].val1)/100;
		sd->paramb[4] += (sd->status.dex+sd->paramb[4]+sd->parame[4]-sd->paramcard[4])*(2+sd->sc.data[SC_CONCENTRATE].val1)/100;
	}

	// Absolute modifiers from status changes (only for PC)
	if(sd->sc.count){
		if (sd->sc.data[SC_BATTLEORDERS].timer != -1) {
			sd->paramb[0] += 5;
			sd->paramb[3] += 5;
			sd->paramb[4] += 5;
		}
		if (sd->sc.data[SC_GUILDAURA].timer != -1) {
			int guildflag = sd->sc.data[SC_GUILDAURA].val4;
			for (i = 12; i >= 0; i -= 4) {
				skill = guildflag >> i;
				switch (i) {
					case 12: sd->paramb[0] += skill; break;
					case 8: sd->paramb[2] += skill; break;
					case 4: sd->paramb[1] += skill; break;
					case 0: sd->paramb[4] += skill; break;
				}
				guildflag ^= skill << i;
			}
		}
	}

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->paramb[0] = status_calc_str(&sd->bl,sd->paramb[0]);
	sd->paramb[1] = status_calc_agi(&sd->bl,sd->paramb[1]);
	sd->paramb[2] = status_calc_vit(&sd->bl,sd->paramb[2]);
	sd->paramb[3] = status_calc_int(&sd->bl,sd->paramb[3]);
	sd->paramb[4] = status_calc_dex(&sd->bl,sd->paramb[4]);
	sd->paramb[5] = status_calc_luk(&sd->bl,sd->paramb[5]);
	
	// Relative modifiers from status changes (only for PC)
	if(sd->sc.count){
		if(sd->sc.data[SC_MARIONETTE].timer!=-1){
			sd->paramb[0]-= sd->status.str/2;
			sd->paramb[1]-= sd->status.agi/2;
			sd->paramb[2]-= sd->status.vit/2;
			sd->paramb[3]-= sd->status.int_/2;
			sd->paramb[4]-= sd->status.dex/2;
			sd->paramb[5]-= sd->status.luk/2;
		}
		else if(sd->sc.data[SC_MARIONETTE2].timer!=-1){
			struct map_session_data *psd = map_id2sd(sd->sc.data[SC_MARIONETTE2].val3);
			if (psd) {	// if partner is found
				bl = pc_maxparameter(sd); //Cap to max parameter. [Skotlex]
				if (sd->status.str < bl)
					sd->paramb[0] += sd->status.str+psd->status.str/2 > bl ?
						bl-sd->status.str : psd->status.str/2;
				if (sd->status.agi < bl)
					sd->paramb[1] += sd->status.agi+psd->status.agi/2 > bl ?
						bl-sd->status.agi : psd->status.agi/2;
				if (sd->status.vit < bl)
					sd->paramb[2] += sd->status.vit+psd->status.vit/2 > bl ?
						bl-sd->status.vit : psd->status.vit/2;
				if (sd->status.int_ < bl)
					sd->paramb[3] += sd->status.int_+psd->status.int_/2 > bl ?
						bl-sd->status.int_ : psd->status.int_/2;
				if (sd->status.dex < bl)
					sd->paramb[4] += sd->status.dex+psd->status.dex/2 > bl ?
						bl-sd->status.dex : psd->status.dex/2;
				if (sd->status.luk < bl)
					sd->paramb[5] += sd->status.luk+psd->status.luk/2 > bl ?
						bl-sd->status.luk : psd->status.luk/2;
			}
		}
	}

	// Calculate total stats
	sd->paramc[0]=sd->status.str+sd->paramb[0]+sd->parame[0];
	sd->paramc[1]=sd->status.agi+sd->paramb[1]+sd->parame[1];
	sd->paramc[2]=sd->status.vit+sd->paramb[2]+sd->parame[2];
	sd->paramc[3]=sd->status.int_+sd->paramb[3]+sd->parame[3];
	sd->paramc[4]=sd->status.dex+sd->paramb[4]+sd->parame[4];
	sd->paramc[5]=sd->status.luk+sd->paramb[5]+sd->parame[5];

	if(sd->sc.count){
		if(sd->sc.data[SC_SPIRIT].timer!=-1 && sd->sc.data[SC_SPIRIT].val2 == SL_HIGH)
	  	{	//Ups any status under 50 to 50.
			if (sd->paramc[0] < 50) {
				sd->paramb[0] += 50-sd->paramc[0];
				sd->paramc[0] = 50;
			}
			if (sd->paramc[1] < 50) {
				sd->paramb[1] += 50-sd->paramc[1];
				sd->paramc[1] = 50;
			}
			if (sd->paramc[2] < 50) {
				sd->paramb[2] += 50-sd->paramc[2];
				sd->paramc[2] = 50;
			}
			if (sd->paramc[3] < 50) {
				sd->paramb[3] += 50-sd->paramc[3];
				sd->paramc[3] = 50;
			}
			if (sd->paramc[4] < 50) {
				sd->paramb[4] += 50-sd->paramc[4];
				sd->paramc[4] = 50;
			}
			if (sd->paramc[5] < 50) {
				sd->paramb[5] += 50-sd->paramc[5];
				sd->paramc[5] = 50;
			}
		}
	}
	for(i=0;i<6;i++)
		if(sd->paramc[i] < 0) sd->paramc[i] = 0;

	if (sd->sc.count && sd->sc.data[SC_CURSE].timer!=-1)
		sd->paramc[5] = 0;

// ------ BASE ATTACK CALCULATION ------

	// Basic Base ATK value
	switch(sd->status.weapon){
		case 11: // Bows
		case 13: // Musical Instruments
		case 14: // Whips
			str = sd->paramc[4];
			dex = sd->paramc[0];
			break;
		default:
			str = sd->paramc[0];
			dex = sd->paramc[4];
			break;
	}
	dstr = str/10;
	sd->base_atk += str + dstr*dstr + dex/5 + sd->paramc[5]/5;

	// Absolute modifiers from passive skills
	if((skill=pc_checkskill(sd,BS_HILTBINDING))>0)
		sd->base_atk += 4;

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
		sd->base_atk = status_calc_batk(&sd->bl,sd->base_atk);

	if(sd->base_atk < 1)
		sd->base_atk = 1;

// ----- WEAPON ATK CALCULATION -----

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->right_weapon.watk = status_calc_watk(&sd->bl,sd->right_weapon.watk);
	if((index= sd->equip_index[8]) >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == 4)
		sd->left_weapon.watk = status_calc_watk(&sd->bl,sd->left_weapon.watk);

// ----- WEAPON UPGRADE ATK CALCULATION -----

	// Absolute modifiers from status changes (only for PC)
	if(sd->sc.count){
		if(sd->sc.data[SC_NIBELUNGEN].timer!=-1){
			index = sd->equip_index[9];
			if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
				sd->right_weapon.watk2 += sd->sc.data[SC_NIBELUNGEN].val2;
			index = sd->equip_index[8];
			if(index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->wlv == 4)
				sd->left_weapon.watk2 += sd->sc.data[SC_NIBELUNGEN].val2;
		}
	}

// ----- MATK CALCULATION -----

	// Basic MATK value
	sd->matk1 += sd->paramc[3]+(sd->paramc[3]/5)*(sd->paramc[3]/5);
	sd->matk2 += sd->paramc[3]+(sd->paramc[3]/7)*(sd->paramc[3]/7);
	if(sd->matk1 < sd->matk2) {
		int temp = sd->matk2;
		sd->matk2 = sd->matk1;
		sd->matk1 = temp;
	}

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->matk1 = status_calc_matk(&sd->bl,sd->matk1);
	sd->matk2 = status_calc_matk(&sd->bl,sd->matk2);

	// Apply relative modifiers from equipment
	if(sd->matk_rate != 100){
		sd->matk1 = sd->matk1 * sd->matk_rate/100;
		sd->matk2 = sd->matk2 * sd->matk_rate/100;
	}

// ----- CRIT CALCULATION -----

	// Basic Crit value
	sd->critical += (sd->paramc[5]*3)+10;

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->critical = status_calc_critical(&sd->bl,sd->critical);

	// Apply relative modifiers from equipment
	if(sd->critical_rate != 100)
		sd->critical = sd->critical * sd->critical_rate/100;

	if(sd->critical < 10) sd->critical = 10;

// ----- HIT CALCULATION -----

	// Basic Hit value
	sd->hit += sd->paramc[4] + sd->status.base_level;

	// Absolute modifiers from passive skills
	if((skill=pc_checkskill(sd,BS_WEAPONRESEARCH))>0)
		sd->hit += skill*2;
	if((skill=pc_checkskill(sd,AC_VULTURE))>0){
		sd->hit += skill;
		if(sd->status.weapon == 11)
			sd->attackrange += skill;
	}

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->hit = status_calc_hit(&sd->bl,sd->hit);

	// Apply relative modifiers from equipment
	if(sd->hit_rate != 100)
		sd->hit = sd->hit * sd->hit_rate/100;

	if(sd->hit < 1) sd->hit = 1;

// ----- FLEE CALCULATION -----

	// Basic Flee value
	sd->flee += sd->paramc[1] + sd->status.base_level;

	// Absolute modifiers from passive skills
	if((skill=pc_checkskill(sd,TF_MISS))>0)
		sd->flee += skill*(sd->class_&JOBL_2 && (sd->class_&MAPID_BASEMASK) == MAPID_THIEF? 4 : 3);
	if((skill=pc_checkskill(sd,MO_DODGE))>0)
		sd->flee += (skill*3)>>1;

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->flee = status_calc_flee(&sd->bl,sd->flee);

	// Apply relative modifiers from equipment
	if(sd->flee_rate != 100)
		sd->flee = sd->flee * sd->flee_rate/100;

	if(sd->flee < 1) sd->flee = 1;

// ----- PERFECT DODGE CALCULATION -----

	// Basic Perfect Dodge value
	sd->flee2 += sd->paramc[5]+10;

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->flee2 = status_calc_flee2(&sd->bl,sd->flee2);

	// Apply relative modifiers from equipment
	if(sd->flee2_rate != 100)
		sd->flee2 = sd->flee2 * sd->flee2_rate/100;

	if(sd->flee2 < 10) sd->flee2 = 10;

// ----- VIT-DEF CALCULATION -----

	// Special fixed values from status changes
	if(sd->sc.count && sd->sc.data[SC_BERSERK].timer!=-1)
		sd->def2 = 0;
	else if(sd->sc.count && sd->sc.data[SC_ETERNALCHAOS].timer!=-1)
		sd->def2 = 0;
	else {
		// Basic VIT-DEF value
		sd->def2 += sd->paramc[2];

		// Absolute, then relative modifiers from status changes (shared between PC and NPC)
		sd->def2 = status_calc_def2(&sd->bl,sd->def2);

		// Apply relative modifiers from equipment
		if(sd->def2_rate != 100)
			sd->def2 = sd->def2 * sd->def2_rate/100;

		if(sd->def2 < 1) sd->def2 = 1;
	}

// ----- EQUIPMENT-DEF CALCULATION -----

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->def = status_calc_def(&sd->bl,sd->def);

	// Apply relative modifiers from equipment
	if(sd->def_rate != 100)
		sd->def = sd->def * sd->def_rate/100;

	if(sd->def < 0) sd->def = 0;

	else if (!battle_config.player_defense_type && sd->def > battle_config.max_def)
	{
		sd->def2 += battle_config.over_def_bonus*(sd->def -battle_config.max_def);
		sd->def = battle_config.max_def;
	}

// ----- INT-MDEF CALCULATION -----

	// Special fixed values from status changes
	if(sd->sc.count && sd->sc.data[SC_BERSERK].timer!=-1)
		sd->mdef2 = 0;
	else {
		// Basic INT-MDEF value
		sd->mdef2 += sd->paramc[3];

		// sd->mdef2 = status_calc_mdef2(&sd->bl,sd->mdef2);

		// Apply relative modifiers from equipment
		if(sd->mdef2_rate != 100)
			sd->mdef2 = sd->mdef2 * sd->mdef2_rate/100;

		if(sd->mdef2 < 1) sd->mdef2 = 1;
	}

// ----- EQUIPMENT-MDEF CALCULATION -----

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->mdef = status_calc_mdef(&sd->bl,sd->mdef);

	// Apply relative modifiers from equipment
	if(sd->mdef_rate != 100)
		sd->mdef = sd->mdef * sd->mdef_rate/100;

	if(sd->mdef < 0) sd->mdef = 0;

	else if (!battle_config.player_defense_type && sd->mdef > battle_config.max_def)
	{
		sd->mdef2 += battle_config.over_def_bonus*(sd->mdef -battle_config.max_def);
		sd->mdef = battle_config.max_def;
	}
	
// ----- WALKING SPEED CALCULATION -----

	// Relative, then absolute modifiers from status changes (shared between PC and NPC)
	sd->speed = status_calc_speed(&sd->bl,sd->speed);

	// Relative modifiers from passive skills
	if((skill=pc_checkskill(sd,TF_MISS))>0 && (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN && sd->sc.data[SC_CLOAKING].timer==-1)
		sd->speed -= sd->speed * skill/100;
	if(pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0)
		sd->speed -= sd->speed * 25/100;
	if(pc_ishiding(sd) && (skill=pc_checkskill(sd,RG_TUNNELDRIVE))>0)
		sd->speed += sd->speed * (100-16*skill)/100;
	if(pc_iscarton(sd) && (skill=pc_checkskill(sd,MC_PUSHCART))>0)
		sd->speed += sd->speed * (100-10*skill)/100;
 	if(sd->skilltimer != -1 && (skill=pc_checkskill(sd,SA_FREECAST))>0) {
		sd->prev_speed = sd->speed; //Store previous speed to correctly restore it. [Skotlex]
		sd->speed += sd->speed * (75-5*skill)/100;
	}
	if(sd->sc.count && sd->sc.data[SC_DANCING].timer!=-1){
			int s_rate = 500-40*pc_checkskill(sd,(sd->status.sex?BA_MUSICALLESSON:DC_DANCINGLESSON));
			if (sd->sc.data[SC_SPIRIT].timer != -1 && sd->sc.data[SC_SPIRIT].val2 == SL_BARDDANCER)
				s_rate -= 40; //TODO: Figure out real bonus rate.
			if (sd->sc.data[SC_LONGING].timer!=-1)
				s_rate -= 20 * sd->sc.data[SC_LONGING].val1;
			sd->speed += sd->speed * s_rate/100;
	}
	if(sd->sc.data[SC_FUSION].timer != -1) //Additional movement speed from SG_FUSION [Komurka]
		sd->speed -= sd->speed * 25/100;

	// Apply relative modifiers from equipment
	if(sd->speed_rate != 100)
		sd->speed = sd->speed*sd->speed_rate/100;

	if(sd->speed < battle_config.max_walk_speed)
		sd->speed = battle_config.max_walk_speed;

// ----- ASPD CALCULATION -----
// Unlike other stats, ASPD rate modifiers from skills/SCs/items/etc are first all added together, then the final modifier is applied

	// Basic ASPD value
	if (sd->status.weapon <= 16)
		sd->aspd += aspd_base[sd->status.class_][sd->status.weapon]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[sd->status.class_][sd->status.weapon]/1000;
	else
		sd->aspd += (
			(aspd_base[sd->status.class_][sd->weapontype1]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[sd->status.class_][sd->weapontype1]/1000) +
			(aspd_base[sd->status.class_][sd->weapontype2]-(sd->paramc[1]*4+sd->paramc[4])*aspd_base[sd->status.class_][sd->weapontype2]/1000)
			) *2/3; //From what I read in rodatazone, 2/3 should be more accurate than 0.7 -> 140 / 200; [Skotlex]

	// Relative modifiers from passive skills
	if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0)
		sd->aspd_rate -= (skill/2);
	if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && !pc_nextjobexp(sd))
		sd->aspd_rate -= (skill*3);

	if(pc_isriding(sd))
		sd->aspd_rate += 50-10*pc_checkskill(sd,KN_CAVALIERMASTERY);

	// Relative modifiers from status changes (shared between PC and NPC)
	sd->aspd_rate = status_calc_aspd_rate(&sd->bl,sd->aspd_rate);

	// Apply all relative modifiers
	if(sd->aspd_rate != 100)
		sd->aspd = sd->aspd*sd->aspd_rate/100;

	if(sd->aspd < battle_config.max_aspd) sd->aspd = battle_config.max_aspd;
	sd->amotion = sd->aspd;

// ----- HP MAX AND REGEN CALCULATION -----

	// Basic MaxHP value
	// here we recycle variable index, and do this calc apart to avoid mixing up the 30% bonus with card bonuses. [Skotlex]
	bl = sd->status.base_level;
	index = (3500 + bl*hp_coefficient2[sd->status.class_] +
		hp_sigma_val[sd->status.class_][(bl > 0)? bl-1:0])/100 *
		(100 + sd->paramc[2])/100 + (sd->parame[2] - sd->paramcard[2]);
	if (sd->class_&JOBL_UPPER)
		index += index * 30/100;
	else if (sd->class_&JOBL_BABY)
		index -= index * 30/100;
	if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_istop10fame(sd->char_id, MAPID_TAEKWON))
		index *= 3; //Triple max HP for top ranking Taekwons over level 90.
	
	sd->status.max_hp += index;

	if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99)
		sd->status.max_hp = sd->status.max_hp + 2000;

	// Absolute modifiers from passive skills
	if((skill=pc_checkskill(sd,CR_TRUST))>0)
		sd->status.max_hp += skill*200;

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->status.max_hp = status_calc_maxhp(&sd->bl,sd->status.max_hp);

	// Apply relative modifiers from equipment
	if(sd->hprate!=100)
		sd->status.max_hp = sd->status.max_hp * sd->hprate/100;
	if(battle_config.hp_rate != 100)
		sd->status.max_hp = sd->status.max_hp * battle_config.hp_rate/100;

	if(sd->status.max_hp > battle_config.max_hp)
		sd->status.max_hp = battle_config.max_hp;
	if(sd->status.max_hp <= 0) sd->status.max_hp = 1;
	if(sd->status.hp>sd->status.max_hp)
		sd->status.hp=sd->status.max_hp;

	// Basic natural HP regeneration value
	sd->nhealhp = 1 + (sd->paramc[2]/5) + (sd->status.max_hp/200);

	// Apply relative modifiers from equipment
	if(sd->hprecov_rate != 100)
		sd->nhealhp = sd->nhealhp*sd->hprecov_rate/100;

	if(sd->nhealhp < 1) sd->nhealhp = 1;
	if(sd->nhealhp > 0x7fff) sd->nhealhp = 0x7fff;

	// Skill-related HP recovery
	if((skill=pc_checkskill(sd,SM_RECOVERY)) > 0)
		sd->nshealhp = skill*5 + (sd->status.max_hp*skill/500);
	// Skill-related HP recovery (only when sit)
	if((skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0)
		sd->nsshealhp = skill*4 + (sd->status.max_hp*skill/500);
	if((skill=pc_checkskill(sd,TK_HPTIME)) > 0 && sd->state.rest == 1)
		sd->nsshealhp = skill*30 + (sd->status.max_hp*skill/500);

	if(sd->nshealhp > 0x7fff) sd->nshealhp = 0x7fff;
	if(sd->nsshealhp > 0x7fff) sd->nsshealhp = 0x7fff;

// ----- SP MAX AND REGEN CALCULATION -----

	// Basic MaxSP value
	// here we recycle variable index, and do this calc apart to avoid mixing up the 30% bonus with card bonuses. [Skotlex]
	index = ((sp_coefficient[sd->status.class_] * bl) + 1000)/100 * (100 + sd->paramc[3])/100 + (sd->parame[3] - sd->paramcard[3]);
	if (sd->class_&JOBL_UPPER)
		index += index * 30/100;
	else if (sd->class_&JOBL_BABY)
		index -= index * 30/100;
	if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_istop10fame(sd->char_id, MAPID_TAEKWON))
		index *= 3; //Triple max SP for top ranking Taekwons over level 90.
	
	sd->status.max_sp += index;

	// Absolute modifiers from passive skills
	if((skill=pc_checkskill(sd,SL_KAINA))>0)
		sd->status.max_sp += 30*skill;
	if((skill=pc_checkskill(sd,HP_MEDITATIO))>0)
		sd->status.max_sp += sd->status.max_sp * skill/100;
	if((skill=pc_checkskill(sd,HW_SOULDRAIN))>0)
		sd->status.max_sp += sd->status.max_sp * 2*skill/100;

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	sd->status.max_sp = status_calc_maxsp(&sd->bl,sd->status.max_sp);

	// Apply relative modifiers from equipment
	if(sd->sprate!=100)
		sd->status.max_sp = sd->status.max_sp * sd->sprate/100;
	if(battle_config.sp_rate != 100)
		sd->status.max_sp = sd->status.max_sp * battle_config.sp_rate/100;
	
	if(sd->status.max_sp > battle_config.max_sp)
		sd->status.max_sp = battle_config.max_sp;
	if(sd->status.sp>sd->status.max_sp)
		sd->status.sp=sd->status.max_sp;
	if(sd->status.max_sp <= 0) sd->status.max_sp = 1;

	if(sd->sc.data[SC_DANCING].timer==-1){
		// Basic natural SP regeneration value
		sd->nhealsp = 1 + (sd->paramc[3]/6) + (sd->status.max_sp/100);
		if(sd->paramc[3] >= 120)
			sd->nhealsp += ((sd->paramc[3]-120)>>1) + 4;

		// Relative modifiers from passive skills
		if((skill=pc_checkskill(sd,HP_MEDITATIO)) > 0)
			sd->nhealsp += sd->nhealsp * 3*skill/100;

		// Apply relative modifiers from equipment
		if(sd->sprecov_rate != 100)
			sd->nhealsp = sd->nhealsp*sd->sprecov_rate/100;

		if(sd->nhealsp < 1) sd->nhealsp = 1;
		if(sd->nhealsp > 0x7fff) sd->nhealsp = 0x7fff;

		// Skill-related SP recovery
		if((skill=pc_checkskill(sd,MG_SRECOVERY)) > 0)
			sd->nshealsp = skill*3 + (sd->status.max_sp*skill/500);
		// Skill-related SP recovery (only when sit)
		if((skill = pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0)
			sd->nsshealsp = skill*2 + (sd->status.max_sp*skill/500);
		if((skill=pc_checkskill(sd,TK_SPTIME)) > 0 && sd->state.rest == 1) {
			sd->nsshealsp = skill*3 + (sd->status.max_sp*skill/500);
			if ((skill=pc_checkskill(sd,SL_KAINA)) > 0) //Power up Enjoyable Rest
				sd->nsshealsp += (30+10*skill)*sd->nsshealsp/100;
		}
		if(sd->nshealsp > 0x7fff) sd->nshealsp = 0x7fff;
		if(sd->nsshealsp > 0x7fff) sd->nsshealsp = 0x7fff;
	}

// ----- MISC CALCULATIONS -----

	//Even though people insist this is too slow, packet data reports this is the actual real equation.
	sd->dmotion = 800-sd->paramc[1]*4;
	if(sd->dmotion<400)	sd->dmotion = 400;

	// Weight
	if((skill=pc_checkskill(sd,MC_INCCARRY))>0)
		sd->max_weight += 2000*skill;
	if(pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0)
		sd->max_weight += 10000;
	if( (skill=pc_checkskill(sd,SG_KNOWLEDGE))>0) //SG skill [Komurka]
		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)
			sd->max_weight += sd->max_weight*skill/10;

	// Skill SP cost
	if((skill=pc_checkskill(sd,HP_MANARECHARGE))>0 )
		sd->dsprate -= 4*skill;

	if(sd->sc.count){
		if(sd->sc.data[SC_SERVICE4U].timer!=-1)
			sd->dsprate -= sd->sc.data[SC_SERVICE4U].val3;
	}

	if(sd->dsprate < 0) sd->dsprate = 0;

	// Anti-element and anti-race
	if((skill=pc_checkskill(sd,CR_TRUST))>0)
		sd->subele[6] += skill*5;
	if((skill=pc_checkskill(sd,BS_SKINTEMPER))>0) {
		sd->subele[0] += skill;
		sd->subele[3] += skill*4;
	}
	if((skill=pc_checkskill(sd,SA_DRAGONOLOGY))>0 ){
		skill = skill*4;
		sd->right_weapon.addrace[9]+=skill;
		sd->left_weapon.addrace[9]+=skill;
		sd->magic_addrace[9]+=skill;
		sd->subrace[9]+=skill;
	}

	if(sd->sc.count){
       	if(sd->sc.data[SC_SIEGFRIED].timer!=-1){
			sd->subele[1] += sd->sc.data[SC_SIEGFRIED].val2;
			sd->subele[2] += sd->sc.data[SC_SIEGFRIED].val2;
			sd->subele[3] += sd->sc.data[SC_SIEGFRIED].val2;
			sd->subele[4] += sd->sc.data[SC_SIEGFRIED].val2;
			sd->subele[5] += sd->sc.data[SC_SIEGFRIED].val2;
			sd->subele[6] += sd->sc.data[SC_SIEGFRIED].val2;
			sd->subele[7] += sd->sc.data[SC_SIEGFRIED].val2;
			sd->subele[8] += sd->sc.data[SC_SIEGFRIED].val2;
			sd->subele[9] += sd->sc.data[SC_SIEGFRIED].val2;
		}
		if(sd->sc.data[SC_PROVIDENCE].timer!=-1){
			sd->subele[6] += sd->sc.data[SC_PROVIDENCE].val2;
			sd->subrace[6] += sd->sc.data[SC_PROVIDENCE].val2;
		}
	}

// ----- CLIENT-SIDE REFRESH -----
	if(first&1) { //Since this is the initial loading, the Falcon and Peco icons must be loaded. [Skotlex]
		if (sd->sc.option&OPTION_FALCON)
			clif_status_load(&sd->bl, SI_FALCON, 1);
		if (sd->sc.option&OPTION_RIDING)
			clif_status_load(&sd->bl, SI_RIDING, 1);
	}
	if(first&4) {
		calculating = 0;
		return 0;
	}
	if(first&3) {
		clif_updatestatus(sd,SP_SPEED);
		clif_updatestatus(sd,SP_MAXHP);
		clif_updatestatus(sd,SP_MAXSP);
		if(first&1) {
			clif_updatestatus(sd,SP_HP);
			clif_updatestatus(sd,SP_SP);
		}
		calculating = 0;
		return 0;
	}

	
	if(sd->sc.data[SC_WEDDING].timer != -1 && sd->view_class != JOB_WEDDING)
		sd->view_class=JOB_WEDDING;
	
	if(sd->sc.data[SC_XMAS].timer != -1 && sd->view_class != JOB_XMAS)
		sd->view_class=JOB_XMAS;

	if(b_class != sd->view_class) {
		clif_changelook(&sd->bl,LOOK_BASE,sd->view_class);
#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
	//Restoring cloth dye color after the view class changes. [Skotlex]
	// Added Xmas Suit [Valaris]
	if(battle_config.save_clothcolor && sd->status.clothes_color > 0 &&
		((sd->view_class != JOB_WEDDING && sd->view_class !=JOB_XMAS) || (sd->view_class==JOB_WEDDING && !battle_config.wedding_ignorepalette) ||
			 (sd->view_class==JOB_XMAS && !battle_config.xmas_ignorepalette)))
			clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color);
	}

	if( memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)) || b_attackrange != sd->attackrange)
		clif_skillinfoblock(sd);

	if(b_speed != sd->speed)
		clif_updatestatus(sd,SP_SPEED);
	if(b_weight != sd->weight)
		clif_updatestatus(sd,SP_WEIGHT);
	if(b_max_weight != sd->max_weight) {
		clif_updatestatus(sd,SP_MAXWEIGHT);
		pc_checkweighticon(sd);
	}
	for(i=0;i<6;i++)
		if(b_paramb[i] + b_parame[i] != sd->paramb[i] + sd->parame[i])
			clif_updatestatus(sd,SP_STR+i);
	if(b_hit != sd->hit)
		clif_updatestatus(sd,SP_HIT);
	if(b_flee != sd->flee)
		clif_updatestatus(sd,SP_FLEE1);
	if(b_aspd != sd->aspd)
		clif_updatestatus(sd,SP_ASPD);
	if(b_watk != sd->right_weapon.watk + sd->left_weapon.watk || b_base_atk != sd->base_atk)
		clif_updatestatus(sd,SP_ATK1);
	if(b_def != sd->def)
		clif_updatestatus(sd,SP_DEF1);
	if(b_watk2 != sd->right_weapon.watk2 + sd->left_weapon.watk2)
		clif_updatestatus(sd,SP_ATK2);
	if(b_def2 != sd->def2)
		clif_updatestatus(sd,SP_DEF2);
	if(b_flee2 != sd->flee2)
		clif_updatestatus(sd,SP_FLEE2);
	if(b_critical != sd->critical)
		clif_updatestatus(sd,SP_CRITICAL);
	if(b_matk1 != sd->matk1)
		clif_updatestatus(sd,SP_MATK1);
	if(b_matk2 != sd->matk2)
		clif_updatestatus(sd,SP_MATK2);
	if(b_mdef != sd->mdef)
		clif_updatestatus(sd,SP_MDEF1);
	if(b_mdef2 != sd->mdef2)
		clif_updatestatus(sd,SP_MDEF2);
	if(b_attackrange != sd->attackrange)
		clif_updatestatus(sd,SP_ATTACKRANGE);
	if(b_max_hp != sd->status.max_hp)
		clif_updatestatus(sd,SP_MAXHP);
	if(b_max_sp != sd->status.max_sp)
		clif_updatestatus(sd,SP_MAXSP);
	if(b_hp != sd->status.hp)
		clif_updatestatus(sd,SP_HP);
	if(b_sp != sd->status.sp)
		clif_updatestatus(sd,SP_SP);

	/* I don't think there's a need for this here. It should be handled in pc_damage and pc_heal. [Skotlex]
	if(sd->status.hp<sd->status.max_hp>>2 && sd->sc.data[SC_AUTOBERSERK].timer!=-1 &&
		(sd->sc.data[SC_PROVOKE].timer==-1 || sd->sc.data[SC_PROVOKE].val2==0) && !pc_isdead(sd))
		status_change_start(&sd->bl,SC_PROVOKE,100,10,1,0,0,0,0);
	*/
	calculating = 0;
	return 0;
}

/*==========================================
 * Apply shared stat mods from status changes [DracoRPG]
 *------------------------------------------
 */
int status_calc_str(struct block_list *bl, int str)
{
	struct status_change *sc;
	nullpo_retr(str,bl);
	sc= status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_INCALLSTATUS].timer!=-1)
			str += sc->data[SC_INCALLSTATUS].val1;
		if(sc->data[SC_INCSTR].timer!=-1)
			str += sc->data[SC_INCSTR].val1;
		if(sc->data[SC_STRFOOD].timer!=-1)
			str += sc->data[SC_STRFOOD].val1;
		if(sc->data[SC_LOUD].timer!=-1)
			str += 4;
  		if(sc->data[SC_TRUESIGHT].timer!=-1)
			str += 5;
		if(sc->data[SC_SPURT].timer!=-1)
			str += 10; //Bonus is +!0 regardless of skill level
		if(sc->data[SC_BLESSING].timer != -1){
			int race = status_get_race(bl);
			if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6)
				str >>= 1;
			else str += sc->data[SC_BLESSING].val1;
		}
	}

	return str;
}

int status_calc_agi(struct block_list *bl, int agi)
{
	struct status_change *sc;
	nullpo_retr(agi,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_INCALLSTATUS].timer!=-1)
			agi += sc->data[SC_INCALLSTATUS].val1;
		if(sc->data[SC_INCAGI].timer!=-1)
			agi += sc->data[SC_INCAGI].val1;
		if(sc->data[SC_AGIFOOD].timer!=-1)
			agi += sc->data[SC_AGIFOOD].val1;
  		if(sc->data[SC_TRUESIGHT].timer!=-1)
			agi += 5;
		if(sc->data[SC_INCREASEAGI].timer!=-1)
			agi += 2 + sc->data[SC_INCREASEAGI].val1;
		if(sc->data[SC_DECREASEAGI].timer!=-1)
			agi -= 2 + sc->data[SC_DECREASEAGI].val1;
		if(sc->data[SC_QUAGMIRE].timer!=-1)
			agi -= sc->data[SC_QUAGMIRE].val1*(bl->type==BL_PC?5:10);
	}

	return agi;
}

int status_calc_vit(struct block_list *bl, int vit)
{
	struct status_change *sc;
	nullpo_retr(vit,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_INCALLSTATUS].timer!=-1)
			vit += sc->data[SC_INCALLSTATUS].val1;
		if(sc->data[SC_INCVIT].timer!=-1)
			vit += sc->data[SC_INCVIT].val1;
		if(sc->data[SC_VITFOOD].timer!=-1)
			vit += sc->data[SC_VITFOOD].val1;
  		if(sc->data[SC_TRUESIGHT].timer!=-1)
			vit += 5;
		if(sc->data[SC_STRIPARMOR].timer!=-1 && bl->type != BL_PC)
			vit -= vit * 8*sc->data[SC_STRIPARMOR].val1/100;
	}

	return vit;
}

int status_calc_int(struct block_list *bl, int int_)
{
	struct status_change *sc;
	nullpo_retr(int_,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_INCALLSTATUS].timer!=-1)
			int_ += sc->data[SC_INCALLSTATUS].val1;
		if(sc->data[SC_INCINT].timer!=-1)
			int_ += sc->data[SC_INCINT].val1;
		if(sc->data[SC_INTFOOD].timer!=-1)
			int_ += sc->data[SC_INTFOOD].val1;
  		if(sc->data[SC_TRUESIGHT].timer!=-1)
			int_ += 5;
		if(sc->data[SC_BLESSING].timer != -1){
			int race = status_get_race(bl);
			if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6)
				int_ >>= 1;
			else int_ += sc->data[SC_BLESSING].val1;
		}
		if(sc->data[SC_STRIPHELM].timer!=-1 && bl->type != BL_PC)
			int_ -= int_ * 8*sc->data[SC_STRIPHELM].val1/100;
	}

	return int_;
}

int status_calc_dex(struct block_list *bl, int dex)
{
	struct status_change *sc;
	nullpo_retr(dex,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_INCALLSTATUS].timer!=-1)
			dex += sc->data[SC_INCALLSTATUS].val1;
		if(sc->data[SC_INCDEX].timer!=-1)
			dex += sc->data[SC_INCDEX].val1;
		if(sc->data[SC_DEXFOOD].timer!=-1)
			dex += sc->data[SC_DEXFOOD].val1;
  		if(sc->data[SC_TRUESIGHT].timer!=-1)
			dex += 5;
		if(sc->data[SC_QUAGMIRE].timer!=-1)
			dex -= sc->data[SC_QUAGMIRE].val1*(bl->type==BL_PC?5:10);
		if(sc->data[SC_BLESSING].timer != -1){
			int race = status_get_race(bl);
			if(battle_check_undead(race,status_get_elem_type(bl)) || race == 6)
				dex >>= 1;
			else dex += sc->data[SC_BLESSING].val1;
		}
	}

	return dex;
}

int status_calc_luk(struct block_list *bl, int luk)
{
	struct status_change *sc;
	nullpo_retr(luk,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_INCALLSTATUS].timer!=-1)
			luk += sc->data[SC_INCALLSTATUS].val1;
		if(sc->data[SC_INCLUK].timer!=-1)
			luk += sc->data[SC_INCLUK].val1;
		if(sc->data[SC_LUKFOOD].timer!=-1)
			luk += sc->data[SC_LUKFOOD].val1;
  		if(sc->data[SC_TRUESIGHT].timer!=-1)
			luk += 5;
  		if(sc->data[SC_GLORIA].timer!=-1)
			luk += 30;
	}

	return luk;
}

int status_calc_batk(struct block_list *bl, int batk)
{
	struct status_change *sc;
	nullpo_retr(batk,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_ATKPOTION].timer!=-1)
			batk += sc->data[SC_ATKPOTION].val1;
		if(sc->data[SC_BATKFOOD].timer!=-1)
			batk += sc->data[SC_BATKFOOD].val1;
		if(sc->data[SC_INCATKRATE].timer!=-1)
			batk += batk * sc->data[SC_INCATKRATE].val1/100;
		if(sc->data[SC_PROVOKE].timer!=-1)
			batk += batk * (2+3*sc->data[SC_PROVOKE].val1)/100;
		if(sc->data[SC_CONCENTRATION].timer!=-1)
			batk += batk * 5*sc->data[SC_CONCENTRATION].val1/100;
		if(sc->data[SC_SKE].timer!=-1)
			batk += batk * 3;
		if(sc->data[SC_JOINTBEAT].timer!=-1 && sc->data[SC_JOINTBEAT].val2==4)
  			batk -= batk * 25/100;
		if(sc->data[SC_CURSE].timer!=-1)
  			batk -= batk * 25/100;
		if(sc->data[SC_BLEEDING].timer != -1)
			batk -= batk * 25/100;
	}

	return batk;
}

int status_calc_watk(struct block_list *bl, int watk)
{
	struct status_change *sc;
	nullpo_retr(watk,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_IMPOSITIO].timer!=-1)
			watk += 5*sc->data[SC_IMPOSITIO].val1;
		if(sc->data[SC_WATKFOOD].timer!=-1)
			watk += sc->data[SC_WATKFOOD].val1;
		if(sc->data[SC_DRUMBATTLE].timer!=-1)
			watk += sc->data[SC_DRUMBATTLE].val2;
		if(sc->data[SC_VOLCANO].timer!=-1 && status_get_elem_type(bl)==3)
			watk += sc->data[SC_VOLCANO].val3;
		if(sc->data[SC_INCATKRATE].timer!=-1)
			watk += watk * sc->data[SC_INCATKRATE].val1/100;
		if(sc->data[SC_PROVOKE].timer!=-1)
			watk += watk * (2+3*sc->data[SC_PROVOKE].val1)/100;
		if(sc->data[SC_CONCENTRATION].timer!=-1)
			watk += watk * 5*sc->data[SC_CONCENTRATION].val1/100;
		if(sc->data[SC_SKE].timer!=-1)
			watk += watk * 3;
		if(sc->data[SC_NIBELUNGEN].timer!=-1 && bl->type != BL_PC && (status_get_element(bl)/10)>=8)
			watk += sc->data[SC_NIBELUNGEN].val2;
		if(sc->data[SC_CURSE].timer!=-1)
			watk -= watk * 25/100;
		if(sc->data[SC_STRIPWEAPON].timer!=-1 && bl->type != BL_PC)
			watk -= watk * 5*sc->data[SC_STRIPWEAPON].val1/100;
	}
	return watk;
}

int status_calc_matk(struct block_list *bl, int matk)
{
	struct status_change *sc;
	nullpo_retr(matk,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_MATKPOTION].timer!=-1)
			matk += sc->data[SC_MATKPOTION].val1;
		if(sc->data[SC_MATKFOOD].timer!=-1)
			matk += sc->data[SC_MATKFOOD].val1;
		if(sc->data[SC_MAGICPOWER].timer!=-1)
			matk += matk * 5*sc->data[SC_MAGICPOWER].val1/100;
		if(sc->data[SC_MINDBREAKER].timer!=-1)
			matk += matk * 20*sc->data[SC_MINDBREAKER].val1/100;
		if(sc->data[SC_INCMATKRATE].timer!=-1)
			matk += matk * sc->data[SC_INCMATKRATE].val1/100;
	}

	return matk;
}

int status_calc_critical(struct block_list *bl, int critical)
{
	struct status_change *sc;
	nullpo_retr(critical,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if (sc->data[SC_EXPLOSIONSPIRITS].timer!=-1)
			critical += sc->data[SC_EXPLOSIONSPIRITS].val2;
		if (sc->data[SC_FORTUNE].timer!=-1)
			critical += sc->data[SC_FORTUNE].val2*10;
		if (sc->data[SC_TRUESIGHT].timer!=-1)
			critical += sc->data[SC_TRUESIGHT].val1*10;
		if(sc->data[SC_CLOAKING].timer!=-1)
			critical += critical;
	}

	return critical;
}

int status_calc_hit(struct block_list *bl, int hit)
{
	struct status_change *sc;
	nullpo_retr(hit,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_INCHIT].timer != -1)
			hit += sc->data[SC_INCHIT].val1;
		if(sc->data[SC_HITFOOD].timer!=-1)
			hit += sc->data[SC_HITFOOD].val1;
		if(sc->data[SC_TRUESIGHT].timer != -1)
			hit += 3*sc->data[SC_TRUESIGHT].val1;
		if(sc->data[SC_HUMMING].timer!=-1)
			hit += sc->data[SC_HUMMING].val2;
		if(sc->data[SC_CONCENTRATION].timer != -1)
			hit += 10*sc->data[SC_CONCENTRATION].val1;
		if(sc->data[SC_INCHITRATE].timer != -1)
			hit += hit * sc->data[SC_INCHITRATE].val1/100;
		if(sc->data[SC_BLIND].timer != -1)
			hit -= hit * 25 / 100;
	}

	return hit;
}

int status_calc_flee(struct block_list *bl, int flee)
{
	struct status_change *sc;
	nullpo_retr(flee,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_INCFLEE].timer!=-1)
			flee += sc->data[SC_INCFLEE].val1;
		if(sc->data[SC_FLEEFOOD].timer!=-1)
			flee += sc->data[SC_FLEEFOOD].val1;
		if(sc->data[SC_WHISTLE].timer!=-1)
			flee += sc->data[SC_WHISTLE].val2;
		if(sc->data[SC_WINDWALK].timer!=-1)
			flee += flee * sc->data[SC_WINDWALK].val2/100;
		if(sc->data[SC_INCFLEERATE].timer!=-1)
			flee += flee * sc->data[SC_INCFLEERATE].val1/100;
		if(sc->data[SC_VIOLENTGALE].timer!=-1 && status_get_elem_type(bl)==4)
			flee += flee * sc->data[SC_VIOLENTGALE].val3/100;
		if(sc->data[SC_MOON_COMFORT].timer!=-1) //SG skill [Komurka]
			flee += (status_get_lv(bl) + status_get_dex(bl) + status_get_luk(bl))/10;
		if(sc->data[SC_CLOSECONFINE].timer!=-1)
			flee += 10;
		if(sc->data[SC_SPIDERWEB].timer!=-1)
			flee -= flee * 50/100;
		if(sc->data[SC_BERSERK].timer!=-1)
			flee -= flee * 50/100;
		if(sc->data[SC_BLIND].timer!=-1)
			flee -= flee * 25/100;
	}

	if (bl->type == BL_PC && map_flag_gvg(bl->m)) //GVG grounds flee penalty, placed here because it's "like" a status change. [Skotlex]
		flee -= flee * battle_config.gvg_flee_penalty/100;
	return flee;
}

int status_calc_flee2(struct block_list *bl, int flee2)
{
	struct status_change *sc;
	nullpo_retr(flee2,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_WHISTLE].timer!=-1)
			flee2 += sc->data[SC_WHISTLE].val3*10;
	}

	return flee2;
}

int status_calc_def(struct block_list *bl, int def)
{
	struct status_change *sc;
	nullpo_retr(def,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_BERSERK].timer!=-1)
			return 0;
		if(sc->data[SC_KEEPING].timer!=-1)
			return 100;
		if(sc->data[SC_STEELBODY].timer!=-1)
			return 90;
		if(sc->data[SC_SKA].timer != -1) // [marquis007]
			return 90;
		if(sc->data[SC_DRUMBATTLE].timer!=-1)
			def += sc->data[SC_DRUMBATTLE].val3;
		if(sc->data[SC_INCDEFRATE].timer!=-1)
			def += def * sc->data[SC_INCDEFRATE].val1/100;
		if(sc->data[SC_SIGNUMCRUCIS].timer!=-1)
			def -= def * sc->data[SC_SIGNUMCRUCIS].val2/100;
		if(sc->data[SC_CONCENTRATION].timer!=-1)
			def -= def * 5*sc->data[SC_CONCENTRATION].val1/100;
		if(sc->data[SC_SKE].timer!=-1)
			def -= def  * 50/100;
		if(sc->data[SC_PROVOKE].timer!=-1 && bl->type != BL_PC) // Provoke doesn't alter player defense.
			def -= def * (5+5*sc->data[SC_PROVOKE].val1)/100;
		if(sc->data[SC_STRIPSHIELD].timer!=-1 && bl->type != BL_PC)
			def -= def * 3*sc->data[SC_STRIPSHIELD].val1/100;
	}

	return def;
}

int status_calc_def2(struct block_list *bl, int def2)
{
	struct status_change *sc;
	nullpo_retr(def2,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_BERSERK].timer!=-1)
			return 0;
		if(sc->data[SC_ETERNALCHAOS].timer!=-1)
			return 0;
		if(sc->data[SC_SUN_COMFORT].timer!=-1)
			def2 += (status_get_lv(bl) + status_get_dex(bl) + status_get_luk(bl))/2;
		if(sc->data[SC_ANGELUS].timer!=-1)
			def2 += def2 * (10+5*sc->data[SC_ANGELUS].val1)/100;
		if(sc->data[SC_CONCENTRATION].timer!=-1)
			def2 -= def2 * 5*sc->data[SC_CONCENTRATION].val1/100;
		if(sc->data[SC_POISON].timer!=-1)
			def2 -= def2 * 25/100;
		if(sc->data[SC_SKE].timer!=-1)
			def2 -= def2 * 50/100;
		if(sc->data[SC_PROVOKE].timer!=-1)
			def2 -= def2 * (5+5*sc->data[SC_PROVOKE].val1)/100;
		if(sc->data[SC_SKE].timer!=-1)
			def2 /= 2;
		if(sc->data[SC_JOINTBEAT].timer!=-1){
			if(sc->data[SC_JOINTBEAT].val2==3)
				def2 -= def2 * 50/100;
			else if(sc->data[SC_JOINTBEAT].val2==4)
				def2 -= def2 * 25/100;
		}
	}

	return def2;
}

int status_calc_mdef(struct block_list *bl, int mdef)
{
	struct status_change *sc;
	nullpo_retr(mdef,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_BERSERK].timer!=-1)
			return 0;
		if(sc->data[SC_BARRIER].timer!=-1)
			return 100;
		if(sc->data[SC_STEELBODY].timer!=-1)
			return 90;
		if(sc->data[SC_SKA].timer != -1) // [marquis007]
			return 90; // should it up mdef too?
		if(sc->data[SC_ENDURE].timer!=-1)
			mdef += sc->data[SC_ENDURE].val1;
	}

	return mdef;
}

int status_calc_mdef2(struct block_list *bl, int mdef2)
{
	struct status_change *sc;
	nullpo_retr(mdef2,bl);
	sc = status_get_sc(bl);

	if(sc && sc->count){
		if(sc->data[SC_BERSERK].timer!=-1)
			return 0;
		if(sc->data[SC_MINDBREAKER].timer!=-1)
			mdef2 -= mdef2 * 12*sc->data[SC_MINDBREAKER].val1/100;
	}

	return mdef2;
}

int status_calc_speed(struct block_list *bl, int speed)
{
	struct status_change *sc;
	sc = status_get_sc(bl);

	if(sc && sc->count) {
		if(sc->data[SC_CURSE].timer!=-1)
			speed += 450;
		if(sc->data[SC_SWOO].timer != -1) // [marquis007]
			speed += 450; //Let's use Curse's slow down momentarily (exact value unknown)
		if(sc->data[SC_SPEEDUP1].timer!=-1)
			speed -= speed*50/100;
		else if(sc->data[SC_SPEEDUP0].timer!=-1)
			speed -= speed*25/100;
		else if(sc->data[SC_INCREASEAGI].timer!=-1)
			speed -= speed * 25/100;
		else if(sc->data[SC_CARTBOOST].timer!=-1)
			speed -= speed * 20/100;
		else if(sc->data[SC_BERSERK].timer!=-1)
			speed -= speed * 20/100;
		else if(sc->data[SC_WINDWALK].timer!=-1)
			speed -= speed * 4*sc->data[SC_WINDWALK].val2/100;
		if(sc->data[SC_WEDDING].timer!=-1)
			speed += speed * 50/100;
		if(sc->data[SC_SLOWDOWN].timer!=-1)
			speed += speed * 50/100;
		if(sc->data[SC_DECREASEAGI].timer!=-1)
			speed += speed * 25/100;
		if(sc->data[SC_STEELBODY].timer!=-1)
			speed += speed * 25/100;
		if(sc->data[SC_SKA].timer!=-1)
			speed += speed * 25/100;
		if(sc->data[SC_QUAGMIRE].timer!=-1)
			speed += speed * 50/100;
		if(sc->data[SC_DONTFORGETME].timer!=-1)
			speed += speed * sc->data[SC_DONTFORGETME].val3/100;
		if(sc->data[SC_DEFENDER].timer!=-1)
			speed += speed * (55-5*sc->data[SC_DEFENDER].val1)/100;
		if(sc->data[SC_GOSPEL].timer!=-1 && sc->data[SC_GOSPEL].val4 == BCT_ENEMY)
			speed += speed * 25/100;
		if(sc->data[SC_JOINTBEAT].timer!=-1) {
			if (sc->data[SC_JOINTBEAT].val2 == 0)
				speed += speed * 50/100;
			else if (sc->data[SC_JOINTBEAT].val2 == 2)
				speed += speed * 30/100;
		}
		if(sc->data[SC_CLOAKING].timer!=-1)
			speed = speed * (sc->data[SC_CLOAKING].val3-3*sc->data[SC_CLOAKING].val1) /100;
		if(sc->data[SC_CHASEWALK].timer!=-1)
			speed = speed * sc->data[SC_CHASEWALK].val3/100;
		if(sc->data[SC_RUN].timer!=-1)/*�삯���ɂ�鑬�x�ω�*/
			speed -= speed * 25/100;
	}

	return speed;
}

int status_calc_aspd_rate(struct block_list *bl, int aspd_rate)
{
	struct status_change *sc;
	sc = status_get_sc(bl);

	if(sc && sc->count) {
		int i;
		if(sc->data[SC_QUAGMIRE].timer==-1 && sc->data[SC_DONTFORGETME].timer==-1){
			if(sc->data[SC_TWOHANDQUICKEN].timer!=-1)
				aspd_rate -= 30;
			else if(sc->data[SC_ONEHAND].timer!=-1)
				aspd_rate -= 30;
			else if(sc->data[SC_ADRENALINE2].timer!=-1)
				aspd_rate -= (sc->data[SC_ADRENALINE2].val2 || !battle_config.party_skill_penalty)?30:20;
			else if(sc->data[SC_ADRENALINE].timer!=-1)
				aspd_rate -= (sc->data[SC_ADRENALINE].val2 || !battle_config.party_skill_penalty)?30:20;
			else if(sc->data[SC_SPEARSQUICKEN].timer!=-1)
				aspd_rate -= sc->data[SC_SPEARSQUICKEN].val2;
			else if(sc->data[SC_ASSNCROS].timer!=-1 && (bl->type!=BL_PC || ((struct map_session_data*)bl)->status.weapon != 11))
				aspd_rate -= sc->data[SC_ASSNCROS].val2;
		}
		if(sc->data[SC_BERSERK].timer!=-1)
			aspd_rate -= 30;
		if(sc->data[i=SC_ASPDPOTION3].timer!=-1 || sc->data[i=SC_ASPDPOTION2].timer!=-1 || sc->data[i=SC_ASPDPOTION1].timer!=-1 || sc->data[i=SC_ASPDPOTION0].timer!=-1)
			aspd_rate -= sc->data[i].val2;
		if(sc->data[SC_DONTFORGETME].timer!=-1)
			aspd_rate += sc->data[SC_DONTFORGETME].val2;
		if(sc->data[SC_STEELBODY].timer!=-1)
			aspd_rate += 25;
		if(sc->data[SC_SKA].timer!=-1)
			aspd_rate += 25;
		if(sc->data[SC_DEFENDER].timer != -1)
			aspd_rate += 25 -sc->data[SC_DEFENDER].val1*5;
		if(sc->data[SC_GOSPEL].timer!=-1 && sc->data[SC_GOSPEL].val4 == BCT_ENEMY)
			aspd_rate += 25;
		if(sc->data[SC_GRAVITATION].timer!=-1)
			aspd_rate += sc->data[SC_GRAVITATION].val2;
		if(sc->data[SC_BLEEDING].timer != -1)
			aspd_rate += 25;
		if(sc->data[SC_JOINTBEAT].timer!=-1) {
			if (sc->data[SC_JOINTBEAT].val2 == 1)
				aspd_rate += 25;
			else if (sc->data[SC_JOINTBEAT].val2 == 2)
				aspd_rate += 10;
		}
		if(sc->data[SC_STAR_COMFORT].timer!=-1)
			aspd_rate -= (status_get_lv(bl) + status_get_dex(bl) + status_get_luk(bl))/10;
	}

	return aspd_rate;
}

int status_calc_maxhp(struct block_list *bl, int maxhp)
{
	struct status_change *sc;
	sc = status_get_sc(bl);

	if(sc && sc->count) {
		if(sc->data[SC_INCMHPRATE].timer!=-1)
			maxhp += maxhp * sc->data[SC_INCMHPRATE].val1/100;
		if(sc->data[SC_APPLEIDUN].timer!=-1)
			maxhp += maxhp * sc->data[SC_APPLEIDUN].val2/100;
		if(sc->data[SC_DELUGE].timer!=-1 && status_get_elem_type(bl)==1)
			maxhp += maxhp * deluge_eff[sc->data[SC_DELUGE].val1-1]/100;
		if(sc->data[SC_BERSERK].timer!=-1)
			maxhp += maxhp * 2;
	}

	return maxhp;
}

int status_calc_maxsp(struct block_list *bl, int maxsp)
{
	struct status_change *sc;
	sc = status_get_sc(bl);

	if(sc && sc->count) {
		if(sc->data[SC_INCMSPRATE].timer!=-1)
			maxsp += maxsp * sc->data[SC_INCMSPRATE].val1/100;
		if(sc->data[SC_SERVICE4U].timer!=-1)
			maxsp += maxsp * sc->data[SC_SERVICE4U].val2/100;
	}

	return maxsp;
}

/*==========================================
 * For quick calculating [Celest] Adapted by [Skotlex]
 *------------------------------------------
 */
int status_quick_recalc_speed(struct map_session_data *sd, int skill_num, int skill_lv, char start)
{
	/*	[Skotlex]
	This function individually changes a character's speed upon a skill change and restores it upon it's ending.
	Should only be used on non-inclusive skills to avoid exploits.
	Currently used for freedom of cast
	and when cloaking changes it's val3 (in which case the new val3 value comes in the level.
	*/
	
	int b_speed;
	
	b_speed = sd->speed;
	
	switch (skill_num)
	{
		case SA_FREECAST:
			if (start)
			{
				sd->prev_speed = sd->speed;
				sd->speed = sd->speed*(175 - skill_lv*5)/100;
			}
			else
				sd->speed = sd->prev_speed;
			break;
		case AS_CLOAKING:
			if (start && sd->sc.data[SC_CLOAKING].timer != -1)
			{	//There shouldn't be an "stop" case here.
				//If the previous upgrade was 
				//SPEED_ADD_RATE(3*sd->sc.data[SC_CLOAKING].val1 -sd->sc.data[SC_CLOAKING].val3);
				//Then just changing val3 should be a net difference of....
				if (3*sd->sc.data[SC_CLOAKING].val1 != sd->sc.data[SC_CLOAKING].val3)	//This reverts the previous value.
					sd->speed = sd->speed * 100 /(sd->sc.data[SC_CLOAKING].val3-3*sd->sc.data[SC_CLOAKING].val1);
				sd->sc.data[SC_CLOAKING].val3 = skill_lv;
					sd->speed = sd->speed * (sd->sc.data[SC_CLOAKING].val3-sd->sc.data[SC_CLOAKING].val1*3) /100;
			}
			break;
	}

	if(sd->speed < battle_config.max_walk_speed)
		sd->speed = battle_config.max_walk_speed;

	if(b_speed != sd->speed)
		clif_updatestatus(sd,SP_SPEED);

	return 0;
}

/*==========================================
 * �Ώۂ�Class��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_class(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_MOB)
		return ((struct mob_data *)bl)->class_;
	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->status.class_;
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->class_;
	return 0;
}
/*==========================================
 * �Ώۂ̕�����Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_dir(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_MOB)
		return ((struct mob_data *)bl)->dir;
	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->dir;
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->dir;
	return 0;
}
/*==========================================
 * �Ώۂ̃��x����Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_lv(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_MOB)
		return ((struct mob_data *)bl)->level;
	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->status.base_level;
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->msd->pet.level;
	return 0;
}

/*==========================================
 * �Ώۂ̎˒���Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_range(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_MOB)
		return ((struct mob_data *)bl)->db->range;
	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->attackrange;
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->db->range;
	return 0;
}
/*==========================================
 * �Ώۂ�HP��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_hp(struct block_list *bl)
{
	nullpo_retr(1, bl);
	if(bl->type==BL_MOB)
		return ((struct mob_data *)bl)->hp;
	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->status.hp;
	return 1;
}
/*==========================================
 * �Ώۂ�MHP��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_max_hp(struct block_list *bl)
{
	nullpo_retr(1, bl);

	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->status.max_hp;
	else {
		int max_hp = 1;

		if(bl->type == BL_MOB) {
			struct mob_data *md;
			nullpo_retr(1, md = (struct mob_data *)bl);
			max_hp = md->max_hp;

			if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris]
				max_hp += (md->level - md->db->lv) * status_get_vit(bl);

		}
		else if(bl->type == BL_PET) {
			struct pet_data *pd;
			nullpo_retr(1, pd = (struct pet_data*)bl);
			max_hp = pd->db->max_hp;
		}

		max_hp = status_calc_maxhp(bl,max_hp);
		if(max_hp < 1) max_hp = 1;
		return max_hp;
	}
}
/*==========================================
 * �Ώۂ�Str��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_str(struct block_list *bl)
{
	int str = 0;
	nullpo_retr(0, bl);

	if (bl->type == BL_PC)
		return ((struct map_session_data *)bl)->paramc[0];
	else {
		if(bl->type == BL_MOB) {
			str = ((struct mob_data *)bl)->db->str;
			if(battle_config.mobs_level_up) // mobs leveling up increase [Valaris]
				str += ((struct mob_data *)bl)->level - ((struct mob_data *)bl)->db->lv;
			if(((struct mob_data*)bl)->special_state.size==1) // change for sized monsters [Valaris]
				str/=2;
			else if(((struct mob_data*)bl)->special_state.size==2)
				str*=2;
		} else if(bl->type == BL_PET){	//<Skotlex> Use pet's stats
			if (battle_config.pet_lv_rate && ((struct pet_data *)bl)->status)
				str = ((struct pet_data *)bl)->status->str;
			else
				str = ((struct pet_data *)bl)->db->str;
		}

		str = status_calc_str(bl,str);
	}
	if(str < 0) str = 0;
	return str;
}
/*==========================================
 * �Ώۂ�Agi��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */

int status_get_agi(struct block_list *bl)
{
	int agi=0;
	nullpo_retr(0, bl);

	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->paramc[1];
	else {
		if(bl->type == BL_MOB) {
			agi = ((struct mob_data *)bl)->db->agi;
			if(battle_config.mobs_level_up) // increase of mobs leveling up [Valaris]
				agi += ((struct mob_data *)bl)->level - ((struct mob_data *)bl)->db->lv;
			if(((struct mob_data*)bl)->special_state.size==1) // change for sized monsters [Valaris]
				agi/=2;
			else if(((struct mob_data*)bl)->special_state.size==2)
				agi*=2;
		} else if(bl->type == BL_PET) {	//<Skotlex> Use pet's stats
			if (battle_config.pet_lv_rate && ((struct pet_data *)bl)->status)
				agi = ((struct pet_data *)bl)->status->agi;
			else
				agi = ((struct pet_data *)bl)->db->agi;
		}

		agi = status_calc_agi(bl,agi);
	}
	if(agi < 0) agi = 0;
	return agi;
}
/*==========================================
 * �Ώۂ�Vit��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_vit(struct block_list *bl)
{
	int vit = 0;
	nullpo_retr(0, bl);

	if(bl->type == BL_PC)
		return ((struct map_session_data *)bl)->paramc[2];
	else {
		if(bl->type == BL_MOB) {
			vit = ((struct mob_data *)bl)->db->vit;
			if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
				vit += ((struct mob_data *)bl)->level - ((struct mob_data *)bl)->db->lv;
			if(((struct mob_data*)bl)->special_state.size==1) // change for sizes monsters [Valaris]
				vit/=2;
			else if(((struct mob_data*)bl)->special_state.size==2)
				vit*=2;
		} else if(bl->type == BL_PET) {	//<Skotlex> Use pet's stats
			if (battle_config.pet_lv_rate && ((struct pet_data *)bl)->status)
				vit = ((struct pet_data *)bl)->status->vit;
			else
				vit = ((struct pet_data *)bl)->db->vit;
		}

		vit = status_calc_vit(bl,vit);
	}
	if(vit < 0) vit = 0;
	return vit;
}
/*==========================================
 * �Ώۂ�Int��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_int(struct block_list *bl)
{
	int int_=0;
	nullpo_retr(0, bl);

	if(bl->type == BL_PC)
		return ((struct map_session_data *)bl)->paramc[3];
	else {
		if(bl->type == BL_MOB) {
			int_ = ((struct mob_data *)bl)->db->int_;
			if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
				int_ += ((struct mob_data *)bl)->level - ((struct mob_data *)bl)->db->lv;
			if(((struct mob_data*)bl)->special_state.size==1) // change for sized monsters [Valaris]
				int_/=2;
			else if(((struct mob_data*)bl)->special_state.size==2)
				int_*=2;
		} else if(bl->type == BL_PET) {	//<Skotlex> Use pet's stats
			if (battle_config.pet_lv_rate && ((struct pet_data *)bl)->status)
				int_ = ((struct pet_data *)bl)->status->int_;
			else
				int_ = ((struct pet_data *)bl)->db->int_;
		}

		int_ = status_calc_int(bl,int_);
	}
	if(int_ < 0) int_ = 0;
	return int_;
}
/*==========================================
 * �Ώۂ�Dex��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_dex(struct block_list *bl)
{
	int dex = 0;
	nullpo_retr(0, bl);

	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->paramc[4];
	else {
		if(bl->type == BL_MOB) {
			dex = ((struct mob_data *)bl)->db->dex;
			if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
				dex += ((struct mob_data *)bl)->level - ((struct mob_data *)bl)->db->lv;
			if(((struct mob_data*)bl)->special_state.size==1) // change for sized monsters [Valaris]
				dex/=2;
			else if(((struct mob_data*)bl)->special_state.size==2)
				dex*=2;
		} else if(bl->type == BL_PET) {	//<Skotlex> Use pet's stats
			if (battle_config.pet_lv_rate && ((struct pet_data *)bl)->status)
				dex = ((struct pet_data *)bl)->status->dex;
			else
				dex = ((struct pet_data *)bl)->db->dex;
		}

		dex = status_calc_dex(bl,dex);
	}
	if(dex < 0) dex = 0;
	return dex;
}
/*==========================================
 * �Ώۂ�Luk��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_luk(struct block_list *bl)
{
	int luk = 0;
	nullpo_retr(0, bl);

	if(bl->type == BL_PC)
		return ((struct map_session_data *)bl)->paramc[5];
	else {
		if(bl->type == BL_MOB) {
			luk = ((struct mob_data *)bl)->db->luk;
			if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
				luk += ((struct mob_data *)bl)->level - ((struct mob_data *)bl)->db->lv;
			if(((struct mob_data*)bl)->special_state.size==1) // change for sized monsters [Valaris]
				luk/=2;
			else if(((struct mob_data*)bl)->special_state.size==2)
				luk*=2;
		} else if(bl->type == BL_PET) {	//<Skotlex> Use pet's stats
			if (battle_config.pet_lv_rate && ((struct pet_data *)bl)->status)
				luk = ((struct pet_data *)bl)->status->luk;
			else
				luk = ((struct pet_data *)bl)->db->luk;
		}

		luk = status_calc_luk(bl,luk);
	}
	if(luk < 0) luk = 0;
	return luk;
}

/*==========================================
 * �Ώۂ�Flee��Ԃ�(�ėp)
 * �߂�͐�����1�ȏ�
 *------------------------------------------
 */
int status_get_flee(struct block_list *bl)
{
	int flee = 1;
	nullpo_retr(1, bl);

	if(bl->type == BL_PC)
		return ((struct map_session_data *)bl)->flee;
	
	flee = status_calc_flee(bl,status_get_agi(bl)+status_get_lv(bl));
	if(flee < 1) flee = 1;
	return flee;
}
/*==========================================
 * �Ώۂ�Hit��Ԃ�(�ėp)
 * �߂�͐�����1�ȏ�
 *------------------------------------------
 */
int status_get_hit(struct block_list *bl)
{
	int hit = 1;
	nullpo_retr(1, bl);
	if (bl->type == BL_PC)
		return ((struct map_session_data *)bl)->hit;
	
	hit = status_calc_hit(bl,status_get_dex(bl)+status_get_lv(bl));
	if(hit < 1) hit = 1;
	return hit;
}
/*==========================================
 * �Ώۂ̊��S�����Ԃ�(�ėp)
 * �߂�͐�����1�ȏ�
 *------------------------------------------
 */
int status_get_flee2(struct block_list *bl)
{
	int flee2 = 1;
	nullpo_retr(1, bl);

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

	flee2 = status_calc_flee2(bl,status_get_luk(bl)+10);
	if (flee2 < 1) flee2 = 1;
	return flee2;
}
/*==========================================
 * �Ώۂ̃N���e�B�J����Ԃ�(�ėp)
 * �߂�͐�����1�ȏ�
 *------------------------------------------
 */
int status_get_critical(struct block_list *bl)
{
	int critical = 1;
	nullpo_retr(1, bl);

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

	critical = status_get_luk(bl)*3+10;
	if(battle_config.enemy_critical_rate != 100)
		critical = critical*battle_config.enemy_critical_rate/100;
	critical = status_calc_critical(bl,critical);
	if (critical < 1) critical = 1;
	return critical;
}
/*==========================================
 * base_atk�̎擾
 * �߂�͐�����1�ȏ�
 *------------------------------------------
 */
int status_get_batk(struct block_list *bl)
{
	int batk = 1;
	nullpo_retr(1, bl);
	
	if(bl->type==BL_PC) {
		batk = ((struct map_session_data *)bl)->base_atk;
		if (((struct map_session_data *)bl)->status.weapon < 16)
			batk += ((struct map_session_data *)bl)->weapon_atk[((struct map_session_data *)bl)->status.weapon];
	} else {
		int str,dstr;
		str = status_get_str(bl); //STR
		dstr = str/10;
		batk = dstr*dstr + str; //base_atk���v�Z����

		if(bl->type == BL_MOB && ((struct mob_data *)bl)->guardian_data)
			batk += batk * 10*((struct mob_data *)bl)->guardian_data->guardup_lv/100; // Strengthen Guardians - custom value +10% ATK / lv

		batk = status_calc_batk(bl,batk);
	}
	if(batk < 1) batk = 1; //base_atk�͍Œ�ł�1
	return batk;
}
/*==========================================
 * �Ώۂ�Atk��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_atk(struct block_list *bl)
{
	int atk=0;
	nullpo_retr(0, bl);
	switch (bl->type) {
		case BL_PC:
			return ((struct map_session_data*)bl)->right_weapon.watk;
		case BL_MOB:
			atk = ((struct mob_data*)bl)->db->atk1;
			if(((struct mob_data *)bl)->guardian_data)
				atk += atk * 10*((struct mob_data *)bl)->guardian_data->guardup_lv/100; // Strengthen Guardians - custom value +10% ATK / lv
		break;
		case BL_PET:	//<Skotlex> Use pet's stats
			if (battle_config.pet_lv_rate && ((struct pet_data *)bl)->status)
				atk = ((struct pet_data *)bl)->status->atk1;
			else
				atk = ((struct pet_data*)bl)->db->atk1;
		break;
	}
	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	atk = status_calc_watk(bl,atk);
	if(atk < 0) atk = 0;
	return atk;
}
/*==========================================
 * �Ώۂ̍���Atk��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_atk_(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_PC){
		return ((struct map_session_data*)bl)->left_weapon.watk;
	}
	return 0;
}
/*==========================================
 * �Ώۂ�Atk2��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_atk2(struct block_list *bl)
{
	int atk2=0;
	nullpo_retr(0, bl);

	switch (bl->type) {
		case BL_PC:
			return ((struct map_session_data*)bl)->right_weapon.watk2;
		case BL_MOB:
			atk2 = ((struct mob_data*)bl)->db->atk2;
			
			if(((struct mob_data *)bl)->guardian_data)
				atk2 += atk2 * 10*((struct mob_data *)bl)->guardian_data->guardup_lv/100; // Strengthen Guardians - custom value +10% ATK / lv
		break;
		case BL_PET:	//<Skotlex> Use pet's stats
			if (battle_config.pet_lv_rate && ((struct pet_data *)bl)->status)
				atk2 = ((struct pet_data *)bl)->status->atk2;
			else
				atk2 = ((struct pet_data*)bl)->db->atk2;
		break;
	}		  

	// Absolute, then relative modifiers from status changes (shared between PC and NPC)
	atk2 = status_calc_watk(bl,atk2);

	if(atk2 < 0) atk2 = 0;
		return atk2;
}
/*==========================================
 * �Ώۂ̍���Atk2��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_atk_2(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_PC)
		return ((struct map_session_data*)bl)->left_weapon.watk2;
	return 0;
}
/*==========================================
 * �Ώۂ�MAtk1��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_matk1(struct block_list *bl)
{
	nullpo_retr(0, bl);

	if(bl->type == BL_PC)
		return ((struct map_session_data *)bl)->matk1;
	else {
		int matk = 0;
		int int_ = status_get_int(bl);
		matk = status_calc_matk(bl,int_+(int_/5)*(int_/5));
 		return matk;
	}
}
/*==========================================
 * �Ώۂ�MAtk2��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_matk2(struct block_list *bl)
{
	nullpo_retr(0, bl);

	if(bl->type == BL_PC)
		return ((struct map_session_data *)bl)->matk2;
	else {
        int matk = 0;
		int int_ = status_get_int(bl);
		matk = status_calc_matk(bl,int_+(int_/7)*(int_/7));
		return matk;
	}
}
/*==========================================
 * �Ώۂ�Def��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_def(struct block_list *bl)
{
	int def=0;
	nullpo_retr(0, bl);

	if(bl->type==BL_PC){
		def = ((struct map_session_data *)bl)->def;
		if(((struct map_session_data *)bl)->skilltimer != -1)
			def -= def * skill_get_castdef(((struct map_session_data *)bl)->skillid)/100;
	} else if(bl->type==BL_MOB) {
		def = ((struct mob_data *)bl)->db->def;
		def -= def * skill_get_castdef(((struct mob_data *)bl)->skillid)/100;
	} else if(bl->type==BL_PET)
		def = ((struct pet_data *)bl)->db->def;

	def = status_calc_def(bl,def);
	if(def < 0) def = 0;

	return def;
}
/*==========================================
 * �Ώۂ�Def2��Ԃ�(�ėp)
 * �߂�͐�����1�ȏ�
 *------------------------------------------
 */
int status_get_def2(struct block_list *bl)
{
	int def2 = 1;
	nullpo_retr(1, bl);
	
	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->def2;
	else if(bl->type==BL_MOB)
		def2 = ((struct mob_data *)bl)->db->vit;
	else if(bl->type==BL_PET) {	//<Skotlex> Use pet's stats
		if (battle_config.pet_lv_rate && ((struct pet_data *)bl)->status)
			def2 = ((struct pet_data *)bl)->status->vit;
		else
			def2 = ((struct pet_data *)bl)->db->vit;
	}

	def2 = status_calc_def2(bl,def2);
	if(def2 < 1) def2 = 1;
	
	return def2;
}
/*==========================================
 * �Ώۂ�MDef��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_mdef(struct block_list *bl)
{
	int mdef=0;
	nullpo_retr(0, bl);

	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->mdef;
	else if(bl->type==BL_MOB)
		mdef = ((struct mob_data *)bl)->db->mdef;
	else if(bl->type==BL_PET)
		mdef = ((struct pet_data *)bl)->db->mdef;

	mdef = status_calc_mdef(bl,mdef);
	if(mdef < 0) mdef = 0;

 	return mdef;
}
/*==========================================
 * �Ώۂ�MDef2��Ԃ�(�ėp)
 * �߂�͐�����0�ȏ�
 *------------------------------------------
 */
int status_get_mdef2(struct block_list *bl)
{
	int mdef2=0;
	nullpo_retr(0, bl);

	if(bl->type == BL_PC)
		return ((struct map_session_data *)bl)->mdef2 + (((struct map_session_data *)bl)->paramc[2]>>1);
	else if(bl->type == BL_MOB)
		mdef2 = ((struct mob_data *)bl)->db->int_ + (((struct mob_data *)bl)->db->vit>>1);
	else if(bl->type == BL_PET) {	//<Skotlex> Use pet's stats
		if (battle_config.pet_lv_rate && ((struct pet_data *)bl)->status)
			mdef2 = ((struct pet_data *)bl)->status->int_ +(((struct pet_data *)bl)->status->vit>>1);
		else
			mdef2 = ((struct pet_data *)bl)->db->int_ + (((struct pet_data *)bl)->db->vit>>1);
	}

	mdef2 = status_calc_mdef2(bl,mdef2);
	if(mdef2 < 0) mdef2 = 0;
	
	return mdef2;
}
/*==========================================
 * �Ώۂ�Speed(�ړ����x)��Ԃ�(�ėp)
 * �߂�͐�����1�ȏ�
 * Speed�͏������ق����ړ����x������
 *------------------------------------------
 */
int status_get_speed(struct block_list *bl)
{
	int speed = 1000;
	nullpo_retr(1000, bl);
	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->speed;
	else if(bl->type==BL_MOB) {
		speed = ((struct mob_data *)bl)->speed;
		if(battle_config.mobs_level_up) // increase from mobs leveling up [Valaris]
			speed-=((struct mob_data *)bl)->level - ((struct mob_data *)bl)->db->lv;
	}
	else if(bl->type==BL_PET)
		speed = ((struct pet_data *)bl)->msd->petDB->speed;
	else if(bl->type==BL_NPC)	//Added BL_NPC (Skotlex)
		speed = ((struct npc_data *)bl)->speed;

	speed = status_calc_speed(bl,speed);

	if(speed < 1) speed = 1;
	return speed;
}
/*==========================================
 * �Ώۂ�aDelay(�U�����f�B���C)��Ԃ�(�ėp)
 * aDelay�͏������ق����U�����x������
 *------------------------------------------
 */
int status_get_adelay(struct block_list *bl)
{
	int adelay,aspd_rate;
	nullpo_retr(4000, bl);
	switch (bl->type) {
		case BL_PC:
			return (((struct map_session_data *)bl)->aspd<<1);
		case BL_MOB:
			adelay = ((struct mob_data *)bl)->db->adelay;
			if(((struct mob_data *)bl)->guardian_data)
				aspd_rate = 100 - 10*((struct mob_data *)bl)->guardian_data->guardup_lv; // Strengthen Guardians - custom value +10% ASPD / lv
			else
				aspd_rate = 100;
			break;
		case BL_PET:
			adelay = ((struct pet_data *)bl)->db->adelay;
			aspd_rate = 100;
			break;
		default:
			adelay=4000;
			aspd_rate = 100;
			break;
	}
	aspd_rate = status_calc_aspd_rate(bl,aspd_rate);

	if(aspd_rate != 100)
		adelay = adelay*aspd_rate/100;
	if(adelay < battle_config.monster_max_aspd<<1) adelay = battle_config.monster_max_aspd<<1;
		return adelay;
}
int status_get_amotion(struct block_list *bl)
{
	nullpo_retr(2000, bl);
	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->amotion;
	else {
		int amotion=2000,aspd_rate = 100;
		if(bl->type==BL_MOB) {
			amotion = ((struct mob_data *)bl)->db->amotion;

			if(((struct mob_data *)bl)->guardian_data)
				aspd_rate -= aspd_rate * 10*((struct mob_data *)bl)->guardian_data->guardup_lv/100; // Strengthen Guardians - custom value +10% ASPD / lv
		} else if(bl->type==BL_PET)
			amotion = ((struct pet_data *)bl)->db->amotion;

		aspd_rate = status_calc_aspd_rate(bl,aspd_rate);

		if(aspd_rate != 100)
			amotion = amotion*aspd_rate/100;
		if(amotion < battle_config.monster_max_aspd) amotion = battle_config.monster_max_aspd;
		return amotion;
	}
	return 2000;
}
int status_get_dmotion(struct block_list *bl)
{
	int ret;
	struct status_change *sc;

	nullpo_retr(0, bl);
	sc = status_get_sc(bl);
	if(bl->type==BL_MOB){
		ret=((struct mob_data *)bl)->db->dmotion;
		if(battle_config.monster_damage_delay_rate != 100)
			ret = ret*battle_config.monster_damage_delay_rate/100;
	}
	else if(bl->type==BL_PC){
		ret=((struct map_session_data *)bl)->dmotion;
		if(battle_config.pc_damage_delay_rate != 100)
			ret = ret*battle_config.pc_damage_delay_rate/100;
	}
	else if(bl->type==BL_PET)
		ret=((struct pet_data *)bl)->db->dmotion;
	else
		return 2000;

	if(sc && sc->count && (sc->data[SC_ENDURE].timer!=-1 || sc->data[SC_CONCENTRATION].timer!=-1 || sc->data[SC_BERSERK].timer!=-1))
		if (!map_flag_gvg(bl->m)) //Only works on non-gvg grounds. [Skotlex]
			return 0;

	return ret;
}
int status_get_element(struct block_list *bl)
{
	// removed redundant variable ret [zzo]
	struct status_change *sc= status_get_sc(bl);

	nullpo_retr(20, bl);

	if(sc && sc->count) {
		if( sc->data[SC_FREEZE].timer!=-1 )	// ����
			return 21;
		if( sc->data[SC_STONE].timer!=-1 && sc->data[SC_STONE].val2==0)
			return 22;
		if( sc->data[SC_BENEDICTIO].timer!=-1 )	// ���̍~��
			return 26;
	}
	if(bl->type==BL_MOB)	// 10�̈ʁ�Lv*2�A�P�̈ʁ�����
		return ((struct mob_data *)bl)->def_ele;
	if(bl->type==BL_PC)
		return 20+((struct map_session_data *)bl)->def_ele;	// �h�䑮��Lv1
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->db->element;

	return 20;
}
//Retrieves the object's element acquired by status changes only.
int status_get_attack_sc_element(struct block_list *bl)
{
	struct status_change *sc =status_get_sc(bl);
	if(sc && sc->count) {
		if( sc->data[SC_WATERWEAPON].timer!=-1)	// �t���X�g�E�F�|��
			return 1;
		if( sc->data[SC_EARTHWEAPON].timer!=-1)	// �T�C�Y�~�b�N�E�F�|��
			return 2;
		if( sc->data[SC_FIREWEAPON].timer!=-1)	// �t���[�������`���[
			return 3;
		if( sc->data[SC_WINDWEAPON].timer!=-1)	// ���C�g�j���O���[�_�[
			return 4;
		if( sc->data[SC_ENCPOISON].timer!=-1)	// �G���`�����g�|�C�Y��
			return 5;
		if( sc->data[SC_ASPERSIO].timer!=-1)		// �A�X�y���V�I
			return 6;
		if( sc->data[SC_SHADOWWEAPON].timer!=-1)
			return 7;
		if( sc->data[SC_GHOSTWEAPON].timer!=-1)
			return 8;
	}
	return 0;
}


int status_get_attack_element(struct block_list *bl)
{
	int ret = status_get_attack_sc_element(bl);

	nullpo_retr(0, bl);
	
	if (ret)	return ret;
	
	if(bl->type==BL_MOB && (struct mob_data *)bl)
		return 0;
	if(bl->type==BL_PC && (struct map_session_data *)bl)
		return ((struct map_session_data *)bl)->right_weapon.atk_ele;
	if(bl->type==BL_PET && (struct pet_data *)bl)
		return 0;

	return 0;
}
int status_get_attack_element2(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_PC) {
		// removed redundant var, speeded up a bit [zzo]
		int ret = status_get_attack_sc_element(bl);

		if(ret) return ret;
		return ((struct map_session_data *)bl)->left_weapon.atk_ele;
	}
	return 0;
}
int status_get_party_id(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->status.party_id;
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->msd->status.party_id;
	if(bl->type==BL_MOB){
		struct mob_data *md=(struct mob_data *)bl;
		if( md->master_id>0 )
		{
			struct map_session_data *msd;
			if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
				return msd->status.party_id;
			return -md->master_id;
		}
		return 0; //No party.
	}
	if(bl->type==BL_SKILL)
		return ((struct skill_unit *)bl)->group->party_id;
	return 0;
}

int status_get_guild_id(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_PC)
		return ((struct map_session_data *)bl)->status.guild_id;
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->msd->status.guild_id;
	if(bl->type==BL_MOB)
	{
		struct map_session_data *msd;
		struct mob_data *md = (struct mob_data *)bl;
		if (md->guardian_data)	//Guardian's guild [Skotlex]
			return md->guardian_data->guild_id;
		if (md->special_state.ai && (msd = map_id2sd(md->master_id)) != NULL)
			return msd->status.guild_id; //Alchemist's mobs [Skotlex]
		return 0; //No guild.
	}
	if(bl->type==BL_SKILL)
		return ((struct skill_unit *)bl)->group->guild_id;
	return 0;
}
int status_get_race(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_MOB)
		return ((struct mob_data *)bl)->db->race;
	if(bl->type==BL_PC)
		return 7;
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->db->race;
	return 0;
}
int status_get_size(struct block_list *bl)
{
	nullpo_retr(1, bl);
	switch (bl->type) {
		case BL_MOB:
			if (((struct mob_data *)bl)->sc.data[SC_SWOO].timer != -1) // [marquis007]
				return 0;
			return ((struct mob_data *)bl)->db->size;
		case BL_PET:	
			return ((struct pet_data *)bl)->db->size;
		case BL_PC:
		{
			struct map_session_data *sd = (struct map_session_data *)bl;
			if (sd->sc.data[SC_SWOO].timer != -1)
				return 0;
			if (sd->class_&JOBL_BABY) //[Lupus]
				return (pc_isriding(sd) && battle_config.character_size&2); //Baby Class Peco Rider + enabled option -> size = 1, else 0
			return 1+(pc_isriding(sd) && battle_config.character_size&1);	//Peco Rider + enabled option -> size = 2, else 1
		}
	}
	return 1;
}
int status_get_mode(struct block_list *bl)
{
	nullpo_retr(MD_CANMOVE, bl);
	if(bl->type==BL_MOB)
	{
		if (((struct mob_data *)bl)->mode)
			return ((struct mob_data *)bl)->mode;
		return ((struct mob_data *)bl)->db->mode;
	}
	if(bl->type==BL_PC)
		return (MD_CANMOVE|MD_LOOTER|MD_CANATTACK);
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->db->mode;
	if (bl->type==BL_SKILL)
		return (MD_CANATTACK|MD_CANMOVE);	//Default mode for skills: Can attack, can move (think dances).
	//Default universal mode, can move
	return MD_CANMOVE;	// �Ƃ肠���������Ƃ������Ƃ�1
}

int status_get_mexp(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type==BL_MOB)
		return ((struct mob_data *)bl)->db->mexp;
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->db->mexp;
	return 0;
}
int status_get_race2(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type == BL_MOB)
		return ((struct mob_data *)bl)->db->race2;
	if(bl->type==BL_PET)
		return ((struct pet_data *)bl)->db->race2;
	return 0;
}
int status_isdead(struct block_list *bl)
{
	nullpo_retr(0, bl);
	if(bl->type == BL_MOB)
		return ((struct mob_data *)bl)->state.state == MS_DEAD;
	if(bl->type==BL_PC)
		return pc_isdead((struct map_session_data *)bl);
	return 0;
}
int status_isimmune(struct block_list *bl)
{
	struct status_change *sc =status_get_sc(bl);
	if (bl->type == BL_PC &&
		((struct map_session_data *)bl)->special_state.no_magic_damage)
		return 1;
	if (sc && sc->count && sc->data[SC_HERMODE].timer != -1)
		return 1;
	return 0;
}

struct status_change *status_get_sc(struct block_list *bl)
{
	nullpo_retr(NULL, bl);
	if(bl->type==BL_MOB)
		return &((struct mob_data*)bl)->sc;
	if(bl->type==BL_PC)
		return &((struct map_session_data*)bl)->sc;
	return NULL;
}

//Returns defense against the specified status change.
//Return range is 0 (no resist) to 10000 (inmunity)
int status_get_sc_def(struct block_list *bl, int type)
{
	int sc_def;
	struct status_change* sc;
	nullpo_retr(0, bl);

	//Status that are blocked by Golden Thief Bug card or Wand of Hermod
	if (status_isimmune(bl))
	switch (type)
	{
	case SC_DECREASEAGI:
	case SC_SILENCE:
	case SC_COMA:
	case SC_INCREASEAGI:
	case SC_BLESSING:
	case SC_SLOWPOISON:
	case SC_IMPOSITIO:
	case SC_AETERNA:
	case SC_SUFFRAGIUM:
	case SC_BENEDICTIO:
	case SC_PROVIDENCE:
	case SC_KYRIE:
	case SC_ASSUMPTIO:
	case SC_ANGELUS:
	case SC_MAGNIFICAT:
	case SC_GLORIA:
	case SC_WINDWALK:
	case SC_MAGICROD:
	case SC_HALLUCINATION:
	case SC_STONE:
	case SC_QUAGMIRE:
		return 10000;
	}
	
	switch (type)
	{
	//Note that stats that are *100/3 were simplified to *33
	case SC_STONE:
	case SC_FREEZE:
	case SC_DECREASEAGI:
	case SC_COMA:
		sc_def = 300 +100*status_get_mdef(bl) +33*status_get_luk(bl);
		break;
	case SC_SLEEP:
	case SC_CONFUSION:
		sc_def = 300 +100*status_get_int(bl) +33*status_get_luk(bl);
		break;
// Removed since it collides with normal sc.
//	case SP_DEF1:	// def
//		sc_def = 300 +100*status_get_def(bl) +33*status_get_luk(bl);
//		break;
	case SC_STUN:
	case SC_POISON:
	case SC_SILENCE:
	case SC_STOP:
		sc_def = 300 +100*status_get_vit(bl) +33*status_get_luk(bl);
		break;
	case SC_BLIND:
		sc_def = 300 +100*status_get_int(bl) +33*status_get_vit(bl);
		break;
	case SC_CURSE:
		sc_def = 300 +100*status_get_luk(bl) +33*status_get_vit(bl);
		break;
	default:
		return 0; //Effect that cannot be reduced? Likely a buff.
	}

	if (bl->type == BL_PC) {
		if (battle_config.pc_sc_def_rate != 100)
			sc_def = sc_def*battle_config.pc_sc_def_rate/100;
	} else
	if (battle_config.mob_sc_def_rate != 100)
		sc_def = sc_def*battle_config.mob_sc_def_rate/100;
	
	sc = status_get_sc(bl);
	if (sc && sc->count)
	{
		if (sc->data[SC_SCRESIST].timer != -1)
			sc_def += 100*sc->data[SC_SCRESIST].val1; //Status resist
		else if (sc->data[SC_SIEGFRIED].timer != -1)
			sc_def += 100*sc->data[SC_SIEGFRIED].val2; //Status resistance.
	}

	if(bl->type == BL_PC) {
		if (sc_def > battle_config.pc_max_sc_def)
			sc_def = battle_config.pc_max_sc_def;
	} else if (sc_def > battle_config.mob_max_sc_def)
		sc_def = battle_config.mob_max_sc_def;
	
	return sc_def;
}

//Reduces tick delay based on type and character defenses.
int status_get_sc_tick(struct block_list *bl, int type, int tick)
{
	struct map_session_data *sd;
	int rate=0, min=0;
	//If rate is positive, it is a % reduction (10000 -> 100%)
	//if it is negative, it is an absolute reduction in ms.
	sd = bl->type == BL_PC?(struct map_session_data *)bl:NULL;
	switch (type) {
		case SC_DECREASEAGI:		/* ���x���� */
			if (sd)	// Celest
				tick>>=1;
		break;
		case SC_ADRENALINE:			/* �A�h���i�������b�V�� */
		case SC_ADRENALINE2:
		case SC_WEAPONPERFECTION:	/* �E�F�|���p?�t�F�N�V���� */
		case SC_OVERTHRUST:			/* �I?�o?�X���X�g */
			if(sd && pc_checkskill(sd,BS_HILTBINDING)>0)
				tick += tick / 10;
		break;
		case SC_STONE:				/* �Ή� */
			rate = -200*status_get_mdef(bl);
		break;
		case SC_FREEZE:				/* ���� */
			rate = 100*status_get_mdef(bl);
		break;
		case SC_STUN:				/* �X�^���ival2�Ƀ~���b�Z�b�g�j */
			rate = status_get_sc_def_vit(bl);
		break;
		case SC_DPOISON:			/* �ғ� */
		case SC_POISON:				/* �� */
			rate = 100*status_get_vit(bl) + 20*status_get_luk(bl);
		break;
		case SC_SILENCE:			/* ��?�i���b�N�X�f�r?�i�j */
		case SC_CONFUSION:
		case SC_CURSE:
			rate = 100*status_get_vit(bl);
		break;
		case SC_BLIND:				/* ��? */
			rate = 10*status_get_lv(bl) + 7*status_get_int(bl);
			min = 5000; //Minimum 5 secs?
		break;
		case SC_BLEEDING:
			rate = 20*status_get_lv(bl) +100*status_get_vit(bl);
			min = 10000; //Need a min of 10 secs for it to hurt at least once.
		break;
		case SC_SWOO:
			if (status_get_mode(bl)&MD_BOSS)
				tick /= 5; //TODO: Reduce skill's duration. But for how long?
		break;
		case SC_ANKLE:
			if(status_get_mode(bl)&MD_BOSS) // Lasts 5 times less on bosses
				tick /= 5;
			rate = -100*status_get_agi(bl);
		// Minimum trap time of 3+0.03*skilllv seconds [celest]
		// Changed to 3 secs and moved from skill.c [Skotlex]
			min = 3000;
		break;
		case SC_STOP:
		// Unsure of this... but I get a feeling that agi reduces this
		// (it was on Tiger Fist Code, but at -1 ms per 10 agi....
			rate = -100*status_get_agi(bl);
		break;
	}
	if (rate) {
		if (bl->type == BL_PC) {
			if (battle_config.pc_sc_def_rate != 100)
				rate = rate*battle_config.pc_sc_def_rate/100;
			if (battle_config.pc_max_sc_def != 10000)
				min = tick*(10000-battle_config.pc_max_sc_def)/10000;
		} else {
			if (battle_config.mob_sc_def_rate != 100)
				rate = rate*battle_config.mob_sc_def_rate/100;
			if (battle_config.mob_max_sc_def != 10000)
				min = tick*(10000-battle_config.mob_max_sc_def)/10000;
		}
		
		if (rate >0)
			tick -= tick*rate/10000;
		else
			tick -= rate;
	}
	return tick<min?min:tick;
}
/*==========================================
 * Starts a status change.
 * type = type, val1~4 depend on the type.
 * rate = base success rate. 100 = 100%
 * Tick is base duration
 * flag:
 * &1: Cannot be avoided (it has to start)
 * &2: Tick should not be reduced (by vit, luk, lv, etc)
 * &4: sc_data loaded, no value has to be altered.
 * &8: rate should not be reduced
 *------------------------------------------
 */
int status_change_start(struct block_list *bl,int type,int rate,int val1,int val2,int val3,int val4,int tick,int flag)
{
	struct map_session_data *sd = NULL;
	struct status_change* sc;
	int opt_flag , calc_flag = 0,updateflag = 0, save_flag = 0, race, mode, elem, undead_flag;

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

	if (!sc || status_isdead(bl))
		return 0;
	
	switch (bl->type)
	{
		case BL_PC:
			sd=(struct map_session_data *)bl;
			break;
		case BL_MOB:
			if (((struct mob_data*)bl)->class_ == MOBID_EMPERIUM && type != SC_SAFETYWALL)
				return 0; //Emperium can't be afflicted by status changes.
			break;
	}

	if(type < 0 || type >= SC_MAX) {
		if(battle_config.error_log)
			ShowError("status_change_start: invalid status change (%d)!\n", type);
		return 0;
	}

	//Check rate
	if (!(flag&(4|1))) {
		rate*=100; //Pass to 10000 = 100%
		race = flag&8?0:status_get_sc_def(bl, type); //recycling race to store the sc_def value.
		//sd resistance applies even if the flag is &8
		if(sd && SC_COMMON_MIN<=type && type<=SC_COMMON_MAX && sd->reseff[type-SC_COMMON_MIN] > 0)
			race+= sd->reseff[type-SC_COMMON_MIN];

		if (race)
			rate -= rate*race/10000;

		if (!(rand()%10000 < rate))
			return 0;
	}
	
	race=status_get_race(bl);
	mode=status_get_mode(bl);
	elem=status_get_elem_type(bl);
	undead_flag=battle_check_undead(race,elem);

	//Check for inmunities / sc fails
	switch (type) {
		case SC_FREEZE:
		case SC_STONE:
			//Undead are inmune to Freeze/Stone
			if (undead_flag && !(flag&1))
				return 0;
		case SC_SLEEP:
		case SC_STUN:
			if (sc->opt1)
				return 0; //Cannot override other opt1 status changes. [Skotlex]
		break;
		case SC_CURSE:
			//Dark Elementals are inmune to curse.
			if (elem == 7 && !(flag&1))
				return 0;
		break;
		case SC_COMA:
			//Dark elementals and Demons are inmune to coma.
			if((elem == 7 || race == 6) && !(flag&1))
				return 0;
		break;
		case SC_SIGNUMCRUCIS:
			//Only affects demons and undead.
			if(race != 6 && !undead_flag)
				return 0;
			break;
		case SC_AETERNA:
		  if (sc->data[SC_STONE].timer != -1 || sc->data[SC_FREEZE].timer != -1)
			  return 0;
		break;
		case SC_OVERTHRUST:
			if (sc->data[SC_MAXOVERTHRUST].timer != -1)
				return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
		break;
		case SC_ADRENALINE:
		 	if (sd && !(skill_get_weapontype(BS_ADRENALINE)&(1<<sd->status.weapon)))
				return 0;
			if (sc->data[SC_QUAGMIRE].timer!=-1 ||
				sc->data[SC_DONTFORGETME].timer!=-1 ||
				sc->data[SC_DECREASEAGI].timer!=-1
			)
				return 0;
		break;
		case SC_ADRENALINE2:
			if (sd && !(skill_get_weapontype(BS_ADRENALINE2)&(1<<sd->status.weapon)))
				return 0;
			if (sc->data[SC_QUAGMIRE].timer!=-1 ||
				sc->data[SC_DONTFORGETME].timer!=-1 ||
				sc->data[SC_DECREASEAGI].timer!=-1
			)
				return 0;
		break;
		case SC_ONEHAND:
		case SC_TWOHANDQUICKEN:
			if(sc->data[SC_DECREASEAGI].timer!=-1)
				return 0;
		case SC_CONCENTRATE:
		case SC_INCREASEAGI:
		case SC_SPEARSQUICKEN:
		case SC_TRUESIGHT:
		case SC_WINDWALK:
		case SC_CARTBOOST:
		case SC_ASSNCROS:
			if (sc->data[SC_QUAGMIRE].timer!=-1 || sc->data[SC_DONTFORGETME].timer!=-1)
				return 0;
		break;
		case SC_CLOAKING:
		//Avoid cloaking with no wall and low skill level. [Skotlex]
		//Due to the cloaking card, we have to check the wall versus to known skill level rather than the used one. [Skotlex]
//			if (sd && skilllv < 3 && skill_check_cloaking(bl))
			if (sd && pc_checkskill(sd, AS_CLOAKING)< 3 && skill_check_cloaking(bl))
				return 0;
		break;
	}

	//Check for BOSS resistnces
	if(mode & MD_BOSS && !(flag&1)) {
		 if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX)
			 return 0;
		 switch (type) {
			case SC_BLESSING:
			  if (!undead_flag || race != 6)
				  break;
			case SC_QUAGMIRE:
			case SC_DECREASEAGI:
			case SC_SIGNUMCRUCIS:
			case SC_PROVOKE:
			case SC_ROKISWEIL:
			case SC_COMA:
			case SC_GRAVITATION:
				return 0;
		}
	}

	//Check for overlapping fails
	if(sc->data[type].timer != -1){
		switch (type) {
			case SC_ADRENALINE:
			case SC_ADRENALINE2:
			case SC_WEAPONPERFECTION:
			case SC_OVERTHRUST:
				if (sc->data[type].val2 && !val2)
					return 0;
			break;
			case SC_GOSPEL:
				 //Must not override a casting gospel char.
				if (sc->data[type].val4 == BCT_SELF)
					return 0;
			case SC_STUN:
			case SC_SLEEP:
			case SC_POISON:
			case SC_CURSE:
			case SC_SILENCE:
			case SC_CONFUSION:
			case SC_BLIND:
			case SC_BLEEDING:
			case SC_DPOISON:
			case SC_COMBO: //You aren't supposed to change the combo (and it gets turned off when you trigger it)
			case SC_CLOSECONFINE2: //Can't be re-closed in.
				return 0;
			case SC_DANCING:
			case SC_DEVOTION:
			case SC_ASPDPOTION0:
			case SC_ASPDPOTION1:
			case SC_ASPDPOTION2:
			case SC_ASPDPOTION3:
			case SC_ATKPOTION:
			case SC_MATKPOTION:
				break;
			default:
				if(sc->data[type].val1 > val1)
					return 0;
			}
		(sc->count)--;
		delete_timer(sc->data[type].timer, status_change_timer);
		sc->data[type].timer = -1;
	}

	//SC duration reduction.
	if(!(flag&(2|4)) && tick) {
		tick = status_get_sc_tick(bl, type, tick);
		if (tick < 0)
			return 0;
	}

	switch(type){	/* �ُ�̎�ނ��Ƃ�?�� */
		case SC_PROVOKE:			/* �v���{�b�N */
			calc_flag = 1;
			if(tick <= 0) tick = 1000;	/* (�I?�g�o?�T?�N) */
			break;
		case SC_ENDURE:				/* �C���f���A */
			if(tick <= 0) tick = 1000 * 60;
			calc_flag = 1; // for updating mdef
			val2 = 7; // [Celest]
			break;
		case SC_AUTOBERSERK:
			{
				if (!(flag&4))
					tick = 60*1000;
				if (sd && sd->status.hp<sd->status.max_hp>>2 &&
					(sc->data[SC_PROVOKE].timer==-1 || sc->data[SC_PROVOKE].val2==0))
					status_change_start(bl,SC_PROVOKE,10,100,1,0,0,0,0);
			}
			break;
		
		case SC_INCREASEAGI:		/* ���x�㏸ */
			calc_flag = 1;
			if(sc->data[SC_DECREASEAGI].timer!=-1 )
				status_change_end(bl,SC_DECREASEAGI,-1);
			break;
		case SC_DECREASEAGI:		/* ���x���� */
			calc_flag = 1;
			if(sc->data[SC_INCREASEAGI].timer!=-1 )
				status_change_end(bl,SC_INCREASEAGI,-1);
			if(sc->data[SC_ADRENALINE].timer!=-1 )
				status_change_end(bl,SC_ADRENALINE,-1);
			if(sc->data[SC_ADRENALINE2].timer!=-1 )
				status_change_end(bl,SC_ADRENALINE2,-1);
			if(sc->data[SC_SPEARSQUICKEN].timer!=-1 )
				status_change_end(bl,SC_SPEARSQUICKEN,-1);
			if(sc->data[SC_TWOHANDQUICKEN].timer!=-1 )
				status_change_end(bl,SC_TWOHANDQUICKEN,-1);
			if(sc->data[SC_CARTBOOST].timer!=-1 )
				status_change_end(bl,SC_CARTBOOST,-1);
			if(sc->data[SC_ONEHAND].timer!=-1 )
				status_change_end(bl,SC_ONEHAND,-1);
			break;
		case SC_SIGNUMCRUCIS:		/* �V�O�i���N���V�X */
			calc_flag = 1;
			val2 = 10 + val1*2;
			if (!(flag&4))
				tick = 600*1000;
			clif_emotion(bl,4);
			break;
		case SC_ONEHAND: //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
			if(sc->data[SC_ASPDPOTION0].timer!=-1)
				status_change_end(bl,SC_ASPDPOTION0,-1);
			if(sc->data[SC_ASPDPOTION1].timer!=-1)
				status_change_end(bl,SC_ASPDPOTION1,-1);
			if(sc->data[SC_ASPDPOTION2].timer!=-1)
				status_change_end(bl,SC_ASPDPOTION2,-1);
			if(sc->data[SC_ASPDPOTION3].timer!=-1)
				status_change_end(bl,SC_ASPDPOTION3,-1);
			calc_flag = 1;
			break;
		case SC_MAXOVERTHRUST: //Cancels Normal Overthrust. [Skotlex]
			if (sc->data[SC_OVERTHRUST].timer != -1)
				status_change_end(bl, SC_OVERTHRUST, -1);
			break;
		case SC_MAXIMIZEPOWER:		/* �}�L�V�}�C�Y�p��?(SP��1���鎞��,val2�ɂ�) */
			if (!(flag&4))
			{
				if(bl->type != BL_PC)
					tick = 5000;
				val2 = tick;
			}
			break;
		case SC_EDP:	// [Celest]
			val2 = val1 + 2;			/* �ғŕt?�m��(%) */
			calc_flag = 1;
			break;
		case SC_POISONREACT:	/* �|�C�Y�����A�N�g */
			if (!(flag&4))
				val2=val1/2 + val1%2; // [Celest]
			break;
		case SC_MAGICROD:
			val2 = val1*20;
			break;
		case SC_KYRIE:				/* �L���G�G���C�\�� */
			if (!(flag&4))
			{
				val2 = status_get_max_hp(bl) * (val1 * 2 + 10) / 100;/* �ϋv�x */
				val3 = (val1 / 2 + 5);	/* ��? */
			}
// -- moonsoul (added to undo assumptio status if target has it)
			if(sc->data[SC_ASSUMPTIO].timer!=-1 )
				status_change_end(bl,SC_ASSUMPTIO,-1);
			break;
		case SC_MINDBREAKER:
			calc_flag = 1;
			if(tick <= 0) tick = 1000;	/* (�I?�g�o?�T?�N) */
			break;
		case SC_QUAGMIRE:			/* �N�@�O�}�C�A */
			calc_flag = 1;
			if(sc->data[SC_CONCENTRATE].timer!=-1 )	/* �W���͌������ */
				status_change_end(bl,SC_CONCENTRATE,-1);
			if(sc->data[SC_INCREASEAGI].timer!=-1 )	/* ���x�㏸���� */
				status_change_end(bl,SC_INCREASEAGI,-1);
			if(sc->data[SC_TWOHANDQUICKEN].timer!=-1 )
				status_change_end(bl,SC_TWOHANDQUICKEN,-1);
			if(sc->data[SC_ONEHAND].timer!=-1 )
				status_change_end(bl,SC_ONEHAND,-1);
			if(sc->data[SC_SPEARSQUICKEN].timer!=-1 )
				status_change_end(bl,SC_SPEARSQUICKEN,-1);
			if(sc->data[SC_ADRENALINE].timer!=-1 )
				status_change_end(bl,SC_ADRENALINE,-1);
			if(sc->data[SC_ADRENALINE2].timer!=-1 )
				status_change_end(bl,SC_ADRENALINE2,-1);
			if(sc->data[SC_TRUESIGHT].timer!=-1 )	/* �g�D��?�T�C�g */
				status_change_end(bl,SC_TRUESIGHT,-1);
			if(sc->data[SC_WINDWALK].timer!=-1 )	/* �E�C���h�E�H?�N */
				status_change_end(bl,SC_WINDWALK,-1);
			if(sc->data[SC_CARTBOOST].timer!=-1 )	/* �J?�g�u?�X�g */
				status_change_end(bl,SC_CARTBOOST,-1);
			break;
		case SC_MAGICPOWER:
			calc_flag = 1;
			val2 = 1;
			break;
		case SC_SACRIFICE:
			if (!(flag&4))
				val2 = 5;
			break;
		case SC_ENCPOISON:			/* �G���`�����g�|�C�Y�� */
			calc_flag = 1;
			val2=(((val1 - 1) / 2) + 3)*100;	/* �ŕt?�m�� */
		case SC_ASPERSIO:			/* �A�X�y���V�I */
		case SC_FIREWEAPON:		/* �t��?�������`��? */
		case SC_WATERWEAPON:		/* �t���X�g�E�F�|�� */
		case SC_WINDWEAPON:	/* ���C�g�j���O��?�_? */
		case SC_EARTHWEAPON:		/* �T�C�Y�~�b�N�E�F�|�� */
		case SC_SHADOWWEAPON:
		case SC_GHOSTWEAPON:
			skill_enchant_elemental_end(bl,type);
			break;
		case SC_PROVIDENCE:			/* �v�����B�f���X */
			calc_flag = 1;
			val2=val1*5;
			break;
		case SC_REFLECTSHIELD:
			val2=10+val1*3;
			break;
		case SC_STRIPWEAPON:
			if (val2==0) val2=90;
			break;
		case SC_STRIPSHIELD:
			if (val2==0) val2=85;
			break;

		case SC_AUTOSPELL:			/* �I?�g�X�y�� */
			val4 = 5 + val1*2;
			break;

		case SC_VOLCANO:
			calc_flag = 1;
			val3 = val1*10;
			break;
		case SC_DELUGE:
			calc_flag = 1;
			if (sc->data[SC_FOGWALL].timer != -1 && sc->data[SC_BLIND].timer != -1)
				status_change_end(bl,SC_BLIND,-1);
			break;
		case SC_VIOLENTGALE:
			calc_flag = 1;
			val3 = val1*3;
			break;

		case SC_SPEARSQUICKEN:		/* �X�s�A�N�C�b�P�� */
			calc_flag = 1;
			val2 = 20+val1;
			break;

		case SC_BLADESTOP:		/* ���n��� */
			if(val2==2) clif_bladestop((struct block_list *)val3,(struct block_list *)val4,1);
			break;

		case SC_DONTFORGETME:		/* ����Y��Ȃ��� */
			calc_flag = 1;
			if(sc->data[SC_INCREASEAGI].timer!=-1 )	/* ���x�㏸���� */
				status_change_end(bl,SC_INCREASEAGI,-1);
			if(sc->data[SC_TWOHANDQUICKEN].timer!=-1 )
				status_change_end(bl,SC_TWOHANDQUICKEN,-1);
			if(sc->data[SC_ONEHAND].timer!=-1 )
				status_change_end(bl,SC_ONEHAND,-1);
			if(sc->data[SC_SPEARSQUICKEN].timer!=-1 )
				status_change_end(bl,SC_SPEARSQUICKEN,-1);
			if(sc->data[SC_ADRENALINE].timer!=-1 )
				status_change_end(bl,SC_ADRENALINE,-1);
			if(sc->data[SC_ADRENALINE2].timer!=-1 )
				status_change_end(bl,SC_ADRENALINE2,-1);
			if(sc->data[SC_ASSNCROS].timer!=-1 )
				status_change_end(bl,SC_ASSNCROS,-1);
			if(sc->data[SC_TRUESIGHT].timer!=-1 )	/* �g�D��?�T�C�g */
				status_change_end(bl,SC_TRUESIGHT,-1);
			if(sc->data[SC_WINDWALK].timer!=-1 )	/* �E�C���h�E�H?�N */
				status_change_end(bl,SC_WINDWALK,-1);
			if(sc->data[SC_CARTBOOST].timer!=-1 )	/* �J?�g�u?�X�g */
				status_change_end(bl,SC_CARTBOOST,-1);
			break;
		case SC_MOONLIT:
			val2 = bl->id;
			skill_setmapcell(bl,CG_MOONLIT, val1, CELL_SETMOONLIT);
			break;
		case SC_DANCING:			/* �_���X/���t�� */
			calc_flag = 1;
			if (!(flag&4))
			{
				val3= tick / 1000;
				tick = 1000;
			}
			break;

		case SC_EXPLOSIONSPIRITS:	// �����g��
			calc_flag = 1;
			val2 = 75 + 25*val1;
			break;
		case SC_AUTOCOUNTER:
			val3 = val4 = 0;
			break;

		case SC_ASPDPOTION0:		/* ?���|?�V���� */
		case SC_ASPDPOTION1:
		case SC_ASPDPOTION2:
		case SC_ASPDPOTION3:
			calc_flag = 1;
			if (!(flag&4))
				val2 = 5*(2+type-SC_ASPDPOTION0);
			break;

		case SC_XMAS: // Xmas Suit [Valaris]
		case SC_WEDDING:	//�����p(�����ߏւɂȂ���?���̂�?���Ƃ�)
		if (sd)
		{	//Change look.
			if(type==SC_WEDDING)
				sd->view_class = JOB_WEDDING;
			else if(type==SC_XMAS)
				sd->view_class = JOB_XMAS;
			clif_changelook(&sd->bl,LOOK_BASE,sd->view_class);
#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(battle_config.save_clothcolor && sd->status.clothes_color > 0 && 
				((type==SC_WEDDING && !battle_config.wedding_ignorepalette) || 
					(type==SC_XMAS && !battle_config.xmas_ignorepalette)))
				clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color);
		}
			break;
		case SC_NOCHAT:	//�`���b�g�֎~?��
			{
				if(!battle_config.muting_players)
					return 0;
				
				if (!(flag&4))
					tick = 60000;
				updateflag = SP_MANNER;
				save_flag = 1; // celest
			}
			break;

		/* option1 */
		case SC_STONE:				/* �Ή� */
			if (flag&4)
				break;
			val2 = 1;
			val3 = tick/1000;
			if(val3 < 1) val3 = 1;
			tick = 5000;
			break;
		case SC_SLEEP:				/* ���� */
			if(!(flag&4))
				tick = 30000;//�����̓X�e?�^�X�ϐ���?��炸30�b
			break;

			/* option2 */
		case SC_DPOISON:			/* �ғ� */
		{
			int hp = status_get_hp(bl);
			int mhp = status_get_max_hp(bl);

			// MHP?1/4????????
			if (hp > mhp>>2) {
				if(bl->type == BL_PC) {
					int diff = mhp*10/100;
					if (hp - diff < mhp>>2)
						diff = hp - (mhp>>2);
					pc_heal((struct map_session_data *)bl, -diff, 0);
				} else if(bl->type == BL_MOB) {
					struct mob_data *md = (struct mob_data *)bl;
					hp -= mhp*15/100;
					if (hp > mhp>>2)
						md->hp = hp;
					else
						md->hp = mhp>>2;
				}
			}
		}	// fall through
		case SC_POISON:				/* �� */
		{
			int mhp;

			calc_flag = 1;
			if (flag&4)
				break;
			val3 = tick/1000;
			if(val3 < 1) val3 = 1;
			tick = 1000;
			mhp = status_get_max_hp(bl);
			if (bl->type == BL_PC)
				val4 = (type == SC_DPOISON) ? 3 + mhp/50 : 3 + mhp*3/200;
			else
				val4 = (type == SC_DPOISON) ? 3 + mhp/100 : 3 + mhp/200;
		
		}
		break;
		case SC_SILENCE:			/* ��?�i���b�N�X�f�r?�i�j */
			if (sc->data[SC_GOSPEL].timer!=-1) {
				if (sc->data[SC_GOSPEL].val4 == BCT_SELF) { //Clear Gospel [Skotlex]
					status_change_end(bl,SC_GOSPEL,-1);
				}
				break;
			}
			break;
		case SC_CONFUSION:
			clif_emotion(bl,1);
			break;
		case SC_BLEEDING:
			val4 = tick;
			tick = 10000;
			break;
		/* option */
		case SC_HIDING:		/* �n�C�f�B���O */
			calc_flag = 1;
			if(sc->data[SC_CLOSECONFINE].timer != -1)
				status_change_end(bl, SC_CLOSECONFINE, -1);
			if(sc->data[SC_CLOSECONFINE2].timer != -1)
				status_change_end(bl, SC_CLOSECONFINE2, -1);
			if(bl->type == BL_PC && !(flag&4)) {
				val2 = tick / 1000;		/* ��?���� */
				tick = 1000;
			}
			break;
		case SC_CHASEWALK:
		case SC_CLOAKING:		/* �N��?�L���O */
			if (flag&4)
				break;
			if(bl->type != BL_PC)
				tick = 5000*val1;
			calc_flag = 1; // [Celest]
			val2 = tick;
			val3 = type==SC_CLOAKING ? 130-val1*3 : 135-val1*5;
			break;
		case SC_SIGHT:			/* �T�C�g/���A�t */
		case SC_RUWACH:
		case SC_SIGHTBLASTER:
			if (flag&4)
				break;
			val2 = tick/250;
			tick = 10;
			break;

		case SC_WEIGHT50:
		case SC_WEIGHT90:
		case SC_BROKENWEAPON:
		case SC_BROKENARMOR:
		case SC_READYSTORM: // Taekwon stances SCs [Dralnu]
		case SC_READYDOWN:
		case SC_READYCOUNTER:
		case SC_READYTURN:
		case SC_DODGE:
			if (flag&4)
				break;
			tick = 600*1000;
			break;

		case SC_AUTOGUARD:
			if (!flag)
			{
				struct map_session_data *tsd;
				int i,t;
				for(i=val2=0;i<val1;i++) {
					t = 5-(i>>1);
					val2 += (t < 0)? 1:t;
				}
				if (sd)
					for (i = 0; i < 5; i++)
					{	//Pass the status to the other affected chars. [Skotlex]
						if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])))
							status_change_start(&tsd->bl,SC_AUTOGUARD,100,val1,val2,0,0,tick,1);
					}
			}
			break;

		case SC_DEFENDER:
			calc_flag = 1;
			if (!flag)
			{	
				struct map_session_data *tsd;
				int i;
				val2 = 5 + val1*15;
				if (sd)
					for (i = 0; i < 5; i++)
					{	//See if there are devoted characters, and pass the status to them. [Skotlex]
						if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])))
							status_change_start(&tsd->bl,SC_DEFENDER,100,val1,val2,0,0,tick,1);
					}
			}
			break;

		case SC_TENSIONRELAX:	/* �e���V���������b�N�X */
			if (flag&4)
				break;
			if(bl->type == BL_PC) {
				tick = 10000;
			} else return 0;
			break;

		case SC_PARRYING:		/* �p���C���O */
		    val2 = 20 + val1*3;
			break;

		case SC_WINDWALK:		/* �E�C���h�E�H?�N */
			calc_flag = 1;
			val2 = (val1+1)/2; // Flee bonus is 1/1/2/2/3/3/4/4/5/5, movement speed % increase is 4 times that
			break;

		case SC_JOINTBEAT: // Random break [DracoRPG]
			calc_flag = 1;
			val2 = rand()%6;
			if (val2 == 5) status_change_start(bl,SC_BLEEDING,100,val1,0,0,0,skill_get_time2(StatusSkillChangeTable[type],val1),0);
			break;

		case SC_BERSERK:		/* �o?�T?�N */
			if(battle_config.berserk_cancels_buffs)
			{
				if (sc->data[SC_ONEHAND].timer != -1)
					status_change_end(bl,SC_ONEHAND,-1);
				if (sc->data[SC_TWOHANDQUICKEN].timer != -1)
					status_change_end(bl,SC_TWOHANDQUICKEN,-1);
				if (sc->data[SC_CONCENTRATION].timer != -1)
					status_change_end(bl,SC_CONCENTRATION,-1);
				if (sc->data[SC_PARRYING].timer != -1)
					status_change_end(bl,SC_PARRYING,-1);
				if (sc->data[SC_ENDURE].timer != -1)
					status_change_end(bl,SC_ENDURE,-1);
				if (sc->data[SC_AURABLADE].timer != -1)
					status_change_end(bl,SC_AURABLADE,-1);
			}
			if(sd && !(flag&4)){
				sd->status.hp = sd->status.max_hp * 3;
				sd->status.sp = 0;
				clif_updatestatus(sd,SP_HP);
				clif_updatestatus(sd,SP_SP);
				sd->canregen_tick = gettick() + 300000;
			}
			if (!(flag&4))
				tick = 10000;
			calc_flag = 1;
			break;

		case SC_ASSUMPTIO:		/* �A�X���v�e�B�I */
			if(sc->data[SC_KYRIE].timer!=-1)
				status_change_end(bl,SC_KYRIE,-1);
			break;

		case SC_WARM: //SG skills [Komurka]
			if (!(flag&4)) {
				val2 = tick/100;
				tick = 100;
			}
			break;

		case SC_GOSPEL:
			if (val4 == BCT_SELF) {	// self effect
				if (flag&4)
					break;
				val2 = tick;
				tick = 1000;
				status_change_clear_buffs(bl);
				status_change_clear_debuffs(bl); //Gospel clears both types.
			} else
				calc_flag = 1;
			break;

		case SC_MARIONETTE:		/* �}���I�l�b�g�R���g��?�� */
		case SC_MARIONETTE2:
			if (flag&4)
				break;
			val2 = tick;
			if (!val3)
				return 0;
			tick = 1000;
			calc_flag = 1;
			break;

		case SC_REJECTSWORD:	/* ���W�F�N�g�\?�h */
			val2 = 3; //3��U?�𒵂˕Ԃ�
			break;

		case SC_MEMORIZE:		/* �������C�Y */
			val2 = 5; //��r����1/3�ɂ���
			break;

		case SC_GRAVITATION:
			if (sd) {
				if (val3 == BCT_SELF) {
					sd->canmove_tick += tick;
					sd->canact_tick += tick;
				} else calc_flag = 1;
			}
			break;

		case SC_HERMODE:
			status_change_clear_buffs(bl);
			break;

		case SC_REGENERATION:
			val1 = 2;
		case SC_BATTLEORDERS:
			if (!(flag&4))
				tick = 60000; // 1 minute
			calc_flag = 1;
			break;
		case SC_GUILDAURA:
			calc_flag = 1;
			if (!(flag&4))
				tick = 1000;
			break;

		case SC_DEVOTION:			/* �f�B�{?�V���� */
		{
			struct map_session_data *src;
			if ((src = map_id2sd(val1)) && src->sc.count)
			{	//Try to inherit the status from the Crusader [Skotlex]
			//Ideally, we should calculate the remaining time and use that, but we'll trust that
			//once the Crusader's status changes, it will reflect on the others. 
				int type2 = SC_AUTOGUARD;
				if (src->sc.data[type2].timer != -1)
					status_change_start(bl,type2,100,
						src->sc.data[type2].val1,0,0,0,
						skill_get_time(StatusSkillChangeTable[type2],src->sc.data[type2].val1),0);
				type2 = SC_DEFENDER;
				if (src->sc.data[type2].timer != -1)
					status_change_start(bl,type2,100,
						src->sc.data[type2].val1,0,0,0,
						skill_get_time(StatusSkillChangeTable[type2],src->sc.data[type2].val1),0);
			}
			break;
		}

		case SC_COMA: //Coma. Sends a char to 1HP
			battle_damage(NULL, bl, status_get_hp(bl)-1, 0);
			return 0;

		case SC_CARTBOOST:		/* �J?�g�u?�X�g */
			if(sc->data[SC_DECREASEAGI].timer!=-1 )
			{	//Cancel Decrease Agi, but take no further effect [Skotlex]
				status_change_end(bl,SC_DECREASEAGI,-1);
				return 0;
			}
			calc_flag = 1;
			break;

		case SC_CLOSECONFINE2:
			{
				struct block_list *src = val2?map_id2bl(val2):NULL;
				struct status_change *sc2 = src?status_get_sc(src):NULL;
				if (src && sc2 && sc2->count) {
					if (sc2->data[SC_CLOSECONFINE].timer == -1) //Start lock on caster.
						status_change_start(src,SC_CLOSECONFINE,100,sc->data[type].val1,1,0,0,tick+1000,0);
					else { //Increase count of locked enemies and refresh time.
						sc2->data[SC_CLOSECONFINE].val2++;
						delete_timer(sc2->data[SC_CLOSECONFINE].timer, status_change_timer);
						sc2->data[SC_CLOSECONFINE].timer = add_timer(gettick()+tick+1000, status_change_timer, src->id, SC_CLOSECONFINE);
					}
				}
			}
			break;
		case SC_KAITE:
			val2 = 1+val1/5; //Number of bounces: 1 + skilllv/5
			break;
		case SC_KAUPE:
			if (flag&4)
				break; //Do nothing when loading.
			switch (val1) {
				case 3: //33*3 + 1 -> 100%
					val2++;
				case 1:
				case 2: //33, 66%
					val2 += 33*val1;
					val3 = 1; //Dodge 1 attack total.
					break;
				default: //Custom. For high level mob usage, higher level means more blocks. [Skotlex]
					val2 = 100;
					val3 = val1-2;
					break;
			}
			break;
		case SC_COMBO:
			switch (val1) { //Val1 contains the skill id
				case TK_STORMKICK:
					clif_skill_nodamage(bl,bl,TK_READYSTORM,1,1);
					if (sd) sd->attackabletime = gettick()+tick;
					break;
				case TK_DOWNKICK:
					clif_skill_nodamage(bl,bl,TK_READYDOWN,1,1);
					if (sd) sd->attackabletime = gettick()+tick;
					break;
				case TK_TURNKICK:
					clif_skill_nodamage(bl,bl,TK_READYTURN,1,1);
					if (sd) sd->attackabletime = gettick()+tick;
					break;
				case TK_COUNTER:
					clif_skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
					if (sd) sd->attackabletime = gettick()+tick;
					break;
			}
			break;
		case SC_TKDORI:
			val2 = 11-val1; //Chance to consume: 11-skilllv%
			break;
		case SC_RUN:
			if (!(flag&4))
				val4 = gettick(); //Store time at which you started running.
			calc_flag = 1;
			break;
		case SC_BLESSING:
			if (bl->type==BL_PC || (!undead_flag && race!=6)) {
				if (sc->data[SC_CURSE].timer!=-1)
					status_change_end(bl,SC_CURSE,-1);
				if (sc->data[SC_STONE].timer!=-1 && sc->data[SC_STONE].val2==0)
					status_change_end(bl,SC_STONE,-1);
			}
		case SC_CONCENTRATION:	/* �R���Z���g��?�V���� */case SC_ETERNALCHAOS:		/* �G�^?�i���J�I�X */
		case SC_DRUMBATTLE:			/* ?���ۂ̋��� */
		case SC_NIBELUNGEN:			/* �j?�x�����O�̎w�� */
		case SC_SIEGFRIED:			/* �s���g�̃W?�N�t��?�h */
		case SC_WHISTLE:			/* ���J */
		case SC_ASSNCROS:			/* �[�z�̃A�T�V���N���X */
		case SC_APPLEIDUN:			/* �C�h�D���̗ь� */
		case SC_HUMMING:			/* �n�~���O */
		case SC_ATKPOTION: // Valaris
		case SC_MATKPOTION:
		case SC_FORTUNE:			/* �K�^�̃L�X */
		case SC_SERVICE4U:			/* �T?�r�X�t�H?��? */
		case SC_ADRENALINE2:
		case SC_ADRENALINE:			/* �A�h���i�������b�V�� */
		case SC_BLIND:				/* ��? */
		case SC_CURSE:
		case SC_CONCENTRATE:		/* �W���͌��� */
		case SC_ANGELUS:			/* �A���[���X */
		case SC_IMPOSITIO:			/* �C���|�V�e�B�I�}�k�X */
		case SC_GLORIA:				/* �O�����A */
		case SC_LOUD:				/* ���E�h�{�C�X */
		case SC_KEEPING:
		case SC_BARRIER:
		case SC_MELTDOWN:		/* �����g�_�E�� */
		case SC_TRUESIGHT:		/* �g�D��?�T�C�g */
		case SC_SPIDERWEB:		/* �X�p�C�_?�E�F�b�u */
		case SC_SLOWDOWN:
		case SC_SPEEDUP0:
		case SC_SPEEDUP1:
		case SC_INCALLSTATUS:
		case SC_INCHIT:			/* HIT�㏸ */
		case SC_INCHITRATE:		/* HIT%�㏸ */
		case SC_INCFLEE:		/* FLEE�㏸ */
		case SC_INCFLEERATE:		/* FLEE%�㏸ */
		case SC_INCMHPRATE:		/* MHP%�㏸ */
		case SC_INCMSPRATE:		/* MSP%�㏸ */
		case SC_INCATKRATE:		/* ATK%�㏸ */
		case SC_INCMATKRATE:
		case SC_INCDEFRATE:
		case SC_INCSTR:
		case SC_INCAGI:
		case SC_INCVIT:
		case SC_INCINT:
		case SC_INCDEX:
		case SC_INCLUK:
		case SC_STRFOOD:
		case SC_AGIFOOD:
		case SC_VITFOOD:
		case SC_INTFOOD:
		case SC_DEXFOOD:
		case SC_LUKFOOD:
		case SC_FLEEFOOD:
		case SC_HITFOOD:
		case SC_BATKFOOD:
		case SC_WATKFOOD:
		case SC_MATKFOOD:
		case SC_SPURT:
		case SC_SPIRIT:
		case SC_SUN_COMFORT:
		case SC_MOON_COMFORT:
		case SC_STAR_COMFORT:
		case SC_FUSION:
		case SC_SKE:
		case SC_SWOO: // [marquis007]
		case SC_STEELBODY:			// ����
		case SC_SKA:
		case SC_TWOHANDQUICKEN:		/* 2HQ */
		case SC_MIRACLE:
			calc_flag = 1;
			break;

		case SC_LULLABY:			/* �q��S */
		case SC_RICHMANKIM:
		case SC_ROKISWEIL:			/* ���L�̋��� */
		case SC_INTOABYSS:			/* �[���̒��� */
		case SC_POEMBRAGI:			/* �u���M�̎� */
		case SC_UGLYDANCE:			/* ��������ȃ_���X */
		case SC_WEAPONPERFECTION:	/* �E�F�|���p?�t�F�N�V���� */
		case SC_TRICKDEAD:			/* ���񂾂ӂ� */
		case SC_FREEZE:				/* ���� */
		case SC_STUN:				/* �X�^���ival2�Ƀ~���b�Z�b�g�j */
		case SC_ENERGYCOAT:			/* �G�i�W?�R?�g */
		case SC_SAFETYWALL:
		case SC_OVERTHRUST:			/* �I?�o?�X���X�g */
		case SC_SLOWPOISON: //Slow potion can be activated even if not poisoned.
		case SC_SUFFRAGIUM:			/* �T�t���M�� */
		case SC_BENEDICTIO:			/* ��? */
		case SC_MAGNIFICAT:			/* �}�O�j�t�B�J?�g */
		case SC_AETERNA:			/* �G?�e���i */
  		case SC_STRIPARMOR:
		case SC_STRIPHELM:
		case SC_CP_WEAPON:
		case SC_CP_SHIELD:
		case SC_CP_ARMOR:
		case SC_CP_HELM:
		case SC_EXTREMITYFIST:		/* ���C���e���� */
		case SC_ANKLE:	/* �A���N�� */
		case SC_BLADESTOP_WAIT:		/* ���n���(�҂�) */
		case SC_HALLUCINATION:
		case SC_SPLASHER:		/* �x�i���X�v���b�V��? */
		case SC_FOGWALL:
		case SC_PRESERVE:
		case SC_DOUBLECAST:
		case SC_AURABLADE:		/* �I?���u��?�h */
		case SC_BABY:
		case SC_WATK_ELEMENT:
		case SC_ARMOR_ELEMENT:
		case SC_LONGING:
		case SC_ORCISH:
		case SC_SHRINK:
		case SC_WINKCHARM:
		case SC_SCRESIST:
		case SC_STOP:
		case SC_CLOSECONFINE:
		case SC_SKILLRATE_UP:
		case SC_KAIZEL:
		case SC_KAAHI:
		case SC_INTRAVISION:
		case SC_BASILICA:
			break;

		default:
			if(battle_config.error_log)
				ShowError("UnknownStatusChange [%d]\n", type);
			return 0;
	}

	//Those that make you stop attacking/walking....
	switch (type) {
		case SC_FREEZE:
		case SC_STUN:
		case SC_SLEEP:
		case SC_STONE:
			if (sd && pc_issit(sd)) //Avoid sprite sync problems.
				pc_setstand(sd);
		case SC_TRICKDEAD:
			battle_stopattack(bl);
			skill_stop_dancing(bl);	/* ���t/�_���X�̒�? */
			// Cancel cast when get status [LuzZza]
			if (battle_config.sc_castcancel)
				skill_castcancel(bl, 0);
		case SC_STOP:
		case SC_CONFUSION:
		case SC_CLOSECONFINE:
		case SC_CLOSECONFINE2:
			battle_stopwalking(bl,1);
		break;
		case SC_HIDING:
		case SC_CLOAKING:
		case SC_CHASEWALK:
			battle_stopattack(bl);	/* �U?��~ */
		break;
	}


	if (bl->type == BL_PC)
	{
		if (flag&4)
			clif_status_load(bl,StatusIconChangeTable[type],1); //Sending to owner since they aren't in the map yet. [Skotlex]
		clif_status_change(bl,StatusIconChangeTable[type],1);
	}

	// Set option as needed.
	opt_flag = 1;
	switch(type){
		//OPT1
		case SC_STONE:
		case SC_FREEZE:
		case SC_STUN:
		case SC_SLEEP:
			if(type == SC_STONE)
				sc->opt1 = OPT1_STONEWAIT;
			else
				sc->opt1 = OPT1_STONE + (type - SC_STONE);
			break;
		//OPT2
		case SC_POISON:
		case SC_CURSE:
		case SC_SILENCE:
		case SC_BLIND:
			sc->opt2 |= 1<<(type-SC_POISON);
			break;
		case SC_DPOISON:	// �b��œł̃G�t�F�N�g���g�p
			sc->opt2 |= OPT2_DPOISON;
			break;
		case SC_SIGNUMCRUCIS:
			sc->opt2 |= OPT2_SIGNUMCRUCIS;
			break;
		//OPT3
		case SC_TWOHANDQUICKEN:		/* 2HQ */
		case SC_SPEARSQUICKEN:		/* �X�s�A�N�C�b�P�� */
		case SC_CONCENTRATION:	/* �R���Z���g��?�V���� */
			sc->opt3 |= 1;
			opt_flag = 0;
			break;
		case SC_MAXOVERTHRUST:
		case SC_OVERTHRUST:			/* �I?�o?�X���X�g */
			sc->opt3 |= 2;
			opt_flag = 0;
			break;
		case SC_ENERGYCOAT:			/* �G�i�W?�R?�g */
			sc->opt3 |= 4;
			opt_flag = 0;
			break;
		case SC_INCATKRATE:		/* ATK%�㏸ */
			//Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex]
			if (bl->type != BL_MOB) {
				opt_flag = 0;
				break;
			}
		case SC_EXPLOSIONSPIRITS:	// �����g��
			sc->opt3 |= 8;
			opt_flag = 0;
			break;
		case SC_STEELBODY:			// ����
		case SC_SKA:
			sc->opt3 |= 16;
			opt_flag = 0;
			break;
		case SC_BLADESTOP:		/* ���n��� */
			sc->opt3 |= 32;
			opt_flag = 0;
			break;
		case SC_BERSERK:		/* �o?�T?�N */
			sc->opt3 |= 128;
			opt_flag = 0;
			break;
		case SC_MARIONETTE:		/* �}���I�l�b�g�R���g��?�� */
		case SC_MARIONETTE2:
			sc->opt3 |= 1024;
			opt_flag = 0;
			break;
		case SC_ASSUMPTIO:		/* �A�X���v�e�B�I */
			sc->opt3 |= 2048;
			opt_flag = 0;
			break;
		case SC_WARM: //SG skills [Komurka]
			sc->opt3 |= 4096;
			opt_flag = 0;
			break;
//		case SC_SWOO: // [marquis007]
//			sc->opt3 |= 8192; //We haven't figured out this value yet...
//			break;
			
		//OPTION
		case SC_HIDING:
			sc->option |= OPTION_HIDE;
			break;
		case SC_CLOAKING:
			sc->option |= OPTION_CLOAK;
			break;
		case SC_CHASEWALK:
			sc->option |= OPTION_CHASEWALK|OPTION_CLOAK;
			break;
		case SC_SIGHT:
			sc->option |= OPTION_SIGHT;
			break;
		case SC_RUWACH:
			sc->option |= OPTION_RUWACH;
			break;
		case SC_WEDDING:
			sc->option |= OPTION_WEDDING;
			break;
		case SC_ORCISH:
			sc->option |= OPTION_ORCISH;
			break;
		case SC_SIGHTTRASHER:
			sc->option |= OPTION_SIGHTTRASHER;
			break;
		case SC_FUSION:
			sc->option |= OPTION_FLYING;
			break;
		default:
			opt_flag = 0;
	}

	if(opt_flag)	/* option��?�X */
		clif_changeoption(bl);

	(sc->count)++;	/* �X�e?�^�X�ُ��? */

	sc->data[type].val1 = val1;
	sc->data[type].val2 = val2;
	sc->data[type].val3 = val3;
	sc->data[type].val4 = val4;
	/* �^�C�}?�ݒ� */
	sc->data[type].timer = add_timer(
		gettick() + tick, status_change_timer, bl->id, type);

	if(sd) {
		if (calc_flag)
			status_calc_pc(sd,0);	/* �X�e?�^�X�Čv�Z */
		if(save_flag)
			chrif_save(sd,0); // save the player status
		if(updateflag)
			clif_updatestatus(sd,updateflag);	/* �X�e?�^�X���N���C�A���g�ɑ��� */
		if (sd->pd)
			pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing
		if (type==SC_RUN)
			pc_run(sd,val1,val2);
	}
	return 1;
}
/*==========================================
 * �X�e�[�^�X�ُ�S����
 *------------------------------------------
 */
int status_change_clear(struct block_list *bl,int type)
{
	struct status_change* sc;
	int i;

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

	if (sc->count == 0)
		return 0;
	for(i = 0; i < SC_MAX; i++)
	{
		//Type 0: PC killed -> EDP and Meltdown must not be dispelled. [Skotlex]
		// Do not reset Xmas status when killed. [Valaris]
		if(sc->data[i].timer == -1 ||
			(type == 0 &&
			(i == SC_EDP || i == SC_MELTDOWN || i == SC_XMAS || i == SC_NOCHAT)))
			continue;

		status_change_end(bl, i, -1);

		if (type == 1 && sc->data[i].timer != -1)
		{	//If for some reason status_change_end decides to still keep the status when quitting. [Skotlex]
			(sc->count)--;
			delete_timer(sc->data[i].timer, status_change_timer);
			sc->data[i].timer = -1;
		}
	}
	sc->opt1 = 0;
	sc->opt2 = 0;
	sc->opt3 = 0;
	sc->option &= OPTION_MASK;

	if(!type || type&2)
		clif_changeoption(bl);

	return 0;
}

/*==========================================
 * �X�e�[�^�X�ُ�I��
 *------------------------------------------
 */
int status_change_end( struct block_list* bl , int type,int tid )
{
	struct map_session_data *sd;
	struct status_change *sc;
	int opt_flag=0, calc_flag = 0;

	nullpo_retr(0, bl);
	
	sc = status_get_sc(bl);
	if(!sc) {
		if(battle_config.error_log)
			ShowError("status_change_end: BL type %d doesn't has sc data!\n", bl->type);
		return 0;
	}

	if(type < 0 || type >= SC_MAX)
		return 0;

	sd = bl->type==BL_PC?(struct map_session_data *)bl:NULL;

	if (sc->data[type].timer != -1 && (sc->data[type].timer == tid || tid == -1)) {

		if (tid == -1)	// �^�C�}����Ă΂�Ă��Ȃ��Ȃ�^�C�}�폜������
			delete_timer(sc->data[type].timer,status_change_timer);

		/* �Y?�ُ̈�𐳏��?�� */
		sc->data[type].timer=-1;
		(sc->count)--;

		switch(type){	/* �ُ�̎�ނ��Ƃ�?�� */
			case SC_PROVOKE:			/* �v���{�b�N */
			case SC_ENDURE: // celest
			case SC_CONCENTRATE:		/* �W���͌��� */
			case SC_BLESSING:			/* �u���b�V���O */
			case SC_ANGELUS:			/* �A���[���X */
			case SC_INCREASEAGI:		/* ���x�㏸ */
			case SC_DECREASEAGI:		/* ���x���� */
			case SC_SIGNUMCRUCIS:		/* �V�O�i���N���V�X */
			case SC_HIDING:
			case SC_ONEHAND:
			case SC_TWOHANDQUICKEN:		/* 2HQ */
			case SC_ADRENALINE2:
			case SC_ADRENALINE:			/* �A�h���i�������b�V�� */
			case SC_ENCPOISON:			/* �G���`�����g�|�C�Y�� */
			case SC_IMPOSITIO:			/* �C���|�V�e�B�I�}�k�X */
			case SC_GLORIA:				/* �O�����A */
			case SC_LOUD:				/* ���E�h�{�C�X */
			case SC_QUAGMIRE:			/* �N�@�O�}�C�A */
			case SC_PROVIDENCE:			/* �v�����B�f���X */
			case SC_SPEARSQUICKEN:		/* �X�s�A�N�C�b�P�� */
			case SC_VOLCANO:
			case SC_DELUGE:
			case SC_VIOLENTGALE:
			case SC_ETERNALCHAOS:		/* �G�^?�i���J�I�X */
			case SC_DRUMBATTLE:			/* ?���ۂ̋��� */
			case SC_NIBELUNGEN:			/* �j?�x�����O�̎w�� */
			case SC_SIEGFRIED:			/* �s���g�̃W?�N�t��?�h */
			case SC_WHISTLE:			/* ���J */
			case SC_ASSNCROS:			/* �[�z�̃A�T�V���N���X */
			case SC_HUMMING:			/* �n�~���O */
			case SC_DONTFORGETME:		/* ����Y��Ȃ��� */
			case SC_FORTUNE:			/* �K�^�̃L�X */
			case SC_SERVICE4U:			/* �T?�r�X�t�H?��? */
			case SC_EXPLOSIONSPIRITS:	// �����g��
			case SC_STEELBODY:			// ����
			case SC_APPLEIDUN:			/* �C�h�D���̗ь� */
			case SC_BLADESTOP_WAIT:
			case SC_CONCENTRATION:		/* �R���Z���g��?�V���� */
			case SC_ASSUMPTIO:			/* �A�V�����v�e�B�I */
			case SC_WINDWALK:		/* �E�C���h�E�H?�N */
			case SC_TRUESIGHT:		/* �g�D��?�T�C�g */
			case SC_SPIDERWEB:		/* �X�p�C�_?�E�F�b�u */
			case SC_MAGICPOWER:		/* ���@��?�� */
			case SC_CHASEWALK:
			case SC_ATKPOTION:		// [Valaris]
			case SC_MATKPOTION:		// [Valaris]
			case SC_MELTDOWN:		/* �����g�_�E�� */
			case SC_CARTBOOST:
			case SC_MINDBREAKER:		/* �}�C���h�u���[�J�[ */
			case SC_EDP:	// Celest
			case SC_SLOWDOWN:
			case SC_ASPDPOTION0:		/* ?���|?�V���� */
			case SC_ASPDPOTION1:
			case SC_ASPDPOTION2:
			case SC_ASPDPOTION3:
			case SC_SPEEDUP0:
			case SC_SPEEDUP1:
			case SC_INCALLSTATUS:
			case SC_INCHIT:			/* HIT�㏸ */
			case SC_INCHITRATE:		/* HIT%�㏸ */
			case SC_INCFLEE:		/* FLEE�㏸ */
			case SC_INCFLEERATE:		/* FLEE%�㏸ */
			case SC_INCMHPRATE:		/* MHP%�㏸ */
			case SC_INCMSPRATE:		/* MSP%�㏸ */
			case SC_INCATKRATE:		/* ATK%�㏸ */
			case SC_INCMATKRATE:
			case SC_INCDEFRATE:
			case SC_INCSTR:
			case SC_INCAGI:
			case SC_INCVIT:
			case SC_INCINT:
			case SC_INCDEX:
			case SC_INCLUK:
			case SC_STRFOOD:
			case SC_AGIFOOD:
			case SC_VITFOOD:
			case SC_INTFOOD:
			case SC_DEXFOOD:
			case SC_LUKFOOD:
			case SC_FLEEFOOD:
			case SC_HITFOOD:
			case SC_BATKFOOD:
			case SC_WATKFOOD:
			case SC_MATKFOOD:
			case SC_BATTLEORDERS:
			case SC_REGENERATION:
			case SC_GUILDAURA:
			case SC_SPURT:
			case SC_SPIRIT: 
			case SC_SUN_COMFORT:
			case SC_MOON_COMFORT:
			case SC_STAR_COMFORT:
			case SC_FUSION:
			case SC_SKE:
			case SC_SWOO: // [marquis007]
			case SC_SKA: // [marquis007]
				calc_flag = 1;
				break;

			case SC_XMAS: // Xmas Suit [Valaris]
			case SC_WEDDING:	//�����p(�����ߏւɂȂ���?���̂�?���Ƃ�)
			if (sd) {
				//Restore look
				sd->view_class = sd->status.class_;
				clif_changelook(&sd->bl,LOOK_BASE,sd->view_class);
#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(battle_config.save_clothcolor && sd->status.clothes_color > 0)
					clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color);
			}
			break;
			case SC_RUN://�삯��
				if (sd && sd->walktimer != -1)
						pc_stop_walking(sd,1);
				if (sc->data[type].val1 >= 7 &&
					DIFF_TICK(gettick(), sc->data[type].val4) <= 1000 &&
					(!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
				)
					status_change_start(bl,SC_SPURT,100,sc->data[type].val1,0,0,0,skill_get_time2(StatusSkillChangeTable[type], sc->data[type].val1),0);
				calc_flag = 1;
			break;
			case SC_AUTOBERSERK:
				if (sc->data[SC_PROVOKE].timer != -1 && sc->data[SC_PROVOKE].val2 == 1)
					status_change_end(bl,SC_PROVOKE,-1);
				break;

			case SC_DEFENDER:
				calc_flag = 1;
			case SC_AUTOGUARD:
			if (sd) {
				struct map_session_data *tsd;
				int i;
				for (i = 0; i < 5; i++)
				{	//Clear the status from the others too [Skotlex]
					if (sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) && tsd->sc.data[type].timer != -1)
						status_change_end(&tsd->bl,type,-1);
				}
			}
			break;
			case SC_DEVOTION:		/* �f�B�{?�V���� */
				{
					struct map_session_data *md = map_id2sd(sc->data[type].val1);
					//The status could have changed because the Crusader left the game. [Skotlex]
					if (md)
					{
						md->devotion[sc->data[type].val2] = 0;
						clif_devotion(md);
					}
					//Remove AutoGuard and Defender [Skotlex]
					if (sc->data[SC_AUTOGUARD].timer != -1)
						status_change_end(bl,SC_AUTOGUARD,-1);
					if (sc->data[SC_DEFENDER].timer != -1)
						status_change_end(bl,SC_DEFENDER,-1);
				}
				break;
			case SC_BLADESTOP:
				{
					struct status_change *tsc = status_get_sc((struct block_list *)sc->data[type].val4);
					//�Е����؂ꂽ�̂ő���̔��n?�Ԃ��؂�ĂȂ��̂Ȃ����
					if(tsc && tsc->data[SC_BLADESTOP].timer!=-1)
						status_change_end((struct block_list *)sc->data[type].val4,SC_BLADESTOP,-1);

					if(sc->data[type].val2==2)
						clif_bladestop((struct block_list *)sc->data[type].val3,(struct block_list *)sc->data[type].val4,0);
				}
				break;
			case SC_DANCING:
				{
					struct map_session_data *dsd;
					struct status_change *dsc;
					if(sc->data[type].val2)
					{
						skill_delunitgroup((struct skill_unit_group *)sc->data[type].val2);
						sc->data[type].val2 = 0;
					}
					if(sc->data[type].val4 && sc->data[type].val4 != BCT_SELF && (dsd=map_id2sd(sc->data[type].val4))){
						dsc = &dsd->sc;
						//���t�ő��肪����ꍇ�����val4��0�ɂ���
						if(dsc && dsc->data[type].timer!=-1)
						{
							dsc->data[type].val2 = dsc->data[type].val4 = 0; //This will prevent recursive loops. 
							status_change_end(&dsd->bl, type, -1);
						}
					}
					if(sc->data[type].val1 == CG_MOONLIT) //Only dance that doesn't has ground tiles... [Skotlex]
						status_change_end(bl, SC_MOONLIT, -1);
				}
				if (sc->data[SC_LONGING].timer!=-1)
					status_change_end(bl,SC_LONGING,-1);				
				calc_flag = 1;
				break;
			case SC_NOCHAT:	//�`���b�g�֎~?��
				if (sd) {
					if(battle_config.manner_system){
						if (sd->status.manner >= 0) // weeee ^^ [celest]
							sd->status.manner = 0;
						clif_updatestatus(sd,SP_MANNER);
					}
				}
				break;
			case SC_SPLASHER:		/* �x�i���X�v���b�V��? */
				{
					struct block_list *src=map_id2bl(sc->data[type].val3);
					if(src && tid!=-1){
						//�����Ƀ_��?�W����?3*3�Ƀ_��?�W
						skill_castend_damage_id(src, bl,sc->data[type].val2,sc->data[type].val1,gettick(),0 );
					}
				}
				break;
			case SC_CLOSECONFINE2:
				{
					struct block_list *src = sc->data[type].val2?map_id2bl(sc->data[type].val2):NULL;
					struct status_change *sc2 = src?status_get_sc(src):NULL;
					if (src && sc2 && sc2->count) {
						if (sc2->data[SC_CLOSECONFINE].timer != -1) //If status was already ended, do nothing.
						{ //Decrease count
							if (--sc2->data[SC_CLOSECONFINE].val1 <= 0) //No more holds, free him up.
								status_change_end(src, SC_CLOSECONFINE, -1);
						}
					}
				}
				break;
			case SC_CLOSECONFINE:
				if (sc->data[type].val2 > 0) { //Caster has been unlocked... nearby chars need to be unlocked.
					int range = 2*skill_get_range2(bl, StatusSkillChangeTable[type], sc->data[type].val1);
					map_foreachinarea(status_change_timer_sub, 
						bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sc,type,gettick());
				}
				break;
		/* option1 */
			case SC_FREEZE:
				sc->data[type].val3 = 0;
				break;

		/* option2 */
			case SC_POISON:				/* �� */
			case SC_BLIND:				/* ��? */
			case SC_CURSE:
				calc_flag = 1;
				break;

			case SC_MARIONETTE:		/* �}���I�l�b�g�R���g��?�� */
			case SC_MARIONETTE2:	/// Marionette target
				{
					// check for partner and end their marionette status as well
					int type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE;
					struct block_list *pbl = map_id2bl(sc->data[type].val3);
					struct status_change* sc2 = pbl?status_get_sc(pbl):NULL;
					if (pbl && sc2 && sc2->count && sc2->data[type2].timer != -1)
							status_change_end(pbl, type2, -1);
					if (type == SC_MARIONETTE)
						clif_marionette(bl, 0); 
					calc_flag = 1;
				}
				break;

			case SC_BERSERK: //val4 indicates if the skill was dispelled. [Skotlex]
				if (sd && sd->status.hp > 100 && !sc->data[type].val4) {
					sd->status.hp = 100;
					clif_updatestatus(sd,SP_HP);
				}
				calc_flag = 1;
				break;
				
			case SC_GRAVITATION:
				if (sd) {
					if (sc->data[type].val3 == BCT_SELF) {
						unsigned int tick = gettick();
						sd->canmove_tick = tick;
						sd->canact_tick = tick;
					} else calc_flag = 1;
				}
				break;
			
			case SC_GOSPEL: //Clear the buffs from other chars.
				if(sc->data[type].val4 != BCT_SELF)
					calc_flag = 1;
				else if (sc->data[type].val3) { //Clear the group.
					struct skill_unit_group *group = (struct skill_unit_group *)sc->data[type].val3;
					sc->data[type].val3 = 0;
					skill_delunitgroup(group);
				}
				break;
			case SC_HERMODE: 
			case SC_BASILICA: //Clear the skill area. [Skotlex]
				if(sc->data[type].val3 == BCT_SELF)
					skill_clear_unitgroup(bl);
				break;
			case SC_MOONLIT: //Clear the unit effect. [Skotlex]
				skill_setmapcell(bl,CG_MOONLIT, sc->data[SC_MOONLIT].val1, CELL_CLRMOONLIT);
				break;
			}


		if (sd)
			clif_status_change(bl,StatusIconChangeTable[type],0);

		switch(type){	/* �����?��Ƃ��Ȃɂ�?�����K�v */
		case SC_STONE:
		case SC_FREEZE:
		case SC_STUN:
		case SC_SLEEP:
			sc->opt1 = 0;
			opt_flag = 1;
			break;

		case SC_POISON:
		case SC_CURSE:
		case SC_SILENCE:
		case SC_BLIND:
			sc->opt2 &= ~(1<<(type-SC_POISON));
			opt_flag = 1;
			break;
		case SC_DPOISON:
			sc->opt2 &= ~OPT2_DPOISON;	// ��?�ԉ���
			opt_flag = 1;
			break;
		case SC_SIGNUMCRUCIS:
			sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
			opt_flag = 1;
			break;

		case SC_HIDING:
			sc->option &= ~OPTION_HIDE;
			opt_flag = 1 ;
			break;
		case SC_CLOAKING:
			sc->option &= ~OPTION_CLOAK;
			calc_flag = 1;	// orn
			opt_flag = 1 ;
			break;
		case SC_CHASEWALK:
			sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
			opt_flag = 1 ;
			break;
		case SC_SIGHT:
			sc->option &= ~OPTION_SIGHT;
			opt_flag = 1;
			break;
		case SC_WEDDING:	//�����p(�����ߏւɂȂ���?���̂�?���Ƃ�)
			sc->option &= ~OPTION_WEDDING;
			opt_flag = 1;
			break;
		case SC_ORCISH:
			sc->option &= ~OPTION_ORCISH;
			opt_flag = 1;
			break;
		case SC_RUWACH:
			sc->option &= ~OPTION_RUWACH;
			opt_flag = 1;
			break;
		case SC_SIGHTTRASHER:
			sc->option &= ~OPTION_SIGHTTRASHER;
			opt_flag = 1;
			break;
		case SC_FUSION:
			sc->option &= ~OPTION_FLYING;
			opt_flag = 1;
			break;
		//opt3
		case SC_TWOHANDQUICKEN:		/* 2HQ */
		case SC_ONEHAND:		/* 1HQ */
		case SC_SPEARSQUICKEN:		/* �X�s�A�N�C�b�P�� */
		case SC_CONCENTRATION:		/* �R���Z���g��?�V���� */
			sc->opt3 &= ~1;
			break;
		case SC_OVERTHRUST:			/* �I?�o?�X���X�g */
			sc->opt3 &= ~2;
			break;
		case SC_ENERGYCOAT:			/* �G�i�W?�R?�g */
			sc->opt3 &= ~4;
			break;
		case SC_INCATKRATE: //Simulated Explosion spirits effect.
			if (bl->type != BL_MOB)
				break;
		case SC_EXPLOSIONSPIRITS:	// �����g��
			sc->opt3 &= ~8;
			break;
		case SC_STEELBODY:			// ����
		case SC_SKA:
			sc->opt3 &= ~16;
			break;
		case SC_BLADESTOP:		/* ���n��� */
			sc->opt3 &= ~32;
			break;
		case SC_BERSERK:		/* �o?�T?�N */
			sc->opt3 &= ~128;
			break;
		case SC_MARIONETTE:		/* �}���I�l�b�g�R���g��?�� */
		case SC_MARIONETTE2:
			sc->opt3 &= ~1024;
			break;
		case SC_ASSUMPTIO:		/* �A�X���v�e�B�I */
			sc->opt3 &= ~2048;
			break;
		case SC_WARM: //SG skills [Komurka]
			sc->opt3 &= ~4096;
			break;
		}

		if(opt_flag)	/* option��?�X��?���� */
			clif_changeoption(bl);

		if (sd && calc_flag)
			status_calc_pc((struct map_session_data *)bl,0);	/* �X�e?�^�X�Čv�Z */
	}

	return 1;
}


/*==========================================
 * �X�e�[�^�X�ُ�I���^�C�}�[
 *------------------------------------------
 */
int status_change_timer(int tid, unsigned int tick, int id, int data)
{
	int type = data;
	struct block_list *bl;
	struct map_session_data *sd=NULL;
	struct status_change *sc;

// security system to prevent forgetting timer removal
	int temp_timerid;

	bl=map_id2bl(id);
#ifndef _WIN32
	nullpo_retr_f(0, bl, "id=%d data=%d",id,data);
#endif
	nullpo_retr(0, sc=status_get_sc(bl));

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

	if(sc->data[type].timer != tid) {
		if(battle_config.error_log)
			ShowError("status_change_timer %d != %d\n",tid,sc->data[type].timer);
		return 0;
	}

	// security system to prevent forgetting timer removal
	// you shouldn't be that careless inside the switch here
	temp_timerid = sc->data[type].timer;
	sc->data[type].timer = -1;

	switch(type){	/* �����?���ɂȂ�ꍇ */
	case SC_MAXIMIZEPOWER:	/* �}�L�V�}�C�Y�p��? */
	case SC_CLOAKING:
		if(!sd || sd->status.sp > 0)
		{
			if (sd)
			{
				sd->status.sp--;
				clif_updatestatus(sd,SP_SP);
			}
			sc->data[type].timer=add_timer( /* �^�C�}?�Đݒ� */
				sc->data[type].val2+tick, status_change_timer, bl->id, data);
			return 0;
		}
		break;

	case SC_CHASEWALK:
		if(sd){
			int sp = 10+sc->data[type].val1*2;
			if (map_flag_gvg(sd->bl.m)) sp *= 5;
			if (pc_damage_sp(sd, sp, 0) > 0) {
				if ((++sc->data[type].val4) == 1) {
					status_change_start(bl, SC_INCSTR,100,
						1<<(sc->data[type].val1-1), 0, 0, 0,
						(sc->data[SC_SPIRIT].timer != -1 && sc->data[SC_SPIRIT].val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration
						*skill_get_time2(StatusSkillChangeTable[type],sc->data[type].val1), 0);
				}
				sc->data[type].timer = add_timer( /* �^�C�}?�Đݒ� */
					sc->data[type].val2+tick, status_change_timer, bl->id, data);
				return 0;
			}
		}
	break;

	case SC_HIDING:		/* �n�C�f�B���O */
		if(sd){		/* SP�������āA���Ԑ����̊Ԃ͎�? */
			if( sd->status.sp > 0 && (--sc->data[type].val2)>0 ){
				if(sc->data[type].val2 % (sc->data[type].val1+3) ==0 ){
					sd->status.sp--;
					clif_updatestatus(sd,SP_SP);
				}
				sc->data[type].timer=add_timer(	/* �^�C�}?�Đݒ� */
					1000+tick, status_change_timer,
					bl->id, data);
				return 0;
			}
		}
	break;

	case SC_SIGHT:	/* �T�C�g */
	case SC_RUWACH:	/* ���A�t */
	case SC_SIGHTBLASTER:
		{
			map_foreachinrange( status_change_timer_sub, bl, 
				skill_get_splash(StatusSkillChangeTable[type], sc->data[type].val1),
				BL_CHAR, bl,sc,type,tick);

			if( (--sc->data[type].val2)>0 ){
				sc->data[type].timer=add_timer(	/* �^�C�}?�Đݒ� */
					250+tick, status_change_timer,
					bl->id, data);
				return 0;
			}
		}
		break;

	case SC_SIGNUMCRUCIS:		/* �V�O�i���N���V�X */
		{
			int race = status_get_race(bl);
			if(race == 6 || battle_check_undead(race,status_get_elem_type(bl))) {
				sc->data[type].timer=add_timer(1000*600+tick,status_change_timer, bl->id, data );
				return 0;
			}
		}
		break;

	case SC_WARM: //SG skills [Komurka]
		if( (--sc->data[type].val2)>0){
			map_foreachinrange( status_change_timer_sub, bl,
				sc->data[type].val4,BL_CHAR,
				bl,sc,type,tick);
			sc->data[type].timer=add_timer(tick+100, status_change_timer,bl->id, data);
			return 0;
		}
		break;

	case SC_PROVOKE:	/* �v���{�b�N/�I?�g�o?�T?�N */
		if(sc->data[type].val2!=0){	/* �I?�g�o?�T?�N�i�P�b���Ƃ�HP�`�F�b�N�j */
			if(sd && sd->status.hp>sd->status.max_hp>>2)	/* ��~ */
				break;
			sc->data[type].timer=add_timer( 1000+tick,status_change_timer, bl->id, data );
			return 0;
		}
		break;

	case SC_ENDURE:	/* �C���f���A */
		if(sd && sd->special_state.infinite_endure) {
			sc->data[type].timer=add_timer( 1000*60+tick,status_change_timer, bl->id, data );
			return 0;
		}
		break;

	case SC_STONE:
		if(sc->data[type].val2 != 0) {
			sc->data[type].val2 = 0;
			sc->data[type].val4 = 0;
			battle_stopwalking(bl,1);
			sc->opt1 = OPT1_STONE;
			clif_changeoption(bl);
			sc->data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
			return 0;
		}
		else if( (--sc->data[type].val3) > 0) {
			int hp = status_get_max_hp(bl);
			if((++sc->data[type].val4)%5 == 0 && status_get_hp(bl) > hp>>2) {
				hp = hp/100;
				if(hp < 1) hp = 1;
				if(sd)
					pc_heal(sd,-hp,0);
				else if(bl->type == BL_MOB){
					struct mob_data *md;
					if((md=((struct mob_data *)bl)) == NULL)
						break;
					md->hp -= hp;
				}
			}
			sc->data[type].timer=add_timer(1000+tick,status_change_timer, bl->id, data );
			return 0;
		}
		break;

	case SC_POISON:
		if (status_get_hp(bl) <= status_get_max_hp(bl)>>2) //Stop damaging after 25% HP left.
			break;
	case SC_DPOISON:
		if ((--sc->data[type].val3) > 0 && sc->data[SC_SLOWPOISON].timer == -1) {
			if(sd) {
				pc_heal(sd, -sc->data[type].val4, 0);
			} else if (bl->type == BL_MOB) {
				((struct mob_data*)bl)->hp -= sc->data[type].val4;
				if (battle_config.show_mob_hp)
					clif_charnameack (0, bl);
			} else 
				battle_heal(NULL, bl, -sc->data[type].val4, 0, 1);
		}
		if (sc->data[type].val3 > 0 && !status_isdead(bl))
		{
			sc->data[type].timer = add_timer (1000 + tick, status_change_timer, bl->id, data );
			return 0;
		}
		break;

	case SC_TENSIONRELAX:	/* �e���V���������b�N�X */
		if(sd){		/* SP�������āAHP��?�^���łȂ����?? */
			if( sd->status.sp > 12 && sd->status.max_hp > sd->status.hp ){
				sc->data[type].timer=add_timer(	/* �^�C�}?�Đݒ� */
					10000+tick, status_change_timer,
					bl->id, data);
				return 0;
			}
			if(sd->status.max_hp <= sd->status.hp)
			{
				status_change_end(&sd->bl,SC_TENSIONRELAX,-1);
				return 0;
			}
		}
		break;
	case SC_BLEEDING:	// [celest]
		// i hope i haven't interpreted it wrong.. which i might ^^;
		// Source:
		// - 10�����Ȫ�HP�����
		// - ����Ϊުޫ�?����Ѫ��������ƪ�?����Ἢ��ʪ�
		// To-do: bleeding effect increases damage taken?
		if ((sc->data[type].val4 -= 10000) >= 0) {
			int hp = rand()%300 + 400;
			if(sd) {
				pc_heal(sd,-hp,0);
			} else if(bl->type == BL_MOB) {
				struct mob_data *md = (struct mob_data *)bl;
				if (md) md->hp -= hp;
			}
			if (!status_isdead(bl)) {
				// walking and casting effect is lost
				battle_stopwalking (bl, 1);
				skill_castcancel (bl, 0);
				sc->data[type].timer = add_timer(10000 + tick, status_change_timer, bl->id, data );
			}
			return 0;
		}
		break;

	// Status changes that don't have a time limit
	case SC_AETERNA:
	case SC_TRICKDEAD:
	case SC_WEIGHT50:
	case SC_WEIGHT90:
	case SC_MAGICPOWER:
	case SC_REJECTSWORD:
	case SC_MEMORIZE:
	case SC_BROKENWEAPON:
	case SC_BROKENARMOR:
	case SC_SACRIFICE:
	case SC_READYSTORM:
	case SC_READYDOWN:
	case SC_READYTURN:
	case SC_READYCOUNTER:
	case SC_RUN:
	case SC_DODGE:
	case SC_AUTOBERSERK: //continues until triggered off manually. [Skotlex]
		sc->data[type].timer=add_timer( 1000*600+tick,status_change_timer, bl->id, data );
		return 0;

	case SC_DANCING: //�_���X�X�L���̎���SP����
		{
			int s = 0;
			int sp = 1;
			if (--sc->data[type].val3 <= 0)
				break;
			if(sd) {
				switch(sc->data[type].val1){
				case BD_RICHMANKIM:				/* �j�����h�̉� 3�b��SP1 */
				case BD_DRUMBATTLEFIELD:		/* ?���ۂ̋��� 3�b��SP1 */
				case BD_RINGNIBELUNGEN:			/* �j?�x�����O�̎w�� 3�b��SP1 */
				case BD_SIEGFRIED:				/* �s���g�̃W?�N�t��?�h 3�b��SP1 */
				case BA_DISSONANCE:				/* �s���a�� 3�b��SP1 */
				case BA_ASSASSINCROSS:			/* �[�z�̃A�T�V���N���X 3�b��SP1 */
				case DC_UGLYDANCE:				/* ��������ȃ_���X 3�b��SP1 */
					s=3;
					break;
				case BD_LULLABY:				/* �q��� 4�b��SP1 */
				case BD_ETERNALCHAOS:			/* �i���̍��� 4�b��SP1 */
				case BD_ROKISWEIL:				/* ���L�̋��� 4�b��SP1 */
				case DC_FORTUNEKISS:			/* �K�^�̃L�X 4�b��SP1 */
					s=4;
					break;
				case CG_HERMODE:				// Wand of Hermod
					sp=5;	//Upkeep = 5
				case BD_INTOABYSS:				/* �[���̒��� 5�b��SP1 */
				case BA_WHISTLE:				/* ���J 5�b��SP1 */
				case DC_HUMMING:				/* �n�~���O 5�b��SP1 */
				case BA_POEMBRAGI:				/* �u���M�̎� 5�b��SP1 */
				case DC_SERVICEFORYOU:			/* �T?�r�X�t�H?��? 5�b��SP1 */
					s=5;
					break;
				case BA_APPLEIDUN:				/* �C�h�D���̗ь� 6�b��SP1 */
					s=6;
					break;
				case CG_MOONLIT:				/* ������̐�ɗ�����Ԃт� 10�b��SP1�H */
					sp= 4*sc->data[type].val2; //Moonlit's cost is 4sp*skill_lv [Skotlex]
					//Upkeep is also every 10 secs.
				case DC_DONTFORGETME:			/* ����Y��Ȃ��Łc 10�b��SP1 */
					s=10;
					break;
				}
				if (s && ((sc->data[type].val3 % s) == 0)) {
					if (sc->data[SC_LONGING].timer != -1)
						sp = s;
					if (pc_damage_sp(sd, sp, 0) <= 0)
						break;
				}
			}
			sc->data[type].timer=add_timer(	/* �^�C�}?�Đݒ� */
				1000+tick, status_change_timer,
				bl->id, data);
			return 0;
		}
		break;

	case SC_DEVOTION:
		{	//Check range and timeleft to preserve status [Skotlex]
			//This implementation won't work for mobs because of map_id2sd, but it's a small cost in exchange of the speed of map_id2sd over map_id2sd
			struct map_session_data *md = map_id2sd(sc->data[type].val1);
			if (md && battle_check_range(bl, &md->bl, sc->data[type].val3) && (sc->data[type].val4-=1000)>0)
			{
				sc->data[type].timer = add_timer(1000+tick, status_change_timer, bl->id, data);
				return 0;
			}
		}
		break;
		
	case SC_BERSERK:		/* �o?�T?�N */
		if(sd){		/* HP��100�ȏ�Ȃ�?? */
			if( (sd->status.hp - sd->status.max_hp*5/100) > 100 ){	// 5% every 10 seconds [DracoRPG]
				sd->status.hp -= sd->status.max_hp*5/100;	// changed to max hp [celest]
				clif_updatestatus(sd,SP_HP);
				sc->data[type].timer = add_timer(	/* �^�C�}?�Đݒ� */
					10000+tick, status_change_timer,
					bl->id, data);
				return 0;
			}
			else
				sd->canregen_tick = gettick() + 300000;
		}
		break;
	case SC_NOCHAT:	//�`���b�g�֎~?��
		if(sd && battle_config.manner_system){
			sd->status.manner++;
			clif_updatestatus(sd,SP_MANNER);
			if (sd->status.manner < 0)
			{	//Every 60 seconds your manner goes up by 1 until it gets back to 0.
				sc->data[type].timer=add_timer(60000+tick, status_change_timer, bl->id, data);
				return 0;
			}
		}
		break;

	case SC_SPLASHER:
		if (sc->data[type].val4 % 1000 == 0) {
			char timer[2];
			sprintf (timer, "%d", sc->data[type].val4/1000);
			clif_message(bl, timer);
		}
		if((sc->data[type].val4 -= 500) > 0) {
			sc->data[type].timer = add_timer(
				500 + tick, status_change_timer,
				bl->id, data);
				return 0;
		}
		break;

	case SC_MARIONETTE:		/* �}���I�l�b�g�R���g��?�� */
	case SC_MARIONETTE2:
		{
			struct block_list *pbl = map_id2bl(sc->data[type].val3);
			if (pbl && battle_check_range(bl, pbl, 7) &&
				(sc->data[type].val2 -= 1000)>0) {
				sc->data[type].timer = add_timer(
					1000 + tick, status_change_timer,
					bl->id, data);
					return 0;
			}
		}
		break;

	case SC_GOSPEL:
		if(sc->data[type].val4 == BCT_SELF){
			int hp, sp;
			hp = (sc->data[type].val1 > 5) ? 45 : 30;
			sp = (sc->data[type].val1 > 5) ? 35 : 20;
			if(status_get_hp(bl) - hp > 0 &&
				(sd == NULL || sd->status.sp - sp> 0))
			{
				if (sd)
					pc_heal(sd,-hp,-sp);
				else if (bl->type == BL_MOB)
					mob_heal((struct mob_data *)bl,-hp);
					
				if ((sc->data[type].val2 -= 10000) > 0) {
					sc->data[type].timer = add_timer(
					10000+tick, status_change_timer,
						bl->id, data);
					return 0;
				}
			}
		}
		break;
		
	case SC_GUILDAURA:
		{
			struct block_list *tbl = map_id2bl(sc->data[type].val2);
			
			if (tbl && battle_check_range(bl, tbl, 2)){
				sc->data[type].timer = add_timer(
					1000 + tick, status_change_timer,
					bl->id, data);
					return 0;
			}
		}
		break;
	}

	// default for all non-handled control paths
	// security system to prevent forgetting timer removal

	// if we reach this point we need the timer for the next call, 
	// so restore it to have status_change_end handle a valid timer
	sc->data[type].timer = temp_timerid; 

	return status_change_end( bl,type,tid );
}

/*==========================================
 * �X�e�[�^�X�ُ�^�C�}�[�͈͏���
 *------------------------------------------
 */
int status_change_timer_sub(struct block_list *bl, va_list ap )
{
	struct block_list *src;
	struct status_change *sc, *tsc;
	struct map_session_data* sd=NULL;
	struct map_session_data* tsd=NULL;

	int type;
	unsigned int tick;

	src=va_arg(ap,struct block_list*);
	sc=va_arg(ap,struct status_change*);
	type=va_arg(ap,int);
	tick=va_arg(ap,unsigned int);
	tsc=status_get_sc(bl);
	
	if (status_isdead(bl))
		return 0;
	if (src->type==BL_PC) sd= (struct map_session_data*)src;
	if (bl->type==BL_PC) tsd= (struct map_session_data*)bl;

	switch( type ){
	case SC_SIGHT:	/* �T�C�g */
	case SC_CONCENTRATE:
		if (tsc && tsc->count) {
			if (tsc->data[SC_HIDING].timer != -1)
				status_change_end( bl, SC_HIDING, -1);
			if (tsc->data[SC_CLOAKING].timer != -1)
				status_change_end( bl, SC_CLOAKING, -1);
		}
		break;
	case SC_RUWACH:	/* ���A�t */
		if (tsc && tsc->count && (tsc->data[SC_HIDING].timer != -1 ||	// if the target is using a special hiding, i.e not using normal hiding/cloaking, don't bother
			tsc->data[SC_CLOAKING].timer != -1)) {
			status_change_end( bl, SC_HIDING, -1);
			status_change_end( bl, SC_CLOAKING, -1);
			if(battle_check_target( src, bl, BCT_ENEMY ) > 0)
				skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0);
		}
		break;
	case SC_SIGHTBLASTER:
		{
			if (sc && sc->count && sc->data[type].val2 > 0 && battle_check_target( src, bl, BCT_ENEMY ) > 0)
			{	//sc_ check prevents a single round of Sight Blaster hitting multiple opponents. [Skotlex]
				skill_attack(BF_MAGIC,src,src,bl,WZ_SIGHTBLASTER,1,tick,0);
				sc->data[type].val2 = 0; //This signals it to end.
			}
		}
		break;
	case SC_WARM: //SG skills [Komurka]
		if(sc && sc->data[type].val2 &&
			battle_check_target( src,bl, BCT_ENEMY ) > 0)
	 	{
			if(tsd)
				//Only damage SP [Skotlex]
				//	case SG_SUN_WARM:
				pc_damage_sp(tsd, 60, 0);
			else { //Otherwise, Knockback attack.
				if(sd && pc_damage_sp(sd, 2, 0) <= 0)
					sd->sc.data[type].val2 = 0; //Makes it end on the next tick.
				skill_attack(BF_WEAPON,src,src,bl,sc->data[type].val3,sc->data[type].val1,tick,0);
			}
		}
		break;
	case SC_CLOSECONFINE:
		//Lock char has released the hold on everyone...
		if (tsc && tsc->count && tsc->data[SC_CLOSECONFINE2].timer != -1 && tsc->data[SC_CLOSECONFINE2].val2 == src->id) {
			tsc->data[SC_CLOSECONFINE2].val2 = 0;
			status_change_end(bl, SC_CLOSECONFINE2, -1);
		}
		break;
	}
	return 0;
}

int status_change_clear_buffs (struct block_list *bl)
{
	int i;
	struct status_change *sc= status_get_sc(bl);
	if (!sc || !sc->count)
		return 0;		
	for (i = 20; i < SC_MAX; i++) {
		if(i==SC_HALLUCINATION || i==SC_WEIGHT50 || i==SC_WEIGHT90
			|| i == SC_QUAGMIRE || i == SC_SIGNUMCRUCIS || i == SC_DECREASEAGI 
			|| i == SC_SLOWDOWN || i == SC_ANKLE|| i == SC_BLADESTOP
			|| i == SC_MINDBREAKER || i == SC_WINKCHARM 
			|| i == SC_STOP || i == SC_NOCHAT || i == SC_ORCISH
			|| i == SC_STRIPWEAPON || i == SC_STRIPSHIELD || i == SC_STRIPARMOR || i == SC_STRIPHELM
			|| i == SC_COMBO || i == SC_DANCING || i == SC_GUILDAURA
			)
			continue;
		if(sc->data[i].timer != -1)
			status_change_end(bl,i,-1);
	}
	return 0;
}
int status_change_clear_debuffs (struct block_list *bl)
{
	int i;
	struct status_change *sc = status_get_sc(bl);
	if (!sc || !sc->count)
		return 0;
	for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++) {
		if(sc->data[i].timer != -1)
			status_change_end(bl,i,-1);
	}
	//Other ailments not in the common range.
	if(sc->data[SC_HALLUCINATION].timer != -1)
		status_change_end(bl,SC_HALLUCINATION,-1);
	if(sc->data[SC_QUAGMIRE].timer != -1)
		status_change_end(bl,SC_QUAGMIRE,-1);
	if(sc->data[SC_SIGNUMCRUCIS].timer != -1)
		status_change_end(bl,SC_SIGNUMCRUCIS,-1);
	if(sc->data[SC_DECREASEAGI].timer != -1)
		status_change_end(bl,SC_DECREASEAGI,-1);
	if(sc->data[SC_SLOWDOWN].timer != -1)
		status_change_end(bl,SC_SLOWDOWN,-1);
	if(sc->data[SC_MINDBREAKER].timer != -1)
		status_change_end(bl,SC_MINDBREAKER,-1);
	if(sc->data[SC_WINKCHARM].timer != -1)
		status_change_end(bl,SC_WINKCHARM,-1);
	if(sc->data[SC_STOP].timer != -1)
		status_change_end(bl,SC_STOP,-1);
	if(sc->data[SC_ORCISH].timer != -1)
		status_change_end(bl,SC_ORCISH,-1);
	if(sc->data[SC_STRIPWEAPON].timer != -1)
		status_change_end(bl,SC_STRIPWEAPON,-1);
	if(sc->data[SC_STRIPSHIELD].timer != -1)
		status_change_end(bl,SC_STRIPSHIELD,-1);
	if(sc->data[SC_STRIPARMOR].timer != -1)
		status_change_end(bl,SC_STRIPARMOR,-1);
	if(sc->data[SC_STRIPHELM].timer != -1)
		status_change_end(bl,SC_STRIPHELM,-1);
	return 0;
}

static int status_calc_sigma(void)
{
	int i,j,k;

	for(i=0;i<MAX_PC_CLASS;i++) {
		memset(hp_sigma_val[i],0,sizeof(hp_sigma_val[i]));
		for(k=0,j=2;j<=MAX_LEVEL;j++) {
			k += hp_coefficient[i]*j + 50;
			k -= k%100;
			hp_sigma_val[i][j-1] = k;
		}
	}
	return 0;
}

int status_readdb(void) {
	int i,j;
	FILE *fp;
	char line[1024], path[1024],*p;

	sprintf(path, "%s/job_db1.txt", db_path);
	fp=fopen(path,"r"); // Job-specific values (weight, HP, SP, ASPD)
	if(fp==NULL){
		ShowError("can't read %s\n", path);
		return 1;
	}
	while(fgets(line, sizeof(line)-1, fp)){
		char *split[23];
		if(line[0]=='/' && line[1]=='/')
			continue;
		for(j=0,p=line;j<22 && p;j++){
			split[j]=p;
			p=strchr(p,',');
			if(p) *p++=0;
		}
		if(j<22)
			continue;
       	if(atoi(split[0])>=MAX_PC_CLASS)
		    continue;
		max_weight_base[atoi(split[0])]=atoi(split[1]);
		hp_coefficient[atoi(split[0])]=atoi(split[2]);
		hp_coefficient2[atoi(split[0])]=atoi(split[3]);
		sp_coefficient[atoi(split[0])]=atoi(split[4]);
		for(j=0;j<17;j++)
			aspd_base[atoi(split[0])][j]=atoi(split[j+5]);
	}
	fclose(fp);
	ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","job_db1.txt");

	memset(job_bonus,0,sizeof(job_bonus)); // Job-specific stats bonus
	sprintf(path, "%s/job_db2.txt", db_path);
	fp=fopen(path,"r");
	if(fp==NULL){
		ShowError("can't read %s\n", path);
		return 1;
	}
	while(fgets(line, sizeof(line)-1, fp)){
       	char *split[MAX_LEVEL+1]; //Job Level is limited to MAX_LEVEL, so the bonuses should likewise be limited to it. [Skotlex]
		if(line[0]=='/' && line[1]=='/')
			continue;
		for(j=0,p=line;j<MAX_LEVEL+1 && p;j++){
			split[j]=p;
			p=strchr(p,',');
			if(p) *p++=0;
		}
		if(atoi(split[0])>=MAX_PC_CLASS)
		    continue;
		for(i=1;i<j && split[i];i++)
			job_bonus[atoi(split[0])][i-1]=atoi(split[i]);
	}
	fclose(fp);
	ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",path);

	// �T�C�Y�␳�e?�u��
	for(i=0;i<3;i++)
		for(j=0;j<20;j++)
			atkmods[i][j]=100;
	sprintf(path, "%s/size_fix.txt", db_path);
	fp=fopen(path,"r");
	if(fp==NULL){
		ShowError("can't read %s\n", path);
		return 1;
	}
	i=0;
	while(fgets(line, sizeof(line)-1, fp)){
		char *split[20];
		if(line[0]=='/' && line[1]=='/')
			continue;
		if(atoi(line)<=0)
			continue;
		memset(split,0,sizeof(split));
		for(j=0,p=line;j<20 && p;j++){
			split[j]=p;
			p=strchr(p,',');
			if(p) *p++=0;
		}
		for(j=0;j<20 && split[j];j++)
			atkmods[i][j]=atoi(split[j]);
		i++;
	}
	fclose(fp);
	ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",path);

	// ��?�f?�^�e?�u��
	for(i=0;i<5;i++){
		for(j=0;j<MAX_REFINE; j++)
			percentrefinery[i][j]=100;
		percentrefinery[i][j]=0; //Slot MAX+1 always has 0% success chance [Skotlex]
		refinebonus[i][0]=0;
		refinebonus[i][1]=0;
		refinebonus[i][2]=10;
	}

	sprintf(path, "%s/refine_db.txt", db_path);
	fp=fopen(path,"r");
	if(fp==NULL){
		ShowError("can't read %s\n", path);
		return 1;
	}
	i=0;
	while(fgets(line, sizeof(line)-1, fp)){
		char *split[16];
		if(line[0]=='/' && line[1]=='/')
			continue;
		if(atoi(line)<=0)
			continue;
		memset(split,0,sizeof(split));
		for(j=0,p=line;j<16 && p;j++){
			split[j]=p;
			p=strchr(p,',');
			if(p) *p++=0;
		}
		refinebonus[i][0]=atoi(split[0]);	// ��?�{?�i�X
		refinebonus[i][1]=atoi(split[1]);	// ��?��?�{?�i�X
		refinebonus[i][2]=atoi(split[2]);	// ���S��?���E
		for(j=0;j<MAX_REFINE && split[j];j++)
			percentrefinery[i][j]=atoi(split[j+3]);
		i++;
	}
	fclose(fp); //Lupus. close this file!!!
	ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",path);

	return 0;
}

/*==========================================
 * �X�L���֌W����������
 *------------------------------------------
 */
int do_init_status(void)
{
	if (SC_MAX > MAX_STATUSCHANGE)
	{
		ShowDebug("status.h defines %d status changes, but the MAX_STATUSCHANGE is %d! Fix it.\n", SC_MAX, MAX_STATUSCHANGE);
		exit(1);
	}
	add_timer_func_list(status_change_timer,"status_change_timer");
	initChangeTables();
	status_readdb();
	status_calc_sigma();
	return 0;
}