Facebook Twitter YouTube Frictional Games | Forum | Privacy Policy | Dev Blog | Dev Wiki | Support | Gametee


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Script Help [SOLVED] Using a Single Crowbar on Multiple Doors
AGP Offline
Senior Member

Posts: 448
Threads: 45
Joined: Dec 2012
Reputation: 23
#1
[SOLVED] Using a Single Crowbar on Multiple Doors

All righty, so basically I'm trying to break against the traditional crowbar-breaks-after-one-use shenanigans and I have at least four doors that will require using the crowbar, three being the regular mansion door and the last being boards covering a door.

I've been able to successfully script for a single door, but now that I have to add to it, I have no idea where to really start. While I know that I can use the Variables to help condense the scripts, I'm not entirely sure how to go about it or if with also needing to script for boards, if that might makes things a little different.

____________________________________________________________
Finished Script:

-Be sure to check the names thoroughly
-I'm leaving the 4 in the script, but you do not necessarily have to leave it at 4

Thank you to the guys who contributed to this thread to get this script working![/code]

void OnStart()
{  
    for(int i = 1; i <= 4; i++) {
    AddUseItemCallback("crowbarondoors", "crowbar", "Door_"+i, "UseCrowbarOnDoor", false);
    AddEntityCollideCallback("Joint_Door_"+i, "AreaBreak_"+i, "BreakDoor", true, 1);
    }
}
    
void UseCrowbarOnDoor(string &in asItem, string &in asEntity)
{
    RemoveItem(asItem);
    PlaySoundAtEntity("", "player_crouch.snt", "Player", 0.05, false);
    AddTimer(asEntity, 0.2, "TimerPlaceCrowbar");

    SetLocalVarString("CrowbarDoor", asEntity);
}
    
void TimerPlaceCrowbar(string &in asTimer)
{
    SetEntityActive("Joint_"+asTimer, true);
    PlaySoundAtEntity("", "puzzle_place_jar.snt", asTimer, 0, false);
}
    
void BreakDoor(string &in asParent, string &in asChild, int alState)
{
    SetEntityActive(asParent, false);
  
    SetSwingDoorLocked(GetLocalVarString("CrowbarDoor"), false, false);
    SetSwingDoorClosed(GetLocalVarString("CrowbarDoor"), false, false);
    SetSwingDoorDisableAutoClose(GetLocalVarString("CrowbarDoor"), true);
    
    AddPropImpulse(GetLocalVarString("CrowbarDoor"), 0, 0, 3, "world");

    CreateParticleSystemAtEntity("", "ps_hit_wood.ps", "AreaEffect_"+asChild, false);
    PlaySoundAtEntity("", "break_wood_metal", "AreaEffect_"+asChild, 0, false);
    
    GiveSanityBoostSmall();
    
    PlayMusic("10_puzzle01.ogg", false, 0.7, 0.1, 10, false);
    
    AddTimer("", 0.1, "TimerPushDoor");

    GiveItem("crowbar", "Puzzle", "crowbar", "crowbar.tga", 1);
}

void TimerPushDoor(string &in asTimer)
{
        AddPropImpulse(GetLocalVarString("CrowbarDoor"), -4, 2, 1, "world");
        AddTimer("", 1.1, "TimerDoorCanClose");
}
    
void TimerDoorCanClose(string &in asTimer)
{
        SetSwingDoorDisableAutoClose(GetLocalVarString("CrowbarDoor"), false);
}

(This post was last modified: 09-22-2014, 09:10 PM by AGP.)
09-21-2014, 08:13 PM
Find
Neelke Offline
Senior Member

Posts: 668
Threads: 82
Joined: Apr 2013
Reputation: 26
#2
RE: Using a Single Crowbar on Multiple Doors

You can try to check what entity the crowbar is being used at.

if(asEntity == "NameOfDoor")
{
     //Setup the stuff you want to happen for this door
}
else if(asEntity == "ThisNameOfDoor")
{
     //Setup the other door here
}

Basically, you do all four doors in one single use item script.
At least I hope this is what youre looking for.

Derp.
(This post was last modified: 09-21-2014, 08:21 PM by Neelke.)
09-21-2014, 08:20 PM
Find
AGP Offline
Senior Member

