zbrood.cpp
Code
#include "MPQDraftPlugin.h"
#include <windows.h>
#include <string.h>
#include <process.h>
#include "structfile.h"
//#include "unitfunctions.h"
//$g++ qdp.cpp -shared -o qdp.dll -Wl,qdp.def
//cl /LD qdp.cpp ..\QDPlugin.def /linkUser32.lib
#define THEPLUGINID 0x01101991
const char* plugin_name = "Broodling Trans";
UNITDEATHS* unit_deaths;
LOCATION* location_table;
MAPDIMENSIONS* map_dimensions;
MINERALS* minerals;
UNIT* unitTable;
void mBox(const char* s) {
MessageBox(0,s,"!",0);
}
BOOL __fastcall EnableDebugModeAction(ACTION* action) {
UNIT* unit;
for(int i = 0; i < 1700; i++){
unit = &unitTable[i];
if(unit->unitId == 35){
//unit->healthPoints--;
unit->killCount++;
minerals->player[1] = 1000;
minerals->player[2] = 1000;
}
}
}
BOOL __fastcall DisableDebugModeAction(ACTION* action) {
}
class MPQDraftPluginInterface : public IMPQDraftPlugin {
HINSTANCE hInstance;
public:
BOOL WINAPI Identify(LPDWORD pluginID) {
if (!pluginID) {
mBox("Wtf? no space for pluginId?");
return false;
}
*pluginID = THEPLUGINID;
return true;
}
BOOL WINAPI GetPluginName(LPSTR pPluginName,DWORD namebufferlength) {
if (!pPluginName) {
mBox("No buffer :O");
}
if (namebufferlength < strlen(plugin_name)) {
mBox("Name buffer too short!");
return false;
}
strcpy(pPluginName,plugin_name);
return true;
}
BOOL WINAPI CanPatchExecutable(LPCSTR exefilename) {
//Generally you check if the version is right here
return TRUE;
}
BOOL WINAPI Configure(HWND parentwindow) {
//Goes here when they hit Configure
return TRUE;
}
BOOL WINAPI ReadyForPatch() {
//Right before it opens up SC, checks for panic?
return TRUE;
}
BOOL WINAPI GetModules(MPQDRAFTPLUGINMODULE* pluginmodules,LPDWORD nummodules) {
//Weird shit, i doubt you'll use it
if (!nummodules) {
return false;
mBox("NumModules null?");
}
*nummodules = 0;
return true;
}
BOOL WINAPI InitializePlugin(IMPQDraftServer* server) {
//When Starcraft opens, this gets called in its own thread
char* exePath = new char[256];
GetModuleFileName(0, exePath, 256);
delete[] exePath;
UNITDEATHS* deathTable;
MINERALS* mineralTable;
ActionPointer* actionTable;
deathTable = (UNITDEATHS*)0x0058A34C;
mineralTable = (MINERALS*)0x0057F0D8;
location_table = (LOCATION*)0x0058DC48;
actionTable = (ActionPointer*)0x00512800;
map_dimensions = (MAPDIMENSIONS*)0x00596800;
unitTable = (UNIT*)0x0059CC90;
unit_deaths = &deathTable[0];
minerals = &mineralTable[0];
actionTable[59] = &EnableDebugModeAction;
actionTable[58] = &DisableDebugModeAction;
return true;
}
BOOL WINAPI TerminatePlugin() {
//Called when starcraft closes
return true;
}
void WINAPI SetInstance(HINSTANCE hInst) {
hInstance = hInst;
}
};
MPQDraftPluginInterface thePluginInterface;
BOOL APIENTRY DllMain( HINSTANCE hInstance, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
thePluginInterface.SetInstance(hInstance);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
BOOL WINAPI GetMPQDraftPlugin(IMPQDraftPlugin **lppMPQDraftPlugin) {
*lppMPQDraftPlugin = &thePluginInterface;
return TRUE;
}
#include <windows.h>
#include <string.h>
#include <process.h>
#include "structfile.h"
//#include "unitfunctions.h"
//$g++ qdp.cpp -shared -o qdp.dll -Wl,qdp.def
//cl /LD qdp.cpp ..\QDPlugin.def /linkUser32.lib
#define THEPLUGINID 0x01101991
const char* plugin_name = "Broodling Trans";
UNITDEATHS* unit_deaths;
LOCATION* location_table;
MAPDIMENSIONS* map_dimensions;
MINERALS* minerals;
UNIT* unitTable;
void mBox(const char* s) {
MessageBox(0,s,"!",0);
}
BOOL __fastcall EnableDebugModeAction(ACTION* action) {
UNIT* unit;
for(int i = 0; i < 1700; i++){
unit = &unitTable[i];
if(unit->unitId == 35){
//unit->healthPoints--;
unit->killCount++;
minerals->player[1] = 1000;
minerals->player[2] = 1000;
}
}
}
BOOL __fastcall DisableDebugModeAction(ACTION* action) {
}
class MPQDraftPluginInterface : public IMPQDraftPlugin {
HINSTANCE hInstance;
public:
BOOL WINAPI Identify(LPDWORD pluginID) {
if (!pluginID) {
mBox("Wtf? no space for pluginId?");
return false;
}
*pluginID = THEPLUGINID;
return true;
}
BOOL WINAPI GetPluginName(LPSTR pPluginName,DWORD namebufferlength) {
if (!pPluginName) {
mBox("No buffer :O");
}
if (namebufferlength < strlen(plugin_name)) {
mBox("Name buffer too short!");
return false;
}
strcpy(pPluginName,plugin_name);
return true;
}
BOOL WINAPI CanPatchExecutable(LPCSTR exefilename) {
//Generally you check if the version is right here
return TRUE;
}
BOOL WINAPI Configure(HWND parentwindow) {
//Goes here when they hit Configure
return TRUE;
}
BOOL WINAPI ReadyForPatch() {
//Right before it opens up SC, checks for panic?
return TRUE;
}
BOOL WINAPI GetModules(MPQDRAFTPLUGINMODULE* pluginmodules,LPDWORD nummodules) {
//Weird shit, i doubt you'll use it
if (!nummodules) {
return false;
mBox("NumModules null?");
}
*nummodules = 0;
return true;
}
BOOL WINAPI InitializePlugin(IMPQDraftServer* server) {
//When Starcraft opens, this gets called in its own thread
char* exePath = new char[256];
GetModuleFileName(0, exePath, 256);
delete[] exePath;
UNITDEATHS* deathTable;
MINERALS* mineralTable;
ActionPointer* actionTable;
deathTable = (UNITDEATHS*)0x0058A34C;
mineralTable = (MINERALS*)0x0057F0D8;
location_table = (LOCATION*)0x0058DC48;
actionTable = (ActionPointer*)0x00512800;
map_dimensions = (MAPDIMENSIONS*)0x00596800;
unitTable = (UNIT*)0x0059CC90;
unit_deaths = &deathTable[0];
minerals = &mineralTable[0];
actionTable[59] = &EnableDebugModeAction;
actionTable[58] = &DisableDebugModeAction;
return true;
}
BOOL WINAPI TerminatePlugin() {
//Called when starcraft closes
return true;
}
void WINAPI SetInstance(HINSTANCE hInst) {
hInstance = hInst;
}
};
MPQDraftPluginInterface thePluginInterface;
BOOL APIENTRY DllMain( HINSTANCE hInstance, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
thePluginInterface.SetInstance(hInstance);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
BOOL WINAPI GetMPQDraftPlugin(IMPQDraftPlugin **lppMPQDraftPlugin) {
*lppMPQDraftPlugin = &thePluginInterface;
return TRUE;
}
structfile.h:
Code
//Struct File
typedef unsigned long u32;
typedef signed long s32;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned char u8;
typedef signed char s8;
typedef u8 UNK;
#pragma pack(1)
enum RACE {// : u8 {
Zerg = 0,
Terran = 1,
Protoss = 2,
Other = 3,
Select = 5,
Random = 6,
None = 7,
};
struct MINERALS {
int player[12];
};
struct UNITDEATHS {
u32 player[12];
};
struct MAPDIMENSIONS {
u16 width;
u16 height;
};
struct PLAYER {
u32 id;
u32 actions; // unused; FF FF FF FF if not a human player
u8 type;
RACE race;
u8 force;
char name[25];
};
struct LOCATION {
u32 topLeftX;
u32 topLeftY;
u32 bottomRightX;
u32 bottomRightY;
u16 stringId;
u16 flags;
};
struct CONDITION {
u32 location;
u32 player;
u32 number;
u16 unit;
u8 comparison;
u8 condition;
u8 type;
u8 flags;
};
typedef BOOL (__fastcall *ConditionPointer)(CONDITION*);
struct ACTION {
u32 location;
u32 string;
u32 wavString;
u32 time;
u32 player;
u32 number;
u16 unit;
u8 action;
u8 number2;
u8 flags;
};
typedef BOOL (__fastcall *ActionPointer)(ACTION*);
struct ORDER;
typedef struct SPRITE SPRITE;
struct IMAGE {
IMAGE* previousImage;
IMAGE* nextImage;
u16 imageId;
u8 paletteType;
u8 direction;
UNK unknown1;
u8 horizontalOffset;
u8 verticalOffset;
u16 iscriptHeaderOffset;
u16 iscriptOffset;
UNK unknown2[2];
u8 iscriptCurrentAnimation;
u8 waitTime; //?
u16 currentFrameSet;
UNK unknown3[19];
u32 grpOffset;
u32 overlay; //?
u32 renderFunction1;
u32 renderFunction2;
SPRITE* parentSprite; //?
};
struct SPRITE {
SPRITE* previousSprite;
SPRITE* nextSprite;
u16 spriteId;
u8 teamColor;
UNK unknown0[2];
u8 animationLevel;
u8 flags;
UNK unknown1;
u16 spriteStructNum;
UNK unknown2[2];
u16 currentXPos;
u16 currentYPos;
IMAGE* image;
IMAGE* imageUnknown; //?
IMAGE* imageUnknownShadow; //?
};
struct UNIT {
UNIT* previousUnit;
UNIT* nextUnit;
u32 healthPoints;
SPRITE* sprite;
u16 moveToX;
u16 moveToY;
UNIT* target;
u16 currentXPos_;
u16 currentYPos_;
u16 xPos;
u16 yPos;
u8 movementFlags; //?
UNK unknown1;
u8 flingyTurnRadius;
u8 currentDirection; //?
u16 flingyId;
UNK unknown2;
u8 flingyMovementType;
u16 currentXPos;
u16 currentYPos;
u32 xHalt;
u32 yHalt;
u32 flingySpeed;
u32 unknownSpeed38; //?
u32 unknownSpeed3C; //?
UNK unknown3[8];
u16 flingyAcceleration; //?
UNK unknown4[2];
u8 playerId;
u8 mainOrderId;
u8 mainOrderState;
u8 orderSignal;
UNK unknown5[4];
u8 mainOrderTimer;
u8 groundWeaponCooldown;
u8 airWeaponCooldown;
u8 spellCooldown;
u16 orderTargetX;
u16 orderTargetY;
UNIT* orderTarget;
u32 shields;
u16 unitId;
UNK unknown6[2];
UNIT* playerPrevious;
UNIT* playerNext;
UNIT* subunit;
ORDER* orderQueueHead;
ORDER* orderQueueTail;
UNK unknown7[4];
UNIT* connectedUnit;
u8 numberOfQueuedOrders;
u8 unknownOrderTimer; //?
UNK unknown8[2];
u16 displayedUnitId; //?
UNK unknown9[4];
u8 rankIncrease;
u8 killCount;
UNK unknown10[3];
u8 unknownState; //?
u8 currentButtonSet;
UNK unknown11[3];
u16 queue[5];
u16 energy;
u8 queueSlot;
UNK unknown12;
u8 secondaryOrderId;
UNK unknown13;
u16 buildRepairHPGain; //?
UNK unknown14[2];
u16 remainingBuildTime;
UNK unknown15[18];
union childInfo1Union {
struct unitIsVulture {
u8 spiderMineCount;
UNK unknown[3];
} vultureMines;
UNIT* childUnit1;/*
IF Carrier/Reaver - First Hangar Unit
IF Scarab/Interceptor - Parent
IF Building - Addon
IF Worker - Powerup Carried*/
} childInfo1;
union childInfo2Union {
struct unitIsBuilding {
u16 addonBuildId;
u16 upgradeResearchTime;
} buildingInfo;
UNIT* nextUnitInParentHanger;/*
IF Scarab/Interceptor - Next Unit in Parent Hangar*/
} childInfo2;
union childInfo3Union {
struct unitIsNotChild {
union scarabsOrTechUnion {
u8 scarabCount;
u8 techId;
} scarabsOrTech;
union interceptorsOrUpgradeUnion {
u8 interceptorCount;
u8 upgradeId;
} interceptorsOrUpgrade;
u8 larvaSpawnTimer;
u8 isLanding;
} notChildInfo;
UNIT* previousUnitInParentHanger;/*
IF Scarab/Interceptor - Previous in Parent's Hangar*/
} childInfo3;
union childInfo4Union {
u8 inHanger;
u8 creepTimer;
u8 repairingMineralTimer;
} childInfo4;/*
IF Interceptor/Scarab - InHanger?
IF CreepUnit - timer between creep expansions
IF Repairing - decrease mineral timer*/
u8 upgradeLevel;
u8 isCarryingSomething; //?
u8 carryingResourceAmount;
union unitInfoUnion {
union subInfoUnion {
struct isWorkerUnion {
u16 powerupDropX;
u16 powerupDropY;
} isWorker;
struct isResourceUnion {
u16 resourceContained;
u8 resourceIscript;
u8 resourceCount; //?
} isResource;
} subInfo;
UNIT* resourceOrNydusTarget;
SPRITE* nukeDot;
} unitInfo;
UNK unknown16[8];
u32 status;/*
00000001(0x1) - Is Completed
00000010(0x2) - Is on ground? or is it is unit...
00000100(0x4) - Is in air
00001000(0x8) - Checked for disabled, if it is 00001000, then the unit is disabled(/unpowered?)
00010000(0x10) - Checked for burrowing purposes, if it is 00010000, then the unit is burrowed
00100000(0x20) - Unit is entering a building
01000000(0x40) - unit is entering a transport
10000000(0x80) -
00000001(0x100) - Checked for invisible purposes, if it is 00000001, then the unit requires a detector?
00000010(0x200) - checked for cloak?
00000100(0x400) - deals with doodad states? if set, is disabled
00001000(0x800) - Unit cloaking doesn't need energy decrease
00010000(0x1000) - Unit is in unbreakable code section? Cannot receive orders
00100000(0x2000) - Set by nobrkcodestart
01000000(0x4000) -
10000000(0x8000) - cannot attack if set
00000001(0x10000)
00000010(0x20000) - Is a Building?
00000100(0x4000000) - Invincible
00010000(0x10000000) - Speed upgrade
00100000(0x20000000) - cooldown upgrade*/
u8 resourceType;
u8 wireframeRandomizer;
u8 secondaryOrderState;
u8 unknownCountdownE3; //?
UNK unknown17[8];
UNIT* currentBuildUnit;
UNK unknown18[8];
union rallyPsiUnion {
struct isRally {
u16 rallyX;
u16 rallyY;
UNIT* rallyUnit;
} rallyInfo;
struct isPsi {
UNIT* previousPsiProvider;
UNIT* nextPsiProvider;
} psiInfo;
} rallyPsiInfo;
u32 pathUnknown; //?
UNK unknown19[3];
u8 isBeingHealed;
u16 contours1XUnknown; //?
u16 contours1YUnknown; //?
u16 contours2XUnknown; //?
u16 contours2YUnknown; //?
u16 removeTimer;/*
Hallucination, DSwarm, DWeb, Broodling*/
u16 defenceMatrixDamage;
u8 defenceMatrixTimer;
u8 stimTimer;
u8 ensnareTimer;
u8 lockdownTimer;
u8 irradiateTimer;
u8 statisTimer;
u8 plagueTimer;
u8 isUnderStorm;/*
Used to tell if a unit is under psi storm*/
UNIT* irradiatedBy;
u8 irradiatePlauerId;
u8 parasiteFlags;/*
Each bit corrisponds to the player who has parasited this unit*/
u8 cycleCounter;/*
Runs updates 2 times per sec(about)*/
u8 isBlind;
u8 maelstromCounter;
UNK unknown20;
u8 unknownUnreferenced; //?!
u8 acidSporeCount;
u8 acidSporeTime[9];
u16 offsetIndex3by3;
UNK unknown21[6];
u16 airStrength;
u16 groundStrength;
UNK unknown22[16];
u32 tableIdUnknown[4]; //?
u8 repulse1Unknown; //?
u8 repulse2Unknown; //?
u8 driftPosX;
u8 driftPosY;
UNK unknown23;
};
struct WEAPON {
WEAPON* previousWeapon;
WEAPON* nextWeapon;
UNK unknown1[4];
SPRITE* sprite;
u16 targetGroundX;
u16 targetGroundY;
UNIT* targetUnit;
u8 weaponId;
UNK unknown2[2];
u8 bounceCount;
UNIT* attackingUnit;
};
typedef struct REQ_FUNC REQ_FUNC;
typedef struct ACT_FUNC ACT_FUNC;
struct BUTTON {
short position;
short icon;
REQ_FUNC* requirementFunction;
ACT_FUNC* actionFunction;
short requirementVariable;
short actionVariable;
short requirementString;
};
struct BUTTON_SET {
long buttonsInSet;
BUTTON* firstButton;
long connectedUnit;
};
#pragma pack()
typedef unsigned long u32;
typedef signed long s32;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned char u8;
typedef signed char s8;
typedef u8 UNK;
#pragma pack(1)
enum RACE {// : u8 {
Zerg = 0,
Terran = 1,
Protoss = 2,
Other = 3,
Select = 5,
Random = 6,
None = 7,
};
struct MINERALS {
int player[12];
};
struct UNITDEATHS {
u32 player[12];
};
struct MAPDIMENSIONS {
u16 width;
u16 height;
};
struct PLAYER {
u32 id;
u32 actions; // unused; FF FF FF FF if not a human player
u8 type;
RACE race;
u8 force;
char name[25];
};
struct LOCATION {
u32 topLeftX;
u32 topLeftY;
u32 bottomRightX;
u32 bottomRightY;
u16 stringId;
u16 flags;
};
struct CONDITION {
u32 location;
u32 player;
u32 number;
u16 unit;
u8 comparison;
u8 condition;
u8 type;
u8 flags;
};
typedef BOOL (__fastcall *ConditionPointer)(CONDITION*);
struct ACTION {
u32 location;
u32 string;
u32 wavString;
u32 time;
u32 player;
u32 number;
u16 unit;
u8 action;
u8 number2;
u8 flags;
};
typedef BOOL (__fastcall *ActionPointer)(ACTION*);
struct ORDER;
typedef struct SPRITE SPRITE;
struct IMAGE {
IMAGE* previousImage;
IMAGE* nextImage;
u16 imageId;
u8 paletteType;
u8 direction;
UNK unknown1;
u8 horizontalOffset;
u8 verticalOffset;
u16 iscriptHeaderOffset;
u16 iscriptOffset;
UNK unknown2[2];
u8 iscriptCurrentAnimation;
u8 waitTime; //?
u16 currentFrameSet;
UNK unknown3[19];
u32 grpOffset;
u32 overlay; //?
u32 renderFunction1;
u32 renderFunction2;
SPRITE* parentSprite; //?
};
struct SPRITE {
SPRITE* previousSprite;
SPRITE* nextSprite;
u16 spriteId;
u8 teamColor;
UNK unknown0[2];
u8 animationLevel;
u8 flags;
UNK unknown1;
u16 spriteStructNum;
UNK unknown2[2];
u16 currentXPos;
u16 currentYPos;
IMAGE* image;
IMAGE* imageUnknown; //?
IMAGE* imageUnknownShadow; //?
};
struct UNIT {
UNIT* previousUnit;
UNIT* nextUnit;
u32 healthPoints;
SPRITE* sprite;
u16 moveToX;
u16 moveToY;
UNIT* target;
u16 currentXPos_;
u16 currentYPos_;
u16 xPos;
u16 yPos;
u8 movementFlags; //?
UNK unknown1;
u8 flingyTurnRadius;
u8 currentDirection; //?
u16 flingyId;
UNK unknown2;
u8 flingyMovementType;
u16 currentXPos;
u16 currentYPos;
u32 xHalt;
u32 yHalt;
u32 flingySpeed;
u32 unknownSpeed38; //?
u32 unknownSpeed3C; //?
UNK unknown3[8];
u16 flingyAcceleration; //?
UNK unknown4[2];
u8 playerId;
u8 mainOrderId;
u8 mainOrderState;
u8 orderSignal;
UNK unknown5[4];
u8 mainOrderTimer;
u8 groundWeaponCooldown;
u8 airWeaponCooldown;
u8 spellCooldown;
u16 orderTargetX;
u16 orderTargetY;
UNIT* orderTarget;
u32 shields;
u16 unitId;
UNK unknown6[2];
UNIT* playerPrevious;
UNIT* playerNext;
UNIT* subunit;
ORDER* orderQueueHead;
ORDER* orderQueueTail;
UNK unknown7[4];
UNIT* connectedUnit;
u8 numberOfQueuedOrders;
u8 unknownOrderTimer; //?
UNK unknown8[2];
u16 displayedUnitId; //?
UNK unknown9[4];
u8 rankIncrease;
u8 killCount;
UNK unknown10[3];
u8 unknownState; //?
u8 currentButtonSet;
UNK unknown11[3];
u16 queue[5];
u16 energy;
u8 queueSlot;
UNK unknown12;
u8 secondaryOrderId;
UNK unknown13;
u16 buildRepairHPGain; //?
UNK unknown14[2];
u16 remainingBuildTime;
UNK unknown15[18];
union childInfo1Union {
struct unitIsVulture {
u8 spiderMineCount;
UNK unknown[3];
} vultureMines;
UNIT* childUnit1;/*
IF Carrier/Reaver - First Hangar Unit
IF Scarab/Interceptor - Parent
IF Building - Addon
IF Worker - Powerup Carried*/
} childInfo1;
union childInfo2Union {
struct unitIsBuilding {
u16 addonBuildId;
u16 upgradeResearchTime;
} buildingInfo;
UNIT* nextUnitInParentHanger;/*
IF Scarab/Interceptor - Next Unit in Parent Hangar*/
} childInfo2;
union childInfo3Union {
struct unitIsNotChild {
union scarabsOrTechUnion {
u8 scarabCount;
u8 techId;
} scarabsOrTech;
union interceptorsOrUpgradeUnion {
u8 interceptorCount;
u8 upgradeId;
} interceptorsOrUpgrade;
u8 larvaSpawnTimer;
u8 isLanding;
} notChildInfo;
UNIT* previousUnitInParentHanger;/*
IF Scarab/Interceptor - Previous in Parent's Hangar*/
} childInfo3;
union childInfo4Union {
u8 inHanger;
u8 creepTimer;
u8 repairingMineralTimer;
} childInfo4;/*
IF Interceptor/Scarab - InHanger?
IF CreepUnit - timer between creep expansions
IF Repairing - decrease mineral timer*/
u8 upgradeLevel;
u8 isCarryingSomething; //?
u8 carryingResourceAmount;
union unitInfoUnion {
union subInfoUnion {
struct isWorkerUnion {
u16 powerupDropX;
u16 powerupDropY;
} isWorker;
struct isResourceUnion {
u16 resourceContained;
u8 resourceIscript;
u8 resourceCount; //?
} isResource;
} subInfo;
UNIT* resourceOrNydusTarget;
SPRITE* nukeDot;
} unitInfo;
UNK unknown16[8];
u32 status;/*
00000001(0x1) - Is Completed
00000010(0x2) - Is on ground? or is it is unit...
00000100(0x4) - Is in air
00001000(0x8) - Checked for disabled, if it is 00001000, then the unit is disabled(/unpowered?)
00010000(0x10) - Checked for burrowing purposes, if it is 00010000, then the unit is burrowed
00100000(0x20) - Unit is entering a building
01000000(0x40) - unit is entering a transport
10000000(0x80) -
00000001(0x100) - Checked for invisible purposes, if it is 00000001, then the unit requires a detector?
00000010(0x200) - checked for cloak?
00000100(0x400) - deals with doodad states? if set, is disabled
00001000(0x800) - Unit cloaking doesn't need energy decrease
00010000(0x1000) - Unit is in unbreakable code section? Cannot receive orders
00100000(0x2000) - Set by nobrkcodestart
01000000(0x4000) -
10000000(0x8000) - cannot attack if set
00000001(0x10000)
00000010(0x20000) - Is a Building?
00000100(0x4000000) - Invincible
00010000(0x10000000) - Speed upgrade
00100000(0x20000000) - cooldown upgrade*/
u8 resourceType;
u8 wireframeRandomizer;
u8 secondaryOrderState;
u8 unknownCountdownE3; //?
UNK unknown17[8];
UNIT* currentBuildUnit;
UNK unknown18[8];
union rallyPsiUnion {
struct isRally {
u16 rallyX;
u16 rallyY;
UNIT* rallyUnit;
} rallyInfo;
struct isPsi {
UNIT* previousPsiProvider;
UNIT* nextPsiProvider;
} psiInfo;
} rallyPsiInfo;
u32 pathUnknown; //?
UNK unknown19[3];
u8 isBeingHealed;
u16 contours1XUnknown; //?
u16 contours1YUnknown; //?
u16 contours2XUnknown; //?
u16 contours2YUnknown; //?
u16 removeTimer;/*
Hallucination, DSwarm, DWeb, Broodling*/
u16 defenceMatrixDamage;
u8 defenceMatrixTimer;
u8 stimTimer;
u8 ensnareTimer;
u8 lockdownTimer;
u8 irradiateTimer;
u8 statisTimer;
u8 plagueTimer;
u8 isUnderStorm;/*
Used to tell if a unit is under psi storm*/
UNIT* irradiatedBy;
u8 irradiatePlauerId;
u8 parasiteFlags;/*
Each bit corrisponds to the player who has parasited this unit*/
u8 cycleCounter;/*
Runs updates 2 times per sec(about)*/
u8 isBlind;
u8 maelstromCounter;
UNK unknown20;
u8 unknownUnreferenced; //?!
u8 acidSporeCount;
u8 acidSporeTime[9];
u16 offsetIndex3by3;
UNK unknown21[6];
u16 airStrength;
u16 groundStrength;
UNK unknown22[16];
u32 tableIdUnknown[4]; //?
u8 repulse1Unknown; //?
u8 repulse2Unknown; //?
u8 driftPosX;
u8 driftPosY;
UNK unknown23;
};
struct WEAPON {
WEAPON* previousWeapon;
WEAPON* nextWeapon;
UNK unknown1[4];
SPRITE* sprite;
u16 targetGroundX;
u16 targetGroundY;
UNIT* targetUnit;
u8 weaponId;
UNK unknown2[2];
u8 bounceCount;
UNIT* attackingUnit;
};
typedef struct REQ_FUNC REQ_FUNC;
typedef struct ACT_FUNC ACT_FUNC;
struct BUTTON {
short position;
short icon;
REQ_FUNC* requirementFunction;
ACT_FUNC* actionFunction;
short requirementVariable;
short actionVariable;
short requirementString;
};
struct BUTTON_SET {
long buttonsInSet;
BUTTON* firstButton;
long connectedUnit;
};
#pragma pack()
The problems with the code:
unit->unitID == 35 is never registered as true, even when there are larva on the map (which marva are unit ID #35). Now, even when I take out the if statement, and just put:
unit->mainOrderId = 0;
It still crashes, even though this should just cause all larva to die on the map. I suspect that I didn't set up the struct right or reference it correctly.
And another question, the health of a of a unit is said to be at 0x08 and is the size of u32. However, I find that the health of a unit is at 0x09 and is the size of an int -- how to I make this change to the struct?