Duke4.net Forums: EDuke32 Scripting - Duke4.net Forums

Jump to content

  • 124 Pages +
  • « First
  • 119
  • 120
  • 121
  • 122
  • 123
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

EDuke32 Scripting  "CON coding help"

User is offline   Danukem 

  • Duke Plus Developer

#3601

View PostReaper_Man, on 11 December 2024 - 03:10 PM, said:

I'd have to double check but I am 99% certain that "notenemy" useractors start awake and never go asleep.


You are half right. Yes, they do start awake but they will go to sleep and quite quickly too if they are far away from and not in view of the player when the map starts. And after that they follow the rules of any other actor about falling asleep / waking up.
1

User is online   Mark 

#3602

My biggest takeaway from ReaperMan's code review and suggestions was that the use of while loops should be avoided if possible for performance reasons. I wasn't sure what a while or for loop looked like so I googled it. From what I can discern with my limited understanding, I use while loops quite extensively and if I read correctly its been a common practice in mods for years.

I haven't a clue how to change over. One example of a while loop IIRC. A useractor waiting for a keyboard input while performing some action like walking/moving. The code is looping and waiting for an ifhitspace command. Or waiting for ifpdistl to reach a certain value before performing another action. If those are indeed while loops what would be a for loop example?
0

User is offline   dwtietz 

#3603

View PostMark, on 12 December 2024 - 05:57 AM, said:

My biggest takeaway from ReaperMan's code review and suggestions was that the use of while loops should be avoided if possible for performance reasons. I wasn't sure what a while or for loop looked like so I googled it. From what I can discern with my limited understanding, I use while loops quite extensively and if I read correctly its been a common practice in mods for years.

I haven't a clue how to change over. One example of a while loop IIRC. A useractor waiting for a keyboard input while performing some action like walking/moving. The code is looping and waiting for an ifhitspace command. Or waiting for ifpdistl to reach a certain value before performing another action. If those are indeed while loops what would be a for loop example?


https://wiki.eduke32.com/wiki/For
0

User is online   Reaper_Man 

  • Once and Future King

#3604

I wouldn't worry about it too much. Unless you are specifically using EDuke while loops - and by that I mean these things https://wiki.eduke32.com/wiki/While - then you don't need to worry about it. I'm sure whatever you found on google was technically correct and accurate, in a broad sense about the concept of a code loop, but without the context of how your script actually runs in the game, it's probably going to put you down an incorrect path. There's no way that you use while loops in your CON scripts to do things like waiting for ifhitspace, if you did then your code would never work and you'd just lock up the game.

Like I said, post whatever code you might be worried about if you think you're using while loops in a bad way, otherwise the other stuff I mentioned is probably more relevant to 90% of scripts.
0

User is online   Mark 

#3605

I guess I just misinterpreted what I read about the loops. I don't have any code lines with "whilexxx" in them but it looked like they were acting like a while loop according to the googled description of what one is. I shan't lose sleep over it then. Thanks.

My coding is very simplistic so maybe any slight performance hit isn't an issue. But I thought it couldn't hurt to try changing to for loops if I had the skill for it.

This post has been edited by Mark: 12 December 2024 - 07:42 AM

0

User is online   eniojr 

#3606

After countless attempts to add JUMPAD, LADDER, MANTLING and DODGE effects, I only had success with JUMPAD (the effect related to you jumping high when you step on a certain floor in a certain sector, represented by the letter J in the image). First, I looked for all the codes I could related to the movement mechanics linked to jumping and climbing. I found a lot of them. I put them in a customized .CON file to work with the others from the Legacy mod and also other customized ones that I created myself, but that don't interfere here. I started trying to add JUMPAD because right away I saw that of all the movement effects it seemed to be the simplest and most obvious to find the necessary codes and adjust them to work with the mod I'm using as a base. After so much trial and error, with the help of an AI assistant, I managed to create the effect. At first I started with errors, but then I managed to add a forward momentum and make the jump higher than the Dukeplus, which I used this effect as a base.

I'm basically trying to add Dukeplus's movement effects to Legacy. In other words, the JUMPAD effect works successfully!

Now my focus is on the stairs. I've tried everything, even with the help of my artificial assistant, but I'm still just going around in circles, not knowing how to make this effect work in Legacy. I put all the events and states I could find in the script in USERPLUS.CON, PLAYERPLUS.CON and DUKEPLUS.CON. I'm not sure, but I suspect that some code or other escaped my notice in these files, or there may be specific errors that I still don't have a clue about. I also tried to make the mantling and dodge effects, but without success. Out of desperation I even added onevent EVENT_JUMP and others of the sort, but still couldn't do it. There's even the pythagoras state, but without success. Another problem could be the order of the codes, but I don't have a clear clue about that. There are even codes within the states and events that may be related to things that I don't intend to add to the mod. But as I'm afraid of changing the code too much and ending up doing something wrong, I left such codes.

I tried to make this work for DAYS!

One thing that really made it difficult for me was the fact that code for the same mechanic seems to be spread across multiple files. That's why I always prefer to put everything related to something in a single file. The day I make a real mod, I'll put each type of thing in its own file, so I can organize myself better and avoid conflicts and confusion. But unfortunately, sharing code between files is something that is common in game mods, unfortunately, even more so when it comes to complex mechanics of effects and movement. For someone like me (newbie in coding) who wants to extract a particular effect or function, it gets complicated and very frustrating!

Here is a picture of how the icons related to the effects look in Mapster32. "J" is the JUMPAD, while "L" is the ladder effect.

The way the icons are on the map is exactly like on the Dukeplus effects test map.

Posted Image

And now, the code (that sucks, so prepare yourself) :lol: :

Because the script is BIG, I'll separate in parts.

Note: At least on Legacy and on my computer, there were no compilation errors. The desired effects just didn't occur.

/////////////////////////////////////////////

Part 1: Definitions and variations

// LADDER.CON - Advanced Player Movement Mechanics

// Global Configuration Flags
define MANTLING YES
define DODGING YES
define FREERUNNER YES
define REALRUNNING YES
define MANTCHECK 6
define MANTDIST 480
define DODGE_IMPULSE_MULTIPLIER 2  
define DODGE_DISTANCE 640  

// DEFINES FOR RUNNING: THESE DO NOTHING UNLESS REALRUNNING IS ON
define SPEED1 45000 // the speed that you start at when you begin to run
define SPEED2TIME 30 // the number of ticks of acceleration before reaching RUNNINGSPEED
define RUNACCEL 256 // the rate of acceleration between SPEED1 and SPEED2

define LADDER 2951
define MOVEMENT 2952
define LADDER_CLIMB_SPEED -256      
define LADDER_DETECT_DIST 480       

define LADDER_STATE_NONE 0
define LADDER_STATE_CLIMBING 1
define LADDER_STATE_DISMOUNTING 2

define pforward 1
define pbackward 2

gamevar cannonid -1 1
gamevar sleeping 0 1
gamevar numallies 0 0
gamearray ptrails 100
gamevar ptrailtimer 0 1
gamevar dpsounds YES 0 
gamevar menunag 1 1
gamevar nomenu 0 0
gamevar nagpos 900 1
gamevar menutoggle 0 1
gamevar ONCAR 0 1

gamevar timer 0 0
gamevar canmantle MANTLING 0
gamevar mantling 0 1
gamevar mantwait 0 1
gamevar mantwaittime 0 1
gamevar mantcheck 0 1
gamevar mantz 0 1
gamevar jumped 0 1
gamevar backview 0 1
gamevar holding -1 1
gamevar pickup 0 1
gamevar holdingpic 0 1
gamevar drinksoda 0 1 
gamevar monstflags 0 2
gamevar hitag 0 2
gamevar lotag 0 2
gamevar spriteid 0 0
gamevar monstatus 0 2
gamevar target -1 2

gamevar candodge DODGING 0
gamevar dodge 0 1
gamevar botdodge 0 2
gamevar dodgeagain 0 1
gamevar dodgeang 0 1
gamevar nofalldamage 0 1 

gamevar ftap 0 1
gamevar fpresstime 0 1
gamevar btap 0 1
gamevar bpresstime 0 1
gamevar ltap 0 1
gamevar lpresstime 0 1
gamevar rtap 0 1
gamevar rpresstime 0 1
gamevar fhold 0 1
gamevar bhold 0 1
gamevar lhold 0 1
gamevar rhold 0 1

gamevar mx 0 0
gamevar my 0 0
gamevar mz 0 0
gamevar initx 0 2
gamevar inity 0 2
gamevar initz 0 2

gamevar walljump 0 1
gamevar jumptap 0 1
gamevar jumpadxvel 0 1
gamevar onladder 0 1
gamevar topladder 0 2
gamevar laddervel 0 1
gamevar lastladderx 0 1
gamevar lastladdery 0 1
gamevar laddersound -1 1

gamevar scaled NO 0
gamevar doubled NO 0
gamevar onblock 0 1
gamevar bits 0 1
gamevar thrust 0 1
gamevar extbits 0 1
gamevar fpress 0 1
gamevar bpress 0 1
gamevar mysector -1 2
gamevar mywall -1 2
gamevar underwater 0 2

gamevar xvel 0 0
gamevar yvel 0 0
gamevar zvel 0 0
gamevar tempc 0 0
gamevar tempd 0 0
gamevar tempe 0 0
gamevar zdist 0 0
gamevar xydist 0 0
gamevar xydist2 0 0
gamevar angvar 0 0

gamevar canseeplayer 0 2
gamevar canshootplayer 0 2
gamevar mysin 0 1  
gamevar mycos 0 1 
gamevar hitsector 0 1  
gamevar hitwall 0 1   
gamevar hitwall2 0 1
gamevar nextsector 0 1
gamevar hitsprite -1 1 
gamevar scannedsprite -1 1
gamevar hitx 0 2  
gamevar hity 0 2
gamevar hitz 0 2
gamevar clipmask 4294901808 0
gamevar hp 0 2

gamevar slowrunaccel REALRUNNING 0
gamevar pspeed 0 1
gamevar camshake 0 1
gamevar runcount 0 1
gamevar runflag 0 1
gamevar strafedir 0 1
gamevar laststrafedir 0 1
gamevar forbackdir 0 1
gamevar lastforbackdir 0 1
gamevar oposxv 0 1 // velocities from last tick
gamevar oposyv 0 1
gamevar oposzv 0 1
gamevar offground 0 1 // counter
gamevar weight 0 2

gamevar activator 0 2
gamevar initshade 0 2
gamevar playerally 0 2
gamevar pal 0 2
gamevar peractor1 0 2
gamevar peractor2 0 2
gamevar peractor3 0 2
gamevar fallflag 0 2
gamevar peractor4 0 2
gamevar peractor5 0 2
gamevar peractor6 0 2
gamevar peractor7 0 2
gamevar target2 -1 2
gamevar intensity 0 2
gamevar mtype 0 2
gamevar countvar 0 2
gamevar countvarb 0 2
gamevar myspawner -1 2
gamevar teleported 0 2
gamevar digx 0 1
gamevar digy 0 1
gamevar digz 0 1
gamevar orientation 0 1
gamevar shade 0 1

gamevar superkicking 0 1
gamevar superkickdone 0 1
gamevar spinkick 0 1
gamevar reversekick 0 1
gamevar kicktarg -1 1
gamevar kickimpact 0 1 
define KENERGY 780 
gamevar kickenergy KENERGY 1

action PSTAND     0   1   5   1  1


/////////////////////////////////////////////

Part 2: Pythagoras and JUMPAD codes (that seemed to work somehow)

state pythagoras

setvarvar xydist x
subvarvar xydist hitx
mulvarvar xydist xydist
setvarvar tempb y
subvarvar tempb hity
mulvarvar tempb tempb
addvarvar xydist tempb
sqrt xydist xydist

ends

/////////////////////////////////////////////

eventloadactor JUMPAD
    readgamevar scaled
    getactor[THISACTOR].extra monstflags
    ifvare monstflags -1 setvar monstflags 0
    
    getactor[THISACTOR].lotag lotag
    getactor[THISACTOR].hitag hitag
    
    // Default hitag if not set
    ifvare hitag 0 setvar hitag 640
    
    // Initialize velocity components
    getactor[THISACTOR].xvel initx
    getactor[THISACTOR].yvel inity
    ifvare inity 0 setvar inity 26
    
    getactor[THISACTOR].zvel initz
    mulvar initz -8
	
    ifvare scaled YES
    {
        // More controlled scaling
        mulvar initx 1.5  // Less aggressive horizontal scaling
        mulvar initz 2    // More vertical boost
    }

    // Ensure minimum and maximum velocity limits
    ifvarg initx 1024 setvar initx 1024
    ifvarg initz 512 setvar initz 512
    
    // Optional scaling for jump pad
    ifvare scaled YES
    {
        mulvar initx 2
        mulvar initz 3
        divvar initz 2
    }
    ifvare candodge YES
    {
        ifvarn jumpadxvel 0
        {
            mulvarvar xvel jumpadxvel
            mulvarvar yvel jumpadxvel
        }
        
        getincangle dodgeang angvar sprite[spriteid].ang
    }
enda

/////////////////////////////////////////////

// Jump Pad Activation Logic
useractor notenemy JUMPAD 0
    ifvare DODGING NO break   // Global dodge disable
    ifvarn lotag 1 break

    cstat 32768
    getplayer[THISACTOR].i spriteid
    ldist xydist THISACTOR spriteid
    
    // Distance-based jump pad activation
    ifvarvarl xydist hitag
    {
        getplayer[THISACTOR].falling_counter temp
        
        // Falling counter logic
        ifvarg temp 8
        {
            ifpdistg 1536 setvar temp 0
        }
        else
        {
            ifpdistl 1024 setvar temp 1
            else ifpdistl 8192 ifvarn dodge 0 setvar temp 1
            else setvar temp 0
        }
        
        // Jump pad activation
        ifvarn temp 0
        {
            getplayer[THISACTOR].i spriteid
            getactor[spriteid].z mz
            subvar mz 8192
            setactor[spriteid].z mz
            
            getplayer[THISACTOR].posz z
            subvar z 8192
            setplayer[THISACTOR].posz z
            
            setplayer[THISACTOR].jumping_counter 0
            setplayer[THISACTOR].jumping_toggle 0
            setplayer[THISACTOR].poszv initz
			
            getplayer[THISACTOR].ang angvar
            cos xvel angvar
            sin yvel angvar
            
            mulvar xvel 256  
            mulvar yvel 256  
            
            setplayer[THISACTOR].posxv xvel
            setplayer[THISACTOR].posyv yvel
            
            getactor[THISACTOR].ang dodgeang
            setvarvar dodge inity
            setvarvar jumpadxvel initx
            
            setplayer[THISACTOR].falling_counter 0
            setvar nofalldamage 1 
            soundonce LAUNCHSND
        }
    }
    ifvare candodge YES
    {
        ifvarn dodge 0
        {
            setvarvar jumpadxvel initx
            mulvar jumpadxvel DODGE_IMPULSE_MULTIPLIER
            
            divvar initz 2
        }
    }
enda


/////////////////////////////////////////////

Part 3: Codes related to ladder (the only thing seemed to work was related to extra value that made "L" sprite invisible. The rest... nothing!)

eventloadactor LADDER
{
    getactor[THISACTOR].extra monstflags
    setactor[THISACTOR].cstat 32768      
    setactor[THISACTOR].extra -1
    getactor[THISACTOR].hitag hitag
    getactor[THISACTOR].lotag lotag
    
    setvar monstatus 0
    setvar mtype 0
    setvar myspawner -1
    
    setactor[THISACTOR].clipdist 32
    setactor[THISACTOR].xrepeat 32
    setactor[THISACTOR].yrepeat 32
}
enda

/////////////////////////////////////////////

state laddercheck
{
    getplayer[THISACTOR].i spriteid
    
    ifvarn onladder 0 break
    
    setvar temp 0
    whilevarn temp 16384
    {
        getactor[temp].picnum picnum
        ifvare picnum LADDER ifvarvarn temp THISACTOR
        {
            ldist xydist temp spriteid
            ifvarl xydist LADDER_DETECT_DIST
            {
                getactor[temp].z mz
                getplayer[THISACTOR].posz z
                
                ifp pducking subvar z 4096
                
                ifvarvarg z mz
                {
                    addvar mz 16384  
                    ifvarvarl z mz   
                    {
                        setvarvar myspawner temp
                        setvar mtype 1
                        setvarvar topladder mz
                        getactor[temp].x lastladderx
                        getactor[temp].y lastladdery
                        break
                    }
                }
            }
        }
        addvar temp 1
    }
}
ends

/////////////////////////////////////////////

state laddercode
{
    ifvare onladder 0 break
    setvar mantling 0
    setvar dodge 0
    setvar walljump 0
    setplayer[THISACTOR].horiz 0
    
    ifaction PSTAND nullop else action PSTAND
    setplayer[THISACTOR].falling_counter 0
    
    ifvare fpress 1 
    {
        setvar laddervel LADDER_CLIMB_SPEED
        soundonce DUKE_GRUNT
    }
    else ifvare bpress 1
    {
        setvar laddervel 256
        soundonce DUKE_GRUNT
    }
    else  
    {
        setvar laddervel 0
        setplayer[THISACTOR].posxv 0
        setplayer[THISACTOR].posyv 0
        setplayer[THISACTOR].posx lastladderx
        setplayer[THISACTOR].posy lastladdery
    }
    setplayer[THISACTOR].poszv laddervel
    
    getplayer[THISACTOR].posz z
    ifvarvarg z topladder
    {
        setvar onladder 0
        break
    }
    ifp pjumping
    {
        setvar onladder 0
        setvar laddervel -512
    }
    else
    {
        subvar onladder 1
    }
}
ends

