Code edit (4 edits merged)
Please save this source code
User prompt
under welcomeText, add a help text "how to play..."
Code edit (2 edits merged)
Please save this source code
User prompt
on the popup write the text "Welcome on Dune."
Code edit (1 edits merged)
Please save this source code
User prompt
before game starts, show popup Asset
User prompt
before the game starts display a popup
Code edit (6 edits merged)
Please save this source code
User prompt
how would you handle energy so that low energy level slow down constructions
Code edit (3 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'type')' in or related to this line: 'player1.spice += buildableRepository.getBuildableInfo(currentBuildingForPlacement.type).cost;' Line Number: 462
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (8 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: unit is not defined' in or related to this line: 'switch (unit.type) {' Line Number: 2176
Code edit (1 edits merged)
Please save this source code
Code edit (14 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: rockIlot2Center is not defined' in or related to this line: 'baseBuilding = {' Line Number: 1740
Code edit (1 edits merged)
Please save this source code
Code edit (5 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: LK.getTime is not a function' in or related to this line: 'self.lastHitTime = LK.getTime();' Line Number: 1099
Code edit (2 edits merged)
Please save this source code
User prompt
could you implement findFactoryForUnit
Code edit (1 edits merged)
Please save this source code
User prompt
add a new function findEmplacementForBuilding(building, cellX, cellY) that scans the map around the given cellX,cellY to find a free area of rocks that fits the given building size
===================================================================
--- original.js
+++ change.js
@@ -1575,8 +1575,11 @@
gameMap.cells[x][y].unit = unit;
if (playerId === player1.playerId) {
player1.addUnit(unit);
} else if (playerId === player2.playerId) {
+ if (aiCurrentlyBuildingForArmy) {
+ aiCurrentArmyUnits.push(unit);
+ }
player2.addUnit(unit);
}
game.addChild(unit);
return unit;
@@ -2033,11 +2036,19 @@
};
var aiCurrentUnitConstruction = null;
var aiCurrentBuildingConstruction = null;
var aiNeededBuildingList = null;
-var aiNeededUnitsList = null;
+var aiNeededDefenseUnitsList = null;
var aiBuildingsUnderAttackList = null;
var aiUnitsUnderAttackList = null;
+var aiCurrentArmyUnits = [];
+var aiCurrentlyBuildingForArmy = false;
+var aiArmyIsReady = false;
+var aiNeededAttackUnitsList = null;
+var aiLastAttackWaveTime = 0;
+var aiNextAttackWaveSize = 0;
+var aiCurrentAttackWave = 1;
+var aiNextAttackWaveDelayMs = 1000 * 5; //1000 * 60; // TODO : handle in AiLevel // TEMP DEBUG !!!// TEMP DEBUG !!!// TEMP DEBUG !!!
var aiUnderAttackDelayMs = aiCurrentLevel.thinkingDelay * 10;
// Think of what AI must do
function aiThinking() {
if (LK.ticks % aiCurrentLevel.thinkingDelay !== 0) {
@@ -2046,14 +2057,15 @@
console.log("aiThinking...");
// Check buildings requirements
aiNeededBuildingList = checkBuildingRequirements();
// Check units requirements
- aiNeededUnitsList = checkUnitRequirements();
+ aiNeededDefenseUnitsList = checkDefenseUnitsRequirements();
// Check buildings defense needs
aiBuildingsUnderAttackList = checkBuildingUnderAttack();
// Check units defense needs
aiUnitsUnderAttackList = checkUnitsUnderAttack();
// Check attack opportunities
+ aiNeededAttackUnitsList = checkAttckWaveUnitNeeds();
}
function checkBuildingRequirements() {
console.log("checkBuildingRequirements...");
console.log("player2 buildings:", player2.buildings);
@@ -2101,10 +2113,81 @@
}
});
return tempUnderAttackUnitsArray;
}
-function checkUnitRequirements() {
- console.log("checkUnitRequirements...");
+function checkAttckWaveUnitNeeds() {
+ console.log("checkAttckWaveUnitNeeds...");
+ var tempNeededUnitList = {};
+ var aiBaseUnitListPerWave = getUnitNeedsPerWave(aiCurrentAttackWave);
+ // aiThinking : evaluate army needs => list needed units
+ // Browse aiCurrentArmyUnits and compare with aiBaseUnitListPerWave
+ var tempNbQuads = 0;
+ var tempNbLightTanks = 0;
+ var tempNbHeavyTanks = 0;
+ aiCurrentArmyUnits.forEach(function (unit) {
+ if (unit && unit.health > 0) {
+ var unit = this; // Define the unit variable
+ switch (unit.type) {
+ case "unitQuad":
+ tempNbQuads++;
+ break;
+ case "unitLightTank":
+ tempNbLightTanks++;
+ break;
+ case "unitHeavyTank":
+ tempNbHeavyTanks++;
+ break;
+ default:
+ console.error("unknown army unit type:", unit.type);
+ break;
+ }
+ }
+ });
+ Object.keys(aiBaseUnitListPerWave).forEach(function (unitType) {
+ switch (unit.type) {
+ case "unitQuad":
+ if (tempNbQuads < aiBaseUnitListPerWave[unitType]) {
+ tempNeededUnitList[unitType] = aiBaseUnitListPerWave[unitType] - tempNbQuads;
+ }
+ break;
+ case "unitLightTank":
+ if (tempNbLightTanks < aiBaseUnitListPerWave[unitType]) {
+ tempNeededUnitList[unitType] = aiBaseUnitListPerWave[unitType] - tempNbLightTanks;
+ }
+ break;
+ case "unitHeavyTank":
+ if (tempNbHeavyTanks < aiBaseUnitListPerWave[unitType]) {
+ tempNeededUnitList[unitType] = aiBaseUnitListPerWave[unitType] - tempNbHeavyTanks;
+ }
+ break;
+ default:
+ console.error("unknown base unit type:", unit.type);
+ break;
+ }
+ });
+ return tempNeededUnitList;
+}
+function getUnitNeedsPerWave(waveIndex) {
+ console.log("getUnitNeedsPerWave...", waveIndex);
+ /*
+ Wave 1 : 1 Quad
+ Wave 2 : 2 Quad
+ Wave 3 : 2 Quad + 1 LightTank
+ Wave 4 : 2 Quad + 2 LightTank
+ Wave 5 : 2 Quad + 2 LightTank + 1 HeavyTank
+ Wave 6+ : 2 Quad + 2 LightTank + 2 HeavyTank
+ */
+ var tempNbQuads = Math.min(2, waveIndex);
+ var tempNbLightTanks = Math.min(2, Math.max(0, waveIndex - 2));
+ var tempNbHeavyTanks = Math.min(2, Math.max(0, waveIndex - 4));
+ return {
+ 'unitQuad': tempNbQuads,
+ 'unitLightTank': tempNbLightTanks,
+ 'unitHeavyTank': tempNbHeavyTanks
+ };
+}
+function checkDefenseUnitsRequirements() {
+ console.log("checkDefenseUnitsRequirements...");
console.log("player2 units:", player2.units);
// 1) Count currently owned units
var aiCurrentUnitList = {
'unitHarvester': 0,
@@ -2137,11 +2220,11 @@
if (Object.keys(aiNeededBuildingList).length > 0 && !player2.isCurrentlyBuilding) {
aiHandleBuildingConstruction(Object.keys(aiNeededBuildingList)[0]);
}
// 2) Meet units requirements
- console.log("aiNeededUnitsList:", aiNeededUnitsList);
- if (Object.keys(aiNeededUnitsList).length > 0 && !player2.isCurrentlyBuildingUnit) {
- var tempUnitToBuild = Object.keys(aiNeededUnitsList)[0];
+ console.log("aiNeededUnitsList:", aiNeededDefenseUnitsList);
+ if (Object.keys(aiNeededDefenseUnitsList).length > 0 && !player2.isCurrentlyBuildingUnit) {
+ var tempUnitToBuild = Object.keys(aiNeededDefenseUnitsList)[0];
var tempSourceFactory = findFactoryForUnit(tempUnitToBuild, player2);
if (tempSourceFactory) {
aiHandleUnitConstruction(tempUnitToBuild, tempSourceFactory);
} else {
@@ -2161,8 +2244,28 @@
aiUnitsUnderAttackList.forEach(function (unit) {
aiHandleUnitUnderAttack(unit);
});
}
+ // 5) Meet attack wave needs
+ if (Object.keys(aiNeededAttackUnitsList).length > 0) {
+ aiArmyIsReady = false;
+ console.log("Army not ready:", aiNeededAttackUnitsList);
+ // Take 1st needed unit
+ var tempUnitToBuild = Object.keys(aiNeededAttackUnitsList)[0];
+ var tempSourceFactory = findFactoryForUnit(tempUnitToBuild, player2);
+ if (tempSourceFactory) {
+ aiHandleUnitConstruction(tempUnitToBuild, tempSourceFactory, true);
+ } else {
+ console.warn("5 - No factory found for unit " + tempUnitToBuild);
+ }
+ } else {
+ console.log("Army is ready:", aiCurrentArmyUnits);
+ aiArmyIsReady = true;
+ }
+ // 6) Launch attack wave
+ if (aiArmyIsReady && Date.now() - aiLastAttackWaveTime < aiNextAttackWaveDelayMs) {
+ console.warn("6 - ATTACK !!! ATTACK !!! ATTACK !!! ATTACK !!! ATTACK !!!");
+ }
}
function aiHandleBuildingConstruction(buildingToBuild) {
console.log("aiHandleBuildingConstruction...", buildingToBuild);
if (player2.isCurrentlyBuilding) {
@@ -2247,15 +2350,16 @@
} else {
console.log("No defenders found");
}
}
-function aiHandleUnitConstruction(unitToBuild, sourceFactory) {
- console.log("aiHandleUnitConstruction...", unitToBuild, sourceFactory);
+function aiHandleUnitConstruction(unitToBuild, sourceFactory, forArmy) {
+ console.log("aiHandleUnitConstruction...", unitToBuild, sourceFactory, forArmy);
if (player2.isCurrentlyBuildingUnit) {
console.log("Already building unit...");
return;
}
player2.isCurrentlyBuildingUnit = true;
+ aiCurrentlyBuildingForArmy = !!forArmy; // Flag to add the unit to the army
enqueueBuildable(unitToBuild, sourceFactory, player2);
}
/* ***************************************************************************************************** */
/* ********************************************* INIT FUNCTIONS ****************************************** */
@@ -2454,15 +2558,16 @@
if (currentUserActionState === UserActionState.PLACING_BUILDINGS) {
var cellCoord = screenCoordToWorldCell(input.x, input.y);
var cellX = cellCoord.wCellX;
var cellY = cellCoord.wCellY;
+ console.log("Trying cell ", cellX + ',' + cellY);
var isValidPlacement = checkBuildingPlacement(currentBuildingForPlacement, cellX, cellY);
if (currentBuildingForPlacement && currentBuildingForPlacement.asset) {
currentBuildingForPlacement.asset.tint = isValidPlacement ? 0x00FF00 : 0xFF0000;
currentBuildingForPlacement.visible = input.y + currentBuildingForPlacement.cellH * tileSize < mapHeight;
}
- currentBuildingForPlacement.x = (cellX + currentBuildingForPlacement.cellW / 2) * tileSize;
- currentBuildingForPlacement.y = (cellY + currentBuildingForPlacement.cellH / 2) * tileSize;
+ currentBuildingForPlacement.x = (cellX + currentBuildingForPlacement.cellW / 2 - viewPort.wCellX) * tileSize;
+ currentBuildingForPlacement.y = (cellY + currentBuildingForPlacement.cellH / 2 - viewPort.wCellY) * tileSize;
} else if (dragStart) {
var deltaX = currentPos.x - dragStart.x;
var deltaY = currentPos.y - dragStart.y;
var inputPosition = {
@@ -2501,9 +2606,9 @@
var isValidPlacement = checkBuildingPlacement(currentBuildingForPlacement, cellX, cellY);
if (!isValidPlacement) {
return;
}
- //console.log("Placing building ", currentBuildingForPlacement, " at " + cellX + ',' + cellY);
+ console.log("Placing building ", currentBuildingForPlacement, " at " + cellX + ',' + cellY);
handleBuildingPlacement(currentBuildingForPlacement, cellX, cellY);
currentUserActionState = UserActionState.NAVIGATING;
dragStart = null;
dragDelta = 0;
@@ -2539,9 +2644,9 @@
// Normal click
var clickCell = screenCoordToWorldCell(input.x, input.y);
var cellX = clickCell.wCellX;
var cellY = clickCell.wCellY;
- //console.log("Click at cell " + cellX + ',' + cellY);
+ console.log("Click at cell " + cellX + ',' + cellY);
var allUnits = player1.units.concat(player2.units);
allUnits.forEach(function (unit) {
unit.handleDrag(input);
unit.visible = true;
a tileable sand terrain tile.
A square tileable rock terrain tile WITHOUT BBORDER. Single Game Texture. In-Game asset. 2d. No shadows. No Border
Zenith view of Dune's Wind Trap power facility square fence. Ressembles a bit to Sydney's Opera. Zenith view Directly from above.
grey cancel icon. UI
thin white circle empty.
0x5e86ff
Zenith view of a white rectangular Harvester shape of a garbage truck with a triangular head. Harvesting on sand, with flowing spice in the back. inside a square fence. Zenith view. Directly overhead. Plumb view.
Minimal Ui icon of an right sign aside with an icon of a target. sand background
Minimal icon of a home with direction icon pointing to the home. sand background
3 white flat isometric concentric circles like a target.
Remove background
Gray background
Minimal Ui icon of target sign on a fire icon.. sand background
top view of an explosion effect.
Simple heavy army tank factory buiding a tank with a crane. Square fence... Zenith view Directly overhead. Plumb view.
an empty black popup UI. UI