
EDuke32 Scripting "CON coding help"
#2633 Posted 20 December 2020 - 02:48 PM
#2634 Posted 20 December 2020 - 03:18 PM
Reaper_Man, on 18 December 2020 - 11:17 AM, said:
You can theoretically hack "seekplayer" to navigate towards any other actor, due to how it interacts with HoloDuke. From VM_AlterAng:
int const spriteAngle = vm.pSprite->ang; int const holoDukeSprite = vm.pPlayer->holoduke_on; // NOTE: looks like 'owner' is set to target sprite ID... vm.pSprite->owner = (holoDukeSprite >= 0 && cansee(sprite[holoDukeSprite].x, sprite[holoDukeSprite].y, sprite[holoDukeSprite].z, sprite[holoDukeSprite].sectnum, vm.pSprite->x, vm.pSprite->y, vm.pSprite->z, vm.pSprite->sectnum)) ? holoDukeSprite : vm.pPlayer->i; int const goalAng = (sprite[vm.pSprite->owner].picnum == APLAYER) ? getangle(vm.pActor->lastv.x - vm.pSprite->x, vm.pActor->lastv.y - vm.pSprite->y) : getangle(sprite[vm.pSprite->owner].x - vm.pSprite->x, sprite[vm.pSprite->owner].y - vm.pSprite->y);
This bit of code sets goalAng to the angle to face the target, where the target is either the player or the HoloDuke, specifically the actor stored on "holoduke_on" player member. Meaning you can do this:
// holoduke_on resets to -1 when holoduke_amount hits 0, so always keep the holoduke_amount at full setplayer[THISACTOR].holoduke_amount 2400 ifaction 0 { findnearsprite 100 32768 ACTOR_TARGET ifvare ACTOR_TARGET -1 killit setplayer[THISACTOR].holoduke_on ACTOR_TARGET action A_ACTOR move M_ACTOR seekplayer break }
This actor now is using "seekplayer" to seek out something other than the player.
Unfortunately, the catch is the "cansee" check, meaning that this only works if there's already line of sight between the actor calling this and the faked HoloDuke, rendering this mostly useless.
lol that's cool - but it also sounds like something unintended that's definitely going to break in some future eduke32 version

#2635 Posted 20 December 2020 - 03:23 PM
Sangman, on 20 December 2020 - 03:18 PM, said:

Why wait, it's already pre-broken because seekplayer is garbage and the hack also depends on line of sight.
#2636 Posted 20 December 2020 - 06:25 PM
Danukem, on 20 December 2020 - 03:23 PM, said:
seekplayer is garbage. For anyone who has never looked in the source code, all it essentially does is change the angle of the actor by a random value between -128 and +128 degrees to the nearest direction of the target every few tics. That's it. Doom's target search was even more advanced than this, where enemies would walk until they hit a wall, and then trace the walls in the direction nearest the target. This is why Doom's enemies can manage to get themselves out of rooms that Duke's can't. I highly recommend a custom approach for target search when writing your own enemy AI, and use seekplayer only as a worst case fallback.
This post has been edited by Reaper_Man: 20 December 2020 - 06:27 PM
#2637 Posted 21 December 2020 - 12:31 AM
Danukem, on 20 December 2020 - 02:48 PM, said:
I have a machinegun, wich is stationary that shoots bursts if the player is close and in its line of sight, but this works on its own and looks silly as a result, so i want an enemy to 'operate' it meaning that the machinegun only fires if the enemy is close and alive. If it was the player i could use ifpdistl and ifpalive or something but afaik there is no such command for enemies.
I could make it into one large sprite and cactor enemy if the machinegun is destroyed but that would make the sprite very large and cause clipping issues
#2638 Posted 21 December 2020 - 12:37 AM
#2639 Posted 21 December 2020 - 12:50 AM
#2640 Posted 21 December 2020 - 06:35 AM

Make a small sector behind the machine gun and put a stayput version of the enemy in that sector. Then use the findnearactor feature in the gun actor so that if the enemy gets killed first it is no longer found and the gun stops shooting. And if the gun gets "killed" first have that cactor the enemy into the non-stayput version. The only problem is if you need the gun to fire in any direction and not just mostly forward. It would still work but the enemy won't follow the gun direction. Also you would have to tag this enemy somehow different from the rest so they don't all get affected. Maybe a different pal.
This post has been edited by Mark: 21 December 2020 - 06:50 AM
#2641 Posted 22 December 2020 - 10:33 AM
Mark, on 21 December 2020 - 06:35 AM, said:

