ZScript "Standard Library" - Brainstorming

Post your example zscripts/ACS scripts/etc here.

ZScript "Standard Library" - Brainstorming

Postby Xaser » Thu Jan 19, 2017 6:31 pm

The idea's been vaguely mentioned before, but it's probably worth opening up a separate discussion channel, so...

Now that ZScript is a thing, there's way less burden on the developers to implement certain types of new features since a vast amount of things that previously required engine development can now be DIY'd in scripting. 'Course, that also means that the burden is now on us as a community to implement these things, and there's liable to be many common problems that folks will wish to solve in script-land.

The Idea: a quasi-official ZScript "Standard Library" would be a cool community project to undertake at some point, and I'm interested to hear what ideas folks may have for such a thing, just to get the ball rolling. I've got a few ideas I'll jot down myself at some point (standardized reloading and synthfire, for instance), but mostly I wanted to open the door for brainstorming.

As a quick word of warning, I'd advise folks interested in actually writing such a library to exercise caution before jumping headlong into things. Doing this correctly is a non-trivial undertaking -- there needs to be a clean, well-documented API and sane versioning/release scheduling, else folks will try and axe-murder you when you publish a version that breaks everything. :P

Anyhow, discuss. Or don't -- I'm a Xaser, not a cop.
User avatar
Xaser
autodefenestrator
 
 
 
Joined: 20 Jul 2003

Re: ZScript "Standard Library" - Brainstorming

Postby Gez » Thu Jan 19, 2017 7:04 pm

How about a modified item grab function replicating stuff like Smart Scavenger? E.g., you have 47 shells, you move over a shellbox, you know have 50 shells -- but the shellbox is still there and will give up to a full 17 shells the next time. Having such an override function ready to be plugged in would be useful. Same for medikits and why not armors.
Gez
 
 
 
Joined: 06 Jul 2007

Re: ZScript "Standard Library" - Brainstorming

Postby Nash » Fri Jan 20, 2017 2:20 am

I've been preparing a set of minimal ZScript demo WAD set. :D Here's what I have so far:

ZScript examples

Position object to player smoothly
How to iterate through objects
Draw something on the screen
User avatar
Nash
 
 
 
Joined: 27 Oct 2003
Location: Kuala Lumpur, Malaysia

Re: ZScript "Standard Library" - Brainstorming

Postby kodi » Fri Jan 20, 2017 5:50 am

A radial "hitscan" function would be incredibly useful, something that automatically spawns a single puff on any shootable actor within the radius (sight check optional).
User avatar
kodi
Proscrastinator
 
Joined: 06 May 2013

Re: ZScript "Standard Library" - Brainstorming

Postby Major Cooke » Fri Jan 20, 2017 2:16 pm

Xaser wrote:As a quick word of warning, I'd advise folks interested in actually writing such a library to exercise caution before jumping headlong into things. Doing this correctly is a non-trivial undertaking -- there needs to be a clean, well-documented API and sane versioning/release scheduling, else folks will try and axe-murder you when you publish a version that breaks everything. :P


Structs and/or classes with static functions aught to be fine. For example I use the struct TIterator to ease creation of ThinkerIterator so I can stop looking it up so much.

Note this is moreso tailed towards what I need it for so a lot of stuff can be left out.

Code: Select allExpand view
// Contains the iterator flags and instructions.
Struct TIteratorProperties
{
    enum EItFlags
    
{
        ITF_EXACT =         1,        // Disregard inheritance.
        ITF_NOTID =            1 << 1,    // Ignore actors with a TID.
        ITF_NOSPECIAL =        1 << 2, // Ignore actors with a special.
        
        ITF_SAFE 
=            ITF_NOTID|ITF_NOSPECIAL,
    };
    
    enum EItInstructions
    
{
        ITN_DESTROY =        1,        // Destroy all actors found.
        ITN_LOGCOUNT =        2,        // Displays how many of the actors were found.
    };
}

//------------------------------------------------------------------------------
// TIterator
//
// -- Properties --
// * p             - Contains a copy of accessible flags.
// * caller        - The actor doing the distance check.
//
// -- Functions --
// * (!)ErrorMessage (count)
//        Logs a problem message to console.
//        
// * (!)FindActors (ActorType, instructions, flags, maxcount, dist);
//        Looks for ActorType based on flags and distance, then executes the given
//        instruction.
//
// * Setup (mo)
//        Inserts the caller into the struct so it may run properly.
// 
// * DoFindActors
//        A wrapper function which sets up the iterator itself, and calls 
//        FindActors inside the TIterator struct.
//
// (!) - Private function. Must be called on by another.
//------------------------------------------------------------------------------