Posts: 448
Threads: 45
Joined: Dec 2012
Reputation: 23
#3
RE: Using a Single Crowbar on Multiple Doors

Yeah, that's basically what I'm looking for, to be able to use the one item for all four functions, but I'm not entirely sure how to use the script you posted.

09-21-2014, 08:48 PM
Find
Darkfire Offline
Senior Member

Posts: 371
Threads: 22
Joined: May 2014
Reputation: 15
#4
RE: Using a Single Crowbar on Multiple Doors

I'd suggest writing a script without the usage of normal names, but with asEntity and asItem instead. That way you can use the same thing few times. I'm not sure if it's possible thouh, haven't done that.

PS. I'm proud of ya for not breaking the crowbar in half. It's such a crap Tongue

09-21-2014, 09:37 PM
Find
Neelke Offline
Senior Member

Posts: 668
Threads: 82
Joined: Apr 2013
Reputation: 26
#5
RE: Using a Single Crowbar on Multiple Doors

Basically you write a regular use item function and put all these things in there. Here's a breef example.

void UseCrowbarOnDoor(string &in asEntity, string &in asItem)
{
      if(asEntity == "mansion_1")
      {
           SetPropHealth(asEntity); //Break the door (for some reason)
      }
      else if(asEntity == "mansion_2")
      {
           SetEntityActive("crowbar", true); //Some simple activate entity
      }
}

void OnStart()
{
     for(int i=1; i<=4; ++i) AddUseItemCallback("crowbarondoors", "crowbar", "mansion_"+i, "UseCrowbarOnDoor", false);
}

Go ahead and ask me if theres anything you don't entirely understand about the script.

Derp.
09-21-2014, 09:47 PM
Find
AGP Offline
Senior Member

Posts: 448
Threads: 45
Joined: Dec 2012
Reputation: 23
#6
RE: Using a Single Crowbar on Multiple Doors

