Skip to content

Commit 77e8205

Browse files
committed
implement last canX methods in game
1 parent 866b0a8 commit 77e8205

File tree

2 files changed

+191
-7
lines changed

2 files changed

+191
-7
lines changed

src/main/java/bwapi/Game.java

Lines changed: 191 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -621,9 +621,114 @@ public boolean canMake(final UnitType type) {
621621
return canMake(type, null);
622622
}
623623

624-
//TODO
625624
public boolean canMake(final UnitType type, final Unit builder) {
626-
return true;
625+
Player pSelf = self();
626+
// Error checking
627+
if (pSelf == null) {
628+
return false;
629+
}
630+
631+
// Check if the unit type is available (UMS game)
632+
if ( !pSelf.isUnitAvailable(type) ) {
633+
return false;
634+
}
635+
636+
// Get the required UnitType
637+
final UnitType requiredType = type.whatBuilds().getKey();
638+
639+
// do checks if a builder is provided
640+
if ( builder != null ) {
641+
// Check if the owner of the unit is you
642+
if (!pSelf.equals(builder.getPlayer())) {
643+
return false;
644+
}
645+
646+
final UnitType builderType = builder.getType();
647+
if ( type == Zerg_Nydus_Canal && builderType == Zerg_Nydus_Canal ) {
648+
if ( !builder.isCompleted() ) {
649+
return false;
650+
}
651+
return builder.getNydusExit() == null;
652+
}
653+
654+
// Check if this unit can actually build the unit type
655+
if ( requiredType == Zerg_Larva && builderType.producesLarva() ) {
656+
if ( builder.getLarva().size() == 0 ) {
657+
return false;
658+
}
659+
}
660+
else if ( builderType != requiredType ) {
661+
return false;
662+
}
663+
664+
// Carrier/Reaver space checking
665+
int max_amt;
666+
switch ( builderType ) {
667+
case Protoss_Carrier:
668+
case Hero_Gantrithor:
669+
// Get max interceptors
670+
max_amt = 4;
671+
if ( pSelf.getUpgradeLevel(UpgradeType.Carrier_Capacity) > 0 || builderType == Hero_Gantrithor ) {
672+
max_amt += 4;
673+
}
674+
675+
// Check if there is room
676+
if ( builder.getInterceptorCount() + builder.getTrainingQueue().size() >= max_amt ) {
677+
return false;
678+
}
679+
break;
680+
case Protoss_Reaver:
681+
case Hero_Warbringer:
682+
// Get max scarabs
683+
max_amt = 5;
684+
if ( pSelf.getUpgradeLevel(UpgradeType.Reaver_Capacity) > 0 || builderType == Hero_Warbringer ) {
685+
max_amt += 5;
686+
}
687+
688+
// check if there is room
689+
if (builder.getScarabCount() + builder.getTrainingQueue().size() >= max_amt) {
690+
return false;
691+
}
692+
break;
693+
}
694+
} // if builder != nullptr
695+
696+
// Check if player has enough minerals
697+
if ( pSelf.minerals() < type.mineralPrice() ) {
698+
return false;
699+
}
700+
701+
// Check if player has enough gas
702+
if ( pSelf.gas() < type.gasPrice() ) {
703+
return false;
704+
}
705+
706+
// Check if player has enough supplies
707+
Race typeRace = type.getRace();
708+
final int supplyRequired = type.supplyRequired() * (type.isTwoUnitsInOneEgg() ? 2 : 1);
709+
if (supplyRequired > 0 && pSelf.supplyTotal(typeRace) < pSelf.supplyUsed(typeRace) + supplyRequired - (requiredType.getRace() == typeRace ? requiredType.supplyRequired() : 0)) {
710+
return false;
711+
}
712+
713+
UnitType addon = UnitType.None;
714+
Map<UnitType, Integer> reqUnits = type.requiredUnits();
715+
for (final UnitType ut : type.requiredUnits().keySet()) {
716+
if (ut.isAddon())
717+
addon = ut;
718+
719+
if (!pSelf.hasUnitTypeRequirement(ut, reqUnits.get(ut))) {
720+
return false;
721+
}
722+
}
723+
724+
if (type.requiredTech() != TechType.None && !pSelf.hasResearched(type.requiredTech())) {
725+
return false;
726+
}
727+
728+
return builder == null ||
729+
addon == UnitType.None ||
730+
addon.whatBuilds().getKey() != type.whatBuilds().getKey() ||
731+
(builder.getAddon() != null && builder.getAddon().getType() == addon);
627732
}
628733

