Changeset View
Changeset View
Standalone View
Standalone View
binaries/data/mods/public/simulation/ai/petra/basesManager.js
Show All 19 Lines | |||||||||||
}; | }; | ||||||||||
PETRA.BasesManager.prototype.init = function(gameState) | PETRA.BasesManager.prototype.init = function(gameState) | ||||||||||
{ | { | ||||||||||
// Initialize base map. Each pixel is a base ID, or 0 if not or not accessible. | // Initialize base map. Each pixel is a base ID, or 0 if not or not accessible. | ||||||||||
this.basesMap = new API3.Map(gameState.sharedScript, "territory"); | this.basesMap = new API3.Map(gameState.sharedScript, "territory"); | ||||||||||
this.noBase = new PETRA.BaseManager(gameState, this); | this.noBase = new PETRA.BaseManager(gameState, this); | ||||||||||
this.noBase.init(gameState); | this.noBase.init(gameState); | ||||||||||
Silier: this one is missed | |||||||||||
this.noBase.accessIndex = 0; | this.noBase.accessIndex = 0; | ||||||||||
for (const cc of gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")).values()) | for (const cc of gameState.getOwnStructures().filter(API3.Filters.byClass("CivCentre")).values()) | ||||||||||
if (cc.foundationProgress() === undefined) | if (cc.foundationProgress() === undefined) | ||||||||||
this.createBase(gameState, cc); | this.createBase(gameState, cc, PETRA.BaseManager.STATE_WITH_ANCHOR); | ||||||||||
else | else | ||||||||||
this.createBase(gameState, cc, "unconstructed"); | this.createBase(gameState, cc, PETRA.BaseManager.STATE_UNCONSTRUCTED); | ||||||||||
}; | }; | ||||||||||
/** | /** | ||||||||||
* Initialization needed after deserialization (only called when deserialising). | * Initialization needed after deserialization (only called when deserialising). | ||||||||||
*/ | */ | ||||||||||
PETRA.BasesManager.prototype.postinit = function(gameState) | PETRA.BasesManager.prototype.postinit = function(gameState) | ||||||||||
{ | { | ||||||||||
// Rebuild the base maps from the territory indices of each base. | // Rebuild the base maps from the territory indices of each base. | ||||||||||
Show All 16 Lines | PETRA.BasesManager.prototype.postinit = function(gameState) | ||||||||||
} | } | ||||||||||
}; | }; | ||||||||||
/** | /** | ||||||||||
* Create a new base in the baseManager: | * Create a new base in the baseManager: | ||||||||||
* If an existing one without anchor already exist, use it. | * If an existing one without anchor already exist, use it. | ||||||||||
* Otherwise create a new one. | * Otherwise create a new one. | ||||||||||
* TODO when buildings, criteria should depend on distance | * TODO when buildings, criteria should depend on distance | ||||||||||
* allowedType: undefined => new base with an anchor | |||||||||||
* "unconstructed" => new base with a foundation anchor | |||||||||||
* "captured" => captured base with an anchor | |||||||||||
* "anchorless" => anchorless base, currently with dock | |||||||||||
*/ | */ | ||||||||||
PETRA.BasesManager.prototype.createBase = function(gameState, ent, type) | PETRA.BasesManager.prototype.createBase = function(gameState, ent, type) | ||||||||||
Done Inline Actions
^? To please @Silier. :) Freagarach: ^? To please @Silier. :) | |||||||||||
{ | { | ||||||||||
const access = PETRA.getLandAccess(gameState, ent); | const access = PETRA.getLandAccess(gameState, ent); | ||||||||||
let newbase; | let newbase; | ||||||||||
for (const base of this.baseManagers) | for (const base of this.baseManagers) | ||||||||||
{ | { | ||||||||||
if (base.accessIndex != access) | if (base.accessIndex != access) | ||||||||||
continue; | continue; | ||||||||||
if (type != "anchorless" && base.anchor) | if (type != PETRA.BaseManager.STATE_ANCHORLESS && base.anchor) | ||||||||||
continue; | continue; | ||||||||||
if (type != "anchorless") | if (type != PETRA.BaseManager.STATE_ANCHORLESS) | ||||||||||
{ | { | ||||||||||
// TODO we keep the first one, we should rather use the nearest if buildings | // TODO we keep the first one, we should rather use the nearest if buildings | ||||||||||
// and possibly also cut on distance | // and possibly also cut on distance | ||||||||||
newbase = base; | newbase = base; | ||||||||||
break; | break; | ||||||||||
} | } | ||||||||||
else | else | ||||||||||
{ | { | ||||||||||
// TODO here also test on distance instead of first | // TODO here also test on distance instead of first | ||||||||||
if (newbase && !base.anchor) | if (newbase && !base.anchor) | ||||||||||
continue; | continue; | ||||||||||
newbase = base; | newbase = base; | ||||||||||
if (newbase.anchor) | if (newbase.anchor) | ||||||||||
break; | break; | ||||||||||
} | } | ||||||||||
} | } | ||||||||||
if (this.Config.debug > 0) | if (this.Config.debug > 0) | ||||||||||
{ | { | ||||||||||
API3.warn(" ----------------------------------------------------------"); | API3.warn(" ----------------------------------------------------------"); | ||||||||||
API3.warn(" BasesManager createBase entrance avec access " + access + " and type " + type); | API3.warn(" BasesManager createBase entrance avec access " + access + " and type " + type); | ||||||||||
Done Inline Actionscan we have mapping for type or go back with strings? Silier: can we have mapping for type or go back with strings? | |||||||||||
API3.warn(" with access " + uneval(this.baseManagers.map(base => base.accessIndex)) + | API3.warn(" with access " + uneval(this.baseManagers.map(base => base.accessIndex)) + | ||||||||||
" and base nbr " + uneval(this.baseManagers.map(base => base.ID)) + | " and base nbr " + uneval(this.baseManagers.map(base => base.ID)) + | ||||||||||
" and anchor " + uneval(this.baseManagers.map(base => !!base.anchor))); | " and anchor " + uneval(this.baseManagers.map(base => !!base.anchor))); | ||||||||||
} | } | ||||||||||
if (!newbase) | if (!newbase) | ||||||||||
{ | { | ||||||||||
newbase = new PETRA.BaseManager(gameState, this); | newbase = new PETRA.BaseManager(gameState, this); | ||||||||||
newbase.init(gameState, type); | newbase.init(gameState, type); | ||||||||||
this.baseManagers.push(newbase); | this.baseManagers.push(newbase); | ||||||||||
} | } | ||||||||||
else | else | ||||||||||
newbase.reset(type); | newbase.reset(type); | ||||||||||
if (type != "anchorless") | if (type != PETRA.BaseManager.STATE_ANCHORLESS) | ||||||||||
newbase.setAnchor(gameState, ent); | newbase.setAnchor(gameState, ent); | ||||||||||
else | else | ||||||||||
newbase.setAnchorlessEntity(gameState, ent); | newbase.setAnchorlessEntity(gameState, ent); | ||||||||||
return newbase; | return newbase; | ||||||||||
}; | }; | ||||||||||
/** TODO check if the new anchorless bases should be added to addBase */ | /** TODO check if the new anchorless bases should be added to addBase */ | ||||||||||
Show All 39 Lines | for (const evt of events.Create) | ||||||||||
// (normal foundations are taken care in baseManager.assignToFoundations) | // (normal foundations are taken care in baseManager.assignToFoundations) | ||||||||||
const ent = gameState.getEntityById(evt.entity); | const ent = gameState.getEntityById(evt.entity); | ||||||||||
if (!ent || ent.owner() != PlayerID || ent.foundationProgress() === undefined) | if (!ent || ent.owner() != PlayerID || ent.foundationProgress() === undefined) | ||||||||||
continue; | continue; | ||||||||||
if (ent.getMetadata(PlayerID, "base") == -1) // Standard base around a cc | if (ent.getMetadata(PlayerID, "base") == -1) // Standard base around a cc | ||||||||||
{ | { | ||||||||||
// Okay so let's try to create a new base around this. | // Okay so let's try to create a new base around this. | ||||||||||
const newbase = this.createBase(gameState, ent, "unconstructed"); | const newbase = this.createBase(gameState, ent, PETRA.BaseManager.STATE_UNCONSTRUCTED); | ||||||||||
// Let's get a few units from other bases there to build this. | // Let's get a few units from other bases there to build this. | ||||||||||
const builders = this.bulkPickWorkers(gameState, newbase, 10); | const builders = this.bulkPickWorkers(gameState, newbase, 10); | ||||||||||
if (builders !== false) | if (builders !== false) | ||||||||||
{ | { | ||||||||||
builders.forEach(worker => { | builders.forEach(worker => { | ||||||||||
worker.setMetadata(PlayerID, "base", newbase.ID); | worker.setMetadata(PlayerID, "base", newbase.ID); | ||||||||||
worker.setMetadata(PlayerID, "subrole", "builder"); | worker.setMetadata(PlayerID, "subrole", "builder"); | ||||||||||
worker.setMetadata(PlayerID, "target-foundation", ent.id()); | worker.setMetadata(PlayerID, "target-foundation", ent.id()); | ||||||||||
}); | }); | ||||||||||
} | } | ||||||||||
} | } | ||||||||||
else if (ent.getMetadata(PlayerID, "base") == -2) // anchorless base around a dock | else if (ent.getMetadata(PlayerID, "base") == -2) // anchorless base around a dock | ||||||||||
{ | { | ||||||||||
const newbase = this.createBase(gameState, ent, "anchorless"); | const newbase = this.createBase(gameState, ent, PETRA.BaseManager.STATE_ANCHORLESS); | ||||||||||
// Let's get a few units from other bases there to build this. | // Let's get a few units from other bases there to build this. | ||||||||||
const builders = this.bulkPickWorkers(gameState, newbase, 4); | const builders = this.bulkPickWorkers(gameState, newbase, 4); | ||||||||||
if (builders != false) | if (builders != false) | ||||||||||
{ | { | ||||||||||
builders.forEach(worker => { | builders.forEach(worker => { | ||||||||||
worker.setMetadata(PlayerID, "base", newbase.ID); | worker.setMetadata(PlayerID, "base", newbase.ID); | ||||||||||
worker.setMetadata(PlayerID, "subrole", "builder"); | worker.setMetadata(PlayerID, "subrole", "builder"); | ||||||||||
worker.setMetadata(PlayerID, "target-foundation", ent.id()); | worker.setMetadata(PlayerID, "target-foundation", ent.id()); | ||||||||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | for (const evt of events.OwnershipChanged) | ||||||||||
{ | { | ||||||||||
PETRA.getBestBase(gameState, ent).assignEntity(gameState, ent); | PETRA.getBestBase(gameState, ent).assignEntity(gameState, ent); | ||||||||||
continue; | continue; | ||||||||||
} | } | ||||||||||
if (ent.hasClass("CivCentre")) // build a new base around it | if (ent.hasClass("CivCentre")) // build a new base around it | ||||||||||
{ | { | ||||||||||
let newbase; | let newbase; | ||||||||||
if (ent.foundationProgress() !== undefined) | if (ent.foundationProgress() !== undefined) | ||||||||||
newbase = this.createBase(gameState, ent, "unconstructed"); | newbase = this.createBase(gameState, ent, PETRA.BaseManager.STATE_UNCONSTRUCTED); | ||||||||||
else | else | ||||||||||
{ | { | ||||||||||
newbase = this.createBase(gameState, ent, "captured"); | newbase = this.createBase(gameState, ent, PETRA.BaseManager.STATE_CAPTURED); | ||||||||||
addBase = true; | addBase = true; | ||||||||||
} | } | ||||||||||
newbase.assignEntity(gameState, ent); | newbase.assignEntity(gameState, ent); | ||||||||||
} | } | ||||||||||
else | else | ||||||||||
{ | { | ||||||||||
let base; | let base; | ||||||||||
// If dropsite on new island, create a base around it | // If dropsite on new island, create a base around it | ||||||||||
if (!ent.decaying() && ent.resourceDropsiteTypes()) | if (!ent.decaying() && ent.resourceDropsiteTypes()) | ||||||||||
base = this.createBase(gameState, ent, "anchorless"); | base = this.createBase(gameState, ent, PETRA.BaseManager.STATE_ANCHORLESS); | ||||||||||
else | else | ||||||||||
base = PETRA.getBestBase(gameState, ent) || this.noBase; | base = PETRA.getBestBase(gameState, ent) || this.noBase; | ||||||||||
base.assignEntity(gameState, ent); | base.assignEntity(gameState, ent); | ||||||||||
} | } | ||||||||||
} | } | ||||||||||
for (const evt of events.TrainingFinished) | for (const evt of events.TrainingFinished) | ||||||||||
{ | { | ||||||||||
▲ Show 20 Lines • Show All 302 Lines • ▼ Show 20 Lines | if ((!ent.getMetadata(PlayerID, "base") || ent.getMetadata(PlayerID, "base") != base.ID) && | ||||||||||
continue; | continue; | ||||||||||
base.assignEntity(gameState, ent); | base.assignEntity(gameState, ent); | ||||||||||
bestbase = base; | bestbase = base; | ||||||||||
break; | break; | ||||||||||
} | } | ||||||||||
if (!bestbase) // entity outside our territory | if (!bestbase) // entity outside our territory | ||||||||||
{ | { | ||||||||||
if (ent.hasClass("Structure") && !ent.decaying() && ent.resourceDropsiteTypes()) | if (ent.hasClass("Structure") && !ent.decaying() && ent.resourceDropsiteTypes()) | ||||||||||
bestbase = this.createBase(gameState, ent, "anchorless"); | bestbase = this.createBase(gameState, ent, PETRA.BaseManager.STATE_ANCHORLESS); | ||||||||||
else | else | ||||||||||
bestbase = PETRA.getBestBase(gameState, ent) || this.noBase; | bestbase = PETRA.getBestBase(gameState, ent) || this.noBase; | ||||||||||
bestbase.assignEntity(gameState, ent); | bestbase.assignEntity(gameState, ent); | ||||||||||
} | } | ||||||||||
// now assign entities garrisoned inside this entity | // now assign entities garrisoned inside this entity | ||||||||||
if (ent.isGarrisonHolder() && ent.garrisoned().length) | if (ent.isGarrisonHolder() && ent.garrisoned().length) | ||||||||||
for (const id of ent.garrisoned()) | for (const id of ent.garrisoned()) | ||||||||||
bestbase.assignEntity(gameState, gameState.getEntityById(id)); | bestbase.assignEntity(gameState, gameState.getEntityById(id)); | ||||||||||
▲ Show 20 Lines • Show All 198 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
this one is missed