Applying translation to actor on WorldThingSpawned

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!
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!)
Post Reply
Kzer-Za
Posts: 522
Joined: Sat Aug 19, 2017 11:52 pm
Graphics Processor: nVidia (Modern GZDoom)

Applying translation to actor on WorldThingSpawned

Post by Kzer-Za »

I'm trying to give normal (not fire) Gargoyles in Heretic a different color so that they can be told from Fire Gargoyles at a glance. (Just a minimod for personal use). Since I already have several minimods that check things on WorldThingSpawned event, I thought I would put this thing also on this event.

The translation is defined in TRNSLATE.txt as

Code: Select all

TestBlue = "0:255=%[0,0,0]:[0,0,1]"
(Just to start with something and then adjust if needed).

Then I'm trying to apply it on WorldThingSpawned:

Code: Select all

if (event.thing is "HereticImp" && event.thing.Health == 40)
	event.thing.translation = "TestBlue";
However the engine gives an error:

Code: Select all

Script error, ":zscript.zsc" line 40:
Numeric type expected
It seems I can't use a name for translation in this way, the engine expects some number. How can I apply it?
Jarewill
 
 
Posts: 1855
Joined: Sun Jul 21, 2019 8:54 am

Re: Applying translation to actor on WorldThingSpawned

Post by Jarewill »

To use translations from the TRNSLATE file, use A_SetTranslation.
Kzer-Za
Posts: 522
Joined: Sat Aug 19, 2017 11:52 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Applying translation to actor on WorldThingSpawned

Post by Kzer-Za »

Ah, thanks!

Maybe you also could tell me how to make a translation that would change shades of red to shades of light-blue? I don't understand well how the whole translation thing works. The described TestBlue translation now kinda works, but it is a dark blue color and almost solid color.
Kzer-Za
Posts: 522
Joined: Sat Aug 19, 2017 11:52 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Applying translation to actor on WorldThingSpawned

Post by Kzer-Za »

Here's a better translation I came up with after some trial and error (it would really help if there was some information on how to make new translations). It repaints the gargoyle to shades of grey, so it looks kinda like "stone gargoyle".

Code: Select all

GargGrey = "145:168=6:32", "248:250=36:38"
And application of this translation is, as advised by Jarewill, with A_SetTranslation:

Code: Select all

if (event.thing.GetClassName() == "HereticImp")
	event.thing.A_SetTranslation("GargGrey");
I'm using GetClassName here instead of "is" to avoid repainting also HereticImpLeader, which I want to remain red, as a "fire gargoyle".
User avatar
Nash
 
 
Posts: 17503
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: Applying translation to actor on WorldThingSpawned

Post by Nash »

Hey, sorry for hijacking the thread but it's kinda related. :D

Does anyone know if it's possible at all - in ZScript - to generate translations at runtime, like in ACS?
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Applying translation to actor on WorldThingSpawned

Post by Player701 »

Theoretically, yes. There is a struct Translation that has an array of 256 colors, which probably map to palette indices. You can use it like this:

Code: Select all

Translation tran;

for (int i = 0; i < 256; i++)
{
    tran.Colors[i] = ... ; // <-- TODO
}

int t = tran.AddTranslation();

// TODO: Do something with t
However, I've never used this in my own projects, so I'm unsure where exactly you should put this code. For example, if you run it in a static event handler, it may not work correctly because AddTranslation could generate a different index depending on whether there are any other custom translations in the table. And it also seems that these translations are not serialized in save files.
User avatar
Nash
 
 
Posts: 17503
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: Applying translation to actor on WorldThingSpawned

Post by Nash »

Player701 wrote:And it also seems that these translations are not serialized in save files.
Ah, I've read about this before. That's a blocker indeed. Looks like ACS still has its uses here in this particular use case... :mrgreen:
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Applying translation to actor on WorldThingSpawned

Post by Player701 »

The main problem is not with serialization but with indexing. ZScript API does not allow you to specify translation indices when adding them, otherwise it would be possible to use them from static event handlers (re-creating them each time the game is started). And since you only have a raw color array, without any fancy syntactic sugar like "112:127=[0,255,0]:[255,0,0]", it'd still be kind of difficult to work with translations in ZScript. I think both the parsing code for translation definitions as well as the ability to specify the index should be made available in user code for ZScript to fully replace ACS for this purpose.
User avatar
Apeirogon
Posts: 1606
Joined: Mon Jun 12, 2017 12:57 am

Re: Applying translation to actor on WorldThingSpawned

Post by Apeirogon »

You can kinda hack it

Code: Select all


enum all_require_translations
{
    green_to_blue = 1,
    red_to_purple = 2,
    all other translations here
}

class translation_handler
{
    array<int> translations_here;

    private void init_translations()
    {
        translations_here.resize(greatest number from all_require_translations enum);

        int t = set_green_to_blue_translation();
        translations_here[green_to_blue] = t;
        //repeat previous two lines with each translation function for each translation until all tanslations are created
    }
    //require personal function for each translation
    private int set_green_to_blue_translation()
    {
        Translation tran;

        for (int i = 0; i < 256; i++)
        {
            tran.Colors[i] = ... ; // <-- TODO
        }

        return tran.AddTranslation();
    }
    
    int get_translations(int translation_enum)
    {
        return translations_here[translation_enum];
    }

    override void worldloaded()
    {
        init_translations();
    }
}

usage is translation_handler(eventhandler.find("translation_handler") ).get_translations(enum of traslation here);
Pseudocode and Untested, just an idea.
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Applying translation to actor on WorldThingSpawned

Post by Player701 »

Yeah, this is exactly what I was talking about. Not easy to use, and since we don't have any control over values returned by AddTranslation, there is no guarantee that they will always stay the same.
User avatar
Apeirogon
Posts: 1606
Joined: Mon Jun 12, 2017 12:57 am

Re: Applying translation to actor on WorldThingSpawned

Post by Apeirogon »

Well, my approach gets around this. Translation reinited each time world is loaded with saving specific translation type under specific index in array. So it didnt matter what value translation "green to blue" have, 1, 17 or 864, it stored in all_translation array under green_to_blue enum index aka all_translation[green_to_blue enum here]. Of course if you insert corresponding to enumeration translation into array.
Its crutchy, but possible. Not much worse than decorate hacks back in the day.
User avatar
Player701
 
 
Posts: 1710
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: Applying translation to actor on WorldThingSpawned

Post by Player701 »

Apeirogon wrote:So it didnt matter what value translation "green to blue" have, 1, 17 or 864
Well, actually, it does matter, because this "1, 17, or 864" is exactly what is going to be stored in the save file. And if some other mod is loaded alongside, or perhaps the underlying implementation is changed in GZDoom source code, next time these values will be different, and the saved values will point to some other, probably even non-existent data. This solution is quite volatile and definitely should not be considered future-proof.
User avatar
Apeirogon
Posts: 1606
Joined: Mon Jun 12, 2017 12:57 am

Re: Applying translation to actor on WorldThingSpawned

Post by Apeirogon »

Check is loaded from save file in world loaded event then, and if yes again reinit translation?!
Post Reply

Return to “Scripting”