Oh! I think I get what you mean!! (Not gonna lie, that makes me feel super awesome since I'm still learning the craft of scripting).

I'll test it out and let you know how it goes.

_____________________________________________________________
EDIT:

I don't think I'm doing this correctly. This is the script that I'm running on a test map (to prevent any unsavory things from happening to the rest of the script file).

There are probably some other errors in here as I had previously used this to run another test and I don't think I quite found all the leftovers of that.

void OnStart()
{  
    AddUseItemCallback("", "Crowbar_1", "asEntity", "UseCrowbarOnDoor", true);
    AddEntityCollideCallback("Joint", "AreaBreak", "BreakDoor", true, 1);
}
    
void UseCrowbarOnDoor(string &in asItem, string &in asEntity)
{
    if(asEntity == "Door_1")
      {
        PlaySoundAtEntity("", "player_crouch.snt", "Player", 0.05, false);
        AddTimer(asEntity, 0.2, "TimerPlaceCrowbar");
      }
      else if(asEntity == "Door_2")
      {
        PlaySoundAtEntity("", "player_crouch.snt", "Player", 0.05, false);
        AddTimer(asEntity, 0.2, "TimerPlaceCrowbar");
      }
}
    
void TimerPlaceCrowbar(string &in asTimer)
{
        SetEntityActive("Joint", true);
        PlaySoundAtEntity("", "puzzle_place_jar.snt", asTimer, 0, false);
}
    
void BreakDoor(string &in asParent, string &in asChild, int alState)
{
        SetEntityActive("Joint", false);
        SetEntityActive("Broken", true);
  
        SetSwingDoorLocked("Door_x", false, false);
        SetSwingDoorClosed("Door_x", false, false);
        SetSwingDoorDisableAutoClose("Door_x", true);
    
        AddPropImpulse("Door_x", 0, 0, 3, "world");
    
        CreateParticleSystemAtEntity("", "ps_hit_wood.ps", "AreaEffect", false);
        PlaySoundAtEntity("", "break_wood_metal", "AreaEffect", 0, false);
    
        GiveSanityBoostSmall();
    
        PlayMusic("10_puzzle01.ogg", false, 0.7, 0.1, 10, false);
    
        AddTimer("", 0.1, "TimerPushDoor");
}
    
void TimerPushDoor(string &in asTimer)
{
        AddPropImpulse("Door_x", -4, 2, 1, "world");
        AddTimer("", 1.1, "TimerDoorCanClose");
}
    
void TimerDoorCanClose(string &in asTimer)
{
        SetSwingDoorDisableAutoClose("Door_x", false);
}

(This post was last modified: 09-21-2014, 10:40 PM by AGP.)
09-21-2014, 10:24 PM
Find
FlawlessHappiness Offline
Posting Freak

Posts: 3,980
Threads: 145
Joined: Mar 2012
Reputation: 171
#7
RE: Using a Single Crowbar on Multiple Doors

You're getting closer but not all the way.

I'm very sorry about this but
WALL OF TEXT INCOMING!
I felt inspired to help you ^^

See, in the beginning you wrote:

PHP Code: (Select All)
void OnStart()
{  
    
AddUseItemCallback("""Crowbar_1""asEntity""UseCrowbarOnDoor"true);
    
AddEntityCollideCallback("Joint""AreaBreak""BreakDoor"true1);


You used "asEntity" as the entity. This will not work, and there's a simple explanation.

asEntity, is referring to the parameters in a function.
Fx. when using a collide-function you write:

void CollideFunction(string &in asParent, string &in asChild, int alState)

Notice all the things inside the paranthesises! ^^^^^
You have 3 different parameters here: asParent, asChild and alState.
asParent and asChild has "string" in front of them, because you have to use a word.
alState has "int" in front of it, because it's a whole number, without decimals (1, 0, or -1)

But you wrote "asEntity" in voidOnStart(), which has nothing in the paranthesises. That's why it won't work.

Neelke wrote this:
PHP Code: (Select All)
void OnStart()
{
for(
int i=1i<=4; ++iAddUseItemCallback("crowbarondoors""crowbar""mansion_"+i"UseCrowbarOnDoor"false);


for(int i=1; i<=4; ++i) is used to create a loop.
The first number "int i=1;" says that it has to start at 1.
The second number "i<=4;" says that it has to end at 4.

So by writing "mansion_"+i in the entities-space he selects all the mansion doors named, mansion_1, mansion_2, mansion_3, and mansion_4.

He did this, to save time and space. To understand it better, what he's actually doing is writing this:
PHP Code: (Select All)
void OnStart()
{
AddUseItemCallback("crowbarondoors""crowbar""mansion_1""UseCrowbarOnDoor"false);
AddUseItemCallback("crowbarondoors""crowbar""mansion_2""UseCrowbarOnDoor"false);
AddUseItemCallback("crowbarondoors""crowbar""mansion_3""UseCrowbarOnDoor"false);
AddUseItemCallback("crowbarondoors""crowbar""mansion_4""UseCrowbarOnDoor"false);


Do you see?
He selects all the doors, but he uses the same crowbar. This means that the function "UseCrowbarOnDoor" will call when he uses "crowbar" on either of the selected doors.

In your script, you have chosen to name all the doors "Door_1", "Door_2", and so on...
Remember to rename these.

Now to the function.

PHP Code: (Select All)
void UseCrowbarOnDoor(string &in asItemstring &in asEntity)
{
    if(
asEntity == "Door_1")
      {
        
PlaySoundAtEntity("""player_crouch.snt""Player"0.05false);
        
AddTimer(asEntity0.2"TimerPlaceCrowbar");
      }
      else if(
asEntity == "Door_2")
      {
        
PlaySoundAtEntity("""player_crouch.snt""Player"0.05false);
        
AddTimer(asEntity0.2"TimerPlaceCrowbar");
      }


In this function you are only checking for 2 of the doors. If i recall correctly, you had 4. So the script is not done before you've done it to all 4 doors.
BUT! Since you are now learning about "asEntity" how about we optimize the script a bit?

PHP Code: (Select All)
void UseCrowbarOnDoor(string &in asItemstring &in asEntity)
{
RemoveItem("asItem");
PlaySoundAtEntity("""player_crouch.snt""Player"0.05false);
AddTimer(asEntity0.2"TimerPlaceCrowbar");

SetLocalVarString("CrowbarDoor"asEntity);


Since you are using "asEntity" in the AddTimer it doesn't matter which door you are using it on, since it will always pick the door you are using it on anyway. (Because the door you are using the crowbar on will automatically be "asEntity").

Notice that I added an extra line about setting a "string" to asEntity. This will be useful later. I'm just storing the information. Just read along.

Also notice that I'm removing the crowbar. This is so that the player won't go and use the crowbar on another area, while the joint it active, because then suddenly 2 joints will be active, meaning 2 crowbars. And the player will be like: "Wut? How did i do that?"

Now something a little more difficult appears.

PHP Code: (Select All)
void TimerPlaceCrowbar(string &in asTimer)
{
        
SetEntityActive("Joint"true);
        
PlaySoundAtEntity("""puzzle_place_jar.snt"asTimer0false);


You have chosen only to set "Joint" active. Since there's only 1 object named "Joint" in the map, and it's only placed at 1 of the doors, what will happen at the 4 other doors?
Good question. Right now, the answer is: The same "Joint" will go active again. Which is, (what I'm pretty sure) not what you want.

So instead, let's go and rename all the "Joints" into "Joint_Door_1" if it's at "Door_1", "Joint_Door_2" if it's at "Door_2". And so on...
Hopefully you get the idea now.

This means that we can now write:

PHP Code: (Select All)
void TimerPlaceCrowbar(string &in asTimer)
{
        
SetEntityActive("Joint_"+asTimertrue);
        
PlaySoundAtEntity("""puzzle_place_jar.snt"asTimer0false);


This is because "asTimer" was previously set to be "asEntity", which was the door we were using the crowbar on, in the first case: "Door_1". This means that the object that goes active is "Joint_Door_1", just as we renamed it to.

So what happens when the Joint collides with the area?

PHP Code: (Select All)
void BreakDoor(string &in asParentstring &in asChildint alState)
{
        
SetEntityActive("Joint"false);
        
SetEntityActive("Broken"true);
  
        
SetSwingDoorLocked("Door_x"falsefalse);
        
SetSwingDoorClosed("Door_x"falsefalse);
        
SetSwingDoorDisableAutoClose("Door_x"true);
    
        
AddPropImpulse("Door_x"003"world");
    
        
CreateParticleSystemAtEntity("""ps_hit_wood.ps""AreaEffect"false);
        
PlaySoundAtEntity("""break_wood_metal""AreaEffect"0false);
     
        
GiveSanityBoostSmall();
     
        
PlayMusic("10_puzzle01.ogg"false0.70.110false);
     
        
AddTimer(""0.1"TimerPushDoor");


This is not general enough, since the exact same thing will happen, as the above where, only the first Joint will be deactivated.
So let's touch it up a bit:

PHP Code: (Select All)
void BreakDoor(string &in asParentstring &in asChildint alState)
{
        
SetEntityActive(asParentfalse);
  
        
SetSwingDoorLocked(GetLocalVarString("CrowbarDoor"), falsefalse);
        
SetSwingDoorClosed(GetLocalVarString("CrowbarDoor"), falsefalse);
        
SetSwingDoorDisableAutoClose(GetLocalVarString("CrowbarDoor"), true);
    
        
AddPropImpulse(GetLocalVarString("CrowbarDoor"), 003"world");
    
        
CreateParticleSystemAtEntity("""ps_hit_wood.ps""AreaEffect"false);
        
PlaySoundAtEntity("""break_wood_metal""AreaEffect"0false);
     
        
GiveSanityBoostSmall();
     
        
PlayMusic("10_puzzle01.ogg"false0.70.110false);
     
        
AddTimer(""0.1"TimerPushDoor");

GiveItem("crowbar""Puzzle""crowbar""crowbar.tga"1);


Ok, so what did I edit?

I changed the SetEntityActive entity to asParent, because now we're just setting the Joint inactive.
And now you wanted to add a broken crowbar? Why is that exactly? Because since you're going to be using it again, it shouldn't just break should it?
I deleted that line.

And here comes the special thing. I'm now pulling back the information I stored earlier by using GetLocalVarString("CrowbarDoor"). This way, it'll remember what door it was we were using it on, because it we set it that way.

Also, notice that in the end I'm giving the player the crowbar again, so that he can use it again.

This became rather long. I hope you understand! Smile


EDIT:
Oh right. And in the last 2 functions:

PHP Code: (Select All)
void TimerPushDoor(string &in asTimer)
{
        
AddPropImpulse("Door_x", -421"world");
        
AddTimer(""1.1"TimerDoorCanClose");
}
     
void TimerDoorCanClose(string &in asTimer)
{
        
SetSwingDoorDisableAutoClose("Door_x"false);


Just put "GetLocalVarString("CrowbarDoor")" instead of "Door_x", because "Door_x" isn't anything you have in the editor, and therefore nothing will happen.

It will look like this:

PHP Code: (Select All)
void TimerPushDoor(string &in asTimer)
{
        
AddPropImpulse(GetLocalVarString("CrowbarDoor"), -421"world");
        
AddTimer(""1.1"TimerDoorCanClose");
}
     
void TimerDoorCanClose(string &in asTimer)
{
        
SetSwingDoorDisableAutoClose(GetLocalVarString("CrowbarDoor"), false);


Trying is the first step to success.
(This post was last modified: 09-21-2014, 11:51 PM by FlawlessHappiness.)
09-21-2014, 11:42 PM
Find
AGP Offline
Senior Member

Posts: 448
Threads: 45
Joined: Dec 2012
Reputation: 23
#8
RE: Using a Single Crowbar on Multiple Doors

Oh my goodness, Flawless!! Thank you so much! I knew something needed to happen with the +i, but thought it was the _x (facepalm). And it all made complete sense to me, so thank you thank you thank you!

Unfortunately though, I'm trying to run this on my test map, and I can't even use the crowbar on the door. I'm wondering if maybe some of the names don't match up, but this has become such a scrambled mess in my own head, I'm probably just looking it right over.

Here is the revised .hps:

Spoiler below!
void OnStart()
{  
    for(int i=1; i<=4; ++i) AddUseItemCallback("crowbarondoors", "crowbar", "mansion_"+i, "UseCrowbarOnDoor", false);
    AddEntityCollideCallback("Joint", "AreaBreak", "BreakDoor", true, 1);
}
    
void UseCrowbarOnDoor(string &in asItem, string &in asEntity)
{
    RemoveItem("asItem");
    PlaySoundAtEntity("", "player_crouch.snt", "Player", 0.05, false);
    AddTimer(asEntity, 0.2, "TimerPlaceCrowbar");

SetLocalVarString("CrowbarDoor", asEntity);
}
    
void TimerPlaceCrowbar(string &in asTimer)
{
        SetEntityActive("Joint_"+asTimer, true);
        PlaySoundAtEntity("", "puzzle_place_jar.snt", asTimer, 0, false);
}
    
void BreakDoor(string &in asParent, string &in asChild, int alState)
{
        SetEntityActive(asParent, false);
  
        SetSwingDoorLocked(GetLocalVarString("CrowbarDoor"), false, false);
        SetSwingDoorClosed(GetLocalVarString("CrowbarDoor"), false, false);
        SetSwingDoorDisableAutoClose(GetLocalVarString("CrowbarDoor"), true);
    
        AddPropImpulse(GetLocalVarString("CrowbarDoor"), 0, 0, 3, "world");
    
        CreateParticleSystemAtEntity("", "ps_hit_wood.ps", "AreaEffect", false);
        PlaySoundAtEntity("", "break_wood_metal", "AreaEffect", 0, false);
    
        GiveSanityBoostSmall();
    
        PlayMusic("10_puzzle01.ogg", false, 0.7, 0.1, 10, false);
    
        AddTimer("", 0.1, "TimerPushDoor");

GiveItem("crowbar", "Puzzle", "crowbar", "crowbar.tga", 1);
}

void TimerPushDoor(string &in asTimer)
{
        AddPropImpulse(GetLocalVarString("CrowbarDoor"), -4, 2, 1, "world");
        AddTimer("", 1.1, "TimerDoorCanClose");
}
    
void TimerDoorCanClose(string &in asTimer)
{
        SetSwingDoorDisableAutoClose(GetLocalVarString("CrowbarDoor"), false);
}


And here are the assets we are starting out with:

Crowbar: Crowbar_1
Door: Door_1
Joint: Joint_Door_1
Areas: AreaBreak_1 (for where the joint hits to call the script)
AreaEffect_1 (for the particles as the door opens)

So the question I have is: do I need to do the same variable technique for the areas as well? Is there anything else that I am missing?


________________________________________________________________
EDIT:

Nvm! I realized that some of the more obvious names were not changed!

Now, the crowbar is not showing up after using the crowbar on the door. The sounds is played, but there is no crowbar!

Revised script is as so:

Spoiler below!
void OnStart()
{  
    for(int i=1; i<=4; ++i) AddUseItemCallback("crowbarondoors", "Crowbar_1", "Door_"+i, "UseCrowbarOnDoor", false);
    for(int i=1; i<=4; ++i) AddEntityCollideCallback("Joint_Door_"+i, "AreaBreak_"+i, "BreakDoor", true, 1);
}
    
void UseCrowbarOnDoor(string &in asItem, string &in asEntity)
{
    RemoveItem("asItem");
    PlaySoundAtEntity("", "player_crouch.snt", "Player", 0.05, false);
    AddTimer(asEntity, 0.2, "TimerPlaceCrowbar");

    SetLocalVarString("CrowbarDoor", asEntity);
}
    
void TimerPlaceCrowbar(string &in asTimer)
{
    SetEntityActive("Joint_Door_"+asTimer, true);
    PlaySoundAtEntity("", "puzzle_place_jar.snt", asTimer, 0, false);
}
    
void BreakDoor(string &in asParent, string &in asChild, int alState)
{
    SetEntityActive(asParent, false);
  
    SetSwingDoorLocked(GetLocalVarString("CrowbarDoor"), false, false);
    SetSwingDoorClosed(GetLocalVarString("CrowbarDoor"), false, false);
    SetSwingDoorDisableAutoClose(GetLocalVarString("CrowbarDoor"), true);
    
    AddPropImpulse(GetLocalVarString("CrowbarDoor"), 0, 0, 3, "world");

    CreateParticleSystemAtEntity("", "ps_hit_wood.ps", "AreaEffect", false);
    PlaySoundAtEntity("", "break_wood_metal", "AreaEffect", 0, false);
    
    GiveSanityBoostSmall();
    
    PlayMusic("10_puzzle01.ogg", false, 0.7, 0.1, 10, false);
    
    AddTimer("", 0.1, "TimerPushDoor");

    GiveItem("crowbar", "Puzzle", "crowbar", "crowbar.tga", 1);
}

void TimerPushDoor(string &in asTimer)
{
        AddPropImpulse(GetLocalVarString("CrowbarDoor"), -4, 2, 1, "world");
        AddTimer("", 1.1, "TimerDoorCanClose");
}
    
void TimerDoorCanClose(string &in asTimer)
{
        SetSwingDoorDisableAutoClose(GetLocalVarString("CrowbarDoor"), false);
}


(This post was last modified: 09-22-2014, 02:59 AM by AGP.)
09-22-2014, 01:04 AM
Find
Mudbill Offline
Muderator

Posts: 3,881
Threads: 59
Joined: Apr 2013
Reputation: 179
#9
RE: Using a Single Crowbar on Multiple Doors

On your SetEntityActive line within TimerPlaceCrowbar, try doing "Joint_"+asTimer instead. If your joint name is Joint_Door_1 and asTimer is the same as your door name, then doing what you have will result in Joint_Door_Door_1.

Just trace it back if you're unsure. asTimer = internal name from the AddTimer function calling, which is a few lines above. That internal name = asEntity of the UseCrowbarOnDoor function. asEntity in the function creating that callback is "Door_"+i, so "Door_1" for example, depending on the door.

(This post was last modified: 09-22-2014, 07:07 AM by Mudbill.)
09-22-2014, 07:03 AM
Find
AGP Offline
Senior Member

Posts: 448
Threads: 45
Joined: Dec 2012
Reputation: 23
#10
RE: Using a Single Crowbar on Multiple Doors

That fixed the crowbar appearing. Now all it does is go back and forth. The door is not breaking.

09-22-2014, 07:12 AM
Find




Users browsing this thread: 2 Guest(s)