Jump to content

Help with "Shoot through Wall" Script debuging


Nightterror5

Recommended Posts

I got quite a lot of scripting experiance so that should actualy work, but as usual it involves some trial and error.

What the scriot does (is supposed to do)

The script places a marker at the player and at the reticle position, then calculates a vector from their coordiantes, along witch a series of small explosions is spawned.

The Activator that is spawned at the reticles position writes it's own current coordiantes into 3 globals, and sets another global true (1) when placed, after that it deletes itself.

This was necessary due to the fact that placeAtReticle does NOT return a reference. Things would be to easy that way, right Bethesda? ha ha...

Right now nothing happens when you shoot the weapon ingame.

 

What I tried so far:

  • Checking if the scritps are realy assigned to the propper objects
  • Changing the distances between the explosions (shorter minivectors, because maybe the explosions spawned out of my sight)
  • Setting required variables constantly to their desired values (mostly 0 = ready to shoot)
  • Maybe there is a problem with the disable->enable of the explosions, I am currently checking this.

 

Scripts commented in german atm.

 

Script on the weapon (type: object)

scn 01FShootTroughWallsTESTScript

;die marker für schussposition und zielposition
ref rStartMarker
ref rReticleMarker

;referenz auf die Explosion, um die explosion zur richtigen position zu setzen und zu aktivieren
;ist nötig da man bei placeatme
ref rNextExplosion

;die Koordinaten der Schussposition
float fStartX
float fStartY
float fStartZ

;die Koordinaten der Zielposition
float fReticleX
float fReticleY
float fReticleZ

;der resultierende Vektor
float fVektorX
float fVektorY
float fVektorZ

;der verkleinerte Einheitsvektor
float fEinheitsVektorX
float fEinheitsVektorY
float fEinheitsVektorZ

;der reultierende Vektor wo die jeweilige explosion gespawnt wird
float fExplosionDistanceVektorX
float fExplosionDistanceVektorY
float fExplosionDistanceVektorZ

;distanz zwischen Start und Ziel, zur berechnung des einheitsvektors
float fDistanceToReticle

;ob der explosionslaser gestartet ist
short bFired

;die distanz zwischen start marker und der Explosion -> also auch irgendwie die Anzahl der explosionen
short iDistMulti

;globals die vom 01ShootThroughWallsCoordinateActivator übergeben werden
;aaaSchootThroughWallSuccesfullyPlaced
;aaaSchootThroughWallCoordinateX 
;aaaSchootThroughWallCoordinateY
;aaaSchootThroughWallCoordinateZ



Begin OnFire

;TEST
set bfired to 0


;Zuerst die globalen resetten
set aaaSchootThroughWallSuccesfullyPlaced to 0
set aaaSchootThroughWallCoordinateX to 0
set aaaSchootThroughWallCoordinateY to 0
set aaaSchootThroughWallCoordinateZ to 0


