Shanjaq / uhexen2

GitHub clone of SVN repo svn://svn.code.sf.net/p/uhexen2/code/trunk (cloned by http://svn2github.com/)
12 stars 1 forks source link

New function PimpModel to decorate models with cool client-side effects #87

Closed Inky-Inky closed 2 years ago

Inky-Inky commented 2 years ago

New function PimpModel to decorate models with cool client-side effects previously hard coded for certain models only.

Previously, only very specific hard coded models were allowed to cast light around (namely projectiles) or have a nice colored glow (like mana or torches). There were also all kinds of cool client effects (mainly trails for projectiles) triggerable through mdl flags only. Now it's possible to add such effects to any model without having to give it a special hard coded name or fiddle with its flags in QME (whose latest version anyway doesn't give access to them anymore). Just a line of code in HexenC and that's it. 🙂

Supported features:

To test the game engine edit, here is the tailored new misc_modelpimp entity :

@PointClass base(Appearflags, Targetname) color(255 170 255) model ({"path": model}) = misc_modelpimp : "Model properties"
[
    model(string) : "Model to pimp"
    spawnflags(flags) =
    [
        1: "Spin" : 0
        2: "Float" : 0
        4: "Glow orb" : 0
        8: "Cast light" : 0
    ]
    flags(flags) =
    [
        1: "Rocket smoke trail" : 0
        2: "Grenade smoke trail" : 0
        4: "Gib long blood trail" : 0
        8: "Rotate" : 0
        16: "Scrag double green trail" : 0
        32: "Zombie gib short blood trail" : 0
        64: "Hellknight orange split trail" : 0
        128: "Vore purple trail" : 0
        256: "Fireball" : 0
        512: "Ice trail" : 0
        1024: "Mipmap" : 0
        2048: "Ink spit" : 0
        4096: "Transparent sprite" : 0
        8192: "Vertical spray" : 0
        16384: "Holey (fence) texture" : 0
        32768: "Translucent" : 0
        65536: "Always facing" : 0
        131072: "Bottom & top trail" : 0
        262144: "Slow staff move" : 0
        524288: "Blue/white magic drip" : 0
        1048576: "Bone shards drip" : 0
        2097152: "Scarab dust" : 0
        4194304: "Acid ball" : 0
        8388608: "Blood rain" : 0
        16777216: "Far mipmap" : 0
    ]
    glow_color(string) : "Color for the glow and/or illumination"
    abslight(integer)  : "Glow alpha transparency" : 0.75
    view_ofs(string)   : "Glow offset relatively to model origin (x y z)" : "0 0 0"
    health(integer)    : "Glow radius" : 20
    max_health(integer): "Cast light radius" : 200
    wait(integer)      : "Refresh rate" : 0.5
    style(choices) : "Style (32-63 for groups)" : 0 =
    [
        0 : "Normal"
        1 : "Soft flicker"
        6 : "Faster flicker"

        4 : "Low falloff"

        5 : "Pulse"
        2 : "Slow pulse in & out"
        11 : "Quick pulse in & out"

        3 : "Erratic pulse & flicker A"
        7 : "Erratic pulse & flicker B"
        8 : "Erratic pulse & flicker C"
        9 : "Slow blink"
        10 : "Fluorescent flicker"

        12 : "Custom style 1"
        13 : "Custom style 2"
        14 : "Custom style 3"
        15 : "Custom style 4"
        16 : "Custom style 5"
        17 : "Custom style 6"
        18 : "Custom style 7"
        19 : "Custom style 8"
        20 : "Custom style 9"
        21 : "Custom style 10"
        22 : "Custom style 11"
        23 : "Custom style 12"
        24 : "Custom style 13"

        25 : "MLS_FULLBRIGHT"
        26 : "MLS_POWERMODE"
        27 : "MLS_TORCH"
        28 : "MLS_FIREFLICKER"
        29 : "MLS_CRYSTALGOLEM"
    ]
]

An its code :

/*QUAKED misc_modelpimp by Inky (11/2021)
An entity able to pimp the properties of a model (like rotation, glow, dynamic light, etc.)
flags   ignore the hard coded flags in the mdl file and use those instead
        Caution : the value set in flags is ignored if the "Showcase flags" mode is active because of a targetname set
                  if so the flags value is handled by code automatically and each call to .use
                  applies a different flag value for flags testing purpose
*/
string FlagFriendlyNames[25] =
{
    "_Rocket smoke trail",
    "_Grenade smoke trail",
    "_Gib long blood trail",
    "_Rotate",
    "_Scrag double green trail",
    "_Zombie gib short blood trail",
    "_Hellknight orange split trail",
    "_Vore purple trail",
    "_Fireball",
    "_Ice trail",
    "_Mipmap",
    "_Ink spit",
    "_Transparent sprite",
    "_Vertical spray",
    "_Holey (fence) texture",
    "_Translucent",
    "_Always facing player",
    "_Bottom & top trail",
    "_Slow staff move",
    "_Blue/white magic drip",
    "_Bone shards drip",
    "_Scarab dust",
    "_Acid ball",
    "_Blood rain",
    "_Far mipmap"
};

float modelpimp_showcase()
{
    //Advance the flags for the next call
    if(self.flags == 16777216)
    {
        self.walkframe = 0;
        self.flags = 1; //We've come full circle, back to the beginning
    }
    else
    {
        self.walkframe = self.walkframe + 1;
        if(self.flags == 0) self.flags = 1; else self.flags = self.flags * 2; //Next value 
    }
    entity player = find (world, classname, "player");
    centerprint(player,FlagFriendlyNames[self.walkframe]);

    return pimpmodel(self, self.glow_color);
}

void modelpimp_think ()
{
    pimpmodel(self, self.glow_color);

    //Do it again later (a small delay is mandatory when (re)loading a map; trying to pimp the model right away would come too early and fail)
    self.nextthink = time + self.wait;
}

void() misc_modelpimp =
{
    precache_model(self.model);
    setmodel(self, self.model);
    self.effects(+)EF_NODRAW;

    if(!self.wait) self.wait = 0.5;

    if(self.targetname)
    {
        self.use = modelpimp_showcase;
        self.walkframe = -1;
        self.flags = 0;
    }

    self.think = modelpimp_think;
    self.nextthink = time + self.wait;
}

Unrelated to what's above but also included in this PR: