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);
}