; Script startet nur wenn nicht schon eine Explosionlaser aktiv ist
if (bfired == 0)

	;PROBLEM Reticle marker gibt keine referenz zurück!!!
	;set rReticleMarker to (PlaceatReticle XMarkerHeading 1 1 1000000)

	;LOESUNG via activator
	;er schreibt seine koordinaten in 3 globale Variablen und löscht sich selbst wieder
	 PlaceAtReticle 01ShootThroughWallsCoordinateActivator 1 1 1000000

	;nur wenn ein Marker plaziert wird, also etwas im weg ist, startet das script
	if(aaaSchootThroughWallSuccesfullyPlaced ==1)
		set rStartMarker to (player.Placeatme 000ItemViewer)
		;ein paar einheiten hoch damit der laser auch bei der Waffe und nicht bei den Füßen spawnt
		rStartMarker.moveto player 0 0 0 ;TESTEN ob 16 passt		

		;NEU Jetzt einen marker bei den übergebenen koordinaten plazieren
		set rReticleMarker to (player.Placeatme 000ItemViewer)
		rReticleMarker.setPos X aaaSchootThroughWallCoordinateX
		rReticleMarker.setPos Y aaaSchootThroughWallCoordinateZ
		rReticleMarker.setPos Z aaaSchootThroughWallCoordinateZ
		
		
		;Die rotation wieder auf weltkoordinaten nullen, damit der vektor, wenn er z.B. negativ ist, nicht hinter den marker schießt
		;Wen jetzt ein negativer vektor kommt dann geht der schuss nach hinten, so solls aber auch sein weil der marker ja umgedreht wurde
		rStartMarker.SetAngle x 0
		rStartMarker.SetAngle y 0
		rStartMarker.SetAngle z 0
		
		;Distanz zwischen start und reticle punkt
		set fDistanceToReticle to rStartMarker.GetDistance rReticleMarker

		;koordinaten von startpunkt
		set fStartX to rStartMarker.GetPos x
		set fStartY to rStartMarker.GetPos y
		set fStartZ to rStartMarker.GetPos z

		;ALT koordinaten von Reticle Punkt
		;set fReticleX to rReticleMarker.GetPos x
		;set fReticleY to rReticleMarker.GetPos y			
		;set fReticleZ to rReticleMarker.GetPos z

		;NEU koordinaten vom 01ShootThroughWallsCoordinateActivator erzeugt wurden
		set fReticleX to aaaSchootThroughWallCoordinateX
		set fReticleY to aaaSchootThroughWallCoordinateY			
		set fReticleZ to aaaSchootThroughWallCoordinateZ

		;Vektor Berechen
		set fVektorX to (fStartX - fReticleX)
		set fVektorY to (fStartY - fReticleY)
		set fVektorZ to (fStartZ - fReticleZ)

		;Vektor durch distanz teilen -> einheitlicher Vektor
		set fEinheitsVektorX to (fVektorX / fDistanceToReticle)
		set fEinheitsVektorY to (fVektorY / fDistanceToReticle)
		set fEinheitsVektorZ to (fVektorZ / fDistanceToReticle)	

		;alle berechnungen fertig -> Explosionslaser starten lassen
		set bfired to 1	
		
		;die start distanz wie weit weg die erste explosion vom marker spawnt
		set iDistMulti to 1	;!TESTEN ob 100 passt!	
	endif
endif
	
end


;Varianten fürs explosions Spawnen:
;1.) Vektor
;set rNextExplosion to rStartMarker.placeatme Explosion -> rNextExplosion.disable -> rNextExplosion moveto.rStartMarker + k * Vekror offset -> rNextExplosion.enable
;2.) Globlae Koordinaten
;set rNextExplosion to rStartMarker.placeatme Explosion -> rNextExplosion.disable -> SetPos <- da braucht ich keinen vektor, sondern globale koordinaten


Begin GameMode
if (bfired == 1)
	
	;die explosion 1000 mal spawnend und immer 1 weiter setzen
	if (iDistMulti	<= 1000);!testen ob 1000 passt!

		;Berechnen wo die explosion spawnt
		set fExplosionDistanceVektorX to (iDistMulti * fEinheitsVektorX)
		set fExplosionDistanceVektorY to (iDistMulti * fEinheitsVektorY)
		set fExplosionDistanceVektorZ to (iDistMulti * fEinheitsVektorZ)

		;explosion weit weg (9999 einheiten hinter marker) spawnend und disablen, dann verschieben und enablen
		set rNextExplosion to rStartMarker.placeatme 01FAmmoExplosionSmall 1 9999 1
		rNextExplosion.disable
		rNextExplosion.moveto rStartMarker fExplosionDistanceVektorX fExplosionDistanceVektorY fExplosionDistanceVektorZ
	
		;distanz für nächste explosion setzen
		set iDistMulti to iDistMulti+1	


	;nach 1000 mal spawnen marker löschen, den Explosionslaser beenden,
	else
		rStartMarker.disable
		rStartMarker.markfordelete
		rReticleMarker.disable
		rReticleMarker.markfordelete
		set bfired to 0
	endif		
endif
end




 

 

Script on the activator that is spwaned under the reticle (type: object)

scn 01FShootThroughWallsCoordinateActivatorSCRIPT

ref selfREF
short Timer
short start

Begin OnLoad 		;läuft nur einmal durch
	set selfREF to getself

	;schreibt eigene koordinaten in die globalen variablen
	set aaaSchootThroughWallCoordinateX to (selfREF.GetPos X)
	set aaaSchootThroughWallCoordinateY to (selfREF.GetPos Y)
	set aaaSchootThroughWallCoordinateZ to (selfREF.GetPos Z)


	;teilt dem anderen script mit ob tatsächlich auch ein reticle marker plaziert wurde
	set aaaSchootThroughWallSuccesfullyPlaced to 1

	;löscht sich wieder
	selfREF.disable
	selfREF.markfordelete
	disable
	markfordelete

