Hi I wonder how you'd make an Immortal Shield.
I know a little bit about programming in AS3 and I'm 99% sure this can be done.
If damage exceeds 9 on shields, take 10 damage on shields and play a chosen effect.
My friend told me that this is probably possible but if two zerglings attack the immortal at the same frame they would activate the hardened shield together, or if two sieged tanks damages it at the same time the shield would only take 10 damage and only one tank would be revealed.
How do you guys think this can be dealt with?
I need to know how the hardened shield could be made to react on each incoming attack separately.
Any ideas?
None.
Find Me On Discord (Brood War UMS Community & Staredit Network)
OK now I may or may not have no idea what I'm talking about but couldn't you do something like this:
IF damage exceeds 9 on shields, SUBTRACT 1 shield damage
IF damage exceeds 9 on shields, SUBTRACT 1 shield damage
IF damage exceeds 9 on shields, SUBTRACT 1 shield damage
repeat until...
IF damage EQUALS 9 on shields, subtract 9 shield damage.
Let's say we do your way, if two weak attacks hit the shield simultaneously it seems like they get added up and activate the hardened shield instead og doing the damage of two low damage attacks.
This especially happens if an Immortal comes in rage of let's say three lumped tanks, they'll hit it simultaneously but only one tank will be revealed and the hardened shield would only be activated once meaning that Each tank that hits the Immortal at the same time gets all their combined damage reduced to 10 combined.
This creates a big issue which I have no idea how to solve, the hardened shield has to react on each attack separately meaning that if there are several things damaging under 10 it should react like any other unit, if a high damage unit and a low damage unit is damaging the Immortal the low damage should do it's full damage and the High damage should reduce the damage to 10 from the specified attack only, if two high damage units attack the Immortal the hardened shield should activate and reduce the damage for 10 but for each attack not for both if they happen to damage the immortal simultaneously.
None.
I don't think it's possible to get around the problem as long as splash damage or projectiles are in the game. Even then, you would have to consider a lot of factors such as weapon, shield, and armour upgrades.
How does the shield upgrade work for the Immortal in SC2 if anyone knows, not even I know how to find out.
I think that if the shield armor level limites the damage made to the unit's shield and if that exceedes 9 the hardened shield would be activated.
About incoming damage it's very easy, as the damage exceeds the limit the hardened shield would be activated.
This is how I think it works and should make that the hardened shield isn't constantly used, this also means that if incoming attack deals like 12 damage and the shield upgrade is at level 3 assuming it adds +1 for each level, then that damage would be reduced to 9 and the hardened shield would not activate.
Does this sound right?
I think it is because how else would the Immortal make use of the hardened shield without it being constantly triggered by upgraded attacks.
Post has been edited 1 time(s), last time on Oct 13 2012, 12:00 pm by Raygoza.
None.
You could make part of the Hardened Shield ability the prevention of multiple attacks. That'd solve your problem.
A friend of mine says that that only works on Melee attack or instant attacks and not on projectile kind of damage nor splash damage.
Do you know of a solution to this?
I'd prefer that tank fire wont add up to get their damage reduced to 10.
None.
It doesn't matter if two attacks occur on the same frame, they're still evaluated separately; two tanks firing on the same frame will inflict a net of 20 damage. Additionally, in triggers, multiple instances occurring simultaneously will still run as separate instances.
As for the shield upgrade, the damage is reduced before hardened shield is taken into consideration.
None.
I don't know if it's possible to detect the separate evaluations though. I don't know of a hook to the damage evaluation function.
Observer, said that every attacking thing will have it's damage made calculated separately and even activate the hardened shield separately, does this even apply to the splash damage of siege tanks?
Meaning that the unit with this shield isn't the targeted one and is just getting hurt by the splash nearby.
Anyone may answer the question by the way.
To avoid duble posting here's my friend who is struggling with this and said this
The damage instances are calculated separately in game, but with plugins i can see what happens from frame to frame, so that is why i can not identify every damage instance. So unless i find a way to intercept the doWeaponDamage function used by SC i cannot be able to replicate the immortal shield.
How I ask your people, do you know how to find the doweapon Damage function taht is used by StarCraft?
Post has been edited 2 time(s), last time on Oct 20 2012, 7:49 pm by Raygoza.
None.
You need to use JmpCallPatch() to hijack the doWeaponDamage() function, as well as write some custom assembly code.
Here's how I did the "Plasma Shields receive only 50% damage from independent-damage weapons" thing in my mini-mod.
Note: This code goes in game.h
const DWORD DamagePlasmaShieldsInject = 0x004799F7;
const DWORD DamagePlasmaShieldsReturn = 0x00479A01;
void __declspec(naked) DamagePlasmaShields() {
__asm {
MOVZX eax, BYTE PTR [ebp+8] ; Weapon ID
MOV edx, [WeaponsDat_DamageType] ; The address for this table is defined elsewhere...see BWAPI's Offsets.h for more info
MOVZX edx, BYTE PTR [edx+eax] ; Damage type
CMP edx, 0 ; Independent damage
JNE IsNotVenomousDamage
SAR esi, 1
IsNotVenomousDamage:
CMP esi, 128 ; This part also fixes the Irradiate/D-Matrix/Plasma Shields bug
JGE DoDamageToShields
MOV esi, 128
DoDamageToShields:
CMP esi, ecx ; ESI = damage amount, ECX = shield amount
MOV ebx, ecx ; EBX = amount of shields reduced
JG HasMoreShieldsThanDamage
MOV ebx, esi
HasMoreShieldsThanDamage:
SUB esi, ebx
CMP edx, 0 ; Independent damage
JNE ReturnToSC
SAL esi, 1
ReturnToSC:
JMP [DamagePlasmaShieldsReturn]
}
}
Note: this code goes in qdp.cpp, inside the InitializePlugin() function code:
JmpCallPatch(DamagePlasmaShields, DamagePlasmaShieldsInject);
P.S. I personally think the Immortal in SC2 is a crappily-designed unit made by someone thinking "ooh siege tanks so IMBA, they melt all my dragoons when I A-move...let's make them resistant to tank fire so I can A-move and win heh heh". SRSLY all they're good for is (1) saying F-you to Terran mech and positional play (2) kill Zerg in all-in pushes.
Post has been edited 1 time(s), last time on Oct 22 2012, 12:54 am by RadiganP.
None.
You're probably right about the Immortal, Dragoons in SC1 died easily from a group of sieged tanks, seeems that's the only reason they made the Immortal in teh first place.
And thanks a lot for the help, how did you learn all this by the way?
I mean knowing stuff like this allows for advanced functions.
Post has been edited 4 time(s), last time on Oct 28 2012, 7:47 am by Raygoza.
None.
Heinermann, the lead(?) developer of
BWAPI, has been working on analyzing StarCraft's internal functions for quite a while. He was kind enough to send me
a partial analysis of StarCraft.exe. To read it, you need a copy of IDA Pro + Hex-Rays plug-in.
None.
Also how could you import triggers in a mod?
The code you posted may need some tweaks because it seem to work for every unit with shields, what's needed is to identify the unit who it is receiving the damage so only immortals activate the effect. sS my friend is also investigating assembly and the internal functions of SC to see what can be done.
But for the moment there's no solution.
None.
Okay...how's about this? I haven't tested but it should work
const DWORD DamagePlasmaShieldsInject = 0x004799F7;
const DWORD DamagePlasmaShieldsReturn = 0x00479A01;
void __declspec(naked) DamagePlasmaShields() {
__asm {
; Register data at this point:
;
; ESI: Damage amount, after subtracting Defensive Matrix and Plasma Shields upgrades
; EDI: Pointer to the unit being hit
; ECX: Current amount of shields
;
; Stack data at this point:
;
; BYTE PTR [EBP + 0x8] : Weapon ID
; DWORD PTR [EBP + 0x14]: Pointer to the attacking unit (note: this may be NULL!)
;
; Goals:
; (1) Store the amount of Plasma Shields subtracted in the EBX register
; (2) Subtract the damage dealt to shields from the ESI register
; (3) It's okay to use EAX/ECX/EDX, don't touch anything else!
MOVZX eax, WORD PTR [edi+0x64] ; EAX <- Victim unit's ID
CMP eax, Immortal_unitID_1
JE Is_Immortal
CMP eax, Immortal_unitID_2
JE Is_Immortal
; Repeat above 2 lines as many times as needed
Unit_Is_Not_Immortal:
JMP DoDamageToShields
Unit_Is_Immortal:
CMP esi, 2560 ; ESI = damage amount. Let's say we want minimum damage to be 10, just like in StarCraft 2.
JBE DoDamageToShields
MOV esi, 2560 ; Set damage to 10
DoDamageToShields:
CMP esi, ecx ; ESI = damage amount, ECX = shield amount
MOV ebx, ecx ; EBX = amount of shields reduced
JG HasMoreShieldsThanDamage
MOV ebx, esi
HasMoreShieldsThanDamage:
SUB esi, ebx
JMP [DamagePlasmaShieldsReturn]
}
}
None.