"How do I ZScript?"

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: "How do I ZScript?"

Post by Major Cooke »

Ed the Bat wrote:I see. So ApplyDamageFactors is not the answer, then. Thanks.
There's two versions.

ApplyDamageFactor
ApplyDamageFactors

Because someone's going to have a hard time finding that 's', I just know it. :P

Code: Select all

native int ApplyDamageFactor(Name damagetype, int damage);
native static int ApplyDamageFactors(class<Inventory> itemcls, Name damagetype, int damage, int defdamage);
Last edited by Major Cooke on Fri Mar 03, 2017 3:05 pm, edited 1 time in total.
User avatar
Ed the Bat
Posts: 3060
Joined: Thu May 03, 2012 1:18 pm
Graphics Processor: nVidia with Vulkan support
Location: Maryland, US

Re: "How do I ZScript?"

Post by Ed the Bat »

Hmm, ApplyDamageFactor vs ApplyDamageFactors... interesting.

But will one of these get me what I want?
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: "How do I ZScript?"

Post by Major Cooke »

You haven't really told anyone what you wanted. The first one appears to be what's used with regular DamageFactors not on items.
User avatar
Ed the Bat
Posts: 3060
Joined: Thu May 03, 2012 1:18 pm
Graphics Processor: nVidia with Vulkan support
Location: Maryland, US

Re: "How do I ZScript?"

Post by Ed the Bat »

Major Cooke wrote:You haven't really told anyone what you wanted.
Ed the Bat wrote:Am I able to change type-specific DamageFactors for an actor, so as to modify only how much damage certain types, or "elements", will do to the actor?
Ahem...
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: "How do I ZScript?"

Post by Major Cooke »

And this is what happens when things get buried. Shit gets overlooked. :P

Anyway, the only foolproof way that I can think of is manually overriding DamageMobj. Be careful -- that can get a little sticky.

Code: Select all

override int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags = 0, double angle = 0)
{
    if (mod == "HologramDmgType") return 0;

    // Don't negate stuff if it's telefrag-esque damage amounts.
    if (damage < TELEFRAG_DAMAGE)
    {
        // Reduce by 1% for every megasphere we've picked up.
        // DoomDoll does not give this bonus.
        int pc1 = Clamp(CountInv("D4MegasphereDamageReducer"),0,25);
        if (pc1 > 0)
        {
            damage = Max(0,damage * (1 - (0.01 * pc1)));
        }
    }
    return Super.DamageMobj(inflictor, source, damage, mod, flags, angle);
} 
"mod" is the damagetype.
Last edited by Major Cooke on Fri Mar 03, 2017 3:14 pm, edited 1 time in total.
User avatar
krokots
Posts: 272
Joined: Tue Jan 19, 2010 5:07 pm

Re: "How do I ZScript?"

Post by krokots »

Major Cooke wrote: And because of your ninja edit, yes, it's fully possible to make your own kind of look function. Bear in mind, mine doesn't do natural monster searching -- it only goes by TIDs.
Well a custom look function would cut all the crap with Thing_Hate I am using right now, I could make two types of monsters, and each would only target the TID of enemy. Anyway, for now I am sticking with Thing_Hate, I just had a small problem with spawned actors mid battle who did not know who to attack, but it's solved. Super crap method - just change them tid to temporary number 45, ask them to hate tid of -10, and change tid back to original. And yes, this are TID's I use. :P
Thanks for the code!
User avatar
Ed the Bat
Posts: 3060
Joined: Thu May 03, 2012 1:18 pm
Graphics Processor: nVidia with Vulkan support
Location: Maryland, US

Re: "How do I ZScript?"

Post by Ed the Bat »

Buried? It's even quoted in the follow-up post... viewtopic.php?f=3&t=55073&start=375#p981411

Anyway... I guess I can give that method a try. I just wish setting DamageFactor <type> was as simple as setting an actor's 'global' DamageFactor (i.e., DamageFactor=<number>;)
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: "How do I ZScript?"

Post by Major Cooke »

@Krokots: Just an FYI, I only did a TID search because A_Look is useless in my mod itself with team oriented goals, not to mention same-actor entities running all over the place. But the thing is, just check and find a target and then search for other targets via nearby allies. You always have things like iterators to help out.