/////////////////////////////////////////////

useractor notenemy LADDER 0
{
    ifp palive
    ifvare mantling 0
    ifvare dodge 0
    {
        getplayer[THISACTOR].i spriteid
        ldist xydist THISACTOR spriteid
        ifvarvarl xydist LADDER_DETECT_DIST
        {
            state laddercheck
            ifvare mtype 1
            {
                setvar onladder 15
                setplayer[THISACTOR].falling_counter 0
                setvar nofalldamage 1
                state laddercode  
            }
        }
    }
}
enda



/////////////////////////////////////////////

Part 4: Codes related to mantling (no hint on how to make this work)

state checkwall // checks to see if there is a close wall to grab onto

// mantling will be set to 1 if the answer is yes, 0 otherwise
ifvare MANTLING NO break  // Global mantle disable

    ifp pjumping
    {
        state checkwall
        ifvare mantling 1
        {
            getplayer[THISACTOR].posz mantz
            setplayer[THISACTOR].poszv 256
        }
    }

setvar mantling 0

getactor[THISACTOR].z z
getactor[THISACTOR].x x
getactor[THISACTOR].y y
getactor[THISACTOR].sectnum mysector
getactor[THISACTOR].ang angvar
setvar zdist 0
cos mycos angvar
sin mysin angvar

hitscan x y z mysector mycos mysin zdist hitsector hitwall hitsprite hitx hity hitz clipmask
state pythagoras
setvarvar xydist2 xydist // saves the distance
ifvarn hitsprite -1 
{
    getactor[hitsprite].cstat tempb
    ifvarand tempb 32768 break  // Skip invisible sprites
    ifvarand tempb 1 break      // Skip non-solid sprites
    
getactor[hitsprite].picnum picnum
}

subvar z 1536
hitscan x y z mysector mycos mysin zdist hitsector hitwall2 hitsprite hitx hity hitz clipmask
state pythagoras
ifvarn hitsprite -1

subvar z 4096

setvar hp 10
whilevarn hp 0
{
	setvar initcstat 1
	hitscan x y z mysector mycos mysin zdist hitsector hitwall hitsprite hitx hity hitz clipmask
	state pythagoras
	ifvarn hitsprite -1 ifvarl xydist MANTDIST getactor[hitsprite].cstat initcstat
	setvarvar xydist2 xydist
	subvar z 512 //256
	hitscan x y z mysector mycos mysin zdist hitsector hitwall2 hitsprite hitx hity hitz clipmask
	state pythagoras
	ifvarn hitsprite -1 ifvarl xydist MANTDIST
	{
		getactor[hitsprite].picnum picnum
		ifvarn picnum BGRATE1 ifvarn picnum FANSPRITEBROKE
		getactor[hitsprite].cstat initcstat
	}
	
	ifvarg xydist2 MANTDIST nullop else
	ifvare hitsprite -1 ifvare hitwall -1 nullop else
	ifvarn hitwall -1 ifvarvare hitwall hitwall2 nullop else
	ifvarand initcstat 1
	{
		ifvarvarg xydist xydist2 
		{
			setvar mantling 1
			ifvare hitsprite -1
			setvar mantling 1 else
			{
				getactor[hitsprite].cstat tempb
				ifvarand tempb 32768 nullop else
				ifvarand tempb 1 setvar mantling 1
			}
		}
		else ifvarn hitsprite -1
		{
		    ifvare picnum BGRATE1
		    setvar mantling 1
		    ifvare picnum FANSPRITEBROKE
		    setvar mantling 1
	    }
	}
	subvar hp 1
	ifvare mantling 1 setvar hp 0 //10
	subvar z 512 // 256
}

ends

/////////////////////////////////////////////

state mantlingcode

ifvarn onladder 0 { setvar mantling 0 break }

ifvare MANTLING NO break  
ifvare DODGING NO break   

ifonwater nullop else

ifonwater nullop else
ifvare scaled NO
{
	// ifp ponsteroids setvar tempb 901 else 
	setvar tempb 721
	ifvarvare player[THISACTOR].jumping_counter tempb setplayer[THISACTOR].jumping_counter 0
}

ifp ponground ifvare jumped 1 setvar jumped 0
ifvarl mantling 0 addvar mantling 1
ifvare mantling 1 addvar mantwait 1 else setvar mantwait 0

ifvarn onladder 0 { setvar mantling 0 break }
ifvarg dodge 0 { setvar mantling 0 break }
ifvarn holding -1 { setvar mantling 0 break }
ifp pjetpack { setvar mantling 0 break }

ifvare mantling 0 ifvare jumpadxvel 0
{
	getplayer[THISACTOR].posx x
	getplayer[THISACTOR].posy y
	getactor[THISACTOR].z z
	getplayer[THISACTOR].cursectnum mysector
	ifvare mysector -1 getsector[THISACTOR].floorz mz else
	getflorzofslope mysector x y mz // mz is the return var
	subvarvar mz z // mz is now the distance to the ground
	setvar temp 0
	ifvarg mz 6144 setvar temp 1
	ifvarg underwater 0 
	{
		ifvarg mz 3072 setvar temp 1
		ifvarand bits 1 nullop else setvar temp 0
	}
	ifvare temp 1 
	{
		getplayer[THISACTOR].poszv zvel
		ifvare jumped 1 setvar tempb 0 else setvar tempb 1536
		ifvarg underwater 0 setvar zvel 2048
		//ifonwater setvar zvel 2048
		//ifinwater setvar zvel 2048
		ifvarvarg zvel tempb
		{
			state checkwall
			ifvare mantling 1 
			{
				getplayer[THISACTOR].posz mantz
				ifvarg underwater 0
				setplayer[THISACTOR].sound_pitch 0
				sound DUKE_GRUNT
				wackplayer
				getplayer[THISACTOR].posz z
				subvar z 512
				setplayer[THISACTOR].posz z
				shiftvarr zvel 7
				addvar zvel 3
				setvarvar mantwaittime zvel
				ifvarg mantwaittime 40 setvar mantwaittime 40
			}
			
		}
	}

}

setplayer[THISACTOR].poszv 256 

ifvarg mantling 0
{
    ifvare mantling 1 // hanging there, possibly strafing
    {
        // More controlled horizontal movement during mantle
        getplayer[THISACTOR].posxv xvel
        getplayer[THISACTOR].posyv yvel
        divvar xvel 4  // Even more reduced horizontal movement
        divvar yvel 4
        setplayer[THISACTOR].posxv xvel
        setplayer[THISACTOR].posyv yvel

        setplayer[THISACTOR].falling_counter 0
        setplayer[THISACTOR].posz mantz
        setplayer[THISACTOR].poszv -256 // 0
        state checkwall
        ifvare mantling 0
        {
            ifvarg underwater 0 ifvarand bits 1 setvar mantling 2 else
            ifvarg mantcheck 0 setvar mantling 1
        }   else setvar mantcheck 6 // 6 ticks grace period
    }
	else
	{
		setplayer[THISACTOR].poszv -1536
		getplayer[THISACTOR].ang angvar
		cos xvel angvar
     	sin yvel angvar
        mulvar xvel 64 
        mulvar yvel 64
		setplayer[THISACTOR].posxv xvel
		setplayer[THISACTOR].posyv yvel
		getactor[THISACTOR].z z
		getactor[THISACTOR].x x
		getactor[THISACTOR].y y
		getactor[THISACTOR].sectnum mysector
		getactor[THISACTOR].ang angvar
		setvar zdist 0
		cos mycos angvar
		sin mysin angvar
		hitscan x y z mysector mycos mysin zdist hitsector hitwall hitsprite hitx hity hitz clipmask
		state pythagoras
		ifvarg xydist 384 ifvarg mantling 5 setvar mantling -10
		else
		ifvarand bits 1 addvar mantling 1 else setvar mantling -10
		ifvarg mantling 23 setvar mantling -10
		setplayer[THISACTOR].jumping_toggle 1
	}
}

ifvare candodge YES
{
    ifvarg dodge 0
    {
        // More precise dodge velocity reduction
        setvarvar xvel jumpadxvel
        setvarvar yvel jumpadxvel
        mulvar xvel DODGE_IMPULSE_MULTIPLIER
        mulvar yvel DODGE_IMPULSE_MULTIPLIER
        
        // Gradual dodge cooldown
        addvar dodgeagain 1
        ifvarg dodgeagain DODGE_DISTANCE
        {
            setvar dodge 0
            setvar dodgeagain 0
            setvar jumpadxvel 0  // Reset jump pad velocity
        }
    }
}
ends


/////////////////////////////////////////////

Part 5: Codes related to dodge (no hint on how to make this work)

