
EDuke32 Scripting "CON coding help"
#564 Posted 03 August 2010 - 11:51 AM
Anyway, new problem, well not really a problem but it would be handy if there were a solution.
Is there any way to "wake up" a sleeping actor once it's asleep? Setting its httimetosleep to anything other than 1 from another actor doesn't work. I'm guessing that's because when the actor is asleep it wont receive any form of commands, not even gamevar changes and only seems to check the hard coded way.
I know I can prevent an actor from going to sleep by having it change its httimetosleep while active, but to save performance I would like my actors to go to sleep now and again and would still like them to be controlled from other actors.
My actors are all "useractor notenemy" (in case that makes a difference from useractor enemy)
Is there any way?
This post has been edited by Chip: 03 August 2010 - 11:53 AM
#565 Posted 03 August 2010 - 12:03 PM
Chip, on Aug 3 2010, 12:51 PM, said:
Anyway, new problem, well not really a problem but it would be handy if there were a solution.
Is there any way to "wake up" a sleeping actor once it's asleep? Setting its httimetosleep to anything other than 1 from another actor doesn't work. I'm guessing that's because when the actor is asleep it wont receive any form of commands, not even gamevar changes and only seems to check the hard coded way.
I know I can prevent an actor from going to sleep by having it change its httimetosleep while active, but to save performance I would like my actors to go to sleep now and again and would still like them to be controlled from other actors.
My actors are all "useractor notenemy" (in case that makes a difference from useractor enemy)
Is there any way?
Here is the code I use. Typically the code is executed by a SHOTSPARK1 when it hits a wall (the idea being the enemies may see the bullet hitting and come to investigate). I guess it works ok. The monstflags variable is something I use for storing various monster attributes. Ifvarand monstflags 2048 == the monster is a smart type who notices things like bullets hitting walls.
state wakemon getactor[spriteid].picnum picnum switch picnum case LIZTROOP case LIZTROOPDUCKING case LIZTROOPJETPACK case LIZTROOPSHOOT case LIZTROOPONTOILET case LIZTROOPJUSTSIT case LIZTROOPRUNNING case OCTABRAIN case OCTABRAINSTAYPUT case DRONE case COMMANDER case COMMANDERSTAYPUT case TANK case PIGCOP case PIGCOPDIVE case PIGCOPSTAYPUT case LIZMAN case LIZMANSTAYPUT case LIZMANSPITTING case LIZMANJUMP case ROTATEGUN case BOSS1 case BOSS1STAYPUT case BOSS2 case BOSS3 case NEWBEAST case BOSS4 case BOSS4STAYPUT canseespr THISACTOR spriteid temp ifvare temp 1 { changespritestat spriteid 1 setactor[spriteid].httimetosleep 780 } break default break endswitch ends state wakeupmonsters headspritestat spriteid 2 whilevarn spriteid -1 { ifvarand actorvar[spriteid].monstflags 2048 state wakemon nextspritestat spriteid spriteid } ends
This post has been edited by DeeperThought: 03 August 2010 - 12:04 PM
#566 Posted 04 August 2010 - 01:21 PM
Thanks once more