Struct TIterator
{
    TIteratorProperties p;
    private Actor caller;
//------------------------------------------------------------------------------
    private void ErrorMessage (int count)
    {
        if (!caller)    return;
        String msg = "";
        Switch (count)
        {
            Case -1:
            {
                msg = "Iterator error: No ActorType specified";
                break;
            }
            Case -3:
            {
                msg = "Iterator error: No instructions passed";
                break;
            }
            Default:    break;
        }
        caller.A_Log(msg);
    }
    
//------------------------------------------------------------------------------
    void Setup(Actor mo)
    {
        if (mo)    caller = mo;
    }
//------------------------------------------------------------------------------
    void DoFindActors (Class<Actor> ActorType, int instructions, int flags = 0, int maxcount = 0, double dist = 0.0)
    {
        if (caller)
        {
            int count = FindActors(ActorType, instructions, flags, maxcount, dist);
            
            if 
(count < 0)
            {
                ErrorMessage (count);
                return;
            }
            
            if 
(flags & p.ITN_LOGCOUNT)
                caller.A_LogInt(count);
        }
    }
//------------------------------------------------------------------------------
    private int FindActors (Class<Actor> ActorType, int instructions, int flags = 0, int maxcount = 0, double dist = 0.0)
    {
        // Indicate something went wrong or its not set up properly.            
        if (!ActorType)        return -1;    // Actor type doesn't exist
        if (!caller)        return -2;    // No caller was passed
        if (!instructions)    return -3;    // No instructions were passed
        
        ThinkerIterator it 
= ThinkerIterator.Create(ActorType);
        Actor mo;
        int count = 0;
        while (mo = Actor(it.Next(flags & p.ITF_EXACT)))
        {
            if (((flags & p.ITF_EXACT) && mo.GetClass() != ActorType) || !(mo is ActorType))
                continue;
                
            
// Ignore actors with special and/or tids unless specified.
            if ((flags & p.ITF_NOTID) && mo.tid)
                continue;
            if ((flags & p.ITF_NOSPECIAL) && mo.special)
                continue;
            
            
// Don't take owned items.
            if (mo is "Inventory")
            {
                let inv = Inventory(mo);
                if (inv.Owner != null)
                    continue;
            }
            
            
// Make sure it's in range.
            if (dist <= 0.0 || caller.Distance3D(mo) <= dist)
            {
                count++;
                
                
// Now perform the instructions.
                if (instructions & p.ITN_DESTROY)
                {
                    mo.Destroy();
                    continue;
                }
            }
        }
        return count;
    }
}

//------------------------------------------------------------------------------
// IteratorBase
//
// Houses all the setup materials for inheriting from. 
// Don't spawn it directly -- Inherit from it and replace
// PostBeginPlay instead.
//------------------------------------------------------------------------------

Class IteratorBase : Actor
{
    
TIterator finder;
    TIteratorProperties p;

    override void PostBeginPlay()
    {
        Destroy();
        return;
    }
    
    Default
    
{
        +NOSECTOR
        
+NOINTERACTION
        
+THRUACTORS
        
+NOBLOCKMAP
    
}
}

//==============================================================================
//==============================================================================
//    Examples
//==============================================================================
//==============================================================================

// Removes ammo on the map and prints the number of actors removed, but only if
// they have no tid or special.
Class AmmoRemover : IteratorBase
{
    override void PostBeginPlay()
    {   
        int instructions 
= p.ITN_DESTROY|p.ITN_LOGCOUNT;
        int flags = p.ITF_SAFE;
        int maxcount = 0;
        double dist = 0.0;
        
        finder
.Setup(self);
        finder.DoFindActors("Ammo",instructions, flags, maxcount, dist);
        Destroy();
        return;
    }
}
User avatar
Major Cooke
Slaughterer of Sewers
 
Joined: 28 Jan 2007
Discord: Major Cooke#0846

Re: ZScript "Standard Library" - Brainstorming

Postby ZzZombo » Mon Jan 23, 2017 9:41 am

Attach an object to another at certain offset, and angle, relative or absolute.
Copy properties from one actor to another, provided one is subclass of another, that's it, they are assignment-compatible. Create a copy of an actor.
Provide an alternative actor flag system where multiple sources of a flag would work with each other independently. So if two things make an actor invulnerable, removing one doesn't cancel the other.
ZzZombo
 
Joined: 16 Jul 2012

Re: ZScript "Standard Library" - Brainstorming

Postby Enjay » Mon Jan 23, 2017 1:27 pm

I don't think that I am talented enough to write anything meaningful, but I fully support the idea of this script library. It makes a lot of sense and, if it takes off, I'm sure it will be very useful to a lot of people (myself included). I also suspect that the best/most useful/most frequently used might find their way into official support as part of a library within gzdoom.pk3.
User avatar
Enjay
Everyone is a moon, and has a dark side which he never shows to anybody. Twain
 
 
 
