Merged with released L2J-Unity files.
This commit is contained in:
241
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/DarkWaterDragon.java
vendored
Normal file
241
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/DarkWaterDragon.java
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 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 ai.areas.IsleOfPrayer;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Dark Water Dragon's AI.
|
||||
*/
|
||||
public final class DarkWaterDragon extends AbstractNpcAI
|
||||
{
|
||||
private static final int DRAGON = 22267;
|
||||
private static final int SHADE1 = 22268;
|
||||
private static final int SHADE2 = 22269;
|
||||
private static final int FAFURION = 18482;
|
||||
private static final int DETRACTOR1 = 22270;
|
||||
private static final int DETRACTOR2 = 22271;
|
||||
private static Set<Integer> SECOND_SPAWN = ConcurrentHashMap.newKeySet(); // Used to track if second Shades were already spawned
|
||||
private static Set<Integer> MY_TRACKING_SET = ConcurrentHashMap.newKeySet(); // Used to track instances of npcs
|
||||
private static Map<Integer, L2PcInstance> ID_MAP = new ConcurrentHashMap<>(); // Used to track instances of npcs
|
||||
|
||||
private DarkWaterDragon()
|
||||
{
|
||||
final int[] mobs =
|
||||
{
|
||||
DRAGON,
|
||||
SHADE1,
|
||||
SHADE2,
|
||||
FAFURION,
|
||||
DETRACTOR1,
|
||||
DETRACTOR2
|
||||
};
|
||||
addKillId(mobs);
|
||||
addAttackId(mobs);
|
||||
addSpawnId(mobs);
|
||||
MY_TRACKING_SET.clear();
|
||||
SECOND_SPAWN.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
if (event.equalsIgnoreCase("first_spawn")) // timer to start timer "1"
|
||||
{
|
||||
startQuestTimer("1", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("second_spawn")) // timer to start timer "2"
|
||||
{
|
||||
startQuestTimer("2", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("third_spawn")) // timer to start timer "3"
|
||||
{
|
||||
startQuestTimer("3", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("fourth_spawn")) // timer to start timer "4"
|
||||
{
|
||||
startQuestTimer("4", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("1")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR1, (npc.getX() + 100), (npc.getY() + 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("2")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR2, (npc.getX() + 100), (npc.getY() - 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("3")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR1, (npc.getX() - 100), (npc.getY() + 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("4")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR2, (npc.getX() - 100), (npc.getY() - 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("fafurion_despawn")) // Fafurion Kindred disappears and drops reward
|
||||
{
|
||||
cancelQuestTimer("fafurion_poison", npc, null);
|
||||
cancelQuestTimer("1", npc, null);
|
||||
cancelQuestTimer("2", npc, null);
|
||||
cancelQuestTimer("3", npc, null);
|
||||
cancelQuestTimer("4", npc, null);
|
||||
|
||||
MY_TRACKING_SET.remove(npc.getObjectId());
|
||||
player = ID_MAP.remove(npc.getObjectId());
|
||||
if (player != null)
|
||||
{
|
||||
((L2Attackable) npc).doItemDrop(NpcData.getInstance().getTemplate(18485), player);
|
||||
}
|
||||
|
||||
npc.deleteMe();
|
||||
}
|
||||
else if (event.equalsIgnoreCase("fafurion_poison")) // Reduces Fafurions hp like it is poisoned
|
||||
{
|
||||
if (npc.getCurrentHp() <= 500)
|
||||
{
|
||||
cancelQuestTimer("fafurion_despawn", npc, null);
|
||||
cancelQuestTimer("first_spawn", npc, null);
|
||||
cancelQuestTimer("second_spawn", npc, null);
|
||||
cancelQuestTimer("third_spawn", npc, null);
|
||||
cancelQuestTimer("fourth_spawn", npc, null);
|
||||
cancelQuestTimer("1", npc, null);
|
||||
cancelQuestTimer("2", npc, null);
|
||||
cancelQuestTimer("3", npc, null);
|
||||
cancelQuestTimer("4", npc, null);
|
||||
MY_TRACKING_SET.remove(npc.getObjectId());
|
||||
ID_MAP.remove(npc.getObjectId());
|
||||
}
|
||||
npc.reduceCurrentHp(500, npc, null); // poison kills Fafurion if he is not healed
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final int npcId = npc.getId();
|
||||
final int npcObjId = npc.getObjectId();
|
||||
if (npcId == DRAGON)
|
||||
{
|
||||
if (MY_TRACKING_SET.add(npcObjId)) // this allows to handle multiple instances of npc
|
||||
{
|
||||
// Spawn first 5 shades on first attack on Dark Water Dragon
|
||||
final L2Character originalAttacker = isSummon ? attacker.getServitors().values().stream().findFirst().orElse(attacker.getPet()) : attacker;
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() + 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() + 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 150, npc.getY() + 150, npc.getZ());
|
||||
}
|
||||
else if ((npc.getCurrentHp() < (npc.getMaxHp() / 2.0)) && SECOND_SPAWN.add(npcObjId))
|
||||
{
|
||||
// Spawn second 5 shades on half hp of on Dark Water Dragon
|
||||
final L2Character originalAttacker = isSummon ? attacker.getServitors().values().stream().findFirst().orElse(attacker.getPet()) : attacker;
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() + 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() + 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 150, npc.getY() + 150, npc.getZ());
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final int npcId = npc.getId();
|
||||
final int npcObjId = npc.getObjectId();
|
||||
if (npcId == DRAGON)
|
||||
{
|
||||
MY_TRACKING_SET.remove(npcObjId);
|
||||
SECOND_SPAWN.remove(npcObjId);
|
||||
final L2Attackable faf = (L2Attackable) addSpawn(FAFURION, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0); // spawns Fafurion Kindred when Dard Water Dragon is dead
|
||||
ID_MAP.put(faf.getObjectId(), killer);
|
||||
}
|
||||
else if (npcId == FAFURION)
|
||||
{
|
||||
cancelQuestTimer("fafurion_poison", npc, null);
|
||||
cancelQuestTimer("fafurion_despawn", npc, null);
|
||||
cancelQuestTimer("first_spawn", npc, null);
|
||||
cancelQuestTimer("second_spawn", npc, null);
|
||||
cancelQuestTimer("third_spawn", npc, null);
|
||||
cancelQuestTimer("fourth_spawn", npc, null);
|
||||
cancelQuestTimer("1", npc, null);
|
||||
cancelQuestTimer("2", npc, null);
|
||||
cancelQuestTimer("3", npc, null);
|
||||
cancelQuestTimer("4", npc, null);
|
||||
MY_TRACKING_SET.remove(npcObjId);
|
||||
ID_MAP.remove(npcObjId);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final int npcId = npc.getId();
|
||||
final int npcObjId = npc.getObjectId();
|
||||
if (npcId == FAFURION)
|
||||
{
|
||||
if (MY_TRACKING_SET.add(npcObjId))
|
||||
{
|
||||
// Spawn 4 Detractors on spawn of Fafurion
|
||||
final int x = npc.getX();
|
||||
final int y = npc.getY();
|
||||
addSpawn(DETRACTOR2, x + 100, y + 100, npc.getZ(), 0, false, 40000);
|
||||
addSpawn(DETRACTOR1, x + 100, y - 100, npc.getZ(), 0, false, 40000);
|
||||
addSpawn(DETRACTOR2, x - 100, y + 100, npc.getZ(), 0, false, 40000);
|
||||
addSpawn(DETRACTOR1, x - 100, y - 100, npc.getZ(), 0, false, 40000);
|
||||
startQuestTimer("first_spawn", 2000, npc, null); // timer to delay timer "1"
|
||||
startQuestTimer("second_spawn", 4000, npc, null); // timer to delay timer "2"
|
||||
startQuestTimer("third_spawn", 8000, npc, null); // timer to delay timer "3"
|
||||
startQuestTimer("fourth_spawn", 10000, npc, null); // timer to delay timer "4"
|
||||
startQuestTimer("fafurion_poison", 3000, npc, null, true); // Every three seconds reduces Fafurions hp like it is poisoned
|
||||
startQuestTimer("fafurion_despawn", 120000, npc, null); // Fafurion Kindred disappears after two minutes
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public void spawnShade(L2Character attacker, int npcId, int x, int y, int z)
|
||||
{
|
||||
final L2Npc shade = addSpawn(npcId, x, y, z, 0, false, 0);
|
||||
shade.setRunning();
|
||||
((L2Attackable) shade).addDamageHate(attacker, 0, 999);
|
||||
shade.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, attacker);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DarkWaterDragon();
|
||||
}
|
||||
}
|
66
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/EvasGiftBox.java
vendored
Normal file
66
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/EvasGiftBox.java
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 ai.areas.IsleOfPrayer;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Eva's Gift Box AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class EvasGiftBox extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int BOX = 32342; // Eva's Gift Box
|
||||
// Skill
|
||||
private static final SkillHolder KISS_OF_EVA = new SkillHolder(1073, 1); // Kiss of Eva
|
||||
// Items
|
||||
private static final int CORAL = 9692; // Red Coral
|
||||
private static final int CRYSTAL = 9693; // Crystal Fragment
|
||||
|
||||
private EvasGiftBox()
|
||||
{
|
||||
addKillId(BOX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (killer.hasAbnormalType(KISS_OF_EVA.getSkill().getAbnormalType())) // It was checking if abnormal level is > 0. All cases when has this abnormal type, level is > 0.
|
||||
{
|
||||
if (getRandomBoolean())
|
||||
{
|
||||
npc.dropItem(killer, CRYSTAL, 1);
|
||||
}
|
||||
|
||||
if (getRandom(100) < 33)
|
||||
{
|
||||
npc.dropItem(killer, CORAL, 1);
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new EvasGiftBox();
|
||||
}
|
||||
}
|
4
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/Rignos/32349-01.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/Rignos/32349-01.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Rignos:<br>
|
||||
Marvellous! So, have you collected all 4 Race Stamps? You haven't taken any shortcuts or copied any of them, have you? Excellent! Then take this key -- it will prove useful when rescuing Parme!<br>
|
||||
<a action="bypass -h Quest Rignos exchange">Exchange Race Stamps for the Secret Garden Key.</a>
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/Rignos/32349-02.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/Rignos/32349-02.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Rignos:<br>
|
||||
Welcome, welcome! I am Rignos. Parme and I are old friends, so I've come here to help. It's been a long time since I've traveled this far, but beautiful Isle of Prayer always makes me feel like I'm on vacation. Now then, how can I help? A race! You know what I always say, "Joy and energy, all the time and in every way!" I call it the <font color="LEVEL">Grand Isle of Prayer Race</font>!<br>
|
||||
You're a little late, though -- the race is already underway!<br>
|
||||
Come back another time.
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/Rignos/32349-03.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/Rignos/32349-03.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Rignos:<br>
|
||||
You have 30 minutes to find three other structures just like the one behind me. They are scattered around the island. Once you find them, go inside and battle the opponents you find there. One of these combatants will drop a Race Stamp. Bring 4 Race Stamps to me within the allotted time, and I will give you a reward that will aid you in your endeavor to rescue Parme.<br>
|
||||
Don't forget to include the building behind me!<br>
|
||||
<a action="bypass -h Quest Rignos startRace">I'm ready! Let's start the race.</a>
|
||||
</body></html>
|
6
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/Rignos/32349.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/Rignos/32349.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Rignos:<br>
|
||||
Welcome, welcome! I am Rignos. Parme and I are old friends, so I've come here to help. It's been a long time since I've traveled this far, but the beautiful Isle of Prayer always makes me feel like I'm on vacation. Now then, how can I help? A race! You know what I always say, "Joy and energy, all the time and in every way!" I call it the <font color="LEVEL">Grand Isle of Prayer Race</font>!<br>
|
||||
You do know what this means, don't you?<br>
|
||||
<a action="bypass -h Quest Rignos 32349-03.html">Ask about the Grand Isle of Prayer Race.</a><br>
|
||||
<a action="bypass -h Quest Rignos startRace">Start the Race.</a>
|
||||
</body></html>
|
115
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/Rignos/Rignos.java
vendored
Normal file
115
trunk/dist/game/data/scripts/ai/areas/IsleOfPrayer/Rignos/Rignos.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 ai.areas.IsleOfPrayer.Rignos;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* Rignos AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public class Rignos extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int RIGNOS = 32349; // Rignos
|
||||
// Item
|
||||
private static final int STAMP = 10013; // Race Stamp
|
||||
private static final int KEY = 9694; // Secret Key
|
||||
// Skill
|
||||
private static final SkillHolder TIMER = new SkillHolder(5239, 5); // Event Timer
|
||||
// Misc
|
||||
private static final int MIN_LV = 78;
|
||||
|
||||
private Rignos()
|
||||
{
|
||||
addStartNpc(RIGNOS);
|
||||
addTalkId(RIGNOS);
|
||||
addFirstTalkId(RIGNOS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "32349-03.html":
|
||||
{
|
||||
return event;
|
||||
}
|
||||
case "startRace":
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("TIME_OUT", 1800000, npc, null);
|
||||
TIMER.getSkill().applyEffects(player, player);
|
||||
final L2Summon pet = player.getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
TIMER.getSkill().applyEffects(pet, pet);
|
||||
}
|
||||
player.getServitors().values().forEach(s ->
|
||||
{
|
||||
TIMER.getSkill().applyEffects(s, s);
|
||||
});
|
||||
|
||||
if (hasQuestItems(player, STAMP))
|
||||
{
|
||||
takeItems(player, STAMP, -1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "exchange":
|
||||
{
|
||||
if (getQuestItemsCount(player, STAMP) >= 4)
|
||||
{
|
||||
giveItems(player, KEY, 3);
|
||||
takeItems(player, STAMP, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TIME_OUT":
|
||||
{
|
||||
npc.setScriptValue(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = (npc.isScriptValue(0) && (player.getLevel() >= MIN_LV)) ? "32349.html" : "32349-02.html";
|
||||
if (getQuestItemsCount(player, STAMP) >= 4)
|
||||
{
|
||||
htmltext = "32349-01.html";
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Rignos();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user