Page 1 of 1

Player visual puking effect

Posted: Sun Jul 20, 2003 8:42 pm
by Neve
This script will make a player puke green goo and chunks of... stuff...

Usage :

Code: Select all

#include "puke"

object oPlayer = ###;

Puke(oPlayer);
Credit to most of the code goes to the person who scripted the Smoking Pipe.

Code: Select all

location GetLocationAboveAndInFrontOf(object oPC, float fDist, float fHeight){
    float  fDistance    = -fDist;
    object oTarget      = (oPC);
    object oArea        = GetArea(oTarget);
    vector vPosition    = GetPosition(oTarget);
    vPosition.z        += fHeight;
    float  fOrientation = GetFacing(oTarget);
    vector vNewPos      = AngleToVector(fOrientation);
    float  vZ           = vPosition.z;
    float  vX           = vPosition.x - fDistance * vNewPos.x;
    float  vY           = vPosition.y - fDistance * vNewPos.y;
    fOrientation        = GetFacing(oTarget);
    vX                  = vPosition.x - fDistance * vNewPos.x;
    vY                  = vPosition.y - fDistance * vNewPos.y;
    vNewPos             = AngleToVector(fOrientation);
    vZ                  = vPosition.z;
    vNewPos             = Vector(vX, vY, vZ);

    return Location(oArea, vNewPos, fOrientation);
}

void Puke(object oActivator){
    float fHeight   = 1.7;
    float fDistance = 0.1;

    if (GetGender(oActivator) == GENDER_MALE){
        switch (GetRacialType(oActivator)){
            case RACIAL_TYPE_HUMAN:
            case RACIAL_TYPE_HALFELF:
                fHeight   = 1.7;
                fDistance = 0.12;
                break;

            case RACIAL_TYPE_ELF:
                fHeight   = 1.55;
                fDistance = 0.08;
                break;

            case RACIAL_TYPE_GNOME:
            case RACIAL_TYPE_HALFLING:
                fHeight   = 1.15;
                fDistance = 0.12;
                break;

            case RACIAL_TYPE_DWARF:
                fHeight   = 1.2;
                fDistance = 0.12;
                break;

            case RACIAL_TYPE_HALFORC:
                fHeight   = 1.9;
                fDistance = 0.2;
                break;
        }
    }
    else{
        switch (GetRacialType(oActivator)){
            case RACIAL_TYPE_HUMAN:
            case RACIAL_TYPE_HALFELF:
                fHeight   = 1.6;
                fDistance = 0.12;
                break;

            case RACIAL_TYPE_ELF:
                fHeight   = 1.45;
                fDistance = 0.12;
                break;

            case RACIAL_TYPE_GNOME:
            case RACIAL_TYPE_HALFLING:
                fHeight   = 1.1;
                fDistance = 0.075;
                break;

            case RACIAL_TYPE_DWARF:
                fHeight   = 1.2;
                fDistance = 0.1;
                break;

            case RACIAL_TYPE_HALFORC:
                fHeight   = 1.8;
                fDistance = 0.13;
                break;
        }
    }
    location lAboveHead = GetLocationAboveAndInFrontOf(oActivator, fDistance + 0.2, fHeight - 0.4);

    AssignCommand(oActivator, ActionPlayAnimation(ANIMATION_LOOPING_TALK_PLEADING, 1.0, 0.5));
    AssignCommand(oActivator, ActionSpeakString("*Pukes*", TALKVOLUME_TALK));
    DelayCommand(0.1, AssignCommand(oActivator, ActionDoCommand(ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_CHUNK_YELLOW_SMALL), lAboveHead))));
    switch(d3()){
    case 1 :
        DelayCommand(0.3, PlayVoiceChat(VOICE_CHAT_PAIN1, oActivator));
        break;
    case 2 :
        DelayCommand(0.3, PlayVoiceChat(VOICE_CHAT_PAIN2, oActivator));
        break;
    case 3 :
        DelayCommand(0.3, PlayVoiceChat(VOICE_CHAT_PAIN3, oActivator));
        break;
    }
}

Posted: Sun Jul 20, 2003 10:30 pm
by Silk
hmmm... this would go well with the new disease system

Posted: Mon Jul 21, 2003 12:35 pm
by Neve
Feel free to use it :) I'm trying out some more animations instead of the begging one, maybe one that drops the player on the knees, like Dying_front. I'll keep you posted :)

[Edit]

