Staredit Network > Forums > Modding Assistance > Topic: [help] defense matrix modfiy
[help] defense matrix modfiy
Aug 24 2019, 7:02 pm
By: Lagi  

Aug 24 2019, 7:02 pm Lagi Post #1



I want to modify Defense matrix as follow:


1. how to target only mechanical unit with this spell? (by default Matrix is not targeting f.ex building)
2. how to disable unit attack when Def Matrix timer > 0 ?
3. how to set 3 use of this spell (like with Spidermines) ?


my stuff in game hook so far (+ in weapon range i reduce attackk range to 1 - cannot be set to zero)
//Nano robots
if (unit->defensiveMatrixTimer >0) {

//unit->orderToIdle(); this will make unit unable to receive any orders

if(!(units_dat::BaseProperty[unit->id] & UnitProperty::Mechanical)) {
unit->reduceDefensiveMatrixHp(unit->defensiveMatrixHp); // this is zeroing timer if bio unit targeted, not elegant at all
}
if (unit->hitPoints > 0 &&
unit->hitPoints != units_dat::MaxHitPoints[unit->id]) {
unit->setHp(unit->hitPoints + 40);
}


}

//Nano robots




None.

Aug 29 2019, 3:55 pm Voyager7456 Post #2

Responsible for my own happiness? I can't even be responsible for my own breakfast

>1. how to target only mechanical unit with this spell? (by default Matrix is not targeting f.ex building)

Try this:
Change a weapon so it has the appropriate targeting flags, then in orders.dat set the "Targeting" field of the Defense Matrix to that weapon and check "Use weapon.dat targeting". Also change the condition in check_tech_target.cpp.

>2. how to disable unit attack when Def Matrix timer > 0 ?

My initial thought is to modify checkAttackableTarget() in attack_priority.cpp, always return false if the dmatrix timer is active. That should prevent units from auto-acquiring targets. Then in game_hooks.cpp, do a check to see if a unit has an active dmatrix timer and call unit->orderToIdle(). That should prevent manual orders to attack. You'll need to test this though, I haven't experimented with shutting down unit attacks.


>3. how to set 3 use of this spell (like with Spidermines) ?

There's a FireGraft condition "Has Spidermine & Is Researched". Use that and set the action variable to the appropriate tech.
Decrementing the spider mine count on cast is a bit trickier though, because Defense Matrix is one of the few spells where there isn't a hook for its behavior yet. We could do something hacky to detect Defense Matrix casts (like have it use a separate spellcast animation and signal a cast via sigorder) but it'd probably be nicer if someone took a look at writing a proper dmatrix hook...



all i am is a contrary canary
but i'm crazy for you
i watched you cradling a tissue box
sneezing and sniffling, you were still a fox


Modding Resources: The Necromodicon [WIP] | Mod Night
My Projects: SCFC | ARAI | Excision [WIP] | SCFC2 [BETA] | Robots vs. Humans | Leviathan Wakes [BETA]


Aug 31 2019, 3:02 pm Lagi Post #3



ad 1 .
solved tech target cpp

stringId = 877; //Unable to target structure.<0>
else
stringId = 0; //valid target
}
// nano robots igal
else
if(techId == TechId::DefensiveMatrix) {
if(units_dat::BaseProperty[target->id] & UnitProperty::Building)
stringId = 877; //Unable to target structure.<0>
else
if(units_dat::BaseProperty[target->id] & UnitProperty::Mechanical)
stringId = 0; //valid target

else
stringId = 881; //Must target mechanical units.<0>
}
// end nano robots igal

