Core.Object | +--Engine.Actor | +--RuneI.Accelerator | +--RuneI.TreePoint
Actor
Attraction
BeamActor
float
BranchLength
DampFactor
GravAccel
vector
GravDir
MaxVelocityAllowed
TreePoint
Parent
name
ParentTag
SpringConstant
SwayDir
SwayMagnitude
bool
bAffectsParent
bApplyAcceleration
bApplySway
bDrawRope
bHooker
bLeaf
bRestrictVelocity
bSpring
bStiffRotation
rotator
hookOrientation
hooked
void
ApplySwing(TreePoint r1, TreePoint r2, float DeltaTime)
// r1 = parent, r2 = child
ElasticCollision(Actor a1, Actor a2)
HitWall(vector HitNormal, Actor HitWall)
PostBeginPlay()
PreBeginPlay()
// Private members // --------------------------------------------------------
SetAttraction(Actor Other)
SetBranchLength(float len)
SetDrawRope(bool on)
SetGravDir(vector dir)
// Public interface members // --------------------------------------------------------
SpawnChild()
Touch(Actor Other)
TreePointTick(float DeltaSeconds)
UnTouch(Actor Other)
UpdateBeam()
WakeSelfAndChildren()
WakeSelfAndParents()
WakeUp()
BeginState()
Tick(float DeltaTime)
00001 //============================================================================= 00002 // TreePoint. 00003 //============================================================================= 00004 class TreePoint extends Accelerator 00005 native; 00006 00007 var() bool bHooker; // Whether this point "hooks" actors 00008 var() bool bRestrictVelocity; // Restrict TreePoint velocity to MaxVelocityAllowed 00009 var() bool bAffectsParent; // If children affect parent velocity 00010 var() bool bDrawRope; // Draw our fake rope between this and child 00011 var() float MaxVelocityAllowed; // Creates cone centered at DesiredRotation 00012 var() float GravAccel; // Acceleration magnitude of gravitation 00013 var() float DampFactor; // Dampening Factor [0..1] (1=infinite damp) 00014 var() name ParentTag; // Tag of this TreePoint's parent 00015 var() bool bApplyAcceleration; // Apply local gravitation force 00016 var() bool bStiffRotation; // Rotation stays perfectly synced with parent 00017 var() bool bSpring; 00018 var() float SpringConstant; 00019 00020 var() bool bApplySway; // Get rid of these, use controller class to sway 00021 var() vector SwayDir; 00022 var() float SwayMagnitude; 00023 00024 var(Sounds) sound WhileMoving; 00025 var(Sounds) sound HitAWall; 00026 00027 var TreePoint Parent; 00028 var bool bLeaf; // This is last TreePoint in chain 00029 var private vector GravDir; // Direction of gravitation 00030 var float BranchLength; // Distance to parent TreePoint 00031 var actor Attraction; // Actor attracted to 00032 var actor BeamActor; // Beam actor for drawing 00033 00034 const MaximumVelocityPickup = 500; // Maximum velocity transfer allowed from collision 00035 00036 // To be implimented 00037 var actor hooked; // Actor hooked to point 00038 var rotator hookOrientation; // Orientation of Hooked actors 00039 00040 00041 native(654) final function TreePointTick(float DeltaSeconds); 00042 00043 00044 // Public interface members 00045 // -------------------------------------------------------- 00046 00047 function SetGravDir(vector dir) 00048 { 00049 GravDir = Normal(dir); 00050 } 00051 00052 function SetBranchLength(float len) 00053 { 00054 BranchLength = len; 00055 UpdateBeam(); 00056 } 00057 00058 function SetAttraction(actor Other) 00059 { 00060 Attraction = None; 00061 } 00062 00063 function SetDrawRope(bool on) 00064 { 00065 if (on) 00066 { 00067 if (BeamActor == None) 00068 Spawn(class'Beam',,,Location,); 00069 UpdateBeam(); 00070 bDrawRope = true; 00071 } 00072 else 00073 { 00074 if (BeamActor != None) 00075 BeamActor.Destroy(); 00076 bDrawRope = false; 00077 } 00078 } 00079 00080 function SpawnChild() 00081 { 00082 } 00083 00084 00085 // Private members 00086 // -------------------------------------------------------- 00087 00088 00089 function PreBeginPlay() 00090 { 00091 // Validate user set variables 00092 SetPhysics(PHYS_PROJECTILE); // Don't force this, may want gravity 00093 bLeaf = true; // Nodes are leaves until proven otherwise 00094 Parent = None; 00095 BeamActor = None; 00096 Attraction = None; 00097 DampFactor = FClamp(DampFactor, -1.0, 1.0); 00098 } 00099 00100 00101 function PostBeginPlay() 00102 { 00103 local TreePoint PotentialParent; 00104 00105 if (ParentTag == '') 00106 { // Root 00107 SetPhysics(PHYS_NONE); 00108 } 00109 else 00110 { // Fill in 'Parent' based on 'ParentTag' 00111 foreach AllActors(class'TreePoint', PotentialParent, ParentTag) 00112 { 00113 // Notice: If more than one matches ParentTag, the last is used 00114 Parent = PotentialParent; 00115 PotentialParent.bLeaf = false; 00116 00117 // Pre-calc variables 00118 GravDir = Location - PotentialParent.Location; 00119 BranchLength = VSize(GravDir); 00120 Gravdir = Normal(GravDir); 00121 } 00122 00123 SetDrawRope(bDrawRope); 00124 } 00125 00126 if (Skeletal != None) 00127 { 00128 LoopAnim('run', 1.0, 0.0); 00129 } 00130 } 00131 00132 function ElasticCollision(actor a1, actor a2) 00133 { 00134 local float m1,m2,mt; 00135 local vector v1,v2; 00136 00137 m1 = a1.Mass; 00138 m2 = a2.Mass; 00139 mt = m1+m2; 00140 v1 = a1.Velocity; 00141 v2 = a2.Velocity; 00142 a1.Velocity = (m1*v1 + 2*m2*v2 - m2*v1) / mt; 00143 a2.Velocity = (m2*v2 + 2*m1*v1 - m1*v2 ) / mt; 00144 } 00145 00146 function HitWall(vector HitNormal, actor HitWall) 00147 { 00148 PlaySound(HitAWall, , 1.0); 00149 } 00150 00151 function Touch(actor Other) 00152 { 00153 // Note: 00154 // When objects are internally in order such that this touch gets called 00155 // after the swing calculations, velocity can be transfered continually, 00156 // moving the TreePoint out of it's orbit. Maybe Touch/UnTouch are not 00157 // behaving as expected. Perhaps moving this swing logic to the physics 00158 // subsystem would cure this ordering problem. 00159 00160 // Non-blocking velocity transfer 00161 if (!Other.IsA('TreePoint')) 00162 { 00163 Velocity += Normal(Other.Velocity) * Min(VSize(Other.Velocity), MaximumVelocityPickup); 00164 Disable('Touch'); 00165 WakeUp(); 00166 } 00167 return; 00168 00169 // Rigid body elastic collision 00170 ElasticCollision(Other, self); 00171 Disable('Touch'); 00172 WakeUp(); 00173 } 00174 00175 function UnTouch(actor Other) 00176 { 00177 Enable('Touch'); 00178 } 00179 00180 function UpdateBeam() 00181 { 00182 if (BeamActor != None) 00183 { 00184 Beam(BeamActor).SetEndPoints(Location, Parent.Location); 00185 } 00186 } 00187 00188 // r1 = parent, r2 = child 00189 function ApplySwing(TreePoint r1, TreePoint r2, float DeltaTime) 00190 { 00191 local vector RopeVector, VelocityLookahead, RopeDir, NewLocation,NewVelocity; 00192 local float velmag; 00193 local rotator rot; 00194 local float stretchAmount; 00195 local vector SpringAccel; 00196 local vector loc1, loc2; 00197 00198 if ((r1 == None)||(r2 == None)) 00199 return; 00200 00201 loc1 = r1.Location; 00202 loc2 = r2.Location; 00203 00204 // Apply Acceleration 00205 if (r2.bApplyAcceleration) 00206 r2.Velocity += r2.GravDir*(r2.GravAccel*DeltaTime); 00207 00208 // Apply sway 00209 if (r2.bApplySway && (FRand() < 0.1)) 00210 r2.Velocity += Normal(r2.SwayDir) * FRand() * SwayMagnitude * DeltaTime; 00211 00212 // Apply velocity on child TreePoint 00213 VelocityLookahead = Loc2 + (r2.Velocity * DeltaTime); 00214 RopeDir = Normal(Loc1 - VelocityLookahead); 00215 00216 // Find Next child Location 00217 if (r2.bSpring) 00218 { // Apply spring acceleration 00219 RopeVector = Loc1 - Loc2; 00220 stretchAmount = VSize(RopeVector) - r2.BranchLength; 00221 SpringAccel = Normal(RopeVector) * (r2.SpringConstant * stretchAmount / r2.Mass); 00222 NewLocation = VelocityLookahead + SpringAccel * (DeltaTime * DeltaTime); 00223 } 00224 else 00225 { 00226 RopeVector = RopeDir * r2.BranchLength; 00227 NewLocation = Loc1 - RopeVector; 00228 } 00229 00230 NewVelocity = NewLocation - Loc2; 00231 if (r2.bRestrictVelocity) 00232 { 00233 velmag = VSize(NewVelocity); 00234 if (velmag > r2.MaxVelocityAllowed) 00235 { 00236 NewVelocity = Normal(NewVelocity) * r2.MaxVelocityAllowed; 00237 } 00238 } 00239 r2.Velocity = NewVelocity *(1.0-r2.DampFactor)/ DeltaTime; 00240 00241 // Set child's rotation 00242 if (bStiffRotation) 00243 rot = rotator(-RopeVector); // Predicted location 00244 else 00245 rot = rotator(Loc2-Loc1); // Last location (lagged) 00246 rot.Roll = rot.Yaw; 00247 r2.SetRotation(rot); 00248 00249 //*** This needs to be moved to C side *** 00250 if (r1.Parent == None) // Set root rotation too 00251 r1.SetRotation(rot); 00252 00253 // Apply velocity on parent TreePoint 00254 if (r2.bAffectsParent) 00255 { 00256 r1.Velocity = (r1.Velocity + (r2.Velocity * 0.5)) * 0.5; 00257 } 00258 00259 // Play WhileMoving Sound 00260 if (VSize(r2.Velocity) > 1.0) 00261 PlaySound(r2.WhileMoving, , 1.0); 00262 } 00263 00264 00265 function WakeSelfAndParents() 00266 { 00267 if (Parent != None) 00268 { 00269 GotoState('Active'); 00270 Parent.WakeSelfAndParents(); 00271 } 00272 } 00273 00274 function WakeSelfAndChildren() 00275 { 00276 local TreePoint point; 00277 00278 // Wake myself if not the root 00279 if (Parent != None) 00280 GotoState('Active'); 00281 foreach AllActors(class'TreePoint', point) 00282 { 00283 if (point.Parent == self) 00284 point.WakeSelfAndChildren(); 00285 } 00286 } 00287 00288 function WakeUp() 00289 { 00290 WakeSelfAndParents(); 00291 WakeSelfAndChildren(); 00292 } 00293 00294 state Inactive 00295 { 00296 ignores Tick; 00297 00298 function BeginState() 00299 { 00300 SetPhysics(PHYS_NONE); 00301 } 00302 } 00303 00304 00305 auto state Active 00306 { 00307 function Tick(float DeltaTime) 00308 { 00309 local TreePoint point; 00310 00311 UpdateBeam(); 00312 00313 if (bLeaf) 00314 { 00315 // TreePointTick(DeltaTime); 00316 // 00317 point = self; 00318 while (point != None) 00319 { 00320 ApplySwing(point.Parent, point, DeltaTime); 00321 point = point.Parent; 00322 } 00323 // 00324 } 00325 00326 if (VSize(Velocity) < 0.1) 00327 { 00328 Velocity = vect(0,0,0); 00329 GotoState('Inactive'); 00330 } 00331 } 00332 00333 function BeginState() 00334 { 00335 SetPhysics(PHYS_PROJECTILE); 00336 } 00337 } 00338 00339 defaultproperties 00340 { 00341 bAffectsParent=True 00342 bDrawRope=True 00343 GravAccel=950.000000 00344 DampFactor=0.010000 00345 bApplyAcceleration=True 00346 Physics=PHYS_Projectile 00347 CollisionRadius=20.000000 00348 CollisionHeight=30.000000 00349 bCollideActors=True 00350 bCollideWorld=True 00351 }