Only problem I found with this script is that you will only hear a sound when the player's walking, no visual effects. Maybe a short period of domination and a drunk animation would be nice...

Posted: Mon Jul 21, 2003 3:15 pm
by Jordicus
what about queueing all the actions using DelayCommand and then performing a SetCommandable(False) while your desired effects take place?

Posted: Mon Jul 21, 2003 3:47 pm
by Neve
Hmm, I wasn't aware of that command. I'll try that when I get home :) Thanks !

Posted: Mon Jul 21, 2003 4:02 pm
by Jordicus
once you do a SetCommandable(False) no more actions can be added or removed from the queue, which prevents the user from cancelling the actions as well. The difficult thing is to accurately judge the timing of the actions you have planned because the SetCommandable(False) will also disallow further actions you wish to add to the Action Queue as well.

And don't forget to add a SetCommandable(True) to your list so that they character is free once all your actions have completed..

Posted: Mon Jul 21, 2003 5:00 pm
by Myk D'vor
One thing I've been doing with the shovel and crafting placeables is to set up a queue of continuous animations that inherently have a duration parameter and last x amount of time. The nice thing is that they naturally start the next animation after the first one is finished. Once I have the queue set up, I do the SetCommandable(FALSE) and then a DelayCommand(40.0,SetCommandable(TRUE)), essentially. Then for 40 seconds the PC goes through a series of animations, and is unable to break them, until the 40 seconds is up. Now if you're adding visual effects, you'd have to time them carefully using DelayCommand, but it could be done, especially since they do not require adding to the PC's action queue.

Myk D'Vor

Posted: Mon Jul 21, 2003 6:21 pm
by Neve
Hmm... I tried that, but I have some other delayactions which fall inside the moments that the SetCommandable is already false, which causes those animations not to activate.

I did change the puking effect a bit, a player will first try to stop the first one with his/her hands, after that he/she will fall on the knees and have another go... It's a messy happening, but I just can't seem to make it work. After changing the chunk effect to an effect on a location rather than a command, it worked, but now the animations don't work anymore... :?

This is the part of the code that should play the animations, I did it according to a tutorial I found in the NWN Lexicon.

Also, I tried to play sound effect Objects, but I didn't hear them. I'd like to add a sound of an attacking ghoul instead of the standard pain voices...

PlaySound("filename") didn't work for me, neither did the PlaySoundObject(GetObjectByTag(Barfnoises))... The latter one didn't work with standard soundsets either.

Code: Select all


    AssignCommand(oActivator, ClearAllActions());

    //Puke (0.0 - 0.5)
    AssignCommand(oActivator, ActionPlayAnimation(ANIMATION_LOOPING_TALK_PLEADING, 1.0, 0.5));
    DelayCommand(0.1, AssignCommand(oActivator, ActionSpeakString("*Pukes*", TALKVOLUME_TALK)));
    DelayCommand(0.1, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_CHUNK_YELLOW_SMALL), GetLocationAboveAndInFrontOf(oActivator, fDistance + 0.2, fHeight - 0.4)));
    DelayCommand(0.1, Moan(oActivator));

    //Woozy movement (0.5 - 2.0)
    AssignCommand(oActivator, ActionPlayAnimation(ANIMATION_LOOPING_SPASM, 1.0, 1.5));

    //Fall down, puke again (2.0 - 2.4)
    AssignCommand(oActivator, ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT, 0.5, 0.4));

    DelayCommand(2.1, Moan(oActivator));
    DelayCommand(2.1, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_CHUNK_YELLOW_SMALL), GetLocationAboveAndInFrontOf(oActivator, fDistance + 0.1, fHeight - 0.8)));

    //And again
    DelayCommand(2.4, Moan(oActivator));
    DelayCommand(2.4, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_CHUNK_GREEN_SMALL), GetLocationAboveAndInFrontOf(oActivator, fDistance + 0.3, fHeight - 1.1)));

    SetCommandable(FALSE, oActivator);
    DelayCommand(2.5, SetCommandable(TRUE,  oActivator));


Posted: Mon Jul 21, 2003 6:28 pm
by Jordicus
you may need to change all the commands to delays after the ClearAllActions. that way they all get queued up correctly before you throw in the first SetCommandable.

not too sure though since you have a large queue of actions you are planning

Posted: Mon Jul 21, 2003 6:44 pm
by Neve
Yeah, I wanted to make them look really ill :)

Initially I just had one animation and one effect in the queue... I guess I'll have to fallback on that to make it work.

