Faction System (Good vs Evil).

This commit is contained in:
MobiusDev
2018-04-10 18:21:54 +00:00
parent 80be005f0e
commit 76abf2d6b2
31 changed files with 997 additions and 31 deletions

View File

@@ -0,0 +1,4 @@
<html><body>Sentinel:<br>
You must use extreme caution, sir! There have been reports of roaming thugs in this area, who think nothing of killing for the sheer pleasure of it. Please let me know if you see any of them. My bow will protect you from these murderers.<br>
May the divine protection of Eva be with you always.
</body></html>

View File

@@ -0,0 +1,3 @@
<html><body>Centurion:<br>
I am sworn by the will of Paagrio to destroy all evildoers! If you see any of them, tell me. My bow will put an end to their treachery!
</body></html>

View File

@@ -0,0 +1,186 @@
/*
* 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.FactionSystem;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.L2World;
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.network.serverpackets.NpcHtmlMessage;
import ai.AbstractNpcAI;
/**
* @author Mobius
*/
public final class FactionSystem extends AbstractNpcAI
{
// NPCs
private static final int MANAGER = Config.FACTION_MANAGER_NPCID;
private static final int GOOD_GUARD = Config.FACTION_GOOD_GUARD_NPCID;
private static final int EVIL_GUARD = Config.FACTION_EVIL_GUARD_NPCID;
// Other
private static final String[] TEXTS =
{
Config.FACTION_GOOD_TEAM_NAME + " or " + Config.FACTION_EVIL_TEAM_NAME + "?",
"Select your faction!",
"The choice is yours!"
};
private FactionSystem()
{
addSpawnId(MANAGER);
addStartNpc(MANAGER);
addTalkId(MANAGER);
addFirstTalkId(MANAGER);
addSeeCreatureId(EVIL_GUARD, GOOD_GUARD);
if (Config.FACTION_SYSTEM_ENABLED)
{
addSpawn(MANAGER, Config.FACTION_MANAGER_LOCATION, false, 0);
}
}
@Override
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
{
switch (event)
{
case "selectGoodFaction":
{
if (Config.FACTION_BALANCE_ONLINE_PLAYERS && (L2World.getInstance().getAllGoodPlayers().size() >= (L2World.getInstance().getAllEvilPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT)))
{
final String htmltext = null;
final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId());
packet.setHtml(getHtm(player.getHtmlPrefix(), "onlinelimit.html"));
packet.replace("%name%", player.getName());
packet.replace("%more%", Config.FACTION_GOOD_TEAM_NAME);
packet.replace("%less%", Config.FACTION_EVIL_TEAM_NAME);
player.sendPacket(packet);
return htmltext;
}
if (Config.FACTION_AUTO_NOBLESS)
{
player.setNoble(true);
}
player.setGood();
player.getAppearance().setNameColor(Config.FACTION_GOOD_NAME_COLOR);
player.getAppearance().setTitleColor(Config.FACTION_GOOD_NAME_COLOR);
player.setTitle(Config.FACTION_GOOD_TEAM_NAME);
player.sendMessage("You are now fighting for the " + Config.FACTION_GOOD_TEAM_NAME + " faction.");
player.teleToLocation(Config.FACTION_GOOD_BASE_LOCATION);
broadcastMessageToFaction(Config.FACTION_GOOD_TEAM_NAME, Config.FACTION_GOOD_TEAM_NAME + " faction grows stronger with the arrival of " + player.getName() + ".");
L2World.addFactionPlayerToWorld(player);
break;
}
case "selectEvilFaction":
{
if (Config.FACTION_BALANCE_ONLINE_PLAYERS && (L2World.getInstance().getAllEvilPlayers().size() >= (L2World.getInstance().getAllGoodPlayers().size() + Config.FACTION_BALANCE_PLAYER_EXCEED_LIMIT)))
{
final String htmltext = null;
final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId());
packet.setHtml(getHtm(player.getHtmlPrefix(), "onlinelimit.html"));
packet.replace("%name%", player.getName());
packet.replace("%more%", Config.FACTION_EVIL_TEAM_NAME);
packet.replace("%less%", Config.FACTION_GOOD_TEAM_NAME);
player.sendPacket(packet);
return htmltext;
}
if (Config.FACTION_AUTO_NOBLESS)
{
player.setNoble(true);
}
player.setEvil();
player.getAppearance().setNameColor(Config.FACTION_EVIL_NAME_COLOR);
player.getAppearance().setTitleColor(Config.FACTION_EVIL_NAME_COLOR);
player.setTitle(Config.FACTION_EVIL_TEAM_NAME);
player.sendMessage("You are now fighting for the " + Config.FACTION_EVIL_TEAM_NAME + " faction.");
player.teleToLocation(Config.FACTION_EVIL_BASE_LOCATION);
broadcastMessageToFaction(Config.FACTION_EVIL_TEAM_NAME, Config.FACTION_EVIL_TEAM_NAME + " faction grows stronger with the arrival of " + player.getName() + ".");
L2World.addFactionPlayerToWorld(player);
break;
}
case "SPEAK":
{
if (npc != null)
{
npc.broadcastSay(ChatType.NPC_GENERAL, TEXTS[getRandom(TEXTS.length)], 1500);
}
break;
}
}
return super.onAdvEvent(event, npc, player);
}
@Override
public String onFirstTalk(L2Npc npc, L2PcInstance player)
{
final String htmltext = null;
final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId());
packet.setHtml(getHtm(player.getHtmlPrefix(), "manager.html"));
packet.replace("%name%", player.getName());
packet.replace("%good%", Config.FACTION_GOOD_TEAM_NAME);
packet.replace("%evil%", Config.FACTION_EVIL_TEAM_NAME);
player.sendPacket(packet);
return htmltext;
}
@Override
public String onSpawn(L2Npc npc)
{
if (npc.getId() == MANAGER)
{
startQuestTimer("SPEAK", 10000, npc, null, true);
}
return super.onSpawn(npc);
}
private void broadcastMessageToFaction(String factionName, String message)
{
if (factionName.equals(Config.FACTION_GOOD_TEAM_NAME))
{
for (L2PcInstance player : L2World.getInstance().getAllGoodPlayers())
{
player.sendMessage(message);
}
}
else
{
for (L2PcInstance player : L2World.getInstance().getAllEvilPlayers())
{
player.sendMessage(message);
}
}
}
@Override
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
{
if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && creature.isPlayer() && ((creature.getActingPlayer().isGood() && (npc.getId() == EVIL_GUARD)) || (creature.getActingPlayer().isEvil() && (npc.getId() == GOOD_GUARD))))
{
addAttackDesire(npc, creature);
}
return super.onSeeCreature(npc, creature, isSummon);
}
public static void main(String[] args)
{
new FactionSystem();
}
}

