boomerangaide / gptp-for-vs2008 Goto Github PK
View Code? Open in Web Editor NEW[Old version] The General Plugin Template Project of Starcraft adapted to Visual Studio 2008
Home Page: https://github.com/BoomerangAide/GPTP
[Old version] The General Plugin Template Project of Starcraft adapted to Visual Studio 2008
Home Page: https://github.com/BoomerangAide/GPTP
Is it possible to add a CGame struct to encapsulate all the game data?
#include "structures.h" // PLAYER_COUNT, PLAYABLE_PLAYER_COUNT
#pragma pack(1)
/// @name Structure tables
//////////////////////////////////////////////////////////////// @{
SCBW_DATA(CGame*, game, 0x0057F0F0);
//////////////////////////////////////////////////////////////// @}
struct Resources {
int minerals[PLAYER_COUNT];
int gas[PLAYER_COUNT];
int cumulativeGas[PLAYER_COUNT];
int cumulativeMinerals[PLAYER_COUNT];
};
struct Location { // (0x14)
/*0x00*/ Rect32 area;
/*0x12*/ word flags;
}
//BW's game struct (Incomplete/May contain mistakes) (0x17700)
struct CGame {
/*0x00000*/ Resources *resources; // (0057F120)
/*0x000c0*/ u32 *starting_local_player_id; // (0057F1B0) (Command 40 etc)
/*0x000c4*/ byte starting_player_types[PLAYER_COUNT]; // (0057F1B4)
/*0x000d0*/ byte starting_races[PLAYER_COUNT]; // (0057F1C0)
// These two are mainly for saves and some team game stuff, they are before starting locations are randomized
// Lobby settings?
/*0x000dc*/ byte team_game_main_player[0x4]; // (0057F1CC)
/*0x000e0*/ word screen_pos_x_tiles; // (0057F1D0)
/*0x000e2*/ word screen_pos_y_tiles; // (0057F1D2)
/*0x000e4*/ word map_width_tiles; // (0057F1D4)
/*0x000e6*/ word map_height_tiles; // (0057F1D6)
/*0x000ec*/ word tileset; // (0057F1DC)
/*0x000f1*/ byte active_net_players; // (0057F1E1)
/*0x000f2*/ byte player_race; // (0057F1E2) Ui, etc.
/*0x000f3*/ byte custom_singleplayer; // (0057F1E3) 0x0 in campaign, 0x1 in other singleplayer, undefined in multiplayer.
/*0x000fc*/ dword visions[PLAYER_COUNT]; // (0057F1EC, first dword tells who see pl1 units etc)
/*0x0012c*/ dword player_randomization[PLAYABLE_PLAYER_COUNT]; // (0057F21C) Player id to original id, for ai force names and entry in player color .pcx
/*0x0014c*/ dword frame_count; // (0057F23C)
/*0x00150*/ dword saved_elapsed_seconds; // (0057F240) The one used with GetGameDurationSeconds
/*0x00154*/ word campaign_mission; // (0057F244)
/*0x00156*/ char next_scenario[0x20]; // (0057F246)
/*0x00176*/ byte selected_singleplayer_race; // (0057F266)
/*0x00177*/ byte selected_singleplayer_computer_races[PLAYABLE_PLAYER_COUNT]; // (0057F267) Last entry is never used?
/*0x0017f*/ byte padding; // (0057F26F)
/*0x00180*/ word saved_screen_positions[0x3 * 0x2]; // (0057F270) F1 to F3
/*0x0018c*/ byte unit_availability[0xe4 * 0x8]; // (0057F27C)
/*0x00c4c*/ char map_path[0x104]; // (0057FD3C)
/*0x00d50*/ char map_title[0x20]; // (0057FE40)
/*0x00d70*/ dword selection_hotkeys[0xc * 0x12 * 0x8]; // unit index, not pointer, 0xa ... 0x11 are recent selection groups (0057FE60, 00580040 first recent selection)
/*0x010a0*/ Unit *unk_selections[0x8 * 0xc * 0x4?]; // (00580190)
/*0x02c70*/ byte unk_team;; // (00581D60) 9 if tvb, 8 otherwise?
/*0x02c7a*/ byte bool self_alliance_colors[PLAYER_COUNT]; // (00581D6A)
/*0x02c80*/
/*0x02c86*/ byte player_color_palette[0x8 * 0xc]; // (00581D76)
/*0x02ce6*/ byte player_minimap_color[PLAYER_COUNT]; // (00581DD6)
/*0x02cf2*/ byte padding[0x2]
// Score: (0x600)
/*0x02cf4*/ dword unit_count_score[PLAYER_COUNT]; // (00581DE4)
/*0x02d54*/ dword building_count[PLAYER_COUNT] (Vissii current); // (00581E44)
/*0x02d84*/ dword men_deaths[PLAYER_COUNT]; // (00581E74)
/*0x02db4*/ dword men_kills[PLAYER_COUNT]; // (00581EA4)
/*0x02de4*/ dword men_score[PLAYER_COUNT]; // (00581ED4)
/*0x02e14*/ dword men_killed_score[PLAYER_COUNT]; // (00581F04)
/*0x02ed4*/ dword building_deaths[PLAYER_COUNT]; // (00581FC4)
/*0x02f04*/ dword building_kills[PLAYER_COUNT]; // (00581FF4)
/*0x02f64*/ dword buildings_killed_score[PLAYER_COUNT]; // (00582054)
/*0x02f94*/ dword factories_built_score[PLAYER_COUNT]; // (00582084) (Unit producing building)
/*0x02ff4*/ dword factory_deaths[PLAYER_COUNT]; // (005820E4)
/*0x03054*/ dword zerg_supply_available[PLAYER_COUNT]; // (00582144) (Not free supply, includes used)
/*0x03084*/ dword zerg_supply_used[PLAYER_COUNT]; // (00582174)
/*0x030b4*/ dword zerg_supply_max[PLAYER_COUNT]; // (005821A4) (So 400 usually)
/*0x030e4*/ dword terran_supply_available[PLAYER_COUNT]; // (005821D4)
/*0x03114*/ dword terran_supply_used[PLAYER_COUNT]; // (00582204)
/*0x03144*/ dword terran_supply_max[PLAYER_COUNT]; // (00582234)
/*0x03174*/ dword protoss_supply_available[PLAYER_COUNT]; // (00582264)
/*0x031a4*/ dword protoss_supply_used[PLAYER_COUNT]; // (00582294)
/*0x031d4*/ dword protoss_supply_max[PLAYER_COUNT]; // (005822C4)
//UnitCounts: (0xab00)
/*0x03234*/ dword all_units_count[0xe4 * 0xc]; // (00582324)
// 00584064 = pylon count
/*0x05cf4*/ dword completed_units_count[0xe4 * 0xc]; // (00584DE4, 005873F0 is pl12 dark swarm)
/*0x070d0*/ dword bool unk; // (005861C0) unused?
/*0x07e20*/ dword unk; // (00586F10)
/*0x07e50*/ dword unk; // (00586F40)
/*0x07e80*/ dword unk; // (00586F70)
/*0x087b4*/ dword unit_kills[0xc * 0xe4]; // (005878A4)
/*0x0b274*/ dword unit_deaths[0xc * 0xe4]; // (0058A364)
/*0x0dd34*/ byte tech_availability_sc[0x18 * 0xc];
/*0x0de54*/ byte tech_level_sc[0x18 * 0xc]; // (0058CF44)
/*0x0df98*/ byte upgrade_limit_sc[0x2e * 0xc]; // (0058D088)
/*0x0e1c0*/ byte upgrade_level_sc[0x2e * 0xc]; // (0058D2B0)
/*0x0e4c0*/ byte player_forces?[PLAYABLE_PLAYER_COUNT]; // (005993D4)
/*0x0e4c8*/ byte force_flags?[0x4]; // (0058D5B8)
/*0x0e4cc*/ char force_names[0x1e * 0x4]; // (0058D5BC)
/*0x0e544*/ byte alliances[PLAYABLE_PLAYER_COUNT * PLAYABLE_PLAYER_COUNT]; // (0058D634) 0 = enemy, 1 = self, 2 = ally
/*0x0e5d4*/ dword player_objectives_string_id[PLAYER_COUNT]; // (0058D6C4)
/*0x0e604*/ dword countdown_timer; // (0058D6F4)
/*0x0e608*/ dword elapsed_seconds; // (0058D6F8) (16 frames, is not dependent on game speed)
/*0x0e610*/ byte player_victory_status[PLAYABLE_PLAYER_COUNT]; // (0058D700) 0x0 = Playing, 0x1 = Draw?, 0x2 = Lose, 0x3 = Win?
/*0x0e618*/ dword bool computers_in_leaderboard; // (0058D708)
/*0x0e61c*/ byte leaderboard_type; // (0058D70C) ???
/*0x0e61e*/ word leaderboard_unit_id; // (0058D70E)
/*0x0e620*/ dword leaderboard_unk; // (0058D710)
/*0x0e624*/ dword leaderboard_unk; // (0058D714)
/*0x0e628*/ byte pauses_remaining[PLAYABLE_PLAYER_COUNT]; // (0058D718)
/*0x0e630*/ word start_position[0x8 * 0x2]; // (0058D720)
/*0x0e650*/ Location sc_locations[0x40]; // (0058D740) (Used only when loading old saves)
/*0x0eb70*/ Location locations[0xff]; // (0058DC60)
/*0x0ff60*/ byte tech_availability_bw[0x14 * 0xc];
/*0x10050*/ byte tech_level_bw[0x14 * 0xc]; // (0058F140) (Usually as 0058F128)
/*0x10188*/ byte upgrade_limit_bw[0xf * 0xc]; // (0058F278) (Usually 0058F24A)
/*0x1023c*/ byte upgrade_level_bw[0xf * 0xc]; // (0058F32C) (Bw usually uses 0058F2FE)
/*0x10350*/ byte bool is_bw; // (0058F440)
};
C_ASSERT(sizeof(CGame) == 96000);
#pragma pack()
[22/08/2015]:
Hi!.
Maybe you could work on the screen size.
Right now, SC engine only renders a 640px400p image:
http://www.moddb.com/members/kysxd/images/weirdCould you find a way to make the game render a fully 640x480??
Edit: Is there a way to resize the game layer from 640X400 to 640x480 (and also, resize the dialog layer to avoid conflicts)??
Also, could you make more than 1 building selectable?
(And maybe after that, look for +12 units selection).Greetings.
[18/09/2015]:
Hi!. Some questions/request.
There are some hooks for the AI on spells.
Any chance to make one for the harvest behavior (AI)?Where can i modify the larva amount for buildings?
I want to make the Hatchery, Lair and Hive to spawn 3,4 and 5 larva.I know there is an example of how to copy a button set.
Could you make and example of how to change the buttonset of a unit for a custom one?Where is controlled the orderQueueTimer ?
Also, is possible to re-write the pathfinding?
Thank you.
This is the old version.
The new version is at https://github.com/BoomerangAide/GPTP
Besides the updates, the main difference is the files handling by project files.
If it wasn't for this, project could be identical, the update isn't for advanced language features or anything, and updates from the new project could be brought to this one...it's just that you have to manually include the files in the project, and watch out for things that may have been deleted, renamed, moved, updated...
The overlay for defensive matrix persists until the unit dies and does not fall off after the effect ends.
Here's some research about larva_creep_spawn hook:
Some research about function_00414680().
It seems that this function tries to spread creep on nearby tiles, and returns:
0 - if creep spread is completed (all surronding tiles are covered by creep)
1 - if the unit can continue with creep spread
2 - if the creep spread is blocked (has a building, is unpassable terrain)
Still not sure why the function uses UnitId.
Also, function doesn't create creep unless UnitId is Hatchery, Lair, Hive, Creep colony, Sunken colony or Spore colony. Maybe is related to "AI actions" in units.dat?
Values higher than UnitId:None causes to create creep only in a vertical way (after reaching the maximun default radial range).
There's a mistake in "updateNewUnitVision" function call. It uses unit pointer, but it should use unit id instead.
Using hook in its current shape leads to bugs - creep doesn't properly spawn (it is very noticeable if building was placed near the map's edge), sometimes preplaced structures (spire in my example) crash once their morph is finished.
Loading a multiplayer lobby crashes.
Disabling jmpPatch(InitializeDialogWrapper, 0x00419D20, 1);
seems to fix this behaviour.
When CMDRECV_CancelResearch is hooked, the game crashes when you cancel research. I am using the unmodified 4.014 hook.
It seems that the loop in the CreatInitialMeleeUnits() function loops the value at
raceIdOffset
from
playerTable[8].race
to
playerTable[0].race
Also, the unk1 value seems to be part of the GoT struct:
005967F8 = GameData game_data
GameData: (0x8d)
0x0 dword save_time?
0x4 char game_name[?]
GameStatstringData:
0x1c dword save_timestamp (00596814)
0x20 word map_width_tiles
0x22 word map_height_tiles
0x24 byte active_human_players (0059681C)
0x25 byte human_player_slots (0059681D)
0x26 byte game_speed
0x27 byte approval_status
0x28 byte game_type_id (Sama kuin st435x0)
0x29 byte game_type_unk
0x2a word game_type_param
0x2c dword cdkey_hash
0x30 word tileset
0x32 byte is_replay
0x33 byte active_computer_players (0059682B)
0x34 byte host_name[0x19]
0x4d char map_title[0x20?] (00596845)
0x6d Got got (00596865)
Edit: Here's the Got struct, finished after some research.
#pragma pack(1)
struct Got //(0x20)
{
/*0x00*/ u8 template_id; // See GameType::Enum
/*0x01*/ u8 variation_id; // An ID used to define the order of the variation when its listed in SC
/*0x02*/ u32 variation_value; // The value defining the variation amount (e.g. mineral count for greed or amount of teams for Team Vs)
/*0x06*/ u16 unk_0; // unused? possibly padding
/*0x08*/ u8 victory_conditions; // 0x0 = map default, 0x1 = melee, 0x2 = high score, 0x3 = resources, 0x4 = CTF, 0x5 = Sudden Death, 0x6 = Slaughter, 0x7 = One on One (0059686D)
/*0x09*/ u8 resource_type; // 0x0 = map default, 0x1 = fixed value, 0x2 = low, 0x3 = medium, 0x4 = high, 0x5 = income
/*0x0a*/ u8 unit_stats; // 0x0 = map default, 0x0 = Standar
/*0x0b*/ u8 fogOfWar_mode; // 0x0 = Off, 0x1 = No fog, 0x2 = On
/*0x0c*/ u8 starting_units; // 0x0 = map default, 0x1 = workers, 0x2 = Workers + townhall (00596871)
/*0x0d*/ u8 start_positions; // 0x0 = random, 0x1 = fixed (00596872)
/*0x0e*/ u8 player_types; // 0x0 = no single, no comp, 0x1 = no single, comp allow, 0x2 = single, no comp, 0x3 = single, comp allow
/*0x0f*/ u8 alliances; // 0x0 = not allowed, 0x1 = allowed
/*0x10*/ u8 team_mode; // 0x0 = off, 0x1 = 2 teams, 0x2 = 3 teams, 0x3 = 4 teams (00596875) (Team amount)
/*0x11*/ u8 cheat_codes; // 0x0 = off, ox1 = on
/*0x12*/ u8 tournament_mode; // 0x0 = off, 0x1 = on (00596877)
/*0x13*/ u8 unk_1[0xD]; // unused?
};
C_ASSERT(sizeof(Got) == 0x20);
#pragma pack()
Got *game_data_got = (Got*)(0x00596865);
Also:
0059BDA8 = byte bool user_select_slots[0x8] (Race selection, guess it is Player entry)
Maybe it could help to clean the code a little.
If you have the Medic selected in a group of other units and order the group to attack a target, the game will crash when the Medic gets in range of the target. This only occurs if MedicOrdersHooks is enabled.
I wanted to make cheat hooks, possibly allowing to edit cheats effects or even create new cheat codes, but I gave up.Yet I will report here what I found during my research:
CommandLineCheatCompare @ 004B23E0 is where it start.This function call verifyCheatCode and _radioFreeZergCheat (and maybe campaignTypeCheatStrings count too).
verifyCheatCode @ 004B1B50 detect the actual codes with XOR commands using a value corresponding to CheatFlags.Most codes are detected there and the function return 1 (true) after finding a code.
_radioFreeZergCheat @ 004B2350 for some reason has a XOR command corresponding to CheatFlags::Noglues (never really knew what this code was doing, and this make it even weirder), and seems to play directly the music if some weird conditions are met.
cheatActivation @ 004B1FA0 is what apply the effects of several cheat (mostly the resources ones), though for some reason it use 2 registers to read the current cheat value, or so it looked to me.
If anybody ever try to hook the cheat mechanisms, I wish him or her good luck, because I failed doing so.
This hook connect to the Tank Mode and Siege Mode orders of the Siege Tank (and Duke in a Tank).
The original code is heavily hardcoded for the units it's made for, but with this code, you may be able to get rid of all the annoying stuff (hardcoded id identification, hardcoded use of subunits, hardcoded assumption the unit in siege mode act like a turret, and so on...)
My test run (the one after all those that crashed :p) showed Edmund Duke properly going in and out siege mode with this code, so I think there should be no problem.
In the last version (update 3) there is a bug:
Can't use the sub - button sets (like the SCV's basic buildings), because after a few seconds the game changes the displayed buttons to the first ones (the basic ones).
Edit:
It seems that the bug is caused by the buttonset hook. No problem when commenting them on initialize.cpp
Last Edit: June 29 of 2018.
Previous Edit: May 03 of 2016.
Here I'm leaving a note to myself about known bugs that I should look into in the near future:
-The way it work, the "extend sight limit" feature can cause memory leaks when loading several maps (as it recreate something on every load), should find a fix for it, and check for possible others leaks (my testing way until now could not catch such things)
[EDIT: Tried to observe the phenomenon, and failed to see the leak in action. I guess I will have to go back to this later, because if I can't observe it, I can't find a generic fix for it.
[EDIT: Played the entire Brood War campaign with the feature on, didn't get much above 100MB consumption.May be a visual studio issue, project options issue, operating system issue, or even something map-specific.Can't fix trouble that don't happen when you try to get it.
-A recent development showed me that Starcraft may be more sensitive to types than I thought sometimes (some 4 bytes coordinate could be used either as 2 or 4 bytes by internal functions, but not doing the conversion beforehand would cause crashes), should run a check at least on my made hooks and make things stricter to be sure.
-Still about type, I encountered the case where in a helper, I would move a 16 bits value into AX like the original code, but it would crash, because in the original code EAX had been set to 0 or 1 before using AX, so the fix was to use MOVZX EAX, my_16bits_value.
This behavior is a serious concern.If mysterious unidentified crashes happen in the futures, maybe a security would be to always use the full 32 bits register in helpers to be sure nothing go wrong, but that's a lot of work, and maybe in some cases it could have the opposite effect?
-I seriously doubt the AI Folder content work as it should (because I'm certain some things don't, and the rest I don't know), but I haven't made it, and it rely on code mixed from several functions, so I can't go and fix it easily (may be easier to just rewrite from scratch instead of hanging to it).
-Overlords seems very aggressive on first BW Protoss mission when playing around with Zeratul, compared to behavior without GPTP.Must find out why one day, but that's something coming from the initial code of GPTP.
-In the Terran mission "the Emperor Flight" (the one with valkyries VS mutalisks), if you keep pausing, less mutalisks may join the fight against valkyries, then the tanks unloaded on the right of the base would get obliterated.
But it's not my fault after all, as what I'm describing is behavior on unmodded Starcraft (but that sure was confusing @_@)
GPTP/SCBW/scbwdata.h fix!
ButtonIcon isn't in orders_dat DatLoad structure.
Asm call for function 00488D50 is not correct. Should be "MOV ECX, unk1" instead of "MOV unk1, ECX".
Casting Optical Flare on a unit appears to crash the game.
Hi BoomerangAide,
First of all thanks a lot for your work updating GPTP, its really appreciated.
I have a problem using the new burrow tech hooks, basically the functions seems to never execute (or im missing something?)
I have called the hooks::injectBurrowTechHooks(); in the initialize.cpp, but when i burrow / unburrow units in the mod nothing change… (I tried print text at the begin of each function, setting units hp to 1, but nothing happens) Also tested with a clean mod and only that hook injected
And some minor mistakes
-In the recall_spell.cpp: the energy cost must be multiplied by 256 when checking if there is enough energy and when the energy cost is subtracted (lines 163 and 199)
-And in hallucination_spell.cpp: line 43 have counter == 0; where it should be counter = 0;
And finally, a request. It is possible to inject the code when the target position of the orders are given to units by the user? Specifically, I would like to change the target point assigned to units when a spell is issued to multiple units
Hi,
If there's a particular game feature you're interested in, you can leave a message here.
There are some things I would not be able to deal with, but for others, I may be able to get one or several hooks that would be enough to interact/interfere with the feature you're interested in.
Of course this may take time, but at least, there you can try asking.
The hook functions should be usable without trouble, unless I've overlooked a leftover bug.
The main issue remaining is this bunch of helpers functions that take lots of space.
Some are modified to fit the specific case of Infestation (incrementUnitScores), and while their general use can be understood to an extent, not knowing how they do it could be a problem.
It seems that the train unit hook causes the building to queue the unit without setting the build order.
It also seems to happen after training some units and creating a new building.
Disabling this hook fixes this problem (so far).
Having the Recharge Shields hook active will prevent the Shield Battery (and other units) from successfully using Recharge Shields.
There's no jmpPatch in injectStatsPanelDisplayHook().
I tried adding my own, but when I attempted to select a unit I got an invalid access when selecting a unit:
Instruction at 0x00456c88 referenced memory at 0x00000000
Not sure if that's because I screwed up the jmpPatch or if there's an error in stats_panel_display()
I recently realized that the current version of GPTP give an error message box if the mod try to launch StarEdit (because StarEdit is still version 1.0.0.2 when GPTP expect something that would be version 1.16.1.1).
If GPTP don't automatically break StarEdit, then I should make it so StarEdit version is recognized as valid.
And if it's always broken, just changing the message for this special case would do, but I don't think it's that bad normally.
So this issue is basically an addition to my todo list :p
My Internet was cut in the middle of an update.
The current files may not work.
I apologize about it.
I will fix things as soon as my Internet is back for my desktop pc.
Hi,
I will reopen this issue every time an update is in progress but may get temporarily interrupted, thus some required files or changes may be missing.
If you update at such a time, make sure you don't take files whose version is below the version of the Changelog (that should be the last thing I update).
Those files might be trouble since they can't be edited directly.
Will have to to through normal git again >_<
wpnspellhit.cpp, in ConsumeHit:
if((energyMax - attacker->energy) > 12800) //12800 is 50 energy ingame
attacker->energy = energyMax;
else
attacker->energy += 12800;
The conditions should be reversed.
Removing all units in a carrier's queue crashes.
This doesn't happen with Reaver.
Crash issue was solved, thanks to BoomerangAide, but I found another particularly troubling bug with infestation hook, while working with my AI scripts.
For some reason, AI somehow still treats infested structures as enemy units (if I understand correctly). As result of that, AI refuses to train Infested Terrans from infested structures. Pre-placed Infested Command Centers work just fine.
I'm not sure what is the source of problem, but I checked it both with infestation hook enabled and disabled, so I'm sure the problem is here.
When the Command Center (or any other infestable unit) is destroyed while Queen is infesting it, the Queen doesn't reappear and the game crashes.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.