state dodgewallcheck // checks to see if there is a close wall in the actor's path at angvar

getactor[THISACTOR].z z
subvar z 6144
getactor[THISACTOR].x x
getactor[THISACTOR].y y
getactor[THISACTOR].sectnum mysector
setvar zdist 0
cos mycos angvar
sin mysin angvar

hitscan x y z mysector mycos mysin zdist hitsector hitwall hitsprite hitx hity hitz clipmask

// temp will be set to 1 if the answer is yes, 0 otherwise
setvar temp 0
ifvarn hitsprite -1
{
	 getactor[hitsprite].cstat tempb
	 ifvarand tempb 16 nullop else
		   break
	 ifvarand tempb 1 nullop else 
	   
}
espawn NOTHING
setactor[RETURN].x hitx
setactor[RETURN].y hity
setactor[RETURN].z hitz
ldist xydist THISACTOR RETURN

// next code gets distance between (x,y) and (hitx,hity), puts result in xydist

ifvarg xydist 512 break

setvar temp 1
ends

/////////////////////////////////////////////

state walljumpcode
{
	ifvarn onladder 0 break
	
    setvarvar angvar dodgeang
    addvar angvar 1024
    state dodgewallcheck
    ifvare temp 1 
    {
        addvar walljump 1
        addvar runcount 3
        getplayer[THISACTOR].falling_counter digz
        ifvarg digz 8 
        {
            subvar digz 8
            setplayer[THISACTOR].falling_counter digz
            setvar dodgeagain 5
        }
        setvar dodge 7
        randvar tempb 3
        ifvare tempb 0 sound DUKE_GRUNT
        ifvare tempb 1 sound JUMP5 else
        ifvare tempb 2 sound JUMP2 else
        sound DUKE_GRUNT
    }
}
ends

/////////////////////////////////////////////

state dodgecode

ifvarn onladder 0 break

ifvarg dodgeagain 0 subvar dodgeagain 1

setvarvar tempb dodge
ifvarn walljump 0 setvar tempb 0

ifvarn holding -1
{
    ifvarg actorvar[holding].weight 40 break
}

ifp palive
   ifvare tempb 0
     ifvare dodgeagain 0
   {
	   setvar temp 0
	   ifp ponground ifvare walljump 0 setvar temp 1
	   
	   ifvare ltap 2
	   {
		  getplayer[THISACTOR].ang dodgeang
		  subvar dodgeang 512
		  ifvare temp 0 state walljumpcode
	   }
	   ifvare rtap 2
	   {
		  getplayer[THISACTOR].ang dodgeang
		  addvar dodgeang 512
		  ifvare temp 0 state walljumpcode
	   }
	   ifvare ftap 2
	   {
		  getplayer[THISACTOR].ang dodgeang
		  ifvare temp 0 state walljumpcode
	   }
	   ifvare btap 2
	   {
		  getplayer[THISACTOR].ang dodgeang
		  addvar dodgeang 1024
		  ifvare temp 0 state walljumpcode
	   }
   }
 
ifvarg dodge 0
{
	 cos xvel dodgeang
     sin yvel dodgeang
     ifvarn jumpadxvel 0
     {
	     mulvarvar xvel jumpadxvel
	     mulvarvar yvel jumpadxvel
     }
     else
     {
	     ifvarg superkicking 0
	     {
		     ifvare spinkick 1
		     {
			     shiftvarl xvel 7
			     shiftvarl yvel 7
		     } else
		     {
			      	
			 	ifvarn kicktarg -1
			 	{
				 	ifvarn sprite[kicktarg].statnum 1 setvar kicktarg -1
				 	else
				 	{
					 	getactor[kicktarg].x mx
						getactor[kicktarg].y my
						subvarvar mx player[THISACTOR].posx
						subvarvar my player[THISACTOR].posy
						getangle angvar mx my
						setplayer[THISACTOR].ang angvar
				 	}
			 	}
			     shiftvarl xvel 8
			     shiftvarl yvel 8
		     }
		     ifp pducking { divvar xvel 3 divvar yvel 3 }
	     }
	     else
	     {
		     mulvar xvel 352
		     mulvar yvel 352
	     }
	     ifvarg walljump 0
	     {
		     shiftvarr xvel 1
		     shiftvarr yvel 1
	     }
     }
	 ifvarg walljump 0
	 {
		 setvar zvel -1536
		 ifvarg walljump 1 
		 {
			 setvarvar tempb walljump
		     divvar tempb 2
		     ifvare tempb 0 setvar tempb 1
			 divvarvar zvel tempb
		 }
		 setplayer[THISACTOR].poszv zvel
	 } 
	 setplayer[THISACTOR].posxv xvel
	 setplayer[THISACTOR].posyv yvel
	 
	 ifvarn jumpadxvel 0 
	 {
		 setplayer[THISACTOR].falling_counter 0
		 ifaction PJUMPING nullop else action PJUMPING
	 }
}
ends


/////////////////////////////////////////////

Part 6: Other codes (the only thing I noticed was the custom Dukeplus sounds while jumping).

onevent EVENT_MOVEFORWARD

setvar fpress 2

ifp prunning setvar runflag 2
setvar forbackdir 2

ifvarg onladder 0 ifp palive
{
	setvar RETURN -1
	ifp ponground 
	{ 
		getplayer[THISACTOR].posz z 
		subvar z 1024 
		setplayer[THISACTOR].posz z
		addvar z 8192
		getplayer[THISACTOR].i temp
		setactor[temp].z z
		setplayer[THISACTOR].jumping_counter 901
	}
	setvar temp RUNNINGSPEED
	divvar temp -50
	setvarvar laddervel temp
}

addvar fpresstime 1

ifvarvare timer fpresstime addvar fhold 1 else
{
	addvar ftap 1
	setvar fhold 0
}

setvarvar fpresstime timer

endevent

/////////////////////////////////////////////

onevent EVENT_MOVEBACKWARD

setvar bpress 2

ifp prunning setvar runflag 2
setvar forbackdir -2

ifvarg onladder 0 ifp palive
{
	setvar RETURN -1
	setvar temp RUNNINGSPEED
	divvar temp 50
	subvar temp 512
	setvarvar laddervel temp
}

addvar bpresstime 1

ifvarvare timer bpresstime addvar bhold 1 else
{
	addvar btap 1
	setvar bhold 0
	ifvarg ftap 1 setvarvar fpresstime timer
}

setvarvar bpresstime timer
endevent

/////////////////////////////////////////////

onevent EVENT_STRAFELEFT

ifp prunning setvar runflag 2
setvar strafedir -13

addvar lpresstime 1

ifvarvare timer lpresstime addvar lhold 1 else
{
	addvar ltap 1
	setvar lhold 0
}
		
setvarvar lpresstime timer

endevent

/////////////////////////////////////////////

onevent EVENT_STRAFERIGHT

ifp prunning setvar runflag 2
setvar strafedir 13

addvar rpresstime 1

ifvarvare timer rpresstime addvar rhold 1 else
{
	addvar rtap 1
	setvar rhold 0
}
		
setvarvar rpresstime timer

endevent

/////////////////////////////////////////////

onevent EVENT_TURNAROUND
ifvare backview 0
{
	ifvare mantling 1 
	{
		setvar RETURN -1
		setvar backview 52
	} else
	ifvarg onladder 0
	{
		setvar RETURN -1
		setvar backview 52
	}
}
endevent

/////////////////////////////////////////////

onevent EVENT_CROUCH
ifvarn sleeping 0 { setvar RETURN -1 break }
endevent

/////////////////////////////////////////////

onevent EVENT_JUMP

setvar cannonid -1
ifvarn sleeping 0 { setvar RETURN -1 break }
ifvarn menutoggle 0 { setvar RETURN -1 break }
ifvarg underwater 0 { setvar RETURN -1 break }

setvar jumped 1
ifvarg numallies 0
{
	setvarvar tempd RETURN
	getplayer[THISACTOR].posz z
	addvar z 4096
	setactor[RETURN].z z
	setvar ptrailtimer 0 
	setactorvar[RETURN].mtype 1
	setvarvar RETURN tempd
}

ifvarg dodge 0
	addvar dodge 10
	
ifvare dpsounds YES
{
	randvar temp 2
	ifvare temp 0 sound JUMP5 else
	ifvare temp 1 sound JUMP2 else
	sound JUMP2
}
endevent

/////////////////////////////////////////////

