Staredit Network > Forums > Modding Assistance > Topic: More help on plugin code
More help on plugin code
Apr 2 2009, 5:13 am
By: A_of-s_t  

Apr 2 2009, 5:13 am A_of-s_t Post #1

aka idmontie

Okay, I'll simply state what code I'm using first:

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;
}


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()



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?



Personal GitHub
Starcraft GitHub Organization - Feel free to request member status!
TwitchTV

Apr 2 2009, 4:58 pm Fyrinite Post #2



1. I don't know if I like how you're getting the address of the units in there. Although the array math is easier, is it doing what it's supposed to? I'd check that.

2. Double check the struct to be sure it's right for the version you're using. The UnitID is at +0x64 in memory from the beginning of the struct.

3. Health and shields have a fractional value that is stored internally. You know how stuff like wireframe glows work? Those happen when the total of the displayed + fraction is more than the total from the .dat file. If you want to deal with the upper 3 bytes, use shifts to get what you need either when storing or reading.



None.

Apr 2 2009, 5:05 pm A_of-s_t Post #3

aka idmontie

1. I've used similar loops before and they work fine, th eonly change I'm making is trying to use structs instead od long lines of dereference code.

2. I'm using the right version, the struct comes from Hienermann.

3. K, thanks :D .

EDIT: It's been brought to my attention that the struct is not 336 bytes long, it appears to be 354 bytes long. Something is obviously wrong in it >.>

Post has been edited 1 time(s), last time on Apr 2 2009, 5:11 pm by A_of-s_t.



Personal GitHub
Starcraft GitHub Organization - Feel free to request member status!
TwitchTV

Apr 2 2009, 5:10 pm Fyrinite Post #4



mkay, my only suggestion is to try to change from array code to pointer code. i know, not easy, but here's what it would look like(i think):

Code
unit = UnitTable;
for(int i = 0; i < 1700; i++, unit++)
{
    if (unit->unitId == 35)
    {
         //stuff
    }
}




None.

Apr 2 2009, 5:14 pm A_of-s_t Post #5

aka idmontie

I'm going to try rewritting the stuct first, if that doesn't work, I'll try your method.



Personal GitHub
Starcraft GitHub Organization - Feel free to request member status!
TwitchTV

Apr 2 2009, 10:41 pm poiuy_qwert Post #6

PyMS and ProTRG developer

I don't know which struct you are talking about, especially since you said the struct came from Heinermann when all the structs I see are from me. Since you are talking about it being 336 bytes, im assuming you are talking about the UNIT struct. Yes it is too large for some reason (I've been to lazy to find the problem), but I know for a fact that all the values you are using are correctly placed in the struct. I know that most if not all the values are correctly placed up until parasiteFlags, which is almost at the end. The only problem I've had with this UNIT node is that you can't use it like an array since its size is wrong. This is how you should use it:
Code
const u32 unit_array = 0x0059CC90; // Or whatever the offset for your patch is
UNIT *unit = NULL;
for (u16 id = 0; id < 1700; id++) {
    unit = (UNIT*)(unit_array + 0x150 * id);
}

You are also using an old version I sent you which is missing a few changes. You can find my most up to date BW.h in the LocUnlock source download I posted at BWAI.




Apr 10 2009, 3:19 pm A_of-s_t Post #7

aka idmontie

For reading health, how do I do it? I know I need to bit shift, but how does it look (I'm a visual learner)? Does it looks simething like this:

unit->healthPoints >> 1 = 20;
?



Personal GitHub
Starcraft GitHub Organization - Feel free to request member status!
TwitchTV

Apr 10 2009, 3:29 pm Fyrinite Post #8



when reading - to get rid of the internal counter byte, shift it right by 8.

when writing, shift the value you are putting in there by 8 to the left.

so, like this

to read -> int HP = unit->healthPoints >> 8;
to write -> unit->healthPoints = HP << 8;



None.

Apr 10 2009, 3:33 pm A_of-s_t Post #9

aka idmontie

Thank you DoA. :D



Personal GitHub
Starcraft GitHub Organization - Feel free to request member status!
TwitchTV

Apr 10 2009, 8:37 pm poiuy_qwert Post #10

PyMS and ProTRG developer

If you had got my newer BW.h like I told you you would have some helpfull comments like how to do that :P




Apr 10 2009, 11:51 pm A_of-s_t Post #11

aka idmontie

NO U :P I have it, I don't really want to read through all the comments though >.>



Personal GitHub
Starcraft GitHub Organization - Feel free to request member status!
TwitchTV

Options
  Back to forum
Please log in to reply to this topic or to report it.
Members in this topic: None.
[02:26 pm]
UndeadStar -- Vrael, since the ad messages get removed, you look like a total madman for someone that come late
[2024-5-02. : 1:19 pm]
Vrael -- IM GONNA MANUFACTURE SOME SPORTBALL EQUIPMENT WHERE THE SUN DONT SHINE BOY
[2024-5-02. : 1:35 am]
Ultraviolet -- Vrael
Vrael shouted: NEED SOME SPORTBALL> WE GOT YOUR SPORTBALL EQUIPMENT MANUFACTURING
Gonna put deez sportballs in your mouth
[2024-5-01. : 1:24 pm]
Vrael -- NEED SOME SPORTBALL> WE GOT YOUR SPORTBALL EQUIPMENT MANUFACTURING
[2024-4-30. : 5:08 pm]
Oh_Man -- https://youtu.be/lGxUOgfmUCQ
[2024-4-30. : 7:43 am]
NudeRaider -- Vrael
Vrael shouted: if you're gonna link that shit at least link some quality shit: https://www.youtube.com/watch?v=uUV3KvnvT-w
Yeah I'm not a big fan of Westernhagen either, Fanta vier much better! But they didn't drop the lyrics that fit the situation. Farty: Ich bin wieder hier; nobody: in meinem Revier; Me: war nie wirklich weg
[2024-4-29. : 6:36 pm]
RIVE -- Nah, I'm still on Orange Box.
[2024-4-29. : 4:36 pm]
Oh_Man -- anyone play Outside the Box yet? it was a fun time
[2024-4-29. : 12:52 pm]
Vrael -- if you're gonna link that shit at least link some quality shit: https://www.youtube.com/watch?v=uUV3KvnvT-w
[2024-4-29. : 11:17 am]
Zycorax -- :wob:
Please log in to shout.


Members Online: Roy, lil-Inferno