It's there for the taking. This hack should work:
Edit: Wait, no, it won't work. You'll still have to alter it so UpdateParticles() takes a camera entity as the argument instead of a Player object, and you'll also need to copy a few more functions (I think just UpdateVector and Vec_Copy), can't get the source at the moment (on my parent's PC) so I can't edit this so it works properly.
; The Flag object is used by Vein to store and retrieve variables.
; A good example of its use can be found under c_particle.bb or c_sspart.bb
Type Flags
Field UFlag# [32] ;user flags, can be modified via the scripting engine
Field VFlag# [32] ;flags set by functions in Vein
Field BitFlag% [31] ;bit flags, these should only be set as 0 or 1, because that's what they'll get turned into the instant they're saved
End Type
; The Vector object is used by Vein to store position, acceleration, velocity, angles, etc.
; There are also functions to modify/return these objects (such as CrossProduct, Magnitude, and Vec_Dist)
Type Vector
Field X#,Y#,Z# ;World position
Field Pan#,Tilt#,Roll# ;Absolute Angles
Field Vel_Pan#,Vel_Tilt#,Vel_Roll# ;Angle velocity
Field Accel_Pan#,Accel_Tilt#,Accel_Roll# ;Angle acceleration
Field Vel_X#,Vel_Y#,Vel_Z# ;Local velocity
Field Accel_X#,Accel_Y#,Accel_Z# ;Local acceleration
End Type
;Particle Object
;Used to record and update particles created by emitters.
Type Particle
Field Vert ;The upper-left corner vertex of the particle's triangle.
;Field Piv
Field Life% ;The life of the particle before it dies.
Field Alpha# ;The particle's current alpha.
Field Size# ;The particle's current size.
Field V.Vector ;The particle's position and velocity. This is copied from its parent emitter.
Field Parent.Emitter ;The particle's parent emitter.
Field Roll# ;The particle's current angle (roll).
End Type
;Emitter Object
;Used to record and update emitters.
Type Emitter
Field Child.Emitter ;The emitter's child
Field V.Vector ;The position, velocity, angle, and acceleration of the particles the emitter creates
Field F.Flags ;Emitter flags
Field Piv ;The pivot used to create the particles.
Field Parent.Emitter ;The parent of the emitter.
Field Bmap% ;The handle of the texture it uses.
Field Mesh% ;The mesh it uses to store the particles.
Field Surface% ;The surface that stores the particle triangles and vertices.
End Type
;Particle Magnet object
;Used to alter the position and velocity of particles
Type Magnet
Field V.Vector ;Position
Field Enabled ;Enabled?
Field Rad# ;Radius of affection
Field Mag# ;Magnitude
Field Falloff% ;Falloff flag
End Type
Const SSPARENT = 5
Const SSCHILD = 4
Global P_TIMEBETWEEN = 4
; Creates an emitter.
; Almost all of the parameters are self explanatory.
; P = The Parent of this emitter. Pass Null to this argument if it isn't a child.
; Blend = The blend mode of the particles. Valid constants are: B_ADD, B_MUL, B_ALF.
; Life = How long before a particle dies, regardless of the circumstances.
; SizeR = The amount by which the size of particles is reduced per frame.
; AlphaR = The amount by which the alpha of particles is reduced per frame.
; AlphaD = The distance before the particles begin to fade out.
; ARR = Toggles whether to set a random roll for the particles.
; FE = True if particles are emitted only once per so many frames, or False if particles are to be created every frame.
; return = An Emitter object if successful, Null if not.
Function CreateEmitter.Emitter( V.Vector, Bmap, P.Emitter, Blend=B_ADD, Life=200, Size#=1, Alpha#=1, SizeR#=0, AlphaR#=.2, AlphaD#=1000, ARR=False, FE=False, Enabled=True)
If Not V <> Null Or BMap <> 0 Then Return Null
E.Emitter = New Emitter
E\V.Vector = V.Vector
E\Bmap = Bmap ;Color+Alpha+ClampedU+ClampedV
If E\Bmap <> 0 Then
E\Mesh = CreateMesh() ;create the mesh
E\Surface = CreateSurface(E\Mesh)
EntityTexture E\Mesh, E\Bmap
EntityBlend E\Mesh, Blend
EntityFX E\Mesh, 1+2+32 ;Full bright + Vertex Colors + Forced Alpha
E\Piv = CreatePivot()
PositionEntity E\Piv, E\V\X, E\V\Y, E\V\Z, True
E\F.Flags = New Flags
E\F\VFlag[1] = Blend
E\F\VFlag[2] = Life
E\F\VFlag[3] = Size
E\F\VFlag[4] = Alpha
E\F\VFlag[5] = SizeR
E\F\VFlag[6] = AlphaR
E\F\VFlag[7] = AlphaD
E\F\VFlag[8] = ARR
E\F\VFlag[9] = FE
E\F\VFlag[10]= Enabled
E\F\VFlag[11]= SSPARENT
If P.Emitter <> Null Then
P\Child.Emitter = E.Emitter
E\F\VFlag[11] = SSCHILD
EndIf
Return E
Else
Delete E
Return Null
EndIf
End Function
; Adds a particle that is a child of the emitter.
; E = The parent of the particle.
; F = If a particle, upon death, has a child emitter then pass that particle to this argument.
; return = A Particle object. Nobody keeps track of them, why should you?
Function AddParticle.Particle(E.Emitter, F.Particle)
P.Particle = New Particle
;P\Piv = CreatePivot()
If F <> Null Then
P\Parent = F\Parent\Child
P\V = Vec_Copy(F\V)
P\V\X = P\V\X + P\Parent\V\X
P\V\Y = P\V\Y + P\Parent\V\Y
P\V\Z = P\V\Z + P\Parent\V\Z
Else
P\Parent = E
P\V = Vec_Copy(P\Parent\V)
EndIf
P\Size = P\Parent\F\VFlag[3]
P\Alpha = P\Parent\F\VFlag[4]
P\Life = P\Parent\F\VFlag[2]
;PositionEntity P\Piv, P\V\X, P\V\Y, P\V\Z
P\Parent\F\VFlag[32] = P\Parent\F\VFlag[32] + 1
If P\Parent\F\VFlag[8] = True Then
SeedRnd(MilliSecs())
P\Roll# = Rnd(0.000, 360.000)
Else
P\Roll# = P\V\Roll
EndIf
End Function
; Updates all particles.
; Pl = The Player object that the particles should face.
; return = True if successful, False if not.
Function UpdateParticles(Pl.Player)
If Not Pl <> Null Then
Pl = First Player
If Not Pl <> Null Then Return False
EndIf
For E.Emitter = Each Emitter
ClearSurface E\Surface
If E\F\VFlag[10] And E\F\VFlag[11] = SSPARENT And E\F\VFlag[15] = P_TIMEBETWEEN Then
E\F\VFlag[15] = 0
AddParticle E, Null
EndIf
If E\F\VFlag[9] Then
E\F\VFlag[15] = Max(E\F\VFlag[15] + 1,P_TIMEBETWEEN)
Else
E\F\VFlag[15] = P_TIMEBETWEEN
EndIf
Next
For P.Particle = Each Particle
If P\Parent <> Null Then
P\Life = P\Life - 1
P\Alpha = P\Alpha + P\Parent\F\VFlag[6]
P\Size = P\Size + P\Parent\F\VFlag[5]
If (P\Parent\F\VFlag[6] <= 0 And P\Alpha <= 0) Or (P\Parent\F\VFlag[6] => 1 And P\Alpha => 1) Or (P\Parent\F\VFlag[5] <= 0 And P\Size# <= 0) Or (P\Life = 0) Then
If P\Parent\Child.Emitter <> Null Then
AddParticle(P\Parent\Child, P)
EndIf
P\Parent\F\VFlag[32] = P\Parent\F\VFlag[32] - 1 ;decrease particle count for the object
Delete P\V
Delete P
Else
For M.Magnet = Each Magnet
Distance# = Min(Vec_Dist(P\V,M\V),1)
If M\Enabled And Distance < M\Rad Then
If M\Falloff = True Then Distance = M\Rad - Distance
L.Vector = Vec_Diff(P\V,M\V)
X_Factor# = L\X/Distance
Y_Factor# = L\Y/Distance
Z_Factor# = L\Z/Distance
P\V\X = P\V\X - ( X_Factor*M\Mag )
P\V\Y = P\V\Y - ( Y_Factor*M\Mag )
P\V\Z = P\V\Z - ( Z_Factor*M\Mag )
Delete L
EndIf
Next
P\Roll = P\Roll + P\Parent\V\Vel_Roll
UpdateVector P\V
PositionEntity P\Parent\Piv, P\V\X, P\V\Y, P\V\Z
TranslateEntity P\Parent\Piv, P\V\Vel_X, P\V\Vel_Y, P\V\Vel_Z
P\V\X = EntityX(P\Parent\Piv,True)
P\V\Y = EntityY(P\Parent\Piv,True)
P\V\Z = EntityZ(P\Parent\Piv,True)
PointEntity P\Parent\Piv, Pl\Camera
TurnEntity P\Parent\Piv, 180, 0, 0
RotateEntity P\Parent\Piv, EntityPitch(P\Parent\Piv), EntityYaw(P\Parent\Piv), P\Roll
MoveEntity P\Parent\Piv, -Abs(P\Size#), -Abs(P\Size#), 0
P\Vert = AddVertex(P\Parent\Surface, EntityX(P\Parent\Piv, True), EntityY(P\Parent\Piv, True), EntityZ(P\Parent\Piv, True), 0, 1)
If Not EntityInView(P\Parent\Piv,Pl\Camera) Then F = F + 1
MoveEntity P\Parent\Piv, 0, Abs(P\Size#)*2, 0
AddVertex(P\Parent\Surface, EntityX(P\Parent\Piv, True), EntityY(P\Parent\Piv, True), EntityZ(P\Parent\Piv, True), 0, 0)
If Not EntityInView(P\Parent\Piv,Pl\Camera) Then F = F + 1
MoveEntity P\Parent\Piv, Abs(P\Size#)*2, 0, 0
AddVertex(P\Parent\Surface, EntityX(P\Parent\Piv, True), EntityY(P\Parent\Piv, True), EntityZ(P\Parent\Piv, True), 1, 0)
If Not EntityInView(P\Parent\Piv,Pl\Camera) Then F = F + 1
MoveEntity P\Parent\Piv, 0, -Abs(P\Size#)*2, 0
AddVertex(P\Parent\Surface, EntityX(P\Parent\Piv, True), EntityY(P\Parent\Piv, True), EntityZ(P\Parent\Piv, True), 1, 1)
If Not EntityInView(P\Parent\Piv,Pl\Camera) Then F = F + 1
MoveEntity P\Parent\Piv, -Abs(P\Size#), Abs(P\Size#), 0
If Not F = 4
AddTriangle(P\Parent\Surface, P\Vert, P\Vert+1, P\Vert+2)
AddTriangle(P\Parent\Surface, P\Vert+2, P\Vert+3, P\Vert)
EndIf
F = 0
For X = 0 To 3
VertexColor P\Parent\Surface, P\Vert+X, 255, 255, 255, Min(Max(P\Alpha, 1), 0)
Next
P\V\X = EntityX(P\Parent\Piv, True) : P\V\Y = EntityY(P\Parent\Piv, True) : P\V\Z = EntityZ(P\Parent\Piv, True)
EndIf
Else
Delete P
EndIf
Next
For E.Emitter = Each Emitter
UpdateNormals E\Mesh
Next
Return True
End Function
; Frees an Emitter object.
; E = The emitter to be freed.
; return = True if successful, False if not.
Function KillEmitter(E.Emitter)
If E <> Null Then
FreeTexture E\BMap
FreeEntity E\Piv
FreeEntity E\Mesh
Delete E\F
Delete E\V
Delete E
Return True
EndIf
Return False
End Function
; Creates a Magnet object.
; Magnets affect a particle movement and speed. They typically pull particles toward them.
; V = The position of the magnet.
; Radius = The distance particles must be within before they are affected.
; Mag = The magnitude of the magnet.
; Falloff = Whether or not there's a falloff to how much the magnet affects particles.
; Enabled = True if the particles are affected by the magnet, False if not.
; return = A Magnet object, Null if not.
Function CreateMagnet.Magnet(V.Vector,Radius#,Mag#,Falloff = True,Enabled=True)
M.Magnet = New Magnet
If V.Vector <> Null
M\V = V
M\Rad = Radius
M\Mag = Mag
M\Enabled = Enabled
M\Falloff = Falloff
Return M
Else
Delete M
Return Null
EndIf
End Function
; Creates a vector.
; All parameters represent the fields of a Vector object.
; return = A Vector object.
Function Vec.Vector(X#=0,Y#=0,Z#=0,Vel_X#=0,Vel_Y#=0,Vel_Z#=0,Accel_X#=0,Accel_Y#=0,Accel_Z#=0,Pan#=0,Tilt#=0,Roll#=0) ;a duplicate of CreateVector, except it has a shorter name which means it's more convenient to use in cases
;slowly the old name will become deprecated and left in only a few modules, which will open up complete replacement of it with Vec
V.Vector = New Vector
V\X = X
V\Y = Y
V\Z = Z
V\Pan = Pan
V\Tilt = Tilt
V\Roll = Roll
V\Vel_X = Vel_X
V\Vel_Y = Vel_Y
V\Vel_Z = Vel_Z
V\Accel_X = Accel_X
V\Accel_Y = Accel_Y
V\Accel_Z = Accel_Z
Return V.Vector
End Function
Long paste. Hm.
|