Empyre Posted May 31, 2017 (edited) I am trying to make a fancy camera script. It works sometimes, but not reliably. Here's the script: #include "zcommon.acs" script "EmpViewCamera" (int CamID) { Thing_Stop (0); ChangeCamera (CamID,0,0); SetPlayerProperty (0,ON,PROP_TOTALLYFROZEN); SetActorProperty (0, APROP_Invulnerable,TRUE); HudMessage (s:"Press Use to return to your own view.";HUDMSG_PLAIN,1,CR_YELLOW,1.5,0.5,0.0); While (GetPlayerInput(-1,INPUT_BUTTONS) & BT_USE) { Delay(4); }; While (!(GetPlayerInput(-1,INPUT_BUTTONS) & BT_USE)) { Delay(4); }; Hudmessage (s:" ";HUDMSG_PLAIN,1,CR_YELLOW,1.5,0.5,1.0/35+1); ChangeCamera (0,0,0); SetPlayerProperty (0,OFF,PROP_TOTALLYFROZEN); Delay (105); SetActorProperty (0, APROP_Invulnerable,FALSE); } The first while loop is waiting until the player releases use, and the second one is waiting until the player presses use again, but the script doesn't always work when the player uses the switch in the attached UDMF test map. How can I make this work reliably? MAP13.zip Edited June 1, 2017 by Empyre Added [Resolved] to thread title. 0 Quote Share this post Link to post
scifista42 Posted May 31, 2017 You're calling the script via ACS_ExecuteAlways, which allows multiple instances of the same script running at the same time. When the player presses use for the second time to cancel the camera effect, he's still facing the switch at the moment, so he immediately activates the switch another time, which runs another instance of the script before the first instance even terminates. 0 Quote Share this post Link to post
Empyre Posted May 31, 2017 That's awkward. I want to use the script on multiple switches in maps that get played in coop, so there is a possibility of more than one player using it at once, which is why I used ACS_ExecuteAlways. Is there a way out of this dilemma? I just now thought of the idea of having the player press fire instead. While totally frozen, they can't fire their weapon, but GetPlayerInput can still detect whether they're pressing fire. The problem I see with that idea is that even though I won't be telling the player to press use, they still can, which would re-activate the switch. If I use ACS_Execute, I would have to have a separate script for each switch (right?), and some maps have quite a few, and I do want the camera to be reusable BTW, each switch will also do something else only once, like lowering a wall or opening a door or raising stars, and the camera is there to show what the switch does, and using it again shows where the switch did something. Right now, I am just using the ChangeCamera line special, set to revert to the player's view when they move, but that confuses players. They press use and fire to try to get out of the camera and I have to tell them in player chat to move, if I am there. Also, it leaves them vulnerable while they are standing there at the switch. Also, they often don't stop moving to use the switch, so they never see the camera at all. I have seen this done correctly, so I know it can be done, for example in iu-part5, but the ACS source code is removed so I can't see how he did it. 0 Quote Share this post Link to post
Empyre Posted May 31, 2017 I thought of another rather-involved idea. I could give the players unique TIDs, and use those as an index into for an array of Booleans, which would be automatically initialized to FALSE, I believe. At the beginning of the script, I'd check if that player's entry in the array is TRUE, and if so, exit the script immediately. Then set it to TRUE, do what the script does, and set it to FALSE at the end of the script. 0 Quote Share this post Link to post
scifista42 Posted May 31, 2017 (edited) The same effect could be implemented slightly more elegantly with inventory items. You would define a DECORATE inventory item like this: actor cameraDummy : Inventory { inventory.maxamount 1 } Then use CheckInventory at the beginning of your script to check if the player has this inventory item. If he does, the script will do nothing. If he doesn't, the script will use GiveInventory to give the item to the player, run the camera effect + whatever, and use TakeInventory to take the item from the player when the script finishes. Edited May 31, 2017 by scifista42 0 Quote Share this post Link to post
Empyre Posted June 1, 2017 Thanks to your help, it is working flawlessly now. Here is the final version of the script, in case somebody might find it useful some day. script "EmpViewCamera" (int CamID) { If(CheckInventory("EmpCameraIsInUse")) { Terminate; } GiveInventory("EmpCameraisInUse",1); Thing_Stop (0); ChangeCamera (CamID,0,0); SetPlayerProperty (0,ON,PROP_TOTALLYFROZEN); SetActorProperty (0, APROP_Invulnerable,TRUE); HudMessage (s:"Press Use to return to your own view.";HUDMSG_PLAIN,1,CR_YELLOW,1.5,0.5,0.0); While (GetPlayerInput(-1,INPUT_BUTTONS) & BT_USE) { Delay(4); } While (!(GetPlayerInput(-1,INPUT_BUTTONS) & BT_USE)) { Delay(4); } Hudmessage (s:" ";HUDMSG_PLAIN,1,CR_YELLOW,1.5,0.5,1.0/35+1); ChangeCamera (0,0,0); SetPlayerProperty (0,OFF,PROP_TOTALLYFROZEN); TakeInventory("EmpCameraIsInUse",1); Delay (105); If(!CheckInventory("EmpCamersIsInUse")) { SetActorProperty (0, APROP_Invulnerable,FALSE); } } I put Emp to the beginning of stuff to make sure that I have unique names that won't step on the toes of any gameplay mod that might be loaded with the maps. I removed the inventory item before the 3-second delay so the player can use the switch again immediately, and check for the item again before removing invulnerability in case the player has indeed used the switch again. I switched back to using use instead of fire because when the player switches back to his own view, he is still pressing fire, and at best he wastes some ammo and at worst he damages himself. 0 Quote Share this post Link to post
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.