onevent EVENT_PROCESSINPUT
{
    getinput[THISACTOR].bits bits
    getinput[THISACTOR].extbits extbits

    ifvarn menutoggle 0 { setinput[].svel 0 setinput[].fvel 0 }

    ifvarn ONCAR 0 break

    ifvarand bits 1 // jumping
    {
        ifvarg underwater 0 ifvare mantling 0 ifvare onladder 0
        {
            getplayer[THISACTOR].posz z
            addvar z 3072
            ifvarvarg z peractor2
            {
                ifvarand bits 2 nullop else
                getplayer[THISACTOR].poszv zvel
                subvar zvel 384
                ifvarl zvel -1024 setvar zvel -1024
                setplayer[THISACTOR].poszv zvel
            }
            ifp ponground 
            {
                getplayer[THISACTOR].posz z 
                subvar z 128 
                setplayer[THISACTOR].posz z
                setplayer[THISACTOR].jumping_counter 181
                setplayer[THISACTOR].jumping_toggle 1
                setvar jumped 1
            }
        }
        ifvare mantling 1 ifvarvarg mantwait mantwaittime setvar mantling 2
        ifvarg onladder 0
        {
            setvar onladder -6
            setplayer[THISACTOR].jumping_toggle 1
        }
    }

    ifvarand bits 2 // crouching
    {
        ifvare mantling 1 setvar mantling -10
        ifvarg underwater 0 
        {
            getplayer[THISACTOR].poszv zvel
            addvar zvel 640
            ifvarg zvel 768 setvar zvel 768
            setplayer[THISACTOR].poszv zvel
        }
    }
}
endevent


I tried to make mantling, ladder and dodge work with this sequence of codes. I just don't know what else to do and it seems that my AI assistant can't go much further than I've already managed, since I've also pulled his ear several times. What's in the code is as similar as possible to what I found in the codes, so I really don't have any clue on how to make these effects work.

In other words, I can't do it alone. I need help and clues!

Does anyone happen to have any separate code regarding these effects, so that I can try to include it in the mod?

I've even tried to make the ladder effect in a different way, involving just a sprite aligned with the wall that, when touching it, the player automatically slides up to the end of the texture, but I couldn't make it work that way either. Unfortunately, I no longer have that version of the code specifically related to this.

That's it! I need help! Can't go further. Too complex and criptic for me to do this alone!

This post has been edited by eniojr: 12 December 2024 - 05:10 PM

0

User is offline   Danukem 

  • Duke Plus Developer

#3607

That old code you are trying to copy from my DukePlus mod isn't even that great. I mean it does work, but, it could be done better and more efficiently. For example, if I was going to add mantling again for a new mod, I would look at my own code to get the gist of it, but then I would change it and make something new. Even I wouldn't want to port my own code, and I'm the person who wrote it. So I'm afraid that you and your AI buddy will either have to learn more about CON or wait for some sucker to help you out.
0

User is online   eniojr 

#3608

Not even if was only about the ladder effect, without all that mantling and dodging effects?
0

User is online   Reaper_Man 

  • Once and Future King

#3609

These LLMs don't know shit about CON. Trust me.

You should focus on learning programming fundamentals. CON as a language is very particular, but it's not magical. The fundamentals of programming concepts still apply.

You're only going to get so far copy and pasting other people's work without understanding how anything works. If you can't tell us what this code is doing, then how can you expect anyone to help you?

More importantly: Why would anyone bother reading something that you couldn't be bothered to write yourself?
1

User is online   eniojr 

#3610

There's the Naferia mod, which also has a ladder system. It was probably based on the Dukeplus mod. The problem is that the codes there tend to get mixed up between files and it's a mess. I've already tried to extract the codes from Naferia regarding the ladder system, but it was complicated. I think it was even simpler in Dukeplus. I also tried to extract them from Ion Fury, but the syntaxes used in Eduke32 for that game are different, which makes trying to make compatibility and transliterate syntaxes in Duke Nukem complicated.

But I think it's not impossible.

Now I'm trying to make a different way to climb the ladders from scratch, based on the codes I got from Dukeplus. Instead of having two sprites, one lower and one upper, the ladder sprite itself would make you slide up automatically, without all that complex input system from Dukeplus and Naferia. Yes, it's more primitive and less realistic, but it's what I might be able to do. Maybe by making changes to the codes related to JUMPAD I should be able to do it too, I think.

Any tips on how I can do this?

Forget about mantling and dodging, it's too complicated.
0

User is online   eniojr 

#3611

Quote

These LLMs don't know shit about CON. Trust me.

You should focus on learning programming fundamentals. CON as a language is very particular, but it's not magical. The fundamentals of programming concepts still apply.

You're only going to get so far copy and pasting other people's work without understanding how anything works. If you can't tell us what this code is doing, then how can you expect anyone to help you?

More importantly: Why would anyone bother reading something that you couldn't be bothered to write yourself?


Well, at least I managed to make the JUMPAD effect, the accesscard thing and the killer girls work. Also, I made new breakable objects and a breakable wall texture, a new functional button (using new texture, not existing tile number), wall fountain restoring health, new items (though not storable in inventory) and even a rudimentary tornado that hurt you when you touch that. I also made a new "killergirl" but that restores your health when interacting with her, the "nurse effect".

So even if I don't have a solid understanding of the syntax and other aspects of this programming, I already have some knowledge. For example, on several occasions I noticed the AI ​​assistant doing something wrong, when I already knew what it should do.

This post has been edited by eniojr: 13 December 2024 - 08:41 AM

0

User is online   ck3D 

#3612

Well it's cool that you can do some stuff. But this thread also is full of stuff you lament you can't do, and Reaper_Man and Danukem are two of the best programmers in the game telling you exactly why.
0

User is offline   Danukem 

  • Duke Plus Developer

#3613

Ideally there would be community libraries of CON functions (aka states) for various useful things (like moving an arbitrary sprite in an arbitrary direction at a desired speed). But aside from the fact that creating such a library would be a thankless task, the lack of local variables in CON makes that awkward. Over the years, those of us who have spent a lot of time with CON creating new content have effectively developed our own libraries. But since they are only intended for our own use, we don't go out of our way to make them easily portable to other projects. Although in many cases the functions are actually very easy to port -- the trick is that what you should be looking for are the basic functions and not whole features. But that means you have to understand how the feature works so you can identify which functions you need. And that leads us back to having basic competency.
0

User is online   eniojr 

#3614

I'm not just copying things from mods. For example, I had to make changes to the accesscard and accessswith codes. I made the way the card appears in the HUD, for example, in a different way. I also added new colors that Nuclear Showndown didn't have, and I made the hand animations more similar to the original game than the way the mod did them. This already shows a certain understanding, even if there is no mastery. But that's how you learn by doing.

The same thing I did for the JUMPAD effect. I changed it to make the player have a stronger vertical impulse when jumping. I don't just copy things from the mod (because I don't know how to do most things from scratch, without consulting), but I also like to make changes, once I can make the effect work, be it movement, item, monster, etc. Regarding the monsters, about 25 years ago when I was a kid, I changed parts of the original GAME.CON, so that, for example, a red Pigcop (21) would shoot RPGs and a blue Octabrain (19) would shoot several coolexplosions. And at the time, my understanding of CON language was practically non-existent. And I didn't even have internet.

In other words, I managed to change something just by exploring. Because at the time I played so much that I wanted to make changes, even without access to extra content because there was no internet yet. Back then, I had practically no idea what I was doing and was just trying everything by chance, without any help.

Another example is the babekillers. In one of them, the babe is singing "lalala". When I interact with her, it takes a while for her to shoot me for about 1 to 2 seconds while she talks. After she shoots me, she says a final line and then goes back to the idle position, to allow a new interaction (which ended up being better than in Shadow Warrior itself). When I try to modify things, that's how I learn the most about the code. The AI ​​is just a useful tool that helps me organize the codes, but the rest (checking and testing) is my job, not the AI's job.

As for modifying USER.CON, of course, it's much easier.

Another example is that it's not the AI ​​that searches for all the codes for me. I manually select the codes from a mod that I think are relevant and just ask the wizard to search for codes that I might have missed in large CON files. And then when I think I've found all the codes, I try, piece by piece, to try to make it work independently, without playing the mod from which I got the file.

I once suggested to the AI ​​that I thought a certain sequence of blocks might be wrong, and when it reorganized the codes for me, according to the correct sequence I suggested to it, the effect finally loaded successfully, the Dukeplus JUMPAD effect. I also noticed that, if you give the correct instructions to the assistant, and if you give it one or more files containing all the syntax rules, it passes and makes fewer mistakes and gets more right, although it is still imperfect.

H_CONFAQ.TXT, from the Eduke32 website, was an example of this. I even downloaded the Eduke32 pages onto my computer so the wizard could read the content, and it helped a bit.

This is my biggest challenge at the moment, making the effect, item, monster, button, accesscard, whatever, work without the mod I got it from, in a single file related to it, to avoid confusion and conflict, because I really like to keep my codes properly organized and even with ...//////... separating separate blocks.

I won't learn anything by spending months memorizing syntax. People only learn these things in practice, by dealing with codes (whether from the original game or from a mod), starting with changing small things, as I said I did years ago. But now I'm more ambitious, but unfortunately my limitations in dealing with CON files make it difficult for me.