This post has been edited by Chip: 04 August 2010 - 01:22 PM
#567 Posted 04 August 2010 - 01:26 PM
This post has been edited by DeeperThought: 04 August 2010 - 01:27 PM
#568 Posted 12 August 2010 - 10:24 PM
#569 Posted 13 August 2010 - 12:05 AM
MIKE SIMS, on Aug 12 2010, 11:24 PM, said:
Sure, just make some replacement art where the access panel is replaced by whatever you want. Or maybe you could do it without replacement art, by putting a colored sprite in front of the panel in the map. I would try messing around with the code only as a last resort, and only if you really know what you are doing.
#570 Posted 13 August 2010 - 12:36 AM
#571 Posted 13 August 2010 - 07:57 AM
TX, on Aug 13 2010, 01:36 AM, said:
But then the player would still be holding the keycard after the door opens.
#572 Posted 13 August 2010 - 09:01 AM
DeeperThought, on Aug 13 2010, 04:57 PM, said:
That's how it works in Doom, so you know what doors you can open since these doors are always locked after each time they close - preventing enemies from opening them.
Personally I wouldn't do this the way TX suggested for the purpose of enemies being able to open doors the moment you pick up the key. Instead I would make it so the player actor would always check the door / wall in front of him when space is hit - checking for a hitag (or even the lotag, actually that'll work better - give the keycard a lotag that matches all the doors' lotags it can open) on the door's sector determine what key would be needed.
But as for making the locked door open, well that is what I'll need to look into..... I have never tried anything like this so can't comment on exactly what to do but there could very well be a simple way to activate an ACTIVATOR and even lock it again or even a way to open a door regardless of locks. (Although useractors can open doors, completely ignoring locked MASTERSWITCHES.)
This post has been edited by Chip: 13 August 2010 - 09:16 AM
#573 Posted 13 August 2010 - 09:30 AM
Chip, on Aug 13 2010, 10:01 AM, said:
Personally I wouldn't do this the way TX suggested for the purpose of enemies being able to open doors the moment you pick up the key. Instead I would make it so the player actor would always check the door / wall in front of him when space is hit - checking for a hitag (or even the lotag, actually that'll work better - give the keycard a lotag that matches all the doors' lotags it can open) on the door's sector determine what key would be needed.
But as for making the locked door open, well that is what I'll need to look into..... I have never tried anything like this so can't comment on exactly what to do but there could very well be a simple way to activate an ACTIVATOR and even lock it again or even a way to open a door regardless of locks. (Although useractors can open doors, completely ignoring locked MASTERSWITCHES.)
If the only problem is monsters opening the doors, then just code them not to open the doors. That would be a lot easier than the stuff you are suggesting.
#574 Posted 13 August 2010 - 12:49 PM
#575 Posted 13 August 2010 - 01:00 PM
MIKE SIMS, on Aug 13 2010, 01:49 PM, said:
Yeah, I think useractors start running code before the player sees them. You can try making them actor instead of useractor, but keep in mind that they won't be considered enemies by the game (even if you code them to attack the player) and this leads to some hardcoded differences, in addition to throwing off the kill count. I would leave them useractor enemy but code them not to do anything after initializing until they can see the player.
#577 Posted 14 August 2010 - 05:55 AM
Putting something like this right at the top of the actor's code should work.
ifai 0
{
ai AIACTORDOSOMETIHNG
changespritestat THISACTOR 2
setactor[THISACTOR].httimetosleep 1
}
ifai 0 means the actor hasn't started up yet so all follwing code with those { } will be initiated once, just remember to set an AI within that block to break it out of the loop (my example was ai AIACTORDOSOMETIHNG)
changespritestat set to 2 will put the actor asleep and setting httimetosleep to 1 ensures it asleep.
The actor will automatically wake up upon seeing the player and will eventually fall back to sleep again if the player is not present for a while.
This post has been edited by Chip: 14 August 2010 - 05:58 AM
#578 Posted 15 August 2010 - 02:07 PM
This post has been edited by MIKE SIMS: 15 August 2010 - 02:09 PM
#579 Posted 16 August 2010 - 01:14 PM
#580 Posted 16 August 2010 - 04:54 PM
Awesomebob, on Aug 16 2010, 02:14 PM, said:
Very possible. Open up the game con and search "state checktroophit". Under the line "ifdead" in that state, put in this
ifspritepal 10 { espawn ACCESSCARD setactor[RETURN].pal 23 }
This code will make the basic liztroop spawn a yellow access card when he dies, if his pallet is 10 (dark red).
#581 Posted 24 August 2010 - 11:10 AM
#582 Posted 24 August 2010 - 11:15 AM
darkcaleb, on Aug 24 2010, 12:10 PM, said:
AFAIK a grappling gun has never been coded for Duke. Getting the physics and look of the rope and hook right would be a lot of work. It would be much easier to make a grappling beam, with designated grappling points, like in the Metroid Prime series.
#584 Posted 24 August 2010 - 02:40 PM
DeeperThought, on Aug 24 2010, 11:15 AM, said:
Would this be similar to the barnacle from half life opposing force (never played metroid)? Cause that sounds interesting.
This post has been edited by Awesomebob: 24 August 2010 - 02:46 PM
#585 Posted 25 August 2010 - 04:03 AM
#586 Posted 25 December 2010 - 09:37 AM
I have a tough problem with differentiating trails spawned by same kind of projectile. Here's what I'm trying to do :
* I'm trying to have my shotgun have ripper projectiles, the way I made it is similar to a railgun. It's "trails" do the damage, but to prevent from all trails doing damage I make it so that there's a variable to check if the target has taken damage from that set of rail trails. It is set to 0 in a short time so the target can get hit again.
* My problem => My shotgun has pellets and each pellet works in this logic. They spawn invisible trails to do the damage, with some limited range. Even if I'm too far (but still in trail's travel range) and even if one single pellet hits, it deals full damage of all pellets. I want to differentiate the trails of one pellet from those of other pellets, so I can make other pellets deal damage; also disabling the damage factor of all trails behind one of the pellets.
I'm sorry if I couldn't explain it better, but here's my code just in case :
state finishraildamage getactor[THISACTOR].owner owner //hitsprite ifvarn owner -1 { ifvarvarn owner hitsprite // making sure enemy doesn't hit itself { getactor[hitsprite].htextra DMG addvarvar DMG randomvar4 ifvare picnum UFORSAKEN { divvar DMG 4 mulvar DMG 3 } ifvare picnum ZOMBIER { setvar DMG -1 setvar htflag 1405 } ifvare picnum APLAYER { getplayer[THISACTOR].i ID ifvarvare ID owner { setvar DMG -1 setvar htflag 1405 } } setactor[hitsprite].htextra DMG ifactor FUSTRAIL ifvarg DMG -1 { getactor[hitsprite].extra DMG ifvarg DMG 0 sound LASGUNHIT } setactor[hitsprite].htpicnum htflag setvar returnvar1 1 } } ends state railhurtcode ifvarn returnvar1 1 { getactor[THISACTOR].x x getactor[THISACTOR].y y getactor[THISACTOR].sectnum TEMP getactor[THISACTOR].ang TEMPT sin my TEMPT cos mx TEMPT getactor[THISACTOR].z z getplayervar[THISACTOR].power_up POWERUPMODE hitscan x y z TEMP mx my 0 hitsect hitwall hitsprite hitx hity hitz CLIPMASK1 ifvarn hitsprite -1 { getactor[hitsprite].picnum picnum switch picnum case LIZTROOP case CDEMON case DEVIL case REVENANT case DEMON case CHAINGUNNER case CHAINGUNNER2 case ZOMBIEPLS case DOUBLEGUNNER case TANK case BOSS1 case BOSS2 case PAINE case LSOUL case ENLISTEE case BLOODSEEKER case ZCAPTAIN case SHADE case IONIMP case UFORSAKEN case EXTERMINATOR case ROBOTGUARD case CACODEMON case SHOTGUNZOMBIE case SENTINEL case FSPIDER case APLAYER case HEAVYTROOPER case SHADOWSHIELD case ZOMBIER case BEAST case SOULCUBE case BIGIMP case BRUISERDEMON getactorvar[hitsprite].hitbysrail temp3 ifvare temp3 1 nullop else { ifactor RIPPERTRAIL { setvar randomvar4 0 randvarvar randomvar4 returnvar2 // RANDOM DAMAGE mulvarvar randomvar4 returnvar3 // MULTIPLIER ifvare randomvar4 0 setvarvar randomvar4 returnvar4 // MIN DAMAGE ifvarand POWERUPMODE 16 mulvar randomvar4 2 setvar htflag SHOTGUNRIPPER state finishraildamage getactor[hitsprite].x mx getactor[hitsprite].y my getactor[hitsprite].z mz subvar mz 4096 espawn JIBS6 setactor[RETURN].x mx setactor[RETURN].y my setactor[RETURN].z mz setactorvar[hitsprite].hitbysrail 1 // There needs to be a variable for all types of rails, because then all trails would deal damage and it would be immense. } } break endswitch } } ends state resetrailstate // Reset the rail stuff as fast as possible getactorvar[THISACTOR].hitbysrail railtemp ifvare railtemp 1 { addvar railcount2 1 ifvarg railcount2 0 { setvar railcount2 0 setactorvar[THISACTOR].hitbysrail 0 } } ends defineprojectile SHOTGUNRIPPER PROJ_WORKSLIKE 1 defineprojectile SHOTGUNRIPPER PROJ_SOUND -1 defineprojectile SHOTGUNRIPPER PROJ_EXTRA 12 defineprojectile SHOTGUNRIPPER PROJ_TRAIL RIPPERTRAIL defineprojectile SHOTGUNRIPPER PROJ_TXREPEAT 45 defineprojectile SHOTGUNRIPPER PROJ_TYREPEAT 45 defineprojectile SHOTGUNRIPPER PROJ_TNUM 900 // defineprojectile SHOTGUNRIPPER PROJ_DECAL -1 defineprojectile SHOTGUNRIPPER PROJ_OFFSET 14354 useractor notenemy RIPPERTRAIL TOUGH cstat 32768 ifvarn countvar 1 { setvar returnvar2 28 setvar returnvar3 8 setvar returnvar4 16 state railhurtcode setvar countvar 1 } else killit enda
This post has been edited by XThX2: 25 December 2010 - 09:37 AM
#587 Posted 27 December 2010 - 03:51 PM
XThX2, on Dec 25 2010, 09:37 AM, said:
I have a tough problem with differentiating trails spawned by same kind of projectile. Here's what I'm trying to do :
* I'm trying to have my shotgun have ripper projectiles, the way I made it is similar to a railgun. It's "trails" do the damage, but to prevent from all trails doing damage I make it so that there's a variable to check if the target has taken damage from that set of rail trails. It is set to 0 in a short time so the target can get hit again.
I'm back from my little vacation.
I don't feel like reading all that code, but based on your description it seems to me you could just use a timer. When something gets hit, check the victim's variable and don't do damage unless it is 0. If nonzero, cause the damage and set the variable to the desired timer length. Make the victim count down the timer in its own code.
#588 Posted 26 February 2011 - 09:56 AM
This is a relatively simple example that will allow the player to manually reload the pistol, like in DukePlus.
First, we'll declare the necessary gamevars...
gamevar PISTOLAMMO 0 1 gamevar KICKBACK 0 1 gamevar PWEAPON 0 1 gamevar PISTOLMAGAZINE 0 1 gamevar PERPLAYER1 0 1 gamevar WEAPON1_CLIP 0 0 // this last gamevar disable's the game's automatic reloading
then, under the APLAYER line in the game.con, we'll store our static variables that will be used, and code in a few functions that the reload is supposed to perform...
actor APLAYER MAXPLAYERHEALTH PSTAND 0 0 getplayer[THISACTOR].curr_weapon PWEAPON // the player's current weapon getplayer[THISACTOR].kickback_pic KICKBACK // the frame of animation the player's weapon is at getplayer[THISACTOR].ammo_amount 1 PISTOLAMMO // the player's pistol ammo ifvare PWEAPON 1 { // if the player has the pistol selected... ifvarl PISTOLMAGAZINE 1 { // and his magazine count is at zero... getplayer[THISACTOR].weapon_pos PERPLAYER1 ifvarn PERPLAYER1 0 break // if he has a weapon that's lowering off screen, break else { ifvarl PISTOLAMMO 1 break else setplayer[THISACTOR].reloading 1 setplayer[THISACTOR].kickback_pic 4 } } // otherwise, if he has ammo for the pistol, start the reloading anim ifvare KICKBACK 5 { // if the reloading animation is on its second frame... ifvarg PISTOLAMMO 11 { setvar PISTOLMAGAZINE 12 } // if the player has at least twelve pistol rounds left, then set his magazine counter to a full magazine else setvarvar PISTOLMAGAZINE PISTOLAMMO } } // otherwise set the magazine counter equal to his remaining ammo
Next we'll access the DOFIRE event, which is called if/when a weapon fires its projectile...
onevent EVENT_DOFIRE ifvare PWEAPON 1 { // if the player has the pistol selected when he fires a projectile... ifvarl PISTOLMAGAZINE 1 break else { subvar PISTOLMAGAZINE 1 } } // subtract 1 from the magazine count, unless it's already at zero endevent
In order to perform a reload, you'll need to assign it a key, which means booting out one of the game's more useless functions. In this example, it'll be the TURNAROUND key...
definegamefuncname 36 RELOAD // rename it, so it'll appear as RELOAD in the control settings menu onevent EVENT_TURNAROUND setvar RETURN -1 // disable the event ifvare PWEAPON 1 { // if the player has the pistol armed ifvare PISTOLMAGAZINE 12 break // and his magazine is full, break else ifvarvare PISTOLMAGAZINE PISTOLAMMO break // if his magazine is equal to his pistol ammo, break else setplayer[THISACTOR].reloading 1 setplayer[THISACTOR].kickback_pic 4 } // otherwise, start the reloading sequence endevent
Because the game's original reloading system is disabled, the player won't load in a clip when the game starts up. We'll take care of that, as well as another potential glitch, by accessing the RESET_PLAYER event.
onevent EVENT_RESETPLAYER setvar PISTOLMAGAZINE 0 // if the player was reset to his starting position (i.e, he died), reset the clip amount to zero. ifvare PWEAPON 1 { // if he has the pistol selected when he loads into the map... setplayer[THISACTOR].reloading 1 setplayer[THISACTOR].kickback_pic 4 } // start the reloading sequence. endevent
The code that was under the APLAYER line made sure the player will automatically reload the pistol if his magazine's empty (and of course, he has the ammunition to do so), however he'll still shoot the projectile even if the magazine's empty, unless the firing key is disabled appropriately...
onevent EVENT_PRESSEDFIRE //when the player presses the fire button... ifvare PWEAPON 1 { // and he has the pistol armed... ifvarl PISTOLMAGAZINE 1 { setvar RETURN -1 } } // if his magazine is at zero, disable the firing key endevent
And lastly, we're going to want the player to know what his magazine count's at, so we'll put a small counter next to the ammo amount...
onevent EVENT_DISPLAYREST digitalnumberz 2930 280 175 PISTOLMAGAZINE 0 0 0 0 0 xdim ydim 50000 // display the magazine count at a slightly smaller size (50000) next to the ammo endevent
This post has been edited by EmericaSkater: 26 February 2011 - 09:57 AM
#589 Posted 26 February 2011 - 11:41 AM
One thing that people should understand is that by looking at tutorials like this they can learn a lot more than just how to add the feature in question. The basics of manipulating variables, members of the player struct, using game events and drawing to the screen are all there. There's also stuff like that in older tutorials.
That's why I get impatient with people who keep posting about one little thing they are trying to do, when I see no evidence that they are actively trying to learn by looking at existing code in released CON files, tutorials, etc.
Good job!
#590 Posted 26 February 2011 - 12:39 PM
#591 Posted 26 February 2011 - 10:51 PM
DeeperThought, on Aug 24 2010, 01:15 PM, said:
In fact I have some old sloppy code laying around that does something like that.
One thing you could do though if you just wanted a quick grapple like say, Batman's hooks, even if you sucked at math you could just code an invisible trail on a projectile and move the player to the sprites.
#592 Posted 01 March 2011 - 03:02 AM
I perfectly included the code, no errors or whatsoever.
#593 Posted 01 March 2011 - 03:28 AM
A) Did you copy the code to a con file that's been modified? If so, there's no guarantee the code will work with other code that's already been added (not without some extra modification, at least)
B ) When you copied the code beneath the APLAYER line, did you erase the APLAYER line itself? Two APLAYER lines could cause some problems if not an error itself.
C) When you copied the code, did you erase the notes that were slashed out on the sides? Those were only meant to help you understand what each step was doing, but if they were copied in with the code, they could possibly cause some kinks.
If the magazine isn't being reloaded, then something must be going wrong beneath the APLAYER line, because that's the only line in the code that actually reloads the magazine. If none of that helps, post your con file, and I'll take a look at it. Rest assure, though, I've done enough testing to know that it works.
This post has been edited by EmericaSkater: 01 March 2011 - 03:28 AM