AQ3D BOT

Posts 1–7 of 7 · Page 1 of 1
AQ3D BOT
Hello everyone,

I've started developing a bot for AQ3D. Currently, it only navigates to enemies on the map, engages them, and moves to the next one until the entire room is cleared. I've managed to make it work specifically for Midas Curse and rare chest drops by focusing solely on cutting the chests. However, I'm attempting to make it more intuitive by modifying the code to respond to various inputs.

I'm uncertain whether I should publish this or continue working on it. I just wanted to gauge reactions. Also, it works by modifying game files, similar to a cheat, that I previously released(now outdated, maybe i update one day). I should compile it as a DLL file. I'm not familiar with compiling in C#, so I need to learn that too.

For now, I'll prepare a todo list based on what's on my mind. The todo list is as follows:

Todo List:

1. **Collecting Loot:**
- Gathering all dropped items is straightforward, so modifications are needed to collect specific items.

2. **Graphic Interface:**
- Currently, it only triggers creature slaying upon pressing a key on the keyboard. I should create an in-game interface to receive inputs and commands.

3. **Skill Usage:**
- Currently, skills activate immediately after the cooldown period ends. I need to make it work more intuitively, perhaps following a sequential activation pattern like in AQW bots.

4. **Creature Filter:**
- It should function in a way that it only targets and attacks desired creatures.

5. **Navigating Maps and Dungeons:**
- Currently, when creatures in a dungeon are defeated, it waits at the last slain location for new creatures. Instead, it should proceed to the next room or area after clearing, be able to re-enter dungeons, etc.


Your feedback on whether I should proceed with this project would be greatly appreciated.

English is not my native language, please excuse me if I wrote something wrong.

Thank you.
Wow, that's insane bro!!! Your project has a lot of potential. I hope everything goes well!
Bot follow
Sounds awesome too. It will be nice if the bot can follow a target player around.
status of this project?
I apologize for the late response. I've been serving my mandatory military service and will be for another year. As a result, I haven't had access to a computer and my project has been on hold. However, the latest version of the bot could use skills in a specific order, kill targeted creatures, and farm specific loot. You could configure this by adding lines to a config.txt file (e.g., "skill: 1 2 3 4 2 4... safelev: 30 safeskill: 2 rpotionlev:25 bpotionlev:10 loot: red potion blue potion... entity: frogzard...").
Bot
Quote Originally Posted by nksakaak View Post
I apologize for the late response. I've been serving my mandatory military service and will be for another year. As a result, I haven't had access to a computer and my project has been on hold. However, the latest version of the bot could use skills in a specific order, kill targeted creatures, and farm specific loot. You could configure this by adding lines to a config.txt file (e.g., "skill: 1 2 3 4 2 4... safelev: 30 safeskill: 2 rpotionlev:25 bpotionlev:10 loot: red potion blue potion... entity: frogzard...").
Dude, this bot is amazing and useful. Are you thinking about releasing it for testing?
Quote Originally Posted by Nocrew View Post
Dude, this bot is amazing and useful. Are you thinking about releasing it for testing?
Hello everyone,

After making a small mistake, I lost the final version of my file. Luckily, I had a simpler backup, which I cleaned up and made usable. I'm sharing the code below so that anyone can add it to their game and use it.

I don’t plan to continue working on this project much further. If the open-source version of Styx becomes available soon, I’ll contribute to it.

If you encounter any issues or have ideas for further improvements, feel free to share them in the comments.

Known Bugs:

The contents of the last loot bag are not collected.

Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using UnityEngine;

public class SkillUsageOrder
{
	public int skill1 { get; set; }
	public int skill2 { get; set; }
	public int skill3 { get; set; }
	public int skillU { get; set; }
	public int skillC { get; set; }
	public int skillS { get; set; }
}

public class PotionSafeThresholds
{
    public int healthPotion { get; set; }
    public int manaPotion { get; set; }
	public int safe { get; set; }
}


public class GameConfig
{

	public List<string> entityNames { get; set; }


	public List<string> lootNames { get; set; }

	
	public PotionSafeThresholds potionSafeUsageThresholds { get; set; }

	public string skillbotClass { get; set; }

	public GameConfig()
	{
		this.entityNames = new List<string>();
		this.lootNames = new List<string>();
		this.potionSafeUsageThresholds = new PotionSafeThresholds();
		this.skillOrder = new SkillUsageOrder();
		this.spell = new SpellTemplate[5];
	}

	public SkillUsageOrder skillOrder { get; set; }

	public SpellTemplate[] spell;

	public int currentOrder;
}


public class KillBot
{
	public void RunKillBotLoop()
	{
		if (!this.killbotInitilazed)
		{
			this.initKillBot();
		}
		this.UpdateSkillBotClass();
		Vector3 position = Entities.Instance.me.position;
		if (this.IsTargetInvalid())
		{
			this.TeleportToNearestEntity(position);
			return;
		}
		this.ExecuteCombatLogic();
	}

	private void initKillBot()
	{
		this.killbotInitilazed = true;
		this.config = new GameConfig();
		this.config.potionSafeUsageThresholds = new PotionSafeThresholds();
		this.LoadAndInitConfig();
	}

	private void LoadAndInitConfig()
	{
		string value = File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.json"));
		this.config = JsonConvert.DeserializeObject<GameConfig>(value);
		this.setSpells();
	}

	private void UpdateSkillBotClass()
	{
		if (this.config.skillbotClass != Entities.Instance.me.ClassName)
		{
			this.setSpells();
		}
	}

	private bool IsTargetInvalid()
	{
		return Entities.Instance.me.Target == null || Entities.Instance.me.Target.HealthPercent == 0f;
	}