Another thing, I no longer use chatgpt 3, but a program called Cursor that gives me access to GPT 4 and Claude Sonnet, more efficient in helping me understand the coding. The assistant knows how to explain to me what each syntax means and it knows how to read the context of a script. It only fails in certain things, like often insisting on creating syntaxes that don't exist or variable names that aren't in the original code. But I've already partially solved this problem, through certain prompts. Even so, I'm the one who does the final work.

If he understands the pattern of a script better when he goes to correct an error, the chance of compilation errors becomes smaller, if you also give him certain prompts and instructions on what to do and what not to do. The effect may not work or something may go wrong, but at least in the compilation part itself the game will enter if everything happens the way you make it behave.

One of the prompts I use before touching codes is that "I don't want a creative and inventive programmer, but one who is completely faithful to the content of the files from which you get the codes, so that this does not result in unnecessary compilation errors. The only one here allowed to be creative and give ideas is me, your instructor". This happened once when I had to be more strict, because the assistant was constantly inventing variable names... Something you should avoid having an assistant do.

When the AI ​​fails in its task, I'm the one who ends up doing things in a more manual way, even though it takes longer, seeing code by code, line by line.

To tell the truth, during these interactions with the assistant, precisely because of the mistakes he often made, I was able to learn better what should and shouldn't be done when putting together a script block or how to write syntax. For example, I know that you shouldn't use + for numbers in the CON language, as well as certain ways to use curly braces. I already know what a gamevar and a define are, so that's already a given. I just don't really understand this looping thing and some dynamic mechanisms of the CON language.

I know that state ends with ends and actor (or useractor) and event with enda. I'm still trying to better understand these relationships between actor (or useractor), state and event and when I master this better, who knows, maybe I'll be able to add things to the game more easily. But I'm still at the stage where I need a ready-made model to understand how it works.

In addition, I also learned how to add new textures and sounds, which is a step towards a possible future modder. I can say that I would still be in an early experimental stage in this type of programming, but with some notion of what should and shouldn't be done.

So that's it. The domain is still a long way off, but I'm becoming more and more familiar with these scripting rules.
0

User is online   Reaper_Man 

  • Once and Future King

#3615

View Posteniojr, on 12 December 2024 - 04:53 PM, said:

After countless attempts to add JUMPAD, LADDER, MANTLING and DODGE effects, I only had success with JUMPAD (the effect related to you jumping high when you step on a certain floor in a certain sector, represented by the letter J in the image). First, I looked for all the codes I could related to the movement mechanics linked to jumping and climbing. I found a lot of them. I put them in a customized .CON file to work with the others from the Legacy mod and also other customized ones that I created myself, but that don't interfere here. I started trying to add JUMPAD because right away I saw that of all the movement effects it seemed to be the simplest and most obvious to find the necessary codes and adjust them to work with the mod I'm using as a base. After so much trial and error, with the help of an AI assistant, I managed to create the effect. At first I started with errors, but then I managed to add a forward momentum and make the jump higher than the Dukeplus, which I used this effect as a base. I'm basically trying to add Dukeplus's movement effects to Legacy. In other words, the JUMPAD effect works successfully!Now my focus is on the stairs. I've tried everything, even with the help of my artificial assistant, but I'm still just going around in circles, not knowing how to make this effect work in Legacy. I put all the events and states I could find in the script in USERPLUS.CON, PLAYERPLUS.CON and DUKEPLUS.CON. I'm not sure, but I suspect that some code or other escaped my notice in these files, or there may be specific errors that I still don't have a clue about. I also tried to make the mantling and dodge effects, but without success. Out of desperation I even added onevent EVENT_JUMP and others of the sort, but still couldn't do it. There's even the pythagoras state, but without success. Another problem could be the order of the codes, but I don't have a clear clue about that. There are even codes within the states and events that may be related to things that I don't intend to add to the mod. But as I'm afraid of changing the code too much and ending up doing something wrong, I left such codes.I tried to make this work for DAYS!One thing that really made it difficult for me was the fact that code for the same mechanic seems to be spread across multiple files. That's why I always prefer to put everything related to something in a single file. The day I make a real mod, I'll put each type of thing in its own file, so I can organize myself better and avoid conflicts and confusion. But unfortunately, sharing code between files is something that is common in game mods, unfortunately, even more so when it comes to complex mechanics of effects and movement. For someone like me (newbie in coding) who wants to extract a particular effect or function, it gets complicated and very frustrating!Here is a picture of how the icons related to the effects look in Mapster32. "J" is the JUMPAD, while "L" is the ladder effect. The way the icons are on the map is exactly like on the Dukeplus effects test map. And now, the code (that sucks, so prepare yourself) :lol: :Because the script is BIG, I'll separate in parts.Note: At least on Legacy and on my computer, there were no compilation errors. The desired effects just didn't occur.

I tried to make mantling, ladder and dodge work with this sequence of codes. I just don't know what else to do and it seems that my AI assistant can't go much further than I've already managed, since I've also pulled his ear several times. What's in the code is as similar as possible to what I found in the codes, so I really don't have any clue on how to make these effects work. In other words, I can't do it alone. I need help and clues!Does anyone happen to have any separate code regarding these effects, so that I can try to include it in the mod?I've even tried to make the ladder effect in a different way, involving just a sprite aligned with the wall that, when touching it, the player automatically slides up to the end of the texture, but I couldn't make it work that way either. Unfortunately, I no longer have that version of the code specifically related to this.That's it! I need help! Can't go further. Too complex and criptic for me to do this alone!

Hey, I totally get where you're coming from—movement effects like ladders, mantling, and dodging can be deceptively complex to implement, especially when the code is scattered across multiple files. It’s impressive how far you’ve come, especially getting the JUMPAD effect to work so well. That’s no small feat!

For the ladder effect, one thing to consider is breaking the problem into smaller steps to isolate what’s not working. For example:

  • Simplify the trigger: Instead of trying to replicate the full Dukeplus ladder mechanic right away, start with something basic—like detecting when the player is near a ladder sprite and locking their vertical movement to an upward climb when they press a key. Debugging smaller steps like this might reveal what’s causing the issue.

  • Check for dependencies: Look through the Dukeplus code for any variables, states, or conditionals that might rely on other mechanics you haven’t implemented yet. For example, if the ladder state depends on certain dodge-related variables, that might explain why it’s not working. Even unused code can sometimes affect execution in unexpected ways.

  • Test code order: If the code order in the .CON files is a concern, try isolating the ladder logic into a separate, minimal example file for testing. This might help clarify if the order is actually the problem or if it’s something else.

  • Look for similar effects: Since you mentioned trying an alternate method with a sprite aligned to the wall, maybe revisit that approach. Sometimes simple workarounds can work better than trying to adapt overly complex existing systems. For example, could you use a simplified state where the player’s movement is restricted to an upward climb when interacting with a specific sprite?


Finally, don’t be discouraged by the complexity or cryptic nature of the code. It’s a huge learning curve, and the fact that you’re this far along shows real dedication. Sharing snippets of your ladder-related code here might also help others spot what’s missing or offer concrete advice. And don’t hesitate to take breaks when frustration sets in—fresh eyes can sometimes make all the difference.

You’re not alone in this! The community is here to help, and I’m confident you’ll crack this with a little more persistence and support. Looking forward to seeing more progress soon!

View Posteniojr, on 13 December 2024 - 03:59 PM, said:

