This is the class, a particle that can hit the level geometry, it is bBounce=True so that HitWall() is called instead of Landed():
Code: Select all
/*
* Supposed to be done by a community
*/
class Particle extends Effects;
const MinDesiredFPS = 55;
var ParticleSystem particleSys;
var vector friction;
const frMagnitude = 0.01; //friction cohefficent (0.01) * friction normal (1).
var vector fixedForce;
var vector bounceDir;
var vector ParticleHitNormal;
var Actor ParticleHitWall;
var int bounceCounter;
var bool bHitEffect;
auto state Init {
event BeginState() {
bCollideWorld = true;
particleSys = ParticleSystem(owner);
if (particleSys == None)
destroy();
if (particleSys.localPlayer == None)
particleSys.FindLocalPlayer();
if (particleSys.localPlayer == None)
destroy();
GotoState('Resetting');
}
}
event FellOutOfWorld() {
GotoState('Resetting');
}
event Timer() {
GotoState('Resetting');
}
state Resetting
{
event BeginState() {
bHidden = true;
Setup();
}
function Setup() {
local vector relativeLoc;
local int i;
for (i = 0; i < particleSys.MaxSetLocationAttempts; ++i) {
relativeLoc = particleSys.Location + particleSys.RandRangeVec(particleSys.minSpawnLoc, particleSys.maxSpawnLoc);
if (SetLocation(relativeLoc))
if (particleSys.allowNewLoc(self))
if (!particleSys.bEmitInZone || (particleSys.bEmitInZone && (Region.Zone == particleSys.Region.Zone)))
if ((particleSys.maxDistFromPlayer == 0) || (VSize(Location - particleSys.localPlayer.Location) <= particleSys.maxDistFromPlayer))
if (!particleSys.bSpawnInViewport || (particleSys.bSpawnInViewport && (PlayerCanSeeMe())))
break;
}
bHidden = i == particleSys.MaxSetLocationAttempts;
if (bHidden) {
GotoState('Resetting');
} else {
//Actual reset.
fixedForce = particleSys.RandRangeVec(particleSys.minFixedForce, particleSys.maxFixedForce);
SetCollision(particleSys.bBlockByActors, false, false);
bounceCounter = 0;
Velocity *= 0;
Mass = particleSys.particlesMass;
Texture = particleSys.particlesTexture;
setTimer(particleSys.resetInterval, false);
GotoState('StartPhysics');
}
}
}
function ApplyForce(vector force) {
Acceleration += (force / Mass);
}
function ApplyAllForces() {
local ForceInfo forceInfo;
ApplyForce(friction);
ApplyForce(/*(Region.Zone.ZoneGravity / particleSys.unrealGravityFix) * Mass*/vect(0,0,-9));
//ApplyForce(Region.Zone.ZoneVelocity);
//ApplyForce(fixedForce);
//foreach AllActors(class'ForceInfo', forceInfo)
// ApplyForce(forceInfo.force - forceInfo.Location);
}
function Hit(actor HitStuff, vector HitNormal) {
local HitEffect hitFX;
local vector bounceDir;
if (HitStuff.IsA('LevelInfo')) {
if ((particleSys.maxBounces <= 0) || ((particleSys.maxBounces > 0) && (bounceCounter >= particleSys.maxBounces))) {
ParticleHitNormal = HitNormal;
ParticleHitWall = HitStuff;
if (bHitEffect) {
hitFX = spawn(particleSys.hitEffectClass,,,Location);
if (hitFX != None)
hitFX.init(ParticleHitNormal, ParticleHitWall);
}
if (!particleSys.bResetOnHit)
GotoState('Idle');
else
GotoState('Resetting');
} else {
if (VSize(bounceDir) == 0) {
/*
bounceDir = vect(1,1,1);
if (HitNormal.X != 0)
bounceDir.X = -1 * particleSys.particlesBuoyancy;
else if (HitNormal.Y != 0)
bounceDir.Y = -1 * particleSys.particlesBuoyancy;
else if (HitNormal.Z != 0)
bounceDir.Z = -1 * particleSys.particlesBuoyancy;
Log(Acceleration@Velocity@bounceDir);
ApplyForce(bounceDir);
*/
//FIXME
bounceDir = HitNormal;
Log(-1@bounceDir);
bounceCounter++;
}
}
} else {
//FIXME - Handle bouncing on actors without HitNormal.
if (!particleSys.bResetOnHit)
GotoState('Idle');
else
GotoState('Resetting');
}
}
event HitWall(vector HitNormal, actor HitWall) {
Hit(HitWall, HitNormal);
}
state Idle {
Ignores HitWall;
}
state StartPhysics {
event BeginState() {
SetPhysics(PHYS_Projectile);
}
event EndState() {
//The particle will move back to the initial position, it needs to be non-collidable.
SetCollision(false);
SetPhysics(PHYS_None);
}
event Touch(Actor Other) {
if (Other.bCollideActors && Other.bBlockActors)
Hit(Other, vect(0,0,0));
}
event ZoneChange(ZoneInfo NewZone) {
particleSys.particleZoneChange(self, NewZone);
}
event Tick(float DeltaTime) {
Log(0@bounceDir);
friction = (Velocity * -1);
friction = Normal(friction);
friction *= frMagnitude;
ApplyAllForces();
Log(1@Velocity);
Velocity += Acceleration;
Log(2@Velocity);
//Limiting the Velocity to the Zone Terminal Velocity.
//Limit positive velocity.
if (Velocity.X > Region.Zone.ZoneTerminalVelocity)
Velocity.X = Region.Zone.ZoneTerminalVelocity;
if (Velocity.Y > Region.Zone.ZoneTerminalVelocity)
Velocity.Y = Region.Zone.ZoneTerminalVelocity;
if (Velocity.Z > Region.Zone.ZoneTerminalVelocity)
Velocity.Z = Region.Zone.ZoneTerminalVelocity;
//Limit negative velocity.
if (Velocity.X < (Region.Zone.ZoneTerminalVelocity * -1))
Velocity.X = Region.Zone.ZoneTerminalVelocity * -1;
if (Velocity.Y < (Region.Zone.ZoneTerminalVelocity * -1))
Velocity.Y = Region.Zone.ZoneTerminalVelocity * -1;
if (Velocity.Z < (Region.Zone.ZoneTerminalVelocity * -1))
Velocity.Z = Region.Zone.ZoneTerminalVelocity * -1;
//Calculate bounce velocity.
if (VSize(bounceDir) != 0) {
Log(3@Velocity);
if (bounceDir.X != 0)
Velocity.X *= -1;
else if (bounceDir.Y != 0)
Velocity.Y *= -1;
else if (bounceDir.Z != 0)
Velocity.Z *= -1;
Log(4@Velocity);
bounceDir *= 0;
}
// Reset acceleration
Acceleration *= 0;
if (DeltaTime > Level.TimeDilation / MinDesiredFPS && FRand() < 0.1) {
bHidden = true;
SetCollision(false);
}
}
}
event Destroyed() {
if (particleSys != None) {
particleSys.particlesCounter--;
particleSys.enable('timer');
}
}
defaultproperties
{
RemoteRole=ROLE_None
DrawType=DT_Sprite
Style=STY_Translucent
DrawScale=0.2
Mass=1
bBounce=True
CollisionRadius=1
CollisionHeight=1
}
bounceDir is multiplied by 0 only inside an "if" body, which is never called cause of the issue I'm gonna talk about.
The issue:
Code: Select all
ScriptLog: -1 -0.000000,-0.000000,1.000000
ScriptLog: 0 0.000000,0.000000,0.000000
I thought it could have been caused by the "if" body that multiplies bounceDir by 0(even if it is never called), but I commented it out and the issue still occurs.
I know it has to be with something else inside the calss, cause I tried making a very simple class:
Code: Select all
/*
* Supposed to be done by a community
*/
class Particle extends Effects;
var vector bounceDir;
function Hit(actor HitStuff, vector HitNormal) {
bounceDir = HitNormal;
Log(-1@bounceDir);
}
event HitWall(vector HitNormal, actor HitWall) {
Hit(HitWall, HitNormal);
}
auto state StartPhysics {
event Tick(float DeltaTime) {
Log(0@bounceDir);
}
}
defaultproperties
{
RemoteRole=ROLE_None
DrawType=DT_Sprite
Physics=PHYS_Falling
bCollideWorld=True
bBounce=True
}
Code: Select all
ScriptLog: -1 -0.000000,-0.000000,1.000000
ScriptLog: 0 -0.000000,-0.000000,1.000000