View File

@@ -0,0 +1,6 @@
<html><body>Faction Manager:<br>
What will your destiny be %name%?<br1>
Will you choose to be %good%? ...or maybe %evil%?<br>
<a action="bypass -h Quest FactionSystem selectGoodFaction">"I choose %good%!"</a><br>
<a action="bypass -h Quest FactionSystem selectEvilFaction">"I choose %evil%!"</a>
</body></html>

View File

@@ -0,0 +1,5 @@
<html><body>Faction Manager:<br>
I am sorry %name%.<br1>
It seems that there are currently more %more% than %less% players online.<br>
Try selecting the opposing faction or wait for some %more% players to logout.
</body></html>

View File

@@ -87,11 +87,33 @@ public final class ChatGeneral implements IChatHandler
}
final CreatureSay cs = new CreatureSay(activeChar.getObjectId(), type, activeChar.getAppearance().getVisibleName(), text);
final CreatureSay csRandom = new CreatureSay(activeChar.getObjectId(), type, activeChar.getAppearance().getVisibleName(), ChatRandomizer.randomize(text));
L2World.getInstance().forEachVisibleObjectInRange(activeChar, L2PcInstance.class, 1250, player ->
{
if ((player != null) && !BlockList.isBlocked(player, activeChar))
{
player.sendPacket(cs);
if (Config.FACTION_SYSTEM_ENABLED)
{
if (Config.FACTION_SPECIFIC_CHAT)
{
if ((activeChar.isGood() && player.isEvil()) || (activeChar.isEvil() && player.isGood()))
{
player.sendPacket(csRandom);
}
else
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
});

View File

@@ -67,7 +67,24 @@ public final class ChatHeroVoice implements IChatHandler
{
if ((player != null) && !BlockList.isBlocked(player, activeChar))
{
player.sendPacket(cs);
if (Config.FACTION_SYSTEM_ENABLED)
{
if (Config.FACTION_SPECIFIC_CHAT)
{
if ((activeChar.isGood() && player.isGood()) || (activeChar.isEvil() && player.isEvil()))
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
}
}

View File

@@ -63,7 +63,24 @@ public class ChatPartyMatchRoom implements IChatHandler
final CreatureSay cs = new CreatureSay(activeChar.getObjectId(), type, activeChar.getName(), text);
for (L2PcInstance _member : _room.getPartyMembers())
{
_member.sendPacket(cs);
if (Config.FACTION_SYSTEM_ENABLED)
{
if (Config.FACTION_SPECIFIC_CHAT)
{
if ((activeChar.isGood() && _member.isGood()) || (activeChar.isEvil() && _member.isEvil()))
{
_member.sendPacket(cs);
}
}
else
{
_member.sendPacket(cs);
}
}
else
{
_member.sendPacket(cs);
}
}
}

View File

@@ -0,0 +1,50 @@
/*
* 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.chathandlers;
import com.l2jmobius.commons.util.Rnd;
/**
* @author Mobius
*/
class ChatRandomizer
{
static String randomize(String text)
{
final StringBuilder textOut = new StringBuilder();
for (char c : text.toCharArray())
{
if ((c > 96) && (c < 123))
{
textOut.append(Character.toString((char) Rnd.get(96, 123)));
}
else if ((c > 64) && (c < 91))
{
textOut.append(Character.toString((char) Rnd.get(64, 91)));
}
else if ((c == 32) || (c == 44) || (c == 46))
{
textOut.append(c);
}
else
{
textOut.append(Character.toString((char) Rnd.get(47, 64)));
}
}
return textOut.toString();
}
}

View File

@@ -63,9 +63,26 @@ public final class ChatShout implements IChatHandler
final int region = MapRegionManager.getInstance().getMapRegionLocId(activeChar);
for (L2PcInstance player : L2World.getInstance().getPlayers())
{
if ((region == MapRegionManager.getInstance().getMapRegionLocId(player)) && !BlockList.isBlocked(player, activeChar) && (player.getInstanceId() == activeChar.getInstanceId()))
if ((region == MapRegionManager.getInstance().getMapRegionLocId(player)) && !BlockList.isBlocked(player, activeChar) && (player.getInstanceId() == activeChar.getInstanceId()) && !BlockList.isBlocked(player, activeChar))
{
player.sendPacket(cs);
if (Config.FACTION_SYSTEM_ENABLED)
{
if (Config.FACTION_SPECIFIC_CHAT)
{
if ((activeChar.isGood() && player.isGood()) || (activeChar.isEvil() && player.isEvil()))
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
}
}
@@ -81,7 +98,24 @@ public final class ChatShout implements IChatHandler
{
if (!BlockList.isBlocked(player, activeChar))
{
player.sendPacket(cs);
if (Config.FACTION_SYSTEM_ENABLED)
{
if (Config.FACTION_SPECIFIC_CHAT)
{
if ((activeChar.isGood() && player.isGood()) || (activeChar.isEvil() && player.isEvil()))
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
}
}

View File

@@ -65,7 +65,24 @@ public final class ChatTrade implements IChatHandler
{
if ((region == MapRegionManager.getInstance().getMapRegionLocId(player)) && !BlockList.isBlocked(player, activeChar) && (player.getInstanceId() == activeChar.getInstanceId()))
{
player.sendPacket(cs);
if (Config.FACTION_SYSTEM_ENABLED)
{
if (Config.FACTION_SPECIFIC_CHAT)
{
if ((activeChar.isGood() && player.isGood()) || (activeChar.isEvil() && player.isEvil()))
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
}
}
@@ -81,7 +98,24 @@ public final class ChatTrade implements IChatHandler
{
if (!BlockList.isBlocked(player, activeChar))
{
player.sendPacket(cs);
if (Config.FACTION_SYSTEM_ENABLED)
{
if (Config.FACTION_SPECIFIC_CHAT)
{
if ((activeChar.isGood() && player.isGood()) || (activeChar.isEvil() && player.isEvil()))
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
else
{
player.sendPacket(cs);
}
}
}
}

View File

@@ -77,6 +77,11 @@ public final class ChatWhisper implements IChatHandler
activeChar.sendMessage("Player is in offline mode.");
return;
}
if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_SPECIFIC_CHAT && ((activeChar.isGood() && receiver.isEvil()) || (activeChar.isEvil() && receiver.isGood())))
{
activeChar.sendMessage("Player belongs to the opposing faction.");
return;
}
if (!BlockList.isBlocked(receiver, activeChar))
{
// Allow reciever to send PMs to this char, which is in silence mode.

View File

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../xsd/npcs.xsd">
<npc id="500" displayId="30115" name="Jurek" usingServerSideName="true" title="Faction Manager" usingServerSideTitle="true" type="L2Npc">
<race>ELF</race>
<sex>FEMALE</sex>
<stats>
<vitals hp="2444.46819" hpRegen="7.5" mp="1345.8" mpRegen="2.7" />
<attack physical="688.86373" magical="470.40463" random="30" critical="4" accuracy="95" attackSpeed="253" type="SWORD" range="40" distance="80" width="120" />
<defence physical="295.91597" magical="216.53847" />
<speed>
<walk ground="50" />
<run ground="120" />
</speed>
</stats>
<status attackable="false" />
<collision>
<radius normal="8" />
<height normal="23" />
</collision>
</npc>
<npc id="501" displayId="31033" level="85" type="L2Guard" name="Sentinel" usingServerSideName="true">
<parameters>
<param name="NoFnHi" value="1" />
<param name="MoveAroundSocial" value="0" />
<param name="MoveAroundSocial1" value="79" />
</parameters>
<race>ELF</race>
<sex>MALE</sex>
<equipment rhand="276" /> <!-- rhand: Elven Bow -->
<stats>
<vitals hp="3290.11306877694" hpRegen="8.5" mp="1674.8" mpRegen="3" />
<attack physical="970.537548504614" magical="662.751329129412" random="10" critical="8" accuracy="100" attackSpeed="253" reuseDelay="1500" type="BOW" range="1100" distance="10" width="0" />
<defence physical="341.375" magical="249.80341" />
<attribute>
<defence fire="150" water="150" wind="150" earth="150" holy="150" dark="150" default="150" />
</attribute>
<speed>
<walk ground="50" />
<run ground="160" />
</speed>
</stats>
<status attackable="false" undying="false" />
<skillList>
<skill id="4045" level="1" /> <!-- Resist Full Magic Attack -->
<skill id="4410" level="16" /> <!-- Very Strong P. Atk. -->
<skill id="4411" level="16" /> <!-- Very Strong M. Atk. -->
<skill id="4412" level="16" /> <!-- Very Strong P. Def. -->
<skill id="4413" level="16" /> <!-- Very Strong M. Def. -->
<skill id="4414" level="2" /> <!-- Standard Type -->
<skill id="4415" level="9" /> <!-- Bows -->
<skill id="4416" level="15" /> <!-- Elves -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai aggroRange="500" clanHelpRange="300">
<clanList>
<clan>Good</clan>
</clanList>
</ai>
<collision>
<radius normal="8" />
<height normal="23.5" />
</collision>
</npc>
<npc id="502" displayId="31036" level="85" type="L2Guard" name="Centurion" usingServerSideName="true">
<parameters>
<param name="NoFnHi" value="1" />
<param name="MoveAroundSocial" value="0" />
<param name="MoveAroundSocial1" value="140" />
</parameters>
<race>ORC</race>
<sex>MALE</sex>
<equipment rhand="273" /> <!-- rhand: Composite Bow -->
<stats>
<vitals hp="13290.11306877694" hpRegen="8.5" mp="11674.8" mpRegen="3" />
<attack physical="970.537548504614" magical="662.751329129412" random="10" critical="8" accuracy="100" attackSpeed="253" reuseDelay="1500" type="BOW" range="1100" distance="10" width="0" />
<defence physical="341.375" magical="249.80341" />
<attribute>
<defence fire="150" water="150" wind="150" earth="150" holy="150" dark="150" default="150" />
</attribute>
<speed>
<walk ground="50" />
<run ground="160" />
</speed>
</stats>
<status attackable="false" undying="false" />
<skillList>
<skill id="4045" level="1" /> <!-- Resist Full Magic Attack -->
<skill id="4410" level="16" /> <!-- Very Strong P. Atk. -->
<skill id="4411" level="16" /> <!-- Very Strong M. Atk. -->
<skill id="4412" level="16" /> <!-- Very Strong P. Def. -->
<skill id="4413" level="16" /> <!-- Very Strong M. Def. -->
<skill id="4414" level="2" /> <!-- Standard Type -->
<skill id="4415" level="9" /> <!-- Bows -->
<skill id="4416" level="17" /> <!-- Orcs -->
</skillList>
<exCrtEffect>true</exCrtEffect>
<ai aggroRange="500" clanHelpRange="300">
<clanList>
<clan>Evil</clan>
</clanList>
</ai>
<collision>
<radius normal="8" />
<height normal="27" />
</collision>
</npc>
</list>