Make a small sector behind the machine gun and put a stayput version of the enemy in that sector. Then use the findnearactor feature in the gun actor so that if the enemy gets killed first it is no longer found and the gun stops shooting. And if the gun gets "killed" first have that cactor the enemy into the non-stayput version. The only problem is if you need the gun to fire in any direction and not just mostly forward. It would still work but the enemy won't follow the gun direction. Also you would have to tag this enemy somehow different from the rest so they don't all get affected. Maybe a different pal.
yeah, you can press the nuke symbol and the tank will auto destruct

i was thinking allong those line, but most eduke programming is beyond my capabilities at the moment.. for now i have a small sector and an stayput enemy, and made the gun destructable. placed a small wall crack and use that to blow the entire area killing everything. a cop out but for the moment it looks half decent. in the future i will make a custom dedicated machine gunner so the game can look for that actor and ignore all others. making the gun shoot in a 45 degree arc relative to the original angle is something to be added.
so how would i implement the findnearactor, something like findnearactor myactor 1, if 1 run code if 0 dont?
right now i have this coded, basically i hacked the floofflame code.
define MG42NPC 3951 define MG42ANPC 3952 // the a is for ambience, this gun is placed outside the playable areas to make the world seem bigger than it really is. action MG42STAND 0 1 5 1 0 action MG42FIRES 5 1 5 1 0 action MG42ASTAND -1 1 5 1 0 action MG42AFIRE 4 1 5 1 0 useractor notenemy MG42NPC 100 MG42STAND ifaction MG42FIRES { ifactioncount 2 shoot SHOTSPARK1 sound MG42FIRE ifrnd 64 { shoot FIRELASER } ifactioncount 16 action MG42STAND } ifaction MG42STAND ifrnd 8 // was 4 { action MG42FIRES resetactioncount else action MG42STAND } ifhitweapon { debris SCRAP1 2 ifdead { sound VENT_BUST debris SCRAP1 10 killit } } enda useractor notenemy MG42ANPC 100 MG42ASTAND // and the ambience version, basically the same but wont require an owner to run. ifaction MG42AFIRE { ifactioncount 2 sound MG42FIRE ifrnd 64 { shoot FIRELASER } ifactioncount 16 action MG42ASTAND } ifaction MG42ASTAND ifcansee ifp palive ifcanshoottarget ifrnd 16 // was 4 { action MG42AFIRE resetactioncount else action MG42ASTAND } ifhitweapon { debris SCRAP1 2 ifdead { sound VENT_BUST debris SCRAP1 10 killit } } enda
so i'd probably add something like
gamevar MGNEAR 0 0 findnearactor MGGUNNER 512 MGNEAR onevent MGNEAR 1 run code ( action MGSTAND, wich will loop in intervalls ) else action MGABANDONED or something ( same action as MGSTAND but wont run the shooting code )
i could also run a check if the gun is still 'alive' and if not callactor MGgunner roaming or something so he can abandon his position and change to a regular soldier.
This post has been edited by jimbob: 22 December 2020 - 10:48 AM
#2642 Posted 22 December 2020 - 12:56 PM

