Addition of fake player system.
This commit is contained in:
parent
fffb78c071
commit
749b2775a8
@ -392,6 +392,9 @@
|
||||
<!-- ADMIN MESSAGES -->
|
||||
<admin command="admin_msg" accessLevel="100" />
|
||||
|
||||
<!-- ADMIN FAKE PLAYERS -->
|
||||
<admin command="admin_fakechat" accessLevel="100" />
|
||||
|
||||
<!-- ADMIN MOB GROUP -->
|
||||
<admin command="admin_mobmenu" accessLevel="100" />
|
||||
<admin command="admin_mobgroup_list" accessLevel="100" />
|
||||
|
33
L2J_Mobius_1.0_Ertheia/dist/game/config/Custom/FakePlayers.ini
vendored
Normal file
33
L2J_Mobius_1.0_Ertheia/dist/game/config/Custom/FakePlayers.ini
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
# Fake players
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Enable fake players.
|
||||
EnableFakePlayers = False
|
||||
|
||||
# Enable chatting with fake players.
|
||||
FakePlayerChat = True
|
||||
|
||||
# Enable shots usage for fake players.
|
||||
FakePlayerUseShots = True
|
||||
|
||||
# Reward PvP kills by killing fake players.
|
||||
FakePlayerKillsRewardPvP = True
|
||||
|
||||
# Fake player kills apply karma rules.
|
||||
FakePlayerUnflaggedKillsKarma = True
|
||||
|
||||
# Aggressive AI fake players attack nearby monsters.
|
||||
FakePlayerAggroMonsters = True
|
||||
|
||||
# Aggressive AI fake players attack nearby players.
|
||||
FakePlayerAggroPlayers = False
|
||||
|
||||
# Aggressive AI fake players attack nearby fake players.
|
||||
FakePlayerAggroFPC = False
|
||||
|
||||
# Fake players can drop items when killing monsters.
|
||||
FakePlayerCanDropItems = True
|
||||
|
||||
# Fake players can pickup dropped items.
|
||||
FakePlayerCanPickup = True
|
24
L2J_Mobius_1.0_Ertheia/dist/game/data/FakePlayerChatData.xml
vendored
Normal file
24
L2J_Mobius_1.0_Ertheia/dist/game/data/FakePlayerChatData.xml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Use lowercase for searchText and answers. -->
|
||||
<!-- You can use specific fpcName or ALL to use with all fpcs. -->
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/FakePlayerChatData.xsd">
|
||||
<fakePlayerChat fpcName="ALL" searchMethod="EQUALS" searchText="hi" answers="hello;hi;hi there;hello there" />
|
||||
<fakePlayerChat fpcName="ALL" searchMethod="EQUALS" searchText="hey" answers="hey hey;hey;hey there" />
|
||||
<fakePlayerChat fpcName="ALL" searchMethod="EQUALS" searchText="hello" answers="hello;hi;hi there;hello there" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="here?" answers="yes;busy;i look for something" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="whats up?" answers="good;busy;i look for something" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="what?" answers="something :P;something for me" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="why?" answers="because;i don't know;what?" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="really" answers="really;yes;of course" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="thanks" answers=":);:D;:*" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="thank you" answers=":);:D;:*" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="STARTS_WITH" searchText="how are you" answers="fine;good;busy" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="STARTS_WITH" searchText="do you know" answers="nope;no sorry;nope, i don't" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="STARTS_WITH" searchText="where can i" answers="i don't know;no clue;ask someone else :P" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="STARTS_WITH" searchText="can i ask you" answers="yes;what?;tell me" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="CONTAINS" searchText="server;ha;problem" answers="it's good;i don't know;i don't think so..." />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="CONTAINS" searchText="server;ha;bug" answers="it's good;i don't know;i don't think so..." />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="CONTAINS" searchText="is th;server;good" answers="it's good :D;i like it :P;yes it is :)" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="CONTAINS" searchText="where;you;go;?" answers="i look for something;checking stuff;looking for curius people :P" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="CONTAINS" searchText="are;you;kidding" answers="^^;:D;:P" />
|
||||
</list>
|
37
L2J_Mobius_1.0_Ertheia/dist/game/data/FakePlayerVisualData.xml
vendored
Normal file
37
L2J_Mobius_1.0_Ertheia/dist/game/data/FakePlayerVisualData.xml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Values that can be set:
|
||||
int classId, int hair, int hairColor, int face, int nameColor, int titleColor, int equipRHand, int equipLHand, int equipHead,
|
||||
int equipGloves, int equipChest, int equipLegs, int equipFeet, int equipCloak, int equipHair, int equipHair2, int agathionId,
|
||||
int weaponEnchantLevel, int armorEnchantLevel, boolean fishing, int baitLocationX, int baitLocationY, int baitLocationZ,
|
||||
int recommends, int nobleLevel, boolean hero, int clanId, int pledgeStatus -->
|
||||
<!--
|
||||
####################################### Hero Weapons #####################################################
|
||||
Bow(37874) Crossbow(37875) Dagger(37868) Dual Blunt Weapon(37881) Dual Dagger(37880) Dual Sword(37879)
|
||||
Fist(37872) OneHand Blunt(37871) OneHand Magic Blunt(37877) One Hand Magic Sword(37876) One Hand Sword(37869)
|
||||
Spear(37873) Two-handed Magic Blunt Weapon(37878) Two-handed Sword(37870) Shield(37870) Sigil(37223)
|
||||
#############################################################################################################
|
||||
-->
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/FakePlayerVisualData.xsd">
|
||||
<!-- Non-Combat -->
|
||||
<fakePlayer npcId="80000" classId="188" hair="1" hairColor="1" face="0" equipRHand="17294" equipHead="37215" equipGloves="37216" equipChest="37213" equipLegs="37214" equipFeet="37217" equipCloak="40200" />
|
||||
|
||||
<!-- Combat -->
|
||||
<!-- Sigel Phoenix Knight -->
|
||||
<fakePlayer npcId="81001" classId="148" hair="0" hairColor="0" face="0" equipRHand="37869" equipLHand="37212" equipHead="37209" equipGloves="37210" equipChest="37207" equipLegs="37208" equipFeet="37211" equipCloak="30310" />
|
||||
<!-- Tyrr Titan -->
|
||||
<fakePlayer npcId="81002" classId="154" hair="0" hairColor="0" face="0" equipRHand="37870" equipHead="37215" equipGloves="37216" equipChest="37213" equipLegs="37214" equipFeet="37217" equipCloak="30311" />
|
||||
<!-- Othell Fortune Seeker -->
|
||||
<fakePlayer npcId="81003" classId="161" hair="0" hairColor="0" face="0" equipRHand="37880" equipHead="37215" equipGloves="37216" equipChest="37213" equipLegs="37214" equipFeet="37217" equipCloak="30312" />
|
||||
<!-- Yul Trickster -->
|
||||
<fakePlayer npcId="81004" classId="165" hair="0" hairColor="0" face="0" equipRHand="37875" equipHead="37215" equipGloves="37216" equipChest="37213" equipLegs="37214" equipFeet="37217" equipCloak="30313" />
|
||||
<!-- Feoh Archmage -->
|
||||
<fakePlayer npcId="81005" classId="166" hair="0" hairColor="0" face="0" equipRHand="37878" equipHead="37220" equipGloves="37221" equipChest="37218" equipLegs="37219" equipFeet="37222" equipCloak="30314" />
|
||||
<!-- Iss Spectral Dancer -->
|
||||
<fakePlayer npcId="81006" classId="173" hair="0" hairColor="0" face="0" equipRHand="37879" equipHead="37209" equipGloves="37210" equipChest="37207" equipLegs="37208" equipFeet="37211" equipCloak="30316" />
|
||||
<!-- Aeore Eva's Saint -->
|
||||
<fakePlayer npcId="81007" classId="180" hair="0" hairColor="0" face="0" equipRHand="37876" equipLHand="37223" equipHead="37220" equipGloves="37221" equipChest="37218" equipLegs="37219" equipFeet="37222" equipCloak="30317" />
|
||||
<!-- Eviscerator -->
|
||||
<fakePlayer npcId="81008" classId="188" hair="0" hairColor="0" face="0" equipRHand="37872" equipHead="37215" equipGloves="37216" equipChest="37213" equipLegs="37214" equipFeet="37217" equipCloak="40200" />
|
||||
<!-- Sayha's Seer -->
|
||||
<fakePlayer npcId="81009" classId="189" hair="0" hairColor="0" face="0" equipRHand="37878" equipHead="37220" equipGloves="37221" equipChest="37218" equipLegs="37219" equipFeet="37222" equipCloak="40201" />
|
||||
</list>
|
39
L2J_Mobius_1.0_Ertheia/dist/game/data/Routes.xml
vendored
39
L2J_Mobius_1.0_Ertheia/dist/game/data/Routes.xml
vendored
@ -2402,4 +2402,43 @@
|
||||
<point X="42630" Y="-48231" Z="-792" delay="0" run="true" />
|
||||
<point X="45069" Y="-48034" Z="-792" delay="0" run="true" />
|
||||
</route>
|
||||
<route name="FPC_Giran_Evi" repeat="true" repeatStyle="cycle">
|
||||
<target id="80000" spawnX="83485" spawnY="147998" spawnZ="-3407" />
|
||||
<point X="83485" Y="147998" Z="-3407" delay="10" run="true" /> <!-- Gatekeeper -->
|
||||
<point X="83575" Y="147722" Z="-3405" delay="32" run="true" /> <!-- Buffer -->
|
||||
<point X="82117" Y="147642" Z="-3469" delay="0" run="true" />
|
||||
<point X="82152" Y="147580" Z="-3469" delay="36" run="true" /> <!-- Olympiad Statue-->
|
||||
<point X="82084" Y="147569" Z="-3469" delay="12" run="true" /> <!-- Olympiad Manager -->
|
||||
<point X="81532" Y="147578" Z="-3469" delay="0" run="true" />
|
||||
<point X="81593" Y="146626" Z="-3533" delay="3" run="true" />
|
||||
<point X="81932" Y="146566" Z="-3533" delay="0" run="true" />
|
||||
<point X="82651" Y="146714" Z="-3466" delay="20" run="true" /> <!-- Dimesional Merchant -->
|
||||
<point X="82807" Y="146649" Z="-3465" delay="0" run="true" />
|
||||
<point X="83216" Y="146672" Z="-3465" delay="28" run="true" /> <!-- Warehouse -->
|
||||
<point X="83211" Y="146724" Z="-3467" delay="88" run="true" /> <!-- Warehouse 2 -->
|
||||
<point X="81659" Y="146555" Z="-3533" delay="3" run="true" />
|
||||
<point X="81283" Y="145519" Z="-3533" delay="0" run="true" />
|
||||
<point X="80375" Y="145484" Z="-3535" delay="28" run="true" /> <!-- Pochi -->
|
||||
<point X="80283" Y="145826" Z="-3533" delay="0" run="true" />
|
||||
<point X="79952" Y="145840" Z="-3496" delay="0" run="true" />
|
||||
<point X="79781" Y="145546" Z="-3496" delay="0" run="true" />
|
||||
<point X="79736" Y="145518" Z="-3495" delay="0" run="true" />
|
||||
<point X="79663" Y="145529" Z="-3496" delay="40" run="true" /> <!-- Galladucci -->
|
||||
<point X="79661" Y="145429" Z="-3495" delay="80" run="true" /> <!-- Alexandria -->
|
||||
<point X="79999" Y="145152" Z="-3496" delay="0" run="true" />
|
||||
<point X="80393" Y="145136" Z="-3533" delay="0" run="true" />
|
||||
<point X="81068" Y="145845" Z="-3533" delay="36" run="true" /> <!-- Pet Manager -->
|
||||
<point X="81061" Y="145563" Z="-3533" delay="0" run="true" />
|
||||
<point X="81563" Y="145532" Z="-3533" delay="3" run="true" />
|
||||
<point X="81692" Y="147231" Z="-3533" delay="32" run="true" /> <!-- Kiki -->
|
||||
<point X="81370" Y="147213" Z="-3533" delay="64" run="true" /> <!-- Plani -->
|
||||
<point X="81517" Y="147231" Z="-3533" delay="1" run="true" />
|
||||
<point X="81542" Y="147570" Z="-3469" delay="0" run="true" />
|
||||
<point X="81109" Y="147770" Z="-3469" delay="99" run="true" /> <!-- Moe -->
|
||||
<point X="81108" Y="149415" Z="-3469" delay="99" run="true" /> <!-- Auction House -->
|
||||
<point X="81413" Y="149700" Z="-3469" delay="52" run="true" /> <!-- Clan Hall Managers -->
|
||||
<point X="81718" Y="149626" Z="-3469" delay="60" run="true" /> <!-- Beauty Shop -->
|
||||
<point X="82815" Y="148840" Z="-3469" delay="3" run="true" />
|
||||
<point X="83307" Y="148431" Z="-3405" delay="21" run="true" /> <!-- Training Camp Manager -->
|
||||
</route>
|
||||
</routes>
|
@ -88,7 +88,7 @@ public final class Wisp extends AbstractNpcAI
|
||||
final L2Character creature = event.getSeen();
|
||||
final L2Npc npc = (L2Npc) event.getSeer();
|
||||
|
||||
if (creature.isPlayer())
|
||||
if (creature.isPlayer() || creature.isFakePlayer())
|
||||
{
|
||||
npc.setTarget(creature);
|
||||
npc.doCast(npc.getId() == WISP ? WISP_HEAL.getSkill() : LARGE_WISP_HEAL.getSkill());
|
||||
|
80
L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/FakePlayers/PvpFlaggingStopTask.java
vendored
Normal file
80
L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/FakePlayers/PvpFlaggingStopTask.java
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 custom.FakePlayers;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* TODO: Move it to L2Character.
|
||||
* @author Mobius
|
||||
*/
|
||||
public class PvpFlaggingStopTask extends AbstractNpcAI
|
||||
{
|
||||
private PvpFlaggingStopTask()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((npc == null) || npc.isDead())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (event.startsWith("FLAG_CHECK"))
|
||||
{
|
||||
final L2Object target = npc.getTarget();
|
||||
if ((target != null) && (target.isPlayable() || target.isFakePlayer()))
|
||||
{
|
||||
npc.setScriptValue(1); // in combat
|
||||
cancelQuestTimer("FINISH_FLAG" + npc.getObjectId(), npc, null);
|
||||
cancelQuestTimer("REMOVE_FLAG" + npc.getObjectId(), npc, null);
|
||||
startQuestTimer("FINISH_FLAG" + npc.getObjectId(), Config.PVP_NORMAL_TIME - 20000, npc, null);
|
||||
startQuestTimer("FLAG_CHECK" + npc.getObjectId(), 5000, npc, null);
|
||||
}
|
||||
}
|
||||
else if (event.startsWith("FINISH_FLAG"))
|
||||
{
|
||||
if (npc.isScriptValue(1))
|
||||
{
|
||||
npc.setScriptValue(2); // blink status
|
||||
npc.broadcastInfo(); // update flag status
|
||||
startQuestTimer("REMOVE_FLAG" + npc.getObjectId(), 20000, npc, null);
|
||||
}
|
||||
}
|
||||
else if (event.startsWith("REMOVE_FLAG"))
|
||||
{
|
||||
if (npc.isScriptValue(2))
|
||||
{
|
||||
npc.setScriptValue(0); // not in combat
|
||||
npc.broadcastInfo(); // update flag status
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PvpFlaggingStopTask();
|
||||
}
|
||||
}
|
115
L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/FakePlayers/RecieveAdventurerBuffs.java
vendored
Normal file
115
L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/custom/FakePlayers/RecieveAdventurerBuffs.java
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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 custom.FakePlayers;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Town Fake Player walkers that receive buffs from Adventurer NPC.
|
||||
* @author Mobius
|
||||
*/
|
||||
public class RecieveAdventurerBuffs extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] ADVENTURERS_GUIDE =
|
||||
{
|
||||
32327,
|
||||
33950,
|
||||
};
|
||||
private static final int[] FAKE_PLAYER_IDS =
|
||||
{
|
||||
80000
|
||||
};
|
||||
// Skills
|
||||
// private static final SkillHolder KNIGHT = new SkillHolder(15648, 1); // Knight's Harmony (Adventurer)
|
||||
private static final SkillHolder WARRIOR = new SkillHolder(15649, 1); // Warrior's Harmony (Adventurer)
|
||||
private static final SkillHolder WIZARD = new SkillHolder(15650, 1); // Wizard's Harmony (Adventurer)
|
||||
private static final SkillHolder[] GROUP_BUFFS =
|
||||
{
|
||||
new SkillHolder(15642, 1), // Horn Melody (Adventurer)
|
||||
new SkillHolder(15643, 1), // Drum Melody (Adventurer)
|
||||
new SkillHolder(15644, 1), // Pipe Organ Melody (Adventurer)
|
||||
new SkillHolder(15645, 1), // Guitar Melody (Adventurer)
|
||||
new SkillHolder(15646, 1), // Harp Melody (Adventurer)
|
||||
new SkillHolder(15647, 1), // Lute Melody (Adventurer)
|
||||
new SkillHolder(15651, 1), // Prevailing Sonata (Adventurer)
|
||||
new SkillHolder(15652, 1), // Daring Sonata (Adventurer)
|
||||
new SkillHolder(15653, 1), // Refreshing Sonata (Adventurer)
|
||||
};
|
||||
|
||||
private RecieveAdventurerBuffs()
|
||||
{
|
||||
if (Config.FAKE_PLAYERS_ENABLED)
|
||||
{
|
||||
addSpawnId(FAKE_PLAYER_IDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.startsWith("AUTOBUFF") && (npc != null) && !npc.isDead())
|
||||
{
|
||||
if (!npc.isMoving())
|
||||
{
|
||||
for (L2Npc nearby : L2World.getInstance().getVisibleObjects(npc, L2Npc.class, 100))
|
||||
{
|
||||
if (CommonUtil.contains(ADVENTURERS_GUIDE, nearby.getId()))
|
||||
{
|
||||
for (SkillHolder holder : GROUP_BUFFS)
|
||||
{
|
||||
SkillCaster.triggerCast(nearby, npc, holder.getSkill());
|
||||
}
|
||||
if (ClassId.getClassId(FakePlayerData.getInstance().getInfo(npc.getId()).getClassId()).isMage())
|
||||
{
|
||||
SkillCaster.triggerCast(nearby, npc, WIZARD.getSkill());
|
||||
}
|
||||
else
|
||||
{
|
||||
SkillCaster.triggerCast(nearby, npc, WARRIOR.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
startQuestTimer("AUTOBUFF" + npc.getObjectId(), 30000, npc, null);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("AUTOBUFF" + npc.getObjectId(), 1000, npc, null);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RecieveAdventurerBuffs();
|
||||
}
|
||||
}
|
@ -79,6 +79,7 @@ import handlers.admincommandhandlers.AdminEnchant;
|
||||
import handlers.admincommandhandlers.AdminEventEngine;
|
||||
import handlers.admincommandhandlers.AdminEvents;
|
||||
import handlers.admincommandhandlers.AdminExpSp;
|
||||
import handlers.admincommandhandlers.AdminFakePlayers;
|
||||
import handlers.admincommandhandlers.AdminFightCalculator;
|
||||
import handlers.admincommandhandlers.AdminFortSiege;
|
||||
import handlers.admincommandhandlers.AdminGeodata;
|
||||
@ -408,6 +409,7 @@ public class MasterHandler
|
||||
AdminEventEngine.class,
|
||||
AdminEvents.class,
|
||||
AdminExpSp.class,
|
||||
AdminFakePlayers.class,
|
||||
AdminFightCalculator.class,
|
||||
AdminFortSiege.class,
|
||||
AdminGeodata.class,
|
||||
|
@ -192,7 +192,7 @@ public class L2NpcActionShift implements IActionShiftHandler
|
||||
}
|
||||
else if (Config.ALT_GAME_VIEWNPC)
|
||||
{
|
||||
if (!target.isNpc())
|
||||
if (!target.isNpc() || target.isFakePlayer())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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 handlers.admincommandhandlers;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class AdminFakePlayers implements IAdminCommandHandler
|
||||
{
|
||||
private static final String[] ADMIN_COMMANDS =
|
||||
{
|
||||
"admin_fakechat"
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean useAdminCommand(String command, L2PcInstance activeChar)
|
||||
{
|
||||
if (command.startsWith("admin_fakechat"))
|
||||
{
|
||||
final String[] words = command.substring(15).split(" ");
|
||||
if (words.length < 3)
|
||||
{
|
||||
activeChar.sendMessage("Usage: //fakechat playername fpcname message");
|
||||
return false;
|
||||
}
|
||||
final L2PcInstance player = L2World.getInstance().getPlayer(words[0]);
|
||||
if (player == null)
|
||||
{
|
||||
activeChar.sendMessage("Player not found.");
|
||||
return false;
|
||||
}
|
||||
final String fpcName = FakePlayerData.getInstance().getProperName(words[1]);
|
||||
if (fpcName == null)
|
||||
{
|
||||
activeChar.sendMessage("Fake player not found.");
|
||||
return false;
|
||||
}
|
||||
String message = "";
|
||||
for (int i = 0; i < words.length; i++)
|
||||
{
|
||||
if (i < 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
message += (words[i] + " ");
|
||||
}
|
||||
FakePlayerChatManager.getInstance().sendChat(player, fpcName, message);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAdminCommandList()
|
||||
{
|
||||
return ADMIN_COMMANDS;
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EnchantItemData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EnchantItemGroupsData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FishingData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ItemCrystalizationData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.MultisellData;
|
||||
@ -45,9 +46,12 @@ import com.l2jmobius.gameserver.data.xml.impl.TransformData;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
@ -301,6 +305,25 @@ public class AdminReload implements IAdminCommandHandler
|
||||
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Fishing data.");
|
||||
break;
|
||||
}
|
||||
case "fakeplayers":
|
||||
{
|
||||
FakePlayerData.getInstance().load();
|
||||
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||
{
|
||||
if (obj.isFakePlayer())
|
||||
{
|
||||
obj.broadcastInfo();
|
||||
}
|
||||
}
|
||||
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Fake Player data.");
|
||||
break;
|
||||
}
|
||||
case "fakeplayerchat":
|
||||
{
|
||||
FakePlayerChatManager.getInstance().load();
|
||||
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Fake Player Chat data.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
activeChar.sendMessage(RELOAD_USAGE);
|
||||
|
@ -17,8 +17,10 @@
|
||||
package handlers.chathandlers;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.handler.IChatHandler;
|
||||
import com.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||
import com.l2jmobius.gameserver.model.BlockList;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.PcCondOverride;
|
||||
@ -59,6 +61,28 @@ public final class ChatWhisper implements IChatHandler
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.FAKE_PLAYERS_ENABLED && (FakePlayerData.getInstance().getProperName(target) != null))
|
||||
{
|
||||
if (FakePlayerData.getInstance().isTalkable(target))
|
||||
{
|
||||
if (Config.FAKE_PLAYER_CHAT)
|
||||
{
|
||||
final String name = FakePlayerData.getInstance().getProperName(target);
|
||||
activeChar.sendPacket(new CreatureSay(activeChar, null, "->" + name, type, text));
|
||||
FakePlayerChatManager.getInstance().manageChat(activeChar, name, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.THAT_PERSON_IS_IN_MESSAGE_REFUSAL_MODE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.THAT_PLAYER_IS_NOT_ONLINE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance receiver = L2World.getInstance().getPlayer(target);
|
||||
|
||||
if ((receiver != null) && !receiver.isSilenceMode(activeChar.getObjectId()))
|
||||
|
@ -40,5 +40,4 @@ public class PlayerLevelCondition implements ICondition
|
||||
{
|
||||
return creature.isPlayer() && (creature.getLevel() >= _minLevel) && (creature.getLevel() < _maxLevel);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,9 +16,11 @@
|
||||
*/
|
||||
package handlers.playeractions;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlEvent;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.ai.NextAction;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.handler.IPlayerActionHandler;
|
||||
import com.l2jmobius.gameserver.model.ActionDataHolder;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
@ -97,6 +99,15 @@ public final class SocialAction implements IPlayerActionHandler
|
||||
return true;
|
||||
}
|
||||
|
||||
private void scheduleDeny(L2PcInstance player)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_COUPLE_ACTION_WAS_DENIED);
|
||||
player.onTransactionResponse();
|
||||
}
|
||||
}
|
||||
|
||||
private void useCoupleSocial(L2PcInstance player, int id)
|
||||
{
|
||||
if (player == null)
|
||||
@ -105,7 +116,26 @@ public final class SocialAction implements IPlayerActionHandler
|
||||
}
|
||||
|
||||
final L2Object target = player.getTarget();
|
||||
if ((target == null) || !target.isPlayer())
|
||||
if ((target == null))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.INVALID_TARGET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FakePlayerData.getInstance().isTalkable(target.getName()))
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_REQUESTED_A_COUPLE_ACTION_WITH_C1);
|
||||
sm.addString(target.getName());
|
||||
player.sendPacket(sm);
|
||||
if (!player.isProcessingRequest())
|
||||
{
|
||||
ThreadPoolManager.schedule(() -> scheduleDeny(player), 10000);
|
||||
player.blockRequest();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target.isPlayer())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.INVALID_TARGET);
|
||||
return;
|
||||
|
@ -216,11 +216,14 @@ public class Q10766_ANewCraft extends Quest
|
||||
@Id(WINDY_HEALING_POTION_1)
|
||||
public void onItemCreate(OnItemCreate event)
|
||||
{
|
||||
final L2PcInstance player = event.getActiveChar();
|
||||
final QuestState qs = getQuestState(player, false);
|
||||
if ((qs != null) && (qs.isCond(3)) && (getQuestItemsCount(qs.getPlayer(), AIR_STONE) >= 1) && (getQuestItemsCount(qs.getPlayer(), WINDY_HEALING_POTION_1) >= 1))
|
||||
final L2PcInstance player = event.getActiveChar().getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
qs.setCond(4, true);
|
||||
final QuestState qs = getQuestState(player, false);
|
||||
if ((qs != null) && (qs.isCond(3)) && (getQuestItemsCount(qs.getPlayer(), AIR_STONE) >= 1) && (getQuestItemsCount(qs.getPlayer(), WINDY_HEALING_POTION_1) >= 1))
|
||||
{
|
||||
qs.setCond(4, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -141,11 +141,14 @@ public class Q10767_AWholeNewLevelOfAlchemy extends Quest
|
||||
@Id(HIGH_GRADE_LOVE_POTION)
|
||||
public void onItemCreate(OnItemCreate event)
|
||||
{
|
||||
final L2PcInstance player = event.getActiveChar();
|
||||
final QuestState qs = getQuestState(player, false);
|
||||
if ((qs != null) && (qs.isCond(1)) && (getQuestItemsCount(qs.getPlayer(), SUPERIOR_WINDY_HEALING_POTION) >= 1000) && (getQuestItemsCount(qs.getPlayer(), SUPERIOR_WINDY_QUIK_HEALING_POTION) >= 1000) && (getQuestItemsCount(qs.getPlayer(), HIGH_GRADE_LOVE_POTION) >= 1000))
|
||||
final L2PcInstance player = event.getActiveChar().getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
final QuestState qs = getQuestState(player, false);
|
||||
if ((qs != null) && (qs.isCond(1)) && (getQuestItemsCount(qs.getPlayer(), SUPERIOR_WINDY_HEALING_POTION) >= 1000) && (getQuestItemsCount(qs.getPlayer(), SUPERIOR_WINDY_QUIK_HEALING_POTION) >= 1000) && (getQuestItemsCount(qs.getPlayer(), HIGH_GRADE_LOVE_POTION) >= 1000))
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
L2J_Mobius_1.0_Ertheia/dist/game/data/spawns/Others/FakePlayers.xml
vendored
Normal file
8
L2J_Mobius_1.0_Ertheia/dist/game/data/spawns/Others/FakePlayers.xml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/spawns.xsd">
|
||||
<spawn name="FakePlayers">
|
||||
<group>
|
||||
<npc id="80000" x="83485" y="147998" z="-3407" heading="23509" respawnTime="60sec" /> <!-- Evi -->
|
||||
</group>
|
||||
</spawn>
|
||||
</list>
|
341
L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/fpc_combat.xml
vendored
Normal file
341
L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/fpc_combat.xml
vendored
Normal file
@ -0,0 +1,341 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../xsd/npcs.xsd">
|
||||
<!-- Sigel Phoenix Knight -->
|
||||
<npc id="81001" level="94" type="L2Monster" name="Siegfield" title="Sigel Phoenix Knight" >
|
||||
<race>HUMAN</race>
|
||||
<sex>MALE</sex>
|
||||
<stats str="88" int="39" dex="55" wit="39" con="82" men="38">
|
||||
<vitals hp="22228" hpRegen="10.8" mp="3681" mpRegen="3.0" />
|
||||
<attack physical="4425" magical="1284" random="30" critical="94" accuracy="206" attackSpeed="517" type="SWORD" range="40" distance="80" width="120" />
|
||||
<defence physical="3613" magical="2307" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="82" />
|
||||
<run ground="132" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="FIGHTER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="9" />
|
||||
<height normal="23" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="10009" level="6" />
|
||||
<skill name="Skill02_ID" id="10010" level="6" />
|
||||
<skill name="Skill03_ID" id="10011" level="4" />
|
||||
<skill name="Skill04_ID" id="10012" level="4" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="10009" level="6" /> <!-- Last Judgment -->
|
||||
<skill id="10010" level="6" /> <!-- Justice Punishment -->
|
||||
<skill id="10011" level="4" /> <!-- Shield Impact -->
|
||||
<skill id="10012" level="4" /> <!-- Shield Wave -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Tyrr Titan -->
|
||||
<npc id="81002" level="94" type="L2Monster" name="Tyrrion" title="Tyrr Titan" >
|
||||
<race>ORC</race>
|
||||
<sex>MALE</sex>
|
||||
<stats str="88" int="37" dex="50" wit="38" con="87" men="41">
|
||||
<vitals hp="19416" hpRegen="10.8" mp="3727" mpRegen="3.0" />
|
||||
<attack physical="11025" magical="1247" random="30" critical="92" accuracy="168" attackSpeed="540" type="SWORD" range="40" distance="80" width="120" />
|
||||
<defence physical="3429" magical="2046" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="70" />
|
||||
<run ground="130" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="FIGHTER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="7" />
|
||||
<height normal="27" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="10267" level="4" />
|
||||
<skill name="Skill02_ID" id="1760" level="5" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="10267" level="4" /> <!-- Hurricane Rush -->
|
||||
<skill id="1760" level="5" /> <!-- Armor Destruction -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Othell Fortune Seeker -->
|
||||
<npc id="81003" level="94" type="L2Monster" name="Othelo" title="Othell Fortune Seeker" >
|
||||
<race>DWARF</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="87" int="39" dex="53" wit="37" con="85" men="40">
|
||||
<vitals hp="17018" hpRegen="10.8" mp="3693" mpRegen="3.0" />
|
||||
<attack physical="4807" magical="1281" random="30" critical="230" accuracy="165" attackSpeed="943" type="SWORD" range="40" distance="80" width="120" />
|
||||
<defence physical="2889" magical="2035" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="80" />
|
||||
<run ground="131" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="FIGHTER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="5" />
|
||||
<height normal="19" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="10508" level="6" />
|
||||
<skill name="Skill02_ID" id="10509" level="6" />
|
||||
<skill name="Skill03_ID" id="10510" level="5" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="10508" level="6" /> <!-- Blood Stab -->
|
||||
<skill id="10509" level="6" /> <!-- Heart Breaker -->
|
||||
<skill id="10510" level="5" /> <!-- Chain Blow -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Yul Trickster -->
|
||||
<npc id="81004" level="94" type="L2Monster" name="Yully" title="Yul Trickster" >
|
||||
<race>KAMAEL</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="88" int="43" dex="57" wit="36" con="80" men="37">
|
||||
<vitals hp="15285" hpRegen="10.8" mp="4596" mpRegen="3.0" />
|
||||
<attack physical="9754" magical="1375" random="30" critical="185" accuracy="167" attackSpeed="483" reuseDelay="1500" type="BOW" range="500" distance="80" width="120" />
|
||||
<defence physical="2885" magical="2318" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="87" />
|
||||
<run ground="140" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="ARCHER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="7" />
|
||||
<height normal="22.6" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="10760" level="6" />
|
||||
<skill name="Skill02_ID" id="10762" level="5" />
|
||||
<skill name="Skill03_ID" id="10763" level="6" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="10760" level="6" /> <!-- Tornado Shot -->
|
||||
<skill id="10762" level="5" /> <!-- Quick Shot -->
|
||||
<skill id="10763" level="6" /> <!-- Pin Point -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Feoh Archmage -->
|
||||
<npc id="81005" level="94" type="L2Monster" name="Feoth" title="Feoh Archmage" >
|
||||
<race>HUMAN</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="38" int="79" dex="27" wit="78" con="41" men="78">
|
||||
<vitals hp="14435" hpRegen="10.8" mp="9103" mpRegen="3.0" />
|
||||
<attack physical="1257" magical="10320" random="30" critical="61" accuracy="158" attackSpeed="336" type="BLUNT" range="40" distance="500" width="120" />
|
||||
<defence physical="3132" magical="2635" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="78" />
|
||||
<run ground="124" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="MAGE" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="8" />
|
||||
<height normal="23.5" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="11011" level="6" />
|
||||
<skill name="Skill02_ID" id="11017" level="6" />
|
||||
<skill name="Skill03_ID" id="11024" level="5" />
|
||||
<skill name="Skill04_ID" id="11047" level="4" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="11011" level="6" /> <!-- Elemental Spike -->
|
||||
<skill id="11017" level="6" /> <!-- Elemental Crash -->
|
||||
<skill id="11024" level="5" /> <!-- Volcanic Destruction -->
|
||||
<skill id="11047" level="4" /> <!-- Ruin -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Iss Spectral Dancer -->
|
||||
<npc id="81006" level="94" type="L2Monster" name="Isda" title="Iss Spectral Dancer" >
|
||||
<race>DARK_ELF</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="92" int="42" dex="56" wit="39" con="77" men="35">
|
||||
<vitals hp="15499" hpRegen="10.8" mp="4038" mpRegen="3.0" />
|
||||
<attack physical="8777" magical="1451" random="30" critical="95" accuracy="162" attackSpeed="582" type="SWORD" range="40" distance="80" width="120" />
|
||||
<defence physical="3429" magical="2026" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="85" />
|
||||
<run ground="139" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="BALANCED" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="7" />
|
||||
<height normal="23.5" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="11508" level="4" />
|
||||
<skill name="Skill02_ID" id="11509" level="6" />
|
||||
<skill name="Skill02_ID" id="11510" level="5" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="11508" level="4" /> <!-- Assault Rush -->
|
||||
<skill id="11509" level="6" /> <!-- Crippling Attack -->
|
||||
<skill id="11510" level="5" /> <!-- Shadow Blade -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Aeore Eva's Saint -->
|
||||
<npc id="81007" level="94" type="L2Monster" name="Aorta" title="Aeore Eva's Saint" >
|
||||
<race>ELF</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="36" int="74" dex="32" wit="84" con="38" men="77">
|
||||
<vitals hp="13651" hpRegen="10.8" mp="11193" mpRegen="3.0" />
|
||||
<attack physical="1008" magical="7469" random="30" critical="63" accuracy="161" attackSpeed="400" type="SWORD" range="40" distance="80" width="120" />
|
||||
<defence physical="2406" magical="2627" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="85" />
|
||||
<run ground="129" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="HEALER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="7.5" />
|
||||
<height normal="23" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="11766" level="6" />
|
||||
<skill name="Skill02_ID" id="11814" level="6" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="11766" level="6" /> <!-- Dark Blast -->
|
||||
<skill id="11814" level="6" /> <!-- Dark Force -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Eviscerator -->
|
||||
<npc id="81008" level="94" type="L2Monster" name="Breezer" title="Eviscerator" >
|
||||
<race>ERTHEIA</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="89" int="40" dex="52" wit="37" con="84" men="39">
|
||||
<vitals hp="18857" hpRegen="10.8" mp="3863" mpRegen="3.0" />
|
||||
<attack physical="10198" magical="1305" random="30" critical="132" accuracy="177" attackSpeed="588" type="FIST" range="40" distance="80" width="120" />
|
||||
<defence physical="3388" magical="2450" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="88" />
|
||||
<run ground="141" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="FIGHTER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="6.5" />
|
||||
<height normal="19.2" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="30500" level="18" />
|
||||
<skill name="Skill02_ID" id="30504" level="6" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="30500" level="18" /> <!-- Lateral Hit -->
|
||||
<skill id="30504" level="6" /> <!-- Gravity Hit -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Sayha's Seer -->
|
||||
<npc id="81009" level="94" type="L2Monster" name="Hoppy" title="Sayha's Seer" >
|
||||
<race>ERTHEIA</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="37" int="79" dex="27" wit="76" con="42" men="80">
|
||||
<vitals hp="18857" hpRegen="10.8" mp="3863" mpRegen="3.0" />
|
||||
<attack physical="1242" magical="4784" random="30" critical="61" accuracy="177" attackSpeed="162" type="BLUNT" range="40" distance="80" width="120" />
|
||||
<defence physical="3388" magical="2450" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="88" />
|
||||
<run ground="141" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="BALANCED" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="6.5" />
|
||||
<height normal="19.2" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="30001" level="22" /> <!-- Hydro Attack -->
|
||||
<skill name="Skill02_ID" id="30019" level="5" /> <!-- Sayha's Word -->
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="30001" level="22" /> <!-- Hydro Attack -->
|
||||
<skill id="30019" level="5" /> <!-- Sayha's Word -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
</list>
|
26
L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/fpc_passive.xml
vendored
Normal file
26
L2J_Mobius_1.0_Ertheia/dist/game/data/stats/npcs/custom/fpc_passive.xml
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../xsd/npcs.xsd">
|
||||
<!-- Eviscerator -->
|
||||
<npc id="80000" level="94" type="L2Npc" name="Evi" >
|
||||
<race>ERTHEIA</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="103" int="40" dex="53" wit="37" con="84" men="39">
|
||||
<vitals hp="18857" hpRegen="10.8" mp="3863" mpRegen="3.0" />
|
||||
<attack physical="10198" magical="1305" random="30" critical="132" accuracy="177" attackSpeed="588" type="FIST" range="40" distance="80" width="120" />
|
||||
<defence physical="3388" magical="2450" />
|
||||
<attribute>
|
||||
<defence fire="200" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="88" />
|
||||
<run ground="141" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" undying="true" attackable="false" />
|
||||
<collision>
|
||||
<radius normal="6.5" />
|
||||
<height normal="19.2" />
|
||||
</collision>
|
||||
</npc>
|
||||
</list>
|
20
L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/FakePlayerChatData.xsd
vendored
Normal file
20
L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/FakePlayerChatData.xsd
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="list">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="fakePlayerChat" maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute type="xs:string" name="fpcName" use="required" />
|
||||
<xs:attribute type="xs:string" name="searchMethod" use="required" />
|
||||
<xs:attribute type="xs:string" name="searchText" use="required" />
|
||||
<xs:attribute type="xs:string" name="answers" use="required" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
45
L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/FakePlayerVisualData.xsd
vendored
Normal file
45
L2J_Mobius_1.0_Ertheia/dist/game/data/xsd/FakePlayerVisualData.xsd
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="list">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="fakePlayer" maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute type="xs:int" name="npcId"/>
|
||||
<xs:attribute type="xs:short" name="classId"/>
|
||||
<xs:attribute type="xs:byte" name="hair"/>
|
||||
<xs:attribute type="xs:byte" name="hairColor"/>
|
||||
<xs:attribute type="xs:byte" name="face"/>
|
||||
<xs:attribute type="xs:string" name="nameColor"/>
|
||||
<xs:attribute type="xs:string" name="titleColor"/>
|
||||
<xs:attribute type="xs:int" name="equipHead"/>
|
||||
<xs:attribute type="xs:int" name="equipLHand"/>
|
||||
<xs:attribute type="xs:int" name="equipRHand"/>
|
||||
<xs:attribute type="xs:int" name="equipGloves"/>
|
||||
<xs:attribute type="xs:int" name="equipChest"/>
|
||||
<xs:attribute type="xs:int" name="equipLegs"/>
|
||||
<xs:attribute type="xs:int" name="equipFeet"/>
|
||||
<xs:attribute type="xs:int" name="equipCloak"/>
|
||||
<xs:attribute type="xs:int" name="equipHair"/>
|
||||
<xs:attribute type="xs:int" name="equipHair2"/>
|
||||
<xs:attribute type="xs:int" name="agathionId"/>
|
||||
<xs:attribute type="xs:byte" name="weaponEnchantLevel"/>
|
||||
<xs:attribute type="xs:byte" name="armorEnchantLevel"/>
|
||||
<xs:attribute type="xs:boolean" name="fishing"/>
|
||||
<xs:attribute type="xs:int" name="baitLocationX"/>
|
||||
<xs:attribute type="xs:int" name="baitLocationY"/>
|
||||
<xs:attribute type="xs:int" name="baitLocationZ"/>
|
||||
<xs:attribute type="xs:byte" name="recommends"/>
|
||||
<xs:attribute type="xs:byte" name="nobleLevel"/>
|
||||
<xs:attribute type="xs:boolean" name="hero"/>
|
||||
<xs:attribute type="xs:long" name="clanId"/>
|
||||
<xs:attribute type="xs:byte" name="pledgeStatus"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
@ -201,6 +201,8 @@
|
||||
<xs:attribute name="hasSummoner" type="xs:boolean" />
|
||||
<xs:attribute name="canBeSown" type="xs:boolean" />
|
||||
<xs:attribute name="isDeathPenalty" type="xs:boolean" />
|
||||
<xs:attribute name="fakePlayer" type="xs:boolean" />
|
||||
<xs:attribute name="fakePlayerTalkable" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="skill_list" minOccurs="0" maxOccurs="1">
|
||||
|
@ -116,6 +116,7 @@ public final class Config
|
||||
public static final String CUSTOM_DEBUG_VOICE_COMMAND_CONFIG_FILE = "./config/Custom/DebugVoiceCommand.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_MULTILANGUAL_SUPPORT_CONFIG_FILE = "./config/Custom/MultilingualSupport.ini";
|
||||
public static final String CUSTOM_NPC_STAT_MULTIPIERS_CONFIG_FILE = "./config/Custom/NpcStatMultipliers.ini";
|
||||
@ -1146,6 +1147,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;
|
||||
@ -2558,6 +2569,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);
|
||||
ENABLE_FIND_PVP = FindPvP.getBoolean("EnableFindPvP", false);
|
||||
|
@ -60,6 +60,7 @@ import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EventEngineData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ExtendDropData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FishingData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.HennaData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.HitConditionBonusData;
|
||||
@ -109,6 +110,7 @@ import com.l2jmobius.gameserver.instancemanager.CommissionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortSiegeManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||
@ -282,6 +284,8 @@ public class GameServer
|
||||
printSection("NPCs");
|
||||
SkillLearnData.getInstance();
|
||||
NpcData.getInstance();
|
||||
FakePlayerData.getInstance();
|
||||
FakePlayerChatManager.getInstance();
|
||||
ExtendDropData.getInstance();
|
||||
SpawnsData.getInstance();
|
||||
WalkingManager.getInstance();
|
||||
|
@ -34,6 +34,7 @@ import com.l2jmobius.gameserver.GameTimeController;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.enums.AISkillScope;
|
||||
import com.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
import com.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
|
||||
import com.l2jmobius.gameserver.model.AggroInfo;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
@ -53,6 +54,7 @@ import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnAttackableFactionCall;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.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.Skill;
|
||||
import com.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
@ -356,7 +358,73 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
||||
// A L2Attackable isn't aggressive during 10s after its spawn because _globalAggro is set to -10
|
||||
if (_globalAggro >= 0)
|
||||
{
|
||||
if (npc.isAggressive() || (npc instanceof L2GuardInstance))
|
||||
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().getAllSkills())
|
||||
{
|
||||
SkillCaster.triggerCast(npc, null, skillHolder.getSkill(), null, false);
|
||||
}
|
||||
npc.broadcastInfo(); // ? check if this is necessary
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getFakePlayerDrops().remove(itemIndex);
|
||||
}
|
||||
npc.setRunning();
|
||||
}
|
||||
}
|
||||
else if (npc.isAggressive() || (npc instanceof L2GuardInstance))
|
||||
{
|
||||
final int range = npc instanceof L2GuardInstance ? 500 : npc.getAggroRange(); // TODO Make sure how guards behave towards players.
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Character.class, range, t ->
|
||||
@ -364,7 +432,18 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
||||
// For each L2Character check if the target is autoattackable
|
||||
if (isAggressiveTowards(t)) // check aggression
|
||||
{
|
||||
if (t.isPlayable())
|
||||
if (t.isFakePlayer())
|
||||
{
|
||||
if (!npc.isFakePlayer() || (npc.isFakePlayer() && Config.FAKE_PLAYER_AGGRO_FPC))
|
||||
{
|
||||
final int hating = npc.getHating(t);
|
||||
if (hating == 0)
|
||||
{
|
||||
npc.addDamageHate(t, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t.isPlayable())
|
||||
{
|
||||
final TerminateReturn term = EventDispatcher.getInstance().notifyEvent(new OnAttackableHate(getActiveChar(), t.getActingPlayer(), t.isSummon()), getActiveChar(), TerminateReturn.class);
|
||||
if ((term != null) && term.terminate())
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -316,6 +316,8 @@ public class NpcData implements IGameXmlReader
|
||||
set.set("hasSummoner", parseBoolean(attrs, "hasSummoner"));
|
||||
set.set("canBeSown", parseBoolean(attrs, "canBeSown"));
|
||||
set.set("isDeathPenalty", parseBoolean(attrs, "isDeathPenalty"));
|
||||
set.set("fakePlayer", parseBoolean(attrs, "fakePlayer"));
|
||||
set.set("fakePlayerTalkable", parseBoolean(attrs, "fakePlayerTalkable"));
|
||||
break;
|
||||
}
|
||||
case "skill_list":
|
||||
|
@ -250,6 +250,11 @@ public class SpawnsData implements IGameXmlReader
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Config.FAKE_PLAYERS_ENABLED && template.isFakePlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("parameters".equalsIgnoreCase(d.getNodeName()))
|
||||
|
@ -41,6 +41,8 @@ import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
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;
|
||||
@ -210,15 +212,14 @@ public final class BotReportTable
|
||||
public boolean reportBot(L2PcInstance reporter)
|
||||
{
|
||||
final L2Object target = reporter.getTarget();
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -229,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_BATTLEGROUND_WHILE_YOU_ARE_AN_OPPOSING_CLAN_MEMBER_DURING_A_CLAN_WAR_OR_WHILE_PARTICIPATING_IN_THE_OLYMPIAD);
|
||||
return false;
|
||||
@ -241,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_XP_AFTER_CONNECTING);
|
||||
return false;
|
||||
@ -320,15 +321,18 @@ public final class BotReportTable
|
||||
}
|
||||
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_WAS_REPORTED_AS_A_BOT);
|
||||
sm.addCharName(bot);
|
||||
sm.addString(bot.getName());
|
||||
reporter.sendPacket(sm);
|
||||
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_USED_A_REPORT_POINT_ON_C1_YOU_HAVE_S2_POINTS_REMAINING_ON_THIS_ACCOUNT);
|
||||
sm.addCharName(bot);
|
||||
sm.addString(bot.getName());
|
||||
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;
|
||||
@ -202,11 +203,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);
|
||||
|
@ -217,6 +217,7 @@ public abstract class IdFactory
|
||||
cleanCount += stmt.executeUpdate("DELETE FROM character_offline_trade_items WHERE character_offline_trade_items.charId NOT IN (SELECT charId FROM characters);");
|
||||
cleanCount += stmt.executeUpdate("DELETE FROM character_tpbookmark WHERE character_tpbookmark.charId NOT IN (SELECT charId FROM characters);");
|
||||
cleanCount += stmt.executeUpdate("DELETE FROM character_variables WHERE character_variables.charId NOT IN (SELECT charId FROM characters);");
|
||||
cleanCount += stmt.executeUpdate("DELETE FROM bot_reported_char_data WHERE bot_reported_char_data.botId NOT IN (SELECT charId FROM characters);");
|
||||
|
||||
// If the clan does not exist...
|
||||
cleanCount += stmt.executeUpdate("DELETE FROM clan_privs WHERE clan_privs.clan_id NOT IN (SELECT clan_id FROM clan_data);");
|
||||
|
@ -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.util.IGameXmlReader;
|
||||
import com.l2jmobius.commons.util.Rnd;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
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)
|
||||
{
|
||||
ThreadPoolManager.schedule(() -> manageResponce(player, fpcName, message), Rnd.get(MIN_DELAY, MAX_DELAY));
|
||||
}
|
||||
|
||||
public void manageChat(L2PcInstance player, String fpcName, String message, int minDelay, int maxDelay)
|
||||
{
|
||||
ThreadPoolManager.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.gameserver.ThreadPoolManager;
|
||||
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;
|
||||
}
|
||||
@ -91,12 +92,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)
|
||||
{
|
||||
|
@ -365,6 +365,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
|
||||
|
@ -70,6 +70,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.npc.OnAttackableAggr
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnAttackableAttack;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.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;
|
||||
@ -279,7 +280,7 @@ public class L2Attackable extends L2Npc
|
||||
|
||||
public synchronized boolean getMustRewardExpSP()
|
||||
{
|
||||
return _mustGiveExpSp;
|
||||
return _mustGiveExpSp && !isFakePlayer();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -958,6 +959,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 (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.getAllSkills())
|
||||
{
|
||||
SkillCaster.triggerCast(mainDamageDealer, null, skillHolder.getSkill(), null, false);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1045,7 +1079,7 @@ public class L2Attackable extends L2Npc
|
||||
*/
|
||||
public void doEventDrop(L2Character lastAttacker)
|
||||
{
|
||||
if (lastAttacker == null)
|
||||
if ((lastAttacker == null) || isFakePlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -1419,6 +1453,15 @@ public class L2Attackable extends L2Npc
|
||||
_harvestItem.set(null);
|
||||
_sweepItems.set(null);
|
||||
|
||||
// fake players
|
||||
if (isFakePlayer())
|
||||
{
|
||||
getFakePlayerDrops().clear(); // Clear existing fake player drops
|
||||
setReputation(0); // reset reputation
|
||||
setScriptValue(0); // remove pvp flag
|
||||
setRunning(); // don't walk
|
||||
}
|
||||
|
||||
// Clear mod Seeded stat
|
||||
_seeded = false;
|
||||
_seed = null;
|
||||
|
@ -29,6 +29,7 @@ import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@ -61,6 +62,7 @@ import com.l2jmobius.gameserver.enums.UserInfoType;
|
||||
import com.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.TimersManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jmobius.gameserver.model.CharEffectList;
|
||||
@ -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.ExTeleportToLocationActivate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.FakePlayerInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MoveToLocation;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcInfo;
|
||||
@ -202,6 +205,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
private double _hpUpdateDecCheck = .0;
|
||||
private double _hpUpdateInterval = .0;
|
||||
|
||||
private int _reputation = 0;
|
||||
|
||||
/** Map containing all skills of this character. */
|
||||
private final Map<Integer, Skill> _skills = new ConcurrentSkipListMap<>();
|
||||
/** Map containing the skill reuse time stamps. */
|
||||
@ -270,6 +275,9 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
/** A map holding info about basic property mesmerizing system. */
|
||||
private volatile Map<BasicProperty, BasicPropertyResist> _basicPropertyResists;
|
||||
|
||||
/** 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
|
||||
@ -1207,6 +1215,17 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
broadcastPacket(attack);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify AI with EVT_READY_TO_ACT
|
||||
ThreadPoolManager.schedule(new NotifyAITask(this, CtrlEvent.EVT_READY_TO_ACT), timeAtk);
|
||||
}
|
||||
@ -2317,7 +2336,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));
|
||||
}
|
||||
@ -2945,7 +2968,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));
|
||||
}
|
||||
@ -4127,7 +4154,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
public boolean isInsidePeaceZone(L2Object attacker, L2Object target)
|
||||
{
|
||||
final Instance instanceWorld = getInstanceWorld();
|
||||
if ((target == null) || !(target.isPlayable() && attacker.isPlayable()) || ((instanceWorld != null) && instanceWorld.isPvP()))
|
||||
if ((target == null) || !((target.isPlayable() || target.isFakePlayer()) && attacker.isPlayable()) || ((instanceWorld != null) && instanceWorld.isPvP()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -5535,6 +5562,16 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
return _basicPropertyResists.computeIfAbsent(basicProperty, k -> new BasicPropertyResist());
|
||||
}
|
||||
|
||||
public int getReputation()
|
||||
{
|
||||
return _reputation;
|
||||
}
|
||||
|
||||
public void setReputation(int reputation)
|
||||
{
|
||||
_reputation = reputation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the distance to target.
|
||||
* @param target the target
|
||||
@ -5549,4 +5586,9 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
|
||||
{
|
||||
_cursorKeyMovement = value;
|
||||
}
|
||||
|
||||
public List<L2ItemInstance> getFakePlayerDrops()
|
||||
{
|
||||
return _fakePlayerDrops;
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.enums.ShotType;
|
||||
import com.l2jmobius.gameserver.enums.Team;
|
||||
import com.l2jmobius.gameserver.enums.UserInfoType;
|
||||
import com.l2jmobius.gameserver.handler.BypassHandler;
|
||||
import com.l2jmobius.gameserver.handler.IBypassHandler;
|
||||
import com.l2jmobius.gameserver.instancemanager.CastleManager;
|
||||
@ -79,6 +80,7 @@ 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.spawns.NpcSpawnTemplate;
|
||||
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.network.NpcStringId;
|
||||
@ -86,6 +88,7 @@ import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExChangeNpcState;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowChannelingEffect;
|
||||
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.NpcInfo;
|
||||
@ -93,6 +96,8 @@ import com.l2jmobius.gameserver.network.serverpackets.NpcInfoAbnormalVisualEffec
|
||||
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.network.serverpackets.UserInfo;
|
||||
import com.l2jmobius.gameserver.taskmanager.DecayTaskManager;
|
||||
import com.l2jmobius.gameserver.util.Broadcast;
|
||||
|
||||
@ -125,6 +130,7 @@ public class L2Npc extends L2Character
|
||||
private boolean _isRandomAnimationEnabled = true;
|
||||
private boolean _isRandomWalkingEnabled = true;
|
||||
private boolean _isTalkable = getTemplate().isTalkable();
|
||||
private final boolean _isFakePlayer = getTemplate().isFakePlayer();
|
||||
|
||||
protected RandomAnimationTask _rAniTask;
|
||||
private int _currentLHandId; // normally this shouldn't change from the template, but there exist exceptions
|
||||
@ -365,7 +371,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));
|
||||
}
|
||||
@ -902,6 +912,78 @@ 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) && (getReputation() >= 0))
|
||||
{
|
||||
if (Config.FAKE_PLAYER_KILL_KARMA)
|
||||
{
|
||||
player.setReputation(player.getReputation() - Formulas.calculateKarmaGain(player.getPkKills(), killer.isSummon()));
|
||||
player.setPkKills(player.getPkKills() + 1);
|
||||
final UserInfo ui = new UserInfo(player, false);
|
||||
ui.addComponentType(UserInfoType.SOCIAL);
|
||||
player.sendPacket(ui);
|
||||
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.S13);
|
||||
sm.addString(msg);
|
||||
Broadcast.toAllOnlinePlayers(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
Broadcast.toAllOnlinePlayers(msg, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Config.FAKE_PLAYER_KILL_PVP)
|
||||
{
|
||||
player.setPvpKills(player.getPvpKills() + 1);
|
||||
final UserInfo ui = new UserInfo(player, false);
|
||||
ui.addComponentType(UserInfoType.SOCIAL);
|
||||
player.sendPacket(ui);
|
||||
// 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.S13);
|
||||
sm.addString(msg);
|
||||
Broadcast.toAllOnlinePlayers(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
Broadcast.toAllOnlinePlayers(msg, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecayTaskManager.getInstance().add(this);
|
||||
|
||||
final L2Spawn spawn = getSpawn();
|
||||
@ -1211,7 +1293,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));
|
||||
}
|
||||
@ -1455,12 +1541,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++)
|
||||
@ -1476,15 +1562,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);
|
||||
@ -1509,14 +1595,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
|
||||
@ -1580,6 +1666,12 @@ public class L2Npc extends L2Character
|
||||
return Config.SHOP_MIN_RANGE_FROM_NPC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFakePlayer()
|
||||
{
|
||||
return _isFakePlayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The player's object Id this NPC is cloning.
|
||||
*/
|
||||
|
@ -304,8 +304,6 @@ public abstract class L2Playable extends L2Character
|
||||
|
||||
public abstract void doPickupItem(L2Object object);
|
||||
|
||||
public abstract int getReputation();
|
||||
|
||||
public abstract boolean useMagic(Skill skill, L2ItemInstance item, boolean forceUse, boolean dontMove);
|
||||
|
||||
public abstract void storeMe();
|
||||
|
@ -725,7 +725,7 @@ public abstract class L2Summon extends L2Playable
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2_S4);
|
||||
sm.addNpcName(this);
|
||||
sm.addCharName(target);
|
||||
sm.addString(target.getName());
|
||||
sm.addInt(damage);
|
||||
sm.addPopup(target.getObjectId(), getObjectId(), (damage * -1));
|
||||
}
|
||||
@ -743,7 +743,7 @@ public abstract class L2Summon extends L2Playable
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
|
||||
sm.addNpcName(this);
|
||||
sm.addCharName(attacker);
|
||||
sm.addString(attacker.getName());
|
||||
sm.addInt((int) damage);
|
||||
sendPacket(sm);
|
||||
}
|
||||
@ -905,6 +905,10 @@ public abstract class L2Summon extends L2Playable
|
||||
{
|
||||
setTarget(target);
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
if (target.isFakePlayer())
|
||||
{
|
||||
getOwner().updatePvPStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ public class DoppelgangerInstance extends L2Npc
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2_S4);
|
||||
sm.addNpcName(this);
|
||||
sm.addCharName(target);
|
||||
sm.addString(target.getName());
|
||||
sm.addInt(damage);
|
||||
sm.addPopup(target.getObjectId(), getObjectId(), (damage * -1));
|
||||
}
|
||||
@ -165,7 +165,7 @@ public class DoppelgangerInstance extends L2Npc
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
|
||||
sm.addNpcName(this);
|
||||
sm.addCharName(attacker);
|
||||
sm.addString(attacker.getName());
|
||||
sm.addInt((int) damage);
|
||||
sendPacket(sm);
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ public class L2GuardInstance extends L2Attackable
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
if (attacker.isMonster())
|
||||
if (attacker.isMonster() && !attacker.isFakePlayer())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -154,6 +154,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())
|
||||
{
|
||||
|
@ -69,6 +69,11 @@ 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))
|
||||
{
|
||||
@ -77,7 +82,7 @@ public class L2MonsterInstance extends L2Attackable
|
||||
|
||||
if (attacker.isMonster())
|
||||
{
|
||||
return false;
|
||||
return attacker.isFakePlayer();
|
||||
}
|
||||
|
||||
// Anything considers monsters friendly except Players, Attackables (Guards, Friendly NPC), Traps and EffectPoints.
|
||||
|
@ -445,9 +445,6 @@ public final class L2PcInstance extends L2Playable
|
||||
/** The Experience of the L2PcInstance before the last Death Penalty */
|
||||
private long _expBeforeDeath;
|
||||
|
||||
/** The Reputation of the L2PcInstance */
|
||||
private int _reputation;
|
||||
|
||||
/** The number of player killed during a PvP (the player killed was PvP Flagged) */
|
||||
private int _pvpKills;
|
||||
|
||||
@ -1992,24 +1989,16 @@ public final class L2PcInstance extends L2Playable
|
||||
return _expBeforeDeath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the reputation of the PlayerInstance.
|
||||
*/
|
||||
@Override
|
||||
public int getReputation()
|
||||
{
|
||||
return _reputation;
|
||||
}
|
||||
|
||||
public void setInitialReputation(int reputation)
|
||||
{
|
||||
_reputation = reputation;
|
||||
super.setReputation(reputation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reputation of the PlayerInstance and send a Server->Client packet StatusUpdate (broadcast).
|
||||
* @param reputation
|
||||
*/
|
||||
@Override
|
||||
public void setReputation(int reputation)
|
||||
{
|
||||
// Notify to scripts.
|
||||
@ -2035,7 +2024,9 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
});
|
||||
}
|
||||
_reputation = reputation;
|
||||
|
||||
super.setReputation(reputation);
|
||||
|
||||
sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOUR_REPUTATION_HAS_BEEN_CHANGED_TO_S1).addInt(getReputation()));
|
||||
broadcastReputation();
|
||||
}
|
||||
@ -4655,6 +4646,10 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
super.doAttack(target);
|
||||
setRecentFakeDeath(false);
|
||||
if (target.isFakePlayer())
|
||||
{
|
||||
updatePvPStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -4982,22 +4977,42 @@ 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);
|
||||
|
||||
if (L2Event.isParticipant(pk))
|
||||
if (pk != null)
|
||||
{
|
||||
pk.getEventStatus().addKill(this);
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerPvPKill(pk, this), this);
|
||||
|
||||
if (L2Event.isParticipant(pk))
|
||||
{
|
||||
pk.getEventStatus().addKill(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))
|
||||
{
|
||||
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.S13);
|
||||
@ -5011,7 +5026,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.S13);
|
||||
@ -5025,20 +5040,9 @@ public final class L2PcInstance extends L2Playable
|
||||
}
|
||||
}
|
||||
|
||||
// pvp/pk item rewards
|
||||
if (!(Config.DISABLE_REWARDS_IN_INSTANCES && (getInstanceId() != 0)) && //
|
||||
!(Config.DISABLE_REWARDS_IN_PVP_ZONES && isInsideZone(ZoneId.PVP)))
|
||||
if (fpcKill && Config.FAKE_PLAYER_KILL_KARMA && (getPvpFlag() == 0) && (getReputation() >= 0))
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
killer.setReputation(killer.getReputation() - 150);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5631,6 +5635,14 @@ public final class L2PcInstance extends L2Playable
|
||||
return (getActiveRequester() != null) || (_activeTradeList != null) || (_requestExpireTime > GameTimeController.getInstance().getGameTicks());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by fake players to emulate proper behavior.
|
||||
*/
|
||||
public void blockRequest()
|
||||
{
|
||||
_requestExpireTime = GameTimeController.getInstance().getGameTicks() + (REQUEST_TIMEOUT * GameTimeController.TICKS_PER_SECOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the Warehouse to be used in next activity.
|
||||
* @param partner
|
||||
@ -11568,7 +11580,7 @@ public final class L2PcInstance extends L2Playable
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2_S4);
|
||||
sm.addPcName(this);
|
||||
sm.addCharName(target);
|
||||
sm.addString(target.getName());
|
||||
sm.addInt(damage);
|
||||
sm.addPopup(target.getObjectId(), getObjectId(), -damage);
|
||||
}
|
||||
|
@ -178,6 +178,7 @@ public final class L2TrapInstance extends L2Npc
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReputation()
|
||||
{
|
||||
return _owner != null ? _owner.getReputation() : 0;
|
||||
@ -265,7 +266,7 @@ public final class L2TrapInstance extends L2Npc
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2_S4);
|
||||
sm.addCharName(this);
|
||||
sm.addCharName(target);
|
||||
sm.addString(target.getName());
|
||||
sm.addInt(damage);
|
||||
sm.addPopup(target.getObjectId(), getObjectId(), (damage * -1));
|
||||
_owner.sendPacket(sm);
|
||||
|
@ -214,7 +214,7 @@ public class PcStatus extends PlayableStatus
|
||||
}
|
||||
}
|
||||
|
||||
if (attacker.isPlayable() && (caster.getCurrentCp() > 0))
|
||||
if ((attacker.isPlayable() || attacker.isFakePlayer()) && (caster.getCurrentCp() > 0))
|
||||
{
|
||||
if (caster.getCurrentCp() > transferDmg)
|
||||
{
|
||||
@ -236,7 +236,7 @@ public class PcStatus extends PlayableStatus
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreCP && attacker.isPlayable())
|
||||
if (!ignoreCP && (attacker.isPlayable() || attacker.isFakePlayer()))
|
||||
{
|
||||
if (getCurrentCp() >= value)
|
||||
{
|
||||
@ -255,7 +255,7 @@ public class PcStatus extends PlayableStatus
|
||||
// Send a System Message to the L2PcInstance
|
||||
SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2);
|
||||
smsg.addString(getActiveChar().getName());
|
||||
smsg.addCharName(attacker);
|
||||
smsg.addString(attacker.getName());
|
||||
smsg.addInt(fullValue);
|
||||
getActiveChar().sendPacket(smsg);
|
||||
|
||||
|
@ -78,6 +78,8 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
||||
private boolean _randomWalk;
|
||||
private boolean _randomAnimation;
|
||||
private boolean _flying;
|
||||
private boolean _fakePlayer;
|
||||
private boolean _fakePlayerTalkable;
|
||||
private boolean _canMove;
|
||||
private boolean _noSleepMode;
|
||||
private boolean _passableDoor;
|
||||
@ -157,6 +159,8 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
||||
_randomWalk = set.getBoolean("randomWalk", !_type.equals("L2Guard"));
|
||||
_randomAnimation = set.getBoolean("randomAnimation", 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);
|
||||
@ -390,6 +394,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;
|
||||
@ -757,7 +771,7 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
||||
}
|
||||
|
||||
// premium chance
|
||||
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
|
||||
if (Config.PREMIUM_SYSTEM_ENABLED && (killer.getActingPlayer() != null) && killer.getActingPlayer().hasPremiumStatus())
|
||||
{
|
||||
if (Config.PREMIUM_RATE_DROP_CHANCE_BY_ID.get(dropItem.getItemId()) != null)
|
||||
{
|
||||
@ -803,7 +817,7 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
||||
}
|
||||
|
||||
// premium chance
|
||||
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
|
||||
if (Config.PREMIUM_SYSTEM_ENABLED && (killer.getActingPlayer() != null) && killer.getActingPlayer().hasPremiumStatus())
|
||||
{
|
||||
if (Config.PREMIUM_RATE_DROP_AMOUNT_BY_ID.get(dropItem.getItemId()) != null)
|
||||
{
|
||||
@ -834,7 +848,7 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
||||
case LUCKY_DROP:
|
||||
{
|
||||
// try chance before luck
|
||||
if (((Rnd.nextDouble() * 100) < dropItem.getChance()) && killer.getActingPlayer().tryLuck())
|
||||
if (((Rnd.nextDouble() * 100) < dropItem.getChance()) && (killer.getActingPlayer() != null) && killer.getActingPlayer().tryLuck())
|
||||
{
|
||||
return new ItemHolder(dropItem.getItemId(), Rnd.get(dropItem.getMin(), dropItem.getMax()));
|
||||
}
|
||||
@ -845,7 +859,7 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
||||
// chance
|
||||
double rateChance = Config.RATE_SPOIL_DROP_CHANCE_MULTIPLIER;
|
||||
// premium chance
|
||||
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
|
||||
if (Config.PREMIUM_SYSTEM_ENABLED && (killer.getActingPlayer() != null) && killer.getActingPlayer().hasPremiumStatus())
|
||||
{
|
||||
rateChance *= Config.PREMIUM_RATE_SPOIL_CHANCE;
|
||||
}
|
||||
@ -858,7 +872,7 @@ public final class L2NpcTemplate extends L2CharTemplate implements IIdentifiable
|
||||
// amount is calculated after chance returned success
|
||||
double rateAmount = Config.RATE_SPOIL_DROP_AMOUNT_MULTIPLIER;
|
||||
// premium amount
|
||||
if (Config.PREMIUM_SYSTEM_ENABLED && killer.getActingPlayer().hasPremiumStatus())
|
||||
if (Config.PREMIUM_SYSTEM_ENABLED && (killer.getActingPlayer() != null) && killer.getActingPlayer().hasPremiumStatus())
|
||||
{
|
||||
rateAmount *= Config.PREMIUM_RATE_SPOIL_AMOUNT;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -277,16 +277,16 @@ public final class L2ItemInstance extends L2Object
|
||||
* <BR>
|
||||
* <li>Do Pickup Item : PCInstance and Pet</li><BR>
|
||||
* <BR>
|
||||
* @param player Player that pick up the item
|
||||
* @param character Character that pick up the item
|
||||
*/
|
||||
public final void pickupMe(L2Character player)
|
||||
public final void pickupMe(L2Character character)
|
||||
{
|
||||
assert getWorldRegion() != null;
|
||||
|
||||
final L2WorldRegion oldregion = getWorldRegion();
|
||||
|
||||
// Create a server->client GetItem packet to pick up the L2ItemInstance
|
||||
player.broadcastPacket(new GetItem(this, player.getObjectId()));
|
||||
character.broadcastPacket(new GetItem(this, character.getObjectId()));
|
||||
|
||||
synchronized (this)
|
||||
{
|
||||
@ -305,10 +305,10 @@ public final class L2ItemInstance extends L2Object
|
||||
// Remove the L2ItemInstance from the world
|
||||
L2World.getInstance().removeVisibleObject(this, oldregion);
|
||||
|
||||
if (player.isPlayer())
|
||||
if (character.isPlayer())
|
||||
{
|
||||
// Notify to scripts
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemPickup(player.getActingPlayer(), this), getItem());
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerItemPickup(character.getActingPlayer(), this), getItem());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1076,7 +1076,7 @@ public final class Skill implements IIdentifiable
|
||||
|
||||
public boolean checkCondition(L2Character activeChar, L2Object object)
|
||||
{
|
||||
if (activeChar.canOverrideCond(PcCondOverride.SKILL_CONDITIONS) && !Config.GM_SKILL_RESTRICTION)
|
||||
if (activeChar.isFakePlayer() || (activeChar.canOverrideCond(PcCondOverride.SKILL_CONDITIONS) && !Config.GM_SKILL_RESTRICTION))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ import com.l2jmobius.gameserver.enums.ItemSkillType;
|
||||
import com.l2jmobius.gameserver.enums.NextActionType;
|
||||
import com.l2jmobius.gameserver.enums.StatusUpdateType;
|
||||
import com.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
import com.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
@ -159,7 +160,7 @@ public class SkillCaster implements Runnable
|
||||
}
|
||||
|
||||
// You should not heal/buff monsters without pressing the ctrl button.
|
||||
if (caster.isPlayer() && target.isMonster() && (skill.getEffectPoint() > 0) && !ctrlPressed)
|
||||
if (caster.isPlayer() && (target.isMonster() && !target.isFakePlayer()) && (skill.getEffectPoint() > 0) && !ctrlPressed)
|
||||
{
|
||||
caster.sendPacket(SystemMessageId.INVALID_TARGET);
|
||||
return null;
|
||||
@ -609,6 +610,10 @@ public class SkillCaster implements Runnable
|
||||
// Add hate to the attackable, and put it in the attack list.
|
||||
((L2Attackable) obj).addDamageHate(caster, 0, -skill.getEffectPoint());
|
||||
((L2Character) obj).addAttackerToAttackByList(caster);
|
||||
if (obj.isFakePlayer())
|
||||
{
|
||||
player.updatePvPStatus();
|
||||
}
|
||||
}
|
||||
|
||||
// notify target AI about the attack
|
||||
@ -617,10 +622,19 @@ public class SkillCaster implements Runnable
|
||||
((L2Character) obj).getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, caster);
|
||||
}
|
||||
}
|
||||
else if (((skill.getEffectPoint() > 0) && obj.isMonster()) || (obj.isPlayable() && ((obj.getActingPlayer().getPvpFlag() > 0) || (obj.getActingPlayer().getReputation() < 0))))
|
||||
else if (((skill.getEffectPoint() > 0) && obj.isMonster()) //
|
||||
|| (obj.isPlayable() && ((obj.getActingPlayer().getPvpFlag() > 0) //
|
||||
|| (((L2Character) obj).getReputation() < 0) //
|
||||
)))
|
||||
{
|
||||
// Supporting players or monsters result in pvpflag.
|
||||
player.updatePvPStatus();
|
||||
if (!obj.isFakePlayer() //
|
||||
|| (obj.isFakePlayer() //
|
||||
&& (!((L2Npc) obj).isScriptValue(0) //
|
||||
|| (((L2Npc) obj).getReputation() < 0))))
|
||||
{
|
||||
player.updatePvPStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,7 +644,7 @@ public class SkillCaster implements Runnable
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnNpcSkillSee(npcMob, player, skill, caster.isSummon(), targets.toArray(new L2Object[0])), npcMob);
|
||||
|
||||
// On Skill See logic
|
||||
if (npcMob.isAttackable())
|
||||
if (npcMob.isAttackable() && !npcMob.isFakePlayer())
|
||||
{
|
||||
final L2Attackable attackable = (L2Attackable) npcMob;
|
||||
|
||||
@ -652,6 +666,19 @@ public class SkillCaster implements Runnable
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (caster.isFakePlayer()) // fake player attacks player
|
||||
{
|
||||
if (target.isPlayable() || target.isFakePlayer())
|
||||
{
|
||||
final L2Npc npc = ((L2Npc) caster);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -1022,7 +1049,6 @@ public class SkillCaster implements Runnable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
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.FakePlayerInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ServerObjectInfo;
|
||||
|
||||
@ -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));
|
||||
}
|
||||
@ -80,7 +85,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));
|
||||
}
|
||||
|
@ -143,7 +143,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);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import java.util.logging.Logger;
|
||||
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;
|
||||
@ -100,7 +101,7 @@ public final class CharacterCreate implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.FORBIDDEN_NAMES.length > 1)
|
||||
if (Config.FORBIDDEN_NAMES.length > 0)
|
||||
{
|
||||
for (String st : Config.FORBIDDEN_NAMES)
|
||||
{
|
||||
@ -112,6 +113,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))
|
||||
{
|
||||
|
@ -18,10 +18,12 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
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.model.BlockList;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
public final class RequestBlock implements IClientIncomingPacket
|
||||
{
|
||||
@ -62,6 +64,24 @@ public final class RequestBlock implements IClientIncomingPacket
|
||||
case BLOCK:
|
||||
case UNBLOCK:
|
||||
{
|
||||
// TODO: Save in database? :P
|
||||
if (FakePlayerData.getInstance().isTalkable(_name))
|
||||
{
|
||||
if (_type == BLOCK)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_HAS_BEEN_ADDED_TO_YOUR_IGNORE_LIST);
|
||||
sm.addString(FakePlayerData.getInstance().getProperName(_name));
|
||||
activeChar.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_HAS_BEEN_REMOVED_FROM_YOUR_IGNORE_LIST);
|
||||
sm.addString(FakePlayerData.getInstance().getProperName(_name));
|
||||
activeChar.sendPacket(sm);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// can't use block/unblock for locating invisible characters
|
||||
if (targetId <= 0)
|
||||
{
|
||||
|
@ -19,6 +19,7 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
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.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExIsCharNameCreatable;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
@ -57,6 +58,10 @@ public class RequestCharacterNameCreatable implements IClientIncomingPacket
|
||||
{
|
||||
result = NAME_ALREADY_EXISTS;
|
||||
}
|
||||
else if (FakePlayerData.getInstance().getProperName(_name) != null)
|
||||
{
|
||||
result = NAME_ALREADY_EXISTS;
|
||||
}
|
||||
else if (_name.length() > 16)
|
||||
{
|
||||
result = INVALID_LENGTH;
|
||||
|
@ -18,9 +18,13 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.model.L2Party;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExDuelAskStart;
|
||||
@ -43,15 +47,67 @@ public final class RequestDuelStart implements IClientIncomingPacket
|
||||
return true;
|
||||
}
|
||||
|
||||
private void scheduleDeny(L2PcInstance player, String name)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_DECLINED_YOUR_CHALLENGE_TO_A_DUEL);
|
||||
sm.addString(name);
|
||||
player.sendPacket(sm);
|
||||
player.onTransactionResponse();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(L2GameClient client)
|
||||
{
|
||||
final L2PcInstance activeChar = client.getActiveChar();
|
||||
final L2PcInstance targetChar = L2World.getInstance().getPlayer(_player);
|
||||
if (activeChar == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (FakePlayerData.getInstance().isTalkable(_player))
|
||||
{
|
||||
final String name = FakePlayerData.getInstance().getProperName(_player);
|
||||
if (activeChar.isInsideZone(ZoneId.PVP) || activeChar.isInsideZone(ZoneId.PEACE) || activeChar.isInsideZone(ZoneId.SIEGE))
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_CANNOT_MAKE_A_CHALLENGE_TO_A_DUEL_BECAUSE_C1_IS_CURRENTLY_IN_A_DUEL_PROHIBITED_AREA_PEACEFUL_ZONE_BATTLE_ZONE_NEAR_WATER_RESTART_PROHIBITED_AREA);
|
||||
sm.addString(name);
|
||||
activeChar.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
boolean npcInRange = false;
|
||||
for (L2Npc npc : L2World.getInstance().getVisibleObjects(activeChar, L2Npc.class, 250))
|
||||
{
|
||||
if (npc.getName().equals(name))
|
||||
{
|
||||
npcInRange = true;
|
||||
}
|
||||
}
|
||||
if (!npcInRange)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_TOO_FAR_AWAY_TO_RECEIVE_A_DUEL_CHALLENGE);
|
||||
sm.addString(name);
|
||||
activeChar.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
if (activeChar.isProcessingRequest())
|
||||
{
|
||||
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_ON_ANOTHER_TASK_PLEASE_TRY_AGAIN_LATER);
|
||||
msg.addString(name);
|
||||
activeChar.sendPacket(msg);
|
||||
return;
|
||||
}
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_BEEN_CHALLENGED_TO_A_DUEL);
|
||||
sm.addString(name);
|
||||
activeChar.sendPacket(sm);
|
||||
ThreadPoolManager.schedule(() -> scheduleDeny(activeChar, name), 10000);
|
||||
activeChar.blockRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance targetChar = L2World.getInstance().getPlayer(_player);
|
||||
if (targetChar == null)
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL);
|
||||
|
@ -18,6 +18,8 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.enums.PartyDistributionType;
|
||||
import com.l2jmobius.gameserver.model.BlockList;
|
||||
import com.l2jmobius.gameserver.model.L2Party;
|
||||
@ -48,17 +50,49 @@ public final class RequestJoinParty implements IClientIncomingPacket
|
||||
return true;
|
||||
}
|
||||
|
||||
private void scheduleDeny(L2PcInstance player)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
if (player.getParty() == null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_PARTY_HAS_DISPERSED);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_PLAYER_DECLINED_TO_JOIN_YOUR_PARTY);
|
||||
}
|
||||
player.onTransactionResponse();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(L2GameClient client)
|
||||
{
|
||||
final L2PcInstance requestor = client.getActiveChar();
|
||||
final L2PcInstance target = L2World.getInstance().getPlayer(_name);
|
||||
|
||||
if (requestor == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (FakePlayerData.getInstance().isTalkable(_name))
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_BEEN_INVITED_TO_THE_PARTY);
|
||||
sm.addString(FakePlayerData.getInstance().getProperName(_name));
|
||||
requestor.sendPacket(sm);
|
||||
if (!requestor.isProcessingRequest())
|
||||
{
|
||||
ThreadPoolManager.schedule(() -> scheduleDeny(requestor), 10000);
|
||||
requestor.blockRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
requestor.sendPacket(SystemMessageId.WAITING_FOR_ANOTHER_REPLY);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance target = L2World.getInstance().getPlayer(_name);
|
||||
if (target == null)
|
||||
{
|
||||
requestor.sendPacket(SystemMessageId.YOU_MUST_FIRST_SELECT_A_USER_TO_INVITE_TO_YOUR_PARTY);
|
||||
|
@ -17,12 +17,15 @@
|
||||
package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.AskJoinPledge;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
@ -41,6 +44,17 @@ public final class RequestJoinPledge implements IClientIncomingPacket
|
||||
return true;
|
||||
}
|
||||
|
||||
private void scheduleDeny(L2PcInstance player, String name)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_DID_NOT_RESPOND_INVITATION_TO_THE_CLAN_HAS_BEEN_CANCELLED);
|
||||
sm.addString(name);
|
||||
player.sendPacket(sm);
|
||||
player.onTransactionResponse();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(L2GameClient client)
|
||||
{
|
||||
@ -56,6 +70,29 @@ public final class RequestJoinPledge implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if ((activeChar.getTarget() != null) && (FakePlayerData.getInstance().isTalkable(activeChar.getTarget().getName())))
|
||||
{
|
||||
if (FakePlayerData.getInstance().getInfo(activeChar.getTarget().getId()).getClanId() > 0)
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.THAT_PLAYER_ALREADY_BELONGS_TO_ANOTHER_CLAN);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!activeChar.isProcessingRequest())
|
||||
{
|
||||
ThreadPoolManager.schedule(() -> scheduleDeny(activeChar, activeChar.getTarget().getName()), 10000);
|
||||
activeChar.blockRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_ON_ANOTHER_TASK_PLEASE_TRY_AGAIN_LATER);
|
||||
msg.addString(activeChar.getTarget().getName());
|
||||
activeChar.sendPacket(msg);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance target = L2World.getInstance().getPlayer(_target);
|
||||
if (target == null)
|
||||
{
|
||||
|
@ -23,6 +23,7 @@ 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.AdminData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.instancemanager.MailManager;
|
||||
import com.l2jmobius.gameserver.model.BlockList;
|
||||
@ -195,6 +196,14 @@ public final class RequestSendPost implements IClientIncomingPacket
|
||||
}
|
||||
}
|
||||
|
||||
if (FakePlayerData.getInstance().isTalkable(_receiver))
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_BLOCKED_YOU_YOU_CANNOT_SEND_MAIL_TO_C1);
|
||||
sm.addString(FakePlayerData.getInstance().getProperName(_receiver));
|
||||
activeChar.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
final int receiverId = CharNameTable.getInstance().getIdByName(_receiver);
|
||||
if (receiverId <= 0)
|
||||
{
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.L2GameClient;
|
||||
@ -46,13 +47,29 @@ public final class RequestVoteNew implements IClientIncomingPacket
|
||||
}
|
||||
|
||||
final L2Object object = activeChar.getTarget();
|
||||
|
||||
if (!(object instanceof L2PcInstance))
|
||||
{
|
||||
if (object == null)
|
||||
{
|
||||
client.sendPacket(SystemMessageId.SELECT_TARGET);
|
||||
}
|
||||
else if (object.isFakePlayer() && FakePlayerData.getInstance().isTalkable(object.getName()))
|
||||
{
|
||||
if (activeChar.getRecomLeft() <= 0)
|
||||
{
|
||||
client.sendPacket(SystemMessageId.YOU_ARE_OUT_OF_RECOMMENDATIONS_TRY_AGAIN_LATER);
|
||||
return;
|
||||
}
|
||||
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_RECOMMENDED_C1_YOU_HAVE_S2_RECOMMENDATIONS_LEFT);
|
||||
sm.addString(FakePlayerData.getInstance().getProperName(object.getName()));
|
||||
sm.addInt(activeChar.getRecomLeft());
|
||||
client.sendPacket(sm);
|
||||
|
||||
activeChar.setRecomLeft(activeChar.getRecomLeft() - 1);
|
||||
client.sendPacket(new UserInfo(activeChar));
|
||||
client.sendPacket(new ExVoteSystemInfo(activeChar));
|
||||
}
|
||||
else
|
||||
{
|
||||
client.sendPacket(SystemMessageId.THAT_IS_AN_INCORRECT_TARGET);
|
||||
|
@ -18,11 +18,14 @@ package com.l2jmobius.gameserver.network.clientpackets;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.datatables.BotReportTable;
|
||||
import com.l2jmobius.gameserver.enums.PrivateStoreType;
|
||||
import com.l2jmobius.gameserver.model.BlockList;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||
import com.l2jmobius.gameserver.model.skills.AbnormalType;
|
||||
@ -47,6 +50,17 @@ public final class TradeRequest implements IClientIncomingPacket
|
||||
return true;
|
||||
}
|
||||
|
||||
private void scheduleDeny(L2PcInstance player, String name)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_DENIED_YOUR_REQUEST_TO_TRADE);
|
||||
sm.addString(name);
|
||||
player.sendPacket(sm);
|
||||
player.onTransactionResponse();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(L2GameClient client)
|
||||
{
|
||||
@ -94,6 +108,37 @@ public final class TradeRequest implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (FakePlayerData.getInstance().isTalkable(target.getName()))
|
||||
{
|
||||
final String name = FakePlayerData.getInstance().getProperName(target.getName());
|
||||
boolean npcInRange = false;
|
||||
for (L2Npc npc : L2World.getInstance().getVisibleObjects(player, L2Npc.class, 150))
|
||||
{
|
||||
if (npc.getName().equals(name))
|
||||
{
|
||||
npcInRange = true;
|
||||
}
|
||||
}
|
||||
if (!npcInRange)
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOUR_TARGET_IS_OUT_OF_RANGE));
|
||||
return;
|
||||
}
|
||||
if (!player.isProcessingRequest())
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_REQUESTED_A_TRADE_WITH_C1);
|
||||
sm.addString(name);
|
||||
player.sendPacket(sm);
|
||||
ThreadPoolManager.schedule(() -> scheduleDeny(player, name), 10000);
|
||||
player.blockRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_ALREADY_TRADING_WITH_SOMEONE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target.isPlayer())
|
||||
{
|
||||
client.sendPacket(SystemMessageId.INVALID_TARGET);
|
||||
|
@ -17,6 +17,8 @@
|
||||
package com.l2jmobius.gameserver.network.clientpackets.friend;
|
||||
|
||||
import com.l2jmobius.commons.network.PacketReader;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.model.BlockList;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
@ -38,6 +40,15 @@ public final class RequestFriendInvite implements IClientIncomingPacket
|
||||
return true;
|
||||
}
|
||||
|
||||
private void scheduleDeny(L2PcInstance player)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_FAILED_TO_ADD_A_FRIEND_TO_YOUR_FRIENDS_LIST));
|
||||
player.onTransactionResponse();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(L2GameClient client)
|
||||
{
|
||||
@ -47,6 +58,25 @@ public final class RequestFriendInvite implements IClientIncomingPacket
|
||||
return;
|
||||
}
|
||||
|
||||
if (FakePlayerData.getInstance().isTalkable(_name))
|
||||
{
|
||||
if (!activeChar.isProcessingRequest())
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_VE_REQUESTED_C1_TO_BE_ON_YOUR_FRIENDS_LIST);
|
||||
sm.addString(_name);
|
||||
activeChar.sendPacket(sm);
|
||||
ThreadPoolManager.schedule(() -> scheduleDeny(activeChar), 10000);
|
||||
activeChar.blockRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_ON_ANOTHER_TASK_PLEASE_TRY_AGAIN_LATER);
|
||||
sm.addString(_name);
|
||||
activeChar.sendPacket(sm);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance friend = L2World.getInstance().getPlayer(_name);
|
||||
|
||||
// Target is not found in the game.
|
||||
|
@ -22,6 +22,7 @@ import java.util.List;
|
||||
import com.l2jmobius.commons.network.PacketWriter;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.instancemanager.MentorManager;
|
||||
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;
|
||||
@ -53,21 +54,24 @@ public final class CreatureSay implements IClientOutgoingPacket
|
||||
_charLevel = sender.getLevel();
|
||||
_textType = messageType;
|
||||
_text = text;
|
||||
if (receiver.getFriendList().contains(sender.getObjectId()))
|
||||
if (receiver != null)
|
||||
{
|
||||
_mask |= 0x01;
|
||||
}
|
||||
if ((receiver.getClanId() > 0) && (receiver.getClanId() == sender.getClanId()))
|
||||
{
|
||||
_mask |= 0x02;
|
||||
}
|
||||
if ((MentorManager.getInstance().getMentee(receiver.getObjectId(), sender.getObjectId()) != null) || (MentorManager.getInstance().getMentee(sender.getObjectId(), receiver.getObjectId()) != null))
|
||||
{
|
||||
_mask |= 0x04;
|
||||
}
|
||||
if ((receiver.getAllyId() > 0) && (receiver.getAllyId() == sender.getAllyId()))
|
||||
{
|
||||
_mask |= 0x08;
|
||||
if (receiver.getFriendList().contains(sender.getObjectId()))
|
||||
{
|
||||
_mask |= 0x01;
|
||||
}
|
||||
if ((receiver.getClanId() > 0) && (receiver.getClanId() == sender.getClanId()))
|
||||
{
|
||||
_mask |= 0x02;
|
||||
}
|
||||
if ((MentorManager.getInstance().getMentee(receiver.getObjectId(), sender.getObjectId()) != null) || (MentorManager.getInstance().getMentee(sender.getObjectId(), receiver.getObjectId()) != null))
|
||||
{
|
||||
_mask |= 0x04;
|
||||
}
|
||||
if ((receiver.getAllyId() > 0) && (receiver.getAllyId() == sender.getAllyId()))
|
||||
{
|
||||
_mask |= 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
// Does not shows level
|
||||
@ -77,6 +81,23 @@ public final class CreatureSay implements IClientOutgoingPacket
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
_charName = name;
|
||||
_charLevel = sender.getLevel();
|
||||
_textType = messageType;
|
||||
_text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param objectId
|
||||
* @param messageType
|
||||
|
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* 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 java.util.Set;
|
||||
|
||||
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.skills.AbnormalVisualEffect;
|
||||
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 = 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.writeH(_npc.getRace().ordinal());
|
||||
packet.writeC(_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());
|
||||
|
||||
for (@SuppressWarnings("unused")
|
||||
int slot : getPaperdollOrderAugument())
|
||||
{
|
||||
packet.writeD(0x00);
|
||||
}
|
||||
|
||||
packet.writeC(_fpcHolder.getArmorEnchantLevel());
|
||||
|
||||
for (@SuppressWarnings("unused")
|
||||
int slot : getPaperdollOrderVisualId())
|
||||
{
|
||||
packet.writeD(0x00);
|
||||
}
|
||||
|
||||
packet.writeC(_npc.getScriptValue()); // getPvpFlag()
|
||||
packet.writeD(_npc.getReputation());
|
||||
|
||||
packet.writeD(_mAtkSpd);
|
||||
packet.writeD(_pAtkSpd);
|
||||
|
||||
packet.writeH(_runSpd);
|
||||
packet.writeH(_walkSpd);
|
||||
packet.writeH(_swimRunSpd);
|
||||
packet.writeH(_swimWalkSpd);
|
||||
packet.writeH(_flyRunSpd);
|
||||
packet.writeH(_flyWalkSpd);
|
||||
packet.writeH(_flyRunSpd);
|
||||
packet.writeH(_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);
|
||||
|
||||
packet.writeC(_npc.isInsideZone(ZoneId.WATER) ? 1 : 0);
|
||||
packet.writeH(_fpcHolder.getRecommends());
|
||||
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.writeC(_fpcHolder.getPledgeStatus());
|
||||
packet.writeH(0x00); // getPledgeType()
|
||||
|
||||
packet.writeD(_fpcHolder.getTitleColor());
|
||||
|
||||
packet.writeC(0x00); // isCursedWeaponEquipped
|
||||
|
||||
packet.writeD(0x00); // getAppearance().getVisibleClanId() > 0 ? getClan().getReputationScore() : 0
|
||||
packet.writeD(0x00); // getTransformationDisplayId()
|
||||
packet.writeD(_fpcHolder.getAgathionId());
|
||||
|
||||
packet.writeC(0x00);
|
||||
|
||||
packet.writeD(0x00); // getCurrentCp()
|
||||
packet.writeD(_npc.getMaxHp());
|
||||
packet.writeD((int) Math.round(_npc.getCurrentHp()));
|
||||
packet.writeD(_npc.getMaxMp());
|
||||
packet.writeD((int) Math.round(_npc.getCurrentMp()));
|
||||
|
||||
packet.writeC(0x00);
|
||||
final Set<AbnormalVisualEffect> abnormalVisualEffects = _npc.getEffectList().getCurrentAbnormalVisualEffects();
|
||||
packet.writeD(abnormalVisualEffects.size() + (_npc.isInvisible() ? 1 : 0));
|
||||
for (AbnormalVisualEffect abnormalVisualEffect : abnormalVisualEffects)
|
||||
{
|
||||
packet.writeH(abnormalVisualEffect.getClientId());
|
||||
}
|
||||
if (_npc.isInvisible())
|
||||
{
|
||||
packet.writeH(AbnormalVisualEffect.STEALTH.getClientId());
|
||||
}
|
||||
packet.writeC(0x00); // cocPlayer.getPosition()
|
||||
packet.writeC((_fpcHolder.getHair() > 0) || (_fpcHolder.getEquipHair2() > 0) ? 0x01 : 0x00);
|
||||
packet.writeC(0x00); // Used Ability Points
|
||||
return true;
|
||||
}
|
||||
}
|
@ -149,6 +149,11 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
addComponentType(NpcInfoType.TITLE_NPCSTRINGID);
|
||||
}
|
||||
|
||||
if (_npc.getReputation() != 0)
|
||||
{
|
||||
addComponentType(NpcInfoType.REPUTATION);
|
||||
}
|
||||
|
||||
if (!_abnormalVisualEffects.isEmpty() || npc.isInvisible())
|
||||
{
|
||||
addComponentType(NpcInfoType.ABNORMALS);
|
||||
@ -402,7 +407,7 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
}
|
||||
if (containsMask(NpcInfoType.REPUTATION))
|
||||
{
|
||||
packet.writeD(0x00); // Name color
|
||||
packet.writeD(_npc.getReputation()); // Reputation
|
||||
}
|
||||
if (containsMask(NpcInfoType.CLAN))
|
||||
{
|
||||
|
@ -82,6 +82,7 @@ Customs:
|
||||
-Classmaster
|
||||
-Community board
|
||||
-Faction system
|
||||
-Fake players
|
||||
-Find PvP
|
||||
-NPC stat multipliers
|
||||
-Realtime offline trade
|
||||
|
@ -392,6 +392,9 @@
|
||||
<!-- ADMIN MESSAGES -->
|
||||
<admin command="admin_msg" accessLevel="100" />
|
||||
|
||||
<!-- ADMIN FAKE PLAYERS -->
|
||||
<admin command="admin_fakechat" accessLevel="100" />
|
||||
|
||||
<!-- ADMIN MOB GROUP -->
|
||||
<admin command="admin_mobmenu" accessLevel="100" />
|
||||
<admin command="admin_mobgroup_list" accessLevel="100" />
|
||||
|
33
L2J_Mobius_2.5_Underground/dist/game/config/Custom/FakePlayers.ini
vendored
Normal file
33
L2J_Mobius_2.5_Underground/dist/game/config/Custom/FakePlayers.ini
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
# Fake players
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Enable fake players.
|
||||
EnableFakePlayers = False
|
||||
|
||||
# Enable chatting with fake players.
|
||||
FakePlayerChat = True
|
||||
|
||||
# Enable shots usage for fake players.
|
||||
FakePlayerUseShots = True
|
||||
|
||||
# Reward PvP kills by killing fake players.
|
||||
FakePlayerKillsRewardPvP = True
|
||||
|
||||
# Fake player kills apply karma rules.
|
||||
FakePlayerUnflaggedKillsKarma = True
|
||||
|
||||
# Aggressive AI fake players attack nearby monsters.
|
||||
FakePlayerAggroMonsters = True
|
||||
|
||||
# Aggressive AI fake players attack nearby players.
|
||||
FakePlayerAggroPlayers = False
|
||||
|
||||
# Aggressive AI fake players attack nearby fake players.
|
||||
FakePlayerAggroFPC = False
|
||||
|
||||
# Fake players can drop items when killing monsters.
|
||||
FakePlayerCanDropItems = True
|
||||
|
||||
# Fake players can pickup dropped items.
|
||||
FakePlayerCanPickup = True
|
24
L2J_Mobius_2.5_Underground/dist/game/data/FakePlayerChatData.xml
vendored
Normal file
24
L2J_Mobius_2.5_Underground/dist/game/data/FakePlayerChatData.xml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Use lowercase for searchText and answers. -->
|
||||
<!-- You can use specific fpcName or ALL to use with all fpcs. -->
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/FakePlayerChatData.xsd">
|
||||
<fakePlayerChat fpcName="ALL" searchMethod="EQUALS" searchText="hi" answers="hello;hi;hi there;hello there" />
|
||||
<fakePlayerChat fpcName="ALL" searchMethod="EQUALS" searchText="hey" answers="hey hey;hey;hey there" />
|
||||
<fakePlayerChat fpcName="ALL" searchMethod="EQUALS" searchText="hello" answers="hello;hi;hi there;hello there" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="here?" answers="yes;busy;i look for something" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="whats up?" answers="good;busy;i look for something" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="what?" answers="something :P;something for me" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="why?" answers="because;i don't know;what?" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="really" answers="really;yes;of course" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="thanks" answers=":);:D;:*" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="EQUALS" searchText="thank you" answers=":);:D;:*" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="STARTS_WITH" searchText="how are you" answers="fine;good;busy" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="STARTS_WITH" searchText="do you know" answers="nope;no sorry;nope, i don't" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="STARTS_WITH" searchText="where can i" answers="i don't know;no clue;ask someone else :P" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="STARTS_WITH" searchText="can i ask you" answers="yes;what?;tell me" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="CONTAINS" searchText="server;ha;problem" answers="it's good;i don't know;i don't think so..." />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="CONTAINS" searchText="server;ha;bug" answers="it's good;i don't know;i don't think so..." />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="CONTAINS" searchText="is th;server;good" answers="it's good :D;i like it :P;yes it is :)" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="CONTAINS" searchText="where;you;go;?" answers="i look for something;checking stuff;looking for curius people :P" />
|
||||
<fakePlayerChat fpcName="Evi" searchMethod="CONTAINS" searchText="are;you;kidding" answers="^^;:D;:P" />
|
||||
</list>
|
37
L2J_Mobius_2.5_Underground/dist/game/data/FakePlayerVisualData.xml
vendored
Normal file
37
L2J_Mobius_2.5_Underground/dist/game/data/FakePlayerVisualData.xml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Values that can be set:
|
||||
int classId, int hair, int hairColor, int face, int nameColor, int titleColor, int equipRHand, int equipLHand, int equipHead,
|
||||
int equipGloves, int equipChest, int equipLegs, int equipFeet, int equipCloak, int equipHair, int equipHair2, int agathionId,
|
||||
int weaponEnchantLevel, int armorEnchantLevel, boolean fishing, int baitLocationX, int baitLocationY, int baitLocationZ,
|
||||
int recommends, int nobleLevel, boolean hero, int clanId, int pledgeStatus -->
|
||||
<!--
|
||||
####################################### Hero Weapons #####################################################
|
||||
Bow(37874) Crossbow(37875) Dagger(37868) Dual Blunt Weapon(37881) Dual Dagger(37880) Dual Sword(37879)
|
||||
Fist(37872) OneHand Blunt(37871) OneHand Magic Blunt(37877) One Hand Magic Sword(37876) One Hand Sword(37869)
|
||||
Spear(37873) Two-handed Magic Blunt Weapon(37878) Two-handed Sword(37870) Shield(37870) Sigil(37223)
|
||||
#############################################################################################################
|
||||
-->
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/FakePlayerVisualData.xsd">
|
||||
<!-- Non-Combat -->
|
||||
<fakePlayer npcId="80000" classId="188" hair="1" hairColor="1" face="0" equipRHand="17294" equipHead="37215" equipGloves="37216" equipChest="37213" equipLegs="37214" equipFeet="37217" equipCloak="40200" />
|
||||
|
||||
<!-- Combat -->
|
||||
<!-- Sigel Phoenix Knight -->
|
||||
<fakePlayer npcId="81001" classId="148" hair="0" hairColor="0" face="0" equipRHand="37869" equipLHand="37212" equipHead="37209" equipGloves="37210" equipChest="37207" equipLegs="37208" equipFeet="37211" equipCloak="30310" />
|
||||
<!-- Tyrr Titan -->
|
||||
<fakePlayer npcId="81002" classId="154" hair="0" hairColor="0" face="0" equipRHand="37870" equipHead="37215" equipGloves="37216" equipChest="37213" equipLegs="37214" equipFeet="37217" equipCloak="30311" />
|
||||
<!-- Othell Fortune Seeker -->
|
||||
<fakePlayer npcId="81003" classId="161" hair="0" hairColor="0" face="0" equipRHand="37880" equipHead="37215" equipGloves="37216" equipChest="37213" equipLegs="37214" equipFeet="37217" equipCloak="30312" />
|
||||
<!-- Yul Trickster -->
|
||||
<fakePlayer npcId="81004" classId="165" hair="0" hairColor="0" face="0" equipRHand="37875" equipHead="37215" equipGloves="37216" equipChest="37213" equipLegs="37214" equipFeet="37217" equipCloak="30313" />
|
||||
<!-- Feoh Archmage -->
|
||||
<fakePlayer npcId="81005" classId="166" hair="0" hairColor="0" face="0" equipRHand="37878" equipHead="37220" equipGloves="37221" equipChest="37218" equipLegs="37219" equipFeet="37222" equipCloak="30314" />
|
||||
<!-- Iss Spectral Dancer -->
|
||||
<fakePlayer npcId="81006" classId="173" hair="0" hairColor="0" face="0" equipRHand="37879" equipHead="37209" equipGloves="37210" equipChest="37207" equipLegs="37208" equipFeet="37211" equipCloak="30316" />
|
||||
<!-- Aeore Eva's Saint -->
|
||||
<fakePlayer npcId="81007" classId="180" hair="0" hairColor="0" face="0" equipRHand="37876" equipLHand="37223" equipHead="37220" equipGloves="37221" equipChest="37218" equipLegs="37219" equipFeet="37222" equipCloak="30317" />
|
||||
<!-- Eviscerator -->
|
||||
<fakePlayer npcId="81008" classId="188" hair="0" hairColor="0" face="0" equipRHand="37872" equipHead="37215" equipGloves="37216" equipChest="37213" equipLegs="37214" equipFeet="37217" equipCloak="40200" />
|
||||
<!-- Sayha's Seer -->
|
||||
<fakePlayer npcId="81009" classId="189" hair="0" hairColor="0" face="0" equipRHand="37878" equipHead="37220" equipGloves="37221" equipChest="37218" equipLegs="37219" equipFeet="37222" equipCloak="40201" />
|
||||
</list>
|
@ -2402,4 +2402,43 @@
|
||||
<point X="42630" Y="-48231" Z="-792" delay="0" run="true" />
|
||||
<point X="45069" Y="-48034" Z="-792" delay="0" run="true" />
|
||||
</route>
|
||||
<route name="FPC_Giran_Evi" repeat="true" repeatStyle="cycle">
|
||||
<target id="80000" spawnX="83485" spawnY="147998" spawnZ="-3407" />
|
||||
<point X="83485" Y="147998" Z="-3407" delay="10" run="true" /> <!-- Gatekeeper -->
|
||||
<point X="83575" Y="147722" Z="-3405" delay="32" run="true" /> <!-- Buffer -->
|
||||
<point X="82117" Y="147642" Z="-3469" delay="0" run="true" />
|
||||
<point X="82152" Y="147580" Z="-3469" delay="36" run="true" /> <!-- Olympiad Statue-->
|
||||
<point X="82084" Y="147569" Z="-3469" delay="12" run="true" /> <!-- Olympiad Manager -->
|
||||
<point X="81532" Y="147578" Z="-3469" delay="0" run="true" />
|
||||
<point X="81593" Y="146626" Z="-3533" delay="3" run="true" />
|
||||
<point X="81932" Y="146566" Z="-3533" delay="0" run="true" />
|
||||
<point X="82651" Y="146714" Z="-3466" delay="20" run="true" /> <!-- Dimesional Merchant -->
|
||||
<point X="82807" Y="146649" Z="-3465" delay="0" run="true" />
|
||||
<point X="83216" Y="146672" Z="-3465" delay="28" run="true" /> <!-- Warehouse -->
|
||||
<point X="83211" Y="146724" Z="-3467" delay="88" run="true" /> <!-- Warehouse 2 -->
|
||||
<point X="81659" Y="146555" Z="-3533" delay="3" run="true" />
|
||||
<point X="81283" Y="145519" Z="-3533" delay="0" run="true" />
|
||||
<point X="80375" Y="145484" Z="-3535" delay="28" run="true" /> <!-- Pochi -->
|
||||
<point X="80283" Y="145826" Z="-3533" delay="0" run="true" />
|
||||
<point X="79952" Y="145840" Z="-3496" delay="0" run="true" />
|
||||
<point X="79781" Y="145546" Z="-3496" delay="0" run="true" />
|
||||
<point X="79736" Y="145518" Z="-3495" delay="0" run="true" />
|
||||
<point X="79663" Y="145529" Z="-3496" delay="40" run="true" /> <!-- Galladucci -->
|
||||
<point X="79661" Y="145429" Z="-3495" delay="80" run="true" /> <!-- Alexandria -->
|
||||
<point X="79999" Y="145152" Z="-3496" delay="0" run="true" />
|
||||
<point X="80393" Y="145136" Z="-3533" delay="0" run="true" />
|
||||
<point X="81068" Y="145845" Z="-3533" delay="36" run="true" /> <!-- Pet Manager -->
|
||||
<point X="81061" Y="145563" Z="-3533" delay="0" run="true" />
|
||||
<point X="81563" Y="145532" Z="-3533" delay="3" run="true" />
|
||||
<point X="81692" Y="147231" Z="-3533" delay="32" run="true" /> <!-- Kiki -->
|
||||
<point X="81370" Y="147213" Z="-3533" delay="64" run="true" /> <!-- Plani -->
|
||||
<point X="81517" Y="147231" Z="-3533" delay="1" run="true" />
|
||||
<point X="81542" Y="147570" Z="-3469" delay="0" run="true" />
|
||||
<point X="81109" Y="147770" Z="-3469" delay="99" run="true" /> <!-- Moe -->
|
||||
<point X="81108" Y="149415" Z="-3469" delay="99" run="true" /> <!-- Auction House -->
|
||||
<point X="81413" Y="149700" Z="-3469" delay="52" run="true" /> <!-- Clan Hall Managers -->
|
||||
<point X="81718" Y="149626" Z="-3469" delay="60" run="true" /> <!-- Beauty Shop -->
|
||||
<point X="82815" Y="148840" Z="-3469" delay="3" run="true" />
|
||||
<point X="83307" Y="148431" Z="-3405" delay="21" run="true" /> <!-- Training Camp Manager -->
|
||||
</route>
|
||||
</routes>
|
@ -88,7 +88,7 @@ public final class Wisp extends AbstractNpcAI
|
||||
final L2Character creature = event.getSeen();
|
||||
final L2Npc npc = (L2Npc) event.getSeer();
|
||||
|
||||
if (creature.isPlayer())
|
||||
if (creature.isPlayer() || creature.isFakePlayer())
|
||||
{
|
||||
npc.setTarget(creature);
|
||||
npc.doCast(npc.getId() == WISP ? WISP_HEAL.getSkill() : LARGE_WISP_HEAL.getSkill());
|
||||
|
80
L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/FakePlayers/PvpFlaggingStopTask.java
vendored
Normal file
80
L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/FakePlayers/PvpFlaggingStopTask.java
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 custom.FakePlayers;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* TODO: Move it to L2Character.
|
||||
* @author Mobius
|
||||
*/
|
||||
public class PvpFlaggingStopTask extends AbstractNpcAI
|
||||
{
|
||||
private PvpFlaggingStopTask()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((npc == null) || npc.isDead())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (event.startsWith("FLAG_CHECK"))
|
||||
{
|
||||
final L2Object target = npc.getTarget();
|
||||
if ((target != null) && (target.isPlayable() || target.isFakePlayer()))
|
||||
{
|
||||
npc.setScriptValue(1); // in combat
|
||||
cancelQuestTimer("FINISH_FLAG" + npc.getObjectId(), npc, null);
|
||||
cancelQuestTimer("REMOVE_FLAG" + npc.getObjectId(), npc, null);
|
||||
startQuestTimer("FINISH_FLAG" + npc.getObjectId(), Config.PVP_NORMAL_TIME - 20000, npc, null);
|
||||
startQuestTimer("FLAG_CHECK" + npc.getObjectId(), 5000, npc, null);
|
||||
}
|
||||
}
|
||||
else if (event.startsWith("FINISH_FLAG"))
|
||||
{
|
||||
if (npc.isScriptValue(1))
|
||||
{
|
||||
npc.setScriptValue(2); // blink status
|
||||
npc.broadcastInfo(); // update flag status
|
||||
startQuestTimer("REMOVE_FLAG" + npc.getObjectId(), 20000, npc, null);
|
||||
}
|
||||
}
|
||||
else if (event.startsWith("REMOVE_FLAG"))
|
||||
{
|
||||
if (npc.isScriptValue(2))
|
||||
{
|
||||
npc.setScriptValue(0); // not in combat
|
||||
npc.broadcastInfo(); // update flag status
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PvpFlaggingStopTask();
|
||||
}
|
||||
}
|
115
L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/FakePlayers/RecieveAdventurerBuffs.java
vendored
Normal file
115
L2J_Mobius_2.5_Underground/dist/game/data/scripts/custom/FakePlayers/RecieveAdventurerBuffs.java
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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 custom.FakePlayers;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Town Fake Player walkers that receive buffs from Adventurer NPC.
|
||||
* @author Mobius
|
||||
*/
|
||||
public class RecieveAdventurerBuffs extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] ADVENTURERS_GUIDE =
|
||||
{
|
||||
32327,
|
||||
33950,
|
||||
};
|
||||
private static final int[] FAKE_PLAYER_IDS =
|
||||
{
|
||||
80000
|
||||
};
|
||||
// Skills
|
||||
// private static final SkillHolder KNIGHT = new SkillHolder(15648, 1); // Knight's Harmony (Adventurer)
|
||||
private static final SkillHolder WARRIOR = new SkillHolder(15649, 1); // Warrior's Harmony (Adventurer)
|
||||
private static final SkillHolder WIZARD = new SkillHolder(15650, 1); // Wizard's Harmony (Adventurer)
|
||||
private static final SkillHolder[] GROUP_BUFFS =
|
||||
{
|
||||
new SkillHolder(15642, 1), // Horn Melody (Adventurer)
|
||||
new SkillHolder(15643, 1), // Drum Melody (Adventurer)
|
||||
new SkillHolder(15644, 1), // Pipe Organ Melody (Adventurer)
|
||||
new SkillHolder(15645, 1), // Guitar Melody (Adventurer)
|
||||
new SkillHolder(15646, 1), // Harp Melody (Adventurer)
|
||||
new SkillHolder(15647, 1), // Lute Melody (Adventurer)
|
||||
new SkillHolder(15651, 1), // Prevailing Sonata (Adventurer)
|
||||
new SkillHolder(15652, 1), // Daring Sonata (Adventurer)
|
||||
new SkillHolder(15653, 1), // Refreshing Sonata (Adventurer)
|
||||
};
|
||||
|
||||
private RecieveAdventurerBuffs()
|
||||
{
|
||||
if (Config.FAKE_PLAYERS_ENABLED)
|
||||
{
|
||||
addSpawnId(FAKE_PLAYER_IDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.startsWith("AUTOBUFF") && (npc != null) && !npc.isDead())
|
||||
{
|
||||
if (!npc.isMoving())
|
||||
{
|
||||
for (L2Npc nearby : L2World.getInstance().getVisibleObjects(npc, L2Npc.class, 100))
|
||||
{
|
||||
if (CommonUtil.contains(ADVENTURERS_GUIDE, nearby.getId()))
|
||||
{
|
||||
for (SkillHolder holder : GROUP_BUFFS)
|
||||
{
|
||||
SkillCaster.triggerCast(nearby, npc, holder.getSkill());
|
||||
}
|
||||
if (ClassId.getClassId(FakePlayerData.getInstance().getInfo(npc.getId()).getClassId()).isMage())
|
||||
{
|
||||
SkillCaster.triggerCast(nearby, npc, WIZARD.getSkill());
|
||||
}
|
||||
else
|
||||
{
|
||||
SkillCaster.triggerCast(nearby, npc, WARRIOR.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
startQuestTimer("AUTOBUFF" + npc.getObjectId(), 30000, npc, null);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("AUTOBUFF" + npc.getObjectId(), 1000, npc, null);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RecieveAdventurerBuffs();
|
||||
}
|
||||
}
|
@ -79,6 +79,7 @@ import handlers.admincommandhandlers.AdminEnchant;
|
||||
import handlers.admincommandhandlers.AdminEventEngine;
|
||||
import handlers.admincommandhandlers.AdminEvents;
|
||||
import handlers.admincommandhandlers.AdminExpSp;
|
||||
import handlers.admincommandhandlers.AdminFakePlayers;
|
||||
import handlers.admincommandhandlers.AdminFightCalculator;
|
||||
import handlers.admincommandhandlers.AdminFortSiege;
|
||||
import handlers.admincommandhandlers.AdminGeodata;
|
||||
@ -409,6 +410,7 @@ public class MasterHandler
|
||||
AdminEventEngine.class,
|
||||
AdminEvents.class,
|
||||
AdminExpSp.class,
|
||||
AdminFakePlayers.class,
|
||||
AdminFightCalculator.class,
|
||||
AdminFortSiege.class,
|
||||
AdminGeodata.class,
|
||||
|
@ -192,7 +192,7 @@ public class L2NpcActionShift implements IActionShiftHandler
|
||||
}
|
||||
else if (Config.ALT_GAME_VIEWNPC)
|
||||
{
|
||||
if (!target.isNpc())
|
||||
if (!target.isNpc() || target.isFakePlayer())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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 handlers.admincommandhandlers;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
*/
|
||||
public class AdminFakePlayers implements IAdminCommandHandler
|
||||
{
|
||||
private static final String[] ADMIN_COMMANDS =
|
||||
{
|
||||
"admin_fakechat"
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean useAdminCommand(String command, L2PcInstance activeChar)
|
||||
{
|
||||
if (command.startsWith("admin_fakechat"))
|
||||
{
|
||||
final String[] words = command.substring(15).split(" ");
|
||||
if (words.length < 3)
|
||||
{
|
||||
activeChar.sendMessage("Usage: //fakechat playername fpcname message");
|
||||
return false;
|
||||
}
|
||||
final L2PcInstance player = L2World.getInstance().getPlayer(words[0]);
|
||||
if (player == null)
|
||||
{
|
||||
activeChar.sendMessage("Player not found.");
|
||||
return false;
|
||||
}
|
||||
final String fpcName = FakePlayerData.getInstance().getProperName(words[1]);
|
||||
if (fpcName == null)
|
||||
{
|
||||
activeChar.sendMessage("Fake player not found.");
|
||||
return false;
|
||||
}
|
||||
String message = "";
|
||||
for (int i = 0; i < words.length; i++)
|
||||
{
|
||||
if (i < 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
message += (words[i] + " ");
|
||||
}
|
||||
FakePlayerChatManager.getInstance().sendChat(player, fpcName, message);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAdminCommandList()
|
||||
{
|
||||
return ADMIN_COMMANDS;
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EnchantItemData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EnchantItemGroupsData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FishingData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ItemCrystalizationData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.MultisellData;
|
||||
@ -45,9 +46,12 @@ import com.l2jmobius.gameserver.data.xml.impl.TransformData;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.QuestManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.scripting.ScriptEngineManager;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
@ -301,6 +305,25 @@ public class AdminReload implements IAdminCommandHandler
|
||||
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Fishing data.");
|
||||
break;
|
||||
}
|
||||
case "fakeplayers":
|
||||
{
|
||||
FakePlayerData.getInstance().load();
|
||||
for (L2Object obj : L2World.getInstance().getVisibleObjects())
|
||||
{
|
||||
if (obj.isFakePlayer())
|
||||
{
|
||||
obj.broadcastInfo();
|
||||
}
|
||||
}
|
||||
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Fake Player data.");
|
||||
break;
|
||||
}
|
||||
case "fakeplayerchat":
|
||||
{
|
||||
FakePlayerChatManager.getInstance().load();
|
||||
AdminData.getInstance().broadcastMessageToGMs(activeChar.getName() + ": Reloaded Fake Player Chat data.");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
activeChar.sendMessage(RELOAD_USAGE);
|
||||
|
@ -17,8 +17,10 @@
|
||||
package handlers.chathandlers;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.handler.IChatHandler;
|
||||
import com.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||
import com.l2jmobius.gameserver.model.BlockList;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.PcCondOverride;
|
||||
@ -59,6 +61,28 @@ public final class ChatWhisper implements IChatHandler
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.FAKE_PLAYERS_ENABLED && (FakePlayerData.getInstance().getProperName(target) != null))
|
||||
{
|
||||
if (FakePlayerData.getInstance().isTalkable(target))
|
||||
{
|
||||
if (Config.FAKE_PLAYER_CHAT)
|
||||
{
|
||||
final String name = FakePlayerData.getInstance().getProperName(target);
|
||||
activeChar.sendPacket(new CreatureSay(activeChar, null, "->" + name, type, text));
|
||||
FakePlayerChatManager.getInstance().manageChat(activeChar, name, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.THAT_PERSON_IS_IN_MESSAGE_REFUSAL_MODE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
activeChar.sendPacket(SystemMessageId.THAT_PLAYER_IS_NOT_ONLINE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final L2PcInstance receiver = L2World.getInstance().getPlayer(target);
|
||||
|
||||
if ((receiver != null) && !receiver.isSilenceMode(activeChar.getObjectId()))
|
||||
|
@ -40,5 +40,4 @@ public class PlayerLevelCondition implements ICondition
|
||||
{
|
||||
return creature.isPlayer() && (creature.getLevel() >= _minLevel) && (creature.getLevel() < _maxLevel);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,9 +16,11 @@
|
||||
*/
|
||||
package handlers.playeractions;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlEvent;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.ai.NextAction;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.handler.IPlayerActionHandler;
|
||||
import com.l2jmobius.gameserver.model.ActionDataHolder;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
@ -97,6 +99,15 @@ public final class SocialAction implements IPlayerActionHandler
|
||||
return true;
|
||||
}
|
||||
|
||||
private void scheduleDeny(L2PcInstance player)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_COUPLE_ACTION_WAS_DENIED);
|
||||
player.onTransactionResponse();
|
||||
}
|
||||
}
|
||||
|
||||
private void useCoupleSocial(L2PcInstance player, int id)
|
||||
{
|
||||
if (player == null)
|
||||
@ -105,7 +116,26 @@ public final class SocialAction implements IPlayerActionHandler
|
||||
}
|
||||
|
||||
final L2Object target = player.getTarget();
|
||||
if ((target == null) || !target.isPlayer())
|
||||
if ((target == null))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.INVALID_TARGET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FakePlayerData.getInstance().isTalkable(target.getName()))
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_REQUESTED_A_COUPLE_ACTION_WITH_C1);
|
||||
sm.addString(target.getName());
|
||||
player.sendPacket(sm);
|
||||
if (!player.isProcessingRequest())
|
||||
{
|
||||
ThreadPoolManager.schedule(() -> scheduleDeny(player), 10000);
|
||||
player.blockRequest();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target.isPlayer())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.INVALID_TARGET);
|
||||
return;
|
||||
|
@ -216,11 +216,14 @@ public class Q10766_ANewCraft extends Quest
|
||||
@Id(WINDY_HEALING_POTION_1)
|
||||
public void onItemCreate(OnItemCreate event)
|
||||
{
|
||||
final L2PcInstance player = event.getActiveChar();
|
||||
final QuestState qs = getQuestState(player, false);
|
||||
if ((qs != null) && (qs.isCond(3)) && (getQuestItemsCount(qs.getPlayer(), AIR_STONE) >= 1) && (getQuestItemsCount(qs.getPlayer(), WINDY_HEALING_POTION_1) >= 1))
|
||||
final L2PcInstance player = event.getActiveChar().getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
qs.setCond(4, true);
|
||||
final QuestState qs = getQuestState(player, false);
|
||||
if ((qs != null) && (qs.isCond(3)) && (getQuestItemsCount(qs.getPlayer(), AIR_STONE) >= 1) && (getQuestItemsCount(qs.getPlayer(), WINDY_HEALING_POTION_1) >= 1))
|
||||
{
|
||||
qs.setCond(4, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -141,11 +141,14 @@ public class Q10767_AWholeNewLevelOfAlchemy extends Quest
|
||||
@Id(HIGH_GRADE_LOVE_POTION)
|
||||
public void onItemCreate(OnItemCreate event)
|
||||
{
|
||||
final L2PcInstance player = event.getActiveChar();
|
||||
final QuestState qs = getQuestState(player, false);
|
||||
if ((qs != null) && (qs.isCond(1)) && (getQuestItemsCount(qs.getPlayer(), SUPERIOR_WINDY_HEALING_POTION) >= 1000) && (getQuestItemsCount(qs.getPlayer(), SUPERIOR_WINDY_QUIK_HEALING_POTION) >= 1000) && (getQuestItemsCount(qs.getPlayer(), HIGH_GRADE_LOVE_POTION) >= 1000))
|
||||
final L2PcInstance player = event.getActiveChar().getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
final QuestState qs = getQuestState(player, false);
|
||||
if ((qs != null) && (qs.isCond(1)) && (getQuestItemsCount(qs.getPlayer(), SUPERIOR_WINDY_HEALING_POTION) >= 1000) && (getQuestItemsCount(qs.getPlayer(), SUPERIOR_WINDY_QUIK_HEALING_POTION) >= 1000) && (getQuestItemsCount(qs.getPlayer(), HIGH_GRADE_LOVE_POTION) >= 1000))
|
||||
{
|
||||
qs.setCond(2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
L2J_Mobius_2.5_Underground/dist/game/data/spawns/Others/FakePlayers.xml
vendored
Normal file
8
L2J_Mobius_2.5_Underground/dist/game/data/spawns/Others/FakePlayers.xml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/spawns.xsd">
|
||||
<spawn name="FakePlayers">
|
||||
<group>
|
||||
<npc id="80000" x="83485" y="147998" z="-3407" heading="23509" respawnTime="60sec" /> <!-- Evi -->
|
||||
</group>
|
||||
</spawn>
|
||||
</list>
|
341
L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/fpc_combat.xml
vendored
Normal file
341
L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/fpc_combat.xml
vendored
Normal file
@ -0,0 +1,341 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../xsd/npcs.xsd">
|
||||
<!-- Sigel Phoenix Knight -->
|
||||
<npc id="81001" level="94" type="L2Monster" name="Siegfield" title="Sigel Phoenix Knight" >
|
||||
<race>HUMAN</race>
|
||||
<sex>MALE</sex>
|
||||
<stats str="88" int="39" dex="55" wit="39" con="82" men="38">
|
||||
<vitals hp="22228" hpRegen="10.8" mp="3681" mpRegen="3.0" />
|
||||
<attack physical="4425" magical="1284" random="30" critical="94" accuracy="206" attackSpeed="517" type="SWORD" range="40" distance="80" width="120" />
|
||||
<defence physical="3613" magical="2307" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="82" />
|
||||
<run ground="132" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="FIGHTER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="9" />
|
||||
<height normal="23" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="10009" level="6" />
|
||||
<skill name="Skill02_ID" id="10010" level="6" />
|
||||
<skill name="Skill03_ID" id="10011" level="4" />
|
||||
<skill name="Skill04_ID" id="10012" level="4" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="10009" level="6" /> <!-- Last Judgment -->
|
||||
<skill id="10010" level="6" /> <!-- Justice Punishment -->
|
||||
<skill id="10011" level="4" /> <!-- Shield Impact -->
|
||||
<skill id="10012" level="4" /> <!-- Shield Wave -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Tyrr Titan -->
|
||||
<npc id="81002" level="94" type="L2Monster" name="Tyrrion" title="Tyrr Titan" >
|
||||
<race>ORC</race>
|
||||
<sex>MALE</sex>
|
||||
<stats str="88" int="37" dex="50" wit="38" con="87" men="41">
|
||||
<vitals hp="19416" hpRegen="10.8" mp="3727" mpRegen="3.0" />
|
||||
<attack physical="11025" magical="1247" random="30" critical="92" accuracy="168" attackSpeed="540" type="SWORD" range="40" distance="80" width="120" />
|
||||
<defence physical="3429" magical="2046" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="70" />
|
||||
<run ground="130" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="FIGHTER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="7" />
|
||||
<height normal="27" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="10267" level="4" />
|
||||
<skill name="Skill02_ID" id="1760" level="5" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="10267" level="4" /> <!-- Hurricane Rush -->
|
||||
<skill id="1760" level="5" /> <!-- Armor Destruction -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Othell Fortune Seeker -->
|
||||
<npc id="81003" level="94" type="L2Monster" name="Othelo" title="Othell Fortune Seeker" >
|
||||
<race>DWARF</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="87" int="39" dex="53" wit="37" con="85" men="40">
|
||||
<vitals hp="17018" hpRegen="10.8" mp="3693" mpRegen="3.0" />
|
||||
<attack physical="4807" magical="1281" random="30" critical="230" accuracy="165" attackSpeed="943" type="SWORD" range="40" distance="80" width="120" />
|
||||
<defence physical="2889" magical="2035" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="80" />
|
||||
<run ground="131" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="FIGHTER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="5" />
|
||||
<height normal="19" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="10508" level="6" />
|
||||
<skill name="Skill02_ID" id="10509" level="6" />
|
||||
<skill name="Skill03_ID" id="10510" level="5" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="10508" level="6" /> <!-- Blood Stab -->
|
||||
<skill id="10509" level="6" /> <!-- Heart Breaker -->
|
||||
<skill id="10510" level="5" /> <!-- Chain Blow -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Yul Trickster -->
|
||||
<npc id="81004" level="94" type="L2Monster" name="Yully" title="Yul Trickster" >
|
||||
<race>KAMAEL</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="88" int="43" dex="57" wit="36" con="80" men="37">
|
||||
<vitals hp="15285" hpRegen="10.8" mp="4596" mpRegen="3.0" />
|
||||
<attack physical="9754" magical="1375" random="30" critical="185" accuracy="167" attackSpeed="483" reuseDelay="1500" type="BOW" range="500" distance="80" width="120" />
|
||||
<defence physical="2885" magical="2318" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="87" />
|
||||
<run ground="140" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="ARCHER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="7" />
|
||||
<height normal="22.6" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="10760" level="6" />
|
||||
<skill name="Skill02_ID" id="10762" level="5" />
|
||||
<skill name="Skill03_ID" id="10763" level="6" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="10760" level="6" /> <!-- Tornado Shot -->
|
||||
<skill id="10762" level="5" /> <!-- Quick Shot -->
|
||||
<skill id="10763" level="6" /> <!-- Pin Point -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Feoh Archmage -->
|
||||
<npc id="81005" level="94" type="L2Monster" name="Feoth" title="Feoh Archmage" >
|
||||
<race>HUMAN</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="38" int="79" dex="27" wit="78" con="41" men="78">
|
||||
<vitals hp="14435" hpRegen="10.8" mp="9103" mpRegen="3.0" />
|
||||
<attack physical="1257" magical="10320" random="30" critical="61" accuracy="158" attackSpeed="336" type="BLUNT" range="40" distance="500" width="120" />
|
||||
<defence physical="3132" magical="2635" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="78" />
|
||||
<run ground="124" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="MAGE" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="8" />
|
||||
<height normal="23.5" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="11011" level="6" />
|
||||
<skill name="Skill02_ID" id="11017" level="6" />
|
||||
<skill name="Skill03_ID" id="11024" level="5" />
|
||||
<skill name="Skill04_ID" id="11047" level="4" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="11011" level="6" /> <!-- Elemental Spike -->
|
||||
<skill id="11017" level="6" /> <!-- Elemental Crash -->
|
||||
<skill id="11024" level="5" /> <!-- Volcanic Destruction -->
|
||||
<skill id="11047" level="4" /> <!-- Ruin -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Iss Spectral Dancer -->
|
||||
<npc id="81006" level="94" type="L2Monster" name="Isda" title="Iss Spectral Dancer" >
|
||||
<race>DARK_ELF</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="92" int="42" dex="56" wit="39" con="77" men="35">
|
||||
<vitals hp="15499" hpRegen="10.8" mp="4038" mpRegen="3.0" />
|
||||
<attack physical="8777" magical="1451" random="30" critical="95" accuracy="162" attackSpeed="582" type="SWORD" range="40" distance="80" width="120" />
|
||||
<defence physical="3429" magical="2026" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="85" />
|
||||
<run ground="139" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="BALANCED" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="7" />
|
||||
<height normal="23.5" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="11508" level="4" />
|
||||
<skill name="Skill02_ID" id="11509" level="6" />
|
||||
<skill name="Skill02_ID" id="11510" level="5" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="11508" level="4" /> <!-- Assault Rush -->
|
||||
<skill id="11509" level="6" /> <!-- Crippling Attack -->
|
||||
<skill id="11510" level="5" /> <!-- Shadow Blade -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Aeore Eva's Saint -->
|
||||
<npc id="81007" level="94" type="L2Monster" name="Aorta" title="Aeore Eva's Saint" >
|
||||
<race>ELF</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="36" int="74" dex="32" wit="84" con="38" men="77">
|
||||
<vitals hp="13651" hpRegen="10.8" mp="11193" mpRegen="3.0" />
|
||||
<attack physical="1008" magical="7469" random="30" critical="63" accuracy="161" attackSpeed="400" type="SWORD" range="40" distance="80" width="120" />
|
||||
<defence physical="2406" magical="2627" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="85" />
|
||||
<run ground="129" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="HEALER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="7.5" />
|
||||
<height normal="23" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="11766" level="6" />
|
||||
<skill name="Skill02_ID" id="11814" level="6" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="11766" level="6" /> <!-- Dark Blast -->
|
||||
<skill id="11814" level="6" /> <!-- Dark Force -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Eviscerator -->
|
||||
<npc id="81008" level="94" type="L2Monster" name="Breezer" title="Eviscerator" >
|
||||
<race>ERTHEIA</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="89" int="40" dex="52" wit="37" con="84" men="39">
|
||||
<vitals hp="18857" hpRegen="10.8" mp="3863" mpRegen="3.0" />
|
||||
<attack physical="10198" magical="1305" random="30" critical="132" accuracy="177" attackSpeed="588" type="FIST" range="40" distance="80" width="120" />
|
||||
<defence physical="3388" magical="2450" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="88" />
|
||||
<run ground="141" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="FIGHTER" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="6.5" />
|
||||
<height normal="19.2" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="30500" level="18" />
|
||||
<skill name="Skill02_ID" id="30504" level="6" />
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="30500" level="18" /> <!-- Lateral Hit -->
|
||||
<skill id="30504" level="6" /> <!-- Gravity Hit -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
<!-- Sayha's Seer -->
|
||||
<npc id="81009" level="94" type="L2Monster" name="Hoppy" title="Sayha's Seer" >
|
||||
<race>ERTHEIA</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="37" int="79" dex="27" wit="76" con="42" men="80">
|
||||
<vitals hp="18857" hpRegen="10.8" mp="3863" mpRegen="3.0" />
|
||||
<attack physical="1242" magical="4784" random="30" critical="61" accuracy="177" attackSpeed="162" type="BLUNT" range="40" distance="80" width="120" />
|
||||
<defence physical="3388" magical="2450" />
|
||||
<attribute>
|
||||
<defence fire="250" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="88" />
|
||||
<run ground="141" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" attackable="true" />
|
||||
<ai type="BALANCED" clanHelpRange="1000" aggroRange="1000" isAggressive="true" > <!-- FIGHTER, ARCHER, BALANCED, MAGE, HEALER -->
|
||||
<clan_list>
|
||||
<clan>FAKE_PLAYER</clan>
|
||||
</clan_list>
|
||||
</ai>
|
||||
<collision>
|
||||
<radius normal="6.5" />
|
||||
<height normal="19.2" />
|
||||
</collision>
|
||||
<parameters>
|
||||
<skill name="Skill01_ID" id="30001" level="22" /> <!-- Hydro Attack -->
|
||||
<skill name="Skill02_ID" id="30019" level="5" /> <!-- Sayha's Word -->
|
||||
</parameters>
|
||||
<skill_list>
|
||||
<skill id="30001" level="22" /> <!-- Hydro Attack -->
|
||||
<skill id="30019" level="5" /> <!-- Sayha's Word -->
|
||||
</skill_list>
|
||||
</npc>
|
||||
</list>
|
26
L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/fpc_passive.xml
vendored
Normal file
26
L2J_Mobius_2.5_Underground/dist/game/data/stats/npcs/custom/fpc_passive.xml
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../xsd/npcs.xsd">
|
||||
<!-- Eviscerator -->
|
||||
<npc id="80000" level="94" type="L2Npc" name="Evi" >
|
||||
<race>ERTHEIA</race>
|
||||
<sex>FEMALE</sex>
|
||||
<stats str="103" int="40" dex="53" wit="37" con="84" men="39">
|
||||
<vitals hp="18857" hpRegen="10.8" mp="3863" mpRegen="3.0" />
|
||||
<attack physical="10198" magical="1305" random="30" critical="132" accuracy="177" attackSpeed="588" type="FIST" range="40" distance="80" width="120" />
|
||||
<defence physical="3388" magical="2450" />
|
||||
<attribute>
|
||||
<defence fire="200" water="250" wind="250" earth="250" holy="250" dark="250" />
|
||||
<attack type="WATER" value="330" />
|
||||
</attribute>
|
||||
<speed>
|
||||
<walk ground="88" />
|
||||
<run ground="141" />
|
||||
</speed>
|
||||
</stats>
|
||||
<status fakePlayer="true" talkable="false" randomAnimation="false" randomWalk="false" undying="true" attackable="false" />
|
||||
<collision>
|
||||
<radius normal="6.5" />
|
||||
<height normal="19.2" />
|
||||
</collision>
|
||||
</npc>
|
||||
</list>
|
20
L2J_Mobius_2.5_Underground/dist/game/data/xsd/FakePlayerChatData.xsd
vendored
Normal file
20
L2J_Mobius_2.5_Underground/dist/game/data/xsd/FakePlayerChatData.xsd
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="list">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="fakePlayerChat" maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute type="xs:string" name="fpcName" use="required" />
|
||||
<xs:attribute type="xs:string" name="searchMethod" use="required" />
|
||||
<xs:attribute type="xs:string" name="searchText" use="required" />
|
||||
<xs:attribute type="xs:string" name="answers" use="required" />
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
45
L2J_Mobius_2.5_Underground/dist/game/data/xsd/FakePlayerVisualData.xsd
vendored
Normal file
45
L2J_Mobius_2.5_Underground/dist/game/data/xsd/FakePlayerVisualData.xsd
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="list">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="fakePlayer" maxOccurs="unbounded" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:string">
|
||||
<xs:attribute type="xs:int" name="npcId"/>
|
||||
<xs:attribute type="xs:short" name="classId"/>
|
||||
<xs:attribute type="xs:byte" name="hair"/>
|
||||
<xs:attribute type="xs:byte" name="hairColor"/>
|
||||
<xs:attribute type="xs:byte" name="face"/>
|
||||
<xs:attribute type="xs:string" name="nameColor"/>
|
||||
<xs:attribute type="xs:string" name="titleColor"/>
|
||||
<xs:attribute type="xs:int" name="equipHead"/>
|
||||
<xs:attribute type="xs:int" name="equipLHand"/>
|
||||
<xs:attribute type="xs:int" name="equipRHand"/>
|
||||
<xs:attribute type="xs:int" name="equipGloves"/>
|
||||
<xs:attribute type="xs:int" name="equipChest"/>
|
||||
<xs:attribute type="xs:int" name="equipLegs"/>
|
||||
<xs:attribute type="xs:int" name="equipFeet"/>
|
||||
<xs:attribute type="xs:int" name="equipCloak"/>
|
||||
<xs:attribute type="xs:int" name="equipHair"/>
|
||||
<xs:attribute type="xs:int" name="equipHair2"/>
|
||||
<xs:attribute type="xs:int" name="agathionId"/>
|
||||
<xs:attribute type="xs:byte" name="weaponEnchantLevel"/>
|
||||
<xs:attribute type="xs:byte" name="armorEnchantLevel"/>
|
||||
<xs:attribute type="xs:boolean" name="fishing"/>
|
||||
<xs:attribute type="xs:int" name="baitLocationX"/>
|
||||
<xs:attribute type="xs:int" name="baitLocationY"/>
|
||||
<xs:attribute type="xs:int" name="baitLocationZ"/>
|
||||
<xs:attribute type="xs:byte" name="recommends"/>
|
||||
<xs:attribute type="xs:byte" name="nobleLevel"/>
|
||||
<xs:attribute type="xs:boolean" name="hero"/>
|
||||
<xs:attribute type="xs:long" name="clanId"/>
|
||||
<xs:attribute type="xs:byte" name="pledgeStatus"/>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
@ -201,6 +201,8 @@
|
||||
<xs:attribute name="hasSummoner" type="xs:boolean" />
|
||||
<xs:attribute name="canBeSown" type="xs:boolean" />
|
||||
<xs:attribute name="isDeathPenalty" type="xs:boolean" />
|
||||
<xs:attribute name="fakePlayer" type="xs:boolean" />
|
||||
<xs:attribute name="fakePlayerTalkable" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="skill_list" minOccurs="0" maxOccurs="1">
|
||||
|
@ -116,6 +116,7 @@ public final class Config
|
||||
public static final String CUSTOM_DEBUG_VOICE_COMMAND_CONFIG_FILE = "./config/Custom/DebugVoiceCommand.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_MULTILANGUAL_SUPPORT_CONFIG_FILE = "./config/Custom/MultilingualSupport.ini";
|
||||
public static final String CUSTOM_NPC_STAT_MULTIPIERS_CONFIG_FILE = "./config/Custom/NpcStatMultipliers.ini";
|
||||
@ -1147,6 +1148,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;
|
||||
@ -2560,6 +2571,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);
|
||||
ENABLE_FIND_PVP = FindPvP.getBoolean("EnableFindPvP", false);
|
||||
|
@ -62,6 +62,7 @@ import com.l2jmobius.gameserver.data.xml.impl.EnsoulData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.EventEngineData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ExtendDropData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FakePlayerData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.FishingData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.HennaData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.HitConditionBonusData;
|
||||
@ -112,6 +113,7 @@ import com.l2jmobius.gameserver.instancemanager.CommissionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.CursedWeaponsManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.DBSpawnManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FactionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FakePlayerChatManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortSiegeManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||
@ -288,6 +290,8 @@ public class GameServer
|
||||
printSection("NPCs");
|
||||
SkillLearnData.getInstance();
|
||||
NpcData.getInstance();
|
||||
FakePlayerData.getInstance();
|
||||
FakePlayerChatManager.getInstance();
|
||||
ExtendDropData.getInstance();
|
||||
SpawnsData.getInstance();
|
||||
WalkingManager.getInstance();
|
||||
|
@ -34,6 +34,7 @@ import com.l2jmobius.gameserver.GameTimeController;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.enums.AISkillScope;
|
||||
import com.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
import com.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
|
||||
import com.l2jmobius.gameserver.model.AggroInfo;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
@ -53,6 +54,7 @@ import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnAttackableFactionCall;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.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.Skill;
|
||||
import com.l2jmobius.gameserver.model.skills.SkillCaster;
|
||||
@ -356,7 +358,73 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
||||
// A L2Attackable isn't aggressive during 10s after its spawn because _globalAggro is set to -10
|
||||
if (_globalAggro >= 0)
|
||||
{
|
||||
if (npc.isAggressive() || (npc instanceof L2GuardInstance))
|
||||
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().getAllSkills())
|
||||
{
|
||||
SkillCaster.triggerCast(npc, null, skillHolder.getSkill(), null, false);
|
||||
}
|
||||
npc.broadcastInfo(); // ? check if this is necessary
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getFakePlayerDrops().remove(itemIndex);
|
||||
}
|
||||
npc.setRunning();
|
||||
}
|
||||
}
|
||||
else if (npc.isAggressive() || (npc instanceof L2GuardInstance))
|
||||
{
|
||||
final int range = npc instanceof L2GuardInstance ? 500 : npc.getAggroRange(); // TODO Make sure how guards behave towards players.
|
||||
L2World.getInstance().forEachVisibleObjectInRange(npc, L2Character.class, range, t ->
|
||||
@ -364,7 +432,18 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
|
||||
// For each L2Character check if the target is autoattackable
|
||||
if (isAggressiveTowards(t)) // check aggression
|
||||
{
|
||||
if (t.isPlayable())
|
||||
if (t.isFakePlayer())
|
||||
{
|
||||
if (!npc.isFakePlayer() || (npc.isFakePlayer() && Config.FAKE_PLAYER_AGGRO_FPC))
|
||||
{
|
||||
final int hating = npc.getHating(t);
|
||||
if (hating == 0)
|
||||
{
|
||||
npc.addDamageHate(t, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t.isPlayable())
|
||||
{
|
||||
final TerminateReturn term = EventDispatcher.getInstance().notifyEvent(new OnAttackableHate(getActiveChar(), t.getActingPlayer(), t.isSummon()), getActiveChar(), TerminateReturn.class);
|
||||
if ((term != null) && term.terminate())
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -316,6 +316,8 @@ public class NpcData implements IGameXmlReader
|
||||
set.set("hasSummoner", parseBoolean(attrs, "hasSummoner"));
|
||||
set.set("canBeSown", parseBoolean(attrs, "canBeSown"));
|
||||
set.set("isDeathPenalty", parseBoolean(attrs, "isDeathPenalty"));
|
||||
set.set("fakePlayer", parseBoolean(attrs, "fakePlayer"));
|
||||
set.set("fakePlayerTalkable", parseBoolean(attrs, "fakePlayerTalkable"));
|
||||
break;
|
||||
}
|
||||
case "skill_list":
|
||||
|
@ -250,6 +250,11 @@ public class SpawnsData implements IGameXmlReader
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Config.FAKE_PLAYERS_ENABLED && template.isFakePlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("parameters".equalsIgnoreCase(d.getNodeName()))
|
||||
|
@ -41,6 +41,8 @@ import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
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;
|
||||
@ -210,15 +212,14 @@ public final class BotReportTable
|
||||
public boolean reportBot(L2PcInstance reporter)
|
||||
{
|
||||
final L2Object target = reporter.getTarget();
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -229,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_BATTLEGROUND_WHILE_YOU_ARE_AN_OPPOSING_CLAN_MEMBER_DURING_A_CLAN_WAR_OR_WHILE_PARTICIPATING_IN_THE_OLYMPIAD);
|
||||
return false;
|
||||
@ -241,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_XP_AFTER_CONNECTING);
|
||||
return false;
|
||||
@ -320,15 +321,18 @@ public final class BotReportTable
|
||||
}
|
||||
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_WAS_REPORTED_AS_A_BOT);
|
||||
sm.addCharName(bot);
|
||||
sm.addString(bot.getName());
|
||||
reporter.sendPacket(sm);
|
||||
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_USED_A_REPORT_POINT_ON_C1_YOU_HAVE_S2_POINTS_REMAINING_ON_THIS_ACCOUNT);
|
||||
sm.addCharName(bot);
|
||||
sm.addString(bot.getName());
|
||||
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;
|
||||
@ -202,11 +203,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);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user