I'm still stuck trying to make the "actor-array-that-the-compiler-thinks-is-a-boolean-array" work! Any ideas why doesn't it work???
BTW, I finished coding the rather simple CaioOrganism:
Code: Select all
// |CaioOrganism|
//
// An way of organizing a tree of CaioJunction's.
class CaioOrganism extends Actor;
var CaioJunction TopJunction;
var float AccumulatedTime;
var int Attempts;
function Timer()
{
GoToState('HasNoTopJunction');
}
state() SearchingTopJunction
{
function PostBeginPlay()
{
SetTimer(30, false);
}
function Tick(float TimeDelta)
{
local CaioJunction CJ;
AccumulatedTime += TimeDelta;
if ( AccumulatedTime > Attempts * 5 )
foreach AllActors(class'CaioJunction', CJ)
if ( CJ.MainOrganism == self && CJ.PreviousJunction == None )
{
TopJunction = CJ;
GoToState('HasTopJunction');
}
}
}
state() HasNoTopJunction {}
state HasTopJunction {}
EDIT: I did get around it with a automatic detection of NextJunctions in a basis: every CaioJunction with PreviousJunction == Self is a NextJunction. I did also clean up the argument list at SetJunctionProperties, and it looks WAY better, as well as some awesome fixes.. and now IT COMPILES:
Code: Select all
// |CaioJunction|
//
// A alternative to CaioBone. THIS IS A STUB! Does not have much physics code yet.
//
// A junction is a spot where a mesh protrudes from, that can add ragdoll physics
// to any meshes.
//
// Usually coordinate by a main CaioOrganism.
class CaioJunction extends Actor;
var CaioJunction NextJunctions[32];
var CaioJunction PreviousJunction;
var Sound ActorCollisionSounds[32];
var Sound GenericCollisionSound;
var Class<Actor> ActorCollisionClasses[32];
var float JunctionFlexibility;
var Rotator MeshOffsetRotation;
var Sound GeometryCollisionSound;
var float JunctionHealth;
//===
// Next 3 variables:
// AC = At Actor
// AJ = At Junction
var Class<Actor> ActorCollisionEffectAA;
var Class<Actor> ActorCollisionEffectAJ;
var Class<Actor> GeometryCollisionEffectAJ;
//===
var Sound GenericBSPCollisionSound;
var Rotator DisplayRotationOffset;
var enum EJunctionLocationType
{
JLT_AtOwner,
JLT_AtOrganism,
JLT_AtPreviousEndPoint,
JLT_AtSpawnLocation
} JunctionLocationType;
var CaioOrganism MainOrganism;
var Vector EndPoint;
var float Buoyancy;
static function vector NewVector(float X, float Y, float Z)
{
local Vector V;
V.X = X;
V.Y = Y;
V.Z = Z;
return V;
}
function PreBeginPlay()
{
local int i;
local CaioJunction CJ;
local bool bSet;
foreach AllActors(class'CaioJunction', CJ)
if ( CJ.PreviousJunction == self )
{
bSet = False;
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] == None )
{
NextJunctions[i] = CJ;
bSet = True;
break;
}
if ( !bSet )
Warn("Warning:" @ name $ "'s amount of NextJunctions exceed 32! Other CaioJunctions will be ignored and NOT set as NextJunctions in" @ name $ "!");
}
}
function SetJunctionProperties(
CaioOrganism Organism,
CaioJunction PreviousJunction,
optional float JunctionHealth,
optional EJunctionLocationType LocationType,
optional Class<Actor> ActorCollisionEffectAA,
optional Class<Actor> ActorCollisionEffectAJ,
optional Class<Actor> GeometryCollisionEffectAJ,
optional Sound GenericCollisionSound,
optional Sound GeometryCollisionSound,
optional Class<Actor> ActorCollisionClasses[32],
optional Sound ActorCollisionSounds[32],
optional float Buoyancy
)
{
local vector EPV;
local int i;
self.PreviousJunction = PreviousJunction;
self.JunctionHealth = JunctionHealth;
JunctionLocationType = LocationType;
self.ActorCollisionEffectAA = ActorCollisionEffectAA;
self.ActorCollisionEffectAJ = ActorCollisionEffectAJ;
self.GeometryCollisionEffectAJ = GeometryCollisionEffectAJ;
self.GenericCollisionSound = GenericCollisionSound;
self.GeometryCollisionSound = GeometryCollisionSound;
self.Buoyancy = Buoyancy;
self.MainOrganism = Organism;
for ( i = 0; i < 32; i++ )
{
self.ActorCollisionClasses[i] = ActorCollisionClasses[i];
self.ActorCollisionSounds[i] = ActorCollisionSounds[i];
}
if ( JunctionLocationType == JLT_AtOwner )
SetLocation(Owner.Location);
else if ( JunctionLocationType == JLT_AtOrganism )
SetLocation(MainOrganism.Location);
else if ( JunctionLocationType == JLT_AtPreviousEndPoint )
GoToState('Locating');
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
EPV += NextJunctions[i].Location;
self.EndPoint = EPV / 16;
if ( !IsInState('Locating') )
GoToState('ActivatedJunction');
}
auto state() DeactivatedJunction
{
}
state Locating
{
Begin:
while ( PreviousJunction == None || PreviousJunction.EndPoint == vect(0,0,0) )
sleep(0.0);
SetLocation(PreviousJunction.EndPoint);
GoToState('ActivatedJunction');
}
function IterateActorReflect(Actor Other, Vector HitNormal, optional bool bTop)
{
local int i;
local bool bFoundClass;
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateActorReflect(Other, HitNormal, true);
for ( i = 0; i < 32; i++ )
if ( Other.class == ActorCollisionClasses[i] && ActorCollisionSounds[i] != None && !bTop )
{
PlaySound(ActorCollisionSounds[i]);
bFoundClass = True;
}
if ( !bFoundClass )
PlaySound(GenericCollisionSound);
if ( !bTop && ActorCollisionEffectAJ != None )
Spawn(ActorCollisionEffectAJ, self);
if ( !bTop && ActorCollisionEffectAA != None )
Spawn(ActorCollisionEffectAA, self, ActorCollisionEffectAA.Name, Other.Location, Other.Rotation);
Velocity += HitNormal * (VSize(Velocity) * Buoyancy);
}
function IterateWallReflect(Vector HitNormal, optional bool bTop)
{
local int i;
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateWallReflect(HitNormal, true);
if ( !bTop && GeometryCollisionSound != None )
PlaySound(GeometryCollisionSound);
if ( !bTop && GeometryCollisionEffectAJ != None )
Spawn(GeometryCollisionEffectAJ, self);
Velocity += HitNormal * (VSize(Velocity) * Buoyancy);
}
state ActivatedJunction
{
function Tick(float TimeDelta)
{
local int i;
local Actor CollidedActor;
local Vector ActorNormal;
local Vector Unused;
CollidedActor = Trace(Unused, ActorNormal, EndPoint, Location);
if ( CollidedActor == None )
return;
else if ( CollidedActor.Name == 'LevelInfo0' )
{
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateWallReflect(ActorNormal);
}
else
{
if ( CollidedActor.bBlockActors )
{
CollidedActor.Bump(self);
Bump(CollidedActor);
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].Bump(CollidedActor);
}
else
{
CollidedActor.Touch(self);
Touch(CollidedActor);
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].Touch(CollidedActor);
}
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateActorReflect(CollidedActor, ActorNormal);
}
}
function Landed(vector HitNormal)
{
IterateWallReflect(HitNormal);
}
}
All that remains now is to make ONE more class, that is spawned between the junction and it's PreviousJunction, that somehow can rotate accordingly to the offsets of the junctions it's in between!
EDIT 2: To avoid complicating things, I decided instead that the mesh will be displayed by the junction itself. Keep in mind the mesh, however, needs to have it's origin at it's back edge for it to be displayed properly!
So, I finished the BASIC LEVEL physics code:
Code: Select all
// |CaioJunction|
//
// A alternative to CaioBone. THIS IS A STUB! Does not have much physics code yet.
//
// A junction is a spot where a mesh protrudes from, that can add ragdoll physics
// to any meshes.
//
// Usually coordinate by a main CaioOrganism.
class CaioJunction extends Actor;
var bool bDamaging;
var CaioJunction NextJunctions[32];
var CaioJunction PreviousJunction;
var Sound ActorCollisionSounds[32];
var Sound GenericCollisionSound;
var Class<Actor> ActorCollisionClasses[32];
var float JunctionFlexibility;
var Rotator MeshOffsetRotation;
var Sound GeometryCollisionSound;
var float JunctionHealth;
//===
// Next 3 variables:
// AC = At Actor
// AJ = At Junction
var Class<Actor> ActorCollisionEffectAA;
var Class<Actor> ActorCollisionEffectAJ;
var Class<Actor> GeometryCollisionEffectAJ;
//===
var Sound GenericBSPCollisionSound;
var Rotator DisplayRotationOffset;
var enum EJunctionLocationType
{
JLT_AtOwner,
JLT_AtOrganism,
JLT_AtPreviousEndPoint,
JLT_AtSpawnLocation
} JunctionLocationType;
var CaioOrganism MainOrganism;
var Vector EndPoint;
var float Buoyancy;
var float Lenght;
static function vector NewVector(float X, float Y, float Z)
{
local Vector V;
V.X = X;
V.Y = Y;
V.Z = Z;
return V;
}
function PreBeginPlay()
{
local int i;
local CaioJunction CJ;
local bool bSet;
foreach AllActors(class'CaioJunction', CJ)
if ( CJ.PreviousJunction == self )
{
bSet = False;
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] == None )
{
NextJunctions[i] = CJ;
bSet = True;
break;
}
if ( !bSet )
Warn("Warning:" @ name $ "'s amount of NextJunctions exceed 32! Other CaioJunctions will be ignored and NOT set as NextJunctions in" @ name $ "!");
}
}
function SetJunctionProperties(
CaioOrganism Organism,
CaioJunction PreviousJunction,
float Lenght,
optional float JunctionHealth,
optional EJunctionLocationType LocationType,
optional Class<Actor> ActorCollisionEffectAA,
optional Class<Actor> ActorCollisionEffectAJ,
optional Class<Actor> GeometryCollisionEffectAJ,
optional Sound GenericCollisionSound,
optional Sound GeometryCollisionSound,
optional Class<Actor> ActorCollisionClasses[32],
optional Sound ActorCollisionSounds[32],
optional float Buoyancy
)
{
local int i;
self.PreviousJunction = PreviousJunction;
self.JunctionHealth = JunctionHealth;
JunctionLocationType = LocationType;
self.ActorCollisionEffectAA = ActorCollisionEffectAA;
self.ActorCollisionEffectAJ = ActorCollisionEffectAJ;
self.GeometryCollisionEffectAJ = GeometryCollisionEffectAJ;
self.GenericCollisionSound = GenericCollisionSound;
self.GeometryCollisionSound = GeometryCollisionSound;
self.Buoyancy = Buoyancy;
self.MainOrganism = Organism;
self.Lenght = Lenght;
if ( JunctionHealth == 0 )
bDamaging = False;
else
bDamaging = True;
for ( i = 0; i < 32; i++ )
{
self.ActorCollisionClasses[i] = ActorCollisionClasses[i];
self.ActorCollisionSounds[i] = ActorCollisionSounds[i];
}
if ( JunctionLocationType == JLT_AtOwner )
SetLocation(Owner.Location);
else if ( JunctionLocationType == JLT_AtOrganism )
SetLocation(MainOrganism.Location);
else if ( JunctionLocationType == JLT_AtPreviousEndPoint )
GoToState('Locating');
if ( !IsInState('Locating') )
GoToState('ActivatedJunction');
}
auto state() DeactivatedJunction
{
}
state Locating
{
Begin:
while ( PreviousJunction == None || PreviousJunction.EndPoint == vect(0,0,0) )
sleep(0.0);
SetLocation(PreviousJunction.EndPoint);
GoToState('ActivatedJunction');
}
function IterateActorReflect(Actor Other, Vector HitNormal, optional bool bTop)
{
local int i;
local bool bFoundClass;
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateActorReflect(Other, HitNormal, true);
for ( i = 0; i < 32; i++ )
if ( Other.class == ActorCollisionClasses[i] && ActorCollisionSounds[i] != None && !bTop )
{
PlaySound(ActorCollisionSounds[i]);
bFoundClass = True;
}
if ( !bFoundClass )
PlaySound(GenericCollisionSound);
if ( !bTop && ActorCollisionEffectAJ != None )
Spawn(ActorCollisionEffectAJ, self);
if ( !bTop && ActorCollisionEffectAA != None )
Spawn(ActorCollisionEffectAA, self, ActorCollisionEffectAA.Name, Other.Location, Other.Rotation);
Velocity += HitNormal * (VSize(Velocity) * Buoyancy);
}
function IterateWallReflect(Vector HitNormal, optional bool bTop)
{
local int i;
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateWallReflect(HitNormal, true);
if ( !bTop && GeometryCollisionSound != None )
PlaySound(GeometryCollisionSound);
if ( !bTop && GeometryCollisionEffectAJ != None )
Spawn(GeometryCollisionEffectAJ, self);
Velocity += HitNormal * (VSize(Velocity) * Buoyancy);
}
state ActivatedJunction
{
function TakeDamage(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, name DamageType)
{
local int i;
local int i2;
if ( bDamaging )
{
JunctionHealth -= Damage;
if ( JunctionHealth <= 0 )
{
for ( i = 0; i < 32; i++ )
{
if ( NextJunctions[i] != None )
NextJunctions[i].PreviousJunction = None;
if ( PreviousJunction.NextJunctions[i] == self )
for ( i2 = i; i2 < 31; i2++ )
{
if ( PreviousJunction.NextJunctions[i2 + 1] == None )
break;
PreviousJunction.NextJunctions[i2] = PreviousJunction.NextJunctions[i2 + 1];
}
}
Destroy();
}
}
}
function Tick(float TimeDelta)
{
local int i;
local Actor CollidedActor;
local Vector ActorNormal;
local Vector Unused;
local Vector EPV;
CollidedActor = Trace(Unused, ActorNormal, EndPoint, Location);
if ( CollidedActor == None )
return;
else if ( CollidedActor.Name == 'LevelInfo0' )
{
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateWallReflect(ActorNormal);
}
else
{
if ( CollidedActor.bBlockActors )
{
CollidedActor.Bump(self);
Bump(CollidedActor);
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].Bump(CollidedActor);
}
else
{
CollidedActor.Touch(self);
Touch(CollidedActor);
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].Touch(CollidedActor);
}
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateActorReflect(CollidedActor, ActorNormal);
}
for ( i = 0; i < 32; i++ )
if ( VSize(NextJunctions[i].Location - Location) != Lenght )
MoveSmooth(Normal(NextJunctions[i].Location - Location) * Lenght);
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] != None )
EPV += NextJunctions[i].Location;
EndPoint = EPV / 32;
}
function Landed(vector HitNormal)
{
IterateWallReflect(HitNormal);
}
}
I don't have meshes to test this, so could someone lend a mesh with it's origin at a edge?
EDIT 3: Now you can place custom ragdolls in maps!
Code: Select all
// |CaioJunction|
//
// A alternative to CaioBone. THIS IS A STUB! Does not have much physics code yet.
//
// A junction is a spot where a mesh protrudes from, that can add ragdoll physics
// to any meshes.
//
// Usually coordinate by a main CaioOrganism.
class CaioJunction extends Actor;
var(Junction) bool bMapJunction;
var(Junction) name PreviousJunctionName;
var(Junction) bool bShootable;
var CaioJunction NextJunctions[32];
var CaioJunction PreviousJunction;
var(Junction) Sound ActorCollisionSounds[32];
var(Junction) Sound GenericCollisionSound;
var(Junction) Class<Actor> ActorCollisionClasses[32];
var(Junction) Sound GeometryCollisionSound;
var(Junction) float JunctionHealth;
//===
// Next 3 variables:
// AC = At Actor
// AJ = At Junction
var(Junction) Class<Actor> ActorCollisionEffectAA;
var(Junction) Class<Actor> ActorCollisionEffectAJ;
var(Junction) Class<Actor> GeometryCollisionEffectAJ;
//===
var(Junction) Sound GenericBSPCollisionSound;
var(Junction) Rotator DisplayRotationOffset;
var(Junction) enum EJunctionLocationType
{
JLT_AtOwner,
JLT_AtOrganism,
JLT_AtPreviousEndPoint,
JLT_AtSpawnLocation
} JunctionLocationType;
var(Junction) name MainOrganismName;
var CaioOrganism MainOrganism;
var Vector EndPoint;
var(Junction) float Buoyancy;
var(Junction) float Lenght;
static function vector NewVector(float X, float Y, float Z)
{
local Vector V;
V.X = X;
V.Y = Y;
V.Z = Z;
return V;
}
function PreBeginPlay()
{
local CaioJunction CJ;
local CaioOrganism BS;
foreach AllActors(class'CaioJunction', CJ)
{
if ( bMapJunction && CJ.Name == PreviousJunctionName )
PreviousJunction = CJ;
}
foreach AllActors(class'CaioOrganism', BS)
{
if ( bMapJunction && BS.Name == MainOrganismName )
MainOrganism = BS;
}
}
function BeginPlay()
{
local int i;
local CaioJunction CJ;
local bool bSet;
foreach AllActors(class'CaioJunction', CJ)
{
if ( CJ.PreviousJunction == self )
{
bSet = False;
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] == None )
{
NextJunctions[i] = CJ;
bSet = True;
break;
}
if ( !bSet )
Warn("One of" @ name $ "'s NextJunctions wasn't set! Decrease the amount of Junctions that have this Junction as PreviousJunction to lower than 33 or contact me if this doesn't solves!");
}
}
}
function SetJunctionProperties(
CaioOrganism Organism,
CaioJunction PreviousJunction,
float Lenght,
optional float JunctionHealth,
optional EJunctionLocationType LocationType,
optional Class<Actor> ActorCollisionEffectAA,
optional Class<Actor> ActorCollisionEffectAJ,
optional Class<Actor> GeometryCollisionEffectAJ,
optional Sound GenericCollisionSound,
optional Sound GeometryCollisionSound,
optional Class<Actor> ActorCollisionClasses[32],
optional Sound ActorCollisionSounds[32],
optional float Buoyancy
)
{
local int i;
self.PreviousJunction = PreviousJunction;
self.JunctionHealth = JunctionHealth;
JunctionLocationType = LocationType;
self.ActorCollisionEffectAA = ActorCollisionEffectAA;
self.ActorCollisionEffectAJ = ActorCollisionEffectAJ;
self.GeometryCollisionEffectAJ = GeometryCollisionEffectAJ;
self.GenericCollisionSound = GenericCollisionSound;
self.GeometryCollisionSound = GeometryCollisionSound;
self.Buoyancy = Buoyancy;
self.MainOrganism = Organism;
self.Lenght = Lenght;
if ( JunctionHealth == 0 )
bShootable = False;
else
bShootable = True;
for ( i = 0; i < 32; i++ )
{
self.ActorCollisionClasses[i] = ActorCollisionClasses[i];
self.ActorCollisionSounds[i] = ActorCollisionSounds[i];
}
if ( JunctionLocationType == JLT_AtOwner )
SetLocation(Owner.Location);
else if ( JunctionLocationType == JLT_AtOrganism )
SetLocation(MainOrganism.Location);
else if ( JunctionLocationType == JLT_AtPreviousEndPoint )
GoToState('Locating');
if ( !IsInState('Locating') )
GoToState('ActivatedJunction');
}
auto state() DeactivatedJunction
{
}
state Locating
{
Begin:
while ( PreviousJunction == None || PreviousJunction.EndPoint == vect(0,0,0) )
sleep(0.0);
SetLocation(PreviousJunction.EndPoint);
GoToState('ActivatedJunction');
}
function IterateActorReflect(Actor Other, Vector HitNormal, optional bool bTop)
{
local int i;
local bool bFoundClass;
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateActorReflect(Other, HitNormal, true);
for ( i = 0; i < 32; i++ )
if ( Other.class == ActorCollisionClasses[i] && ActorCollisionSounds[i] != None && !bTop )
{
PlaySound(ActorCollisionSounds[i]);
bFoundClass = True;
}
if ( !bFoundClass )
PlaySound(GenericCollisionSound);
if ( !bTop && ActorCollisionEffectAJ != None )
Spawn(ActorCollisionEffectAJ, self);
if ( !bTop && ActorCollisionEffectAA != None )
Spawn(ActorCollisionEffectAA, self, ActorCollisionEffectAA.Name, Other.Location, Other.Rotation);
Velocity += HitNormal * (VSize(Velocity) * Buoyancy);
}
function IterateWallReflect(Vector HitNormal, optional bool bTop)
{
local int i;
for ( i = 0; i < 16; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateWallReflect(HitNormal, true);
if ( !bTop && GeometryCollisionSound != None )
PlaySound(GeometryCollisionSound);
if ( !bTop && GeometryCollisionEffectAJ != None )
Spawn(GeometryCollisionEffectAJ, self);
Velocity += HitNormal * (VSize(Velocity) * Buoyancy);
}
state ActivatedJunction
{
function TakeDamage(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, name DamageType)
{
local int i;
local int i2;
if ( bShootable )
{
JunctionHealth -= Damage;
if ( JunctionHealth <= 0 )
{
for ( i = 0; i < 32; i++ )
{
if ( NextJunctions[i] != None )
NextJunctions[i].PreviousJunction = None;
if ( PreviousJunction.NextJunctions[i] == self )
for ( i2 = i; i2 < 31; i2++ )
{
if ( PreviousJunction.NextJunctions[i2 + 1] == None )
break;
PreviousJunction.NextJunctions[i2] = PreviousJunction.NextJunctions[i2 + 1];
}
}
Destroy();
}
}
}
function Tick(float TimeDelta)
{
local int i;
local Actor CollidedActor;
local Vector ActorNormal;
local Vector Unused;
local Vector EPV;
CollidedActor = Trace(Unused, ActorNormal, EndPoint, Location);
if ( CollidedActor == None )
return;
else if ( CollidedActor.Name == 'LevelInfo0' )
{
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateWallReflect(ActorNormal);
}
else
{
if ( CollidedActor.bBlockActors )
{
CollidedActor.Bump(self);
Bump(CollidedActor);
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].Bump(CollidedActor);
}
else
{
CollidedActor.Touch(self);
Touch(CollidedActor);
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].Touch(CollidedActor);
}
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] != None )
NextJunctions[i].IterateActorReflect(CollidedActor, ActorNormal);
}
for ( i = 0; i < 32; i++ )
if ( VSize(NextJunctions[i].Location - Location) != Lenght )
MoveSmooth(Normal(NextJunctions[i].Location - Location) * Lenght);
for ( i = 0; i < 32; i++ )
if ( NextJunctions[i] != None )
EPV += NextJunctions[i].Location;
EndPoint = EPV / 32;
}
function Landed(vector HitNormal)
{
IterateWallReflect(HitNormal);
}
}
Just make sure NOT to edit the default value of them!
EDIT 4: Look at the video:
R-LNaS_G-Mk
These rocket launchers are Junctions with Rocket Launcher mesh.
IT FAILSSSSSSSSSSS
WHY ???? ;_;