This post has been edited by Mark: 22 December 2020 - 03:19 PM
#2643 Posted 22 December 2020 - 03:33 PM
#2644 Posted 22 December 2020 - 04:06 PM
#2645 Posted 22 December 2020 - 04:29 PM
setvar DISTANCE 2147483647 // Maximum integer value, you should use some sort of realistic maximum range setvar ACTORTARGET -1 setvar ACTORI 0 for ACTORI sprofstat 1 { ifvare sprite[ACTORI].picnum MYACTOR { ldist ACTORCHECK THISACTOR ACTORI ifvarvarl ACTORCHECK DISTANCE { setvarvar DISTANCE ACTORCHECK setvarvar ACTORTARGET ACTORI } } } ifvare ACTORTARGET -1 killit // Couldn't find a valid target, goodbye
This post has been edited by Reaper_Man: 22 December 2020 - 06:33 PM
#2646 Posted 22 December 2020 - 04:49 PM
#2647 Posted 22 December 2020 - 04:52 PM
#2648 Posted 22 December 2020 - 05:15 PM
Reaper_Man, on 22 December 2020 - 04:29 PM, said:
setvar DISTANCE 2147483647 // Maximum integer value, you should use some sort of realistic maximum range setvar ACTORTARGET -1 setvar ACTORI 0 for ACTORI allsprites { ifvare sprite[ACTORI].picnum MYACTOR { ldist ACTORCHECK THISACTOR ACTORI ifvarvarl ACTORCHECK DISTANCE { setvarvar DISTANCE ACTORCHECK setvarvar ACTORTARGET ACTORI } } } ifvare ACTORTARGET -1 killit // Couldn't find a valid target, goodbye
If no, do nothing by calling an idle action
If yes, run active action wich runs/triggers the shooting code.
And if the operator dies, i planned on using callactor to call a different actor to lower the MGNEAR flag to zero.
#2649 Posted 23 December 2020 - 02:15 PM
Danukem, on 22 December 2020 - 04:49 PM, said:
Another option, if it's only one specific enemy type that you want to check for, is to appendevent EVENT_SPAWN and add it to an array if it is that actor type. Then loop that array... it's a micro optimization in jimbob's scenario I'm guessing but just throwing that out there.
#2650 Posted 23 December 2020 - 02:48 PM

yes, there wil be one dedicated enemy that occupies the fixed MG position, and will be in various positions on itself ( prone, standing, crouching ) wich means i cant make it one large sprite, given the size of the machinegun, and the size of the enemy it would make more than half of the sprite seethrough causing lots of clipping issues and a ton of useless data being wasted.
#2651 Posted 08 January 2021 - 11:56 AM
state checkoccupied findnearsprite MGGUNNERSTAND ONMGDIST ONMG ifvarn ONMG -1 { action MG42ASTAND break } // run code as normal else { action MG42ADONOTHING break } ends useractor notenemy MG42ANPC 100 MG42ASTAND ifaction MG42AFIRE { ifactioncount 2 state checkoccupied shoot SHOTSPARK1 sound MG42FIRE ifrnd 64 { shoot FIRELASER } ifactioncount 16 action MG42ASTAND } ifaction MG42ASTAND state checkoccupied ifcansee ifp palive ifcanshoottarget // only fire if can see the player ifrnd 16 // was 4 { ifvarn ONMG -1 action MG42AFIRE resetactioncount else ifvarn ONMG -1 action MG42ASTAND else action MG42ADONOTHING } ifhitweapon { debris SCRAP1 2 ifdead { sound VENT_BUST debris SCRAP1 10 killit } } ifaction MG42ADONOTHING { } enda
added a few checks, for whatever reason it occasionally still went to the fire action and fire once or twice.
This post has been edited by jimbob: 08 January 2021 - 12:40 PM
#2652 Posted 30 January 2021 - 01:55 PM
and i also dont know how to make a gun eject a clip, an actual clip this time, i want my M1 garand to eject the enbloc clip at the start of the reload. any help would be very much appericiated