@Ed: You can, if you use global variables. You still have to edit DamageMobj and apply it on all actors but it's only one place to have to edit it.
Last edited by Major Cooke on Fri Mar 03, 2017 3:21 pm, edited 1 time in total.
User avatar
Ed the Bat
Posts: 3060
Joined: Thu May 03, 2012 1:18 pm
Graphics Processor: nVidia with Vulkan support
Location: Maryland, US

Re: "How do I ZScript?"

Post by Ed the Bat »

I've looked at the global variables thread. I'm really not seeing anything in it that would let me edit an actor to give him, for instance, DamageFactor "Fire",2.0; after he's already been created.
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: "How do I ZScript?"

Post by Major Cooke »

I saw the word "global" and thought you meant all actors, not just one.

In a way, you could kinda do it, individually still.

On (Post)BeginPlay, have two dynamic arrays set up: one for strings, one for floats. Then have the DamageMobj function run through those and compare. Put those in the global actor scope, mind.

EDIT: Fuck. I forgot strings and names don't mix well, last I checked. Could be wrong though, so give it a shot.
User avatar
Ed the Bat
Posts: 3060
Joined: Thu May 03, 2012 1:18 pm
Graphics Processor: nVidia with Vulkan support
Location: Maryland, US

Re: "How do I ZScript?"

Post by Ed the Bat »

When I said 'global', I meant the "DamageFactor" property that applies to all damage types. That can be modified by simply saying DamageFactor=<number>; (as I thought I made clear with how often I say this). But again, that will apply to all types, not just "Fire", as per the example. So it's not a solution.

But it sounds like there's no simple or direct way to modify type-specific DamageFactors. I'll take what I can get, though, so next time I'm at my desk I'll see if I can make something of your suggestions.
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: "How do I ZScript?"

Post by Major Cooke »

In that case you just modify the Damage directly inside the function. Just take the guts out of what I had in my example and inside the passed telefrag check, add:

Code: Select all

 Damage *= 0.75;
Note that the call to Super.DamageMobj will still apply damagefactors though. If you want absolute control without weird mash-ups you'll have to throw out all damagefactors and manually do them yourself. You will have to call Super.DamageMobj in order to kill something sanely. Or if you just want something simple like that and allow the damagefactors to be processed normally, the super call can also work as is after the damage change above, without throwing the damagefactors out.
User avatar
Matt
Posts: 9696
Joined: Sun Jan 04, 2004 5:37 pm
Preferred Pronouns: They/Them
Operating System Version (Optional): Debian Bullseye
Location: Gotham City SAR, Wyld-Lands of the Lotus People, Dominionist PetroConfederacy of Saudi Canadia

Re: "How do I ZScript?"

Post by Matt »

Is there a way to just get the number for an actor's damagetype-based damagefactor?

I've got a fire actor that damages 1 point every couple tics for a set duration. If this is subject to a damagefactor of less than 1, it just rounds down to zero and the victim ends up taking no damage at all. I want to access the number so that the duration of the fire would be reduced instead of the amount of damage.
User avatar
Major Cooke
Posts: 8196
Joined: Sun Jan 28, 2007 3:55 pm
Preferred Pronouns: He/Him
Location: QZDoom Maintenance Team

Re: "How do I ZScript?"

Post by Major Cooke »

Damage is an int.
Do ApplyDamageFactor with a damage of 100.
User avatar
Nash
 
 
Posts: 17465
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia

Re: "How do I ZScript?"

Post by Nash »

Graf Zahl wrote:
Xaser wrote:
Nash wrote:Alright, noted... just how expensive is calling the global thinker, by the way? Since the code only does the Init once and never again after that...
It still uses a ThinkerIterator to retrieve the global object after it's been Init'd. There's that plus function call overhead, which currently isn't cheap in scripting-land. Something worth keeping in mind if this function of yours is meant to be called many times in a loop.
Here, the same applies as for every piece of code. If you can store the result of a costly operation in a local variable, do so. It may not register directly as performance loss but it will add up if done repeatedly.
So if I were to only retrieve the global thinker once per level load, and then do all real-time operations on - let's say - some dummy/temporary object I spawn in the world. And on every level change, just synchronize the variables together by copying the variables to/from the temporary object to the global thinker. Would that be better for performance?

Asking first before I actually do because this is a little complicated for my skill level and I don't want to waste time trying to do it when it won't bring me any benefit.

Return to “Scripting”