From 09cfaab4f2dd48bd327257d2bfd0131ff1c1a977 Mon Sep 17 00:00:00 2001 From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com> Date: Sat, 15 Dec 2018 20:42:26 +0000 Subject: [PATCH] Addition of HitAtNight effect. --- .../scripts/handlers/EffectMasterHandler.java | 1 + .../handlers/effecthandlers/HitAtNight.java | 46 +++++++++++++++++++ .../game/data/stats/skills/00200-00299.xml | 2 +- .../game/data/stats/skills/documentation.txt | 1 + .../gameserver/GameTimeController.java | 36 ++++++++++++++- .../gameserver/model/actor/L2Character.java | 1 + .../gameserver/model/stats/Stats.java | 2 + .../stats/finalizers/PAccuracyFinalizer.java | 7 +++ .../scripts/handlers/EffectMasterHandler.java | 1 + .../handlers/effecthandlers/HitAtNight.java | 46 +++++++++++++++++++ .../game/data/stats/skills/00200-00299.xml | 2 +- .../game/data/stats/skills/documentation.txt | 1 + .../gameserver/GameTimeController.java | 36 ++++++++++++++- .../gameserver/model/actor/L2Character.java | 1 + .../gameserver/model/stats/Stats.java | 2 + .../stats/finalizers/PAccuracyFinalizer.java | 7 +++ .../scripts/handlers/EffectMasterHandler.java | 1 + .../handlers/effecthandlers/HitAtNight.java | 46 +++++++++++++++++++ .../game/data/stats/skills/00200-00299.xml | 2 +- .../game/data/stats/skills/documentation.txt | 1 + .../gameserver/GameTimeController.java | 36 ++++++++++++++- .../gameserver/model/actor/L2Character.java | 1 + .../gameserver/model/stats/Stats.java | 2 + .../stats/finalizers/PAccuracyFinalizer.java | 7 +++ .../scripts/handlers/EffectMasterHandler.java | 1 + .../handlers/effecthandlers/HitAtNight.java | 46 +++++++++++++++++++ .../game/data/stats/skills/00200-00299.xml | 2 +- .../game/data/stats/skills/documentation.txt | 1 + .../gameserver/GameTimeController.java | 36 ++++++++++++++- .../gameserver/model/actor/L2Character.java | 1 + .../gameserver/model/stats/Stats.java | 2 + .../stats/finalizers/PAccuracyFinalizer.java | 7 +++ .../scripts/handlers/EffectMasterHandler.java | 1 + .../handlers/effecthandlers/HitAtNight.java | 46 +++++++++++++++++++ .../game/data/stats/skills/00200-00299.xml | 2 +- .../game/data/stats/skills/documentation.txt | 1 + .../gameserver/GameTimeController.java | 36 ++++++++++++++- .../gameserver/model/actor/L2Character.java | 1 + .../gameserver/model/stats/Stats.java | 2 + .../stats/finalizers/PAccuracyFinalizer.java | 7 +++ .../scripts/handlers/EffectMasterHandler.java | 1 + .../handlers/effecthandlers/HitAtNight.java | 46 +++++++++++++++++++ .../game/data/stats/skills/00200-00299.xml | 2 +- .../game/data/stats/skills/documentation.txt | 1 + .../gameserver/GameTimeController.java | 36 ++++++++++++++- .../gameserver/model/actor/L2Character.java | 1 + .../gameserver/model/stats/Stats.java | 2 + .../stats/finalizers/PAccuracyFinalizer.java | 7 +++ .../scripts/handlers/EffectMasterHandler.java | 1 + .../handlers/effecthandlers/HitAtNight.java | 46 +++++++++++++++++++ .../game/data/stats/skills/00200-00299.xml | 2 +- .../game/data/stats/skills/documentation.txt | 1 + .../gameserver/GameTimeController.java | 36 ++++++++++++++- .../gameserver/model/actor/L2Character.java | 1 + .../gameserver/model/stats/Stats.java | 2 + .../stats/finalizers/PAccuracyFinalizer.java | 7 +++ .../scripts/handlers/EffectMasterHandler.java | 1 + .../handlers/effecthandlers/HitAtNight.java | 46 +++++++++++++++++++ .../game/data/stats/skills/00200-00299.xml | 2 +- .../game/data/stats/skills/documentation.txt | 1 + .../gameserver/GameTimeController.java | 36 ++++++++++++++- .../gameserver/model/actor/L2Character.java | 1 + .../gameserver/model/stats/Stats.java | 2 + .../stats/finalizers/PAccuracyFinalizer.java | 7 +++ .../scripts/handlers/EffectMasterHandler.java | 1 + .../handlers/effecthandlers/HitAtNight.java | 46 +++++++++++++++++++ .../game/data/stats/skills/00200-00299.xml | 2 +- .../game/data/stats/skills/documentation.txt | 1 + .../gameserver/GameTimeController.java | 36 ++++++++++++++- .../gameserver/model/actor/L2Character.java | 1 + .../gameserver/model/stats/Stats.java | 2 + .../stats/finalizers/PAccuracyFinalizer.java | 7 +++ .../scripts/handlers/EffectMasterHandler.java | 1 + .../handlers/effecthandlers/HitAtNight.java | 46 +++++++++++++++++++ .../game/data/stats/skills/00200-00299.xml | 2 +- .../game/data/stats/skills/documentation.txt | 1 + .../gameserver/GameTimeController.java | 36 ++++++++++++++- .../gameserver/model/actor/L2Character.java | 1 + .../gameserver/model/stats/Stats.java | 2 + .../stats/finalizers/PAccuracyFinalizer.java | 7 +++ 80 files changed, 940 insertions(+), 20 deletions(-) create mode 100644 L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java create mode 100644 L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java create mode 100644 L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java create mode 100644 L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java create mode 100644 L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java create mode 100644 L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java create mode 100644 L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java create mode 100644 L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java create mode 100644 L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java create mode 100644 L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/EffectMasterHandler.java index 773f6e5940..cc3eb44efa 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -162,6 +162,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("HealOverTime", HealOverTime::new); EffectHandler.getInstance().registerHandler("HealPercent", HealPercent::new); EffectHandler.getInstance().registerHandler("Hide", Hide::new); + EffectHandler.getInstance().registerHandler("HitAtNight", HitAtNight::new); EffectHandler.getInstance().registerHandler("HitNumber", HitNumber::new); EffectHandler.getInstance().registerHandler("Hp", Hp::new); EffectHandler.getInstance().registerHandler("HpByLevel", HpByLevel::new); diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java new file mode 100644 index 0000000000..2f5648e914 --- /dev/null +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.GameTimeController; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Mobius + */ +public class HitAtNight extends AbstractStatEffect +{ + public HitAtNight(StatsSet params) + { + super(params, Stats.HIT_AT_NIGHT); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().addShadowSenseCharacter(effected); + } + + @Override + public void onExit(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().removeShadowSenseCharacter(effected); + } +} diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/skills/00200-00299.xml index 8b74915278..7acbb88190 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/skills/00200-00299.xml @@ -6446,7 +6446,7 @@ P 5 - + 3 DIFF diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/skills/documentation.txt index c4a66a29a4..7cdb106dcd 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/stats/skills/documentation.txt @@ -132,6 +132,7 @@ Heal: Increases current HP by a given amount. HealOverTime: Increases current HP by a given amount over time. HealPercent: Increases current HP by a given percentage amount. Hide: Hide effect. +HitAtNight: Used by Shadow Sense to modify Accuracy at night. (l2jmobius) HitNumber: Polearm attack max hit creatures. HpByLevel: recovers certain amount of HP, but current implementation is wrong... final amount should be computed from skill power and character level difference HpCpHealCritical: HpCp heal effects always trigger Magic Critical Hit. diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/GameTimeController.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/GameTimeController.java index 3a8e1b889c..325fa7bb3b 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/GameTimeController.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/GameTimeController.java @@ -25,6 +25,8 @@ import java.util.logging.Logger; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.events.EventDispatcher; import com.l2jmobius.gameserver.model.events.impl.OnDayNightChange; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * Game Time controller class. @@ -40,10 +42,12 @@ public final class GameTimeController extends Thread public static final int MILLIS_PER_IG_DAY = (3600000 * 24) / IG_DAYS_PER_DAY; public static final int SECONDS_PER_IG_DAY = MILLIS_PER_IG_DAY / 1000; public static final int TICKS_PER_IG_DAY = SECONDS_PER_IG_DAY * TICKS_PER_SECOND; + private final static int SHADOW_SENSE_ID = 294; private static GameTimeController _instance; private final Set _movingObjects = ConcurrentHashMap.newKeySet(); + private final Set _shadowSenseCharacters = ConcurrentHashMap.newKeySet(); private final long _referenceTime; private GameTimeController() @@ -174,12 +178,42 @@ public final class GameTimeController extends Thread if (isNight() != isNight) { isNight = !isNight; - EventDispatcher.getInstance().notifyEventAsync(new OnDayNightChange(isNight)); + notifyShadowSense(); } } } + public synchronized void addShadowSenseCharacter(L2Character character) + { + if (!_shadowSenseCharacters.contains(character)) + { + _shadowSenseCharacters.add(character); + if (isNight()) + { + final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); + msg.addSkillName(SHADOW_SENSE_ID); + character.sendPacket(msg); + } + } + } + + public void removeShadowSenseCharacter(L2Character character) + { + _shadowSenseCharacters.remove(character); + } + + private void notifyShadowSense() + { + final SystemMessage msg = SystemMessage.getSystemMessage(isNight() ? SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT : SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); + msg.addSkillName(SHADOW_SENSE_ID); + for (L2Character character : _shadowSenseCharacters) + { + character.getStat().recalculateStats(true); + character.sendPacket(msg); + } + } + public static GameTimeController getInstance() { return _instance; diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java index ef2757df0a..ff5a9f7136 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -2575,6 +2575,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe case MAGIC_ATTACK: case MAGIC_ATTACK_SPEED: case MAGICAL_DEFENCE: + case HIT_AT_NIGHT: { info.addComponentType(UserInfoType.STATS); break; diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/stats/Stats.java index 097a3f3ee1..7a5d12bb24 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -149,6 +149,8 @@ public enum Stats MAGIC_ATTACK_RANGE("mAtkRange"), ATTACK_COUNT_MAX("atkCountMax"), PHYSICAL_POLEARM_TARGET_SINGLE("polearmSingleTarget"), + HIT_AT_NIGHT("hitAtNight"), + // Run speed, walk & escape speed are calculated proportionally, magic speed is a buff MOVE_SPEED("moveSpeed"), RUN_SPEED("runSpd", new SpeedFinalizer()), diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java index 5a312b3543..94dc8d3e3d 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java @@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.stats.finalizers; import java.util.Optional; +import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.items.L2Item; import com.l2jmobius.gameserver.model.stats.IStatsFunction; @@ -69,6 +70,12 @@ public class PAccuracyFinalizer implements IStatsFunction baseValue += calcEnchantBodyPart(creature, L2Item.SLOT_GLOVES); } + // Shadow sense + if (GameTimeController.getInstance().isNight()) + { + baseValue += creature.getStat().getAdd(Stats.HIT_AT_NIGHT, 0); + } + return Stats.defaultValue(creature, stat, baseValue); } diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/EffectMasterHandler.java index 773f6e5940..cc3eb44efa 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -162,6 +162,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("HealOverTime", HealOverTime::new); EffectHandler.getInstance().registerHandler("HealPercent", HealPercent::new); EffectHandler.getInstance().registerHandler("Hide", Hide::new); + EffectHandler.getInstance().registerHandler("HitAtNight", HitAtNight::new); EffectHandler.getInstance().registerHandler("HitNumber", HitNumber::new); EffectHandler.getInstance().registerHandler("Hp", Hp::new); EffectHandler.getInstance().registerHandler("HpByLevel", HpByLevel::new); diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java new file mode 100644 index 0000000000..2f5648e914 --- /dev/null +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.GameTimeController; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Mobius + */ +public class HitAtNight extends AbstractStatEffect +{ + public HitAtNight(StatsSet params) + { + super(params, Stats.HIT_AT_NIGHT); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().addShadowSenseCharacter(effected); + } + + @Override + public void onExit(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().removeShadowSenseCharacter(effected); + } +} diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_2.5_Underground/dist/game/data/stats/skills/00200-00299.xml index d6f7f796db..fc549fa87c 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_2.5_Underground/dist/game/data/stats/skills/00200-00299.xml @@ -6446,7 +6446,7 @@ P 5 - + 3 DIFF diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_2.5_Underground/dist/game/data/stats/skills/documentation.txt index c4a66a29a4..7cdb106dcd 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_2.5_Underground/dist/game/data/stats/skills/documentation.txt @@ -132,6 +132,7 @@ Heal: Increases current HP by a given amount. HealOverTime: Increases current HP by a given amount over time. HealPercent: Increases current HP by a given percentage amount. Hide: Hide effect. +HitAtNight: Used by Shadow Sense to modify Accuracy at night. (l2jmobius) HitNumber: Polearm attack max hit creatures. HpByLevel: recovers certain amount of HP, but current implementation is wrong... final amount should be computed from skill power and character level difference HpCpHealCritical: HpCp heal effects always trigger Magic Critical Hit. diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/GameTimeController.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/GameTimeController.java index 3a8e1b889c..325fa7bb3b 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/GameTimeController.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/GameTimeController.java @@ -25,6 +25,8 @@ import java.util.logging.Logger; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.events.EventDispatcher; import com.l2jmobius.gameserver.model.events.impl.OnDayNightChange; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * Game Time controller class. @@ -40,10 +42,12 @@ public final class GameTimeController extends Thread public static final int MILLIS_PER_IG_DAY = (3600000 * 24) / IG_DAYS_PER_DAY; public static final int SECONDS_PER_IG_DAY = MILLIS_PER_IG_DAY / 1000; public static final int TICKS_PER_IG_DAY = SECONDS_PER_IG_DAY * TICKS_PER_SECOND; + private final static int SHADOW_SENSE_ID = 294; private static GameTimeController _instance; private final Set _movingObjects = ConcurrentHashMap.newKeySet(); + private final Set _shadowSenseCharacters = ConcurrentHashMap.newKeySet(); private final long _referenceTime; private GameTimeController() @@ -174,12 +178,42 @@ public final class GameTimeController extends Thread if (isNight() != isNight) { isNight = !isNight; - EventDispatcher.getInstance().notifyEventAsync(new OnDayNightChange(isNight)); + notifyShadowSense(); } } } + public synchronized void addShadowSenseCharacter(L2Character character) + { + if (!_shadowSenseCharacters.contains(character)) + { + _shadowSenseCharacters.add(character); + if (isNight()) + { + final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); + msg.addSkillName(SHADOW_SENSE_ID); + character.sendPacket(msg); + } + } + } + + public void removeShadowSenseCharacter(L2Character character) + { + _shadowSenseCharacters.remove(character); + } + + private void notifyShadowSense() + { + final SystemMessage msg = SystemMessage.getSystemMessage(isNight() ? SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT : SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); + msg.addSkillName(SHADOW_SENSE_ID); + for (L2Character character : _shadowSenseCharacters) + { + character.getStat().recalculateStats(true); + character.sendPacket(msg); + } + } + public static GameTimeController getInstance() { return _instance; diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java index ef2757df0a..ff5a9f7136 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -2575,6 +2575,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe case MAGIC_ATTACK: case MAGIC_ATTACK_SPEED: case MAGICAL_DEFENCE: + case HIT_AT_NIGHT: { info.addComponentType(UserInfoType.STATS); break; diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/stats/Stats.java index 097a3f3ee1..7a5d12bb24 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -149,6 +149,8 @@ public enum Stats MAGIC_ATTACK_RANGE("mAtkRange"), ATTACK_COUNT_MAX("atkCountMax"), PHYSICAL_POLEARM_TARGET_SINGLE("polearmSingleTarget"), + HIT_AT_NIGHT("hitAtNight"), + // Run speed, walk & escape speed are calculated proportionally, magic speed is a buff MOVE_SPEED("moveSpeed"), RUN_SPEED("runSpd", new SpeedFinalizer()), diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java index 5a312b3543..94dc8d3e3d 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java @@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.stats.finalizers; import java.util.Optional; +import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.items.L2Item; import com.l2jmobius.gameserver.model.stats.IStatsFunction; @@ -69,6 +70,12 @@ public class PAccuracyFinalizer implements IStatsFunction baseValue += calcEnchantBodyPart(creature, L2Item.SLOT_GLOVES); } + // Shadow sense + if (GameTimeController.getInstance().isNight()) + { + baseValue += creature.getStat().getAdd(Stats.HIT_AT_NIGHT, 0); + } + return Stats.defaultValue(creature, stat, baseValue); } diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/EffectMasterHandler.java index 773f6e5940..cc3eb44efa 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -162,6 +162,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("HealOverTime", HealOverTime::new); EffectHandler.getInstance().registerHandler("HealPercent", HealPercent::new); EffectHandler.getInstance().registerHandler("Hide", Hide::new); + EffectHandler.getInstance().registerHandler("HitAtNight", HitAtNight::new); EffectHandler.getInstance().registerHandler("HitNumber", HitNumber::new); EffectHandler.getInstance().registerHandler("Hp", Hp::new); EffectHandler.getInstance().registerHandler("HpByLevel", HpByLevel::new); diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java new file mode 100644 index 0000000000..2f5648e914 --- /dev/null +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.GameTimeController; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Mobius + */ +public class HitAtNight extends AbstractStatEffect +{ + public HitAtNight(StatsSet params) + { + super(params, Stats.HIT_AT_NIGHT); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().addShadowSenseCharacter(effected); + } + + @Override + public void onExit(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().removeShadowSenseCharacter(effected); + } +} diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_3.0_Helios/dist/game/data/stats/skills/00200-00299.xml index 221f5e85af..09277c64f2 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_3.0_Helios/dist/game/data/stats/skills/00200-00299.xml @@ -6446,7 +6446,7 @@ P 5 - + 3 DIFF diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_3.0_Helios/dist/game/data/stats/skills/documentation.txt index c4a66a29a4..7cdb106dcd 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_3.0_Helios/dist/game/data/stats/skills/documentation.txt @@ -132,6 +132,7 @@ Heal: Increases current HP by a given amount. HealOverTime: Increases current HP by a given amount over time. HealPercent: Increases current HP by a given percentage amount. Hide: Hide effect. +HitAtNight: Used by Shadow Sense to modify Accuracy at night. (l2jmobius) HitNumber: Polearm attack max hit creatures. HpByLevel: recovers certain amount of HP, but current implementation is wrong... final amount should be computed from skill power and character level difference HpCpHealCritical: HpCp heal effects always trigger Magic Critical Hit. diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/GameTimeController.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/GameTimeController.java index 3a8e1b889c..325fa7bb3b 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/GameTimeController.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/GameTimeController.java @@ -25,6 +25,8 @@ import java.util.logging.Logger; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.events.EventDispatcher; import com.l2jmobius.gameserver.model.events.impl.OnDayNightChange; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * Game Time controller class. @@ -40,10 +42,12 @@ public final class GameTimeController extends Thread public static final int MILLIS_PER_IG_DAY = (3600000 * 24) / IG_DAYS_PER_DAY; public static final int SECONDS_PER_IG_DAY = MILLIS_PER_IG_DAY / 1000; public static final int TICKS_PER_IG_DAY = SECONDS_PER_IG_DAY * TICKS_PER_SECOND; + private final static int SHADOW_SENSE_ID = 294; private static GameTimeController _instance; private final Set _movingObjects = ConcurrentHashMap.newKeySet(); + private final Set _shadowSenseCharacters = ConcurrentHashMap.newKeySet(); private final long _referenceTime; private GameTimeController() @@ -174,12 +178,42 @@ public final class GameTimeController extends Thread if (isNight() != isNight) { isNight = !isNight; - EventDispatcher.getInstance().notifyEventAsync(new OnDayNightChange(isNight)); + notifyShadowSense(); } } } + public synchronized void addShadowSenseCharacter(L2Character character) + { + if (!_shadowSenseCharacters.contains(character)) + { + _shadowSenseCharacters.add(character); + if (isNight()) + { + final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); + msg.addSkillName(SHADOW_SENSE_ID); + character.sendPacket(msg); + } + } + } + + public void removeShadowSenseCharacter(L2Character character) + { + _shadowSenseCharacters.remove(character); + } + + private void notifyShadowSense() + { + final SystemMessage msg = SystemMessage.getSystemMessage(isNight() ? SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT : SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); + msg.addSkillName(SHADOW_SENSE_ID); + for (L2Character character : _shadowSenseCharacters) + { + character.getStat().recalculateStats(true); + character.sendPacket(msg); + } + } + public static GameTimeController getInstance() { return _instance; diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java index ef2757df0a..ff5a9f7136 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -2575,6 +2575,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe case MAGIC_ATTACK: case MAGIC_ATTACK_SPEED: case MAGICAL_DEFENCE: + case HIT_AT_NIGHT: { info.addComponentType(UserInfoType.STATS); break; diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/stats/Stats.java index 097a3f3ee1..7a5d12bb24 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -149,6 +149,8 @@ public enum Stats MAGIC_ATTACK_RANGE("mAtkRange"), ATTACK_COUNT_MAX("atkCountMax"), PHYSICAL_POLEARM_TARGET_SINGLE("polearmSingleTarget"), + HIT_AT_NIGHT("hitAtNight"), + // Run speed, walk & escape speed are calculated proportionally, magic speed is a buff MOVE_SPEED("moveSpeed"), RUN_SPEED("runSpd", new SpeedFinalizer()), diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java index 5a312b3543..94dc8d3e3d 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java @@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.stats.finalizers; import java.util.Optional; +import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.items.L2Item; import com.l2jmobius.gameserver.model.stats.IStatsFunction; @@ -69,6 +70,12 @@ public class PAccuracyFinalizer implements IStatsFunction baseValue += calcEnchantBodyPart(creature, L2Item.SLOT_GLOVES); } + // Shadow sense + if (GameTimeController.getInstance().isNight()) + { + baseValue += creature.getStat().getAdd(Stats.HIT_AT_NIGHT, 0); + } + return Stats.defaultValue(creature, stat, baseValue); } diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/EffectMasterHandler.java index 443a2f2b6d..a2a4ef6729 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -166,6 +166,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("HealOverTime", HealOverTime::new); EffectHandler.getInstance().registerHandler("HealPercent", HealPercent::new); EffectHandler.getInstance().registerHandler("Hide", Hide::new); + EffectHandler.getInstance().registerHandler("HitAtNight", HitAtNight::new); EffectHandler.getInstance().registerHandler("HitNumber", HitNumber::new); EffectHandler.getInstance().registerHandler("Hp", Hp::new); EffectHandler.getInstance().registerHandler("HpByLevel", HpByLevel::new); diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java new file mode 100644 index 0000000000..2f5648e914 --- /dev/null +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.GameTimeController; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Mobius + */ +public class HitAtNight extends AbstractStatEffect +{ + public HitAtNight(StatsSet params) + { + super(params, Stats.HIT_AT_NIGHT); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().addShadowSenseCharacter(effected); + } + + @Override + public void onExit(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().removeShadowSenseCharacter(effected); + } +} diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00200-00299.xml index 4a85b1186d..0f9128a21e 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/00200-00299.xml @@ -6474,7 +6474,7 @@ P 5 - + 3 DIFF diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/documentation.txt index 8aa4e9815e..543cc785f5 100644 --- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/stats/skills/documentation.txt @@ -136,6 +136,7 @@ Heal: Increases current HP by a given amount. HealOverTime: Increases current HP by a given amount over time. HealPercent: Increases current HP by a given percentage amount. Hide: Hide effect. +HitAtNight: Used by Shadow Sense to modify Accuracy at night. (l2jmobius) HitNumber: Polearm attack max hit creatures. HpByLevel: recovers certain amount of HP, but current implementation is wrong... final amount should be computed from skill power and character level difference HpCpHealCritical: HpCp heal effects always trigger Magic Critical Hit. diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/GameTimeController.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/GameTimeController.java index 3a8e1b889c..325fa7bb3b 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/GameTimeController.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/GameTimeController.java @@ -25,6 +25,8 @@ import java.util.logging.Logger; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.events.EventDispatcher; import com.l2jmobius.gameserver.model.events.impl.OnDayNightChange; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * Game Time controller class. @@ -40,10 +42,12 @@ public final class GameTimeController extends Thread public static final int MILLIS_PER_IG_DAY = (3600000 * 24) / IG_DAYS_PER_DAY; public static final int SECONDS_PER_IG_DAY = MILLIS_PER_IG_DAY / 1000; public static final int TICKS_PER_IG_DAY = SECONDS_PER_IG_DAY * TICKS_PER_SECOND; + private final static int SHADOW_SENSE_ID = 294; private static GameTimeController _instance; private final Set _movingObjects = ConcurrentHashMap.newKeySet(); + private final Set _shadowSenseCharacters = ConcurrentHashMap.newKeySet(); private final long _referenceTime; private GameTimeController() @@ -174,12 +178,42 @@ public final class GameTimeController extends Thread if (isNight() != isNight) { isNight = !isNight; - EventDispatcher.getInstance().notifyEventAsync(new OnDayNightChange(isNight)); + notifyShadowSense(); } } } + public synchronized void addShadowSenseCharacter(L2Character character) + { + if (!_shadowSenseCharacters.contains(character)) + { + _shadowSenseCharacters.add(character); + if (isNight()) + { + final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); + msg.addSkillName(SHADOW_SENSE_ID); + character.sendPacket(msg); + } + } + } + + public void removeShadowSenseCharacter(L2Character character) + { + _shadowSenseCharacters.remove(character); + } + + private void notifyShadowSense() + { + final SystemMessage msg = SystemMessage.getSystemMessage(isNight() ? SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT : SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); + msg.addSkillName(SHADOW_SENSE_ID); + for (L2Character character : _shadowSenseCharacters) + { + character.getStat().recalculateStats(true); + character.sendPacket(msg); + } + } + public static GameTimeController getInstance() { return _instance; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/L2Character.java index ef2757df0a..ff5a9f7136 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -2575,6 +2575,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe case MAGIC_ATTACK: case MAGIC_ATTACK_SPEED: case MAGICAL_DEFENCE: + case HIT_AT_NIGHT: { info.addComponentType(UserInfoType.STATS); break; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/Stats.java index 37c264621c..8ec09001b8 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -149,6 +149,8 @@ public enum Stats MAGIC_ATTACK_RANGE("mAtkRange"), ATTACK_COUNT_MAX("atkCountMax"), PHYSICAL_POLEARM_TARGET_SINGLE("polearmSingleTarget"), + HIT_AT_NIGHT("hitAtNight"), + // Run speed, walk & escape speed are calculated proportionally, magic speed is a buff MOVE_SPEED("moveSpeed"), RUN_SPEED("runSpd", new SpeedFinalizer()), diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java index 5a312b3543..94dc8d3e3d 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java @@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.stats.finalizers; import java.util.Optional; +import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.items.L2Item; import com.l2jmobius.gameserver.model.stats.IStatsFunction; @@ -69,6 +70,12 @@ public class PAccuracyFinalizer implements IStatsFunction baseValue += calcEnchantBodyPart(creature, L2Item.SLOT_GLOVES); } + // Shadow sense + if (GameTimeController.getInstance().isNight()) + { + baseValue += creature.getStat().getAdd(Stats.HIT_AT_NIGHT, 0); + } + return Stats.defaultValue(creature, stat, baseValue); } diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/EffectMasterHandler.java index e7337fd7bc..d6cf5445b1 100644 --- a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -169,6 +169,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("HealOverTime", HealOverTime::new); EffectHandler.getInstance().registerHandler("HealPercent", HealPercent::new); EffectHandler.getInstance().registerHandler("Hide", Hide::new); + EffectHandler.getInstance().registerHandler("HitAtNight", HitAtNight::new); EffectHandler.getInstance().registerHandler("HitNumber", HitNumber::new); EffectHandler.getInstance().registerHandler("Hp", Hp::new); EffectHandler.getInstance().registerHandler("HpByLevel", HpByLevel::new); diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java new file mode 100644 index 0000000000..2f5648e914 --- /dev/null +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.GameTimeController; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Mobius + */ +public class HitAtNight extends AbstractStatEffect +{ + public HitAtNight(StatsSet params) + { + super(params, Stats.HIT_AT_NIGHT); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().addShadowSenseCharacter(effected); + } + + @Override + public void onExit(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().removeShadowSenseCharacter(effected); + } +} diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_5.0_Salvation/dist/game/data/stats/skills/00200-00299.xml index 4a85b1186d..0f9128a21e 100644 --- a/L2J_Mobius_5.0_Salvation/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/stats/skills/00200-00299.xml @@ -6474,7 +6474,7 @@ P 5 - + 3 DIFF diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_5.0_Salvation/dist/game/data/stats/skills/documentation.txt index 3b07c13bb9..987fb11cd6 100644 --- a/L2J_Mobius_5.0_Salvation/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_5.0_Salvation/dist/game/data/stats/skills/documentation.txt @@ -139,6 +139,7 @@ Heal: Increases current HP by a given amount. HealOverTime: Increases current HP by a given amount over time. HealPercent: Increases current HP by a given percentage amount. Hide: Hide effect. +HitAtNight: Used by Shadow Sense to modify Accuracy at night. (l2jmobius) HitNumber: Polearm attack max hit creatures. HpByLevel: recovers certain amount of HP, but current implementation is wrong... final amount should be computed from skill power and character level difference HpCpHealCritical: HpCp heal effects always trigger Magic Critical Hit. diff --git a/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/GameTimeController.java b/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/GameTimeController.java index 3a8e1b889c..325fa7bb3b 100644 --- a/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/GameTimeController.java +++ b/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/GameTimeController.java @@ -25,6 +25,8 @@ import java.util.logging.Logger; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.events.EventDispatcher; import com.l2jmobius.gameserver.model.events.impl.OnDayNightChange; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * Game Time controller class. @@ -40,10 +42,12 @@ public final class GameTimeController extends Thread public static final int MILLIS_PER_IG_DAY = (3600000 * 24) / IG_DAYS_PER_DAY; public static final int SECONDS_PER_IG_DAY = MILLIS_PER_IG_DAY / 1000; public static final int TICKS_PER_IG_DAY = SECONDS_PER_IG_DAY * TICKS_PER_SECOND; + private final static int SHADOW_SENSE_ID = 294; private static GameTimeController _instance; private final Set _movingObjects = ConcurrentHashMap.newKeySet(); + private final Set _shadowSenseCharacters = ConcurrentHashMap.newKeySet(); private final long _referenceTime; private GameTimeController() @@ -174,12 +178,42 @@ public final class GameTimeController extends Thread if (isNight() != isNight) { isNight = !isNight; - EventDispatcher.getInstance().notifyEventAsync(new OnDayNightChange(isNight)); + notifyShadowSense(); } } } + public synchronized void addShadowSenseCharacter(L2Character character) + { + if (!_shadowSenseCharacters.contains(character)) + { + _shadowSenseCharacters.add(character); + if (isNight()) + { + final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); + msg.addSkillName(SHADOW_SENSE_ID); + character.sendPacket(msg); + } + } + } + + public void removeShadowSenseCharacter(L2Character character) + { + _shadowSenseCharacters.remove(character); + } + + private void notifyShadowSense() + { + final SystemMessage msg = SystemMessage.getSystemMessage(isNight() ? SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT : SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); + msg.addSkillName(SHADOW_SENSE_ID); + for (L2Character character : _shadowSenseCharacters) + { + character.getStat().recalculateStats(true); + character.sendPacket(msg); + } + } + public static GameTimeController getInstance() { return _instance; diff --git a/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/actor/L2Character.java index ef2757df0a..ff5a9f7136 100644 --- a/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -2575,6 +2575,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe case MAGIC_ATTACK: case MAGIC_ATTACK_SPEED: case MAGICAL_DEFENCE: + case HIT_AT_NIGHT: { info.addComponentType(UserInfoType.STATS); break; diff --git a/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/stats/Stats.java index bd106b2849..296836e8aa 100644 --- a/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -149,6 +149,8 @@ public enum Stats MAGIC_ATTACK_RANGE("mAtkRange"), ATTACK_COUNT_MAX("atkCountMax"), PHYSICAL_POLEARM_TARGET_SINGLE("polearmSingleTarget"), + HIT_AT_NIGHT("hitAtNight"), + // Run speed, walk & escape speed are calculated proportionally, magic speed is a buff MOVE_SPEED("moveSpeed"), RUN_SPEED("runSpd", new SpeedFinalizer()), diff --git a/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java b/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java index 5a312b3543..94dc8d3e3d 100644 --- a/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java +++ b/L2J_Mobius_5.0_Salvation/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java @@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.stats.finalizers; import java.util.Optional; +import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.items.L2Item; import com.l2jmobius.gameserver.model.stats.IStatsFunction; @@ -69,6 +70,12 @@ public class PAccuracyFinalizer implements IStatsFunction baseValue += calcEnchantBodyPart(creature, L2Item.SLOT_GLOVES); } + // Shadow sense + if (GameTimeController.getInstance().isNight()) + { + baseValue += creature.getStat().getAdd(Stats.HIT_AT_NIGHT, 0); + } + return Stats.defaultValue(creature, stat, baseValue); } diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/EffectMasterHandler.java index f1cdb32569..9078bed635 100644 --- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -170,6 +170,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("HealOverTime", HealOverTime::new); EffectHandler.getInstance().registerHandler("HealPercent", HealPercent::new); EffectHandler.getInstance().registerHandler("Hide", Hide::new); + EffectHandler.getInstance().registerHandler("HitAtNight", HitAtNight::new); EffectHandler.getInstance().registerHandler("HitNumber", HitNumber::new); EffectHandler.getInstance().registerHandler("Hp", Hp::new); EffectHandler.getInstance().registerHandler("HpByLevel", HpByLevel::new); diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java new file mode 100644 index 0000000000..2f5648e914 --- /dev/null +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.GameTimeController; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Mobius + */ +public class HitAtNight extends AbstractStatEffect +{ + public HitAtNight(StatsSet params) + { + super(params, Stats.HIT_AT_NIGHT); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().addShadowSenseCharacter(effected); + } + + @Override + public void onExit(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().removeShadowSenseCharacter(effected); + } +} diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_5.5_EtinasFate/dist/game/data/stats/skills/00200-00299.xml index 4a85b1186d..0f9128a21e 100644 --- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/stats/skills/00200-00299.xml @@ -6474,7 +6474,7 @@ P 5 - + 3 DIFF diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_5.5_EtinasFate/dist/game/data/stats/skills/documentation.txt index 3c8cab2f8f..8fee471c5c 100644 --- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/stats/skills/documentation.txt @@ -140,6 +140,7 @@ Heal: Increases current HP by a given amount. HealOverTime: Increases current HP by a given amount over time. HealPercent: Increases current HP by a given percentage amount. Hide: Hide effect. +HitAtNight: Used by Shadow Sense to modify Accuracy at night. (l2jmobius) HitNumber: Polearm attack max hit creatures. HpByLevel: recovers certain amount of HP, but current implementation is wrong... final amount should be computed from skill power and character level difference HpCpHealCritical: HpCp heal effects always trigger Magic Critical Hit. diff --git a/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/GameTimeController.java b/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/GameTimeController.java index 3a8e1b889c..325fa7bb3b 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/GameTimeController.java +++ b/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/GameTimeController.java @@ -25,6 +25,8 @@ import java.util.logging.Logger; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.events.EventDispatcher; import com.l2jmobius.gameserver.model.events.impl.OnDayNightChange; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * Game Time controller class. @@ -40,10 +42,12 @@ public final class GameTimeController extends Thread public static final int MILLIS_PER_IG_DAY = (3600000 * 24) / IG_DAYS_PER_DAY; public static final int SECONDS_PER_IG_DAY = MILLIS_PER_IG_DAY / 1000; public static final int TICKS_PER_IG_DAY = SECONDS_PER_IG_DAY * TICKS_PER_SECOND; + private final static int SHADOW_SENSE_ID = 294; private static GameTimeController _instance; private final Set _movingObjects = ConcurrentHashMap.newKeySet(); + private final Set _shadowSenseCharacters = ConcurrentHashMap.newKeySet(); private final long _referenceTime; private GameTimeController() @@ -174,12 +178,42 @@ public final class GameTimeController extends Thread if (isNight() != isNight) { isNight = !isNight; - EventDispatcher.getInstance().notifyEventAsync(new OnDayNightChange(isNight)); + notifyShadowSense(); } } } + public synchronized void addShadowSenseCharacter(L2Character character) + { + if (!_shadowSenseCharacters.contains(character)) + { + _shadowSenseCharacters.add(character); + if (isNight()) + { + final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); + msg.addSkillName(SHADOW_SENSE_ID); + character.sendPacket(msg); + } + } + } + + public void removeShadowSenseCharacter(L2Character character) + { + _shadowSenseCharacters.remove(character); + } + + private void notifyShadowSense() + { + final SystemMessage msg = SystemMessage.getSystemMessage(isNight() ? SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT : SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); + msg.addSkillName(SHADOW_SENSE_ID); + for (L2Character character : _shadowSenseCharacters) + { + character.getStat().recalculateStats(true); + character.sendPacket(msg); + } + } + public static GameTimeController getInstance() { return _instance; diff --git a/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/actor/L2Character.java index ef2757df0a..ff5a9f7136 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -2575,6 +2575,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe case MAGIC_ATTACK: case MAGIC_ATTACK_SPEED: case MAGICAL_DEFENCE: + case HIT_AT_NIGHT: { info.addComponentType(UserInfoType.STATS); break; diff --git a/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/stats/Stats.java index da50188280..5df426e084 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -149,6 +149,8 @@ public enum Stats MAGIC_ATTACK_RANGE("mAtkRange"), ATTACK_COUNT_MAX("atkCountMax"), PHYSICAL_POLEARM_TARGET_SINGLE("polearmSingleTarget"), + HIT_AT_NIGHT("hitAtNight"), + // Run speed, walk & escape speed are calculated proportionally, magic speed is a buff MOVE_SPEED("moveSpeed"), RUN_SPEED("runSpd", new SpeedFinalizer()), diff --git a/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java b/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java index 5a312b3543..94dc8d3e3d 100644 --- a/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java +++ b/L2J_Mobius_5.5_EtinasFate/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java @@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.stats.finalizers; import java.util.Optional; +import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.items.L2Item; import com.l2jmobius.gameserver.model.stats.IStatsFunction; @@ -69,6 +70,12 @@ public class PAccuracyFinalizer implements IStatsFunction baseValue += calcEnchantBodyPart(creature, L2Item.SLOT_GLOVES); } + // Shadow sense + if (GameTimeController.getInstance().isNight()) + { + baseValue += creature.getStat().getAdd(Stats.HIT_AT_NIGHT, 0); + } + return Stats.defaultValue(creature, stat, baseValue); } diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/EffectMasterHandler.java index c5a80cc065..d50a7bd994 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -161,6 +161,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("HealOverTime", HealOverTime::new); EffectHandler.getInstance().registerHandler("HealPercent", HealPercent::new); EffectHandler.getInstance().registerHandler("Hide", Hide::new); + EffectHandler.getInstance().registerHandler("HitAtNight", HitAtNight::new); EffectHandler.getInstance().registerHandler("HitNumber", HitNumber::new); EffectHandler.getInstance().registerHandler("Hp", Hp::new); EffectHandler.getInstance().registerHandler("HpByLevel", HpByLevel::new); diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java new file mode 100644 index 0000000000..2f5648e914 --- /dev/null +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.GameTimeController; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Mobius + */ +public class HitAtNight extends AbstractStatEffect +{ + public HitAtNight(StatsSet params) + { + super(params, Stats.HIT_AT_NIGHT); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().addShadowSenseCharacter(effected); + } + + @Override + public void onExit(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().removeShadowSenseCharacter(effected); + } +} diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/skills/00200-00299.xml index 98cc5f8891..6b5ed2b96f 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/skills/00200-00299.xml @@ -6670,7 +6670,7 @@ P 5 - + 3 DIFF diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/skills/documentation.txt index 995d512e9a..b514f07f33 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/stats/skills/documentation.txt @@ -131,6 +131,7 @@ Heal: Increases current HP by a given amount. HealOverTime: Increases current HP by a given amount over time. HealPercent: Increases current HP by a given percentage amount. Hide: Hide effect. +HitAtNight: Used by Shadow Sense to modify Accuracy at night. (l2jmobius) HitNumber: Polearm attack max hit creatures. HpByLevel: recovers certain amount of HP, but current implementation is wrong... final amount should be computed from skill power and character level difference HpCpHealCritical: HpCp heal effects always trigger Magic Critical Hit. diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/GameTimeController.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/GameTimeController.java index 3a8e1b889c..325fa7bb3b 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/GameTimeController.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/GameTimeController.java @@ -25,6 +25,8 @@ import java.util.logging.Logger; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.events.EventDispatcher; import com.l2jmobius.gameserver.model.events.impl.OnDayNightChange; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * Game Time controller class. @@ -40,10 +42,12 @@ public final class GameTimeController extends Thread public static final int MILLIS_PER_IG_DAY = (3600000 * 24) / IG_DAYS_PER_DAY; public static final int SECONDS_PER_IG_DAY = MILLIS_PER_IG_DAY / 1000; public static final int TICKS_PER_IG_DAY = SECONDS_PER_IG_DAY * TICKS_PER_SECOND; + private final static int SHADOW_SENSE_ID = 294; private static GameTimeController _instance; private final Set _movingObjects = ConcurrentHashMap.newKeySet(); + private final Set _shadowSenseCharacters = ConcurrentHashMap.newKeySet(); private final long _referenceTime; private GameTimeController() @@ -174,12 +178,42 @@ public final class GameTimeController extends Thread if (isNight() != isNight) { isNight = !isNight; - EventDispatcher.getInstance().notifyEventAsync(new OnDayNightChange(isNight)); + notifyShadowSense(); } } } + public synchronized void addShadowSenseCharacter(L2Character character) + { + if (!_shadowSenseCharacters.contains(character)) + { + _shadowSenseCharacters.add(character); + if (isNight()) + { + final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); + msg.addSkillName(SHADOW_SENSE_ID); + character.sendPacket(msg); + } + } + } + + public void removeShadowSenseCharacter(L2Character character) + { + _shadowSenseCharacters.remove(character); + } + + private void notifyShadowSense() + { + final SystemMessage msg = SystemMessage.getSystemMessage(isNight() ? SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT : SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); + msg.addSkillName(SHADOW_SENSE_ID); + for (L2Character character : _shadowSenseCharacters) + { + character.getStat().recalculateStats(true); + character.sendPacket(msg); + } + } + public static GameTimeController getInstance() { return _instance; diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 2f82eee3d7..58becafc19 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -2575,6 +2575,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe case MAGIC_ATTACK: case MAGIC_ATTACK_SPEED: case MAGICAL_DEFENCE: + case HIT_AT_NIGHT: { info.addComponentType(UserInfoType.STATS); break; diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/stats/Stats.java index 116f9e0dde..5f83bc7242 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -149,6 +149,8 @@ public enum Stats MAGIC_ATTACK_RANGE("mAtkRange"), ATTACK_COUNT_MAX("atkCountMax"), PHYSICAL_POLEARM_TARGET_SINGLE("polearmSingleTarget"), + HIT_AT_NIGHT("hitAtNight"), + // Run speed, walk & escape speed are calculated proportionally, magic speed is a buff MOVE_SPEED("moveSpeed"), RUN_SPEED("runSpd", new SpeedFinalizer()), diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java index 5a312b3543..94dc8d3e3d 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java @@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.stats.finalizers; import java.util.Optional; +import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.items.L2Item; import com.l2jmobius.gameserver.model.stats.IStatsFunction; @@ -69,6 +70,12 @@ public class PAccuracyFinalizer implements IStatsFunction baseValue += calcEnchantBodyPart(creature, L2Item.SLOT_GLOVES); } + // Shadow sense + if (GameTimeController.getInstance().isNight()) + { + baseValue += creature.getStat().getAdd(Stats.HIT_AT_NIGHT, 0); + } + return Stats.defaultValue(creature, stat, baseValue); } diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/EffectMasterHandler.java index c5a80cc065..d50a7bd994 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -161,6 +161,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("HealOverTime", HealOverTime::new); EffectHandler.getInstance().registerHandler("HealPercent", HealPercent::new); EffectHandler.getInstance().registerHandler("Hide", Hide::new); + EffectHandler.getInstance().registerHandler("HitAtNight", HitAtNight::new); EffectHandler.getInstance().registerHandler("HitNumber", HitNumber::new); EffectHandler.getInstance().registerHandler("Hp", Hp::new); EffectHandler.getInstance().registerHandler("HpByLevel", HpByLevel::new); diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java new file mode 100644 index 0000000000..2f5648e914 --- /dev/null +++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.GameTimeController; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Mobius + */ +public class HitAtNight extends AbstractStatEffect +{ + public HitAtNight(StatsSet params) + { + super(params, Stats.HIT_AT_NIGHT); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().addShadowSenseCharacter(effected); + } + + @Override + public void onExit(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().removeShadowSenseCharacter(effected); + } +} diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/skills/00200-00299.xml index 98cc5f8891..6b5ed2b96f 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/skills/00200-00299.xml @@ -6670,7 +6670,7 @@ P 5 - + 3 DIFF diff --git a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/skills/documentation.txt index 995d512e9a..b514f07f33 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_Classic_2.1_Zaken/dist/game/data/stats/skills/documentation.txt @@ -131,6 +131,7 @@ Heal: Increases current HP by a given amount. HealOverTime: Increases current HP by a given amount over time. HealPercent: Increases current HP by a given percentage amount. Hide: Hide effect. +HitAtNight: Used by Shadow Sense to modify Accuracy at night. (l2jmobius) HitNumber: Polearm attack max hit creatures. HpByLevel: recovers certain amount of HP, but current implementation is wrong... final amount should be computed from skill power and character level difference HpCpHealCritical: HpCp heal effects always trigger Magic Critical Hit. diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/GameTimeController.java b/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/GameTimeController.java index 3a8e1b889c..325fa7bb3b 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/GameTimeController.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/GameTimeController.java @@ -25,6 +25,8 @@ import java.util.logging.Logger; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.events.EventDispatcher; import com.l2jmobius.gameserver.model.events.impl.OnDayNightChange; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * Game Time controller class. @@ -40,10 +42,12 @@ public final class GameTimeController extends Thread public static final int MILLIS_PER_IG_DAY = (3600000 * 24) / IG_DAYS_PER_DAY; public static final int SECONDS_PER_IG_DAY = MILLIS_PER_IG_DAY / 1000; public static final int TICKS_PER_IG_DAY = SECONDS_PER_IG_DAY * TICKS_PER_SECOND; + private final static int SHADOW_SENSE_ID = 294; private static GameTimeController _instance; private final Set _movingObjects = ConcurrentHashMap.newKeySet(); + private final Set _shadowSenseCharacters = ConcurrentHashMap.newKeySet(); private final long _referenceTime; private GameTimeController() @@ -174,12 +178,42 @@ public final class GameTimeController extends Thread if (isNight() != isNight) { isNight = !isNight; - EventDispatcher.getInstance().notifyEventAsync(new OnDayNightChange(isNight)); + notifyShadowSense(); } } } + public synchronized void addShadowSenseCharacter(L2Character character) + { + if (!_shadowSenseCharacters.contains(character)) + { + _shadowSenseCharacters.add(character); + if (isNight()) + { + final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); + msg.addSkillName(SHADOW_SENSE_ID); + character.sendPacket(msg); + } + } + } + + public void removeShadowSenseCharacter(L2Character character) + { + _shadowSenseCharacters.remove(character); + } + + private void notifyShadowSense() + { + final SystemMessage msg = SystemMessage.getSystemMessage(isNight() ? SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT : SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); + msg.addSkillName(SHADOW_SENSE_ID); + for (L2Character character : _shadowSenseCharacters) + { + character.getStat().recalculateStats(true); + character.sendPacket(msg); + } + } + public static GameTimeController getInstance() { return _instance; diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 2f82eee3d7..58becafc19 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -2575,6 +2575,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe case MAGIC_ATTACK: case MAGIC_ATTACK_SPEED: case MAGICAL_DEFENCE: + case HIT_AT_NIGHT: { info.addComponentType(UserInfoType.STATS); break; diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/stats/Stats.java index 116f9e0dde..5f83bc7242 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -149,6 +149,8 @@ public enum Stats MAGIC_ATTACK_RANGE("mAtkRange"), ATTACK_COUNT_MAX("atkCountMax"), PHYSICAL_POLEARM_TARGET_SINGLE("polearmSingleTarget"), + HIT_AT_NIGHT("hitAtNight"), + // Run speed, walk & escape speed are calculated proportionally, magic speed is a buff MOVE_SPEED("moveSpeed"), RUN_SPEED("runSpd", new SpeedFinalizer()), diff --git a/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java b/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java index 5a312b3543..94dc8d3e3d 100644 --- a/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java +++ b/L2J_Mobius_Classic_2.1_Zaken/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java @@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.stats.finalizers; import java.util.Optional; +import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.items.L2Item; import com.l2jmobius.gameserver.model.stats.IStatsFunction; @@ -69,6 +70,12 @@ public class PAccuracyFinalizer implements IStatsFunction baseValue += calcEnchantBodyPart(creature, L2Item.SLOT_GLOVES); } + // Shadow sense + if (GameTimeController.getInstance().isNight()) + { + baseValue += creature.getStat().getAdd(Stats.HIT_AT_NIGHT, 0); + } + return Stats.defaultValue(creature, stat, baseValue); } diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/EffectMasterHandler.java index cac79b558f..c1fbbe1ec4 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -162,6 +162,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("HealOverTime", HealOverTime::new); EffectHandler.getInstance().registerHandler("HealPercent", HealPercent::new); EffectHandler.getInstance().registerHandler("Hide", Hide::new); + EffectHandler.getInstance().registerHandler("HitAtNight", HitAtNight::new); EffectHandler.getInstance().registerHandler("HitNumber", HitNumber::new); EffectHandler.getInstance().registerHandler("Hp", Hp::new); EffectHandler.getInstance().registerHandler("HpByLevel", HpByLevel::new); diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java new file mode 100644 index 0000000000..2f5648e914 --- /dev/null +++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.GameTimeController; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Mobius + */ +public class HitAtNight extends AbstractStatEffect +{ + public HitAtNight(StatsSet params) + { + super(params, Stats.HIT_AT_NIGHT); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().addShadowSenseCharacter(effected); + } + + @Override + public void onExit(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().removeShadowSenseCharacter(effected); + } +} diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/skills/00200-00299.xml index 92d48d72cb..5e39ec1382 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/skills/00200-00299.xml @@ -7200,7 +7200,7 @@ P 5 - + 3 DIFF diff --git a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/skills/documentation.txt index e9444ba234..8de832a0ad 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_Classic_2.2_Antharas/dist/game/data/stats/skills/documentation.txt @@ -132,6 +132,7 @@ Heal: Increases current HP by a given amount. HealOverTime: Increases current HP by a given amount over time. HealPercent: Increases current HP by a given percentage amount. Hide: Hide effect. +HitAtNight: Used by Shadow Sense to modify Accuracy at night. (l2jmobius) HitNumber: Polearm attack max hit creatures. HpByLevel: recovers certain amount of HP, but current implementation is wrong... final amount should be computed from skill power and character level difference HpCpHealCritical: HpCp heal effects always trigger Magic Critical Hit. diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/GameTimeController.java b/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/GameTimeController.java index 3a8e1b889c..325fa7bb3b 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/GameTimeController.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/GameTimeController.java @@ -25,6 +25,8 @@ import java.util.logging.Logger; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.events.EventDispatcher; import com.l2jmobius.gameserver.model.events.impl.OnDayNightChange; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * Game Time controller class. @@ -40,10 +42,12 @@ public final class GameTimeController extends Thread public static final int MILLIS_PER_IG_DAY = (3600000 * 24) / IG_DAYS_PER_DAY; public static final int SECONDS_PER_IG_DAY = MILLIS_PER_IG_DAY / 1000; public static final int TICKS_PER_IG_DAY = SECONDS_PER_IG_DAY * TICKS_PER_SECOND; + private final static int SHADOW_SENSE_ID = 294; private static GameTimeController _instance; private final Set _movingObjects = ConcurrentHashMap.newKeySet(); + private final Set _shadowSenseCharacters = ConcurrentHashMap.newKeySet(); private final long _referenceTime; private GameTimeController() @@ -174,12 +178,42 @@ public final class GameTimeController extends Thread if (isNight() != isNight) { isNight = !isNight; - EventDispatcher.getInstance().notifyEventAsync(new OnDayNightChange(isNight)); + notifyShadowSense(); } } } + public synchronized void addShadowSenseCharacter(L2Character character) + { + if (!_shadowSenseCharacters.contains(character)) + { + _shadowSenseCharacters.add(character); + if (isNight()) + { + final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); + msg.addSkillName(SHADOW_SENSE_ID); + character.sendPacket(msg); + } + } + } + + public void removeShadowSenseCharacter(L2Character character) + { + _shadowSenseCharacters.remove(character); + } + + private void notifyShadowSense() + { + final SystemMessage msg = SystemMessage.getSystemMessage(isNight() ? SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT : SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); + msg.addSkillName(SHADOW_SENSE_ID); + for (L2Character character : _shadowSenseCharacters) + { + character.getStat().recalculateStats(true); + character.sendPacket(msg); + } + } + public static GameTimeController getInstance() { return _instance; diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 2f82eee3d7..58becafc19 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -2575,6 +2575,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe case MAGIC_ATTACK: case MAGIC_ATTACK_SPEED: case MAGICAL_DEFENCE: + case HIT_AT_NIGHT: { info.addComponentType(UserInfoType.STATS); break; diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/stats/Stats.java index effbbb3be1..8d694bdb83 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -149,6 +149,8 @@ public enum Stats MAGIC_ATTACK_RANGE("mAtkRange"), ATTACK_COUNT_MAX("atkCountMax"), PHYSICAL_POLEARM_TARGET_SINGLE("polearmSingleTarget"), + HIT_AT_NIGHT("hitAtNight"), + // Run speed, walk & escape speed are calculated proportionally, magic speed is a buff MOVE_SPEED("moveSpeed"), RUN_SPEED("runSpd", new SpeedFinalizer()), diff --git a/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java b/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java index 5a312b3543..94dc8d3e3d 100644 --- a/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java +++ b/L2J_Mobius_Classic_2.2_Antharas/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java @@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.stats.finalizers; import java.util.Optional; +import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.items.L2Item; import com.l2jmobius.gameserver.model.stats.IStatsFunction; @@ -69,6 +70,12 @@ public class PAccuracyFinalizer implements IStatsFunction baseValue += calcEnchantBodyPart(creature, L2Item.SLOT_GLOVES); } + // Shadow sense + if (GameTimeController.getInstance().isNight()) + { + baseValue += creature.getStat().getAdd(Stats.HIT_AT_NIGHT, 0); + } + return Stats.defaultValue(creature, stat, baseValue); } diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/EffectMasterHandler.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/EffectMasterHandler.java index e08fa0845a..481455c8b5 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/EffectMasterHandler.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/EffectMasterHandler.java @@ -163,6 +163,7 @@ public final class EffectMasterHandler EffectHandler.getInstance().registerHandler("HealOverTime", HealOverTime::new); EffectHandler.getInstance().registerHandler("HealPercent", HealPercent::new); EffectHandler.getInstance().registerHandler("Hide", Hide::new); + EffectHandler.getInstance().registerHandler("HitAtNight", HitAtNight::new); EffectHandler.getInstance().registerHandler("HitNumber", HitNumber::new); EffectHandler.getInstance().registerHandler("Hp", Hp::new); EffectHandler.getInstance().registerHandler("HpByLevel", HpByLevel::new); diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java new file mode 100644 index 0000000000..2f5648e914 --- /dev/null +++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/scripts/handlers/effecthandlers/HitAtNight.java @@ -0,0 +1,46 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package handlers.effecthandlers; + +import com.l2jmobius.gameserver.GameTimeController; +import com.l2jmobius.gameserver.model.StatsSet; +import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.skills.Skill; +import com.l2jmobius.gameserver.model.stats.Stats; + +/** + * @author Mobius + */ +public class HitAtNight extends AbstractStatEffect +{ + public HitAtNight(StatsSet params) + { + super(params, Stats.HIT_AT_NIGHT); + } + + @Override + public void onStart(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().addShadowSenseCharacter(effected); + } + + @Override + public void onExit(L2Character effector, L2Character effected, Skill skill) + { + GameTimeController.getInstance().removeShadowSenseCharacter(effected); + } +} diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/skills/00200-00299.xml b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/skills/00200-00299.xml index 1974f68a2d..c654f3fbc4 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/skills/00200-00299.xml +++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/skills/00200-00299.xml @@ -7193,7 +7193,7 @@ P 5 - + 3 DIFF diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/skills/documentation.txt b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/skills/documentation.txt index 81d0175133..f873bb26fb 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/skills/documentation.txt +++ b/L2J_Mobius_Classic_2.3_SevenSigns/dist/game/data/stats/skills/documentation.txt @@ -133,6 +133,7 @@ Heal: Increases current HP by a given amount. HealOverTime: Increases current HP by a given amount over time. HealPercent: Increases current HP by a given percentage amount. Hide: Hide effect. +HitAtNight: Used by Shadow Sense to modify Accuracy at night. (l2jmobius) HitNumber: Polearm attack max hit creatures. HpByLevel: recovers certain amount of HP, but current implementation is wrong... final amount should be computed from skill power and character level difference HpCpHealCritical: HpCp heal effects always trigger Magic Critical Hit. diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/GameTimeController.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/GameTimeController.java index 3a8e1b889c..325fa7bb3b 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/GameTimeController.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/GameTimeController.java @@ -25,6 +25,8 @@ import java.util.logging.Logger; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.events.EventDispatcher; import com.l2jmobius.gameserver.model.events.impl.OnDayNightChange; +import com.l2jmobius.gameserver.network.SystemMessageId; +import com.l2jmobius.gameserver.network.serverpackets.SystemMessage; /** * Game Time controller class. @@ -40,10 +42,12 @@ public final class GameTimeController extends Thread public static final int MILLIS_PER_IG_DAY = (3600000 * 24) / IG_DAYS_PER_DAY; public static final int SECONDS_PER_IG_DAY = MILLIS_PER_IG_DAY / 1000; public static final int TICKS_PER_IG_DAY = SECONDS_PER_IG_DAY * TICKS_PER_SECOND; + private final static int SHADOW_SENSE_ID = 294; private static GameTimeController _instance; private final Set _movingObjects = ConcurrentHashMap.newKeySet(); + private final Set _shadowSenseCharacters = ConcurrentHashMap.newKeySet(); private final long _referenceTime; private GameTimeController() @@ -174,12 +178,42 @@ public final class GameTimeController extends Thread if (isNight() != isNight) { isNight = !isNight; - EventDispatcher.getInstance().notifyEventAsync(new OnDayNightChange(isNight)); + notifyShadowSense(); } } } + public synchronized void addShadowSenseCharacter(L2Character character) + { + if (!_shadowSenseCharacters.contains(character)) + { + _shadowSenseCharacters.add(character); + if (isNight()) + { + final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT); + msg.addSkillName(SHADOW_SENSE_ID); + character.sendPacket(msg); + } + } + } + + public void removeShadowSenseCharacter(L2Character character) + { + _shadowSenseCharacters.remove(character); + } + + private void notifyShadowSense() + { + final SystemMessage msg = SystemMessage.getSystemMessage(isNight() ? SystemMessageId.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT : SystemMessageId.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR); + msg.addSkillName(SHADOW_SENSE_ID); + for (L2Character character : _shadowSenseCharacters) + { + character.getStat().recalculateStats(true); + character.sendPacket(msg); + } + } + public static GameTimeController getInstance() { return _instance; diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 2f82eee3d7..58becafc19 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -2575,6 +2575,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe case MAGIC_ATTACK: case MAGIC_ATTACK_SPEED: case MAGICAL_DEFENCE: + case HIT_AT_NIGHT: { info.addComponentType(UserInfoType.STATS); break; diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/stats/Stats.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/stats/Stats.java index f23002e902..00e9b9effa 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/stats/Stats.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/stats/Stats.java @@ -149,6 +149,8 @@ public enum Stats MAGIC_ATTACK_RANGE("mAtkRange"), ATTACK_COUNT_MAX("atkCountMax"), PHYSICAL_POLEARM_TARGET_SINGLE("polearmSingleTarget"), + HIT_AT_NIGHT("hitAtNight"), + // Run speed, walk & escape speed are calculated proportionally, magic speed is a buff MOVE_SPEED("moveSpeed"), RUN_SPEED("runSpd", new SpeedFinalizer()), diff --git a/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java b/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java index 5a312b3543..94dc8d3e3d 100644 --- a/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java +++ b/L2J_Mobius_Classic_2.3_SevenSigns/java/com/l2jmobius/gameserver/model/stats/finalizers/PAccuracyFinalizer.java @@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.stats.finalizers; import java.util.Optional; +import com.l2jmobius.gameserver.GameTimeController; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.items.L2Item; import com.l2jmobius.gameserver.model.stats.IStatsFunction; @@ -69,6 +70,12 @@ public class PAccuracyFinalizer implements IStatsFunction baseValue += calcEnchantBodyPart(creature, L2Item.SLOT_GLOVES); } + // Shadow sense + if (GameTimeController.getInstance().isNight()) + { + baseValue += creature.getStat().getAdd(Stats.HIT_AT_NIGHT, 0); + } + return Stats.defaultValue(creature, stat, baseValue); }