i have my MG42 shells set up as this
define MG42SHELL 3650 define MG42FS 3651 action MG42SFLY 0 4 1 1 4 action MG42FS1 -1 1 1 useractor notenemy MG42SHELL 0 MG42SFLY // ejected brass enda useractor notenemy MG42FS 0 MG42FS1 0 randomangle // shells on the floor fall sizeat 3 3 cstat 32 ifcount 300 killit enda defineprojectile 3650 PROJ_WORKSLIKE 6210 defineprojectile 3650 PROJ_XREPEAT 3 defineprojectile 3650 PROJ_YREPEAT 3 defineprojectile 3650 PROJ_VEL 150 defineprojectile 3650 PROJ_DROP -100 defineprojectile 3650 PROJ_BOUNCES -1 defineprojectile 3650 PROJ_CLIPDIST 0 defineprojectile 3650 PROJ_HITRADIUS -1 defineprojectile 3650 PROJ_BSOUND -1 defineprojectile 3650 PROJ_ISOUND -1 // defineprojectile 3650 PROJ_TOFFSET -30 // defineprojectile 365 PROJ_CSTAT 130 // defineprojectile 365 PROJ_RANGE 40 defineprojectile 3650 PROJ_SPAWNS MG42FS defineprojectile 3650 PROJ_EXTRA 0 defineprojectile 3650 PROJ_OFFSET 240
This post has been edited by jimbob: 30 January 2021 - 01:57 PM
#2653 Posted 31 January 2021 - 04:29 AM
gamevar TEMPANG 0 0 onevent EVENT_DOFIRE ife player[].curr_weapon CHAINGUN_WEAPON { ezshoot -1024 MG42SHELL geta[].ang TEMPANG sub TEMPANG 512 seta[RETURN].ang TEMPANG } endevent
In a non-player actor, you don't use an event. Use shoot CHAINGUN or whatever bullet they are shooting, followed by the angle stuff. I deliberately used "geta[].ang" instead of "getp[].ang" to avoid any errors if you port it to other actors.
#2654 Posted 31 January 2021 - 08:42 AM
it seems to work, just changed the angle to 1536 ( 3 * 512 ) to make the shells fly off to the right, wuch works. but it doesnt fire, and immediatly goed to the reload animation :/
This post has been edited by jimbob: 31 January 2021 - 10:07 AM
#2655 Posted 31 January 2021 - 11:41 AM
jimbob, on 31 January 2021 - 08:42 AM, said:
Oh whoops! I forgot that setting RETURN in that event messes with the actual gun firing. Set RETURN to 0 at the end of the event code and that should fix it:
gamevar TEMPANG 0 0 onevent EVENT_DOFIRE ife player[].curr_weapon CHAINGUN_WEAPON { ezshoot -1024 MG42SHELL geta[].ang TEMPANG sub TEMPANG 1536 seta[RETURN].ang TEMPANG set RETURN 0 } endevent
#2656 Posted 31 January 2021 - 01:43 PM

#2657 Posted 10 February 2021 - 07:45 AM

Another question: Can I change pal and stuff of LASERLINE that active/placed tripmines shoot out?
And: Will a pal change of something cause a desync in multiplayer if it only happens for one of the players? I'm considering changing how stuff LOOKS depending on what player ID you have.
Thanks in advance!
#2658 Posted 10 February 2021 - 01:08 PM
#2659 Posted 11 February 2021 - 07:45 AM
Danukem, on 10 February 2021 - 01:08 PM, said:
Damn, that was EXACTLY what I needed. Everything looks so normal I was confused the first time I turned them on. Looking at players in dark areas lights them up tho, and tripmines on mode 2 are visible too. Thanks!
#2660 Posted 11 February 2021 - 12:18 PM
#2661 Posted 12 February 2021 - 10:54 AM
Danukem, on 11 February 2021 - 12:18 PM, said:
Haven't thoroughly tested, we ain't DM'ing on maps with water. A 1 minute test, however, showed that setgamepalette 1 will probably make everything look normal underwater, but special stuff like players and tripmine lasers will still light up when goggles are on (just like above water/setgamepalette 0). In general, setgamepalette works properly on everything except the few things that has a special interaction with the goggles (if the goggles are on) - in other words: nothing looks weird.
Question: How do I "redefine" certain actors to do stuff I want? For example when I spawn OOZFILTER (1079) ingame I see nothing, but if I spawn 1080 (also oozfilter but without animation) it appears in the game. In my CON file I have a simple block: actor 1079 { do stuff... } enda. Some actors seem to be reserved but they are usually the more interesting ones...
This post has been edited by thisbecasper: 12 February 2021 - 01:32 PM
#2662 Posted 13 February 2021 - 09:21 AM
thisbecasper, on 12 February 2021 - 10:54 AM, said:
Question: How do I "redefine" certain actors to do stuff I want? For example when I spawn OOZFILTER (1079) ingame I see nothing, but if I spawn 1080 (also oozfilter but without animation) it appears in the game. In my CON file I have a simple block: actor 1079 { do stuff... } enda. Some actors seem to be reserved but they are usually the more interesting ones...
why would you want to repurpose existing actors? you can use useractor for new actors unless you are using duke1.3 wich i consider obsolete.