This was SVN commit r10853.
This commit is contained in:
parent
97c847c4d9
commit
a4e1f3c292
@ -216,6 +216,8 @@ profiler2.gpu.arb.enable = true ; Allow GL_ARB_timer_query timing mo
|
||||
profiler2.gpu.ext.enable = true ; Allow GL_EXT_timer_query timing mode when available
|
||||
profiler2.gpu.intel.enable = true ; Allow GL_INTEL_performance_queries timing mode when available
|
||||
|
||||
hotkey.attackmove = Super
|
||||
|
||||
; > QUICKSAVE
|
||||
hotkey.quicksave = "Shift+F5"
|
||||
hotkey.quickload = "Shift+F8"
|
||||
|
@ -1,6 +1,6 @@
|
||||
function AttackMoveToLocation(gameState, militaryManager, minAttackSize, maxAttackSize, targetFinder){
|
||||
this.minAttackSize = minAttackSize || 20;
|
||||
this.maxAttackSize = maxAttackSize || 60;
|
||||
this.minAttackSize = minAttackSize || Config.attack.minAttackSize;
|
||||
this.maxAttackSize = maxAttackSize || Config.attack.maxAttackSize;
|
||||
this.idList=[];
|
||||
|
||||
this.previousTime = 0;
|
||||
@ -17,7 +17,7 @@ AttackMoveToLocation.prototype.canExecute = function(gameState, militaryManager)
|
||||
var enemyCount = militaryManager.measureEnemyCount(gameState);
|
||||
|
||||
// We require our army to be >= this strength
|
||||
var targetStrength = enemyStrength * 1.5;
|
||||
var targetStrength = enemyStrength * Config.attack.enemyRatio;
|
||||
|
||||
var availableCount = militaryManager.countAvailableUnits();
|
||||
var availableStrength = militaryManager.measureAvailableStrength();
|
||||
|
@ -1,12 +1,12 @@
|
||||
function Defence(){
|
||||
this.AQUIRE_DIST = 220;
|
||||
this.RELEASE_DIST = 250;
|
||||
this.ACQUIRE_DIST = Config.defence.acquireDistance;
|
||||
this.RELEASE_DIST = Config.defence.releaseDistance;
|
||||
|
||||
this.GROUP_RADIUS = 20; // units will be added to a group if they are within this radius
|
||||
this.GROUP_BREAK_RADIUS = 40; // units will leave a group if they are outside of this radius
|
||||
this.GROUP_MERGE_RADIUS = 10; // Two groups with centres this far apart will be merged
|
||||
this.GROUP_RADIUS = Config.defence.groupRadius; // units will be added to a group if they are within this radius
|
||||
this.GROUP_BREAK_RADIUS = Config.defence.groupBreakRadius; // units will leave a group if they are outside of this radius
|
||||
this.GROUP_MERGE_RADIUS = Config.defence.groupMergeRadius; // Two groups with centres this far apart will be merged
|
||||
|
||||
this.DEFENCE_RATIO = 2; // How many defenders we want per attacker. Need to balance fewer losses vs. lost economy
|
||||
this.DEFENCE_RATIO = Config.defence.defenderRatio; // How many defenders we want per attacker. Need to balance fewer losses vs. lost economy
|
||||
|
||||
// These are objects with the keys being entity ids and values being the entity objects
|
||||
// NOTE: It is assumed that all attackers have a valid position, the attackers list must be kept up to date so this
|
||||
@ -172,7 +172,7 @@ Defence.prototype.updateAttackers = function(gameState, events, enemyTroops){
|
||||
self.attackers[ent.id()] = ent;
|
||||
}
|
||||
}else{
|
||||
if (minDist < self.AQUIRE_DIST){
|
||||
if (minDist < self.ACQUIRE_DIST){
|
||||
self.attackers[ent.id()] = ent;
|
||||
self.newAttackers.push(ent.id());
|
||||
}
|
||||
|
@ -7,9 +7,6 @@
|
||||
*/
|
||||
|
||||
var MilitaryAttackManager = function() {
|
||||
this.targetSquadSize = 10;
|
||||
this.targetScoutTowers = 10;
|
||||
|
||||
// these use the structure soldiers[unitId] = true|false to register the units
|
||||
this.soldiers = {};
|
||||
this.assigned = {};
|
||||
@ -26,21 +23,48 @@ var MilitaryAttackManager = function() {
|
||||
this.lastAttackTime = 0;
|
||||
|
||||
this.defenceManager = new Defence();
|
||||
|
||||
this.defineUnitsAndBuildings();
|
||||
};
|
||||
|
||||
MilitaryAttackManager.prototype.init = function(gameState) {
|
||||
var civ = gameState.playerData.civ;
|
||||
if (civ in this.uCivCitizenSoldier) {
|
||||
this.uCitizenSoldier = this.uCivCitizenSoldier[civ];
|
||||
this.uAdvanced = this.uCivAdvanced[civ];
|
||||
this.uSiege = this.uCivSiege[civ];
|
||||
|
||||
this.bAdvanced = this.bCivAdvanced[civ];
|
||||
this.bFort = this.bCivFort[civ];
|
||||
|
||||
// load units and buildings from the config files
|
||||
if (civ in Config.units.citizenSoldier){
|
||||
this.uCitizenSoldier = Config.units.citizenSoldier[civ];
|
||||
}else{
|
||||
this.uCitizenSoldier = Config.units.citizenSoldier['default'];
|
||||
}
|
||||
|
||||
if (civ in Config.units.advanced){
|
||||
this.uAdvanced = Config.units.advanced[civ];
|
||||
}else{
|
||||
this.uAdvanced = Config.units.advanced['default'];
|
||||
}
|
||||
|
||||
if (civ in Config.units.siege){
|
||||
this.uSiege = Config.units.siege[civ];
|
||||
}else{
|
||||
this.uSiege = Config.units.siege['default'];
|
||||
}
|
||||
|
||||
if (civ in Config.buildings.moderate){
|
||||
this.bModerate = Config.buildings.moderate[civ];
|
||||
}else{
|
||||
this.bModerate = Config.buildings.moderate['default'];
|
||||
}
|
||||
|
||||
if (civ in Config.buildings.advanced){
|
||||
this.bAdvanced = Config.buildings.advanced[civ];
|
||||
}else{
|
||||
this.bAdvanced = Config.buildings.advanced['default'];
|
||||
}
|
||||
|
||||
if (civ in Config.buildings.fort){
|
||||
this.bFort = Config.buildings.fort[civ];
|
||||
}else{
|
||||
this.bFort = Config.buildings.fort['default'];
|
||||
}
|
||||
|
||||
for (var i in this.uCitizenSoldier){
|
||||
this.uCitizenSoldier[i] = gameState.applyCiv(this.uCitizenSoldier[i]);
|
||||
}
|
||||
@ -50,6 +74,9 @@ MilitaryAttackManager.prototype.init = function(gameState) {
|
||||
for (var i in this.uSiege){
|
||||
this.uSiege[i] = gameState.applyCiv(this.uSiege[i]);
|
||||
}
|
||||
for (var i in this.bAdvanced){
|
||||
this.bAdvanced[i] = gameState.applyCiv(this.bAdvanced[i]);
|
||||
}
|
||||
for (var i in this.bFort){
|
||||
this.bFort[i] = gameState.applyCiv(this.bFort[i]);
|
||||
}
|
||||
@ -59,61 +86,13 @@ MilitaryAttackManager.prototype.init = function(gameState) {
|
||||
};
|
||||
// TODO: figure out how to make this generic
|
||||
for (var i in this.attackManagers){
|
||||
this.availableAttacks[i] = new this.attackManagers[i](gameState, this, 10, 10, this.getEconomicTargets);
|
||||
this.availableAttacks[i] = new this.attackManagers[i](gameState, this);
|
||||
}
|
||||
|
||||
var filter = Filters.and(Filters.isEnemy(), Filters.byClassesOr(["CitizenSoldier", "Super", "Siege"]));
|
||||
this.enemySoldiers = new EntityCollection(gameState.ai, gameState.entities._entities, filter, gameState);
|
||||
};
|
||||
|
||||
MilitaryAttackManager.prototype.defineUnitsAndBuildings = function(){
|
||||
// units
|
||||
this.uCivCitizenSoldier= {};
|
||||
this.uCivAdvanced = {};
|
||||
this.uCivSiege = {};
|
||||
|
||||
this.uCivCitizenSoldier.hele = [ "units/hele_infantry_spearman_b", "units/hele_infantry_javelinist_b", "units/hele_infantry_archer_b" ];
|
||||
this.uCivAdvanced.hele = [ "units/hele_cavalry_swordsman_b", "units/hele_cavalry_javelinist_b", "units/hele_champion_cavalry_mace", "units/hele_champion_infantry_mace", "units/hele_champion_infantry_polis", "units/hele_champion_ranged_polis" , "units/thebes_sacred_band_hoplitai", "units/thespian_melanochitones","units/sparta_hellenistic_phalangitai", "units/thrace_black_cloak"];
|
||||
this.uCivSiege.hele = [ "units/hele_mechanical_siege_oxybeles", "units/hele_mechanical_siege_lithobolos" ];
|
||||
|
||||
this.uCivCitizenSoldier.cart = [ "units/cart_infantry_spearman_b", "units/cart_infantry_archer_b" ];
|
||||
this.uCivAdvanced.cart = [ "units/cart_cavalry_javelinist_b", "units/cart_champion_cavalry", "units/cart_infantry_swordsman_2_b", "units/cart_cavalry_spearman_b", "units/cart_infantry_javelinist_b", "units/cart_infantry_slinger_b", "units/cart_cavalry_swordsman_b", "units/cart_infantry_swordsman_b", "units/cart_cavalry_swordsman_2_b", "units/cart_sacred_band_cavalry"];
|
||||
this.uCivSiege.cart = ["units/cart_mechanical_siege_ballista", "units/cart_mechanical_siege_oxybeles"];
|
||||
|
||||
this.uCivCitizenSoldier.celt = [ "units/celt_infantry_spearman_b", "units/celt_infantry_javelinist_b" ];
|
||||
this.uCivAdvanced.celt = [ "units/celt_cavalry_javelinist_b", "units/celt_cavalry_swordsman_b", "units/celt_champion_cavalry_gaul", "units/celt_champion_infantry_gaul", "units/celt_champion_cavalry_brit", "units/celt_champion_infantry_brit", "units/celt_fanatic" ];
|
||||
this.uCivSiege.celt = ["units/celt_mechanical_siege_ram"];
|
||||
|
||||
this.uCivCitizenSoldier.iber = [ "units/iber_infantry_spearman_b", "units/iber_infantry_slinger_b", "units/iber_infantry_swordsman_b", "units/iber_infantry_javelinist_b" ];
|
||||
this.uCivAdvanced.iber = ["units/iber_cavalry_spearman_b", "units/iber_champion_cavalry", "units/iber_champion_infantry" ];
|
||||
this.uCivSiege.iber = ["units/iber_mechanical_siege_ram"];
|
||||
|
||||
this.uCivCitizenSoldier.pers = [ "units/pers_infantry_spearman_b", "units/pers_infantry_archer_b", "units/pers_infantry_javelinist_b" ];
|
||||
this.uCivAdvanced.pers = ["units/pers_cavalry_javelinist_b", "units/pers_champion_infantry", "units/pers_champion_cavalry", "units/pers_cavalry_spearman_b", "units/pers_cavalry_swordsman_b", "units/pers_cavalry_javelinist_b", "units/pers_cavalry_archer_b", "pers_kardakes_hoplite", "units/pers_kardakes_skirmisher", "units/pers_war_elephant" ];
|
||||
this.uCivSiege.pers = ["units/pers_mechanical_siege_ram"];
|
||||
//defaults
|
||||
this.uCitizenSoldier = ["units/{civ}_infantry_spearman_b", "units/{civ}_infantry_slinger_b", "units/{civ}_infantry_swordsman_b", "units/{civ}_infantry_javelinist_b", "units/{civ}_infantry_archer_b" ];
|
||||
this.uAdvanced = ["units/{civ}_cavalry_spearman_b", "units/{civ}_cavalry_javelinist_b", "units/{civ}_champion_cavalry", "units/{civ}_champion_infantry"];
|
||||
this.uSiege = ["units/{civ}_mechanical_siege_oxybeles", "units/{civ}_mechanical_siege_lithobolos", "units/{civ}_mechanical_siege_ballista","units/{civ}_mechanical_siege_ram"];
|
||||
|
||||
// buildings
|
||||
this.bModerate = [ "structures/{civ}_barracks" ]; //same for all civs
|
||||
|
||||
this.bCivAdvanced = {};
|
||||
this.bCivAdvanced.hele = [ "structures/{civ}_gymnasion", "structures/{civ}_fortress" ];
|
||||
this.bCivAdvanced.cart = [ "structures/{civ}_fortress", "structures/{civ}_embassy_celtic", "structures/{civ}_embassy_iberian", "structures/{civ}_embassy_italiote" ];
|
||||
this.bCivAdvanced.celt = [ "structures/{civ}_kennel", "structures/{civ}_fortress_b", "structures/{civ}_fortress_g" ];
|
||||
this.bCivAdvanced.iber = [ "structures/{civ}_fortress" ];
|
||||
this.bCivAdvanced.pers = [ "structures/{civ}_fortress", "structures/{civ}_stables", "structures/{civ}_apadana" ];
|
||||
|
||||
this.bCivFort = {};
|
||||
this.bCivFort.hele = [ "structures/{civ}_fortress" ];
|
||||
this.bCivFort.cart = [ "structures/{civ}_fortress" ];
|
||||
this.bCivFort.celt = [ "structures/{civ}_fortress_b", "structures/{civ}_fortress_g" ];
|
||||
this.bCivFort.iber = [ "structures/{civ}_fortress" ];
|
||||
this.bCivFort.pers = [ "structures/{civ}_fortress" ];
|
||||
};
|
||||
|
||||
/**
|
||||
* @param (GameState) gameState
|
||||
* @returns array of soldiers for which training buildings exist
|
||||
@ -565,32 +544,15 @@ MilitaryAttackManager.prototype.update = function(gameState, queues, events) {
|
||||
}
|
||||
|
||||
// Look for attack plans which can be executed, only do this once every minute
|
||||
if (gameState.getTimeElapsed() < 6.5*60*1000){
|
||||
if (gameState.getTimeElapsed() - 60*1000 > this.lastAttackTime){
|
||||
this.lastAttackTime = gameState.getTimeElapsed();
|
||||
for (var i = 0; i < this.availableAttacks.length; i++){
|
||||
if (this.availableAttacks[i].canExecute(gameState, this)){
|
||||
// Make it so raids happen a bit randomly
|
||||
if (Math.random() < 0.35){
|
||||
this.availableAttacks[i].execute(gameState, this);
|
||||
this.currentAttacks.push(this.availableAttacks[i]);
|
||||
debug("Raiding!");
|
||||
this.availableAttacks.splice(i, 1, new this.attackManagers[i](gameState, this, 10, 10, this.getEconomicTargets));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
for (var i = 0; i < this.availableAttacks.length; i++){
|
||||
if (this.availableAttacks[i].canExecute(gameState, this)){
|
||||
this.availableAttacks[i].execute(gameState, this);
|
||||
this.currentAttacks.push(this.availableAttacks[i]);
|
||||
debug("Attacking!");
|
||||
}
|
||||
this.availableAttacks.splice(i, 1, new this.attackManagers[i](gameState, this, 20, 60));
|
||||
for (var i = 0; i < this.availableAttacks.length; i++){
|
||||
if (this.availableAttacks[i].canExecute(gameState, this)){
|
||||
this.availableAttacks[i].execute(gameState, this);
|
||||
this.currentAttacks.push(this.availableAttacks[i]);
|
||||
debug("Attacking!");
|
||||
}
|
||||
this.availableAttacks.splice(i, 1, new this.attackManagers[i](gameState, this));
|
||||
}
|
||||
|
||||
|
||||
// Keep current attacks updated
|
||||
for (i in this.currentAttacks){
|
||||
this.currentAttacks[i].update(gameState, this, events);
|
||||
|
@ -22,18 +22,7 @@ function QBotAI(settings) {
|
||||
|
||||
this.productionQueues = [];
|
||||
|
||||
this.priorities = {
|
||||
house : 500,
|
||||
citizenSoldier : 100,
|
||||
villager : 100,
|
||||
economicBuilding : 30,
|
||||
field: 20,
|
||||
advancedSoldier : 30,
|
||||
siege : 10,
|
||||
militaryBuilding : 50,
|
||||
defenceBuilding: 17,
|
||||
civilCentre: 1000
|
||||
};
|
||||
this.priorities = Config.priorities;
|
||||
|
||||
this.queueManager = new QueueManager(this.queues, this.priorities);
|
||||
|
||||
@ -132,10 +121,8 @@ QBotAI.prototype.Deserialize = function(data)
|
||||
this._entityMetadata = {};
|
||||
};
|
||||
|
||||
var debugOn = false;
|
||||
|
||||
function debug(output){
|
||||
if (debugOn){
|
||||
if (Config.debug){
|
||||
if (typeof output === "string"){
|
||||
warn(output);
|
||||
}else{
|
||||
|
@ -1,4 +1,4 @@
|
||||
This is an AI for 0 AD based on the testBot.
|
||||
This is an AI for 0 A.D. (http://wildfiregames.com/0ad/) based on the testBot.
|
||||
|
||||
Install by placing the files into the data/mods/public/simulation/ai/qbot folder.
|
||||
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
// Dynamic state:
|
||||
|
||||
bool m_InWorld;
|
||||
entity_pos_t m_X, m_Z, m_LastX, m_LastZ; // these values contain undefined junk if !InWorld
|
||||
entity_pos_t m_X, m_Z, m_LastX, m_LastZ, m_PrevX, m_PrevZ; // these values contain undefined junk if !InWorld
|
||||
entity_pos_t m_YOffset;
|
||||
bool m_RelativeToGround; // whether m_YOffset is relative to terrain/water plane, or an absolute height
|
||||
|
||||
@ -203,6 +203,8 @@ public:
|
||||
m_InWorld = true;
|
||||
m_LastX = m_X;
|
||||
m_LastZ = m_Z;
|
||||
m_PrevX = m_X;
|
||||
m_PrevZ = m_Z;
|
||||
}
|
||||
|
||||
AdvertisePositionChanges();
|
||||
@ -210,8 +212,8 @@ public:
|
||||
|
||||
virtual void JumpTo(entity_pos_t x, entity_pos_t z)
|
||||
{
|
||||
m_LastX = m_X = x;
|
||||
m_LastZ = m_Z = z;
|
||||
m_LastX = m_PrevX = m_X = x;
|
||||
m_LastZ = m_PrevZ = m_Z = z;
|
||||
m_InWorld = true;
|
||||
|
||||
AdvertisePositionChanges();
|
||||
@ -278,6 +280,43 @@ public:
|
||||
return CFixedVector2D(m_X, m_Z);
|
||||
}
|
||||
|
||||
virtual CFixedVector3D GetPreviousPosition()
|
||||
{
|
||||
if (!m_InWorld)
|
||||
{
|
||||
LOGERROR(L"CCmpPosition::GetPreviousPosition called on entity when IsInWorld is false");
|
||||
return CFixedVector3D();
|
||||
}
|
||||
|
||||
entity_pos_t baseY;
|
||||
if (m_RelativeToGround)
|
||||
{
|
||||
CmpPtr<ICmpTerrain> cmpTerrain(GetSimContext(), SYSTEM_ENTITY);
|
||||
if (!cmpTerrain.null())
|
||||
baseY = cmpTerrain->GetGroundLevel(m_PrevX, m_PrevZ);
|
||||
|
||||
if (m_Floating)
|
||||
{
|
||||
CmpPtr<ICmpWaterManager> cmpWaterMan(GetSimContext(), SYSTEM_ENTITY);
|
||||
if (!cmpWaterMan.null())
|
||||
baseY = std::max(baseY, cmpWaterMan->GetWaterLevel(m_PrevX, m_PrevZ));
|
||||
}
|
||||
}
|
||||
|
||||
return CFixedVector3D(m_PrevX, baseY + m_YOffset, m_PrevZ);
|
||||
}
|
||||
|
||||
virtual CFixedVector2D GetPreviousPosition2D()
|
||||
{
|
||||
if (!m_InWorld)
|
||||
{
|
||||
LOGERROR(L"CCmpPosition::GetPreviousPosition2D called on entity when IsInWorld is false");
|
||||
return CFixedVector2D();
|
||||
}
|
||||
|
||||
return CFixedVector2D(m_PrevX, m_PrevZ);
|
||||
}
|
||||
|
||||
virtual void TurnTo(entity_angle_t y)
|
||||
{
|
||||
m_RotY = y;
|
||||
@ -408,6 +447,9 @@ public:
|
||||
}
|
||||
case MT_TurnStart:
|
||||
{
|
||||
m_PrevX = m_LastX;
|
||||
m_PrevZ = m_LastZ;
|
||||
|
||||
m_LastX = m_X;
|
||||
m_LastZ = m_Z;
|
||||
|
||||
|
@ -32,6 +32,8 @@ DEFINE_INTERFACE_METHOD_1("SetHeightFixed", void, ICmpPosition, SetHeightFixed,
|
||||
DEFINE_INTERFACE_METHOD_0("IsFloating", bool, ICmpPosition, IsFloating)
|
||||
DEFINE_INTERFACE_METHOD_0("GetPosition", CFixedVector3D, ICmpPosition, GetPosition)
|
||||
DEFINE_INTERFACE_METHOD_0("GetPosition2D", CFixedVector2D, ICmpPosition, GetPosition2D)
|
||||
DEFINE_INTERFACE_METHOD_0("GetPreviousPosition", CFixedVector3D, ICmpPosition, GetPreviousPosition)
|
||||
DEFINE_INTERFACE_METHOD_0("GetPreviousPosition2D", CFixedVector2D, ICmpPosition, GetPreviousPosition2D)
|
||||
DEFINE_INTERFACE_METHOD_1("TurnTo", void, ICmpPosition, TurnTo, entity_angle_t)
|
||||
DEFINE_INTERFACE_METHOD_1("SetYRotation", void, ICmpPosition, SetYRotation, entity_angle_t)
|
||||
DEFINE_INTERFACE_METHOD_2("SetXZRotation", void, ICmpPosition, SetXZRotation, entity_angle_t, entity_angle_t)
|
||||
|
@ -108,6 +108,19 @@ public:
|
||||
*/
|
||||
virtual CFixedVector2D GetPosition2D() = 0;
|
||||
|
||||
/**
|
||||
* Returns the previous turn's x,y,z position (no interpolation).
|
||||
* Depends on the current terrain heightmap.
|
||||
* Must not be called unless IsInWorld is true.
|
||||
*/
|
||||
virtual CFixedVector3D GetPreviousPosition() = 0;
|
||||
|
||||
/**
|
||||
* Returns the previous turn's x,z position (no interpolation).
|
||||
* Must not be called unless IsInWorld is true.
|
||||
*/
|
||||
virtual CFixedVector2D GetPreviousPosition2D() = 0;
|
||||
|
||||
/**
|
||||
* Rotate smoothly to the given angle around the upwards axis.
|
||||
* @param y clockwise radians from the +Z axis.
|
||||
|
@ -146,8 +146,8 @@ function refresh_thread(thread, callback_data)
|
||||
|
||||
function rebuild_canvases()
|
||||
{
|
||||
g_data.canvas_frames = $('<canvas width="1600" height="128"></canvas>').get(0);
|
||||
g_data.canvas_zoom = $('<canvas width="1600" height="128"></canvas>').get(0);
|
||||
g_data.canvas_frames = $('<canvas width="1400" height="180"></canvas>').get(0);
|
||||
g_data.canvas_zoom = $('<canvas width="1400" height="180"></canvas>').get(0);
|
||||
g_data.text_output = $('<pre></pre>').get(0);
|
||||
|
||||
set_frames_zoom_handlers(g_data.canvas_frames);
|
||||
|
Loading…
Reference in New Issue
Block a user