else
if( //techId == TechId::DefensiveMatrix ||
techId == TechId::Irradiate ||


ad2


if I comment purple part attack order, unit under def matrix is frozen.
with attack order the unit is acting normal

//Nano robots
if (unit->defensiveMatrixTimer>0) {
//{
if (unit->mainOrderId == OrderId::AttackMove || unit->mainOrderId == OrderId::AttackUnit){

//manageUnitStatusFlags(unit, UnitStatus::CanNotAttack, true);
unit->orderToIdle();
}
/*if(!(units_dat::BaseProperty[unit->id] & UnitProperty::Mechanical)) {
unit->reduceDefensiveMatrixHp(unit->defensiveMatrixHp);
}*/
if (unit->hitPoints > 0 &&
unit->hitPoints != units_dat::MaxHitPoints[unit->id]) {
unit->setHp(unit->hitPoints + 40);
}


}


attack priority

this dont work - not sure why not (inject is active in initialize). I drop gholiath on enemy workers, he aqure targets normally under def matrix.
// can't attack, if it is under Repair bots (def matrix) igal
if (unit->defensiveMatrixTimer >0)
return false;




ad.3

ok, so i would like to limit use of my ability to only 1. If unit use it, then lets remove the button. Is it doable?

it is, work like charm. Spell button disappear after 1, successful use.
if(unit->id == UnitId::TerranDropship &&unit->mainOrderId == OrderId::DefensiveMatrix) {
unit->currentButtonSet = UnitId::ProtossShuttle;
}

in firegraft i make new button set for dropship with Def Matrix.

Post has been edited 3 time(s), last time on Aug 31 2019, 8:17 pm by Lagi.



None.

Aug 31 2019, 4:26 pm Voyager7456 Post #4

Responsible for my own happiness? I can't even be responsible for my own breakfast

Quote from Voyager7456
it'd probably be nicer if someone took a look at writing a proper dmatrix hook...
Lo and behold, someone has done this thing and that person is me.

Hastily written, I can't guarantee that it's perfect.

Attachments:
defense_matrix.h
Hits: 2 Size: 0.17kb
defense_matrix.cpp
Hits: 2 Size: 3.58kb

Post has been edited 1 time(s), last time on Aug 31 2019, 4:39 pm by Voyager7456.



all i am is a contrary canary
but i'm crazy for you
i watched you cradling a tissue box
sneezing and sniffling, you were still a fox


Modding Resources: The Necromodicon [WIP] | Mod Night
My Projects: SCFC | ARAI | Excision [WIP] | SCFC2 [BETA] | Robots vs. Humans | Leviathan Wakes [BETA]


Aug 31 2019, 5:43 pm Lagi Post #5



if(target->defensiveMatrixTimer > 0 || target->status & UnitStatus::Burrowed) {

}
else {

hmm.. there is empty {} ?

==

Can I add limited number of def matrix use with this hook?



None.

Aug 31 2019, 5:58 pm Voyager7456 Post #6

Responsible for my own happiness? I can't even be responsible for my own breakfast

Quote from Lagi
hmm.. there is empty {} ?

Ah yeah... I had something there originally and then refactored it outside the condition once I understood the assembly a little better. :blush: Still logically correct although ugly stylistically.

Quote

Can I add limited number of def matrix use with this hook?

Yes - this is the missing component that you'll need. First you want to change the button condition to disable the button when you don't have spider mines, like I mentioned earlier. Then all you need to do is add "unit->vulture.spiderMineCount--;" in this function to decrease the spider mine count when the spell is cast.

Don't forget that unit->vulture is a union with unit->carrier, unit->interceptor, unit->beacon, unit->building and unit->worker, so if the unit you're giving defense matrix to is one of those things, you're going to want to use something else as your "spell counter".



all i am is a contrary canary
but i'm crazy for you
i watched you cradling a tissue box
sneezing and sniffling, you were still a fox


Modding Resources: The Necromodicon [WIP] | Mod Night
My Projects: SCFC | ARAI | Excision [WIP] | SCFC2 [BETA] | Robots vs. Humans | Leviathan Wakes [BETA]


Sep 8 2019, 4:34 pm Lagi Post #7



I cannot make dropship appear with extra icon or limited to 3 use of Def Matrix use.
I think the issue is that my dropship is not dispalying the Mines counter icon after research (she is able to spam def matrix on everything)

I add your 2 files into project.
i add inlcude .h and hook:: .cpp in initialize.cpp

when i build project, it appears compiler is processing : defense_matrix.cpp

i add in firegraft : has spidermines (def matrix); action (def matrix)
in dat requirment / use tech i add: has spidermines

i add in game_hooks:
if(unit->id == UnitId::TerranDropship)
unit->vulture.spiderMineCount = 3;

without it Dropship has disabled skill after production = looks like has 0 spider mines counter.


check purple below

//Injector source file for the Hallucination Spell Order hook module.
#include "defense_matrix.h"
#include <hook_tools.h>
#include <SCBW/api.h>



namespace {
bool ordersSpell_Sub_4926D0(CUnit* unit, u32 techId, u16* techEnergyCost, u32 sightRange,u32 error_message_index); //926D0
u8 calculateOverlaySize(CUnit* unit);
void function_00498D70(CSprite* sprite, u32 imageId, u32 unk1, u32 unk2, u32 unk3); //98D70
}

namespace hooks {
void orders_DefensiveMatrix(CUnit* unit) {
int sightRange = unit->getSightRange(true);
u16 techCost;

if(ordersSpell_Sub_4926D0(
unit,
TechId::DefensiveMatrix,
&techCost,
sightRange * 32,
880 //Invalid target
)) {
unit->spendUnitEnergy(techCost);
unit->vulture.spiderMineCount--;
CUnit* target = unit->orderTarget.unit;

if(target->defensiveMatrixTimer > 0 || target->status & UnitStatus::Burrowed) {

}
else {


============
edit:
game hook
i try this
if(unit->id == UnitId::TerranVulture)
unit->vulture.spiderMineCount = 4;


vulture dispaly 4 mines, and is not reducing its number, when placing mines

so the issue is with setting initial number of "mines" for dropship and adding icon to tooltips.

Post has been edited 3 time(s), last time on Sep 8 2019, 4:58 pm by Lagi.



None.

Sep 8 2019, 8:03 pm Voyager7456 Post #8

Responsible for my own happiness? I can't even be responsible for my own breakfast

Here's what I ended up doing.

Defense Matrix requirements:


Spider Mine requirements (used to get around something in StatSpidermineCount later, didn't feel like writing a hook for it):


stats_panel_display.cpp
if(
            activeUnit->id == UnitId::TerranVulture ||
            activeUnit->id == UnitId::Hero_JimRaynorVulture ||
            activeUnit->id == UnitId::science_vessel
        )


unit_train.cpp
                    if(builtUnit->status & UnitStatus::Completed) {

                        if(builtUnit->id == UnitId::science_vessel) {
                            builtUnit->vulture.spiderMineCount = 3;
                        }

                        AI_TrainingUnit(unit,builtUnit);
                        ...


game_hooks.cpp
        for (CUnit *unit = *firstVisibleUnit; unit; unit = unit->link.next) {
            //Only necessary if you have pre-placed science vessels that you care about
            if (*elapsedTimeFrames == 0 && unit->id == unitId::science_vessel) {
                unit->spiderMineCount = 3;
            }
        }




all i am is a contrary canary
but i'm crazy for you
i watched you cradling a tissue box
sneezing and sniffling, you were still a fox


Modding Resources: The Necromodicon [WIP] | Mod Night
My Projects: SCFC | ARAI | Excision [WIP] | SCFC2 [BETA] | Robots vs. Humans | Leviathan Wakes [BETA]


Sep 8 2019, 9:16 pm Lagi Post #9



thank you Voyager7456, you are the best

===1==

do evertyhing as per above - it works (only limited number of use).

still my Dropship dont display the icon on tooltips - any idea?

====2==

I was long searching for function to modify something when unit is complete. It open a new horizon for modify stuff for me.

sadly, I try to use below function in unit train , to stop Scourge from rally point, after being morph from zergling - and it doesnt work.

if(builtUnit->status & UnitStatus::Completed) {



None.

Sep 8 2019, 9:22 pm Voyager7456 Post #10

Responsible for my own happiness? I can't even be responsible for my own breakfast

Post your Spider Mines tech requirements and stats_panel_display. The changes I listed should be enough to have the icon display.



all i am is a contrary canary
but i'm crazy for you
i watched you cradling a tissue box
sneezing and sniffling, you were still a fox


Modding Resources: The Necromodicon [WIP] | Mod Night
My Projects: SCFC | ARAI | Excision [WIP] | SCFC2 [BETA] | Robots vs. Humans | Leviathan Wakes [BETA]


Sep 8 2019, 9:25 pm Voyager7456 Post #11

Responsible for my own happiness? I can't even be responsible for my own breakfast

Quote from Lagi

====2==

I was long searching for function to modify something when unit is complete. It open a new horizon for modify stuff for me.

sadly, I try to use below function in unit train , to stop Scourge from rally point, after being morph from zergling - and it doesnt work.

if(builtUnit->status & UnitStatus::Completed) {

The unit train hook is only for units that are trained (IE, from a building or Carrier/Reaver). Scourges are morphed. orders_ZergBirth() in unit_morph.cpp is the best place to do anything post-morph for Zerg units.



all i am is a contrary canary
but i'm crazy for you
i watched you cradling a tissue box
sneezing and sniffling, you were still a fox


Modding Resources: The Necromodicon [WIP] | Mod Night
My Projects: SCFC | ARAI | Excision [WIP] | SCFC2 [BETA] | Robots vs. Humans | Leviathan Wakes [BETA]


Sep 8 2019, 9:31 pm Lagi Post #12





stats panel


i add hook in initialize - h and cpp - ok



None.

Sep 8 2019, 9:39 pm Voyager7456 Post #13

Responsible for my own happiness? I can't even be responsible for my own breakfast

Your spider mines requirements are not correct. It should be

...
Must be researched
Or
Current unit is
Dropship

...
Jim Raynor (Vulture)
Or
Current unit is
Dropship




all i am is a contrary canary
but i'm crazy for you
i watched you cradling a tissue box
sneezing and sniffling, you were still a fox


Modding Resources: The Necromodicon [WIP] | Mod Night
My Projects: SCFC | ARAI | Excision [WIP] | SCFC2 [BETA] | Robots vs. Humans | Leviathan Wakes [BETA]


Sep 8 2019, 9:51 pm Lagi Post #14



i set it as you said, double check firegraft - only difference is dropship instead s vessel

still :/

thanks, i would try with different unit next time





None.

Sep 10 2019, 9:03 pm Lagi Post #15



i set all same for corsair distruption web (unit train, stats all, "just" there is no hook for spell : distruption web)

I cannot understand something

why this works
if(unit->id == UnitId::ProtossCorsair && unit->mainOrderId == OrderId::CastDisruptionWeb) {
unit->vulture.spiderMineCount=0;
}


it disable the distruption web after one use

but this dont?
if(unit->id == UnitId::ProtossCorsair && unit->mainOrderId == OrderId::CastDisruptionWeb) {
unit->vulture.spiderMineCount--;
}


i can spam endlessly the spidermines. The amount of mines for train unit is set in unit train - isnt it?



None.

Sep 10 2019, 9:45 pm Voyager7456 Post #16

Responsible for my own happiness? I can't even be responsible for my own breakfast

Unless you added code to unit_train to set the Corsair's spider mines, it isn't set by default.

The other issue here (assuming this code is in the game_hooks unit loop) is that there's more than one frame where the Corsair's main order is going to be CastDisruptionWeb.

Consider a case where it takes 12 frames for a Corsair to cast Disruption web (whether that is because it needs to move into position, or because the spellcast animation takes that time). In each one of those frames, you decremented spiderMineCount by 1. By frame 3 spiderMineCount is 0 but it still has the order to cast Disruption Web. On frame 4 you will decrement spiderMineCount again. Since it is an unsigned value, it wraps around to 255.

There are similar issues if, for example, you order a Corsair to cast DWeb and then cancel that order. It will have spent the mines without casting. That is why I wrote the hook for DMatrix so that we can decrement the spider mine count at the appropriate time (during the actual spell cast logic, which is executed only once).


Did you try the spider mine display changes with a unit besides the Dropship? I have a theory that it might be related to the Transport unit display, but I haven't had the chance to test it yet.



all i am is a contrary canary
but i'm crazy for you
i watched you cradling a tissue box
sneezing and sniffling, you were still a fox


Modding Resources: The Necromodicon [WIP] | Mod Night
My Projects: SCFC | ARAI | Excision [WIP] | SCFC2 [BETA] | Robots vs. Humans | Leviathan Wakes [BETA]


Sep 10 2019, 10:03 pm Lagi Post #17



thats informative

i try mines on Corsair, and the counter is not displayed as well.

===
this suppose to lower HP by 10 for each use. But as you said: the order last multiple times so it eat HP 10 * frames (or whatever). Unit go to zero, and game crash to desktop , when hP goes below 0.

second line work fine if HP are lower than 50 (in game HP), then corsair is losing spidermines.

if(unit->mainOrderId == OrderId::CastDisruptionWeb) {
unit->hitPoints -= 2560;}

if (unit->hitPoints < 12800){
unit->vulture.spiderMineCount = 0;


====

cant await to come from work tomorrow to mess with this again ( what im doing with my life ;-) )



None.

Sep 12 2019, 8:42 pm Lagi Post #18



so I set corsait to lose 1 hp each cast

if(unit->mainOrderId == OrderId::CastDisruptionWeb) {
unit->hitPoints -= 256;}

if (unit->hitPoints < 12800){
unit->vulture.spiderMineCount = 0;


his hp:
100
87
74
63
50
36

so its not consistent its minus: 13 13 11 13 14 :/

========

here is my unreliable attempt to create 2x use of spell. Not require energy, or rather require NO energy/ no spellcaster.
Most of the time corsair will be able to cast two webs, however rarely he would be able to cast 3 and little more often only 1.

if(unit->mainOrderId == OrderId::CastDisruptionWeb){
if (unit->energy < 4680) {
unit->vulture.spiderMineCount = 0;}
else {unit->vulture.spiderMineCount = 1;
unit->energy -= 256;} }


Post has been edited 1 time(s), last time on Sep 14 2019, 3:26 pm by Lagi.



None.

Options
  Back to forum
Please log in to reply to this topic or to report it.
Members in this topic: None.
[08:35 pm]
Pr0nogo -- zz top
[06:28 pm]
NudeRaider -- Oh_Man
Oh_Man shouted: What happened to rockz
he's playing Elder Scrolls 4
[04:48 pm]
TF- -- doare-n pula
[11:07 am]
TF- -- muh blends
[08:25 am]
Oh_Man -- Last post feb that guy was a legend on the ums assistance forums *takes off hat*
[08:24 am]
Oh_Man -- What happened to rockz
[08:21 am]
jjf28 -- :wob:
[2019-9-19. : 1:45 am]
O)FaRTy1billion[MM] -- :wob:
[2019-9-19. : 12:13 am]
Oh_Man -- Daylight wobbery :wob:
[2019-9-18. : 11:56 pm]
razorback9423 -- :wob: :wob: :wob: :wob: :wob:
Please log in to shout.


Members Online: razorback9423, Roy, Oh_Man, akumydepy