Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[Release] PvP state quick fix solution (Stiff/Stun/Knockdown/Bound)

Joined
Apr 16, 2007
Messages
441
Reaction score
204
If you guys have played BDO then you would have seen in these files that a stiff, knockdown, bound and etc does not work the way it should it feels like 0.1 second and instead should be 1-2+ seconds of state change.

the last few days i have been studying these files and located where the restrictions are applied, but did not find where the timer for these are applied so instead i wrote my own and currently this fix does work and does apply these restrictions as it should.

i should let you know that Java is not my main coding language and this is just a quick solution
this code is still incomplete due to me not being able to test with a 2nd player but it does apply state effects longer.

stun is implemented in this code which the current files does not have stun.

com\bdoemu\gameserver\model\creature\player\controllers\ActionRestrictionController.java
Code:
package com.bdoemu.gameserver.model.creature.player.controllers;

import com.bdoemu.gameserver.model.creature.Creature;
import com.bdoemu.gameserver.model.creature.player.Player;
import com.bdoemu.gameserver.model.creature.player.cooltimes.ActionRestrictionEntry;

import java.util.Calendar;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class ActionRestrictionController {
    private Player _player;
    private ConcurrentHashMap<Integer, ActionRestrictionEntry> _actionRestrictions;
    private long _end;
    private int hitType;
    private int player_state;
    
    public ActionRestrictionController(Player player) {
        _actionRestrictions = new ConcurrentHashMap<>();
        _player = player;
        _end = 0L;
        player_state = 0;
    }

    public Player getPlayer() {
        return _player;
    }

    public boolean isActionRestricted(int actionType) {
        ActionRestrictionEntry entry = _actionRestrictions.get(actionType);
        //_player.getAi().HandleRigid(_player, null);
        return !(entry == null || entry.isExpired());
    }

    public boolean checkRestrictCondition(List<Integer> actionTypes) {
        
        for (Integer actionType : actionTypes) {
            ActionRestrictionEntry entry = _actionRestrictions.get(actionType);
            //_player.getAi().HandleRigid(_player, null);

            //while(System.currentTimeMillis() < _end) {
              // do something
              // pause to avoid churning
              //Thread.sleep( xxx );
                //_player.getAi().HandleRigid(_player, null);
            //}
            if (isActionRestricted(actionType))
                //if(entry.isExpired()){
                return false;
                //}
        }

        return true;
    }

    public void restrictActions(Creature attacker, List<Integer> actionTypes, int mainActionType, int expireTime) {
        //System.out.println("1) Restriction " + (expireTime) + " ms.");
        for (Integer actionType : actionTypes)
            
            restrictAction(attacker, actionType, expireTime, mainActionType == actionType ? 500 : 0);
        
    }

    public void restrictAction(Creature attacker, int actionType, int expireTime, int offset) {
        Calendar calendar = Calendar.getInstance();
        //expireTime = (expireTime * 100);
        //calendar.add(Calendar.MILLISECOND, (expireTime + (offset + 100000)));
        calendar.add(Calendar.MILLISECOND, expireTime);
        
        System.out.println("2) Restrict Type=" + actionType + ", Expire=" + expireTime + " ms.");

        ActionRestrictionEntry entry = _actionRestrictions.get(actionType);
        
         _actionRestrictions.put(actionType, new ActionRestrictionEntry(actionType, calendar.getTimeInMillis()));
        
        
        //Stiff > Stun > Bound/Knockdown/Float
        //Stun > Stiff > Bound/Knockdown/Float
        //player_state: 1 = rigid, 2 = stun, 3 = bound, 4 = knockdown
        //
        //
        //if(_end<=){
        //} else {
        hitType = actionType;
        System.out.println("HitType: " + hitType + ", player_state: " + player_state + ", timer: " + _end);
        
        if(actionType == 1){
            //rigid
            if(player_state==0){
                _end = System.currentTimeMillis() + 1300L;
                player_state = 1;
            } else if(player_state==2){
                _end = System.currentTimeMillis() + 1300L;
                player_state = 1;
            }
        } else if(actionType == 2){
            //knockdown
            if(player_state==0){
                _end = System.currentTimeMillis() + 500L;
                player_state = 4;
            } else if(player_state==1){
                _end = System.currentTimeMillis() + 500L;
                player_state = 4;
            } else if(player_state==2){
                _end = System.currentTimeMillis() + 500L;
                player_state = 4;
            }
            
            } else if(actionType == 3){
                //rigid
                    if(player_state==0){
                        _end = System.currentTimeMillis() + 1300L;
                        player_state = 1;
                        } else if(player_state==2){
                            _end = System.currentTimeMillis() + 1300L;
                            player_state = 1;
                        }
            } else if(actionType == 4){
                //stun
                if(player_state==0){
                        _end = System.currentTimeMillis() + 1300L;
                        player_state = 2;
                        } else if(player_state==1){
                            _end = System.currentTimeMillis() + 1300L;
                            player_state = 2;
                        }
            } else if(actionType == 6){
                //rigid
                if(player_state==0){
                    _end = System.currentTimeMillis() + 1300L;
                    player_state = 1;
                        } else if(player_state==2){
                            _end = System.currentTimeMillis() + 1300L;
                            player_state = 1;
                        }
            } else if(actionType == 7){
                //bound
                if(player_state==0){
                    _end = System.currentTimeMillis() + 800L;
                    player_state = 3;
                } else if(player_state==1){
                    _end = System.currentTimeMillis() + 800L;
                    player_state = 3;
                } else if(player_state==2){
                    _end = System.currentTimeMillis() + 800L;
                    player_state = 3;
                }
                }else if(actionType == 12){
                    //knockdown
                    if(player_state==0){
                        _end = System.currentTimeMillis() + 500L;
                        player_state = 4;
                    } else if(player_state==1){
                        _end = System.currentTimeMillis() + 500L;
                        player_state = 4;
                    } else if(player_state==2){
                        _end = System.currentTimeMillis() + 500L;
                        player_state = 4;
                    }
            }else {
                //_end = System.currentTimeMillis() + 5000L;
            }
        //}
        System.out.println("HitType: " + hitType + ", player_state: " + player_state + ", timer: " + _end);
        
        //if (entry == null) {
        //calendar.add(Calendar.MILLISECOND, (expireTime + (offset + 100000)));

            //_actionRestrictions.put(actionType, new ActionRestrictionEntry(actionType, calendar.getTimeInMillis()));
            //_actionRestrictions.put(actionType, new ActionRestrictionEntry(actionType, 5000));
        //} else {
            //entry.setExpirationTime(calendar.getTimeInMillis());
            if(_end > System.currentTimeMillis()){
        new Thread(new Runnable() {

            @Override
            public void run() {
                //for(int i=0; i<100; i++) {
                while(System.currentTimeMillis() < _end) {
                    System.out.println("HitType: " + hitType + ", player_state: " + player_state);
                    if(hitType==1){
                    _player.getAi().HandleRigid(_player, null);
                    } else if(hitType==2) {
                        _player.getAi().HandleKnockDown(_player, null);
                    } else if(hitType==3) {
                        _player.getAi().HandleRigid(_player, null);
                    } else if(hitType==4) {
                        _player.getAi().HandleRigid(_player, null);
                    } else if(hitType==6) {
                        _player.getAi().HandleRigid(_player, null);
                    } else if(hitType==7) {
                        _player.getAi().HandleBound(_player, null);
                    } else if(hitType==12) {
                        _player.getAi().HandleKnockDown(_player, null);
                    } else {
                        //_player.getAi().HandleRigid(_player, null);
                    }
                    if(System.currentTimeMillis() >= _end) {
                        if(player_state>0){
                        player_state = 0;
                        }
                        _end = 0L;
                        //Thread.interrupted();
                    }
                    }
                }
            
        }).start();

    }
        //}
    }
    
}

I hope others would release their works for fixing and improving the server files.

you must compile this .java to .class and import through Eclipse and export as .jar

if a skill does not apply a state change the print console is there just get the actionType "hitType" ID and update this source with the ID.

if you guys want to know where the HandleRigid, HandleKnockdown state changes are applied it's located at:
gameserver/scripts/ai/Ai_pc.java

Grab code is handled at:
com\bdoemu\gameserver\model\actions\actioncharts\CatchAction.java

i can confirm this is the file that handles grabs as i'm currently trying to fix grabs don't expect too much, but i will release a fix or a temp fix when i can.
 
Last edited:
Newbie Spellweaver
Joined
May 25, 2009
Messages
45
Reaction score
3
how to avoid loading cpu when using it?
 
Newbie Spellweaver
Joined
May 25, 2009
Messages
45
Reaction score
3
whenever a character uses to continue, or opushennye the server starts to load the processor! if we have 100 people and at the same time this happens, there will be trouble :d
 
Newbie Spellweaver
Joined
May 25, 2009
Messages
45
Reaction score
3
Yes, the code loads the processor \ sorry my english is bad

Diminishing is needed for stun
 
Last edited:
Back
Top