Pick up Item sound effect not working as per tutorial

Hi All,

Thank you for your help (in advance).

I'm trying to get the following to work:

Tutorial - Custom Sounds For Collecting Items

Here is the code I am using in my item.c :

Code:
void main()
{

    void self = getlocalvar("self"); //get the self var
    void hit = getlocalvar("damagetaker"); // get target entity
    char Name = getentityproperty(self,"name"); // get target's name   //not sure why 'self' is used here tho, but that's what the posted article had

    if( Name == "Gold")
    {
        //play sound effect
        int SFX1 = loadsample("data/sounds/mysound.wav"); // load samples
        playsample(SFX1, 0, 120, 120, 100, 0);
    }
}


I then add the didhitscript to my <char>.txt (entity level) header :

didhitscript data/scripts/Item.c

When I test it, there are no OpenBOR log errors, but I also don't get any sound for the item pick up (just defaults to regular item pick up sound).

Alternatively, I tried doing an inline script as follows in my <char>.txt under the 'get' animation:
anim get
loop 0
delay 10

offset 19 70
frame data/chars/hero/pickup00.png

@script
if(frame==1)
{
void self = getlocalvar("self"); //get the self var
void hit = getlocalvar("damagetaker"); // get target entity
char Name = getentityproperty(hit,"name"); // get target's name // I changed 'self' to 'hit' which works, but only if I comment out the IF-Statement that follows

// if( Name == "Gold") // if statement is commented out just for testing, and it does play the sound this way (since no validation is being done)
// {
//play sound effect
int SFX1 = loadsample("data/sounds/mysound.wav"); // load samples
playsample(SFX1, 0, 120, 120, 100, 0);

// }
}

@end_script


delay 35
offset 38 47
frame data/chars/hero/pickup01.png

Question #1: I must be doing something wrong for the didhitscript inclusion, as I don't get any sound effect whatsoever (which tells me the code isn't running).

Question #2: I can get the Inline Script to work only if the "If-Statement" is commented out (meaning I can't check for a specific item). Is there a way I can output the 'Name' variable to the OpenBOR log so that I can see what is being returned? In this case "Gold" is the actual name of the item that I am targeting the sfx for, here's the Gold.txt :

name Gold
health 0
score 5000
type item
shadow 0
icon data/chars/misc/goldicon.gif


anim idle
loop 1
offset 9 13
bbox 0 0 17 13
delay 200
frame data/chars/misc/gold00.gif
delay 15
frame data/chars/misc/gold01.gif
frame data/chars/misc/gold02.gif
frame data/chars/misc/gold03.gif
frame data/chars/misc/gold02.gif
frame data/chars/misc/gold01.gif
 
Alternatively, I tried doing an inline script as follows in my <char>.txt under the 'get' animation:
On this case, inline script won't work - because these codes are treated as ANIMATIONSCRIPT and not DIDHITSCRIPT. You in animationscript, there is no "damagetaker", which defeat the whole code.

char Name = getentityproperty(self,"name"); // get target's name //not sure why 'self' is used here tho, but that's what the posted article had
Because you need to know the name of the item - without this, you can't have custom sounds for each item.
Is there a way I can output the 'Name' variable to the OpenBOR log so that I can see what is being returned?
Yes, I always forget to put this on the manual, but you can use the log() function:

C-like:
void main()
{

    void self = getlocalvar("self"); //get the self var
    void hit = getlocalvar("damagetaker"); // get target entity
    char Name = getentityproperty(self,"name"); // get target's name   //not sure why 'self' is used here tho, but that's what the posted article had

    if( Name == "Gold")
    {
        //play sound effect
        int SFX1 = loadsample("data/sounds/mysound.wav"); // load samples
        log(" \n Item: " + Name ); // Print the item name to the log
        playsample(SFX1, 0, 120, 120, 100, 0);
    }
}

But your version is a bit different, as you are loading the sample inside the if, where I load it beforehand. Also, I advice you to keep it using SWITCH instead of IF, as it is more modular this way - plus, you can have a default action for when somethings fails (this is the "default" part of the code). like this:

C-like:
void main(){
    // Custom sounds for picking itens
    // Douglas Baldan / O Ilusionista - 11/12/2016
    // Thanks Damon Caskey for the support
 
    void self = getlocalvar("self"); //get the self var
    void hit = getlocalvar("damagetaker"); // get target entity
    char Name = getentityproperty(self,"name"); // get target's name
    void power = getentityproperty(hit,"mp"); // get target's current mp
 
    int SFX1 = loadsample("data/sounds/power-up.wav"); // load samples
    int SFX2 = loadsample("data/sounds/life-up.wav");
    int SFX3 = loadsample("data/sounds/full-power.wav");
    int SFX4 = loadsample("data/sounds/full-life.wav");
    int SFX5 = loadsample("data/sounds/power-life.wav");
 
    switch(Name) { // check the item name
        case "iMP" : // power up
        log(" \n Item: " + Name ); // output the item name only for debugging, comment this line later
        playsample(SFX1, 0, 120, 120, 100, 0);
        spawnAni("aitemFX",0,30,0,"ANI_FOLLOW1",NULL(),NULL(),NULL());         
        break;
    
        case "iHP" : // life up
        case "cola" : // life up
        log(" \n Item: " + Name ); // output the item name only for debugging, comment this line later
        playsample(SFX2, 0, 120, 120, 100, 0);
        spawnAni("aitemFX",0,30,0,"ANI_IDLE",NULL(),NULL(),NULL());     
        break;
    
        case "iFMP" : // full power up
        log(" \n Item: " + Name ); // output the item name only for debugging, comment this line later
        playsample(SFX3, 0, 120, 120, 100, 0);
        spawnAni("aitemFX",0,30,0,"ANI_FOLLOW4",NULL(),NULL(),NULL());         
        break;
    
        case "iFHP" : // full life up
        log(" \n Item: " + Name ); // output the item name only for debugging, comment this line later
        playsample(SFX4, 0, 120, 120, 100, 0);
        spawnAni("aitemFX",0,30,0,"ANI_FOLLOW3",NULL(),NULL(),NULL());         
        break;
    
        case "iHPMP" : // life and power up
        log(" \n Item: " + Name ); // output the item name only for debugging, comment this line later
        changeentityproperty(hit, "mp", power+30);  // add 30 to entity power
        playsample(SFX5, 0, 120, 120, 100, 0);
        spawnAni("aitemFX",0,30,0,"ANI_FOLLOW2",NULL(),NULL(),NULL());         
        break;
    
        default : // in case of none of above
        log(" \n Item not on the list or error ); // output the item name only for debugging, comment this line later
        break;
   }
}
void spawnAni(void vName, float fX, float fY, float fZ, void Ani, float Vx, float Vy, float Vz)
{
    //spawnB (Generic spawner) + Specific animation + velocities
    //Damon Vaughn Caskey + Douglas Baldan
    //07/06/2007
    //
    //Spawns entity next to caller.
    //
    //vName: Model name of entity to be spawned in.
    //fX: X location adjustment.
    //fZ: Y location adjustment.
      //fY: Z location adjustment.

    void self = getlocalvar("self"); //Get calling entity.
    void vSpawn; //Spawn object.
    int  iDirection = getentityproperty(self, "direction");

    clearspawnentry(); //Clear current spawn entry.
      setspawnentry("name", vName); //Acquire spawn entity by name.

    if (iDirection == 0){ //Is entity facing left?               
          fX = -fX; //Reverse X direction to match facing.
    }

      fX = fX + getentityproperty(self, "x"); //Get X location and add adjustment.
      fY = fY + getentityproperty(self, "a"); //Get Y location and add adjustment.
      fZ = fZ + getentityproperty(self, "z"); //Get Z location and add adjustment.
 
    vSpawn = spawn(); //Spawn in entity.

    changeentityproperty(vSpawn, "position", fX, fZ, fY); //Set spawn location.
    changeentityproperty(vSpawn, "direction", iDirection); //Set direction.
        performattack(vSpawn, openborconstant(Ani));
    changeentityproperty(vSpawn, "velocity", Vx, Vy, Vz);

    return vSpawn; //Return spawn.
}

And I need to update that tutorial to use a forwarder someday, to same memory.
 
@Illusionista thanks for the advice and code examples!

I was trying to replicate the capability at a simpler level, was thinking to have the sound effect specific to the hero/char.

Sounds like I should just use the switch code provided in the tutorial. I will go try this next! = )
 
Also I keep thinking 'damagetaker' is the item being picked up?

And that 'self' was referencing the hero?

But seems my understanding is reversed. Self is actually the item?

Am I placing the didhitscript inclusion in the right place, should it go into the char.txt or the Gold.txt ?

Logically seems like it should go into the Gold.txt

didhitscript data/scripts/Item.c
 
Last edited:
Also I keep thinking 'damagetaker' is the item being picked up?

And that 'self' was referencing the hero?

But seems my understanding is reversed. Self is actually the item?
Take a look at the manual:

didhitscript {path}
Entity's hits another entity normally, or entity is an item type being retrieved.

self: Caller.
damagetaker: Recipient of attack or item.
damage: attack damage.
drop: knockdown power.
attacktype: attack type, see 'openborconstant'.
noblock: block break force of attack.
guardcost: Guardcost of attack.
jugglecost: Jugglecost of attack.
pauseadd: Pause value of attack.
blocked: Receiving entity did (1) or did not (0) block attack.

In this case, it's the item (self) who hits the player (damagetaker).

I was trying to replicate the capability at a simpler level,
I suggest you to use the code as it, just deleting the the CASES you don't need. Or even keep them as they are for now, since nothing bad will happens :)

was thinking to have the sound effect specific to the hero/char.
ah, that is a different story. This code takes the name of the item, not the name of the target.
You would need to adapt the code for that.
 
Thanks for the advice. I got it working using the original code as provided. I did have to put the 'DIDHITSCRIPT' inclusion into Gold.txt (ie: the item itself, which makes sense).

In the manual the wording here threw me off:

didhitscript {path}
Entity's hits another entity normally, or entity is an item type being retrieved.

self: Caller.
damagetaker: Recipient of attack or item. <---- made me think the Caller had to be a Player or Enemy, but overlooked it can be the Item itself
 
Back
Top Bottom