end

Link to comment
Share on other sites

Considering the OnFire block is FNV only, that might be part of the problem. Maybe they didn't fully implement it. Maybe it only ever instantiates the first time you fire the weapon.

 

Thanks for the reply gsmanners!

I got the "onFire" on a other weapon of mine and it works there, every shot.

The onFire is also used on some vanilla weapons in NV, like the archimedis/Helios Orbital Laser beam.

Link to comment
Share on other sites

Okay, well it's probably some misfire in your logic, then. :)

 

I would check the logic in these lines:

 

if(aaaSchootThroughWallSuccesfullyPlaced ==1)

 

and

 

set aaaSchootThroughWallSuccesfullyPlaced to 1

 

See if that matches up with the timing in your OnWhatever blocks.

 

 

I did some more testing:

I put a "showMessage" with nine vars in the beginning of the on fire block. The nine vars are the 3x3 coordinates of player,target and vector.

The message is once called at the beginning of the onFire block and at it's end.

Now when I shoot I get a message displaying 3x3 coordinates where everyone is 0, thats ok.

But then I don't get the message at the end of the block.

AND WHAT IST WORST, it does not work a second time! I got to restart the game, reload the file and shoot for the message to appear aggain.

Note: the showMessage are not inside some "if" blocks, they should always display.

 

It seems your first assumption was somewhat right. The onFire works on other guns though, but here something goes wrong.

 

scn 01FShootTroughWallsTESTScript

;die marker für schussposition und zielposition
ref rStartMarker
ref rReticleMarker

;referenz auf die Explosion, um die explosion zur richtigen position zu setzen und zu aktivieren
;ist nötig da man bei placeatme
ref rNextExplosion

;die Koordinaten der Schussposition
float fStartX
float fStartY
float fStartZ

;die Koordinaten der Zielposition
float fReticleX
float fReticleY
float fReticleZ

;der resultierende Vektor
float fVektorX
float fVektorY
float fVektorZ

;der verkleinerte Einheitsvektor
float fEinheitsVektorX
float fEinheitsVektorY
float fEinheitsVektorZ

;der reultierende Vektor wo die jeweilige explosion gespawnt wird
float fExplosionDistanceVektorX
float fExplosionDistanceVektorY
float fExplosionDistanceVektorZ

;distanz zwischen Start und Ziel, zur berechnung des einheitsvektors
float fDistanceToReticle

;ob der explosionslaser gestartet ist
short bFired

;die distanz zwischen start marker und der Explosion -> also auch irgendwie die Anzahl der explosionen
short iDistMulti

;globals die vom 01ShootThroughWallsCoordinateActivator übergeben werden
;aaaSchootThroughWallSuccesfullyPlaced
;aaaSchootThroughWallCoordinateX 
;aaaSchootThroughWallCoordinateY
;aaaSchootThroughWallCoordinateZ



Begin OnFire

;TEST
ShowMessage 00ShootTroughWallsMessage	fStartX fStartY fStartZ fReticleX fReticleY fReticleZ fEinheitsVektorX fEinheitsVektorY fEinheitsVektorZ

;TEST
set bfired to 0

;Zuerst die globalen resetten
set aaaSchootThroughWallSuccesfullyPlaced to 0
set aaaSchootThroughWallCoordinateX to 0
set aaaSchootThroughWallCoordinateY to 0
set aaaSchootThroughWallCoordinateZ to 0

