-
Notifications
You must be signed in to change notification settings - Fork 1
/
Dll.c
206 lines (177 loc) · 6.67 KB
/
Dll.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// i686-w64-mingw32-gcc -mabi=ms -shared -o Dll.dll Dll.c -I../include -L. -lBWAPIC
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
#include <AIModule.h>
#include <Game.h>
#include <Iterator.h>
#include <Unit.h>
#include <Player.h>
#include <Event.h>
typedef struct BWAPI_Game BWAPI_Game; // BWAPI::Game
typedef struct BWAPI_AIModule BWAPI_AIModule; // BWAPI::AIModule
static Game* Broodwar;
typedef struct ExampleAIModule
{
const AIModule_vtable* vtable_;
const char* name;
} ExampleAIModule;
void onStart(AIModule* self) {
ExampleAIModule* module = (ExampleAIModule*) self;
Game_sendText(Broodwar, "Hello from AIModule!");
Game_sendText(Broodwar, "My name is %s", module->name);
}
void onEnd(AIModule* module, bool isWinner) {
Game_sendText(Broodwar, "Game ended");
}
bool isMineralField(Unit* unit) {
int type_id = Unit_getType(unit).id;
return type_id == 176 // Resource_Mineral_Field
|| type_id == 177 // Resource_Mineral_Field_Type_2
|| type_id == 178; // Resource_Mineral_Field_Type_3
}
void onFrame(AIModule* self) {
const int frame_count = Game_getFrameCount(Broodwar);
CoordinateType CoordinateType_None = { .id = 0 };
Game_drawText(Broodwar, CoordinateType_None, 10, 10, "Frame %d", frame_count);
Player* const ai = Game_self(Broodwar);
if (true) {
// getEvents test
Iterator* const events = (Iterator*) Game_getEvents(Broodwar);
assert(events);
for(; Iterator_valid(events); Iterator_next(events)) {
const Event e = * (Event*)Iterator_get(events);
if (e.type.id != 2) { // MatchFrame
Game_sendText(Broodwar, "EventType = (%d)", e.type.id);
Game_sendText(Broodwar, "Position = (%d,%d)", e.position.x, e.position.y);
if (e.player) {
Game_sendText(Broodwar, "Player minerals = %d", Player_minerals(e.player));
} else {
Game_sendText(Broodwar, "Player = NULL");
}
if (e.unit) {
Game_sendText(Broodwar, "Unit id = %d", Unit_getID(e.unit));
} else {
Game_sendText(Broodwar, "Unit = NULL");
}
BwString* txt = Event_getText(&e);
Game_sendText(Broodwar, "Text = (%s)", BwString_data(txt));
BwString_release(txt);
}
}
Iterator_release(events);
}
if (frame_count == 50) {
// getStartLocations test
Iterator* const positions = (Iterator*) Game_getStartLocations(Broodwar);
if (!Iterator_valid(positions)) {
Game_sendText(Broodwar, "Start location iterator is empty.");
}
for(int i = 0; Iterator_valid(positions); Iterator_next(positions), i++) {
const TilePosition tp = *(TilePosition*) Iterator_get(positions);
Game_sendText(Broodwar, "Start location %d = (%d, %d)", i, tp.x, tp.y);
}
Iterator_release(positions);
}
Iterator* const units = (Iterator*) Player_getUnits(ai);
assert(units);
for (; Iterator_valid(units); Iterator_next(units)) {
Unit* const unit = (Unit*) Iterator_get(units);
assert(unit);
if ( !Unit_exists(unit) )
continue;
const UnitType type = Unit_getType(unit);
switch (type.id) {
case 7: // SCV
case 41: // Drone
case 64: // Probe
if (Unit_isIdle(unit)) {
if (Unit_isCarryingGas(unit) || Unit_isCarryingMinerals(unit)) {
Unit_returnCargo(unit, false);
} else {
Unit* const closest_mineral = Unit_getClosestUnit(unit, &isMineralField, /*radius*/ 999999);
if (closest_mineral)
Unit_rightClick_Unit(unit, closest_mineral, false);
}
}
break;
case 106: {// Terran_Command_Center
UnitType SCV = {.id = 7 };
Unit_train(unit, SCV);
Iterator* const tqueue = (Iterator*) Unit_getTrainingQueue(unit);
assert(tqueue);
for (int x = 10, y = 20; Iterator_valid(tqueue); Iterator_next(tqueue), y += 10) {
UnitType* const unittype = (UnitType*) Iterator_get(tqueue);
assert(unittype);
Game_drawText(Broodwar, CoordinateType_None, x, y, "UnitType %d", unittype->id);
}
Iterator_release(tqueue);
} break;
case 154: { // Protoss_Nexus
UnitType Probe = {.id = 64 };
Unit_train(unit, Probe);
} break;
case 131: // Zerg_Hatchery
case 132: // Zerg_Lair
case 133: { // Zerg_Hive
UnitType Drone = {.id = 41 };
Unit_train(unit, Drone);
} break;
}
}
Iterator_release(units);
}
void onSendText(AIModule* module, const char* text) {}
void onReceiveText(AIModule* module, Player* player, const char* text) {}
void onPlayerLeft(AIModule* module, Player* player) {}
void onNukeDetect(AIModule* module, Position target) {}
void onUnitDiscover(AIModule* module, Unit* unit) {}
void onUnitEvade(AIModule* module, Unit* unit) {}
void onUnitShow(AIModule* module, Unit* unit) {}
void onUnitHide(AIModule* module, Unit* unit) {}
void onUnitCreate(AIModule* module, Unit* unit) {}
void onUnitDestroy(AIModule* module, Unit* unit) {}
void onUnitMorph(AIModule* module, Unit* unit) {}
void onUnitRenegade(AIModule* module, Unit* unit) {}
void onSaveGame(AIModule* module, const char* gameName) {}
void onUnitComplete(AIModule* module, Unit* unit) {}
static AIModule_vtable module_vtable = {
onStart,
onEnd,
onFrame,
onSendText,
onReceiveText,
onPlayerLeft,
onNukeDetect,
onUnitDiscover,
onUnitEvade,
onUnitShow,
onUnitHide,
onUnitCreate,
onUnitDestroy,
onUnitMorph,
onUnitRenegade,
onSaveGame,
onUnitComplete
};
__declspec(dllexport) void gameInit(BWAPI_Game* game) {
Broodwar = (Game*) game;
BWAPIC_setGame(Broodwar);
}
__declspec(dllexport) BWAPI_AIModule* newAIModule() {
ExampleAIModule* const module = (ExampleAIModule*) malloc( sizeof(ExampleAIModule) );
module->name = "ExampleAIModule";
module->vtable_ = &module_vtable;
return (BWAPI_AIModule*) createAIModuleWrapper( (AIModule*) module );
}
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}