Joined: 15 Jul 2003
Location: Scotland

Re: ZScript "Standard Library" - Brainstorming

Postby Rachael » Mon Jan 23, 2017 1:39 pm

Enjay wrote:I also suspect that the best/most useful/most frequently used might find their way into official support as part of a library within gzdoom.pk3.

That is unlikely. Remember the problem you had compiling Stronghold after official sqrt support was added?

Unless Graf can find a way to create exceptions for said library (where GZDoom overrides the library's internal functions instead of erroring out) I don't think it's likely anything will be added in. Unless - of course - said library was careful to prefix its function names, i.e. "ZComLib_FunctionName" etc - whereas GZDoom could opt to omit those prefixes.
User avatar
Rachael
Not all elves needs a stocking hat...
 
Joined: 13 Jan 2004

Re: ZScript "Standard Library" - Brainstorming

Postby Enjay » Mon Jan 23, 2017 1:45 pm

Fair enough. That makes sense. I hadn't really considered the technical/conflict implications of such a thing. I was just sort of thinking out loud that if someone created a particular code-pointer-like function that was clearly pretty universally useful, that such a thing might be a possible candidate for official inclusion.
User avatar
Enjay
Everyone is a moon, and has a dark side which he never shows to anybody. Twain
 
 
 
Joined: 15 Jul 2003
Location: Scotland

Re: ZScript "Standard Library" - Brainstorming

Postby Rachael » Mon Jan 23, 2017 2:13 pm

If someone wants to have that happen, then using prefixes would be a very good idea. Among other things, that would also prevent name clashes when someone actually does, later on, implement a function on their own in their own mod that also uses this library, but would later break because this library picked up on that function and the modder updated it.
User avatar
Rachael
Not all elves needs a stocking hat...
 
Joined: 13 Jan 2004

Re: ZScript "Standard Library" - Brainstorming

Postby Xaser » Mon Jan 23, 2017 7:47 pm

Yeah, I'd absolutely advocate using a prefix -- or a namespace if that indeed becomes a proper thing following Graf's type system overhaul.

Speaking of, even though this is the bikesheddiest sub-topic, I'm thinking of what to name such a thing. I'd originally imagined calling the library "XT" (for XTended or some shiz) just to give all the functions a nice "XT_" prefix, but something like ZTL (reference to C++'s STL) or SZL (Standard ZScript Library) are obvious-maybes as well.

Either way, a ton of cool ideas thus far! That radial hitscan bit reminds me I've always wanted to make something like "A_ArcAttack" which melees all enemies within a cone, for better sword-y weapons and such. So that's on the mental tally as well.
User avatar
Xaser
autodefenestrator
 
 
 
Joined: 20 Jul 2003

Re: ZScript "Standard Library" - Brainstorming

Postby Arctangent » Mon Jan 23, 2017 8:43 pm

Xaser wrote:"A_ArcAttack"

hey don't let everyone just use my signature move like it was nothing
User avatar
Arctangent
squawky
 
Joined: 06 Nov 2014
Discord: SquawkyAtan#2371

Re: ZScript "Standard Library" - Brainstorming

Postby Major Cooke » Mon Jan 23, 2017 8:51 pm

I'll see if I can supply a smooth transitioning from-one-spot-to-another using a sine wave, going from position A to B. Gonna be a little tricky...

Also, I say make it absolutely mandatory that authors of code exhaust themselves at documenting their functions and features. To this day I still look at all the undocumented zscript code and ask myself "What the hell does this even do?"
User avatar
Major Cooke
Slaughterer of Sewers
 
Joined: 28 Jan 2007
Discord: Major Cooke#0846

Re: ZScript "Standard Library" - Brainstorming

Postby Rachael » Mon Jan 23, 2017 10:04 pm

Major Cooke wrote:Also, I say make it absolutely mandatory that authors of code exhaust themselves at documenting their functions and features. To this day I still look at all the undocumented zscript code and ask myself "What the hell does this even do?"

Time to get researching! The world is counting on you! You are our second most knowledgeable person on the subject!

Kidding, of course...

Except about that last part... :twisted:
User avatar
Rachael
Not all elves needs a stocking hat...
 
Joined: 13 Jan 2004

Re: ZScript "Standard Library" - Brainstorming

Postby Major Cooke » Mon Jan 23, 2017 11:34 pm

I tried escaping that responsibility with my trusty steed.
Image

But he got into the horse nip. I'm going nowhere except a hospital if I even try to get on him.
User avatar
Major Cooke
Slaughterer of Sewers
 
Joined: 28 Jan 2007
Discord: Major Cooke#0846

Next

Return to Script Library

Who is online

Users browsing this forum: No registered users and 1 guest