; Script startet nur wenn nicht schon eine Explosionlaser aktiv ist
if (bfired == 0)

	;PROBLEM Reticle marker gibt keine referenz zurück!!!
	;set rReticleMarker to (PlaceatReticle XMarkerHeading 1 1 1000000)

	;LOESUNG via activator
	;er schreibt seine koordinaten in 3 globale Variablen und löscht sich selbst wieder
	 PlaceAtReticle 01ShootThroughWallsCoordinateActivator 1 1 1000000


	;TEST:
	set aaaSchootThroughWallSuccesfullyPlaced to 1

	;nur wenn ein Marker plaziert wird, also etwas im weg ist, startet das script
	if(aaaSchootThroughWallSuccesfullyPlaced ==1)
		set rStartMarker to (player.Placeatme 000ItemViewer)
		;ein paar einheiten hoch damit der laser auch bei der Waffe und nicht bei den Füßen spawnt
		rStartMarker.moveto player 0 0 1 ;TESTEN ob 16 passt		

		;NEU Jetzt einen marker bei den übergebenen koordinaten plazieren
		set rReticleMarker to (player.Placeatme 000ItemViewer)
		rReticleMarker.setPos X aaaSchootThroughWallCoordinateX
		rReticleMarker.setPos Y aaaSchootThroughWallCoordinateZ
		rReticleMarker.setPos Z aaaSchootThroughWallCoordinateZ
		
		
		;Die rotation wieder auf weltkoordinaten nullen, damit der vektor, wenn er z.B. negativ ist, nicht hinter den marker schießt
		;Wen jetzt ein negativer vektor kommt dann geht der schuss nach hinten, so solls aber auch sein weil der marker ja umgedreht wurde
		rStartMarker.SetAngle x 0
		rStartMarker.SetAngle y 0
		rStartMarker.SetAngle z 0
		
		;Distanz zwischen start und reticle punkt
		set fDistanceToReticle to rStartMarker.GetDistance rReticleMarker

		;koordinaten von startpunkt
		set fStartX to rStartMarker.GetPos x
		set fStartY to rStartMarker.GetPos y
		set fStartZ to rStartMarker.GetPos z

		;ALT koordinaten von Reticle Punkt
		;set fReticleX to rReticleMarker.GetPos x
		;set fReticleY to rReticleMarker.GetPos y			
		;set fReticleZ to rReticleMarker.GetPos z

		;NEU koordinaten vom 01ShootThroughWallsCoordinateActivator erzeugt wurden
		set fReticleX to aaaSchootThroughWallCoordinateX
		set fReticleY to aaaSchootThroughWallCoordinateY			
		set fReticleZ to aaaSchootThroughWallCoordinateZ

		;Vektor Berechen
		set fVektorX to (fStartX - fReticleX)
		set fVektorY to (fStartY - fReticleY)
		set fVektorZ to (fStartZ - fReticleZ)

		;Vektor durch distanz teilen -> einheitlicher Vektor
		set fEinheitsVektorX to (fVektorX / fDistanceToReticle)
		set fEinheitsVektorY to (fVektorY / fDistanceToReticle)
		set fEinheitsVektorZ to (fVektorZ / fDistanceToReticle)	

		;alle berechnungen fertig -> Explosionslaser starten lassen
		set bfired to 1	
		
		;die start distanz wie weit weg die erste explosion vom marker spawnt
		set iDistMulti to 1	;!TESTEN ob 100 passt!	
	endif
endif

;TEST
ShowMessage 00ShootTroughWallsMessage	fStartX fStartY fStartZ fReticleX fReticleY fReticleZ fEinheitsVektorX fEinheitsVektorY fEinheitsVektorZ

end


;Varianten fürs explosions Spawnen:
;1.) Vektor
;set rNextExplosion to rStartMarker.placeatme Explosion -> rNextExplosion.disable -> rNextExplosion moveto.rStartMarker + k * Vekror offset -> rNextExplosion.enable
;2.) Globlae Koordinaten
;set rNextExplosion to rStartMarker.placeatme Explosion -> rNextExplosion.disable -> SetPos <- da braucht ich keinen vektor, sondern globale koordinaten


Begin GameMode
if (bfired == 1)
	
	;die explosion 1000 mal spawnend und immer 1 weiter setzen
	if (iDistMulti	<= 1000);!testen ob 1000 passt!

		;Berechnen wo die explosion spawnt
		set fExplosionDistanceVektorX to (iDistMulti * fEinheitsVektorX)
		set fExplosionDistanceVektorY to (iDistMulti * fEinheitsVektorY)
		set fExplosionDistanceVektorZ to (iDistMulti * fEinheitsVektorZ)

		;explosion weit weg (9999 einheiten hinter marker) spawnend und disablen, dann verschieben und enablen
		set rNextExplosion to rStartMarker.placeatme 01FAmmoExplosionSmall 1 9999 1
		rNextExplosion.disable
		rNextExplosion.moveto rStartMarker fExplosionDistanceVektorX fExplosionDistanceVektorY fExplosionDistanceVektorZ
	
		;distanz für nächste explosion setzen
		set iDistMulti to iDistMulti+1	


	;nach 1000 mal spawnen marker löschen, den Explosionslaser beenden,
	else
		rStartMarker.disable
		rStartMarker.markfordelete
		rReticleMarker.disable
		rReticleMarker.markfordelete
		set bfired to 0
	endif		
