Fake players for HighFive.
This commit is contained in:
@@ -112,8 +112,10 @@ public final class Config
|
||||
public static final String CUSTOM_COMMUNITY_BOARD_CONFIG_FILE = "./config/Custom/CommunityBoard.ini";
|
||||
public static final String CUSTOM_DUALBOX_CHECK_CONFIG_FILE = "./config/Custom/DualboxCheck.ini";
|
||||
public static final String CUSTOM_FACTION_SYSTEM_CONFIG_FILE = "./config/Custom/FactionSystem.ini";
|
||||
public static final String CUSTOM_FAKE_PLAYERS_CONFIG_FILE = "./config/Custom/FakePlayers.ini";
|
||||
public static final String CUSTOM_FIND_PVP_CONFIG_FILE = "./config/Custom/FindPvP.ini";
|
||||
public static final String CUSTOM_HELLBOUND_STATUS_CONFIG_FILE = "./config/Custom/HellboundStatus.ini";
|
||||
public static final String CUSTOM_MULTILANGUAL_SUPPORT_CONFIG_FILE = "./config/Custom/MultilingualSupport.ini";
|
||||
public static final String CUSTOM_NPC_STAT_MULTIPIERS_CONFIG_FILE = "./config/Custom/NpcStatMultipliers.ini";
|
||||
public static final String CUSTOM_OFFLINE_TRADE_CONFIG_FILE = "./config/Custom/OfflineTrade.ini";
|
||||
public static final String CUSTOM_PASSWORD_CHANGE_CONFIG_FILE = "./config/Custom/PasswordChange.ini";
|
||||
@@ -131,7 +133,6 @@ public final class Config
|
||||
public static final String CUSTOM_VOTE_REWARD_CONFIG_FILE = "./config/Custom/VoteReward.ini";
|
||||
public static final String CUSTOM_WAREHOUSE_SORTING_CONFIG_FILE = "./config/Custom/WarehouseSorting.ini";
|
||||
public static final String CUSTOM_WEDDING_CONFIG_FILE = "./config/Custom/Wedding.ini";
|
||||
public static final String CUSTOM_MULTILANGUAL_SUPPORT_CONFIG_FILE = "./config/Custom/MultilingualSupport.ini";
|
||||
public static final String CUSTOM_WALKER_BOT_PROTECTION_CONFIG_FILE = "./config/Custom/WalkerBotProtection.ini";
|
||||
|
||||
// --------------------------------------------------
|
||||
@@ -1280,6 +1281,16 @@ public final class Config
|
||||
public static boolean FACTION_SPECIFIC_CHAT;
|
||||
public static boolean FACTION_BALANCE_ONLINE_PLAYERS;
|
||||
public static int FACTION_BALANCE_PLAYER_EXCEED_LIMIT;
|
||||
public static boolean FAKE_PLAYERS_ENABLED;
|
||||
public static boolean FAKE_PLAYER_CHAT;
|
||||
public static boolean FAKE_PLAYER_USE_SHOTS;
|
||||
public static boolean FAKE_PLAYER_KILL_PVP;
|
||||
public static boolean FAKE_PLAYER_KILL_KARMA;
|
||||
public static boolean FAKE_PLAYER_AGGRO_MONSTERS;
|
||||
public static boolean FAKE_PLAYER_AGGRO_PLAYERS;
|
||||
public static boolean FAKE_PLAYER_AGGRO_FPC;
|
||||
public static boolean FAKE_PLAYER_CAN_DROP_ITEMS;
|
||||
public static boolean FAKE_PLAYER_CAN_PICKUP;
|
||||
public static boolean ENABLE_FIND_PVP;
|
||||
public static boolean PREMIUM_SYSTEM_ENABLED;
|
||||
public static float PREMIUM_RATE_XP;
|
||||
@@ -2379,6 +2390,11 @@ public final class Config
|
||||
KARMA_LIST_NONDROPPABLE_ITEMS[i] = Integer.parseInt(karma[i]);
|
||||
}
|
||||
|
||||
ANTIFEED_ENABLE = PVPSettings.getBoolean("AntiFeedEnable", false);
|
||||
ANTIFEED_DUALBOX = PVPSettings.getBoolean("AntiFeedDualbox", true);
|
||||
ANTIFEED_DISCONNECTED_AS_DUALBOX = PVPSettings.getBoolean("AntiFeedDisconnectedAsDualbox", true);
|
||||
ANTIFEED_INTERVAL = PVPSettings.getInt("AntiFeedInterval", 120) * 1000;
|
||||
|
||||
// sorting so binarySearch can be used later
|
||||
Arrays.sort(KARMA_LIST_NONDROPPABLE_PET_ITEMS);
|
||||
Arrays.sort(KARMA_LIST_NONDROPPABLE_ITEMS);
|
||||
@@ -2386,11 +2402,6 @@ public final class Config
|
||||
PVP_NORMAL_TIME = PVPSettings.getInt("PvPVsNormalTime", 120000);
|
||||
PVP_PVP_TIME = PVPSettings.getInt("PvPVsPvPTime", 60000);
|
||||
|
||||
ANTIFEED_ENABLE = PVPSettings.getBoolean("AntiFeedEnable", false);
|
||||
ANTIFEED_DUALBOX = PVPSettings.getBoolean("AntiFeedDualbox", true);
|
||||
ANTIFEED_DISCONNECTED_AS_DUALBOX = PVPSettings.getBoolean("AntiFeedDisconnectedAsDualbox", true);
|
||||
ANTIFEED_INTERVAL = PVPSettings.getInt("AntiFeedInterval", 120) * 1000;
|
||||
|
||||
// Load Olympiad config file (if exists)
|
||||
final PropertiesParser Olympiad = new PropertiesParser(OLYMPIAD_CONFIG_FILE);
|
||||
|
||||
@@ -2766,6 +2777,19 @@ public final class Config
|
||||
FACTION_BALANCE_ONLINE_PLAYERS = FactionSystem.getBoolean("BalanceOnlinePlayers", true);
|
||||
FACTION_BALANCE_PLAYER_EXCEED_LIMIT = FactionSystem.getInt("BalancePlayerExceedLimit", 20);
|
||||
|
||||
// Load FakePlayers config file (if exists)
|
||||
final PropertiesParser FakePlayers = new PropertiesParser(CUSTOM_FAKE_PLAYERS_CONFIG_FILE);
|
||||
FAKE_PLAYERS_ENABLED = Boolean.valueOf(FakePlayers.getBoolean("EnableFakePlayers", false));
|
||||
FAKE_PLAYER_CHAT = Boolean.valueOf(FakePlayers.getBoolean("FakePlayerChat", false));
|
||||
FAKE_PLAYER_USE_SHOTS = Boolean.valueOf(FakePlayers.getBoolean("FakePlayerUseShots", false));
|
||||
FAKE_PLAYER_KILL_PVP = Boolean.valueOf(FakePlayers.getBoolean("FakePlayerKillsRewardPvP", false));
|
||||
FAKE_PLAYER_KILL_KARMA = Boolean.valueOf(FakePlayers.getBoolean("FakePlayerUnflaggedKillsKarma", false));
|
||||
FAKE_PLAYER_AGGRO_MONSTERS = Boolean.valueOf(FakePlayers.getBoolean("FakePlayerAggroMonsters", false));
|
||||
FAKE_PLAYER_AGGRO_PLAYERS = Boolean.valueOf(FakePlayers.getBoolean("FakePlayerAggroPlayers", false));
|
||||
FAKE_PLAYER_AGGRO_FPC = Boolean.valueOf(FakePlayers.getBoolean("FakePlayerAggroFPC", false));
|
||||
FAKE_PLAYER_CAN_DROP_ITEMS = Boolean.valueOf(FakePlayers.getBoolean("FakePlayerCanDropItems", false));
|
||||
FAKE_PLAYER_CAN_PICKUP = Boolean.valueOf(FakePlayers.getBoolean("FakePlayerCanPickup", false));
|
||||
|
||||
// Load FindPvP config file (if exists)
|
||||
final PropertiesParser FindPvP = new PropertiesParser(CUSTOM_FIND_PVP_CONFIG_FILE);
|
||||
|
||||
@@ -2776,6 +2800,43 @@ public final class Config
|
||||
|
||||
HELLBOUND_STATUS = HellboundStatus.getBoolean("HellboundStatus", false);
|
||||
|
||||
// Load MultilingualSupport config file (if exists)
|
||||
final PropertiesParser MultilingualSupport = new PropertiesParser(CUSTOM_MULTILANGUAL_SUPPORT_CONFIG_FILE);
|
||||
|
||||
MULTILANG_DEFAULT = MultilingualSupport.getString("MultiLangDefault", "en");
|
||||
MULTILANG_ENABLE = MultilingualSupport.getBoolean("MultiLangEnable", false);
|
||||
String[] allowed = MultilingualSupport.getString("MultiLangAllowed", MULTILANG_DEFAULT).split(";");
|
||||
MULTILANG_ALLOWED = new ArrayList<>(allowed.length);
|
||||
for (String lang : allowed)
|
||||
{
|
||||
MULTILANG_ALLOWED.add(lang);
|
||||
}
|
||||
if (!MULTILANG_ALLOWED.contains(MULTILANG_DEFAULT))
|
||||
{
|
||||
LOGGER.warning("MultiLang[Config.load()]: default language: " + MULTILANG_DEFAULT + " is not in allowed list !");
|
||||
}
|
||||
MULTILANG_VOICED_ALLOW = MultilingualSupport.getBoolean("MultiLangVoiceCommand", true);
|
||||
MULTILANG_SM_ENABLE = MultilingualSupport.getBoolean("MultiLangSystemMessageEnable", false);
|
||||
allowed = MultilingualSupport.getString("MultiLangSystemMessageAllowed", "").split(";");
|
||||
MULTILANG_SM_ALLOWED = new ArrayList<>(allowed.length);
|
||||
for (String lang : allowed)
|
||||
{
|
||||
if (!lang.isEmpty())
|
||||
{
|
||||
MULTILANG_SM_ALLOWED.add(lang);
|
||||
}
|
||||
}
|
||||
MULTILANG_NS_ENABLE = MultilingualSupport.getBoolean("MultiLangNpcStringEnable", false);
|
||||
allowed = MultilingualSupport.getString("MultiLangNpcStringAllowed", "").split(";");
|
||||
MULTILANG_NS_ALLOWED = new ArrayList<>(allowed.length);
|
||||
for (String lang : allowed)
|
||||
{
|
||||
if (!lang.isEmpty())
|
||||
{
|
||||
MULTILANG_NS_ALLOWED.add(lang);
|
||||
}
|
||||
}
|
||||
|
||||
// Load OfflineTrade config file (if exists)
|
||||
final PropertiesParser OfflineTrade = new PropertiesParser(CUSTOM_OFFLINE_TRADE_CONFIG_FILE);
|
||||
|
||||
@@ -2861,7 +2922,7 @@ public final class Config
|
||||
}
|
||||
}
|
||||
|
||||
// Load CustomSettings config file (if exists)
|
||||
// Load PrivateStoreRange config file (if exists)
|
||||
final PropertiesParser PrivateStoreRange = new PropertiesParser(CUSTOM_PRIVATE_STORE_RANGE_CONFIG_FILE);
|
||||
|
||||
SHOP_MIN_RANGE_FROM_PLAYER = PrivateStoreRange.getInt("ShopMinRangeFromPlayer", 50);
|
||||
@@ -3184,45 +3245,6 @@ public final class Config
|
||||
WEDDING_FORMALWEAR = Wedding.getBoolean("WeddingFormalWear", true);
|
||||
WEDDING_DIVORCE_COSTS = Wedding.getInt("WeddingDivorceCosts", 20);
|
||||
|
||||
// Load MultilingualSupport config file (if exists)
|
||||
final PropertiesParser MultilingualSupport = new PropertiesParser(CUSTOM_MULTILANGUAL_SUPPORT_CONFIG_FILE);
|
||||
|
||||
MULTILANG_DEFAULT = MultilingualSupport.getString("MultiLangDefault", "en");
|
||||
MULTILANG_ENABLE = MultilingualSupport.getBoolean("MultiLangEnable", false);
|
||||
String[] allowed = MultilingualSupport.getString("MultiLangAllowed", MULTILANG_DEFAULT).split(";");
|
||||
MULTILANG_ALLOWED = new ArrayList<>(allowed.length);
|
||||
for (String lang : allowed)
|
||||
{
|
||||
MULTILANG_ALLOWED.add(lang);
|
||||
}
|
||||
|
||||
if (!MULTILANG_ALLOWED.contains(MULTILANG_DEFAULT))
|
||||
{
|
||||
LOGGER.warning("MultiLang[Config.load()]: default language: " + MULTILANG_DEFAULT + " is not in allowed list !");
|
||||
}
|
||||
|
||||
MULTILANG_VOICED_ALLOW = MultilingualSupport.getBoolean("MultiLangVoiceCommand", true);
|
||||
MULTILANG_SM_ENABLE = MultilingualSupport.getBoolean("MultiLangSystemMessageEnable", false);
|
||||
allowed = MultilingualSupport.getString("MultiLangSystemMessageAllowed", "").split(";");
|
||||
MULTILANG_SM_ALLOWED = new ArrayList<>(allowed.length);
|
||||
for (String lang : allowed)
|
||||
{
|
||||
if (!lang.isEmpty())
|
||||
{
|
||||
MULTILANG_SM_ALLOWED.add(lang);
|
||||
}
|
||||
}
|
||||
MULTILANG_NS_ENABLE = MultilingualSupport.getBoolean("MultiLangNpcStringEnable", false);
|
||||
allowed = MultilingualSupport.getString("MultiLangNpcStringAllowed", "").split(";");
|
||||
MULTILANG_NS_ALLOWED = new ArrayList<>(allowed.length);
|
||||
for (String lang : allowed)
|
||||
{
|
||||
if (!lang.isEmpty())
|
||||
{
|
||||
MULTILANG_NS_ALLOWED.add(lang);
|
||||
}
|
||||
}
|
||||
|
||||
// Load VoteReward config file (if exists)
|
||||
final PropertiesParser VoteReward = new PropertiesParser(CUSTOM_VOTE_REWARD_CONFIG_FILE);
|
||||
|
||||
|
@@ -53,6 +53,7 @@ import com.l2jmobius.gameserver.data.xml.impl.EnchantItemHPBonusData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EnchantItemOptionsData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FishData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FishingMonstersData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FishingRodsData;
|
||||
@@ -100,6 +101,7 @@ import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.DayNightSpawnManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.DimensionalRiftManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FishingChampionshipManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortSiegeManager;
|
||||
@@ -269,6 +271,8 @@ public class GameServer
|
||||
DoorData.getInstance();
|
||||
SkillLearnData.getInstance();
|
||||
NpcData.getInstance();
|
||||
FakePlayerData.getInstance();
|
||||
FakePlayerChatManager.getInstance();
|
||||
WalkingManager.getInstance();
|
||||
StaticObjectData.getInstance();
|
||||
ItemAuctionManager.getInstance();
|
||||
|
@@ -30,6 +30,7 @@ import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.interfaces.ILocational;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.AutoAttackStart;
|
||||
@@ -627,6 +628,11 @@ public abstract class AbstractAI implements Ctrl
|
||||
}
|
||||
}
|
||||
|
||||
public void moveTo(ILocational loc)
|
||||
{
|
||||
moveTo(loc.getX(), loc.getY(), loc.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation <I>(broadcast)</I>.<br>
|
||||
* <FONT COLOR=#FF0000><B> <U>Caution</U> : Low level function, used by AI subclasses</B></FONT>
|
||||
|
@@ -34,6 +34,7 @@ import com.l2jmobius.gameserver.enums.AISkillScope;
|
||||
import com.l2jmobius.gameserver.enums.AIType;
|
||||
import com.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
import com.l2jmobius.gameserver.instancemanager.DimensionalRiftManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
@@ -56,6 +57,8 @@ import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.attackable.OnAttackableFactionCall;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.attackable.OnAttackableHate;
|
||||
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.skills.targets.L2TargetType;
|
||||
@@ -489,6 +492,74 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
||||
return;
|
||||
}
|
||||
|
||||
if (npc.isFakePlayer() && npc.isAggressive())
|
||||
{
|
||||
final List<L2ItemInstance> droppedItems = npc.getFakePlayerDrops();
|
||||
if (droppedItems.isEmpty())
|
||||
{
|
||||
L2Character nearestTarget = null;
|
||||
double closestDistance = Double.MAX_VALUE;
|
||||
for (L2Character t : L2World.getInstance().getVisibleObjects(npc, L2Character.class, npc.getAggroRange()))
|
||||
{
|
||||
if ((t == _actor) || (t == null) || t.isDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((Config.FAKE_PLAYER_AGGRO_FPC && t.isFakePlayer()) //
|
||||
|| (Config.FAKE_PLAYER_AGGRO_MONSTERS && t.isMonster() && !t.isFakePlayer()) //
|
||||
|| (Config.FAKE_PLAYER_AGGRO_PLAYERS && t.isPlayer()))
|
||||
{
|
||||
final int hating = npc.getHating(t);
|
||||
final double distance = npc.calculateDistance(t, false, false);
|
||||
if ((hating == 0) && (closestDistance > distance))
|
||||
{
|
||||
nearestTarget = t;
|
||||
closestDistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nearestTarget != null)
|
||||
{
|
||||
npc.addDamageHate(nearestTarget, 0, 1);
|
||||
}
|
||||
}
|
||||
else if (!npc.isInCombat()) // must pickup items
|
||||
{
|
||||
final int itemIndex = npc.getFakePlayerDrops().size() - 1; // last item dropped - can also use 0 for first item dropped
|
||||
final L2ItemInstance droppedItem = npc.getFakePlayerDrops().get(itemIndex);
|
||||
if ((droppedItem != null) && droppedItem.isSpawned())
|
||||
{
|
||||
if (npc.calculateDistance(droppedItem, false, false) > 50)
|
||||
{
|
||||
moveTo(droppedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getFakePlayerDrops().remove(itemIndex);
|
||||
droppedItem.pickupMe(npc);
|
||||
if (Config.SAVE_DROPPED_ITEM)
|
||||
{
|
||||
ItemsOnGroundManager.getInstance().removeObject(droppedItem);
|
||||
}
|
||||
if (droppedItem.getItem().hasExImmediateEffect())
|
||||
{
|
||||
for (SkillHolder skillHolder : droppedItem.getItem().getSkills())
|
||||
{
|
||||
npc.doSimultaneousCast(skillHolder.getSkill());
|
||||
}
|
||||
npc.broadcastInfo(); // ? check if this is necessary
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getFakePlayerDrops().remove(itemIndex);
|
||||
}
|
||||
npc.setRunning();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if this is a festival mob spawn. If it is, then check to see if the aggro trigger is a festival participant...if so, move to attack it.
|
||||
*/
|
||||
@@ -505,6 +576,18 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
||||
// For each L2Character check if the target is autoattackable
|
||||
if (autoAttackCondition(target)) // check aggression
|
||||
{
|
||||
if (target.isFakePlayer())
|
||||
{
|
||||
if (!npc.isFakePlayer() || (npc.isFakePlayer() && Config.FAKE_PLAYER_AGGRO_FPC))
|
||||
{
|
||||
final int hating = npc.getHating(target);
|
||||
if (hating == 0)
|
||||
{
|
||||
npc.addDamageHate(target, 0, 1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (target.isPlayable())
|
||||
{
|
||||
final TerminateReturn term = EventDispatcher.getInstance().notifyEvent(new OnAttackableHate(getActiveChar(), target.getActingPlayer(), target.isSummon()), getActiveChar(), TerminateReturn.class);
|
||||
@@ -752,7 +835,10 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
||||
// Set the AI Intention to AI_INTENTION_ACTIVE
|
||||
setIntention(AI_INTENTION_ACTIVE);
|
||||
|
||||
npc.setWalking();
|
||||
if (!_actor.isFakePlayer())
|
||||
{
|
||||
npc.setWalking();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -42,7 +42,6 @@ import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Playable;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
@@ -859,7 +858,7 @@ public class L2CharacterAI extends AbstractAI
|
||||
// Kill the actor client side by sending Server->Client packet AutoAttackStop, StopMove/StopRotation, Die (broadcast)
|
||||
clientNotifyDead();
|
||||
|
||||
if (!(_actor instanceof L2Playable))
|
||||
if (!_actor.isPlayable() && !_actor.isFakePlayer())
|
||||
{
|
||||
_actor.setWalking();
|
||||
}
|
||||
|
@@ -81,7 +81,7 @@ public abstract class L2PlayableAI extends L2CharacterAI
|
||||
@Override
|
||||
protected void onIntentionCast(Skill skill, L2Object target)
|
||||
{
|
||||
if ((target.isPlayable()) && skill.isBad())
|
||||
if ((target != null) && (target.isPlayable()) && skill.isBad())
|
||||
{
|
||||
if (target.getActingPlayer().isProtectionBlessingAffected() && ((_actor.getActingPlayer().getLevel() - target.getActingPlayer().getLevel()) >= 10) && (_actor.getActingPlayer().getKarma() > 0) && !target.isInsideZone(ZoneId.PVP))
|
||||
{
|
||||
|
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.gameserver.data.xml.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.util.IGameXmlReader;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.holders.FakePlayerHolder;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class FakePlayerData implements IGameXmlReader
|
||||
{
|
||||
private static Logger LOGGER = Logger.getLogger(FakePlayerData.class.getName());
|
||||
|
||||
private final Map<Integer, FakePlayerHolder> _fakePlayerInfos = new HashMap<>();
|
||||
private final Map<String, String> _fakePlayerNames = new HashMap<>();
|
||||
private final Map<String, Integer> _fakePlayerIds = new HashMap<>();
|
||||
private final List<String> _talkableFakePlayerNames = new ArrayList<>();
|
||||
|
||||
protected FakePlayerData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
if (Config.FAKE_PLAYERS_ENABLED)
|
||||
{
|
||||
_fakePlayerInfos.clear();
|
||||
_fakePlayerNames.clear();
|
||||
_fakePlayerIds.clear();
|
||||
_talkableFakePlayerNames.clear();
|
||||
parseDatapackFile("data/FakePlayerVisualData.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fakePlayerInfos.size() + " templates.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.info(getClass().getSimpleName() + ": Disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc, File f)
|
||||
{
|
||||
forEach(doc, "list", listNode -> forEach(listNode, "fakePlayer", fakePlayerNode ->
|
||||
{
|
||||
final StatsSet set = new StatsSet(parseAttributes(fakePlayerNode));
|
||||
final int npcId = set.getInt("npcId");
|
||||
final L2NpcTemplate template = NpcData.getInstance().getTemplate(npcId);
|
||||
final String name = template.getName();
|
||||
if (CharNameTable.getInstance().getIdByName(name) > 0)
|
||||
{
|
||||
LOGGER.info(getClass().getSimpleName() + ": Could not create fake player template " + npcId + ", player name already exists.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_fakePlayerIds.put(name, npcId); // name - npcId
|
||||
_fakePlayerNames.put(name.toLowerCase(), name); // name to lowercase - name
|
||||
_fakePlayerInfos.put(npcId, new FakePlayerHolder(set));
|
||||
if (template.isFakePlayerTalkable())
|
||||
{
|
||||
_talkableFakePlayerNames.add(name.toLowerCase());
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public int getNpcIdByName(String name)
|
||||
{
|
||||
return _fakePlayerIds.get(name);
|
||||
}
|
||||
|
||||
public String getProperName(String name)
|
||||
{
|
||||
return _fakePlayerNames.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
public Boolean isTalkable(String name)
|
||||
{
|
||||
return _talkableFakePlayerNames.contains(name.toLowerCase());
|
||||
}
|
||||
|
||||
public FakePlayerHolder getInfo(int npcId)
|
||||
{
|
||||
return _fakePlayerInfos.get(npcId);
|
||||
}
|
||||
|
||||
public static FakePlayerData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final FakePlayerData _instance = new FakePlayerData();
|
||||
}
|
||||
}
|
@@ -335,6 +335,8 @@ public class NpcData implements IGameXmlReader
|
||||
set.set("passableDoor", parseBoolean(attrs, "passableDoor"));
|
||||
set.set("hasSummoner", parseBoolean(attrs, "hasSummoner"));
|
||||
set.set("canBeSown", parseBoolean(attrs, "canBeSown"));
|
||||
set.set("fakePlayer", parseBoolean(attrs, "fakePlayer"));
|
||||
set.set("fakePlayerTalkable", parseBoolean(attrs, "fakePlayerTalkable"));
|
||||
break;
|
||||
}
|
||||
case "skilllist":
|
||||
|
@@ -41,6 +41,8 @@ import com.l2jmobius.commons.database.DatabaseFactory;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
@@ -215,9 +217,9 @@ public final class BotReportTable
|
||||
return false;
|
||||
}
|
||||
|
||||
final L2PcInstance bot = target.getActingPlayer();
|
||||
final L2Character bot = ((L2Character) target);
|
||||
|
||||
if ((bot == null) || (target.getObjectId() == reporter.getObjectId()))
|
||||
if ((!bot.isPlayer() && !bot.isFakePlayer()) || (bot.isFakePlayer() && !((L2Npc) bot).getTemplate().isFakePlayerTalkable()) || (target.getObjectId() == reporter.getObjectId()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -228,7 +230,7 @@ public final class BotReportTable
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bot.isInOlympiadMode())
|
||||
if (bot.isPlayer() && bot.getActingPlayer().isInOlympiadMode())
|
||||
{
|
||||
reporter.sendPacket(SystemMessageId.THIS_CHARACTER_CANNOT_MAKE_A_REPORT_YOU_CANNOT_MAKE_A_REPORT_WHILE_LOCATED_INSIDE_A_PEACE_ZONE_OR_A_BATTLEFIELD_WHILE_YOU_ARE_AN_OPPOSING_CLAN_MEMBER_DURING_A_CLAN_WAR_OR_WHILE_PARTICIPATING_IN_THE_OLYMPIAD);
|
||||
return false;
|
||||
@@ -240,7 +242,7 @@ public final class BotReportTable
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bot.getExp() == bot.getStat().getStartingExp())
|
||||
if (bot.isPlayer() && (bot.getActingPlayer().getExp() == bot.getActingPlayer().getStat().getStartingExp()))
|
||||
{
|
||||
reporter.sendPacket(SystemMessageId.YOU_CANNOT_REPORT_A_CHARACTER_WHO_HAS_NOT_ACQUIRED_ANY_EXP_AFTER_CONNECTING);
|
||||
return false;
|
||||
@@ -327,7 +329,10 @@ public final class BotReportTable
|
||||
sm.addInt(rcdRep.getPointsLeft());
|
||||
reporter.sendPacket(sm);
|
||||
|
||||
handleReport(bot, rcd);
|
||||
if (bot.isPlayer())
|
||||
{
|
||||
handleReport(bot.getActingPlayer(), rcd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2EventMonsterInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
@@ -200,11 +201,11 @@ public class ItemTable
|
||||
* @param process : String Identifier of process triggering this action
|
||||
* @param itemId : int Item Identifier of the item to be created
|
||||
* @param count : int Quantity of items to be created for stackable items
|
||||
* @param actor : L2PcInstance Player requesting the item creation
|
||||
* @param actor : L2Character requesting the item creation
|
||||
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
|
||||
* @return L2ItemInstance corresponding to the new item
|
||||
*/
|
||||
public L2ItemInstance createItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
|
||||
public L2ItemInstance createItem(String process, int itemId, long count, L2Character actor, Object reference)
|
||||
{
|
||||
// Create and Init the L2ItemInstance corresponding to the Item Identifier
|
||||
final L2ItemInstance item = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
|
||||
|
@@ -89,6 +89,11 @@ public final class SpawnTable implements IGameXmlReader
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Config.FAKE_PLAYERS_ENABLED && npcTemplate.isFakePlayer())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.gameserver.instancemanager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
||||
import com.l2jmobius.commons.util.IGameXmlReader;
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.datatables.SpawnTable;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.FakePlayerChatHolder;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class FakePlayerChatManager implements IGameXmlReader
|
||||
{
|
||||
private static Logger LOGGER = Logger.getLogger(FakePlayerChatManager.class.getName());
|
||||
final List<FakePlayerChatHolder> MESSAGES = new ArrayList<>();
|
||||
private static final int MIN_DELAY = 5000;
|
||||
private static final int MAX_DELAY = 15000;
|
||||
|
||||
protected FakePlayerChatManager()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
if (Config.FAKE_PLAYERS_ENABLED && Config.FAKE_PLAYER_CHAT)
|
||||
{
|
||||
MESSAGES.clear();
|
||||
parseDatapackFile("data/FakePlayerChatData.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + MESSAGES.size() + " chat templates.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.info(getClass().getSimpleName() + ": Disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc, File f)
|
||||
{
|
||||
forEach(doc, "list", listNode -> forEach(listNode, "fakePlayerChat", fakePlayerChatNode ->
|
||||
{
|
||||
final StatsSet set = new StatsSet(parseAttributes(fakePlayerChatNode));
|
||||
MESSAGES.add(new FakePlayerChatHolder(set.getString("fpcName"), set.getString("searchMethod"), set.getString("searchText"), set.getString("answers")));
|
||||
}));
|
||||
}
|
||||
|
||||
public void manageChat(L2PcInstance player, String fpcName, String message)
|
||||
{
|
||||
ThreadPool.schedule(() -> manageResponce(player, fpcName, message), Rnd.get(MIN_DELAY, MAX_DELAY));
|
||||
}
|
||||
|
||||
public void manageChat(L2PcInstance player, String fpcName, String message, int minDelay, int maxDelay)
|
||||
{
|
||||
ThreadPool.schedule(() -> manageResponce(player, fpcName, message), Rnd.get(minDelay, maxDelay));
|
||||
}
|
||||
|
||||
private void manageResponce(L2PcInstance player, String fpcName, String message)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String text = message.toLowerCase();
|
||||
|
||||
// tricky question
|
||||
if (text.contains("can you see me"))
|
||||
{
|
||||
final L2Spawn spawn = SpawnTable.getInstance().getAnySpawn(FakePlayerData.getInstance().getNpcIdByName(fpcName));
|
||||
if (spawn != null)
|
||||
{
|
||||
final L2Npc npc = spawn.getLastSpawn();
|
||||
if (npc != null)
|
||||
{
|
||||
if (npc.calculateDistance(player, false, false) < 3000)
|
||||
{
|
||||
if (GeoEngine.getInstance().canSeeTarget(npc, player) && !player.isInvisible())
|
||||
{
|
||||
sendChat(player, fpcName, Rnd.nextBoolean() ? "i am not blind" : Rnd.nextBoolean() ? "of course i can" : "yes");
|
||||
}
|
||||
else
|
||||
{
|
||||
sendChat(player, fpcName, Rnd.nextBoolean() ? "i know you are around" : Rnd.nextBoolean() ? "not at the moment :P" : "no, where are you?");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendChat(player, fpcName, Rnd.nextBoolean() ? "nope, can't see you" : Rnd.nextBoolean() ? "nope" : "no");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (FakePlayerChatHolder chatHolder : MESSAGES)
|
||||
{
|
||||
if (!chatHolder.getFpcName().equals(fpcName) && !chatHolder.getFpcName().equals("ALL"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (chatHolder.getSearchMethod())
|
||||
{
|
||||
case "EQUALS":
|
||||
{
|
||||
if (text.equals(chatHolder.getSearchText().get(0)))
|
||||
{
|
||||
sendChat(player, fpcName, chatHolder.getAnswers().get(Rnd.get(chatHolder.getAnswers().size())));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "STARTS_WITH":
|
||||
{
|
||||
if (text.startsWith(chatHolder.getSearchText().get(0)))
|
||||
{
|
||||
sendChat(player, fpcName, chatHolder.getAnswers().get(Rnd.get(chatHolder.getAnswers().size())));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CONTAINS":
|
||||
{
|
||||
boolean allFound = true;
|
||||
for (String word : chatHolder.getSearchText())
|
||||
{
|
||||
if (!text.contains(word))
|
||||
{
|
||||
allFound = false;
|
||||
}
|
||||
}
|
||||
if (allFound)
|
||||
{
|
||||
sendChat(player, fpcName, chatHolder.getAnswers().get(Rnd.get(chatHolder.getAnswers().size())));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendChat(L2PcInstance player, String fpcName, String message)
|
||||
{
|
||||
final L2Spawn spawn = SpawnTable.getInstance().getAnySpawn(FakePlayerData.getInstance().getNpcIdByName(fpcName));
|
||||
if (spawn != null)
|
||||
{
|
||||
final L2Npc npc = spawn.getLastSpawn();
|
||||
if (npc != null)
|
||||
{
|
||||
player.sendPacket(new CreatureSay(npc, player, fpcName, ChatType.WHISPER, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static FakePlayerChatManager getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final FakePlayerChatManager _instance = new FakePlayerChatManager();
|
||||
}
|
||||
}
|
@@ -19,6 +19,7 @@ package com.l2jmobius.gameserver.model;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import com.l2jmobius.commons.concurrent.ThreadPool;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||
|
||||
@@ -28,7 +29,7 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
|
||||
public class DropProtection implements Runnable
|
||||
{
|
||||
private volatile boolean _isProtected = false;
|
||||
private L2PcInstance _owner = null;
|
||||
private L2Character _owner = null;
|
||||
private ScheduledFuture<?> _task = null;
|
||||
|
||||
private static final long PROTECTED_MILLIS_TIME = 15000;
|
||||
@@ -46,7 +47,7 @@ public class DropProtection implements Runnable
|
||||
return _isProtected;
|
||||
}
|
||||
|
||||
public L2PcInstance getOwner()
|
||||
public L2Character getOwner()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
@@ -72,12 +73,12 @@ public class DropProtection implements Runnable
|
||||
_task = null;
|
||||
}
|
||||
|
||||
public synchronized void protect(L2PcInstance player)
|
||||
public synchronized void protect(L2Character character)
|
||||
{
|
||||
unprotect();
|
||||
|
||||
_isProtected = true;
|
||||
_owner = player;
|
||||
_owner = character;
|
||||
|
||||
if (_owner == null)
|
||||
{
|
||||
|
@@ -366,6 +366,15 @@ public abstract class L2Object extends ListenersContainer implements IIdentifiab
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if object is a fake player.
|
||||
* @return {@code true} if object is a fake player, {@code false} otherwise
|
||||
*/
|
||||
public boolean isFakePlayer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if object is instance of L2ServitorInstance.
|
||||
* @return {@code true} if object is instance of L2ServitorInstance, {@code false} otherwise
|
||||
|
@@ -62,6 +62,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.npc.attackable.OnAtt
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.attackable.OnAttackableAttack;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.attackable.OnAttackableKill;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
@@ -294,7 +295,7 @@ public class L2Attackable extends L2Npc
|
||||
|
||||
public synchronized boolean getMustRewardExpSP()
|
||||
{
|
||||
return _mustGiveExpSp;
|
||||
return _mustGiveExpSp && !isFakePlayer();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -653,6 +654,12 @@ public class L2Attackable extends L2Npc
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if fake players should aggro each other.
|
||||
if (isFakePlayer() && !Config.FAKE_PLAYER_AGGRO_FPC && attacker.isFakePlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the AggroInfo of the attacker L2Character from the _aggroList of the L2Attackable
|
||||
final AggroInfo ai = _aggroList.computeIfAbsent(attacker, AggroInfo::new);
|
||||
ai.addDamage(damage);
|
||||
@@ -723,7 +730,10 @@ public class L2Attackable extends L2Npc
|
||||
((L2AttackableAI) getAI()).setGlobalAggro(-25);
|
||||
clearAggroList();
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
setWalking();
|
||||
if (!isFakePlayer())
|
||||
{
|
||||
setWalking();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -741,7 +751,10 @@ public class L2Attackable extends L2Npc
|
||||
((L2AttackableAI) getAI()).setGlobalAggro(-25);
|
||||
clearAggroList();
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
setWalking();
|
||||
if (!isFakePlayer())
|
||||
{
|
||||
setWalking();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -936,6 +949,39 @@ public class L2Attackable extends L2Npc
|
||||
// Don't drop anything if the last attacker or owner isn't L2PcInstance
|
||||
if (player == null)
|
||||
{
|
||||
// unless its a fake player and they can drop items
|
||||
if (mainDamageDealer.isFakePlayer() && Config.FAKE_PLAYER_CAN_DROP_ITEMS)
|
||||
{
|
||||
final Collection<ItemHolder> deathItems = npcTemplate.calculateDrops(DropType.DROP, this, mainDamageDealer);
|
||||
if (deathItems != null)
|
||||
{
|
||||
for (ItemHolder drop : deathItems)
|
||||
{
|
||||
final L2Item item = ItemTable.getInstance().getTemplate(drop.getId());
|
||||
// Check if the autoLoot mode is active
|
||||
if (Config.AUTO_LOOT_ITEM_IDS.contains(item.getId()) || isFlying() || (!item.hasExImmediateEffect() && ((!isRaid() && Config.AUTO_LOOT) || (isRaid() && Config.AUTO_LOOT_RAIDS))))
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else if (Config.AUTO_LOOT_HERBS && item.hasExImmediateEffect())
|
||||
{
|
||||
for (SkillHolder skillHolder : item.getSkills())
|
||||
{
|
||||
doSimultaneousCast(skillHolder.getSkill());
|
||||
}
|
||||
mainDamageDealer.broadcastInfo(); // ? check if this is necessary
|
||||
}
|
||||
else
|
||||
{
|
||||
final L2ItemInstance droppedItem = dropItem(mainDamageDealer, drop); // drop the item on the ground
|
||||
if (Config.FAKE_PLAYER_CAN_PICKUP)
|
||||
{
|
||||
mainDamageDealer.getFakePlayerDrops().add(droppedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1023,7 +1069,7 @@ public class L2Attackable extends L2Npc
|
||||
*/
|
||||
public void doEventDrop(L2Character lastAttacker)
|
||||
{
|
||||
if (lastAttacker == null)
|
||||
if ((lastAttacker == null) || isFakePlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1385,12 +1431,29 @@ public class L2Attackable extends L2Npc
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
|
||||
// Clear mob spoil, seed
|
||||
setSpoilerObjectId(0);
|
||||
|
||||
// Clear all aggro char from list
|
||||
clearAggroList();
|
||||
|
||||
// Clear Harvester reward
|
||||
_harvestItem.set(null);
|
||||
|
||||
// fake players
|
||||
if (isFakePlayer())
|
||||
{
|
||||
getFakePlayerDrops().clear(); // Clear existing fake player drops
|
||||
setKarma(0); // reset karma
|
||||
setScriptValue(0); // remove pvp flag
|
||||
setRunning(); // don't walk
|
||||
}
|
||||
else
|
||||
{
|
||||
setWalking();
|
||||
}
|
||||
|
||||
// Clear mod Seeded stat
|
||||
_seeded = false;
|
||||
_seed = null;
|
||||
|
@@ -26,6 +26,7 @@ import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -54,6 +55,7 @@ import com.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.instancemanager.InstanceManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.TerritoryWarManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
@@ -136,6 +138,7 @@ import com.l2jmobius.gameserver.network.serverpackets.Attack;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ChangeMoveType;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ChangeWaitType;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExRotation;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.FakePlayerInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation.FlyType;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillCanceled;
|
||||
@@ -207,6 +210,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
private double _hpUpdateDecCheck = .0;
|
||||
private double _hpUpdateInterval = .0;
|
||||
|
||||
private int _karma = 0;
|
||||
|
||||
/** Table of Calculators containing all used calculator */
|
||||
private Calculator[] _calculators;
|
||||
/** Map containing all skills of this character. */
|
||||
@@ -273,6 +278,9 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
|
||||
private final Map<Integer, Integer> _knownRelations = new ConcurrentHashMap<>();
|
||||
|
||||
/** A list containing the dropped items of this fake player. */
|
||||
private final List<L2ItemInstance> _fakePlayerDrops = new CopyOnWriteArrayList<>();
|
||||
|
||||
/**
|
||||
* Creates a creature.
|
||||
* @param template the creature template
|
||||
@@ -1033,6 +1041,17 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
}
|
||||
}
|
||||
|
||||
if (isFakePlayer() && (target.isPlayable() || target.isFakePlayer()))
|
||||
{
|
||||
final L2Npc npc = ((L2Npc) this);
|
||||
if (!npc.isScriptValue(1))
|
||||
{
|
||||
npc.setScriptValue(1); // in combat
|
||||
broadcastInfo(); // update flag status
|
||||
QuestManager.getInstance().getQuest("PvpFlaggingStopTask").notifyEvent("FLAG_CHECK" + npc.getObjectId(), npc, null);
|
||||
}
|
||||
}
|
||||
|
||||
// Flag the attacker if it's a L2PcInstance outside a PvP area
|
||||
final L2PcInstance player = getActingPlayer();
|
||||
if (player != null)
|
||||
@@ -2818,7 +2837,11 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
return;
|
||||
}
|
||||
|
||||
if (getRunSpeed() == 0)
|
||||
if (isFakePlayer())
|
||||
{
|
||||
player.sendPacket(new FakePlayerInfo((L2Npc) this));
|
||||
}
|
||||
else if (getRunSpeed() == 0)
|
||||
{
|
||||
player.sendPacket(new ServerObjectInfo((L2Npc) this, player));
|
||||
}
|
||||
@@ -3645,7 +3668,11 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
return;
|
||||
}
|
||||
|
||||
if (getRunSpeed() == 0)
|
||||
if (isFakePlayer())
|
||||
{
|
||||
player.sendPacket(new FakePlayerInfo((L2Npc) this));
|
||||
}
|
||||
else if (getRunSpeed() == 0)
|
||||
{
|
||||
player.sendPacket(new ServerObjectInfo((L2Npc) this, player));
|
||||
}
|
||||
@@ -4664,6 +4691,12 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if fake players should aggro each other.
|
||||
if (isFakePlayer() && !Config.FAKE_PLAYER_AGGRO_FPC && target.isFakePlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((isNpc() && target.isAlikeDead()) || target.isDead() || (!isInSurroundingRegion(target) && !isDoor()))
|
||||
{
|
||||
// getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
|
||||
@@ -4976,11 +5009,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
|
||||
public boolean isInsidePeaceZone(L2Object attacker, L2Object target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(target.isPlayable() && attacker.isPlayable()))
|
||||
if ((target == null) || !((target.isPlayable() || target.isFakePlayer()) && attacker.isPlayable()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -5749,6 +5778,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
}
|
||||
}
|
||||
}
|
||||
if (target.isFakePlayer())
|
||||
{
|
||||
player.updatePvPStatus();
|
||||
}
|
||||
}
|
||||
|
||||
// Mobs in range 1000 see spell
|
||||
@@ -5803,6 +5836,20 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
creature.getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, this);
|
||||
}
|
||||
}
|
||||
|
||||
if (isFakePlayer()) // fake player attacks player
|
||||
{
|
||||
if (target.isPlayable() || target.isFakePlayer())
|
||||
{
|
||||
final L2Npc npc = ((L2Npc) this);
|
||||
if (!npc.isScriptValue(1))
|
||||
{
|
||||
npc.setScriptValue(1); // in combat
|
||||
npc.broadcastInfo(); // update flag status
|
||||
QuestManager.getInstance().getQuest("PvpFlaggingStopTask").notifyEvent("FLAG_CHECK" + npc.getObjectId(), npc, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6800,6 +6847,16 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
return _knownRelations;
|
||||
}
|
||||
|
||||
public int getKarma()
|
||||
{
|
||||
return _karma;
|
||||
}
|
||||
|
||||
public void setKarma(int karma)
|
||||
{
|
||||
_karma = karma;
|
||||
}
|
||||
|
||||
public int getMinShopDistance()
|
||||
{
|
||||
return 0;
|
||||
@@ -6809,4 +6866,9 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
{
|
||||
_cursorKeyMovement = value;
|
||||
}
|
||||
|
||||
public List<L2ItemInstance> getFakePlayerDrops()
|
||||
{
|
||||
return _fakePlayerDrops;
|
||||
}
|
||||
}
|
||||
|
@@ -83,18 +83,22 @@ import com.l2jmobius.gameserver.model.items.L2Weapon;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.olympiad.Olympiad;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.stats.Formulas;
|
||||
import com.l2jmobius.gameserver.model.variables.NpcVariables;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2TownZone;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.AbstractNpcInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.FakePlayerInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcSay;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerObjectInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.taskmanager.DecayTaskManager;
|
||||
import com.l2jmobius.gameserver.util.Broadcast;
|
||||
|
||||
@@ -132,6 +136,7 @@ public class L2Npc extends L2Character
|
||||
/** Support for random animation switching */
|
||||
private boolean _isRandomAnimationEnabled = true;
|
||||
private boolean _isTalkable = getTemplate().isTalkable();
|
||||
private final boolean _isFakePlayer = getTemplate().isFakePlayer();
|
||||
|
||||
protected RandomAnimationTask _rAniTask = null;
|
||||
private int _currentLHandId; // normally this shouldn't change from the template, but there exist exceptions
|
||||
@@ -321,7 +326,7 @@ public class L2Npc extends L2Character
|
||||
*/
|
||||
public boolean hasRandomAnimation()
|
||||
{
|
||||
return ((Config.MAX_NPC_ANIMATION > 0) && _isRandomAnimationEnabled && !getAiType().equals(AIType.CORPSE));
|
||||
return ((Config.MAX_NPC_ANIMATION > 0) && isRandomAnimationEnabled() && !getAiType().equals(AIType.CORPSE));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -338,7 +343,7 @@ public class L2Npc extends L2Character
|
||||
*/
|
||||
public boolean isRandomAnimationEnabled()
|
||||
{
|
||||
return _isRandomAnimationEnabled;
|
||||
return !isFakePlayer() && _isRandomAnimationEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -440,7 +445,11 @@ public class L2Npc extends L2Character
|
||||
return;
|
||||
}
|
||||
|
||||
if (getRunSpeed() == 0)
|
||||
if (isFakePlayer())
|
||||
{
|
||||
player.sendPacket(new FakePlayerInfo(this));
|
||||
}
|
||||
else if (getRunSpeed() == 0)
|
||||
{
|
||||
player.sendPacket(new ServerObjectInfo(this, player));
|
||||
}
|
||||
@@ -1239,6 +1248,74 @@ public class L2Npc extends L2Character
|
||||
final L2Weapon weapon = (killer != null) ? killer.getActiveWeaponItem() : null;
|
||||
_killingBlowWeaponId = (weapon != null) ? weapon.getId() : 0;
|
||||
|
||||
if (isFakePlayer() && (killer != null) && killer.isPlayable())
|
||||
{
|
||||
final L2PcInstance player = killer.getActingPlayer();
|
||||
if (isScriptValue(0) && (getKarma() < 0))
|
||||
{
|
||||
if (Config.FAKE_PLAYER_KILL_KARMA)
|
||||
{
|
||||
player.setKarma(player.getKarma() + Formulas.calculateKarmaGain(player.getPkKills(), killer.isSummon()));
|
||||
player.setPkKills(player.getPkKills() + 1);
|
||||
player.broadcastUserInfo();
|
||||
player.checkItemRestriction();
|
||||
// pk item rewards
|
||||
if (Config.REWARD_PK_ITEM)
|
||||
{
|
||||
if (!(Config.DISABLE_REWARDS_IN_INSTANCES && (getInstanceId() != 0)) && //
|
||||
!(Config.DISABLE_REWARDS_IN_PVP_ZONES && isInsideZone(ZoneId.PVP)))
|
||||
{
|
||||
player.addItem("PK Item Reward", Config.REWARD_PK_ITEM_ID, Config.REWARD_PK_ITEM_AMOUNT, this, Config.REWARD_PK_ITEM_MESSAGE);
|
||||
}
|
||||
}
|
||||
// announce pk
|
||||
if (Config.ANNOUNCE_PK_PVP && !player.isGM())
|
||||
{
|
||||
final String msg = Config.ANNOUNCE_PK_MSG.replace("$killer", player.getName()).replace("$target", getName());
|
||||
if (Config.ANNOUNCE_PK_PVP_NORMAL_MESSAGE)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_3);
|
||||
sm.addString(msg);
|
||||
Broadcast.toAllOnlinePlayers(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
Broadcast.toAllOnlinePlayers(msg, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Config.FAKE_PLAYER_KILL_PVP)
|
||||
{
|
||||
player.setPvpKills(player.getPvpKills() + 1);
|
||||
player.broadcastUserInfo();
|
||||
// pvp item rewards
|
||||
if (Config.REWARD_PVP_ITEM)
|
||||
{
|
||||
if (!(Config.DISABLE_REWARDS_IN_INSTANCES && (getInstanceId() != 0)) && //
|
||||
!(Config.DISABLE_REWARDS_IN_PVP_ZONES && isInsideZone(ZoneId.PVP)))
|
||||
{
|
||||
player.addItem("PvP Item Reward", Config.REWARD_PVP_ITEM_ID, Config.REWARD_PVP_ITEM_AMOUNT, this, Config.REWARD_PVP_ITEM_MESSAGE);
|
||||
}
|
||||
}
|
||||
// announce pvp
|
||||
if (Config.ANNOUNCE_PK_PVP && !player.isGM())
|
||||
{
|
||||
final String msg = Config.ANNOUNCE_PVP_MSG.replace("$killer", player.getName()).replace("$target", getName());
|
||||
if (Config.ANNOUNCE_PK_PVP_NORMAL_MESSAGE)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_3);
|
||||
sm.addString(msg);
|
||||
Broadcast.toAllOnlinePlayers(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
Broadcast.toAllOnlinePlayers(msg, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecayTaskManager.getInstance().add(this);
|
||||
return true;
|
||||
}
|
||||
@@ -1456,7 +1533,11 @@ public class L2Npc extends L2Character
|
||||
activeChar.sendMessage("Added NPC: " + getName());
|
||||
}
|
||||
|
||||
if (getRunSpeed() == 0)
|
||||
if (isFakePlayer())
|
||||
{
|
||||
activeChar.sendPacket(new FakePlayerInfo(this));
|
||||
}
|
||||
else if (getRunSpeed() == 0)
|
||||
{
|
||||
activeChar.sendPacket(new ServerObjectInfo(this, activeChar));
|
||||
}
|
||||
@@ -1595,7 +1676,20 @@ public class L2Npc extends L2Character
|
||||
@Override
|
||||
public void rechargeShots(boolean physical, boolean magic)
|
||||
{
|
||||
if ((_soulshotamount > 0) || (_spiritshotamount > 0))
|
||||
if (isFakePlayer() && Config.FAKE_PLAYER_USE_SHOTS)
|
||||
{
|
||||
if (physical)
|
||||
{
|
||||
Broadcast.toSelfAndKnownPlayersInRadius(this, new MagicSkillUse(this, this, 2154, 1, 0, 0), 600);
|
||||
setChargedShot(ShotType.SOULSHOTS, true);
|
||||
}
|
||||
if (magic)
|
||||
{
|
||||
Broadcast.toSelfAndKnownPlayersInRadius(this, new MagicSkillUse(this, this, 2061, 1, 0, 0), 600);
|
||||
setChargedShot(ShotType.SPIRITSHOTS, true);
|
||||
}
|
||||
}
|
||||
else if ((_soulshotamount > 0) || (_spiritshotamount > 0))
|
||||
{
|
||||
if (physical)
|
||||
{
|
||||
@@ -1757,12 +1851,12 @@ public class L2Npc extends L2Character
|
||||
|
||||
/**
|
||||
* Drops an item.
|
||||
* @param player the last attacker or main damage dealer
|
||||
* @param character the last attacker or main damage dealer
|
||||
* @param itemId the item ID
|
||||
* @param itemCount the item count
|
||||
* @return the dropped item
|
||||
*/
|
||||
public L2ItemInstance dropItem(L2PcInstance player, int itemId, long itemCount)
|
||||
public L2ItemInstance dropItem(L2Character character, int itemId, long itemCount)
|
||||
{
|
||||
L2ItemInstance item = null;
|
||||
for (int i = 0; i < itemCount; i++)
|
||||
@@ -1778,15 +1872,15 @@ public class L2Npc extends L2Character
|
||||
return null;
|
||||
}
|
||||
|
||||
item = ItemTable.getInstance().createItem("Loot", itemId, itemCount, player, this);
|
||||
item = ItemTable.getInstance().createItem("Loot", itemId, itemCount, character, this);
|
||||
if (item == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (player != null)
|
||||
if (character != null)
|
||||
{
|
||||
item.getDropProtection().protect(player);
|
||||
item.getDropProtection().protect(character);
|
||||
}
|
||||
|
||||
item.dropMe(this, newX, newY, newZ);
|
||||
@@ -1811,14 +1905,14 @@ public class L2Npc extends L2Character
|
||||
}
|
||||
|
||||
/**
|
||||
* Method overload for {@link L2Attackable#dropItem(L2PcInstance, int, long)}
|
||||
* @param player the last attacker or main damage dealer
|
||||
* Method overload for {@link L2Attackable#dropItem(L2Character, int, long)}
|
||||
* @param character the last attacker or main damage dealer
|
||||
* @param item the item holder
|
||||
* @return the dropped item
|
||||
*/
|
||||
public L2ItemInstance dropItem(L2PcInstance player, ItemHolder item)
|
||||
public L2ItemInstance dropItem(L2Character character, ItemHolder item)
|
||||
{
|
||||
return dropItem(player, item.getId(), item.getCount());
|
||||
return dropItem(character, item.getId(), item.getCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1876,6 +1970,12 @@ public class L2Npc extends L2Character
|
||||
return _killingBlowWeaponId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFakePlayer()
|
||||
{
|
||||
return _isFakePlayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a summoned NPC.
|
||||
* @param npc the summoned NPC
|
||||
|
@@ -319,8 +319,6 @@ public abstract class L2Playable extends L2Character
|
||||
|
||||
public abstract void doPickupItem(L2Object object);
|
||||
|
||||
public abstract int getKarma();
|
||||
|
||||
public abstract byte getPvpFlag();
|
||||
|
||||
public abstract boolean useMagic(Skill skill, boolean forceUse, boolean dontMove);
|
||||
|
@@ -951,6 +951,10 @@ public abstract class L2Summon extends L2Playable
|
||||
{
|
||||
setTarget(target);
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
if (target.isFakePlayer())
|
||||
{
|
||||
getOwner().updatePvPStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -44,13 +44,10 @@ public class L2GuardInstance extends L2Attackable
|
||||
setInstanceType(InstanceType.L2GuardInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True if hte attacker is a L2MonsterInstance.
|
||||
*/
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
if (attacker.isMonster())
|
||||
if (attacker.isMonster() && !attacker.isFakePlayer())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -148,6 +145,13 @@ public class L2GuardInstance extends L2Attackable
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
|
||||
}
|
||||
|
||||
if (isFakePlayer() && isInCombat())
|
||||
{
|
||||
interact = false;
|
||||
// TODO: Fix normal targeting
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
|
||||
}
|
||||
|
||||
// Check if the L2PcInstance already target the L2GuardInstance
|
||||
if (getObjectId() != player.getTargetId())
|
||||
{
|
||||
|
@@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
@@ -60,6 +61,28 @@ public class L2MonsterInstance extends L2Attackable
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
if (isFakePlayer())
|
||||
{
|
||||
return isInCombat() || attacker.isMonster() || (getScriptValue() > 0);
|
||||
}
|
||||
|
||||
// Check if the L2MonsterInstance target is aggressive
|
||||
if (Config.GUARD_ATTACK_AGGRO_MOB && isAggressive() && (attacker instanceof L2GuardInstance))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (attacker.isMonster())
|
||||
{
|
||||
return attacker.isFakePlayer();
|
||||
}
|
||||
|
||||
// Anything considers monsters friendly except Players, Attackables (Guards, Friendly NPC), Traps and EffectPoints.
|
||||
if (!attacker.isPlayable() && !attacker.isAttackable() && !(attacker instanceof L2TrapInstance) && !(attacker instanceof L2EffectPointInstance))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.isAutoAttackable(attacker) && !isEventMob();
|
||||
}
|
||||
|
||||
|
@@ -443,9 +443,6 @@ public final class L2PcInstance extends L2Playable
|
||||
/** The Experience of the L2PcInstance before the last Death Penalty */
|
||||
private long _expBeforeDeath;
|
||||
|
||||
/** The Karma of the L2PcInstance (if higher than 0, the name of the L2PcInstance appears in red) */
|
||||
private int _karma;
|
||||
|
||||
/** The number of player killed during a PvP (the player killed was PvP Flagged) */
|
||||
private int _pvpKills;
|
||||
|
||||
@@ -1923,19 +1920,11 @@ public final class L2PcInstance extends L2Playable
|
||||
return _expBeforeDeath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Karma of the L2PcInstance.
|
||||
*/
|
||||
@Override
|
||||
public int getKarma()
|
||||
{
|
||||
return _karma;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Karma of the L2PcInstance and send a Server->Client packet StatusUpdate (broadcast).
|
||||
* @param karma
|
||||
*/
|
||||
@Override
|
||||
public void setKarma(int karma)
|
||||
{
|
||||
// Notify to scripts.
|
||||
@@ -1945,7 +1934,7 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
karma = 0;
|
||||
}
|
||||
if ((_karma == 0) && (karma > 0))
|
||||
if ((getKarma() == 0) && (karma > 0))
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObject(this, L2GuardInstance.class, object ->
|
||||
{
|
||||
@@ -1955,13 +1944,13 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
});
|
||||
}
|
||||
else if ((_karma > 0) && (karma == 0))
|
||||
else if ((getKarma() > 0) && (karma == 0))
|
||||
{
|
||||
// Send a Server->Client StatusUpdate packet with Karma and PvP Flag to the L2PcInstance and all L2PcInstance to inform (broadcast)
|
||||
setKarmaFlag(0);
|
||||
}
|
||||
|
||||
_karma = karma;
|
||||
super.setKarma(karma);
|
||||
broadcastKarma();
|
||||
}
|
||||
|
||||
@@ -4520,6 +4509,10 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
super.doAttack(target);
|
||||
setRecentFakeDeath(false);
|
||||
if (target.isFakePlayer())
|
||||
{
|
||||
updatePvPStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -5041,40 +5034,44 @@ public final class L2PcInstance extends L2Playable
|
||||
if (killer != null)
|
||||
{
|
||||
final L2PcInstance pk = killer.getActingPlayer();
|
||||
if (pk != null)
|
||||
final boolean fpcKill = killer.isFakePlayer();
|
||||
if ((pk != null) || fpcKill)
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerPvPKill(pk, this), this);
|
||||
|
||||
TvTEvent.onKill(killer, this);
|
||||
|
||||
if (L2Event.isParticipant(pk))
|
||||
if (pk != null)
|
||||
{
|
||||
pk.getEventStatus().getKills().add(this);
|
||||
}
|
||||
|
||||
// pvp/pk item rewards
|
||||
if (!(Config.DISABLE_REWARDS_IN_INSTANCES && (getInstanceId() != 0)) && //
|
||||
!(Config.DISABLE_REWARDS_IN_PVP_ZONES && isInsideZone(ZoneId.PVP)))
|
||||
{
|
||||
// pvp
|
||||
if (Config.REWARD_PVP_ITEM && (getPvpFlag() != 0))
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerPvPKill(pk, this), this);
|
||||
|
||||
TvTEvent.onKill(killer, this);
|
||||
|
||||
if (L2Event.isParticipant(pk))
|
||||
{
|
||||
pk.addItem("PvP Item Reward", Config.REWARD_PVP_ITEM_ID, Config.REWARD_PVP_ITEM_AMOUNT, this, Config.REWARD_PVP_ITEM_MESSAGE);
|
||||
pk.getEventStatus().getKills().add(this);
|
||||
}
|
||||
// pk
|
||||
if (Config.REWARD_PK_ITEM && (getPvpFlag() == 0))
|
||||
|
||||
// pvp/pk item rewards
|
||||
if (!(Config.DISABLE_REWARDS_IN_INSTANCES && (getInstanceId() != 0)) && //
|
||||
!(Config.DISABLE_REWARDS_IN_PVP_ZONES && isInsideZone(ZoneId.PVP)))
|
||||
{
|
||||
pk.addItem("PK Item Reward", Config.REWARD_PK_ITEM_ID, Config.REWARD_PK_ITEM_AMOUNT, this, Config.REWARD_PK_ITEM_MESSAGE);
|
||||
// pvp
|
||||
if (Config.REWARD_PVP_ITEM && (getPvpFlag() != 0))
|
||||
{
|
||||
pk.addItem("PvP Item Reward", Config.REWARD_PVP_ITEM_ID, Config.REWARD_PVP_ITEM_AMOUNT, this, Config.REWARD_PVP_ITEM_MESSAGE);
|
||||
}
|
||||
// pk
|
||||
if (Config.REWARD_PK_ITEM && (getPvpFlag() == 0))
|
||||
{
|
||||
pk.addItem("PK Item Reward", Config.REWARD_PK_ITEM_ID, Config.REWARD_PK_ITEM_AMOUNT, this, Config.REWARD_PK_ITEM_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// announce pvp/pk
|
||||
if (Config.ANNOUNCE_PK_PVP && !pk.isGM())
|
||||
if (Config.ANNOUNCE_PK_PVP && (((pk != null) && !pk.isGM()) || fpcKill))
|
||||
{
|
||||
String msg = "";
|
||||
if (getPvpFlag() == 0)
|
||||
{
|
||||
msg = Config.ANNOUNCE_PK_MSG.replace("$killer", pk.getName()).replace("$target", getName());
|
||||
msg = Config.ANNOUNCE_PK_MSG.replace("$killer", killer.getName()).replace("$target", getName());
|
||||
if (Config.ANNOUNCE_PK_PVP_NORMAL_MESSAGE)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1);
|
||||
@@ -5088,7 +5085,7 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
else if (getPvpFlag() != 0)
|
||||
{
|
||||
msg = Config.ANNOUNCE_PVP_MSG.replace("$killer", pk.getName()).replace("$target", getName());
|
||||
msg = Config.ANNOUNCE_PVP_MSG.replace("$killer", killer.getName()).replace("$target", getName());
|
||||
if (Config.ANNOUNCE_PK_PVP_NORMAL_MESSAGE)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1);
|
||||
@@ -5102,6 +5099,11 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
}
|
||||
|
||||
if (fpcKill && Config.FAKE_PLAYER_KILL_KARMA && (getPvpFlag() == 0) && (getKarma() <= 0))
|
||||
{
|
||||
killer.setKarma(killer.getKarma() + 150);
|
||||
killer.broadcastInfo();
|
||||
}
|
||||
}
|
||||
|
||||
broadcastStatusUpdate();
|
||||
|
@@ -247,6 +247,7 @@ public final class L2TrapInstance extends L2Npc
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getKarma()
|
||||
{
|
||||
return _owner != null ? _owner.getKarma() : 0;
|
||||
|
@@ -22,7 +22,6 @@ import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.instancemanager.DuelManager;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Playable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.stat.PcStat;
|
||||
@@ -189,7 +188,7 @@ public class PcStatus extends PlayableStatus
|
||||
}
|
||||
}
|
||||
|
||||
if ((attacker instanceof L2Playable) && (caster.getCurrentCp() > 0))
|
||||
if ((attacker.isPlayable() || attacker.isFakePlayer()) && (caster.getCurrentCp() > 0))
|
||||
{
|
||||
if (caster.getCurrentCp() > transferDmg)
|
||||
{
|
||||
@@ -211,7 +210,7 @@ public class PcStatus extends PlayableStatus
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreCP && (attacker instanceof L2Playable))
|
||||
if (!ignoreCP && (attacker.isPlayable() || attacker.isFakePlayer()))
|
||||
{
|
||||
if (getCurrentCp() >= value)
|
||||
{
|
||||
|
@@ -74,6 +74,8 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
||||
private boolean _undying;
|
||||
private boolean _showName;
|
||||
private boolean _flying;
|
||||
private boolean _fakePlayer;
|
||||
private boolean _fakePlayerTalkable;
|
||||
private boolean _canMove;
|
||||
private boolean _noSleepMode;
|
||||
private boolean _passableDoor;
|
||||
@@ -143,6 +145,8 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
||||
_undying = set.getBoolean("undying", true);
|
||||
_showName = set.getBoolean("showName", true);
|
||||
_flying = set.getBoolean("flying", false);
|
||||
_fakePlayer = set.getBoolean("fakePlayer", false);
|
||||
_fakePlayerTalkable = set.getBoolean("fakePlayerTalkable", true);
|
||||
_canMove = set.getBoolean("canMove", true);
|
||||
_noSleepMode = set.getBoolean("noSleepMode", false);
|
||||
_passableDoor = set.getBoolean("passableDoor", false);
|
||||
@@ -368,6 +372,16 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
||||
return _flying;
|
||||
}
|
||||
|
||||
public boolean isFakePlayer()
|
||||
{
|
||||
return _fakePlayer;
|
||||
}
|
||||
|
||||
public boolean isFakePlayerTalkable()
|
||||
{
|
||||
return _fakePlayerTalkable;
|
||||
}
|
||||
|
||||
public boolean canMove()
|
||||
{
|
||||
return _canMove;
|
||||
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.events.impl.item;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.events.EventType;
|
||||
import com.l2jmobius.gameserver.model.events.impl.IBaseEvent;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
@@ -28,10 +28,10 @@ public class OnItemCreate implements IBaseEvent
|
||||
{
|
||||
private final String _process;
|
||||
private final L2ItemInstance _item;
|
||||
private final L2PcInstance _activeChar;
|
||||
private final L2Character _activeChar;
|
||||
private final Object _reference;
|
||||
|
||||
public OnItemCreate(String process, L2ItemInstance item, L2PcInstance actor, Object reference)
|
||||
public OnItemCreate(String process, L2ItemInstance item, L2Character actor, Object reference)
|
||||
{
|
||||
_process = process;
|
||||
_item = item;
|
||||
@@ -49,7 +49,7 @@ public class OnItemCreate implements IBaseEvent
|
||||
return _item;
|
||||
}
|
||||
|
||||
public L2PcInstance getActiveChar()
|
||||
public L2Character getActiveChar()
|
||||
{
|
||||
return _activeChar;
|
||||
}
|
||||
|
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.holders;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class FakePlayerChatHolder
|
||||
{
|
||||
private final String _fpcName;
|
||||
private final String _searchMethod;
|
||||
private final List<String> _searchText;
|
||||
private final List<String> _answers;
|
||||
|
||||
public FakePlayerChatHolder(String fpcName, String searchMethod, String searchText, String answers)
|
||||
{
|
||||
_fpcName = fpcName;
|
||||
_searchMethod = searchMethod;
|
||||
_searchText = new ArrayList<>(Arrays.asList(searchText.split(";")));
|
||||
_answers = new ArrayList<>(Arrays.asList(answers.split(";")));
|
||||
}
|
||||
|
||||
public String getFpcName()
|
||||
{
|
||||
return _fpcName;
|
||||
}
|
||||
|
||||
public String getSearchMethod()
|
||||
{
|
||||
return _searchMethod;
|
||||
}
|
||||
|
||||
public List<String> getSearchText()
|
||||
{
|
||||
return _searchText;
|
||||
}
|
||||
|
||||
public List<String> getAnswers()
|
||||
{
|
||||
return _answers;
|
||||
}
|
||||
}
|
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.gameserver.model.holders;
|
||||
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class FakePlayerHolder
|
||||
{
|
||||
private final int _classId;
|
||||
private final int _hair;
|
||||
private final int _hairColor;
|
||||
private final int _face;
|
||||
private final int _nameColor;
|
||||
private final int _titleColor;
|
||||
private final int _equipHead;
|
||||
private final int _equipRHand;
|
||||
private final int _equipLHand;
|
||||
private final int _equipGloves;
|
||||
private final int _equipChest;
|
||||
private final int _equipLegs;
|
||||
private final int _equipFeet;
|
||||
private final int _equipCloak;
|
||||
private final int _equipHair;
|
||||
private final int _equipHair2;
|
||||
private final int _agathionId;
|
||||
private final int _weaponEnchantLevel;
|
||||
private final int _armorEnchantLevel;
|
||||
private final boolean _fishing;
|
||||
private final int _baitLocationX;
|
||||
private final int _baitLocationY;
|
||||
private final int _baitLocationZ;
|
||||
private final int _recommends;
|
||||
private final int _nobleLevel;
|
||||
private final boolean _hero;
|
||||
private final int _clanId;
|
||||
private final int _pledgeStatus;
|
||||
|
||||
public FakePlayerHolder(StatsSet set)
|
||||
{
|
||||
_classId = set.getInt("classId", 182);
|
||||
|
||||
_hair = set.getInt("hair", 1);
|
||||
_hairColor = set.getInt("hairColor", 1);
|
||||
_face = set.getInt("face", 1);
|
||||
|
||||
_nameColor = set.getInt("nameColor", 0xFFFFFF);
|
||||
_titleColor = set.getInt("titleColor", 0xECF9A2);
|
||||
|
||||
_equipHead = set.getInt("equipHead", 0);
|
||||
_equipRHand = set.getInt("equipRHand", 0); // or dual hand
|
||||
_equipLHand = set.getInt("equipLHand", 0);
|
||||
_equipGloves = set.getInt("equipGloves", 0);
|
||||
_equipChest = set.getInt("equipChest", 0);
|
||||
_equipLegs = set.getInt("equipLegs", 0);
|
||||
_equipFeet = set.getInt("equipFeet", 0);
|
||||
_equipCloak = set.getInt("equipCloak", 0);
|
||||
_equipHair = set.getInt("equipHair", 0);
|
||||
_equipHair2 = set.getInt("equipHair2", 0);
|
||||
_agathionId = set.getInt("agathionId", 0);
|
||||
|
||||
_weaponEnchantLevel = set.getInt("weaponEnchantLevel", 0);
|
||||
_armorEnchantLevel = set.getInt("armorEnchantLevel", 0);
|
||||
|
||||
_fishing = set.getBoolean("fishing", false);
|
||||
_baitLocationX = set.getInt("baitLocationX", 0);
|
||||
_baitLocationY = set.getInt("baitLocationY", 0);
|
||||
_baitLocationZ = set.getInt("baitLocationZ", 0);
|
||||
|
||||
_recommends = set.getInt("recommends", 0);
|
||||
_nobleLevel = set.getInt("nobleLevel", 0);
|
||||
_hero = set.getBoolean("hero", false);
|
||||
_clanId = set.getInt("clanId", 0);
|
||||
_pledgeStatus = set.getInt("pledgeStatus", 0);
|
||||
}
|
||||
|
||||
public int getClassId()
|
||||
{
|
||||
return _classId;
|
||||
}
|
||||
|
||||
public int getHair()
|
||||
{
|
||||
return _hair;
|
||||
}
|
||||
|
||||
public int getHairColor()
|
||||
{
|
||||
return _hairColor;
|
||||
}
|
||||
|
||||
public int getFace()
|
||||
{
|
||||
return _face;
|
||||
}
|
||||
|
||||
public int getNameColor()
|
||||
{
|
||||
return _nameColor;
|
||||
}
|
||||
|
||||
public int getTitleColor()
|
||||
{
|
||||
return _titleColor;
|
||||
}
|
||||
|
||||
public int getEquipHead()
|
||||
{
|
||||
return _equipHead;
|
||||
}
|
||||
|
||||
public int getEquipRHand()
|
||||
{
|
||||
return _equipRHand;
|
||||
}
|
||||
|
||||
public int getEquipLHand()
|
||||
{
|
||||
return _equipLHand;
|
||||
}
|
||||
|
||||
public int getEquipGloves()
|
||||
{
|
||||
return _equipGloves;
|
||||
}
|
||||
|
||||
public int getEquipChest()
|
||||
{
|
||||
return _equipChest;
|
||||
}
|
||||
|
||||
public int getEquipLegs()
|
||||
{
|
||||
return _equipLegs;
|
||||
}
|
||||
|
||||
public int getEquipFeet()
|
||||
{
|
||||
return _equipFeet;
|
||||
}
|
||||
|
||||
public int getEquipCloak()
|
||||
{
|
||||
return _equipCloak;
|
||||
}
|
||||
|
||||
public int getEquipHair()
|
||||
{
|
||||
return _equipHair;
|
||||
}
|
||||
|
||||
public int getEquipHair2()
|
||||
{
|
||||
return _equipHair2;
|
||||
}
|
||||
|
||||
public int getAgathionId()
|
||||
{
|
||||
return _agathionId;
|
||||
}
|
||||
|
||||
public int getWeaponEnchantLevel()
|
||||
{
|
||||
return _weaponEnchantLevel;
|
||||
}
|
||||
|
||||
public int getArmorEnchantLevel()
|
||||
{
|
||||
return _armorEnchantLevel;
|
||||
}
|
||||
|
||||
public boolean isFishing()
|
||||
{
|
||||
return _fishing;
|
||||
}
|
||||
|
||||
public int getBaitLocationX()
|
||||
{
|
||||
return _baitLocationX;
|
||||
}
|
||||
|
||||
public int getBaitLocationY()
|
||||
{
|
||||
return _baitLocationY;
|
||||
}
|
||||
|
||||
public int getBaitLocationZ()
|
||||
{
|
||||
return _baitLocationZ;
|
||||
}
|
||||
|
||||
public int getRecommends()
|
||||
{
|
||||
return _recommends;
|
||||
}
|
||||
|
||||
public int getNobleLevel()
|
||||
{
|
||||
return _nobleLevel;
|
||||
}
|
||||
|
||||
public boolean isHero()
|
||||
{
|
||||
return _hero;
|
||||
}
|
||||
|
||||
public int getClanId()
|
||||
{
|
||||
return _clanId;
|
||||
}
|
||||
|
||||
public int getPledgeStatus()
|
||||
{
|
||||
return _pledgeStatus;
|
||||
}
|
||||
}
|
@@ -1001,7 +1001,7 @@ public final class Skill implements IIdentifiable
|
||||
|
||||
public boolean checkCondition(L2Character activeChar, L2Object object, boolean itemOrWeapon)
|
||||
{
|
||||
if (activeChar.canOverrideCond(PcCondOverride.SKILL_CONDITIONS) && !Config.GM_SKILL_RESTRICTION)
|
||||
if (activeChar.isFakePlayer() || (activeChar.canOverrideCond(PcCondOverride.SKILL_CONDITIONS) && !Config.GM_SKILL_RESTRICTION))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.AbstractNpcInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.FakePlayerInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerObjectInfo;
|
||||
|
||||
public class L2WaterZone extends L2ZoneType
|
||||
@@ -54,7 +55,11 @@ public class L2WaterZone extends L2ZoneType
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObject(character, L2PcInstance.class, player ->
|
||||
{
|
||||
if (character.getRunSpeed() == 0)
|
||||
if (character.isFakePlayer())
|
||||
{
|
||||
player.sendPacket(new FakePlayerInfo((L2Npc) character));
|
||||
}
|
||||
else if (character.getRunSpeed() == 0)
|
||||
{
|
||||
player.sendPacket(new ServerObjectInfo((L2Npc) character, player));
|
||||
}
|
||||
@@ -85,7 +90,11 @@ public class L2WaterZone extends L2ZoneType
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObject(character, L2PcInstance.class, player ->
|
||||
{
|
||||
if (character.getRunSpeed() == 0)
|
||||
if (character.isFakePlayer())
|
||||
{
|
||||
player.sendPacket(new FakePlayerInfo((L2Npc) character));
|
||||
}
|
||||
else if (character.getRunSpeed() == 0)
|
||||
{
|
||||
player.sendPacket(new ServerObjectInfo((L2Npc) character, player));
|
||||
}
|
||||
|
@@ -141,7 +141,7 @@ public final class Action implements IClientIncomingPacket
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (!activeChar.isGM() && !(obj.isNpc() && Config.ALT_GAME_VIEWNPC))
|
||||
if (!activeChar.isGM() && (!(obj.isNpc() && Config.ALT_GAME_VIEWNPC) || obj.isFakePlayer()))
|
||||
{
|
||||
obj.onAction(activeChar, false);
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ import java.util.regex.PatternSyntaxException;
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.CharNameTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.InitialEquipmentData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.InitialShortcutData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.PlayerTemplateData;
|
||||
@@ -109,6 +110,12 @@ public final class CharacterCreate implements IClientIncomingPacket
|
||||
}
|
||||
}
|
||||
|
||||
if (FakePlayerData.getInstance().getProperName(_name) != null)
|
||||
{
|
||||
client.sendPacket(new CharCreateFail(CharCreateFail.REASON_INCORRECT_NAME));
|
||||
return;
|
||||
}
|
||||
|
||||
// Last Verified: May 30, 2009 - Gracia Final
|
||||
if (!Util.isAlphaNumeric(_name) || !isValidName(_name))
|
||||
{
|
||||
|
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
@@ -36,6 +37,22 @@ public final class CreatureSay implements IClientOutgoingPacket
|
||||
private int _npcString = -1;
|
||||
private List<String> _parameters;
|
||||
|
||||
/**
|
||||
* Used by fake players.
|
||||
* @param sender
|
||||
* @param receiver
|
||||
* @param name
|
||||
* @param messageType
|
||||
* @param text
|
||||
*/
|
||||
public CreatureSay(L2Npc sender, L2PcInstance receiver, String name, ChatType messageType, String text)
|
||||
{
|
||||
_objectId = sender.getObjectId();
|
||||
_textType = messageType;
|
||||
_charName = name;
|
||||
_text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param objectId
|
||||
* @param messageType
|
||||
|
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.enums.Sex;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.holders.FakePlayerHolder;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.OutgoingPackets;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class FakePlayerInfo implements IClientOutgoingPacket
|
||||
{
|
||||
private final L2Npc _npc;
|
||||
private final int _objId;
|
||||
private final int _x, _y, _z, _heading;
|
||||
private final int _mAtkSpd, _pAtkSpd;
|
||||
private final int _runSpd, _walkSpd;
|
||||
private final int _swimRunSpd;
|
||||
private final int _swimWalkSpd;
|
||||
private final int _flyRunSpd;
|
||||
private final int _flyWalkSpd;
|
||||
private final double _moveMultiplier;
|
||||
private final float _attackSpeedMultiplier;
|
||||
private final FakePlayerHolder _fpcHolder;
|
||||
private final L2Clan _clan;
|
||||
|
||||
public FakePlayerInfo(L2Npc npc)
|
||||
{
|
||||
_npc = npc;
|
||||
_objId = npc.getObjectId();
|
||||
_x = npc.getX();
|
||||
_y = npc.getY();
|
||||
_z = npc.getZ();
|
||||
_heading = npc.getHeading();
|
||||
_mAtkSpd = npc.getMAtkSpd();
|
||||
_pAtkSpd = (int) npc.getPAtkSpd();
|
||||
_attackSpeedMultiplier = npc.getAttackSpeedMultiplier();
|
||||
_moveMultiplier = npc.getMovementSpeedMultiplier();
|
||||
_runSpd = (int) Math.round(npc.getRunSpeed() / _moveMultiplier);
|
||||
_walkSpd = (int) Math.round(npc.getWalkSpeed() / _moveMultiplier);
|
||||
_swimRunSpd = (int) Math.round(npc.getSwimRunSpeed() / _moveMultiplier);
|
||||
_swimWalkSpd = (int) Math.round(npc.getSwimWalkSpeed() / _moveMultiplier);
|
||||
_flyRunSpd = npc.isFlying() ? _runSpd : 0;
|
||||
_flyWalkSpd = npc.isFlying() ? _walkSpd : 0;
|
||||
_fpcHolder = FakePlayerData.getInstance().getInfo(npc.getId());
|
||||
_clan = ClanTable.getInstance().getClan(_fpcHolder.getClanId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean write(PacketWriter packet)
|
||||
{
|
||||
OutgoingPackets.CHAR_INFO.writeId(packet);
|
||||
packet.writeD(_x);
|
||||
packet.writeD(_y);
|
||||
packet.writeD(_z);
|
||||
packet.writeD(0x00); // vehicleId
|
||||
packet.writeD(_objId);
|
||||
packet.writeS(_npc.getName());
|
||||
|
||||
packet.writeD(_npc.getRace().ordinal());
|
||||
packet.writeD(_npc.getTemplate().getSex() == Sex.FEMALE ? 0x01 : 0x00);
|
||||
packet.writeD(_fpcHolder.getClassId());
|
||||
|
||||
packet.writeD(0x00); // Inventory.PAPERDOLL_UNDER
|
||||
packet.writeD(_fpcHolder.getEquipHead());
|
||||
packet.writeD(_fpcHolder.getEquipRHand());
|
||||
packet.writeD(_fpcHolder.getEquipLHand());
|
||||
packet.writeD(_fpcHolder.getEquipGloves());
|
||||
packet.writeD(_fpcHolder.getEquipChest());
|
||||
packet.writeD(_fpcHolder.getEquipLegs());
|
||||
packet.writeD(_fpcHolder.getEquipFeet());
|
||||
packet.writeD(_fpcHolder.getEquipCloak());
|
||||
packet.writeD(_fpcHolder.getEquipRHand()); // dual hand
|
||||
packet.writeD(_fpcHolder.getEquipHair());
|
||||
packet.writeD(_fpcHolder.getEquipHair2());
|
||||
packet.writeD(0x00); // Inventory.PAPERDOLL_RBRACELET
|
||||
packet.writeD(0x00); // Inventory.PAPERDOLL_LBRACELET
|
||||
packet.writeD(0x00); // Inventory.PAPERDOLL_DECO1
|
||||
packet.writeD(0x00); // Inventory.PAPERDOLL_DECO2
|
||||
packet.writeD(0x00); // Inventory.PAPERDOLL_DECO3
|
||||
packet.writeD(0x00); // Inventory.PAPERDOLL_DECO4
|
||||
packet.writeD(0x00); // Inventory.PAPERDOLL_DECO5
|
||||
packet.writeD(0x00); // Inventory.PAPERDOLL_DECO6
|
||||
packet.writeD(0x00); // Inventory.PAPERDOLL_BELT
|
||||
|
||||
for (int i = 0; i < 21; i++)
|
||||
{
|
||||
packet.writeD(0x00);
|
||||
}
|
||||
|
||||
packet.writeD(0x00); // getTalismanSlots
|
||||
packet.writeD(0x01); // canEquipCloak
|
||||
|
||||
packet.writeD(_npc.getScriptValue()); // getPvpFlag()
|
||||
packet.writeD(_npc.getKarma());
|
||||
|
||||
packet.writeD(_mAtkSpd);
|
||||
packet.writeD(_pAtkSpd);
|
||||
|
||||
packet.writeD(0x00); // ?
|
||||
|
||||
packet.writeD(_runSpd);
|
||||
packet.writeD(_walkSpd);
|
||||
packet.writeD(_swimRunSpd);
|
||||
packet.writeD(_swimWalkSpd);
|
||||
packet.writeD(_flyRunSpd);
|
||||
packet.writeD(_flyWalkSpd);
|
||||
packet.writeD(_flyRunSpd);
|
||||
packet.writeD(_flyWalkSpd);
|
||||
packet.writeF(_moveMultiplier);
|
||||
packet.writeF(_attackSpeedMultiplier);
|
||||
|
||||
packet.writeF(_npc.getCollisionRadius());
|
||||
packet.writeF(_npc.getCollisionHeight());
|
||||
|
||||
packet.writeD(_fpcHolder.getHair());
|
||||
packet.writeD(_fpcHolder.getHairColor());
|
||||
packet.writeD(_fpcHolder.getFace());
|
||||
|
||||
packet.writeS(_npc.getTemplate().getTitle());
|
||||
|
||||
if (_clan != null)
|
||||
{
|
||||
packet.writeD(_clan.getId());
|
||||
packet.writeD(_clan.getCrestId());
|
||||
packet.writeD(_clan.getAllyId());
|
||||
packet.writeD(_clan.getAllyCrestId());
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.writeD(0x00);
|
||||
packet.writeD(0x00);
|
||||
packet.writeD(0x00);
|
||||
packet.writeD(0x00);
|
||||
}
|
||||
|
||||
packet.writeC(0x01); // isSitting() ? 0x00 : 0x01 (at some initial tests it worked)
|
||||
packet.writeC(_npc.isRunning() ? 0x01 : 0x00);
|
||||
packet.writeC(_npc.isInCombat() ? 0x01 : 0x00);
|
||||
|
||||
packet.writeC(_npc.isAlikeDead() ? 0x01 : 0x00);
|
||||
|
||||
packet.writeC(_npc.isInvisible() ? 0x01 : 0x00);
|
||||
|
||||
packet.writeC(0x00); // 1-on Strider, 2-on Wyvern, 3-on Great Wolf, 0-no mount
|
||||
packet.writeC(0x00); // getPrivateStoreType().getId()
|
||||
|
||||
packet.writeH(0x00); // getCubics().size()
|
||||
// getCubics().keySet().forEach(packet::writeH);
|
||||
|
||||
packet.writeC(0x00); // isInPartyMatchRoom
|
||||
|
||||
packet.writeD(_npc.getAbnormalVisualEffects());
|
||||
|
||||
packet.writeC(_npc.isInsideZone(ZoneId.WATER) ? 1 : 0);
|
||||
|
||||
packet.writeH(_fpcHolder.getRecommends()); // Blue value for name (0 = white, 255 = pure blue)
|
||||
packet.writeD(0x00); // getMountNpcId() == 0 ? 0 : getMountNpcId() + 1000000
|
||||
packet.writeD(_fpcHolder.getClassId());
|
||||
packet.writeD(0x00); // ?
|
||||
packet.writeC(_fpcHolder.getWeaponEnchantLevel()); // isMounted() ? 0 : _enchantLevel
|
||||
|
||||
packet.writeC(_npc.getTeam().getId());
|
||||
|
||||
packet.writeD(_clan != null ? _clan.getCrestLargeId() : 0x00);
|
||||
packet.writeC(_fpcHolder.getNobleLevel());
|
||||
packet.writeC(_fpcHolder.isHero() ? 0x01 : 0x00);
|
||||
|
||||
packet.writeC(_fpcHolder.isFishing() ? 0x01 : 0x00);
|
||||
|
||||
packet.writeD(_fpcHolder.getBaitLocationX());
|
||||
packet.writeD(_fpcHolder.getBaitLocationY());
|
||||
packet.writeD(_fpcHolder.getBaitLocationZ());
|
||||
|
||||
packet.writeD(_fpcHolder.getNameColor());
|
||||
|
||||
packet.writeD(_heading);
|
||||
|
||||
packet.writeD(_fpcHolder.getPledgeStatus());
|
||||
packet.writeD(0x00); // getPledgeType()
|
||||
|
||||
packet.writeD(_fpcHolder.getTitleColor());
|
||||
|
||||
packet.writeD(0x00); // isCursedWeaponEquipped
|
||||
|
||||
packet.writeD(0x00); // getClanId() > 0 ? getClan().getReputationScore() : 0
|
||||
|
||||
// T1
|
||||
packet.writeD(0x00); // getTransformationDisplayId()
|
||||
packet.writeD(_fpcHolder.getAgathionId());
|
||||
|
||||
// T2
|
||||
packet.writeD(0x01);
|
||||
|
||||
// T2.3
|
||||
packet.writeD(_npc.getAbnormalVisualEffectSpecial());
|
||||
return true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user