Revamped buff system + skill cd/buff schedule rework
Completely rearranged buff system (system can smartly check for the best statup to take effect for it's duration, or the server can be flagged to act as usual). Refactored scheduling system for buffs expiration and cooldowns to use one single thread per player rather than one per instance.
This commit is contained in:
@@ -48,7 +48,7 @@ public enum MapleBuffStat {
|
||||
AURA(0x40000L),
|
||||
CONFUSE(0x80000L),
|
||||
|
||||
// ---- COUPON feature (was unused anyway) ----
|
||||
// ------ COUPON feature ------
|
||||
|
||||
COUPON_EXP1(0x100000L),
|
||||
COUPON_EXP2(0x200000L),
|
||||
|
||||
+908
-442
File diff suppressed because it is too large
Load Diff
@@ -1307,7 +1307,9 @@ public class MapleClient {
|
||||
}
|
||||
}
|
||||
server.getPlayerBuffStorage().addBuffsToStorage(player.getId(), player.getAllBuffs());
|
||||
player.cancelBuffEffects();
|
||||
player.cancelAllBuffs(true);
|
||||
player.cancelBuffExpireTask();
|
||||
player.cancelSkillCooldownTask();
|
||||
//Cancelling magicdoor? Nope
|
||||
//Cancelling mounts? Noty
|
||||
if (player.getBuffedValue(MapleBuffStat.PUPPET) != null) {
|
||||
|
||||
@@ -1252,9 +1252,12 @@ public class Commands {
|
||||
}
|
||||
}
|
||||
|
||||
if(player.getJob().isA(MapleJob.ARAN1)) {
|
||||
if(player.getJob().isA(MapleJob.ARAN1) || player.getJob().isA(MapleJob.LEGEND)) {
|
||||
skill = SkillFactory.getSkill(5001005);
|
||||
player.changeSkillLevel(skill, (byte) -1, -1, -1);
|
||||
} else {
|
||||
skill = SkillFactory.getSkill(21001001);
|
||||
player.changeSkillLevel(skill, (byte) -1, -1, -1);
|
||||
}
|
||||
|
||||
player.yellowMessage("Skills maxed out.");
|
||||
@@ -1664,7 +1667,7 @@ public class Commands {
|
||||
|
||||
case "givems":
|
||||
if (sub.length < 3){
|
||||
player.yellowMessage("Syntax: !givems <playername> <gainmx>");
|
||||
player.yellowMessage("Syntax: !givems <playername> <gainms>");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2051,7 +2054,7 @@ public class Commands {
|
||||
try {
|
||||
if (sub.length == 2) {
|
||||
int itemId = Integer.parseInt(sub[1]);
|
||||
if(!(itemId >= 30000 && itemId < 32000) || MapleItemInformationProvider.getInstance().getName(itemId) == null) {
|
||||
if(!(itemId >= 30000 && itemId < 35000) || MapleItemInformationProvider.getInstance().getName(itemId) == null) {
|
||||
player.yellowMessage("Hair id '" + sub[1] + "' does not exist.");
|
||||
break;
|
||||
}
|
||||
@@ -2061,7 +2064,7 @@ public class Commands {
|
||||
player.equipChanged();
|
||||
} else {
|
||||
int itemId = Integer.parseInt(sub[2]);
|
||||
if(!(itemId >= 30000 && itemId < 32000) || MapleItemInformationProvider.getInstance().getName(itemId) == null) {
|
||||
if(!(itemId >= 30000 && itemId < 35000) || MapleItemInformationProvider.getInstance().getName(itemId) == null) {
|
||||
player.yellowMessage("Hair id '" + sub[2] + "' does not exist.");
|
||||
break;
|
||||
}
|
||||
@@ -2278,6 +2281,7 @@ public class Commands {
|
||||
player.getMap().spawnMonsterOnGroundBelow(monster, player.getPosition());
|
||||
break;
|
||||
|
||||
/*
|
||||
case "playernpc":
|
||||
if (sub.length < 3){
|
||||
player.yellowMessage("Syntax: !playernpc <playername> <npcid>");
|
||||
@@ -2285,6 +2289,7 @@ public class Commands {
|
||||
}
|
||||
player.playerNPC(c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]), Integer.parseInt(sub[2]));
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -487,11 +487,11 @@ public class Equip extends Item {
|
||||
// from level 1 to 2 is killing about 100~200 mobs of the same level range, on a 1x EXP rate scenario.
|
||||
|
||||
if(reqLevel >= 78) {
|
||||
return Math.max(ServerConstants.EQUIP_EXPERIENCE_MOD * (10413.648 * Math.exp(reqLevel * 0.03275)), 15);
|
||||
return Math.max(ServerConstants.EQUIP_EXP_RATE * (10413.648 * Math.exp(reqLevel * 0.03275)), 15);
|
||||
} else if(reqLevel >= 38) {
|
||||
return Math.max(ServerConstants.EQUIP_EXPERIENCE_MOD * ( 4985.818 * Math.exp(reqLevel * 0.02007)), 15);
|
||||
return Math.max(ServerConstants.EQUIP_EXP_RATE * ( 4985.818 * Math.exp(reqLevel * 0.02007)), 15);
|
||||
} else {
|
||||
return Math.max(ServerConstants.EQUIP_EXPERIENCE_MOD * ( 248.219 * Math.exp(reqLevel * 0.11093)), 15);
|
||||
return Math.max(ServerConstants.EQUIP_EXP_RATE * ( 248.219 * Math.exp(reqLevel * 0.11093)), 15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,6 @@ public final class ItemConstants {
|
||||
public final static int KARMA = 0x10;
|
||||
public final static int PET_COME = 0x80;
|
||||
public final static int ACCOUNT_SHARING = 0x100;
|
||||
public final static float ITEM_ARMOR_EXP = 1 / 350000;
|
||||
public static final float ITEM_WEAPON_EXP = 1 / 700000;
|
||||
|
||||
public final static boolean EXPIRING_ITEMS = true;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class ServerConstants {
|
||||
//Server Flags
|
||||
public static final boolean USE_CUSTOM_KEYSET = true; //Enables auto-setup of the MapleSolaxiaV2's custom keybindings when creating characters.
|
||||
public static final boolean USE_MAXRANGE_ECHO_OF_HERO = true;
|
||||
public static final boolean USE_MAXRANGE = true; //Will send and receive packets from all events of a map, rather than those of only view range.
|
||||
public static final boolean USE_MAXRANGE = true; //Will send and receive packets from all events on a map, rather than those of only view range.
|
||||
public static final boolean USE_DEBUG = false; //Will enable some text prints on the client, oriented for debugging purposes.
|
||||
public static final boolean USE_DEBUG_SHOW_RCVD_PACKET = false; //Prints on the cmd all received packet ids.
|
||||
public static final boolean USE_DEBUG_SHOW_INFO_EQPEXP = false; //Prints on the cmd all equip exp gain info.
|
||||
@@ -45,20 +45,23 @@ public class ServerConstants {
|
||||
public static final boolean USE_PARTY_SEARCH = false;
|
||||
public static final boolean USE_AUTOBAN = false; //Commands the server to detect infractors automatically.
|
||||
public static final boolean USE_AUTOSAVE = true; //Enables server autosaving feature (saves characters to DB each 1 hour).
|
||||
public static final boolean USE_SERVER_AUTOASSIGNER = true; //Server-builtin autoassigner, uses algorithm based on distributing AP accordingly to required secondary stat on equipments.
|
||||
public static final boolean USE_SERVER_AUTOASSIGNER = true; //Server-builtin autoassigner, uses algorithm based on distributing AP accordingly with required secondary stat on equipments.
|
||||
public static final boolean USE_REFRESH_RANK_MOVE = true;
|
||||
public static final boolean USE_ENFORCE_MDOOR_POSITION = true; //Forces mystic door to be spawned near spawnpoints. (since things bugs out other way, and this helps players to locate the door faster)
|
||||
public static final boolean USE_ERASE_UNTRADEABLE_DROP = true; //Forces flagged untradeable items to disappear when dropped.
|
||||
public static final boolean USE_BUFF_MOST_SIGNIFICANT = true; //When applying buffs, the player will stick with the highest stat boost among the listed, rather than overwriting stats.
|
||||
|
||||
//Server Rates And Experience
|
||||
public static final int EXP_RATE = 10;
|
||||
public static final int MESO_RATE = 10;
|
||||
public static final int DROP_RATE = 10;
|
||||
public static final int BOSS_DROP_RATE = 20;
|
||||
public static final int PARTY_EXPERIENCE_MOD = 1; //Change for event stuff.
|
||||
public static final double EQUIP_EXPERIENCE_MOD = 10.0; //Rate for equipment exp needed, grows linearly. Set 1.0 for default (about 100~200 same-level range mobs killed to pass equip from level 1 to 2).
|
||||
public static final double EQUIP_EXP_RATE = 10.0; //Rate for equipment exp gain, grows linearly. Set 1.0 for default (about 100~200 same-level range mobs killed to pass equip from level 1 to 2).
|
||||
|
||||
public static final int PARTY_EXPERIENCE_MOD = 1; //Change for event stuff.
|
||||
public static final double PQ_BONUS_EXP_MOD = 0.5;
|
||||
|
||||
public static final byte MAX_MONITORED_BUFFSTATS = 5; //Limits accounting for "dormant" buff effects, that should take place when stronger stat buffs expires.
|
||||
public static final int MAX_AP = 32767; //Max AP allotted on the auto-assigner.
|
||||
public static final int MAX_EVENT_LEVELS = 8; //Event has different levels of rewarding system.
|
||||
public static final long BLOCK_NPC_RACE_CONDT = (long)(0.5 * 1000); //Time the player client must wait before reopening a conversation with an NPC.
|
||||
@@ -91,7 +94,7 @@ public class ServerConstants {
|
||||
|
||||
//Equipment Configuration
|
||||
public static final boolean USE_EQUIPMNT_LVLUP_SLOTS = true;//Equips can upgrade slots at level up.
|
||||
public static final boolean USE_EQUIPMNT_LVLUP_POWER = true;//Enable more powerful stats upgrades at equip level up.
|
||||
public static final boolean USE_EQUIPMNT_LVLUP_POWER = true;//Enable more powerful stat upgrades at equip level up.
|
||||
public static final boolean USE_SPIKES_AVOID_BANISH = true; //Shoes equipped with spikes prevents mobs from banishing wearer.
|
||||
public static final boolean USE_CHAIR_EXTRAHEAL = true; //Enable map chairs to further recover player's HP and MP.
|
||||
public static final int MAX_EQUIPMNT_LVLUP_STAT_UP = 10000; //Max stat upgrade an equipment can have on a levelup.
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
*/
|
||||
package net.server;
|
||||
|
||||
import net.server.worker.CouponWorker;
|
||||
import net.server.worker.RankingWorker;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
@@ -41,6 +41,8 @@ public final class CancelBuffHandler extends AbstractMaplePacketHandler implemen
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
int sourceid = slea.readInt();
|
||||
if(sourceid < 0) sourceid = -sourceid; //oh my...
|
||||
|
||||
switch (sourceid) {
|
||||
case FPArchMage.BIG_BANG:
|
||||
case ILArchMage.BIG_BANG:
|
||||
|
||||
@@ -32,7 +32,6 @@ import tools.Pair;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import client.MapleBuffStat;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleCharacter.CancelCooldownAction;
|
||||
import client.MapleClient;
|
||||
import client.MapleJob;
|
||||
import client.MapleStat;
|
||||
@@ -175,7 +174,7 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
return;
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000, TimerManager.getInstance().schedule(new CancelCooldownAction(player, attack.skill), effect_.getCooldown() * 1000));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,9 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler {
|
||||
mc.closePlayerInteractions();
|
||||
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs());
|
||||
mc.cancelBuffEffects();
|
||||
mc.cancelAllBuffs(true);
|
||||
mc.cancelBuffExpireTask();
|
||||
mc.cancelSkillCooldownTask();
|
||||
mc.cancelExpirationTask();
|
||||
|
||||
c.announce(MaplePacketCreator.openCashShop(c, false));
|
||||
|
||||
@@ -59,6 +59,9 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs());
|
||||
chr.cancelAllBuffs(true);
|
||||
chr.cancelBuffExpireTask();
|
||||
chr.cancelSkillCooldownTask();
|
||||
chr.cancelExpirationTask();
|
||||
chr.saveToDB();
|
||||
chr.getMap().removePlayer(c.getPlayer());
|
||||
|
||||
@@ -27,7 +27,6 @@ import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import client.MapleBuffStat;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleCharacter.CancelCooldownAction;
|
||||
import client.MapleClient;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
@@ -76,7 +75,7 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
|
||||
return;
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000, TimerManager.getInstance().schedule(new CancelCooldownAction(player, attack.skill), effect_.getCooldown() * 1000));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000);
|
||||
}
|
||||
}
|
||||
applyAttack(attack, player, effect.getAttackCount());
|
||||
|
||||
@@ -32,6 +32,7 @@ import constants.ItemConstants;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.Server;
|
||||
import server.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MapleMiniGame;
|
||||
@@ -172,6 +173,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
} else {
|
||||
HiredMerchant merchant = new HiredMerchant(chr, itemId, desc);
|
||||
chr.setHiredMerchant(merchant);
|
||||
c.getWorldServer().registerHiredMerchant(merchant);
|
||||
chr.getClient().getChannelServer().addHiredMerchant(chr.getId(), merchant);
|
||||
chr.announce(MaplePacketCreator.getHiredMerchant(chr, merchant, true));
|
||||
}
|
||||
|
||||
@@ -256,6 +256,8 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
c.announce(MaplePacketCreator.enableReport());
|
||||
player.changeSkillLevel(SkillFactory.getSkill(10000000 * player.getJobType() + 12), (byte) (player.getLinkedLevel() / 10), 20, -1);
|
||||
player.checkBerserk(player.isHidden());
|
||||
player.buffExpireTask();
|
||||
player.skillCooldownTask();
|
||||
player.expirationTask();
|
||||
if (GameConstants.hasSPTable(player.getJob()) && player.getJob().getId() != 2001) {
|
||||
player.createDragon();
|
||||
|
||||
@@ -30,7 +30,6 @@ import tools.Randomizer;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import client.MapleBuffStat;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleCharacter.CancelCooldownAction;
|
||||
import client.MapleClient;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
@@ -208,7 +207,7 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler {
|
||||
return;
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000, TimerManager.getInstance().schedule(new CancelCooldownAction(player, attack.skill), effect_.getCooldown() * 1000));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import tools.FilePrinter;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleCharacter.CancelCooldownAction;
|
||||
import client.autoban.AutobanFactory;
|
||||
import client.MapleClient;
|
||||
import client.MapleStat;
|
||||
@@ -84,8 +83,7 @@ public final class SpecialMoveHandler extends AbstractMaplePacketHandler {
|
||||
return;
|
||||
} else if (skillid != Corsair.BATTLE_SHIP) {
|
||||
c.announce(MaplePacketCreator.skillCooldown(skillid, effect.getCooldown()));
|
||||
ScheduledFuture<?> timer = TimerManager.getInstance().schedule(new CancelCooldownAction(c.getPlayer(), skillid), effect.getCooldown() * 1000);
|
||||
chr.addCooldown(skillid, System.currentTimeMillis(), effect.getCooldown() * 1000, timer);
|
||||
chr.addCooldown(skillid, System.currentTimeMillis(), effect.getCooldown() * 1000);
|
||||
}
|
||||
}
|
||||
if (skillid == Hero.MONSTER_MAGNET || skillid == Paladin.MONSTER_MAGNET || skillid == DarkKnight.MONSTER_MAGNET) { // Monster Magnet
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.server.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class BaseWorker implements Runnable {
|
||||
protected World wserv;
|
||||
|
||||
@Override
|
||||
public void run() {}
|
||||
|
||||
public BaseWorker(World world) {
|
||||
wserv = world;
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -20,17 +20,17 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.server;
|
||||
package net.server.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
import client.MapleCharacter;
|
||||
import constants.ServerConstants;
|
||||
import net.server.PlayerStorage;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class CharacterAutosaverWorker implements Runnable {
|
||||
private World wserv;
|
||||
public class CharacterAutosaverWorker extends BaseWorker implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -45,6 +45,6 @@ public class CharacterAutosaverWorker implements Runnable {
|
||||
}
|
||||
|
||||
public CharacterAutosaverWorker(World world) {
|
||||
wserv = world;
|
||||
super(world);
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,10 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.server;
|
||||
package net.server.worker;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import net.server.Server;
|
||||
import tools.FilePrinter;
|
||||
|
||||
/**
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation version 3 as published by
|
||||
the Free Software Foundation. You may not use, modify or distribute
|
||||
this program under any other version of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.server.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class HiredMerchantWorker extends BaseWorker implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
wserv.runHiredMerchantSchedule();
|
||||
}
|
||||
|
||||
public HiredMerchantWorker(World world) {
|
||||
super(world);
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -20,15 +20,14 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.server;
|
||||
package net.server.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class MountTirednessWorker implements Runnable {
|
||||
private World wserv;
|
||||
public class MountTirednessWorker extends BaseWorker implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -36,6 +35,6 @@ public class MountTirednessWorker implements Runnable {
|
||||
}
|
||||
|
||||
public MountTirednessWorker(World world) {
|
||||
wserv = world;
|
||||
super(world);
|
||||
}
|
||||
}
|
||||
+3
-4
@@ -20,15 +20,14 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.server;
|
||||
package net.server.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class PetFullnessWorker implements Runnable {
|
||||
private World wserv;
|
||||
public class PetFullnessWorker extends BaseWorker implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -36,6 +35,6 @@ public class PetFullnessWorker implements Runnable {
|
||||
}
|
||||
|
||||
public PetFullnessWorker(World world) {
|
||||
wserv = world;
|
||||
super(world);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package net.server;
|
||||
package net.server.worker;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
@@ -28,6 +28,7 @@ import java.sql.SQLException;
|
||||
import client.MapleJob;
|
||||
import tools.DatabaseConnection;
|
||||
import constants.ServerConstants;
|
||||
import net.server.Server;
|
||||
|
||||
/**
|
||||
* @author Matze
|
||||
@@ -45,9 +45,10 @@ import java.util.HashSet;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import server.TimerManager;
|
||||
import net.server.CharacterAutosaverWorker;
|
||||
import net.server.MountTirednessWorker;
|
||||
import net.server.PetFullnessWorker;
|
||||
import server.maps.HiredMerchant;
|
||||
import net.server.worker.CharacterAutosaverWorker;
|
||||
import net.server.worker.MountTirednessWorker;
|
||||
import net.server.worker.PetFullnessWorker;
|
||||
import net.server.PlayerStorage;
|
||||
import net.server.Server;
|
||||
import net.server.channel.Channel;
|
||||
@@ -84,6 +85,10 @@ public class World {
|
||||
private ScheduledFuture<?> mountsSchedule;
|
||||
private long mountUpdate;
|
||||
|
||||
private Map<HiredMerchant, Byte> activeMerchants = new LinkedHashMap<>();
|
||||
private ScheduledFuture<?> MerchantsSchedule;
|
||||
private long merchantUpdate;
|
||||
|
||||
private ScheduledFuture<?> charactersSchedule;
|
||||
|
||||
public World(int world, int flag, String eventmsg, int exprate, int droprate, int mesorate, int bossdroprate) {
|
||||
@@ -773,6 +778,48 @@ public class World {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerHiredMerchant(HiredMerchant hm) {
|
||||
synchronized(activeMerchants) {
|
||||
byte initProc;
|
||||
if(System.currentTimeMillis() - merchantUpdate > 5 * 60 * 1000) initProc = 1;
|
||||
else initProc = 0;
|
||||
|
||||
activeMerchants.put(hm, initProc);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterHiredMerchant(HiredMerchant hm) {
|
||||
synchronized(activeMerchants) {
|
||||
activeMerchants.remove(hm);
|
||||
}
|
||||
}
|
||||
|
||||
public void runHiredMerchantSchedule() {
|
||||
Map<HiredMerchant, Byte> deployedMerchants;
|
||||
synchronized(activeMerchants) {
|
||||
merchantUpdate = System.currentTimeMillis();
|
||||
deployedMerchants = Collections.unmodifiableMap(activeMerchants);
|
||||
}
|
||||
|
||||
for(Map.Entry<HiredMerchant, Byte> dm: deployedMerchants.entrySet()) {
|
||||
byte timeOn = dm.getValue();
|
||||
|
||||
if(timeOn <= 144) { // 1440 minutes == 24hrs
|
||||
synchronized(activeMerchants) {
|
||||
activeMerchants.put(dm.getKey(), (byte)(timeOn + 1));
|
||||
}
|
||||
} else {
|
||||
HiredMerchant hm = dm.getKey();
|
||||
hm.forceClose();
|
||||
this.getChannel(hm.getChannel()).removeHiredMerchant(hm.getOwnerId());
|
||||
|
||||
synchronized(activeMerchants) {
|
||||
activeMerchants.remove(dm.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setServerMessage(String msg) {
|
||||
for (Channel ch : channels) {
|
||||
|
||||
@@ -523,7 +523,7 @@ public class MapleInventoryManipulator {
|
||||
return;
|
||||
}
|
||||
int itemId = source.getItemId();
|
||||
if (itemId >= 5000000 && itemId <= 5000102) {
|
||||
if (ItemConstants.isPet(itemId)) {
|
||||
return;
|
||||
}
|
||||
if (type == MapleInventoryType.EQUIPPED && itemId == 1122017) {
|
||||
|
||||
@@ -110,6 +110,7 @@ public class MapleItemInformationProvider {
|
||||
protected Map<Integer, Boolean> consumeOnPickupCache = new HashMap<>();
|
||||
protected Map<Integer, Boolean> isQuestItemCache = new HashMap<>();
|
||||
protected Map<Integer, String> equipmentSlotCache = new HashMap<>();
|
||||
protected Map<Integer, Boolean> noCancelMouseCache = new HashMap<>();
|
||||
|
||||
private MapleItemInformationProvider() {
|
||||
loadCardIdData();
|
||||
@@ -246,7 +247,7 @@ public class MapleItemInformationProvider {
|
||||
} else if (itemId >= 1080000 && itemId < 1090000) {
|
||||
theData = eqpStringData;
|
||||
cat = "Eqp/Glove";
|
||||
} else if (itemId >= 30000 && itemId < 32000) {
|
||||
} else if (itemId >= 30000 && itemId < 35000) {
|
||||
theData = eqpStringData;
|
||||
cat = "Eqp/Hair";
|
||||
} else if (itemId >= 1050000 && itemId < 1060000) {
|
||||
@@ -278,7 +279,7 @@ public class MapleItemInformationProvider {
|
||||
cat = "Etc";
|
||||
} else if (itemId >= 3000000 && itemId < 4000000) {
|
||||
theData = insStringData;
|
||||
} else if (itemId >= 5000000 && itemId < 5010000) {
|
||||
} else if (ItemConstants.isPet(itemId)) {
|
||||
theData = petStringData;
|
||||
} else {
|
||||
return null;
|
||||
@@ -291,11 +292,19 @@ public class MapleItemInformationProvider {
|
||||
}
|
||||
|
||||
public boolean noCancelMouse(int itemId) {
|
||||
if (noCancelMouseCache.containsKey(itemId)) {
|
||||
return noCancelMouseCache.get(itemId);
|
||||
}
|
||||
|
||||
MapleData item = getItemData(itemId);
|
||||
if (item == null) {
|
||||
noCancelMouseCache.put(itemId, false);
|
||||
return false;
|
||||
}
|
||||
return MapleDataTool.getIntConvert("info/noCancelMouse", item, 0) == 1;
|
||||
|
||||
boolean blockMouse = MapleDataTool.getIntConvert("info/noCancelMouse", item, 0) == 1;
|
||||
noCancelMouseCache.put(itemId, blockMouse);
|
||||
return blockMouse;
|
||||
}
|
||||
|
||||
private MapleData getItemData(int itemId) {
|
||||
|
||||
@@ -132,7 +132,7 @@ public class MapleShop {
|
||||
int cardreduce = value - cost;
|
||||
int diff = cardreduce + c.getPlayer().getMeso();
|
||||
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
|
||||
if (itemId >= 5000000 && itemId <= 5000100) {
|
||||
if (ItemConstants.isPet(itemId)) {
|
||||
int petid = MaplePet.createPet(itemId);
|
||||
MapleInventoryManipulator.addById(c, itemId, quantity, null, petid, -1);
|
||||
} else {
|
||||
|
||||
@@ -565,8 +565,8 @@ public class MapleStatEffect {
|
||||
case Crusader.ARMOR_CRASH:
|
||||
case DragonKnight.POWER_CRASH:
|
||||
case WhiteKnight.MAGIC_CRASH:
|
||||
monsterStatus.put(MonsterStatus.SEAL_SKILL, Integer.valueOf(1));
|
||||
break;
|
||||
monsterStatus.put(MonsterStatus.SEAL_SKILL, Integer.valueOf(1));
|
||||
break;
|
||||
case Rogue.DISORDER:
|
||||
monsterStatus.put(MonsterStatus.WATK, Integer.valueOf(ret.x));
|
||||
monsterStatus.put(MonsterStatus.WDEF, Integer.valueOf(ret.y));
|
||||
@@ -842,7 +842,6 @@ public class MapleStatEffect {
|
||||
} else {
|
||||
MapleInventoryManipulator.removeById(applyto.getClient(), MapleInventoryType.USE, projectile, 200, false, true);
|
||||
}
|
||||
|
||||
}
|
||||
SummonMovementType summonMovementType = getSummonMovementType();
|
||||
if (overTime || isCygnusFA() || summonMovementType != null) {
|
||||
@@ -983,9 +982,12 @@ public class MapleStatEffect {
|
||||
public void silentApplyBuff(MapleCharacter chr, long starttime) {
|
||||
int localDuration = duration;
|
||||
localDuration = alchemistModifyVal(chr, localDuration, false);
|
||||
CancelEffectAction cancelAction = new CancelEffectAction(chr, this, starttime);
|
||||
ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + localDuration) - System.currentTimeMillis()));
|
||||
chr.registerEffect(this, starttime, schedule);
|
||||
//CancelEffectAction cancelAction = new CancelEffectAction(chr, this, starttime);
|
||||
//ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + localDuration) - System.currentTimeMillis()));
|
||||
|
||||
if(starttime + localDuration <= System.currentTimeMillis()) return;
|
||||
|
||||
chr.registerEffect(this, starttime, (starttime + localDuration), true);
|
||||
SummonMovementType summonMovementType = getSummonMovementType();
|
||||
if (summonMovementType != null) {
|
||||
final MapleSummon tosummon = new MapleSummon(chr, sourceid, chr.getPosition(), summonMovementType);
|
||||
@@ -1006,7 +1008,18 @@ public class MapleStatEffect {
|
||||
final long starttime = System.currentTimeMillis();
|
||||
// final CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime);
|
||||
// final ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + 99999) - System.currentTimeMillis()));
|
||||
applyto.registerEffect(this, starttime, null);
|
||||
applyto.registerEffect(this, starttime, Long.MAX_VALUE, false);
|
||||
}
|
||||
|
||||
public void updateBuffEffect(MapleCharacter target, List<Pair<MapleBuffStat, Integer>> activeStats, long starttime) {
|
||||
int localDuration = duration;
|
||||
localDuration = alchemistModifyVal(target, localDuration, false);
|
||||
|
||||
long leftDuration = (starttime + localDuration) - System.currentTimeMillis();
|
||||
if(leftDuration > 0) {
|
||||
byte[] buff = MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), (int)leftDuration, activeStats);
|
||||
target.getClient().announce(buff);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary) {
|
||||
@@ -1107,11 +1120,7 @@ public class MapleStatEffect {
|
||||
List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.MORPH, Integer.valueOf(getMorph(applyto))));
|
||||
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), stat);
|
||||
}
|
||||
long starttime = System.currentTimeMillis();
|
||||
CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime);
|
||||
ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, localDuration);
|
||||
applyto.registerEffect(this, starttime, schedule);
|
||||
|
||||
|
||||
if (buff != null) {
|
||||
if (!hasNoIcon()) { //Thanks flav for such a simple release! :)
|
||||
applyto.getClient().announce(buff);
|
||||
@@ -1120,6 +1129,12 @@ public class MapleStatEffect {
|
||||
System.out.println("<Error> NO buff icon for id " + sourceid);
|
||||
}
|
||||
}
|
||||
|
||||
long starttime = System.currentTimeMillis();
|
||||
//CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime);
|
||||
//ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, localDuration);
|
||||
applyto.registerEffect(this, starttime, starttime + localDuration, false);
|
||||
|
||||
if (mbuff != null) {
|
||||
applyto.getMap().broadcastMessage(applyto, mbuff, false);
|
||||
}
|
||||
@@ -1511,11 +1526,16 @@ public class MapleStatEffect {
|
||||
public int getSourceId() {
|
||||
return sourceid;
|
||||
}
|
||||
|
||||
public int getBuffSourceId() {
|
||||
return skill ? sourceid : -sourceid;
|
||||
}
|
||||
|
||||
public boolean makeChanceResult() {
|
||||
return prop == 1.0 || Math.random() < prop;
|
||||
}
|
||||
|
||||
/*
|
||||
private static class CancelEffectAction implements Runnable {
|
||||
|
||||
private MapleStatEffect effect;
|
||||
@@ -1536,6 +1556,7 @@ public class MapleStatEffect {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public short getHp() {
|
||||
return hp;
|
||||
|
||||
@@ -35,12 +35,10 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import net.server.Server;
|
||||
import server.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MaplePlayerShopItem;
|
||||
import server.TimerManager;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
@@ -61,7 +59,6 @@ public class HiredMerchant extends AbstractMapleMapObject {
|
||||
private List<Pair<String, Byte>> messages = new LinkedList<>();
|
||||
private List<SoldItem> sold = new LinkedList<>();
|
||||
private boolean open;
|
||||
public ScheduledFuture<?> schedule = null;
|
||||
private MapleMap map;
|
||||
|
||||
public HiredMerchant(final MapleCharacter owner, int itemId, String desc) {
|
||||
@@ -74,14 +71,6 @@ public class HiredMerchant extends AbstractMapleMapObject {
|
||||
this.ownerName = owner.getName();
|
||||
this.description = desc;
|
||||
this.map = owner.getMap();
|
||||
this.schedule = TimerManager.getInstance().schedule(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
HiredMerchant.this.forceClose();
|
||||
Server.getInstance().getChannel(world, channel).removeHiredMerchant(ownerId);
|
||||
}
|
||||
}, 1000 * 60 * 60 * 24);
|
||||
}
|
||||
|
||||
public void broadcastToVisitors(final byte[] packet) {
|
||||
@@ -194,9 +183,8 @@ public class HiredMerchant extends AbstractMapleMapObject {
|
||||
}
|
||||
|
||||
public void forceClose() {
|
||||
if (schedule != null) {
|
||||
schedule.cancel(false);
|
||||
}
|
||||
Server.getInstance().getWorld(world).unregisterHiredMerchant(this);
|
||||
|
||||
try {
|
||||
saveItems(true);
|
||||
items.clear();
|
||||
@@ -226,7 +214,6 @@ public class HiredMerchant extends AbstractMapleMapObject {
|
||||
}
|
||||
|
||||
map = null;
|
||||
schedule = null;
|
||||
}
|
||||
|
||||
public void closeShop(MapleClient c, boolean timeout) {
|
||||
@@ -268,7 +255,8 @@ public class HiredMerchant extends AbstractMapleMapObject {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
schedule.cancel(false);
|
||||
|
||||
Server.getInstance().getWorld(world).unregisterHiredMerchant(this);
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
|
||||
@@ -83,7 +83,6 @@ import client.MapleCharacter.SkillEntry;
|
||||
import client.MapleClient;
|
||||
import client.MapleDisease;
|
||||
import client.MapleFamilyEntry;
|
||||
import client.MapleJob;
|
||||
import client.MapleKeyBinding;
|
||||
import client.MapleMount;
|
||||
import client.MapleQuestStatus;
|
||||
|
||||
Reference in New Issue
Block a user