endif
end

 

 

 

 

This TEST script works!

scn 01FShootTroughWallFUNCTIONSTESTScript

float fStartX
float fStartY
float fStartZ

float fReticleX
float fReticleY
float fReticleZ

float fEinheitsVektorX
float fEinheitsVektorY
float fEinheitsVektorZ

Begin OnFire

ShowMessage 00ShootTroughWallsMessage fStartX fStartY fStartZ fReticleX fReticleY fReticleZ fEinheitsVektorX fEinheitsVektorY fEinheitsVektorZ

set fStartX to 5
set fStartY to 5
set fStartZ to 5
set fReticleX to 5
set fReticleY to 5
set fReticleZ to 5
set fEinheitsVektorX to 5
set fEinheitsVektorY to 5
set fEinheitsVektorZ to 5

ShowMessage 00ShootTroughWallsMessage fStartX fStartY fStartZ fReticleX fReticleY fReticleZ fEinheitsVektorX fEinheitsVektorY fEinheitsVektorZ

set fStartX to 0
set fStartY to 0
set fStartZ to 0
set fReticleX to 0
set fReticleY to 0
set fReticleZ to 0
set fEinheitsVektorX to 0
set fEinheitsVektorY to 0
set fEinheitsVektorZ to 0

ShowMessage 00ShootTroughWallsMessage fStartX fStartY fStartZ fReticleX fReticleY fReticleZ fEinheitsVektorX fEinheitsVektorY fEinheitsVektorZ
end

It seems like the ORIGINAL script would never leave the "if (bfired == 0)" Block

 

 

EDIT:

After some more testing I noticed that the coordiante activator writes its coordinates into the globals way to slowly.

The shot is always using the previous target coordinates.

So I need a way to "pause" the script for a while, till the coordinates are right, you know of such a way?

I can't use getSecondsPassed in the OnFireBlock...

 

The current TEST SCRIPT (not the origianl)

scn 01FShootTroughWallFUNCTIONSTESTScript

float fStartX
float fStartY
float fStartZ

float fReticleX
float fReticleY
float fReticleZ

float fEinheitsVektorX
float fEinheitsVektorY
float fEinheitsVektorZ


;aaaSchootThroughWallCoordinateX 
;aaaSchootThroughWallCoordinateY
;aaaSchootThroughWallCoordinateZ

Begin OnFire

PlaceAtReticle 01ShootThroughWallsCoordinateActivator 1 1 1000000

ShowMessage 00ShootTroughWallsMessage fStartX fStartY fStartZ fReticleX fReticleY fReticleZ fEinheitsVektorX fEinheitsVektorY fEinheitsVektorZ


;PROBLEM:
;aaaSchootThroughWallCoordinate sind noch vom vorherigen schuss.
;Die koordinaten werden zu langsam in die globalen geschrieben, das script ruft sie aber schon eher ab


set fStartX to player.getPos x
set fStartY to player.getPos x
set fStartZ to player.getPos x
set fReticleX to aaaSchootThroughWallCoordinateX 
set fReticleY to aaaSchootThroughWallCoordinateY 
set fReticleZ to aaaSchootThroughWallCoordinateZ
set fEinheitsVektorX to 5
set fEinheitsVektorY to 5
set fEinheitsVektorZ to 5

ShowMessage 00ShootTroughWallsMessage fStartX fStartY fStartZ fReticleX fReticleY fReticleZ fEinheitsVektorX fEinheitsVektorY fEinheitsVektorZ

set fStartX to 0
set fStartY to 0
set fStartZ to 0
set fReticleX to 0
set fReticleY to 0
set fReticleZ to 0
set fEinheitsVektorX to 0
set fEinheitsVektorY to 0
set fEinheitsVektorZ to 0

ShowMessage 00ShootTroughWallsMessage fStartX fStartY fStartZ fReticleX fReticleY fReticleZ fEinheitsVektorX fEinheitsVektorY fEinheitsVektorZ
end

Edited by Nightterror5
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...