Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// This is where the magic happens; program your plug-in's core behavior here.
- #include "game_hooks.h"
- #include <graphics/graphics.h>
- #include <SCBW/api.h>
- #include <SCBW/ExtendSightLimit.h>
- #include "psi_field.h"
- #include <cstdio>
- namespace hooks {
- const u32 Func_GetAllUnitsInBounds = 0x0042FF80;
- CUnit** getAllUnitsInBounds(Box16* coords) {
- static CUnit** units_in_bounds;
- __asm {
- PUSHAD
- MOV EAX, coords
- CALL Func_GetAllUnitsInBounds
- MOV units_in_bounds, EAX
- POPAD
- }
- return units_in_bounds;
- };
- u32 alexeiproperties;
- bool detector_upgrade_unresearched = false;
- u8 oldArmorType;
- u8 oldArmorAmount;
- const u32 Func_ReplaceUnitWithType = 0x0049FED0;
- void replaceUnitWithType(CUnit* unit, u16 newUnitId) {
- u32 newUnitId_ = newUnitId;
- __asm {
- PUSHAD
- PUSH newUnitId_
- MOV EAX, unit
- CALL Func_ReplaceUnitWithType
- POPAD
- }
- };
- ;
- void resetTaunt(CUnit* unit) {
- CExtendedUnitLayout* extendedStatus = unit->getExtendedUnitStatus();
- if(extendedStatus) {
- extendedStatus->tauntTimer = 0;
- extendedStatus->tauntTarget = NULL;
- unit->pAI = extendedStatus->oldAIBehavior;
- extendedStatus->oldAIBehavior = NULL;
- unit->prepareForNextOrder_Wrap();
- }
- }
- void doTauntEffect(CUnit* unit) {
- static u32* const unknown_value_6BEE64 = (u32*) 0x006BEE64;
- static u32* const unknown_array_size_6BEE6C = (u32*) 0x006BEE6C; //array with 1st elem being size of array
- static u16* const maxBoxRightValue = (u16*) 0x00628450;
- static u16* const maxBoxBottomValue = (u16*) 0x006284B4;
- Box16 area_of_effect;
- CUnit** unitsInAreaOfEffect;
- CUnit* current_unit;
- int x = unit->getX();
- int y = unit->getY();
- area_of_effect.left = (u16)x - weapons_dat::MaxRange[WeaponId::GaussRifle2_Unused];
- area_of_effect.right = (u16)x + weapons_dat::MaxRange[WeaponId::GaussRifle2_Unused];
- area_of_effect.top = (u16)y - weapons_dat::MaxRange[WeaponId::GaussRifle2_Unused];
- area_of_effect.bottom = (u16)y + weapons_dat::MaxRange[WeaponId::GaussRifle2_Unused];
- if(area_of_effect.left < 0)
- area_of_effect.left = 0;
- else
- if(area_of_effect.right > *maxBoxRightValue)
- area_of_effect.right = *maxBoxRightValue;
- if(area_of_effect.top < 0)
- area_of_effect.top = 0;
- else
- if(area_of_effect.bottom > *maxBoxBottomValue)
- area_of_effect.bottom = *maxBoxBottomValue;
- unitsInAreaOfEffect = getAllUnitsInBounds(&area_of_effect);
- current_unit = *unitsInAreaOfEffect;
- while(current_unit != NULL) {
- if(current_unit->isTargetEnemy(unit) && current_unit != unit) {
- bool shouldBeTaunted = true;
- if(!(current_unit->isTargetEnemy(unit)))
- shouldBeTaunted = false;
- if(shouldBeTaunted) {
- CExtendedUnitLayout* extendedStatus = current_unit->getExtendedUnitStatus();
- if(extendedStatus) {
- extendedStatus->tauntTimer = 48;
- extendedStatus->tauntTarget = unit;
- extendedStatus->oldAIBehavior = current_unit->pAI;
- current_unit->pAI = NULL;
- }
- }
- //current_unit->order(OrderId::Die, current_unit->getX(), current_unit->getY(), current_unit, current_unit->id, true);
- }
- unitsInAreaOfEffect++; //go on next unit of the list (or null)
- current_unit = *unitsInAreaOfEffect;
- }
- //code probably related to the use of getAllUnitsInBounds
- *unknown_value_6BEE64 = unknown_array_size_6BEE6C[unknown_array_size_6BEE6C[0]];
- unknown_array_size_6BEE6C[0] = unknown_array_size_6BEE6C[0] - 1;
- }
- bool resetExtendedStatus = false;
- /// This hook is called every frame; most of your plugin's logic goes here.
- bool nextFrame() {
- if (!scbw::isGamePaused()) { //If the game is not paused
- scbw::setInGameLoopState(true); //Needed for scbw::random() to work
- graphics::resetAllGraphics();
- hooks::updatePsiFieldProviders();
- //This block is executed once every game.
- if (*elapsedTimeFrames == 0) {
- //Write your code here
- oldArmorType = units_dat::ArmorUpgrade[UnitId::fenix_zealot];
- oldArmorAmount = units_dat::ArmorAmount[UnitId::fenix_zealot];
- alexeiproperties = units_dat::BaseProperty[UnitId::Hero_AlexeiStukov]; /// Stores default flags for Alexei Stukov, used to revert data back between maps/saves
- bool detector_upgrade_unresearched = true; /// Boolean variable: set to false when researched; set to true otherwise
- }
- //Loop through all visible units in the game.
- for (CUnit *unit = *firstVisibleUnit; unit; unit = unit->link.next) {
- //Write your code here
- if( !(unit->getExtendedUnitStatus()) /*&& !unit->doNotCreateExtendedStatus*/) {
- CExtendedUnitLayout* extended = (CExtendedUnitLayout*)calloc(1, sizeof(CExtendedUnitLayout));
- unit->storeExtendedUnitStatus(extended);
- }
- if(unit->id == UnitId::fenix_zealot && unit->mainOrderId == OrderId::CarrierStop) {
- if(unit->energy < techdata_dat::EnergyCost[TechId::UnusedTech43] * 256) {
- scbw::showErrorMessageWithSfx(unit->playerId, 864, 158);
- }
- else {
- doTauntEffect(unit);
- unit->energy = unit->energy - (techdata_dat::EnergyCost[TechId::UnusedTech43] * 256);
- }
- }
- CExtendedUnitLayout* extendedStatus = unit->getExtendedUnitStatus();
- if(extendedStatus) {
- if(unit->id == UnitId::fenix_zealot && unit->mainOrderId == OrderId::ReaverStop) {
- if(unit->energy < techdata_dat::EnergyCost[TechId::UnusedTech42] * 256) {
- scbw::showErrorMessageWithSfx(unit->playerId, 864, 158);
- }
- else {
- if(units_dat::ArmorUpgrade[UnitId::fenix_zealot] == oldArmorType) {
- int armorAmount = scbw::getUpgradeLevel(unit->playerId, extendedStatus->oldArmorType) + extendedStatus->oldArmorAmount + 5;
- unit->energy = unit->energy - (techdata_dat::EnergyCost[TechId::UnusedTech42] * 256);
- units_dat::ArmorUpgrade[UnitId::fenix_zealot] = UpgradeId::UnusedUpgrade57;
- units_dat::ArmorAmount[UnitId::fenix_zealot] = armorAmount;
- s32 shields = unit->shields;
- u16 energy = unit->energy;
- replaceUnitWithType(unit, unit->id);
- unit->shields = shields;
- unit->energy = energy;
- }
- extendedStatus->armorBuffTimer += techdata_dat::TimeCost[TechId::UnusedTech42];
- }
- }
- if(unit->id == UnitId::fenix_zealot && units_dat::ArmorUpgrade[UnitId::fenix_zealot] != oldArmorType && extendedStatus->armorBuffTimer == 0) {
- units_dat::ArmorUpgrade[UnitId::fenix_zealot] = oldArmorType;
- units_dat::ArmorAmount[UnitId::fenix_zealot] = oldArmorAmount;
- s32 shields = unit->shields;
- replaceUnitWithType(unit, unit->id);
- unit->shields = shields;
- }
- if( (!(extendedStatus->tauntTarget) || extendedStatus->tauntTarget->hitPoints <= 0 || extendedStatus->tauntTarget->mainOrderId == OrderId::Die) && extendedStatus->tauntTimer > 0) {
- //resetTaunt(unit);
- scbw::printText("YOU SHOULD NOT BE SEEING THIS.");
- }
- if(extendedStatus->tauntTimer == 0 && extendedStatus->tauntTarget) {
- //resetTaunt(unit);
- scbw::printText("YOU SHOULD NOT BE SEEING THIS EITHER.");
- }
- if(extendedStatus->tauntTimer > 0) {
- if(unit->mainOrderId != OrderId::AttackUnit || unit->orderTarget.unit != extendedStatus->tauntTarget) {
- unit->orderTo(OrderId::AttackUnit, extendedStatus->tauntTarget);
- }
- }
- /// Alekei Stukov detector upgrade
- if(unit->id == UnitId::Hero_AlexeiStukov && /// Unit ID 100
- scbw::getUpgradeLevel(unit->playerId, 57) && /// Upgrade ID 57
- detector_upgrade_unresearched) /// Reference to boolean (makes it local? what does this do?)
- {
- units_dat::BaseProperty[UnitId::Hero_AlexeiStukov] |= UnitProperty::Detector; /// Applies Detector flag to all future Alexei Stukov units
- detector_upgrade_unresearched = false; /// Sets boolean to false
- replaceUnitWithType(unit, unit->id); /// Replaces all existing Alexei Stukov units with new instances, to make the upgrade take into effect
- scbw::printText("STUKOV DETECTION ON"); /// Debug text
- }
- }
- }
- scbw::setInGameLoopState(false);
- }
- return true;
- }
- bool gameOn() {
- resetExtendedStatus = true;
- return true;
- }
- bool gameEnd() {
- units_dat::ArmorUpgrade[UnitId::fenix_zealot] = oldArmorType;
- units_dat::ArmorAmount[UnitId::fenix_zealot] = oldArmorAmount;
- units_dat::BaseProperty[UnitId::Hero_AlexeiStukov] = alexeiproperties;
- scbw::setGameLoadState(true);
- return true;
- }
- } //hooks
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement