diff --git a/src/engine/AiPlayers/AiPlayer.java b/src/engine/AiPlayers/AiPlayer.java new file mode 100644 index 00000000..0cd6fc0f --- /dev/null +++ b/src/engine/AiPlayers/AiPlayer.java @@ -0,0 +1,76 @@ +package engine.AiPlayers; + +import engine.Enum; +import engine.InterestManagement.WorldGrid; +import engine.math.Vector3fImmutable; +import engine.net.client.msg.VendorDialogMsg; +import engine.objects.*; + +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +public class AiPlayer { + public PlayerCharacter emulated; + + //randomized constructor + //creates a random AI player to start at level 10 and progress throughout the game world + public AiPlayer(){ + PlayerCharacter emu = generateRandomPlayer(); + if(emu != null) + this.emulated = emu; + } + + public static PlayerCharacter generateRandomPlayer(){ + Race race = AiPlayerManager.getRandomRace(); + if(race == null) + return null; + + BaseClass baseClass = null; + + List validClasses = race.getValidBaseClasses(); + if (!validClasses.isEmpty()) { + Random random = new Random(); + baseClass = validClasses.get(random.nextInt(validClasses.size())); + // Use randomClass here + } + + if(baseClass == null) + return null; + + PromotionClass promo = null; + while (promo == null){ + int promoId = ThreadLocalRandom.current().nextInt(2504,2526); + PromotionClass tempPromo = PromotionClass.GetPromtionClassFromCache(promoId); + if(tempPromo.isAllowedRune(baseClass.getToken())){ + promo = tempPromo; + } + } + + Account a = new Account(); + PlayerCharacter emulated = new PlayerCharacter(AiPlayerManager.generateFirstName(), "AI Player", (short) 0, (short) 0, (short) 0, + (short) 0, (short) 0, Guild.getErrantGuild(), (byte) 0, a, race, baseClass, (byte) 1, (byte) 1, + (byte) 1, (byte) 1, (byte) 1); + + emulated.setPromotionClass(promo.getObjectUUID()); + + return emulated; + } + + public void runAfterLoad(){ + WorldGrid.addObject(this.emulated,this.emulated.bindLoc.x,this.emulated.bindLoc.z); + City hamlet = AiPlayerManager.getRandomHamlet(); + this.emulated.teleport(Vector3fImmutable.getRandomPointOnCircle(hamlet.getTOL().loc,30)); + WorldGrid.updateObject(this.emulated); + this.emulated.removeEffectBySource(Enum.EffectSourceType.Invisibility,40,true); + this.emulated.removeEffectBySource(Enum.EffectSourceType.Invulnerability,40,true); + } + + public void update(){ + this.emulated.update(true); + } + + +} diff --git a/src/engine/AiPlayers/AiPlayerManager.java b/src/engine/AiPlayers/AiPlayerManager.java new file mode 100644 index 00000000..4d2c368e --- /dev/null +++ b/src/engine/AiPlayers/AiPlayerManager.java @@ -0,0 +1,59 @@ +package engine.AiPlayers; + +import engine.objects.City; +import engine.objects.Race; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +public class AiPlayerManager { + + public static ArrayList AiPlayers = new ArrayList<>(); + public static int totalPlayers = 100; + + private static final List GENDER_NEUTRAL_NAMES = Arrays.asList( + "Alex", "Andy", "Avery", "Bailey", "Blake", "Cameron", "Casey", "Charlie", "Dakota", "Dallas", + "Devin", "Drew", "Elliot", "Emerson", "Finley", "Frankie", "Gray", "Harley", "Hayden", "Hunter", + "Jackie", "Jamie", "Jay", "Jessie", "Jordan", "Jules", "Kai", "Keegan", "Kendall", "Lane", + "Leighton", "Lennon", "Lennox", "Logan", "Mackenzie", "Marley", "Mason", "Micah", "Morgan", "Nico", + "Noel", "Oakley", "Parker", "Payton", "Phoenix", "Quinn", "Reagan", "Reese", "Remy", "Riley", + "River", "Robin", "Rowan", "Rory", "Ryan", "Sage", "Sam", "Sawyer", "Shay", "Shiloh", + "Sky", "Skyler", "Spencer", "Stevie", "Sydney", "Tatum", "Taylor", "Toby", "Toni", "Tyler", + "Val", "Wesley", "Winter", "Zephyr", "Arden", "Aspen", "Blaine", "Briar", "Brook", "Camdyn", + "Chandler", "Corey", "Denver", "Devon", "Eden", "Ellis", "Emory", "Ever", "Everest", "Fallon", + "Flynn", "Indigo", "Justice", "Karter", "Kyrie", "Lex", "Lyric", "Monroe", "Peyton", "Sterling" + ); + + private static final int[] hamletIds = {36105, 36245, 36423, 36562, 36661, 39049}; + + private static final Random RANDOM = new Random(); + + public static void init(){ + while(AiPlayers.size() < totalPlayers){ + AiPlayer aiPlayer = new AiPlayer(); + if(aiPlayer != null){ + AiPlayers.add(aiPlayer); + } + } + } + public static String generateFirstName(){ + return GENDER_NEUTRAL_NAMES.get(RANDOM.nextInt(GENDER_NEUTRAL_NAMES.size())); + } + + public static Race getRandomRace(){ + int RaceId = ThreadLocalRandom.current().nextInt(1999,2029); + while (RaceId == 2020 || RaceId == 2021 || RaceId == 2018 || RaceId == 2019){ + RaceId = ThreadLocalRandom.current().nextInt(1999,2029); + } + Race race = Race.getRace(RaceId); + return race; + } + + public static City getRandomHamlet() { + return City.getCity(hamletIds[RANDOM.nextInt(hamletIds.length)]); + } + +} diff --git a/src/engine/objects/Account.java b/src/engine/objects/Account.java index 7beb72b5..95f39cd1 100644 --- a/src/engine/objects/Account.java +++ b/src/engine/objects/Account.java @@ -59,6 +59,11 @@ public class Account extends AbstractGameObject { this.status = Enum.AccountStatus.valueOf(resultSet.getString("status")); } + public Account() { + this.uname = ""; + this.status = Enum.AccountStatus.ACTIVE; + } + public ArrayList getVault() { return vault; } diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index 62ac5654..a603b71b 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -9,6 +9,7 @@ package engine.server.world; +import engine.AiPlayers.AiPlayerManager; import engine.Enum; import engine.Enum.BuildingGroup; import engine.Enum.DispatchChannel; @@ -514,6 +515,9 @@ public class WorldServer { Logger.info("Running garbage collection..."); System.gc(); + Logger.info("Spawning AI Players..."); + AiPlayerManager.init(); + Logger.info("Starting Bane Thread"); BaneThread.startBaneThread();