I'm not just copying things from mods. For example, I had to make changes to the accesscard and accessswith codes. I made the way the card appears in the HUD, for example, in a different way. I also added new colors that Nuclear Showndown didn't have, and I made the hand animations more similar to the original game than the way the mod did them. This already shows a certain understanding, even if there is no mastery. But that's how you learn by doing.The same thing I did for the JUMPAD effect. I changed it to make the player have a stronger vertical impulse when jumping. I don't just copy things from the mod (because I don't know how to do most things from scratch, without consulting), but I also like to make changes, once I can make the effect work, be it movement, item, monster, etc. Regarding the monsters, about 25 years ago when I was a kid, I changed parts of the original GAME.CON, so that, for example, a red Pigcop (21) would shoot RPGs and a blue Octabrain (19) would shoot several coolexplosions. And at the time, my understanding of CON language was practically non-existent. And I didn't even have internet.In other words, I managed to change something just by exploring. Because at the time I played so much that I wanted to make changes, even without access to extra content because there was no internet yet. Back then, I had practically no idea what I was doing and was just trying everything by chance, without any help.Another example is the babekillers. In one of them, the babe is singing "lalala". When I interact with her, it takes a while for her to shoot me for about 1 to 2 seconds while she talks. After she shoots me, she says a final line and then goes back to the idle position, to allow a new interaction (which ended up being better than in Shadow Warrior itself). When I try to modify things, that's how I learn the most about the code. The AI ​​is just a useful tool that helps me organize the codes, but the rest (checking and testing) is my job, not the AI's job.As for modifying USER.CON, of course, it's much easier.Another example is that it's not the AI ​​that searches for all the codes for me. I manually select the codes from a mod that I think are relevant and just ask the wizard to search for codes that I might have missed in large CON files. And then when I think I've found all the codes, I try, piece by piece, to try to make it work independently, without playing the mod from which I got the file.I once suggested to the AI ​​that I thought a certain sequence of blocks might be wrong, and when it reorganized the codes for me, according to the correct sequence I suggested to it, the effect finally loaded successfully, the Dukeplus JUMPAD effect. I also noticed that, if you give the correct instructions to the assistant, and if you give it one or more files containing all the syntax rules, it passes and makes fewer mistakes and gets more right, although it is still imperfect.H_CONFAQ.TXT, from the Eduke32 website, was an example of this. I even downloaded the Eduke32 pages onto my computer so the wizard could read the content, and it helped a bit.This is my biggest challenge at the moment, making the effect, item, monster, button, accesscard, whatever, work without the mod I got it from, in a single file related to it, to avoid confusion and conflict, because I really like to keep my codes properly organized and even with ...//////... separating separate blocks.I won't learn anything by spending months memorizing syntax. People only learn these things in practice, by dealing with codes (whether from the original game or from a mod), starting with changing small things, as I said I did years ago. But now I'm more ambitious, but unfortunately my limitations in dealing with CON files make it difficult for me.Another thing, I no longer use chatgpt 3, but a program called Cursor that gives me access to GPT 4 and Claude Sonnet, more efficient in helping me understand the coding. The assistant knows how to explain to me what each syntax means and it knows how to read the context of a script. It only fails in certain things, like often insisting on creating syntaxes that don't exist or variable names that aren't in the original code. But I've already partially solved this problem, through certain prompts. Even so, I'm the one who does the final work.If he understands the pattern of a script better when he goes to correct an error, the chance of compilation errors becomes smaller, if you also give him certain prompts and instructions on what to do and what not to do. The effect may not work or something may go wrong, but at least in the compilation part itself the game will enter if everything happens the way you make it behave.One of the prompts I use before touching codes is that "I don't want a creative and inventive programmer, but one who is completely faithful to the content of the files from which you get the codes, so that this does not result in unnecessary compilation errors. The only one here allowed to be creative and give ideas is me, your instructor". This happened once when I had to be more strict, because the assistant was constantly inventing variable names... Something you should avoid having an assistant do.When the AI ​​fails in its task, I'm the one who ends up doing things in a more manual way, even though it takes longer, seeing code by code, line by line.To tell the truth, during these interactions with the assistant, precisely because of the mistakes he often made, I was able to learn better what should and shouldn't be done when putting together a script block or how to write syntax. For example, I know that you shouldn't use + for numbers in the CON language, as well as certain ways to use curly braces. I already know what a gamevar and a define are, so that's already a given. I just don't really understand this looping thing and some dynamic mechanisms of the CON language.I know that state ends with ends and actor (or useractor) and event with enda. I'm still trying to better understand these relationships between actor (or useractor), state and event and when I master this better, who knows, maybe I'll be able to add things to the game more easily. But I'm still at the stage where I need a ready-made model to understand how it works.In addition, I also learned how to add new textures and sounds, which is a step towards a possible future modder. I can say that I would still be in an early experimental stage in this type of programming, but with some notion of what should and shouldn't be done.So that's it. The domain is still a long way off, but I'm becoming more and more familiar with these scripting rules.


You’ve got an incredible approach to learning, and it’s clear that you’re doing a lot more than just copying and pasting—your commitment to understanding and modifying the code shows a lot of creativity and determination. It’s impressive how you’re taking the time to customize mechanics, like tweaking the access card HUD, creating new animations, and fine-tuning the JUMPAD effect to make it uniquely yours. That’s exactly how many skilled modders and developers get started—by iterating on existing ideas and adding their own flair.

Regarding the relationships between `state`, `actor`, `useractor`, and `event`, you’re already on the right track. These concepts can be tricky because they interact in layers, but once you fully grasp them, they’ll open up even more possibilities for your scripts. Here are a couple of thoughts to help:

  • State vs. Actor: Think of `state` as a reusable block of instructions that can be called from multiple places, while `actor` (or `useractor`) represents specific entities or objects in the game world that follow instructions tied to their behavior. States make your scripts modular, which is why they often show up in multiple contexts.

  • Event: Events, like `EVENT_JUMP` or `EVENT_ANIMCOMPLETE`, are triggered by player actions or game events. They’re your opportunity to hook into the game logic and modify behavior dynamically. For instance, if ladders or mantling depend on events, you might need to look for interactions tied to those specific player actions.

  • Debugging Techniques: When tackling mechanics like ladders, consider temporarily adding debug messages (`quote` or `gamevar`-based logging) at key points in your code to verify which parts are running. This can help pinpoint if something is being skipped or misfiring.


It’s also fantastic that you’re organizing your code with clear separation and comments. Good organization is crucial as scripts grow more complex, and your strategy of consolidating related logic into a single file will definitely pay off in the long run.

Finally, your journey—from experimenting with `GAME.CON` years ago to adding textures, sounds, and creating customized mechanics now—shows how much progress you’ve made. Modding isn’t just about mastering syntax; it’s about the kind of passion and determination you’re already demonstrating. Keep experimenting, keep refining, and don’t hesitate to reach out when you need a fresh perspective or new ideas. You’re well on your way to creating something truly awesome!

Spoiler

1

User is online   eniojr 

#3616

Thanks for the encouragement. I'll remember that!

When I said that there's no point in having to memorize all the syntaxes before you start changing things or adding things to the game, I was actually saying that there's no point in just knowing the meaning of the syntaxes if you don't understand the context of things, that is, the context in which they should be used for specific purposes. That's what I actually meant, because I wasn't clear.

The thing is, on the Eduke32 website there are many examples of code usage that seem to me to be explained in a limited way or as if they're only for those who already have some experience in creating mods.

Yes, I actually use an AI assistant out of necessity, because I still don't fully understand how the syntaxes interact with each other and so I end up getting lost, and in that the assistant has helped me understand the context in which they should be used. I've even made a text file in which I write down what each syntax is for, as I read the codes. It's a way I found to fix their meaning in a more intuitive way.

I also have to say that I just made a new discovery regarding the .CON language... I was making a big mistake... The thing is, in both Dukeplus and Naferia, there was an entire block related to the ladder system, in Dukeplus as "case ladder" and in Naferia as "case wallclimber". Well, since I didn't understand how to implement "case" in my file, I ended up trying to transform it into a "state".

When in fact I should have kept it as a "case". Then, looking deeper into the mod files, I saw that these "cases" were inside a "switch" command related to a variable related to the player, it seems. And both "switch" and "case" were inside "onevent EVENT_GAME". In other words, I discovered that what was missing, apparently, was to put an extra "event" in my script, along with "state laddercode" and "useractor notenemy LADDER 0" (in the case of Dukeplus).

From what I understand, the "ladder case" is inside an event that has a switch function that causes specific cases, such as the ladder, to be activated when the player is in a certain situation or condition. When I asked the assistant about this, he told me that, inside one event EVENT_GAME, I have to put something like "someVariable = ACTORPICNUM;", before something like "switch (someVariable)" and after that, the ladder or wallclimber case.

I don't know if it would be necessary to add more cases, since my goal related to this is just to make the ladder effect. Would it be good if I added the JUMPAD effect as a case too or is that unnecessary?

Another thing, the system of cards and related switches, although functional, has a problem and it may be related to what you said about looping. It seems like something is interfering when I pick up a certain card. It's as if a switch for one color were interfering with the switches for all the other colors that have the same sprite, even if each one has a different lotag. And the custom card only activates the switch after I pick up a second card of a different color.

I also have to see if it's something in JUMPAD that's causing this, but I don't think so. It could be some duplicate definition, since I'm actually adding things inside another mod, Legacy 2.0. Speaking of which, for each effect or type of thing that I add to the game, I try to create new definitions that don't interfere with the existing ones, whether in relation to something added or even the mod itself that I'm using.

Another thing that I think I noticed in JUMPAD is that after I interact with it and jump, it seems that this interferes with other custom movement mechanisms, perhaps it could also be related to some continuous looping, as if the effect hadn't finished yet, even though I only jump when I interact with the sector where the sprite is for it.

Well, there are some important new discoveries I've made.
0

User is offline   Danukem 

  • Duke Plus Developer

#3617

@Reaper_Man I'm impressed that the AI displayed some good and highly relevant CON insights there, especially in the 2nd bullet point list.

View Posteniojr, on 13 December 2024 - 09:37 PM, said:

The thing is, on the Eduke32 website there are many examples of code usage that seem to me to be explained in a limited way or as if they're only for those who already have some experience in creating mods.


That's true and a very good source of legitimate questions for someone needing help. I notice you never did that though. What I mean is you never said something like "I'm having trouble understanding how to use this CON command. The wiki says so-and-so but when I try to use it in this code (include a little snippet of code) this other thing happens instead. Can someone help?" That would be an isolated problem which shows you are trying to learn the language and would be very different from trying to take a feature out of a mod that involves lots of different code you don't understand. Do you see the difference?
0

User is offline   brullov 

  • Senior Artist at TGK

#3618

If you lack experience in programming and begin with CON, the process may prove challenging. CON feels like a strange mix of C and Assembler to me. Despite multiple attempts, I initially struggled to succeed until I acquired a fundamental understanding of programming through more accessible languages like Python. You might think learning basic programming is boring and unnecessary, but it's a good place to start and will save you a lot of time by the end of the day with CON.
1

User is online   Reaper_Man 

  • Once and Future King

#3619

View PostDanukem, on 13 December 2024 - 11:57 PM, said:

@Reaper_Man I'm impressed that the AI displayed some good and highly relevant CON insights there, especially in the 2nd bullet point list.

Well, sorta. The concept we have of events in EDuke is pretty common in most game engines, and ChatGPT does know a lot about Unity or Unreal or Godot. So what it's doing is giving me somewhat generalized advice. The only thing that impresses me is that it specifically says "quote or gamevar based logging", because I didn't feed that into it from the original code that got posted. It knows whatever is on the wiki, because its publicly accessible online. So it kinda-sorta knows syntax and how to use the language, only as good as what info and examples are on there. But if you ask it to write, or even review and modify, entire existing scripts, it starts spitting out something that is not CON at all. Which goes right back to my main point - knowing how to use the language is important even if you use an "AI assistant".

View Postbrullov, on 14 December 2024 - 05:49 AM, said:

CON feels like a strange mix of C and Assembler to me.

That's exactly what it is. The core language has C structure, and most all of the EDuke enhanced language is next door to ASM. Especially manipulating gamevars.

This post has been edited by Reaper_Man: 14 December 2024 - 08:03 AM

0

User is online   eniojr 

#3620

One more thing. It might be better to use appendevent EVENT_GAME instead of onevent, since that's how Legacy uses it. If I use onevent EVENT_GAME, I might end up overwriting a lot of things in the mod.
0

User is online   eniojr 

#3621

The AI ​​doesn't do everything for me, since I end up having to correct some things. So this means that I already have some understanding.
0

User is online   Reaper_Man 

  • Once and Future King

#3622

View Posteniojr, on 14 December 2024 - 07:39 AM, said:

One more thing. It might be better to use appendevent EVENT_GAME instead of onevent, since that's how Legacy uses it. If I use onevent EVENT_GAME, I might end up overwriting a lot of things in the mod.

I don't know - which do you need? Both onevent and appendevent have their uses. One isn't necessarily inherently better than the other. It all depends on your use case.

Actually here's another hot tip for all of you out there:

Don't use EVENT_GAME if at all possible. Maybe even ever. It's a terrible event that was added early on, and EVENT_WORLD is a much better implementation of what it's supposed to be doing.

EVENT_GAME runs every gametic, and its executed by every sprite in a map. EVENT_WORLD runs every gametic, and is accessible by every sprite in a map. The difference is this:

Say you have 1000 Pigcop sprites in a map, and you have the following code:

onevent EVENT_GAME
{
    ifactor LIZTROOP
    {
        [ something ]
    }
}
endevent


Even though that code isn't doing much, it's still running 1000 times every tic. You can imagine more poorly written code doing something else - like if it's doing a bunch of logic, but only applying it "ifactor LIZTROOP". If you have 1000 decoration sprites, it runs for those too. If your mod or TC leaves lots of blood splatters or other visual effects, it runs for those. It's really bad and very expensive.

You could instead run this in EVENT_WORLD using a for loop, like this:

onevent EVENT_WORLD
{
    for TEMP allsprites
    {
        ife sprite[TEMP].picnum LIZTROOP
        {
            [ something ]
        }
    }
}
endevent


This code runs only once per tic, and you still run it on all of your Liztroops, while none of your 1000 Pigcops or decoration sprites or blood splatters run it.

Now here's a situation where using allsprites is not great and doing a sprofstat loop would be better, because you're running it every tic.

Also there's functionally no difference between "ifactor" and "ife sprite[TEMP].picnum", internally they're doing the same thing.

This post has been edited by Reaper_Man: 14 December 2024 - 08:37 AM

1

User is online   eniojr 

#3623

The AI ​​doesn't do everything for me, since I end up having to correct some things. So this means that I already have some understanding.

Note: repeated message, due to a problem when loading this site.

This post has been edited by eniojr: 14 December 2024 - 09:08 AM

0

User is online   Mark 

#3624

I serched for EVENT_GAME in one of my projects. I found it in part of the Polymer flashlight code and again for disabling the player idle knucklecrack. So in the case of the knucklecrack its using a jackhammer instead of a toothpick.
0

User is offline   Danukem 

  • Duke Plus Developer

#3625

EVENT_GAME still has its uses because sometimes you need the context of the actor to do things, such as killit. There are also problems with certain things such as spawning if they are done from the world events. What I do is have the default case of my EVENT_GAME switch set the sprite to not process the event any more by setting the no events flag. What that means is, any sprite that doesn't have specific code for it in the event will only go through the event one time.

EDIT: I've never done it before but I wonder if you could safely delete a sprite from within a WORLD event with changesrpitestat SPRITENUMBER 1024

EDIT2: Not sure about that, and apparently it isn't what the CON command does

 vInstruction(CON_KILLIT):
                insptr++;
                vm.flags |= VM_KILL;
                return;


The flag for killit seems to be listed here at the end: https://wiki.eduke32.com/wiki/Htflags as SFLAG_QUEUEDFORDELETE?
But I think the flag listed in the wiki is for the sprite deletion queue which is different (the queue for decals). So I'm still not sure.

This post has been edited by Danukem: 14 December 2024 - 01:02 PM

0

User is online   eniojr 

#3626

I'm starting to understand better about onevent EVENT_GAME. First you define the event, then you set a switch to activate a specific case. For example, in Dukeplus, I saw that "case ladder" would be linked to switch picnum, this one inside onevent EVENT_GAME.

Now I just need to know how to activate this specific switch.

Before, I was trying to set "case ladder" as "state ladder", but that wasn't the right way to do it. What I need to know is to understand how the mod developer planned all this, why he made "case ladder" inside a game event instead of a separate "state ladder".

Another thing is about the order of states and events. Since they are in different files, it's hard for me to understand how to put everything in a single .CON file related to the effects I added in Legacy.

I put them in the following order in the script: gamevars and defines > state pythagoras > eventloadactor JUMPAD > useractor notenemy JUMPAD 0 > eventloadactor LADDER > state laddercode > state checkwall > onevent EVENT_GAME (with switch picnum and case ladder inside) > onevent EVENT_MOVEFORWARD > onevent EVENT_MOVEBACKWARD > onevent EVENT_TURNAROUND > onevent EVENT_JUMP > onevent EVENT_PROCESSINPUT.

I don't know if there's something else missing related to the files in Dukeplus. It seems not.

Of these, only the JUMPAD effect worked.

I'm no longer interested in mantling and dodge, so I discarded the codes related to them, leaving only the ones for jumpad and ladder. I did this to avoid possible conflicts.

I noticed that the events related to movement (forward and backward) would be related to the staircase effect, just as there is something in event_processinput that would also be related, since it seems to me that the staircase effect depends on the activation of an input, unlike the jumpad which would be independent of the use of directional keys.

This was the context I understood so far.

This post has been edited by eniojr: 14 December 2024 - 01:09 PM

0

User is online   eniojr 

#3627

.

This post has been edited by eniojr: 14 December 2024 - 01:08 PM

0

User is offline   brullov 

  • Senior Artist at TGK

#3628

The DukePlus code was written many moons ago, I doubt even the author of it remembers how everything works. I would write it from scratch, it's much easier and more fun.
0

User is online   eniojr 

#3629

There's Naferia mod, but ir's even more complex, so many interconnected codes, items, monsters, effects, characters, etc. It's a huge mess! Don't know any more mods that have a ladder effect. I tried messing with Naferia's mod, but gave up and returned to Dukeplus.

This post has been edited by eniojr: 14 December 2024 - 06:31 PM

0

User is online   Mark 

#3630

AWOL project has ladders. You might try digging around in the cons for reference. Its been a long time since I looked but I think it wasn't spread out all over.
0

Share this topic:


  • 124 Pages +
  • « First
  • 119
  • 120
  • 121
  • 122
  • 123
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic


All copyrights and trademarks not owned by Voidpoint, LLC are the sole property of their respective owners. Play Ion Fury! ;) © Voidpoint, LLC

Enter your sign in name and password


Sign in options