Jump to content

Rebel

Members
  • Posts

    436
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Rebel

  1. Ivion is a scripter on eAthena boards. Im sure someone fork or has her scripts lying around somewhere.. 

    2 hours ago, Rynbef said:

    I don't know from which year they should be but I can recommend u to use newer scripts and modify it to ur whishes. Cuz of the years rA does much optimizations and some functions could changed but the best reason why is, that newer scripts are more dynamically, much smaller, faster and efficient.

    If u ask want a specific script u can ask for and we will help u if we can. Search for a script and modify it to what u want. Maybe rewrite it from scratch.

    I've all of my scripts from my old server. But I recreate a few scripts and since my server closure 2017 I've learned much more and the new scripts are much better.

     

    Rynbef~

     

  2. 10 hours ago, Eichi said:

    Hello, I would like to know if anyone knows how to help me, I would like to remove the chance of the 'Miracle' ability to activate, I thought about setting '0' in the configuration of the chance but I was afraid of giving problems.

    Does anyone know if I put the problem here?

    
    sg_miracle_skill_ratio: 0

     

    If I do this will it not activate? can cause problems?

    Just put 0 and you're all set!

  3. 25 minutes ago, Brahms said:

    Good day everyone just want to request some modification for some specific skills such as , Charge Attack, Body Relocation,Back Sliding, Flying Side Kick, High Jump, Shadow Jump. to be fail to move if locked in place due to skill such as Ankle Snare & Spider Web.. kindly help me with these guys please!.. Thank you so much and have a bless day.

    Try this..

    In skill.cpp add below:

    case WM_SATURDAY_NIGHT_FEVER:
    	if( !mapdata_flag_vs(mapdata) ) {
    		clif_skill_teleportmessage(sd,2); // This skill uses this msg instead of skill fails.
    		return true;
    	}
    break;

    this

    case TF_BACKSLIDING:
    case MO_BODYRELOCATION:
    	if( sd && ( sd->sc.data[SC_RG_CCONFINE_S] || sd->sc.data[SC_ANKLESNARE] || sd->sc.data[SC_SPIDERWEB] ) ) {
    		clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
      		return true;
      	}
    break;

    just add the Charge attack, Flying side kick, High jump and Shadow jump..

  4. 2 hours ago, idLaZ said:

    Open skill.c

    Find: struct map_session_data *tsd = BL_CAST(BL_PC, target);

    After, add: struct status_change *sc, *tsc;

    Find the 2: if( require.weapon && !pc_check_weapontype(sd,require.weapon) ) {

    Replace with: if(require.weapon && !(pc_check_weapontype(sd,require.weapon) || (skill_id == LK_PARRYING && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_KNIGHT && sd->status.weapon == W_1HSWORD)) ){

    skill.c? how outdated is your rathena?

  5. On 9/25/2018 at 2:04 AM, idLaZ said:

    If I remember correctly, I made it work in the latest rAthena. Will send you the fix, possible later when I'm in office.

    Okay thank you. Will wait for it.

    BUMP! Any dev that can help? ?

    @vBrenth Not working. Still cant use 1 hand sword when soul linked..

  6. If killed by player:

    [Error]: buildin_getmonsterinfo: Wrong Monster ID: 2000000
    [Debug]: Source (NPC): auto_ress_mvp (invisible/not on a map)

    If killed by monster:

    [Error]: buildin_getmonsterinfo: Wrong Monster ID: 110009749
    [Debug]: Source (NPC): auto_ress_mvp (invisible/not on a map)

    But the player is resurrected after 5 seconds when apple is on inventory. (512 = Apple)

  7. Colosseum - PvP/GvG or Event Arena

    View File

    Join my facebook site at: https://www.facebook.com/OlroxMaps

    The whole main idea was to create a circular colosseum although the ambience style was intended to be a little different than this. I was inspired by the movie -gladiator- where there is a clandestine colosseum outside of Rome where slaves are forced to fight.

    Features:

    • Rigging and animation in Palm Trees and Flags: This animation is based in bones/articulations and its working thanks by the GR2 project of animated mobs in 3D. They are loaded as none-clickeable NPC in game. Please watch the video to get what I mean!
    • The circular core of the colosseum, the stairs, were made and texturized in 3D from scratch. Atm I'm focussing into the way Ragnarok has it textures which for me they tend to have a grainy surface and shadows on some edges. Thats what I did aswell
    • Effects like sand, and a dense fog that you can see if you move the camera at a high zoom, gives the feeling I was looking for.

    Please I suggest you to watch the video. This map comes with animation that you can't see on screensshots


    • Submitter
    • Submitted
      02/28/2014
    • Category
      Map

     

  8. [root@server ~]# cd /home/rAthena
    [root@server rAthena]# gdb map-server core.2543
    GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7
    Copyright (C) 2013 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-redhat-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from /home/rAthena/map-server...done.
    [New LWP 2543]
    Core was generated by `./map-server'.
    Program terminated with signal 11, Segmentation fault.
    #0  0x000000000042a512 in battle_calc_cardfix (attack_type=1, src=0x4bf2060,
        target=<optimized out>, nk=<optimized out>, rh_ele=<optimized out>,
        lh_ele=<optimized out>, damage=3167, left=0, flag=529) at battle.c:595
    595                                     cardfix = cardfix * (100 + sd->magic_add                                                                                        race[tstatus->race] + sd->magic_addrace[RC_ALL] + sd->magic_addrace2[t_race2]) / 100;
    (gdb) bt full
    #0  0x000000000042a512 in battle_calc_cardfix (attack_type=1, src=0x4bf2060,
        target=<optimized out>, nk=<optimized out>, rh_ele=<optimized out>,
        lh_ele=<optimized out>, damage=3167, left=0, flag=529) at battle.c:595
            sd = 0x4bf2060
            tsd = <optimized out>
            cardfix = <optimized out>
            s_class = 4013
            t_class = 4008
            s_race2 = RC2_NONE
            t_race2 = <optimized out>
            s_defele = ELE_NEUTRAL
            sstatus = 0x4bf24e4
            tstatus = 0x4a2fae4
            original_damage = 3167
            i = <optimized out>
    #1  0x00000000004372c7 in initialize_weapon_data (wflag=3167,
        skill_lv=<optimized out>, skill_id=0, target=0x4a2f660, src=0x4bf2060)
        at battle.c:5143
            sstatus = 0x4a2f600
            sc = 0x190
            tstatus = 0x4a2fae4
            sd = <optimized out>
            wd = {damage = <optimized out>, damage2 = <optimized out>,
    ---Type <return> to continue, or q <return> to quit---return
              type = DMG_NORMAL, div_ = <optimized out>,
              amotion = <optimized out>, dmotion = <optimized out>,
              blewcount = <optimized out>, flag = <optimized out>,
              miscflag = <optimized out>, dmg_lv = <optimized out>,
              isspdamage = <optimized out>}
    #2  battle_calc_weapon_attack (src=0x4bf2060, target=0x4a2f660,
        skill_id=<optimized out>, skill_lv=<optimized out>, wflag=3167)
        at battle.c:5266
            sd = <optimized out>
            tsd = <optimized out>
            wd = {damage = 3167, damage2 = 830, type = DMG_NORMAL, div_ = 1,
              amotion = 30, dmotion = 400, blewcount = 0, flag = 529,
              miscflag = 0, dmg_lv = ATK_DEF, isspdamage = 0 '\000'}
            sc = 0x211
            tstatus = 0x211
            right_element = <optimized out>
            left_element = <optimized out>
            infdef = 0 '\000'
            __FUNCTION__.21951 = "battle_calc_weapon_attack"
    #3  0x000000000043c5b8 in battle_weapon_attack (src=0x7fff64e71ff0,
        target=0x4a2f660, tick=<optimized out>, flag=<optimized out>)
        at battle.c:7092
            index = -31585
    ---Type <return> to continue, or q <return> to quit---return
            sd = 0x4bf2060
            tsd = <optimized out>
            sstatus = <optimized out>
            tstatus = <optimized out>
            sc = 0x4bf2540
            tsc = 0x4a2fb40
            damage = <optimized out>
            skillv = <optimized out>
            wd = {damage = 0, damage2 = 0, type = DMG_SIT_DOWN, div_ = 0,
              amotion = 659864132, dmotion = 13, blewcount = 14, flag = 15,
              miscflag = 659864132, dmg_lv = 32757, isspdamage = -126 '\202'}
            vanish_damage = 0 '\000'
            __FUNCTION__.22341 = "battle_weapon_attack"
    #4  0x00000000000e427d in ?? ()
    No symbol table info available.
    #5  0x0000000004bf2060 in ?? ()
    No symbol table info available.
    #6  0x0000000004a2f660 in ?? ()
    No symbol table info available.
    #7  0x0000000004bf2080 in ?? ()
    No symbol table info available.
    #8  0x0000000004bf2060 in ?? ()
    No symbol table info available.
    ---Type <return> to continue, or q <return> to quit---return
    #9  0x0000000000000417 in ?? ()
    No symbol table info available.
    #10 0x00000000000e427d in ?? ()
    No symbol table info available.
    #11 0x0000000004bf2060 in ?? ()
    No symbol table info available.
    #12 0x0000000004a2f660 in ?? ()
    No symbol table info available.
    #13 0x0000000004bf2080 in ?? ()
    No symbol table info available.
    #14 0x000000000055236a in unit_attack (
        src=0x4e395e <skill_check_condition_mercenary+158>, target_id=0,
        continuous=77788768) at unit.c:2210
            target = 0x4bf2060
            ud = 0x4bf2060
            range = <optimized out>
    #15 0x000000000000022d in ?? ()
    No symbol table info available.
    #16 0x0000000004298560 in ?? ()
    No symbol table info available.
    #17 0x00007ff52628113c in ?? ()
    No symbol table info available.
    #18 0x00000000000e5b94 in ?? ()
    ---Type <return> to continue, or q <return> to quit---return
    No symbol table info available.
    #19 0x00000000005ad7ba in get_uptime () at timer.c:405
    No locals.
    #20 0x000e427e00000416 in ?? ()
    No symbol table info available.
    #21 0x00000000028256f0 in ?? ()
    No symbol table info available.
    #22 0x00007fff64e722a8 in ?? ()
    No symbol table info available.
    #23 0x00000000028256f0 in ?? ()
    No symbol table info available.
    #24 0x0000000000000002 in ?? ()
    No symbol table info available.
    #25 0x0000000000000001 in ?? ()
    No symbol table info available.
    #26 0x0000000000000000 in ?? ()
    No symbol table info available.
    (gdb)
    

    battle.c

    int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_list *target, int nk, int rh_ele, int lh_ele, int64 damage, int left, int flag){
    	struct map_session_data *sd, ///< Attacker session data if BL_PC
    		*tsd; ///< Target session data if BL_PC
    	short cardfix = 1000;
    	enum e_classAE s_class, ///< Attacker class
    		t_class; ///< Target class
    	enum e_race2 s_race2, /// Attacker Race2
    		t_race2; ///< Target Race2
    	enum e_element s_defele; ///< Attacker Element (not a weapon or skill element!)
    	struct status_data *sstatus, ///< Attacker status data
    		*tstatus; ///< Target status data
    	int64 original_damage;
    	int i;
    
    	if( !damage )
    		return 0;
    
    	original_damage = damage;
    
    	sd = BL_CAST(BL_PC, src);
    	tsd = BL_CAST(BL_PC, target);
    	t_class = (enum e_classAE)status_get_class(target);
    	s_class = (enum e_classAE)status_get_class(src);
    	sstatus = status_get_status_data(src);
    	tstatus = status_get_status_data(target);
    	s_race2 = status_get_race2(src);
    	t_race2 = status_get_race2(target);
    	s_defele = (tsd) ? (enum e_element)status_get_element(src) : ELE_NONE;
    
    //Official servers apply the cardfix value on a base of 1000 and round down the reduction/increase
    #define APPLY_CARDFIX(damage, fix) { (damage) = (damage) - (int64)(((damage) * (1000 - (fix))) / 1000); }
    
    	switch( attack_type ) {
    		case BF_MAGIC:
    			// Affected by attacker ATK bonuses
    			if( sd && !(nk&NK_NO_CARDFIX_ATK) ) {
    				cardfix = cardfix * (100 + sd->magic_addrace[tstatus->race] + sd->magic_addrace[RC_ALL] + sd->magic_addrace2[t_race2]) / 100;
    				if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
    					cardfix = cardfix * (100 + sd->magic_addele[tstatus->def_ele] + sd->magic_addele[ELE_ALL] + 
    						sd->magic_addele_script[tstatus->def_ele] + sd->magic_addele_script[ELE_ALL]) / 100;
    					cardfix = cardfix * (100 + sd->magic_atk_ele[rh_ele] + sd->magic_atk_ele[ELE_ALL]) / 100;
    				}
    				cardfix = cardfix * (100 + sd->magic_addsize[tstatus->size] + sd->magic_addsize[SZ_ALL]) / 100;
    				cardfix = cardfix * (100 + sd->magic_addclass[tstatus->class_] + sd->magic_addclass[CLASS_ALL]) / 100;
    				for( i = 0; i < ARRAYLENGTH(sd->add_mdmg) && sd->add_mdmg[i].rate; i++ ) {
    					if( sd->add_mdmg[i].class_ == t_class ) {
    						cardfix = cardfix * (100 + sd->add_mdmg[i].rate) / 100;
    						break;
    					}
    				}
    				APPLY_CARDFIX(damage, cardfix);
    			}
    
    			// Affected by target DEF bonuses
    			if( tsd && !(nk&NK_NO_CARDFIX_DEF) ) {
    				cardfix = 1000; // reset var for target
    
    				if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
    					int ele_fix = tsd->subele[rh_ele] + tsd->subele[ELE_ALL] + tsd->subele_script[rh_ele] + tsd->subele_script[ELE_ALL];
    
    					for( i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++ ) {
    						if( tsd->subele2[i].ele != rh_ele )
    							continue;
    						if( !(((tsd->subele2[i].flag)&flag)&BF_WEAPONMASK &&
    							((tsd->subele2[i].flag)&flag)&BF_RANGEMASK &&
    							((tsd->subele2[i].flag)&flag)&BF_SKILLMASK) )
    							continue;
    						ele_fix += tsd->subele2[i].rate;
    					}
    					if (s_defele != ELE_NONE)
    						ele_fix += tsd->subdefele[s_defele] + tsd->subdefele[ELE_ALL];
    					cardfix = cardfix * (100 - ele_fix) / 100;
    				}
    				cardfix = cardfix * (100 - tsd->subsize[sstatus->size] - tsd->subsize[SZ_ALL]) / 100;
    				cardfix = cardfix * (100 - tsd->subrace2[s_race2]) / 100;
    				cardfix = cardfix * (100 - tsd->subrace[sstatus->race] - tsd->subrace[RC_ALL]) / 100;
    				cardfix = cardfix * (100 - tsd->subclass[sstatus->class_] - tsd->subclass[CLASS_ALL]) / 100;
    
    				for( i = 0; i < ARRAYLENGTH(tsd->add_mdef) && tsd->add_mdef[i].rate; i++ ) {
    					if( tsd->add_mdef[i].class_ == s_class ) {
    						cardfix = cardfix * (100 - tsd->add_mdef[i].rate) / 100;
    						break;
    					}
    				}
    #ifndef RENEWAL
    				//It was discovered that ranged defense also counts vs magic! [Skotlex]
    				if( flag&BF_SHORT )
    					cardfix = cardfix * (100 - tsd->bonus.near_attack_def_rate) / 100;
    				else
    					cardfix = cardfix * (100 - tsd->bonus.long_attack_def_rate) / 100;
    #endif
    				cardfix = cardfix * (100 - tsd->bonus.magic_def_rate) / 100;
    
    				if( tsd->sc.data[SC_MDEF_RATE] )
    					cardfix = cardfix * (100 - tsd->sc.data[SC_MDEF_RATE]->val1) / 100;
    				APPLY_CARDFIX(damage, cardfix);
    			}
    			break;
    
    		case BF_WEAPON:
    			// Affected by attacker ATK bonuses
    			if( sd && !(nk&NK_NO_CARDFIX_ATK) && (left&2) ) {
    				short cardfix_ = 1000;
    
    				if( sd->state.arrow_atk ) { // Ranged attack
    					cardfix = cardfix * (100 + sd->right_weapon.addrace[tstatus->race] + sd->arrow_addrace[tstatus->race] +
    						sd->right_weapon.addrace[RC_ALL] + sd->arrow_addrace[RC_ALL]) / 100;
    					if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
    						int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->arrow_addele[tstatus->def_ele] +
    							sd->right_weapon.addele[ELE_ALL] + sd->arrow_addele[ELE_ALL];
    
    						for( i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++ ) {
    							if( sd->right_weapon.addele2[i].ele != tstatus->def_ele )
    								continue;
    							if( !(((sd->right_weapon.addele2[i].flag)&flag)&BF_WEAPONMASK &&
    								((sd->right_weapon.addele2[i].flag)&flag)&BF_RANGEMASK &&
    								((sd->right_weapon.addele2[i].flag)&flag)&BF_SKILLMASK) )
    								continue;
    							ele_fix += sd->right_weapon.addele2[i].rate;
    						}
    						cardfix = cardfix * (100 + ele_fix) / 100;
    					}
    					cardfix = cardfix * (100 + sd->right_weapon.addsize[tstatus->size] + sd->arrow_addsize[tstatus->size] +
    						sd->right_weapon.addsize[SZ_ALL] + sd->arrow_addsize[SZ_ALL]) / 100;
    					cardfix = cardfix * (100 + sd->right_weapon.addrace2[t_race2]) / 100;
    					cardfix = cardfix * (100 + sd->right_weapon.addclass[tstatus->class_] + sd->arrow_addclass[tstatus->class_] +
    						sd->right_weapon.addclass[CLASS_ALL] + sd->arrow_addclass[CLASS_ALL]) / 100;
    				} else { // Melee attack
    					int skill = 0;
    
    					// Calculates each right & left hand weapon bonuses separatedly
    					if( !battle_config.left_cardfix_to_right ) {
    						// Right-handed weapon
    						cardfix = cardfix * (100 + sd->right_weapon.addrace[tstatus->race] + sd->right_weapon.addrace[RC_ALL]) / 100;
    						if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
    							int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->right_weapon.addele[ELE_ALL];
    
    							for( i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++ ) {
    								if( sd->right_weapon.addele2[i].ele != tstatus->def_ele )
    									continue;
    								if( !(((sd->right_weapon.addele2[i].flag)&flag)&BF_WEAPONMASK &&
    									((sd->right_weapon.addele2[i].flag)&flag)&BF_RANGEMASK &&
    									((sd->right_weapon.addele2[i].flag)&flag)&BF_SKILLMASK) )
    									continue;
    								ele_fix += sd->right_weapon.addele2[i].rate;
    							}
    							cardfix = cardfix * (100 + ele_fix) / 100;
    						}
    						cardfix = cardfix * (100 + sd->right_weapon.addsize[tstatus->size] + sd->right_weapon.addsize[SZ_ALL]) / 100;
    						cardfix = cardfix * (100 + sd->right_weapon.addrace2[t_race2]) / 100;
    						cardfix = cardfix * (100 + sd->right_weapon.addclass[tstatus->class_] + sd->right_weapon.addclass[CLASS_ALL]) / 100;
    
    						if( left&1 ) { // Left-handed weapon
    							cardfix_ = cardfix_ * (100 + sd->left_weapon.addrace[tstatus->race] + sd->left_weapon.addrace[RC_ALL]) / 100;
    							if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
    								int ele_fix_lh = sd->left_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[ELE_ALL];
    
    								for( i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++ ) {
    									if( sd->left_weapon.addele2[i].ele != tstatus->def_ele )
    										continue;
    									if( !(((sd->left_weapon.addele2[i].flag)&flag)&BF_WEAPONMASK &&
    										((sd->left_weapon.addele2[i].flag)&flag)&BF_RANGEMASK &&
    										((sd->left_weapon.addele2[i].flag)&flag)&BF_SKILLMASK) )
    										continue;
    									ele_fix_lh += sd->left_weapon.addele2[i].rate;
    								}
    								cardfix_ = cardfix_ * (100 + ele_fix_lh) / 100;
    							}
    							cardfix_ = cardfix_ * (100 + sd->left_weapon.addsize[tstatus->size] + sd->left_weapon.addsize[SZ_ALL]) / 100;
    							cardfix_ = cardfix_ * (100 + sd->left_weapon.addrace2[t_race2]) / 100;
    							cardfix_ = cardfix_ * (100 + sd->left_weapon.addclass[tstatus->class_] + sd->left_weapon.addclass[CLASS_ALL]) / 100;
    						}
    					}
    					// Calculates right & left hand weapon as unity
    					else {
    						//! CHECKME: If 'left_cardfix_to_right' is yes, doesn't need to check NK_NO_ELEFIX?
    						//if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
    							int ele_fix = sd->right_weapon.addele[tstatus->def_ele] + sd->left_weapon.addele[tstatus->def_ele]
    										+ sd->right_weapon.addele[ELE_ALL] + sd->left_weapon.addele[ELE_ALL];
    
    							for( i = 0; ARRAYLENGTH(sd->right_weapon.addele2) > i && sd->right_weapon.addele2[i].rate != 0; i++ ) {
    								if( sd->right_weapon.addele2[i].ele != tstatus->def_ele )
    									continue;
    								if( !(((sd->right_weapon.addele2[i].flag)&flag)&BF_WEAPONMASK &&
    									((sd->right_weapon.addele2[i].flag)&flag)&BF_RANGEMASK &&
    									((sd->right_weapon.addele2[i].flag)&flag)&BF_SKILLMASK) )
    									continue;
    								ele_fix += sd->right_weapon.addele2[i].rate;
    							}
    							for( i = 0; ARRAYLENGTH(sd->left_weapon.addele2) > i && sd->left_weapon.addele2[i].rate != 0; i++ ) {
    								if( sd->left_weapon.addele2[i].ele != tstatus->def_ele )
    									continue;
    								if( !(((sd->left_weapon.addele2[i].flag)&flag)&BF_WEAPONMASK &&
    									((sd->left_weapon.addele2[i].flag)&flag)&BF_RANGEMASK &&
    									((sd->left_weapon.addele2[i].flag)&flag)&BF_SKILLMASK) )
    									continue;
    								ele_fix += sd->left_weapon.addele2[i].rate;
    							}
    							cardfix = cardfix * (100 + ele_fix) / 100;
    						//}
    						cardfix = cardfix * (100 + sd->right_weapon.addrace[tstatus->race] + sd->left_weapon.addrace[tstatus->race] +
    							sd->right_weapon.addrace[RC_ALL] + sd->left_weapon.addrace[RC_ALL]) / 100;
    						cardfix = cardfix * (100 + sd->right_weapon.addsize[tstatus->size] + sd->left_weapon.addsize[tstatus->size] +
    							sd->right_weapon.addsize[SZ_ALL] + sd->left_weapon.addsize[SZ_ALL]) / 100;
    						cardfix = cardfix * (100 + sd->right_weapon.addrace2[t_race2] + sd->left_weapon.addrace2[t_race2]) / 100;
    						cardfix = cardfix * (100 + sd->right_weapon.addclass[tstatus->class_] + sd->left_weapon.addclass[tstatus->class_] +
    							sd->right_weapon.addclass[CLASS_ALL] + sd->left_weapon.addclass[CLASS_ALL]) / 100;
    					}
    					if( sd->status.weapon == W_KATAR && (skill = pc_checkskill(sd,ASC_KATAR)) > 0 ) // Adv. Katar Mastery functions similar to a +%ATK card on official [helvetica]
    						cardfix = cardfix * (100 + (10 + 2 * skill)) / 100;
    				}
    
    				//! CHECKME: These right & left hand weapon ignores 'left_cardfix_to_right'?
    				for( i = 0; i < ARRAYLENGTH(sd->right_weapon.add_dmg) && sd->right_weapon.add_dmg[i].rate; i++ ) {
    					if( sd->right_weapon.add_dmg[i].class_ == t_class ) {
    						cardfix = cardfix * (100 + sd->right_weapon.add_dmg[i].rate) / 100;
    						break;
    					}
    				}
    				if( left&1 ) {
    					for( i = 0; i < ARRAYLENGTH(sd->left_weapon.add_dmg) && sd->left_weapon.add_dmg[i].rate; i++ ) {
    						if( sd->left_weapon.add_dmg[i].class_ == t_class ) {
    							cardfix_ = cardfix_ * (100 + sd->left_weapon.add_dmg[i].rate) / 100;
    							break;
    						}
    					}
    				}
    #ifndef RENEWAL
    				if( flag&BF_LONG )
    					cardfix = cardfix * (100 + sd->bonus.long_attack_atk_rate) / 100;
    #endif
    				if (left&1) {
    					APPLY_CARDFIX(damage, cardfix_);
    				} else {
    					APPLY_CARDFIX(damage, cardfix);
    				}
    			}
    			// Affected by target DEF bonuses
    			else if( tsd && !(nk&NK_NO_CARDFIX_DEF) && !(left&2) ) {
    				if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
    					int ele_fix = tsd->subele[rh_ele] + tsd->subele[ELE_ALL] + tsd->subele_script[rh_ele] + tsd->subele_script[ELE_ALL];
    
    					for( i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++ ) {
    						if( tsd->subele2[i].ele != rh_ele )
    							continue;
    						if( !(((tsd->subele2[i].flag)&flag)&BF_WEAPONMASK &&
    							((tsd->subele2[i].flag)&flag)&BF_RANGEMASK &&
    							((tsd->subele2[i].flag)&flag)&BF_SKILLMASK) )
    							continue;
    						ele_fix += tsd->subele2[i].rate;
    					}
    					cardfix = cardfix * (100 - ele_fix) / 100;
    
    					if( left&1 && lh_ele != rh_ele ) {
    						int ele_fix_lh = tsd->subele[lh_ele] + tsd->subele[ELE_ALL] + tsd->subele_script[lh_ele] + tsd->subele_script[ELE_ALL];
    
    						for( i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++ ) {
    							if( tsd->subele2[i].ele != lh_ele )
    								continue;
    							if( !(((tsd->subele2[i].flag)&flag)&BF_WEAPONMASK &&
    								((tsd->subele2[i].flag)&flag)&BF_RANGEMASK &&
    								((tsd->subele2[i].flag)&flag)&BF_SKILLMASK) )
    								continue;
    							ele_fix_lh += tsd->subele2[i].rate;
    						}
    						cardfix = cardfix * (100 - ele_fix_lh) / 100;
    					}
    
    					cardfix = cardfix * (100 - tsd->subdefele[s_defele] - tsd->subdefele[ELE_ALL]) / 100;
    				}
    				cardfix = cardfix * (100 - tsd->subsize[sstatus->size] - tsd->subsize[SZ_ALL]) / 100;
    				cardfix = cardfix * (100 - tsd->subrace2[s_race2]) / 100;
    				cardfix = cardfix * (100 - tsd->subrace[sstatus->race] - tsd->subrace[RC_ALL]) / 100;
    				cardfix = cardfix * (100 - tsd->subclass[sstatus->class_] - tsd->subclass[CLASS_ALL]) / 100;
    				for( i = 0; i < ARRAYLENGTH(tsd->add_def) && tsd->add_def[i].rate; i++ ) {
    					if( tsd->add_def[i].class_ == s_class ) {
    						cardfix = cardfix * (100 - tsd->add_def[i].rate) / 100;
    						break;
    					}
    				}
    				if( flag&BF_SHORT )
    					cardfix = cardfix * (100 - tsd->bonus.near_attack_def_rate) / 100;
    				else	// BF_LONG (there's no other choice)
    					cardfix = cardfix * (100 - tsd->bonus.long_attack_def_rate) / 100;
    				if( tsd->sc.data[SC_DEF_RATE] )
    					cardfix = cardfix * (100 - tsd->sc.data[SC_DEF_RATE]->val1) / 100;
    				APPLY_CARDFIX(damage, cardfix);
    			}
    			break;
    
    		case BF_MISC:
    			// Affected by target DEF bonuses
    			if( tsd && !(nk&NK_NO_CARDFIX_DEF) ) {
    				if( !(nk&NK_NO_ELEFIX) ) { // Affected by Element modifier bonuses
    					int ele_fix = tsd->subele[rh_ele] + tsd->subele[ELE_ALL] + tsd->subele_script[rh_ele] + tsd->subele_script[ELE_ALL];
    
    					for( i = 0; ARRAYLENGTH(tsd->subele2) > i && tsd->subele2[i].rate != 0; i++ ) {
    						if( tsd->subele2[i].ele != rh_ele )
    							continue;
    						if( !(((tsd->subele2[i].flag)&flag)&BF_WEAPONMASK &&
    							((tsd->subele2[i].flag)&flag)&BF_RANGEMASK &&
    							((tsd->subele2[i].flag)&flag)&BF_SKILLMASK))
    							continue;
    						ele_fix += tsd->subele2[i].rate;
    					}
    					if (s_defele != ELE_NONE)
    						ele_fix += tsd->subdefele[s_defele] + tsd->subdefele[ELE_ALL];
    					cardfix = cardfix * (100 - ele_fix) / 100;
    				}
    				cardfix = cardfix * (100 - tsd->subsize[sstatus->size] - tsd->subsize[SZ_ALL]) / 100;
    				cardfix = cardfix * (100 - tsd->subrace2[s_race2]) / 100;
    				cardfix = cardfix * (100 - tsd->subrace[sstatus->race] - tsd->subrace[RC_ALL]) / 100;
    				cardfix = cardfix * (100 - tsd->subclass[sstatus->class_] - tsd->subclass[CLASS_ALL]) / 100;
    				cardfix = cardfix * (100 - tsd->bonus.misc_def_rate) / 100;
    				if( flag&BF_SHORT )
    					cardfix = cardfix * (100 - tsd->bonus.near_attack_def_rate) / 100;
    				else	// BF_LONG (there's no other choice)
    					cardfix = cardfix * (100 - tsd->bonus.long_attack_def_rate) / 100;
    				APPLY_CARDFIX(damage, cardfix);
    			}
    			break;
    	}
    
    #undef APPLY_CARDFIX
    
    	return (int)cap_value(damage - original_damage, INT_MIN, INT_MAX);
    }
    
    ......
    
    static struct Damage initialize_weapon_data(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int wflag)
    {
    	struct status_data *sstatus = status_get_status_data(src);
    	struct status_data *tstatus = status_get_status_data(target);
    	struct status_change *sc = status_get_sc(src);
    	struct map_session_data *sd = BL_CAST(BL_PC, src);
    	struct Damage wd;
    
    	wd.type = DMG_NORMAL; //Normal attack
    	wd.div_ = skill_id?skill_get_num(skill_id,skill_lv):1;
    	wd.amotion = (skill_id && skill_get_inf(skill_id)&INF_GROUND_SKILL)?0:sstatus->amotion; //Amotion should be 0 for ground skills.
    	// counter attack DOES obey ASPD delay on official, uncomment if you want the old (bad) behavior [helvetica]
    	/*if(skill_id == KN_AUTOCOUNTER)
    		wd.amotion >>= 1; */
    	wd.dmotion = tstatus->dmotion;
    	wd.blewcount =skill_get_blewcount(skill_id,skill_lv);
    	wd.miscflag = wflag;
    	wd.flag = BF_WEAPON; //Initial Flag
    	wd.flag |= (skill_id||wd.miscflag)?BF_SKILL:BF_NORMAL; // Baphomet card's splash damage is counted as a skill. [Inkfish]
    
    	wd.damage = wd.damage2 =
    #ifdef RENEWAL
    	wd.statusAtk = wd.statusAtk2 = wd.equipAtk = wd.equipAtk2 = wd.weaponAtk = wd.weaponAtk2 = wd.masteryAtk = wd.masteryAtk2 =
    #endif
    	0;
    
    	wd.dmg_lv=ATK_DEF;	//This assumption simplifies the assignation later
    
    	if(sd)
    		wd.blewcount += battle_blewcount_bonus(sd, skill_id);
    
    	if (skill_id) {
    		wd.flag |= battle_range_type(src, target, skill_id, skill_lv);
    		switch(skill_id)
    		{
    			case MH_SONIC_CRAW:{
    				TBL_HOM *hd = BL_CAST(BL_HOM,src);
    				wd.div_ = hd->homunculus.spiritball;
    			}
    				break;
    			case MO_FINGEROFFENSIVE:
    				if(sd) {
    					if (battle_config.finger_offensive_type)
    						wd.div_ = 1;
    					else
    						wd.div_ = sd->spiritball_old;
    				}
    				break;
    
    			case KN_PIERCE:
    			case ML_PIERCE:
    				wd.div_= (wd.div_>0?tstatus->size+1:-(tstatus->size+1));
    				break;
    
    			case TF_DOUBLE: //For NPC used skill.
    			case GS_CHAINACTION:
    				wd.type = DMG_MULTI_HIT;
    				break;
    
    			case GS_GROUNDDRIFT:
    				wd.amotion = sstatus->amotion;
    				//Fall through
    			case KN_SPEARSTAB:
    			case KN_BOWLINGBASH:
    			case MS_BOWLINGBASH:
    			case MO_BALKYOUNG:
    			case TK_TURNKICK:
    				wd.blewcount = 0;
    				break;
    
    			case KN_AUTOCOUNTER:
    				wd.flag = (wd.flag&~BF_SKILLMASK)|BF_NORMAL;
    				break;
    			case LK_SPIRALPIERCE:
    				if (!sd) wd.flag = (wd.flag&~(BF_RANGEMASK|BF_WEAPONMASK))|BF_LONG|BF_MISC;
    				break;
    
    			// The number of hits is set to 3 by default for use in Inspiration status.
    			// When in Banding, the number of hits is equal to the number of Royal Guards in Banding.
    			case LG_HESPERUSLIT:
    				if( sc && sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 3 )
    					wd.div_ = sc->data[SC_BANDING]->val2;
    				break;
    		}
    	} else {
    		wd.flag |= is_skill_using_arrow(src, skill_id)?BF_LONG:BF_SHORT;
    	}
    
    	return wd;
    }
    
    ......
    
    static struct Damage battle_calc_weapon_attack(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int wflag)
    {
    	struct map_session_data *sd, *tsd;
    	struct Damage wd;
    	struct status_change *sc = status_get_sc(src);
    	struct status_change *tsc = status_get_sc(target);
    	struct status_data *tstatus = status_get_status_data(target);
    	int right_element, left_element;
    	bool infdef = false;
    
    	memset(&wd,0,sizeof(wd));
    
    	if (src == NULL || target == NULL) {
    		nullpo_info(NLP_MARK);
    		return wd;
    	}
    
    	wd = initialize_weapon_data(src, target, skill_id, skill_lv, wflag);
    
    	right_element = battle_get_weapon_element(wd, src, target, skill_id, skill_lv, EQI_HAND_R, false);
    	left_element = battle_get_weapon_element(wd, src, target, skill_id, skill_lv, EQI_HAND_L, false);
    
    	if (sc && !sc->count)
    		sc = NULL; //Skip checking as there are no status changes active.
    	if (tsc && !tsc->count)
    		tsc = NULL; //Skip checking as there are no status changes active.
    
    	sd = BL_CAST(BL_PC, src);
    	tsd = BL_CAST(BL_PC, target);
    
    	//Check for Lucky Dodge
    	if ((!skill_id || skill_id == PA_SACRIFICE) && tstatus->flee2 && rnd()%1000 < tstatus->flee2) {
    		wd.type = DMG_LUCY_DODGE;
    		wd.dmg_lv = ATK_LUCKY;
    		if(wd.div_ < 0)
    			wd.div_ *= -1;
    		return wd;
    	}
    
    	// on official check for multi hit first so we can override crit on double attack [helvetica]
    	wd = battle_calc_multi_attack(wd, src, target, skill_id, skill_lv);
    
    	// crit check is next since crits always hit on official [helvetica]
    	if (is_attack_critical(wd, src, target, skill_id, skill_lv, true))
    		wd.type = DMG_CRITICAL;
    
    	// check if we're landing a hit
    	if(!is_attack_hitting(wd, src, target, skill_id, skill_lv, true))
    		wd.dmg_lv = ATK_FLEE;
    	else if(!(infdef = is_infinite_defense(target, wd.flag))) { //no need for math against plants
    		int64 ratio = 0;
    		int i = 0;
    
    		wd = battle_calc_skill_base_damage(wd, src, target, skill_id, skill_lv); // base skill damage
    		ratio = battle_calc_attack_skill_ratio(wd, src, target, skill_id, skill_lv); // skill level ratios
    
    		ATK_RATE(wd.damage, wd.damage2, ratio);
    		RE_ALLATK_RATE(wd, ratio);
    
    		ratio = battle_calc_skill_constant_addition(wd, src, target, skill_id, skill_lv); // other skill bonuses
    
    		ATK_ADD(wd.damage, wd.damage2, ratio);
    		RE_ALLATK_ADD(wd, ratio);
    
    #ifdef RENEWAL
    		if(skill_id == HW_MAGICCRASHER) { // Add weapon attack for MATK onto Magic Crasher
    			struct status_data *sstatus = status_get_status_data(src);
    
    			if (sstatus->matk_max > sstatus->matk_min) {
    				ATK_ADD(wd.weaponAtk, wd.weaponAtk2, sstatus->matk_min+rnd()%(sstatus->matk_max-sstatus->matk_min));
    			} else
    				ATK_ADD(wd.weaponAtk, wd.weaponAtk2, sstatus->matk_min);
    		}
    #endif
    		// add any miscellaneous player ATK bonuses
    		if( sd && skill_id && (i = pc_skillatk_bonus(sd, skill_id))) {
    			ATK_ADDRATE(wd.damage, wd.damage2, i);
    			RE_ALLATK_ADDRATE(wd, i);
    		}
    		if (tsd && (i = pc_sub_skillatk_bonus(tsd, skill_id))) {
    			ATK_ADDRATE(wd.damage, wd.damage2, -i);
    			RE_ALLATK_ADDRATE(wd, -i);
    		}
    
    #ifdef RENEWAL
    		// In Renewal we only cardfix to the weapon and equip ATK
    		//Card Fix for attacker (sd), 2 is added to the "left" flag meaning "attacker cards only"
    		wd.weaponAtk += battle_calc_cardfix(BF_WEAPON, src, target, battle_skill_get_damage_properties(skill_id, wd.miscflag), right_element, left_element, wd.weaponAtk, 2, wd.flag);
    		wd.equipAtk += battle_calc_cardfix(BF_WEAPON, src, target, battle_skill_get_damage_properties(skill_id, wd.miscflag), right_element, left_element, wd.equipAtk, 2, wd.flag);
    		if (is_attack_left_handed(src, skill_id)) {
    			wd.weaponAtk2 += battle_calc_cardfix(BF_WEAPON, src, target, battle_skill_get_damage_properties(skill_id, wd.miscflag), right_element, left_element, wd.weaponAtk2, 3, wd.flag);
    			wd.equipAtk2 += battle_calc_cardfix(BF_WEAPON, src, target, battle_skill_get_damage_properties(skill_id, wd.miscflag), right_element, left_element, wd.equipAtk2, 3, wd.flag);
    		}
    
    		// final attack bonuses that aren't affected by cards
    		wd = battle_attack_sc_bonus(wd, src, target, skill_id, skill_lv);
    
    		if (sd) { //monsters, homuns and pets have their damage computed directly
    			wd.damage = wd.statusAtk + wd.weaponAtk + wd.equipAtk + wd.masteryAtk;
    			wd.damage2 = wd.statusAtk2 + wd.weaponAtk2 + wd.equipAtk2 + wd.masteryAtk2;
    			if(wd.flag&BF_LONG && (skill_id != RA_WUGBITE && skill_id != RA_WUGSTRIKE)) //Long damage rate addition doesn't use weapon + equip attack
    				ATK_ADDRATE(wd.damage, wd.damage2, sd->bonus.long_attack_atk_rate);
    		}
    #else
    		// final attack bonuses that aren't affected by cards
    		wd = battle_attack_sc_bonus(wd, src, target, skill_id, skill_lv);
    #endif
    
    		if (wd.damage + wd.damage2) { //Check if attack ignores DEF
    			if(!attack_ignores_def(wd, src, target, skill_id, skill_lv, EQI_HAND_L) || !attack_ignores_def(wd, src, target, skill_id, skill_lv, EQI_HAND_R))
    				wd = battle_calc_defense_reduction(wd, src, target, skill_id, skill_lv);
    
    			wd = battle_calc_attack_post_defense(wd, src, target, skill_id, skill_lv);
    		}
    	}
    
    #ifdef RENEWAL
    	if(!sd) // monsters only have a single ATK for element, in pre-renewal we also apply element to entire ATK on players [helvetica]
    #endif
    		wd = battle_calc_element_damage(wd, src, target, skill_id, skill_lv);
    
    	if(skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS)
    		return wd; //Enough, rest is not needed.
    
    #ifdef RENEWAL
    	if (is_attack_critical(wd, src, target, skill_id, skill_lv, false)) {
    		if (sd) { //Check for player so we don't crash out, monsters don't have bonus crit rates [helvetica]
    			wd.damage = (int)floor((float)((wd.damage * 140) / 100 * (100 + sd->bonus.crit_atk_rate)) / 100);
    			if (is_attack_left_handed(src, skill_id))
    				wd.damage2 = (int)floor((float)((wd.damage2 * 140) / 100 * (100 + sd->bonus.crit_atk_rate)) / 100);
    		} else
    			wd.damage = (int)floor((float)(wd.damage * 140) / 100);
    	}
    #endif
    
    #ifndef RENEWAL
    	if (skill_id == NJ_KUNAI) {
    		short nk = battle_skill_get_damage_properties(skill_id, wd.miscflag);
    
    		ATK_ADD(wd.damage, wd.damage2, 90);
    		nk |= NK_IGNORE_DEF;
    	}
    #endif
    
    	switch (skill_id) {
    		case TK_DOWNKICK:
    		case TK_STORMKICK:
    		case TK_TURNKICK:
    		case TK_COUNTER:
    			if(sd && sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST)
    				ATK_ADD(wd.damage, wd.damage2, 10 * pc_checkskill(sd, TK_RUN));
    			break;
    		case SR_TIGERCANNON:
    			// (Tiger Cannon skill level x 240) + (Target Base Level x 40)
    			if (wd.miscflag&8) {
    				ATK_ADD(wd.damage, wd.damage2, skill_lv * 500 + status_get_lv(target) * 40);
    			} else
    				ATK_ADD(wd.damage, wd.damage2, skill_lv * 240 + status_get_lv(target) * 40);
    			break;
    		case SR_GATEOFHELL: {
    			struct status_data *sstatus = status_get_status_data(src);
    
    			ATK_ADD(wd.damage, wd.damage2, sstatus->max_hp - status_get_hp(src));
    			if(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE) {
    				ATK_ADD(wd.damage, wd.damage2, (sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status_get_lv(src));
    			} else
    				ATK_ADD(wd.damage, wd.damage2, (sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status_get_lv(src));
    		}
    		break;
    	}
    
    	if(sd) {
    #ifndef RENEWAL
    		uint16 skill;
    
    		if ((skill = pc_checkskill(sd, BS_WEAPONRESEARCH)) > 0)
    			ATK_ADD(wd.damage, wd.damage2, skill * 2);
    		if (skill_id == TF_POISON)
    			ATK_ADD(wd.damage, wd.damage2, 15 * skill_lv);
    		if (skill_id == GS_GROUNDDRIFT)
    			ATK_ADD(wd.damage, wd.damage2, 50 * skill_lv);
    		if (skill_id != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus.
    			ATK_ADD2(wd.damage, wd.damage2, ((wd.div_ < 1) ? 1 : wd.div_) * sd->right_weapon.star, ((wd.div_ < 1) ? 1 : wd.div_) * sd->left_weapon.star);
    		if (skill_id != MC_CARTREVOLUTION && pc_checkskill(sd, BS_HILTBINDING) > 0)
    			ATK_ADD(wd.damage, wd.damage2, 4);
    		if (skill_id == MO_FINGEROFFENSIVE) { //The finger offensive spheres on moment of attack do count. [Skotlex]
    			ATK_ADD(wd.damage, wd.damage2, ((wd.div_ < 1) ? 1 : wd.div_) * sd->spiritball_old * 3);
    		} else
    			ATK_ADD(wd.damage, wd.damage2, ((wd.div_ < 1) ? 1 : wd.div_) * sd->spiritball * 3);
    #endif
    		if( skill_id == CR_SHIELDBOOMERANG || skill_id == PA_SHIELDCHAIN ) { //Refine bonus applies after cards and elements.
    			short index = sd->equip_index[EQI_HAND_L];
    
    			if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR )
    				ATK_ADD(wd.damage, wd.damage2, 10*sd->inventory.u.items_inventory[index].refine);
    		}
    #ifndef RENEWAL
    		//Card Fix for attacker (sd), 2 is added to the "left" flag meaning "attacker cards only"
    		switch(skill_id) {
    			case RK_DRAGONBREATH:
    			case RK_DRAGONBREATH_WATER:
    				if(wd.flag&BF_LONG) { //Add check here, because we want to apply the same behavior in pre-renewal [exneval]
    					wd.damage = wd.damage * (100 + sd->bonus.long_attack_atk_rate) / 100;
    					if(is_attack_left_handed(src, skill_id))
    						wd.damage2 = wd.damage2 * (100 + sd->bonus.long_attack_atk_rate) / 100;
    				}
    				break;
    			default:
    				wd.damage += battle_calc_cardfix(BF_WEAPON, src, target, battle_skill_get_damage_properties(skill_id, wd.miscflag), right_element, left_element, wd.damage, 2, wd.flag);
    				if( is_attack_left_handed(src, skill_id ))
    					wd.damage2 += battle_calc_cardfix(BF_WEAPON, src, target, battle_skill_get_damage_properties(skill_id, wd.miscflag), right_element, left_element, wd.damage2, 3, wd.flag);
    				break;
    		}
    #endif
    	}
    
    	if(tsd) { // Card Fix for target (tsd), 2 is not added to the "left" flag meaning "target cards only"
    		switch(skill_id) {
    #ifdef RENEWAL
    			case NJ_ISSEN:
    			case GS_MAGICALBULLET:
    			case ASC_BREAKER:
    			case CR_ACIDDEMONSTRATION:
    			case GN_FIRE_EXPANSION_ACID:
    #endif
    			case SO_VARETYR_SPEAR:
    				break; //These skills will do a card fix later
    			default:
    				wd.damage += battle_calc_cardfix(BF_WEAPON, src, target, battle_skill_get_damage_properties(skill_id, wd.miscflag), right_element, left_element, wd.damage, 0, wd.flag);
    				if(is_attack_left_handed(src, skill_id))
    					wd.damage2 += battle_calc_cardfix(BF_WEAPON, src, target, battle_skill_get_damage_properties(skill_id, wd.miscflag), right_element, left_element, wd.damage2, 1, wd.flag);
    				break;
    		}
    	}
    
    #ifdef RENEWAL
    	// forced to neutral skills [helvetica]
    	// skills forced to neutral gain benefits from weapon element
    	// but final damage is considered "neutral" and resistances are applied again
    	switch (skill_id) {
    		case MC_CARTREVOLUTION:
    		case MO_INVESTIGATE:
    		case CR_ACIDDEMONSTRATION:
    		case SR_GATEOFHELL:
    		case GN_FIRE_EXPANSION_ACID:
    		case KO_BAKURETSU:
    			// Forced to neutral element
    			wd.damage = battle_attr_fix(src, target, wd.damage, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
    			break;
    		case CR_SHIELDBOOMERANG:
    		case LK_SPIRALPIERCE:
    		case ML_SPIRALPIERCE:
    		case PA_SHIELDCHAIN:
    		case PA_SACRIFICE:
    		case RK_DRAGONBREATH:
    		case RK_DRAGONBREATH_WATER:
    		case NC_SELFDESTRUCTION:
    		case KO_HAPPOKUNAI: {
    				int64 tmp = wd.damage;
    
    				if (sd) {
    					if (skill_id == PA_SHIELDCHAIN) {
    						wd.damage = battle_attr_fix(src, target, wd.damage, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
    						if (wd.damage > 0) {
    							wd.damage = battle_attr_fix(src, target, tmp, right_element, tstatus->def_ele, tstatus->ele_lv);
    							if (!wd.damage)
    								wd.damage = battle_attr_fix(src, target, tmp, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
    						}
    					} else if (skill_id == KO_HAPPOKUNAI) {
    						wd.damage = battle_attr_fix(src, target, wd.damage, (sd->bonus.arrow_ele) ? sd->bonus.arrow_ele : ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
    						if (wd.damage > 0) {
    							wd.damage = battle_attr_fix(src, target, tmp, right_element, tstatus->def_ele, tstatus->ele_lv);
    							if (!wd.damage)
    								wd.damage = battle_attr_fix(src, target, tmp, (sd->bonus.arrow_ele) ? sd->bonus.arrow_ele : ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
    						}
    					} else
    						wd.damage = battle_attr_fix(src, target, wd.damage, right_element, tstatus->def_ele, tstatus->ele_lv);
    				}
    			}
    			break;
    		case GN_CARTCANNON: // Cart Cannon gets forced to element of cannon ball (neutral or holy/shadow/ghost)
    			wd.damage = battle_attr_fix(src, target, wd.damage, (sd && sd->bonus.arrow_ele) ? sd->bonus.arrow_ele : ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
    			break;
    	}
    
    	// perform multihit calculations
    	DAMAGE_DIV_FIX_RENEWAL(wd, wd.div_);
    #endif
    	// only do 1 dmg to plant, no need to calculate rest
    	if(infdef)
    		return battle_calc_attack_plant(wd, src, target, skill_id, skill_lv);
    
    	//Apply DAMAGE_DIV_FIX and check for min damage
    	wd = battle_apply_div_fix(wd, skill_id);
    
    	wd = battle_calc_attack_left_right_hands(wd, src, target, skill_id, skill_lv);
    
    	switch (skill_id) {
    #ifdef RENEWAL
    		case NJ_ISSEN:
    		case GS_MAGICALBULLET:
    		case ASC_BREAKER:
    		case CR_ACIDDEMONSTRATION:
    		case GN_FIRE_EXPANSION_ACID:
    #endif
    		case SO_VARETYR_SPEAR:
    			return wd; //These skills will do a GVG fix later
    		default:
    			wd = battle_calc_attack_gvg_bg(wd, src, target, skill_id, skill_lv);
    			break;
    	}
    
    	wd = battle_calc_weapon_final_atk_modifiers(wd, src, target, skill_id, skill_lv);
    
    	battle_absorb_damage(target, &wd);
    
    	battle_do_reflect(BF_WEAPON,&wd, src, target, skill_id, skill_lv); //WIP [lighta]
    
    	return wd;
    }
    
    ......
    
    enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, unsigned int tick, int flag) {
    	struct map_session_data *sd = NULL, *tsd = NULL;
    	struct status_data *sstatus, *tstatus;
    	struct status_change *sc, *tsc;
    	int64 damage;
    	int skillv;
    	struct Damage wd;
    	bool vanish_damage = false;
    
    	nullpo_retr(ATK_NONE, src);
    	nullpo_retr(ATK_NONE, target);
    
    	if (src->prev == NULL || target->prev == NULL)
    		return ATK_NONE;
    
    	sd = BL_CAST(BL_PC, src);
    	tsd = BL_CAST(BL_PC, target);
    
    	sstatus = status_get_status_data(src);
    	tstatus = status_get_status_data(target);
    
    	sc = status_get_sc(src);
    	tsc = status_get_sc(target);
    
    	if (sc && !sc->count) //Avoid sc checks when there's none to check for. [Skotlex]
    		sc = NULL;
    	if (tsc && !tsc->count)
    		tsc = NULL;
    
    	if (sd)
    	{
    		sd->state.arrow_atk = (sd->status.weapon == W_BOW || (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE));
    		if (sd->state.arrow_atk)
    		{
    			short index = sd->equip_index[EQI_AMMO];
    			if (index < 0) {
    				if (sd->weapontype1 > W_KATAR && sd->weapontype1 < W_HUUMA)
    					clif_skill_fail(sd,0,USESKILL_FAIL_NEED_MORE_BULLET,0);
    				else
    					clif_arrow_fail(sd,0);
    				return ATK_NONE;
    			}
    			//Ammo check by Ishizu-chan
    			if (sd->inventory_data[index]) {
    				switch (sd->status.weapon) {
    					case W_BOW:
    						if (sd->inventory_data[index]->look != A_ARROW) {
    							clif_arrow_fail(sd,0);
    							return ATK_NONE;
    						}
    						break;
    					case W_REVOLVER:
    					case W_RIFLE:
    					case W_GATLING:
    					case W_SHOTGUN:
    						if (sd->inventory_data[index]->look != A_BULLET) {
    							clif_skill_fail(sd,0,USESKILL_FAIL_NEED_MORE_BULLET,0);
    							return ATK_NONE;
    						}
    						break;
    					case W_GRENADE:
    						if (sd->inventory_data[index]->look != A_GRENADE) {
    							clif_skill_fail(sd,0,USESKILL_FAIL_NEED_MORE_BULLET,0);
    							return ATK_NONE;
    						}
    						break;
    				}
    			}
    		}
    	}
    	if (sc && sc->count) {
    		if (sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4 & 2))
    			status_change_end(src, SC_CLOAKING, INVALID_TIMER);
    		else if (sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4 & 2))
    			status_change_end(src, SC_CLOAKINGEXCEED, INVALID_TIMER);
    	}
    	if (tsc && tsc->data[SC_AUTOCOUNTER] && status_check_skilluse(target, src, KN_AUTOCOUNTER, 1)) {
    		uint8 dir = map_calc_dir(target,src->x,src->y);
    		int t_dir = unit_getdir(target);
    		int dist = distance_bl(src, target);
    
    		if (dist <= 0 || (!map_check_dir(dir,t_dir) && dist <= tstatus->rhw.range+1)) {
    			uint16 skill_lv = tsc->data[SC_AUTOCOUNTER]->val1;
    
    			clif_skillcastcancel(target); //Remove the casting bar. [Skotlex]
    			clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, DMG_NORMAL, 0, false); //Display MISS.
    			status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER);
    			skill_attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skill_lv,tick,0);
    			return ATK_BLOCK;
    		}
    	}
    
    	if( tsc && tsc->data[SC_BLADESTOP_WAIT] && status_get_class_(src) != CLASS_BOSS && (src->type == BL_PC || tsd == NULL || distance_bl(src, target) <= (tsd->status.weapon == W_FIST ? 1 : 2)) )
    	{
    		uint16 skill_lv = tsc->data[SC_BLADESTOP_WAIT]->val1;
    		int duration = skill_get_time2(MO_BLADESTOP,skill_lv);
    		status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER);
    		if(sc_start4(src,src, SC_BLADESTOP, 100, sd?pc_checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration))
    		{	//Target locked.
    			clif_damage(src, target, tick, sstatus->amotion, 1, 0, 1, DMG_NORMAL, 0, false); //Display MISS.
    			clif_bladestop(target, src->id, 1);
    			sc_start4(src,target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration);
    			return ATK_BLOCK;
    		}
    	}
    
    	if(sd && (skillv = pc_checkskill(sd,MO_TRIPLEATTACK)) > 0) {
    		int triple_rate= 30 - skillv; //Base Rate
    		if (sc && sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == MO_TRIPLEATTACK) {
    			triple_rate+= triple_rate*(sc->data[SC_SKILLRATE_UP]->val2)/100;
    			status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
    		}
    		if (rnd()%100 < triple_rate) {
    			//Need to apply canact_tick here because it doesn't go through skill_castend_id
    			sd->ud.canact_tick = max(tick + skill_delayfix(src, MO_TRIPLEATTACK, skillv), sd->ud.canact_tick);
    			if( skill_attack(BF_WEAPON,src,src,target,MO_TRIPLEATTACK,skillv,tick,0) )
    				return ATK_DEF;
    			return ATK_MISS;
    		}
    	}
    
    	if (sc) {
    		if (sc->data[SC_SACRIFICE]) {
    			uint16 skill_lv = sc->data[SC_SACRIFICE]->val1;
    			damage_lv ret_val;
    
    			if( --sc->data[SC_SACRIFICE]->val2 <= 0 )
    				status_change_end(src, SC_SACRIFICE, INVALID_TIMER);
    
    			/**
    			 * We need to calculate the DMG before the hp reduction, because it can kill the source.
    			 * For further information: bugreport:4950
    			 */
    			ret_val = (damage_lv)skill_attack(BF_WEAPON,src,src,target,PA_SACRIFICE,skill_lv,tick,0);
    
    			status_zap(src, sstatus->max_hp*9/100, 0);//Damage to self is always 9%
    			if( ret_val == ATK_NONE )
    				return ATK_MISS;
    			return ret_val;
    		}
    		if (sc->data[SC_MAGICALATTACK]) {
    			if( skill_attack(BF_MAGIC,src,src,target,NPC_MAGICALATTACK,sc->data[SC_MAGICALATTACK]->val1,tick,0) )
    				return ATK_DEF;
    			return ATK_MISS;
    		}
    		if( sc->data[SC_GT_ENERGYGAIN] ) {
    			int spheres = 5;
    
    			if( sc->data[SC_RAISINGDRAGON] )
    				spheres += sc->data[SC_RAISINGDRAGON]->val1;
    
    			if( sd && rnd()%100 < sc->data[SC_GT_ENERGYGAIN]->val2 )
    				pc_addspiritball(sd, skill_get_time2(SR_GENTLETOUCH_ENERGYGAIN, sc->data[SC_GT_ENERGYGAIN]->val1), spheres);
    		}
    	}
    
    	if( tsc && tsc->data[SC_GT_ENERGYGAIN] ) {
    		int spheres = 5;
    
    		if( tsc->data[SC_RAISINGDRAGON] )
    			spheres += tsc->data[SC_RAISINGDRAGON]->val1;
    
    		if( tsd && rnd()%100 < tsc->data[SC_GT_ENERGYGAIN]->val2 )
    			pc_addspiritball(tsd, skill_get_time2(SR_GENTLETOUCH_ENERGYGAIN, tsc->data[SC_GT_ENERGYGAIN]->val1), spheres);
    	}
    
    	if (tsc && tsc->data[SC_MTF_MLEATKED] && rnd()%100 < tsc->data[SC_MTF_MLEATKED]->val2)
    		clif_skill_nodamage(target, target, SM_ENDURE, tsc->data[SC_MTF_MLEATKED]->val1, sc_start(src, target, SC_ENDURE, 100, tsc->data[SC_MTF_MLEATKED]->val1, skill_get_time(SM_ENDURE, tsc->data[SC_MTF_MLEATKED]->val1)));
    
    	if(tsc && tsc->data[SC_KAAHI] && tstatus->hp < tstatus->max_hp && status_charge(target, 0, tsc->data[SC_KAAHI]->val3)) {
    		int hp_heal = tstatus->max_hp - tstatus->hp;
    		if (hp_heal > tsc->data[SC_KAAHI]->val2)
    			hp_heal = tsc->data[SC_KAAHI]->val2;
    		if (hp_heal)
    			status_heal(target, hp_heal, 0, 2);
    	}
    
    	wd = battle_calc_attack(BF_WEAPON, src, target, 0, 0, flag);
    	wd.isspdamage = false; // Default normal attacks to non-SP Damage attack until battle_vanish is determined
    
    	if (sd && wd.damage + wd.damage2 > 0)
    		vanish_damage = battle_vanish(sd, target, &wd);
    
    	if( sc && sc->count ) {
    		if (sc->data[SC_EXEEDBREAK]) {
    			if (!is_infinite_defense(target, wd.flag) && !vanish_damage)
    				wd.damage *= sc->data[SC_EXEEDBREAK]->val2 / 100;
    			status_change_end(src, SC_EXEEDBREAK, INVALID_TIMER);
    		}
    		if( sc->data[SC_SPELLFIST] ) {
    			if( --(sc->data[SC_SPELLFIST]->val1) >= 0 && !vanish_damage ){
    				if (!is_infinite_defense(target, wd.flag)) {
    					struct Damage ad = battle_calc_attack(BF_MAGIC, src, target, sc->data[SC_SPELLFIST]->val3, sc->data[SC_SPELLFIST]->val4, flag | BF_SHORT);
    
    					wd.damage = ad.damage;
    					DAMAGE_DIV_FIX(wd.damage, wd.div_); // Double the damage for multiple hits.
    				} else {
    					wd.damage = 1;
    					DAMAGE_DIV_FIX(wd.damage, wd.div_);
    				}
    			} else
    				status_change_end(src,SC_SPELLFIST,INVALID_TIMER);
    		}
    		if (sc->data[SC_GIANTGROWTH] && (wd.flag&BF_SHORT) && rnd()%100 < sc->data[SC_GIANTGROWTH]->val2 && !is_infinite_defense(target, wd.flag) && !vanish_damage) {
    			wd.damage <<= 1; // Double Damage
    			if (!sc->data[SC_CRUSHSTRIKE]) { // Increase damage again if Crush Strike is not active
    				if (map_flag_vs(src->m)) // Only half of the 2.5x increase on versus-type maps
    					wd.damage += wd.damage * 125 / 100;
    				else
    					wd.damage += wd.damage * 250 / 100;
    			}
    		}
    
    		if( sd && battle_config.arrow_decrement && sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0) {
    			short idx = sd->equip_index[EQI_AMMO];
    			if (idx >= 0 && sd->inventory.u.items_inventory[idx].amount >= sc->data[SC_FEARBREEZE]->val4) {
    				pc_delitem(sd,idx,sc->data[SC_FEARBREEZE]->val4,0,1,LOG_TYPE_CONSUME);
    				sc->data[SC_FEARBREEZE]->val4 = 0;
    			}
    		}
    	}
    	if (sd && sd->state.arrow_atk) //Consume arrow.
    		battle_consume_ammo(sd, 0, 0);
    
    	damage = wd.damage + wd.damage2;
    	if( damage > 0 && src != target )
    	{
    		if( sc && sc->data[SC_DUPLELIGHT] && (wd.flag&BF_SHORT) && rnd()%100 <= 10+2*sc->data[SC_DUPLELIGHT]->val1 )
    		{	// Activates it only from melee damage
    			uint16 skill_id;
    			if( rnd()%2 == 1 )
    				skill_id = AB_DUPLELIGHT_MELEE;
    			else
    				skill_id = AB_DUPLELIGHT_MAGIC;
    			skill_attack(skill_get_type(skill_id), src, src, target, skill_id, sc->data[SC_DUPLELIGHT]->val1, tick, SD_LEVEL);
    		}
    	}
    
    	wd.dmotion = clif_damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2, wd.isspdamage);
    
    	if (sd && sd->bonus.splash_range > 0 && damage > 0)
    		skill_castend_damage_id(src, target, 0, 1, tick, 0);
    	if ( target->type == BL_SKILL && damage > 0 ) {
    		TBL_SKILL *su = (TBL_SKILL*)target;
    
    		if (su && su->group) {
    			if (su->group->skill_id == HT_BLASTMINE)
    				skill_blown(src, target, 3, -1, BLOWN_NONE);
    			if (su->group->skill_id == GN_WALLOFTHORN) {
    				if (--su->val2 <= 0)
    					skill_delunit(su);
    			}
    		}
    	}
    
    	map_freeblock_lock();
    
    	if( !(tsc && tsc->data[SC_DEVOTION]) && !vanish_damage && skill_check_shadowform(target, damage, wd.div_) ) {
    		if( !status_isdead(target) )
    			skill_additional_effect(src, target, 0, 0, wd.flag, wd.dmg_lv, tick);
    		if( wd.dmg_lv > ATK_BLOCK )
    			skill_counter_additional_effect(src, target, 0, 0, wd.flag, tick);
    	} else
    		battle_delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion, true, wd.isspdamage);
    	if( tsc ) {
    		if( tsc->data[SC_DEVOTION] ) {
    			struct status_change_entry *sce = tsc->data[SC_DEVOTION];
    			struct block_list *d_bl = map_id2bl(sce->val1);
    
    			if( d_bl && (
    				(d_bl->type == BL_MER && ((TBL_MER*)d_bl)->master && ((TBL_MER*)d_bl)->master->bl.id == target->id) ||
    				(d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == target->id)
    				) && check_distance_bl(target, d_bl, sce->val3) )
    			{
    				clif_damage(d_bl, d_bl, gettick(), 0, 0, damage, 0, DMG_NORMAL, 0, false);
    				status_fix_damage(NULL, d_bl, damage, 0);
    			}
    			else
    				status_change_end(target, SC_DEVOTION, INVALID_TIMER);
    		}
    		if (target->type == BL_PC && (wd.flag&BF_SHORT) && tsc->data[SC_CIRCLE_OF_FIRE_OPTION]) {
    			struct elemental_data *ed = ((TBL_PC*)target)->ed;
    
    			if (ed) {
    				clif_skill_damage(&ed->bl, target, tick, status_get_amotion(src), 0, -30000, 1, EL_CIRCLE_OF_FIRE, tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1, DMG_SKILL);
    				skill_attack(BF_WEAPON,&ed->bl,&ed->bl,src,EL_CIRCLE_OF_FIRE,tsc->data[SC_CIRCLE_OF_FIRE_OPTION]->val1,tick,wd.flag);
    			}
    		}
    		if (tsc->data[SC_WATER_SCREEN_OPTION]) {
    			struct block_list *e_bl = map_id2bl(tsc->data[SC_WATER_SCREEN_OPTION]->val1);
    
    			if (e_bl && !status_isdead(e_bl)) {
    				clif_damage(e_bl, e_bl, tick, 0, 0, damage, wd.div_, DMG_NORMAL, 0, false);
    				status_fix_damage(NULL, e_bl, damage, 0);
    			}
    		}
    	}
    	if (sc && sc->data[SC_AUTOSPELL] && rnd()%100 < sc->data[SC_AUTOSPELL]->val4) {
    		int sp = 0;
    		uint16 skill_id = sc->data[SC_AUTOSPELL]->val2;
    		uint16 skill_lv = sc->data[SC_AUTOSPELL]->val3;
    		int i = rnd()%100;
    		if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_SAGE)
    			i = 0; //Max chance, no skill_lv reduction. [Skotlex]
    		//reduction only for skill_lv > 1
    		if (skill_lv > 1) {
    			if (i >= 50) skill_lv /= 2;
    			else if (i >= 15) skill_lv--;
    		}
    		sp = skill_get_sp(skill_id,skill_lv) * 2 / 3;
    
    		if (status_charge(src, 0, sp)) {
    			struct unit_data *ud = unit_bl2ud(src);
    
    			switch (skill_get_casttype(skill_id)) {
    				case CAST_GROUND:
    					skill_castend_pos2(src, target->x, target->y, skill_id, skill_lv, tick, flag);
    					break;
    				case CAST_NODAMAGE:
    					skill_castend_nodamage_id(src, target, skill_id, skill_lv, tick, flag);
    					break;
    				case CAST_DAMAGE:
    					skill_castend_damage_id(src, target, skill_id, skill_lv, tick, flag);
    					break;
    			}
    			if (ud) {
    				int autospell_tick = skill_delayfix(src, skill_id, skill_lv);
    
    				if (DIFF_TICK(ud->canact_tick, tick + autospell_tick) < 0) {
    					ud->canact_tick = max(tick + autospell_tick, ud->canact_tick);
    					if (battle_config.display_status_timers && sd)
    						clif_status_change(src, SI_ACTIONDELAY, 1, autospell_tick, 0, 0, 0);
    				}
    			}
    		}
    	}
    	if (sd) {
    		uint16 r_skill = 0, sk_idx = 0;
    		if( wd.flag&BF_SHORT && sc && sc->data[SC__AUTOSHADOWSPELL] && rnd()%100 < sc->data[SC__AUTOSHADOWSPELL]->val3 &&
    			(r_skill = (uint16)sc->data[SC__AUTOSHADOWSPELL]->val1) && (sk_idx = skill_get_index(r_skill)) &&
    			sd->status.skill[sk_idx].id != 0 && sd->status.skill[sk_idx].flag == SKILL_FLAG_PLAGIARIZED )
    		{
    			int r_lv = sc->data[SC__AUTOSHADOWSPELL]->val2;
    
    			if (r_skill != AL_HOLYLIGHT && r_skill != PR_MAGNUS) {
    				int type;
    				if( (type = skill_get_casttype(r_skill)) == CAST_GROUND ) {
    					int maxcount = 0;
    
    					if( !(BL_PC&battle_config.skill_reiteration) &&
    						skill_get_unit_flag(r_skill)&UF_NOREITERATION )
    							type = -1;
    
    					if( BL_PC&battle_config.skill_nofootset &&
    						skill_get_unit_flag(r_skill)&UF_NOFOOTSET )
    							type = -1;
    
    					if( BL_PC&battle_config.land_skill_limit &&
    						(maxcount = skill_get_maxcount(r_skill, r_lv)) > 0
    					  ) {
    						int v;
    						for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) {
    							if(sd->ud.skillunit[v]->skill_id == r_skill)
    								maxcount--;
    						}
    						if( maxcount == 0 )
    							type = -1;
    					}
    
    					if( type != CAST_GROUND ){
    						clif_skill_fail(sd,r_skill,USESKILL_FAIL_LEVEL,0);
    						map_freeblock_unlock();
    						return wd.dmg_lv;
    					}
    				}
    
    				if (sd->state.autocast == 0) {
    					sd->state.autocast = 1;
    					skill_consume_requirement(sd, r_skill, r_lv, 3);
    					switch (type) {
    						case CAST_GROUND:
    							skill_castend_pos2(src, target->x, target->y, r_skill, r_lv, tick, flag);
    							break;
    						case CAST_NODAMAGE:
    							skill_castend_nodamage_id(src, target, r_skill, r_lv, tick, flag);
    							break;
    						case CAST_DAMAGE:
    							skill_castend_damage_id(src, target, r_skill, r_lv, tick, flag);
    							break;
    					}
    				}
    				sd->state.autocast = 0;
    
    				sd->ud.canact_tick = max(tick + skill_delayfix(src, r_skill, r_lv), sd->ud.canact_tick);
    				clif_status_change(src, SI_ACTIONDELAY, 1, skill_delayfix(src, r_skill, r_lv), 0, 0, 1);
    			}
    		}
    
    		if (wd.flag & BF_WEAPON && src != target && damage > 0) {
    			if (battle_config.left_cardfix_to_right)
    				battle_drain(sd, target, wd.damage, wd.damage, tstatus->race, tstatus->class_);
    			else
    				battle_drain(sd, target, wd.damage, wd.damage2, tstatus->race, tstatus->class_);
    		}
    	}
    
    	if (tsc) {
    		if (damage > 0 && tsc->data[SC_POISONREACT] &&
    			(rnd()%100 < tsc->data[SC_POISONREACT]->val3
    			|| sstatus->def_ele == ELE_POISON) &&
    //			check_distance_bl(src, target, tstatus->rhw.range+1) && Doesn't checks range! o.O;
    			status_check_skilluse(target, src, TF_POISON, 0)
    		) {	//Poison React
    			struct status_change_entry *sce = tsc->data[SC_POISONREACT];
    			if (sstatus->def_ele == ELE_POISON) {
    				sce->val2 = 0;
    				skill_attack(BF_WEAPON,target,target,src,AS_POISONREACT,sce->val1,tick,0);
    			} else {
    				skill_attack(BF_WEAPON,target,target,src,TF_POISON, 5, tick, 0);
    				--sce->val2;
    			}
    			if (sce->val2 <= 0)
    				status_change_end(target, SC_POISONREACT, INVALID_TIMER);
    		}
    	}
    	map_freeblock_unlock();
    	return wd.dmg_lv;
    }

    unit.c

    int unit_attack(struct block_list *src,int target_id,int continuous)
    {
    	struct block_list *target;
    	struct unit_data  *ud;
    	int range;
    
    	nullpo_ret(ud = unit_bl2ud(src));
    
    	target = map_id2bl(target_id);
    	if( target == NULL || status_isdead(target) ) {
    		unit_unattackable(src);
    		return 1;
    	}
    
    	if( src->type == BL_PC ) {
    		TBL_PC* sd = (TBL_PC*)src;
    
    		if( target->type == BL_NPC ) { // Monster npcs [Valaris]
    			npc_click(sd,(TBL_NPC*)target); // Submitted by leinsirk10 [Celest]
    			return 0;
    		}
    
    		if( pc_is90overweight(sd) || pc_isridingwug(sd) ) { // Overweight or mounted on warg - stop attacking
    			unit_stop_attack(src);
    			return 0;
    		}
    
    		if( !pc_can_attack(sd, target_id) ) {
    			unit_stop_attack(src);
    			return 0;
    		}
    	}
    
    	if( battle_check_target(src,target,BCT_ENEMY) <= 0 || !status_check_skilluse(src, target, 0, 0) ) {
    		unit_unattackable(src);
    		return 1;
    	}
    
    	ud->state.attack_continue = (continuous&1)?1:0;
    	ud->state.step_attack = (continuous&2)?1:0;
    	unit_set_target(ud, target_id);
    
    	range = status_get_range(src);
    
    	if (continuous) // If you're to attack continously, set to auto-chase character
    		ud->chaserange = range;
    
    	// Just change target/type. [Skotlex]
    	if(ud->attacktimer != INVALID_TIMER)
    		return 0;
    
    	// New action request received, delete previous action request if not executed yet
    	if(ud->stepaction || ud->steptimer != INVALID_TIMER)
    		unit_stop_stepaction(src);
    	// Remember the attack request from the client while walking to the next cell
    	if(src->type == BL_PC && ud->walktimer != INVALID_TIMER && !battle_check_range(src, target, range-1)) {
    		ud->stepaction = true;
    		ud->target_to = ud->target;
    		ud->stepskill_id = 0;
    		ud->stepskill_lv = 0;
    		return 0; // Attacking will be handled by unit_walktoxy_timer in this case
    	}
    	
    	if(DIFF_TICK(ud->attackabletime, gettick()) > 0) // Do attack next time it is possible. [Skotlex]
    		ud->attacktimer=add_timer(ud->attackabletime,unit_attack_timer,src->id,0);
    	else // Attack NOW.
    		unit_attack_timer(INVALID_TIMER, gettick(), src->id, 0);
    
    	return 0;
    }

    timer.c

    unsigned long get_uptime(void)
    {
    	return (unsigned long)difftime(time(NULL), start_time);
    }

    Git Hash: 5fda4f0f65d3a239becb9f44df38a7cfad9a6160

    our src has modification that im not aware of. :(

    Can anyone help me to fix this.. I tried looking at it and comparing every line to the recent commit but Im having a hard time fixing it..

  9. // Market Clone [AnnieRuru/Dastgir]
    int mob_clone_spawn_market( struct map_session_data *sd, int16 m, int16 x, int16 y, char market_title[], char market_msg[] ) { //Copy of mob_clone_spawn with some modification.
    	int mob_id;
    	struct mob_data *md;
    	struct mob_db* db;
    	struct status_data *mstatus;
    	struct chat_data* cd;
    
    	ARR_FIND( MOB_CLONE_START, MOB_CLONE_END, mob_id, mob_db_data[mob_id] == NULL );
    	if ( mob_id >= MOB_CLONE_END )
    		return 0;
    
    	db = mob_db_data[mob_id] = (struct mob_db*)aCalloc( 1, sizeof(struct mob_db) );
    	mstatus = &db->status;
    	safestrncpy( db->sprite, sd->status.name, NAME_LENGTH );
    	safestrncpy( db->name, sd->status.name, NAME_LENGTH );
    	safestrncpy( db->jname, sd->status.name, NAME_LENGTH );
    	db->lv = status_get_lv(&sd->bl);
    	memcpy( mstatus, &sd->base_status, sizeof( struct status_data ) );
    	mstatus->rhw.atk = mstatus->rhw.atk2 = mstatus->lhw.atk = mstatus->lhw.atk2 = mstatus->hp = mstatus->max_hp = mstatus->sp = mstatus->max_sp =  1;
    	mstatus->mode = 0;
    	memcpy( &db->vd, &sd->vd, sizeof( struct view_data ) );
    	db->base_exp = db->job_exp = db->range2 = db->range3 = 1;
    	db->option = 0;
    
    	md = mob_once_spawn_sub( &sd->bl, m, x, y, sd->status.name, mob_id, "", SZ_SMALL, AI_NONE );
    	if ( !md )
    		return 0;
    	md->special_state.clone = 1;
    	mob_spawn(md);
    	unit_setdir( &md->bl, unit_getdir(&sd->bl) );
    	cd = chat_createchat( &md->bl, market_title, "", 1, false, 0, "", 0, 1, MAX_LEVEL );
    	if ( !cd )
    		return 0;
    	md->market_chat_id = cd->bl.id;
    	safestrncpy( md->market_message, market_msg, CHAT_SIZE_MAX );
    	clif_dispchat( cd, 0 );
    	if ( sd->vd.dead_sit == 2 )
    		clif_sitting( &md->bl );
    
    	return md->bl.id;
    }

    Anyone can help me. I tried the market clone by AnnieRuru/Dastgir in the latest rA commit but it has error when compiling..

    Capture.JPG.4e3f9db417660c4ad2598538180b5dca.JPG

    Hoping that someone can help me.

  10. hi anyone can help me.. it only shows 1 result but when i try it on php sql it shows many results..

    fluxcp result:

    Captures.JPG.026ffa0f88da9588f964c62dff69c904.JPG

     

    Schema:

    <?php if (!defined('FLUX_ROOT')) exit;
    
    $title    = 'PvP Ranking';
    $classes  = Flux::config('JobClasses')->toArray();
    $jobClass = $params->get('jobclass');
    $bind     = array();
    
    if (trim($jobClass) === '') {
    	$jobClass = null;
    }
    
    if (!is_null($jobClass) && !array_key_exists($jobClass, $classes)) {
    	$this->deny();
    }
    
    $col  = "ch.char_id, ch.name AS char_name, ch.class AS char_class, ch.base_level, ch.base_exp, ch.job_level, ch.job_exp, ";
    $col .= "ch.guild_id, guild.name AS guild_name, guild.emblem_len AS guild_emblem_len, ";
    $col .= "ph.char_id, ph.kills, ph.deaths, ph.streaks ";
    
    $sql  = "SELECT $col FROM {$server->charMapDatabase}.char AS ch INNER JOIN {$server->charMapDatabase}.pvpladder AS ph ";
    $sql .= "LEFT JOIN {$server->charMapDatabase}.pvpladder ON ph.char_id = ch.char_id ";
    $sql .= "LEFT JOIN {$server->charMapDatabase}.guild ON guild.guild_id = ch.guild_id ";
    $sql .= "LEFT JOIN {$server->loginDatabase}.login ON login.account_id = ch.account_id ";
    $sql .= "WHERE 1=1 GROUP BY ch.char_id ";
    
    if (Flux::config('PvpHidePermBannedCharRank')) {
    	$sql .= "AND login.state != 5 ";
    }
    if (Flux::config('PvpHideTempBannedCharRank')) {
    	$sql .= "AND (login.unban_time IS NULL OR login.unban_time = 0) ";
    }
    
    $groups = AccountLevel::getGroupID((int)Flux::config('PvPRankingHideGroupLevel'), '<');
    if(!empty($groups)) {
    	$ids   = implode(', ', array_fill(0, count($groups), '?'));
    	$sql  .= "AND login.group_id IN ($ids) ";
    	$bind  = array_merge($bind, $groups);
    }
    
    if ($days=Flux::config('PvpCharRankingThreshold')) {
    	$sql    .= 'AND TIMESTAMPDIFF(DAY, login.lastlogin, NOW()) <= ? ';
    	$bind[]  = $days * 24 * 60 * 60;
    }
    
    if (!is_null($jobClass)) {
    	$sql .= "AND ch.class = ? ";
    	$bind[] = $jobClass;
    }
    
    $sql .= "ORDER BY ph.kills DESC ";
    $sql .= "LIMIT ".(int)Flux::config('PvpRankingLimit');
    $sth  = $server->connection->getStatement($sql);
    
    $sth->execute($bind);
    
    $chars = $sth->fetchAll();
    ?>

    Phpmyadmin Result:

    Capture.thumb.JPG.fa2a1b112aaa6651aa20e16da9e8367a.JPG

×
×
  • Create New...