[Edit]

This one works.

Code: Select all

void Moan(object oMoaner){
    switch(d3()){
    case 1 :
        PlayVoiceChat(VOICE_CHAT_PAIN1, oMoaner);
        break;
    case 2 :
        PlayVoiceChat(VOICE_CHAT_PAIN2, oMoaner);
        break;
    case 3 :
        PlayVoiceChat(VOICE_CHAT_PAIN3, oMoaner);
        break;
    }
}

location GetLocationAboveAndInFrontOf(object oPC, float fDist, float fHeight){
    float  fDistance    = -fDist;
    object oTarget      = (oPC);
    object oArea        = GetArea(oTarget);
    vector vPosition    = GetPosition(oTarget);
    vPosition.z        += fHeight;
    float  fOrientation = GetFacing(oTarget);
    vector vNewPos      = AngleToVector(fOrientation);
    float  vZ           = vPosition.z;
    float  vX           = vPosition.x - fDistance * vNewPos.x;
    float  vY           = vPosition.y - fDistance * vNewPos.y;
    fOrientation        = GetFacing(oTarget);
    vX                  = vPosition.x - fDistance * vNewPos.x;
    vY                  = vPosition.y - fDistance * vNewPos.y;
    vNewPos             = AngleToVector(fOrientation);
    vZ                  = vPosition.z;
    vNewPos             = Vector(vX, vY, vZ);

    return Location(oArea, vNewPos, fOrientation);
}

void Puke(object oActivator){
    float fHeight   = 1.7;
    float fDistance = 0.1;

    if (GetGender(oActivator) == GENDER_MALE){
        switch (GetRacialType(oActivator)){
            case RACIAL_TYPE_HUMAN:
            case RACIAL_TYPE_HALFELF:
                fHeight   = 1.7;
                fDistance = 0.12;
                break;

            case RACIAL_TYPE_ELF:
                fHeight   = 1.55;
                fDistance = 0.08;
                break;

            case RACIAL_TYPE_GNOME:
            case RACIAL_TYPE_HALFLING:
                fHeight   = 1.15;
                fDistance = 0.12;
                break;

            case RACIAL_TYPE_DWARF:
                fHeight   = 1.2;
                fDistance = 0.12;
                break;

            case RACIAL_TYPE_HALFORC:
                fHeight   = 1.9;
                fDistance = 0.2;
                break;
        }
    }
    else{
        switch (GetRacialType(oActivator)){
            case RACIAL_TYPE_HUMAN:
            case RACIAL_TYPE_HALFELF:
                fHeight   = 1.6;
                fDistance = 0.12;
                break;

            case RACIAL_TYPE_ELF:
                fHeight   = 1.45;
                fDistance = 0.12;
                break;

            case RACIAL_TYPE_GNOME:
            case RACIAL_TYPE_HALFLING:
                fHeight   = 1.1;
                fDistance = 0.075;
                break;

            case RACIAL_TYPE_DWARF:
                fHeight   = 1.2;
                fDistance = 0.1;
                break;

            case RACIAL_TYPE_HALFORC:
                fHeight   = 1.8;
                fDistance = 0.13;
                break;
        }
    }
    location lAboveHead;

    AssignCommand(oActivator, ClearAllActions());
    AssignCommand(oActivator, ActionSpeakString("*Pukes*", TALKVOLUME_TALK));
    AssignCommand(oActivator, ActionPlayAnimation(ANIMATION_LOOPING_TALK_PLEADING, 1.0, 0.5));
    DelayCommand(0.1, SetCommandable(FALSE, oActivator));
    DelayCommand(0.4, SetCommandable(TRUE, oActivator));

    switch(d2()){
        case 1 :
            lAboveHead = GetLocationAboveAndInFrontOf(oActivator, fDistance + 0.2, fHeight - 0.4);
            DelayCommand(0.1, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_CHUNK_YELLOW_SMALL), lAboveHead));
            DelayCommand(0.4, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectStunned(), oActivator, 8.0));
            break;
        case 2 :
            lAboveHead = GetLocationAboveAndInFrontOf(oActivator, fDistance + 0.2, fHeight - 0.4);
            DelayCommand(0.1, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_CHUNK_GREEN_SMALL), lAboveHead));
            DelayCommand(0.4, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectFrightened(), oActivator, 8.0));
            break;
    }
    DelayCommand(0.1, Moan(oActivator));
}