	private void TeleportToNearestEntity(Vector3 position)
	{
		Entity entity = null;
		float num = float.MaxValue;
		EntityController[] array = UnityEngine.Object.FindObjectsOfType(typeof(EntityController)) as EntityController[];
		for (int i = 0; i < array.Length; i++)
		{
			Entity entity2 = array[i].Entity;
			if (this.IsEntityInList(entity2) && entity2.type == Entity.Type.NPC && entity2.HealthPercent > 0f && entity2.react > Entity.Reaction.Hostile)
			{
				float num2 = Vector3.Distance(position, entity2.position);
				if (num2 < num)
				{
					num = num2;
					entity = entity2;
				}
			}
		}
		if (entity != null)
		{
			this.TeleportToEntity(position, entity);
		}
	}

	private void TeleportToEntity(Vector3 position, Entity entity)
	{
		Vector3 position2 = entity.position;
		Entities.Instance.me.Teleport(position2.x, position2.y, position2.z, 1f);
		Entities.Instance.me.Target = entity;
	}

	private bool IsEntityInList(Entity entity)
	{
		return entity != null && (this.config.entityNames.Contains(entity.name) || this.config.entityNames.Contains("*"));
	}

	private void ExecuteCombatLogic()
	{
		Game.Instance.entities.me.name = string.Concat(LootBags.Bags.Count);
		this.CastSpellsInOrder();
		this.Loot(LootBags.Bags.Values.ToList<ComLoot>());
	}

	private void CastSpellsInOrder()
	{
		if (this.NeedSafeSkill())
		{
			this.TryCastSpell(this.config.spell[this.config.skillOrder.skillS - 1]);
			return;
		}
		if (this.config.skillOrder.skill1 == this.config.currentOrder && Game.Instance.combat.IsSpellCooldownOver(this.config.spell[0]))
		{
			this.TryCastSpell(this.config.spell[0]);
		}
		else if (this.config.skillOrder.skill2 == this.config.currentOrder && Game.Instance.combat.IsSpellCooldownOver(this.config.spell[1]))
		{
			this.TryCastSpell(this.config.spell[1]);
		}
		else if (this.config.skillOrder.skill3 == this.config.currentOrder && Game.Instance.combat.IsSpellCooldownOver(this.config.spell[2]))
		{
			this.TryCastSpell(this.config.spell[2]);
		}
		else if (this.config.skillOrder.skillU == this.config.currentOrder && Game.Instance.combat.IsSpellCooldownOver(this.config.spell[3]))
		{
			this.TryCastSpell(this.config.spell[3]);
		}
		else if (this.config.skillOrder.skillC == this.config.currentOrder && Game.Instance.combat.IsSpellCooldownOver(this.config.spell[4]))
		{
			this.TryCastSpell(this.config.spell[4]);
		}
		this.config.currentOrder++;
		if (this.config.currentOrder > 5)
		{
			this.config.currentOrder = 1;
		}
	}

	private bool NeedSafeSkill()
	{
		return this.config.potionSafeUsageThresholds.safe < (int)Math.Ceiling((double)Entities.Instance.me.HealthPercent);
	}

	private void Loot(List<ComLoot> lootList)
	{
		Game.Instance.entities.me.name = "loot time";
		List<LootItem> list = new List<LootItem>();
		foreach (ComLoot comLoot in lootList)
		{
			foreach (LootItem lootItem in comLoot.Items)
			{
				if (this.IsLootItemWanted(lootItem))
				{
					list.Add(lootItem);
				}
			}
		}
		this.CollectLoot(list);
	}

	private bool IsLootItemWanted(LootItem lootItem)
	{
		return this.config.lootNames.Contains(lootItem.Name) || this.config.lootNames.Contains("*");
	}

	private void CollectLoot(List<LootItem> lootList)
	{
		foreach (LootItem lootItem in lootList)
		{
			Game.Instance.SendLootItemRequest(lootItem.LootBagID, lootItem.LootItemID);
		}
	}

	private void setSpells()
	{
		this.config.spell[0] = this.GetSpellTemplate(InputAction.Spell_1);
		this.config.spell[1] = this.GetSpellTemplate(InputAction.Spell_2);
		this.config.spell[2] = this.GetSpellTemplate(InputAction.Spell_3);
		this.config.spell[3] = this.GetSpellTemplate(InputAction.Spell_4);
		this.config.spell[4] = this.GetSpellTemplate(InputAction.Spell_5);
	}

	private SpellTemplate GetSpellTemplate(InputAction action)
	{
		return Game.Instance.combat.GetMySpellTemplate(action);
	}

	private void TryCastSpell(SpellTemplate spell)
	{
		Game.Instance.combat.TryCastSpell(spell);
	}

	public KillBot()
	{
	}

	public GameConfig config;

	private bool killbotInitilazed;
}
Please note that a config.json file is required for this code to work. Below, you'll find an example configuration file you can use as a template.
You can use * in the config.json file to represent "collect everything" or "attack everything."
Code:
{
    "entityNames" : [
        "Hostile Green Frogzard",
        "Mammazard",
        "*"
    ],
    "lootNames" : [
        "Frogzard Scale",
        "Greenguard Blade",
        "*"
    ],
    "potionSafeUsageThresholds" : {
        "redPotion" : 30,
        "bluePotion" : 50,
        "safe" : 50
    },
    "skillOrder" : {
        "skill1" : 1,
        "skill2" : 2,
        "skill3" : 3,
        "skillU" : 4,
        "skillC" : 5,
        "skillS" : 1
    }
}
Posts 1–7 of 7 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?