629734
public boolean canResearch(final TechType type, final Unit unit) {
@@ -634,8 +739,50 @@ public boolean canResearch(final TechType type) {
634739
return canResearch(type, null);
635740
}
636741

637-
//TODO
638742
public boolean canResearch(final TechType type, final Unit unit, final boolean checkCanIssueCommandType) {
743+
final Player self = self();
744+
// Error checking
745+
if ( self == null ) {
746+
return false;
747+
}
748+
749+
if ( unit != null ) {
750+
if (!unit.getPlayer().equals(self)) {
751+
return false;
752+
}
753+
754+
if (!unit.getType().isSuccessorOf(type.whatResearches())) {
755+
return false;
756+
}
757+
758+
if ( checkCanIssueCommandType && ( unit.isLifted() || !unit.isIdle() || !unit.isCompleted() ) ) {
759+
return false;
760+
}
761+
}
762+
if (self.isResearching(type)) {
763+
return false;
764+
}
765+
766+
if (self.hasResearched(type)) {
767+
return false;
768+
}
769+
770+
if ( !self.isResearchAvailable(type) ) {
771+
return false;
772+
}
773+
774+
if (self.minerals() < type.mineralPrice()) {
775+
return false;
776+
}
777+
778+
if (self.gas() < type.gasPrice()) {
779+
return false;
780+
}
781+
782+
if (!self.hasUnitTypeRequirement(type.requiredUnit())) {
783+
return false;
784+
}
785+
639786
return true;
640787
}
641788

@@ -647,13 +794,51 @@ public boolean canUpgrade(final UpgradeType type) {
647794
return canUpgrade(type, null);
648795
}
649796

650-
//TODO
651797
public boolean canUpgrade(final UpgradeType type, final Unit unit, final boolean checkCanIssueCommandType) {
652-
return true;
798+
final Player self = self();
799+
if ( self == null) {
800+
return false;
801+
}
802+
803+
if ( unit != null ) {
804+
if (!unit.getPlayer().equals(self)) {
805+
return false;
806+
}
807+
808+
if (!unit.getType().isSuccessorOf(type.whatUpgrades())) {
809+
return false;
810+
}
811+
812+
if ( checkCanIssueCommandType && ( unit.isLifted() || !unit.isIdle() || !unit.isCompleted())) {
813+
return false;
814+
}
815+
}
816+
int nextLvl = self.getUpgradeLevel(type) + 1;
817+
818+
if (!self.hasUnitTypeRequirement(type.whatUpgrades())) {
819+
return false;
820+
}
821+
822+
if (!self.hasUnitTypeRequirement(type.whatsRequired(nextLvl))) {
823+
return false;
824+
}
825+
826+
if (self.isUpgrading(type)) {
827+
return false;
828+
}
829+
830+
if ( self.getUpgradeLevel(type) >= self.getMaxUpgradeLevel(type)) {
831+
return false;
832+
}
833+
834+
if ( self.minerals() < type.mineralPrice(nextLvl)) {
835+
return false;
836+
}
837+
838+
return self.gas() >= type.gasPrice(nextLvl);
653839
}
654840

655841
public List<TilePosition> getStartLocations() {
656-
//TODO cache this?
657842
return IntStream.range(0, gameData.startLocationCount())
658843
.mapToObj(i -> new TilePosition(gameData.startLocationX(i), gameData.startLocationY(i)))
659844
.collect(Collectors.toList());

src/main/java/bwapi/types/UnitTypeContainer.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ class UnitTypeContainer {
8888
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
8989
};
9090

91-
//TODO this is UNSIGNED in bwapi-c++ (ask n00byedge to be sure)
9291
static int Building = 0x00000001;
9392
static int Addon = 0x00000002;
9493
static int Flyer = 0x00000004;

0 commit comments

Comments
 (0)