Partycje szkieł są białe a powinny być brązowe.
Kod:
Kod: Zaznacz cały
///////////////////////////////////////////////////////////////////////////////
// Butelka
// Rycho3D
///////////////////////////////////////////////////////////////////////////////
class Butelka extends KActor;
var (RRendering) bool DynamicShadow;
var (RRendering) bool SingleGame;
var (RRendering) vector LightDirection;
var (RRendering) float LightDistance;
var (RRendering) float MaxTraceDistance;
var RShadow MyShadow;
var ()float DamageThreshold; // How much damage in a single shot you have to
// do in order to break the prop
var ()float Health; // How much health we have. At 0, we break
var ()class<P2Emitter> BreakEffectClass; // Effect generated when you break the prop
var ()StaticMesh BrokenStaticMesh; // Mesh subbed assigned to StaticMesh when the
// prop is broken
var ()bool bFitEffectToProp; // Whether or not to attempt to make the effect
// rotate to fit the prop.
var() sound BreakingSound; // Sound played when it breaks
var() class<DamageType> DamageFilter;// Damage type we're concerned about.
// To allow all damage types, have this be none (default)
var() bool bBlockFilter; // true means you'll accept all damages except DamageFilter
// false means you'll only accept DamageFilter.(default is false)
var() bool bTriggerControlled; // Triggers are the only things that allow these kactors to explode, if true
var() class<TimedMarker>DangerMarker;// Danger notifier (if any) this makes when broken
var ()float BreakPct; // Percentage of max speed for an object to break the window
var() color ParticleColor;
const MOMENTUM_RATIO = 0.02;
const MOM_MAX = 20000;
///////////////////////////////////////////////////////////////////////////////
// Set it to dead, trigger sounds and all, and blow it up, setting off the physics
///////////////////////////////////////////////////////////////////////////////
function BlowThisUp(int Damage, vector HitLocation, vector Momentum)
{
local P2Emitter p2e;
// Say we're broken so we won't break anymore
GotoState('Broken');
// set to dead
Health=0;
// Spawn effect so we don't have to record the hit values and
// do it later in Broken beginstate or something. It's just
// more efficient here
p2e = spawn(BreakEffectClass, self,,Location);
if(bFitEffectToProp)
FitTheEffect(p2e, damage, HitLocation, momentum);
// Play the breaking sound (code copied from mover)
PlaySound( BreakingSound, SLOT_None, SoundVolume / 255.0, false, SoundRadius, 0.96 + FRand()*0.8);
}
///////////////////////////////////////////////////////////////////////////////
// Orient the breaking effect and size it
///////////////////////////////////////////////////////////////////////////////
function FitTheEffect(P2Emitter pse, int damage, vector HitLocation, vector HitMomentum)
{
local float xsize, xradsize, yradsize, zradsize;
local vector vecrot;
local float totalarea, startarea;
local float usedot;
local float velmag;
local int i;
local int newmax;
// Cap the momentum, so explosions and such don't send them so absurdly far
// if(VSize(HitMomentum) < MOM_MAX)
// HitMomentum = MOM_MAX*Normal(HitMomentum);
pse.Emitters[0].StartLocationRange.X.Max = CollisionRadius;
pse.Emitters[0].StartLocationRange.X.Min = -CollisionRadius;
pse.Emitters[0].StartLocationRange.Y.Max = CollisionRadius;
pse.Emitters[0].StartLocationRange.Y.Min = -CollisionRadius;
pse.Emitters[0].StartLocationRange.Z.Max = CollisionHeight;
pse.Emitters[0].StartLocationRange.Z.Min = -CollisionHeight;
// Use this as your speed from the emitter, but also throw in some
// of the damage.
pse.Emitters[0].StartVelocityRange.X.Max=MOMENTUM_RATIO*HitMomentum.x + pse.Emitters[0].StartVelocityRange.X.Max;
pse.Emitters[0].StartVelocityRange.X.Min=-pse.Emitters[0].StartVelocityRange.X.Max/8;
pse.Emitters[0].StartVelocityRange.Y.Max=MOMENTUM_RATIO*HitMomentum.y;
pse.Emitters[0].StartVelocityRange.Y.Min=-pse.Emitters[0].StartVelocityRange.Y.Max/8;
pse.Emitters[0].StartVelocityRange.Z.Max=MOMENTUM_RATIO*HitMomentum.z;
pse.Emitters[0].StartVelocityRange.Z.Min=-pse.Emitters[0].StartVelocityRange.Z.Max/8;
// Color the emitters
for(i=0; i<pse.Emitters.Length; i++)
{
pse.Emitters[i].ColorScale[0].Color = ParticleColor;
pse.Emitters[i].ColorScale[0].RelativeTime = 0.0;
pse.Emitters[i].ColorScale[1].Color = ParticleColor;
pse.Emitters[i].ColorScale[1].RelativeTime = 1.0;
}
}
///////////////////////////////////////////////////////////////////////////////
Simulated Function PostBeginPlay()
{
If(DynamicShadow)
{
MyShadow = Spawn(class'R3DFX.RShadow',Self,'',Location);
MyShadow.ShadowActor = self;
MyShadow.SetCollision(true, false, false);
MyShadow.LightDirection = Normal(vect(1,1,6));
MyShadow.LightDistance = 512;
MyShadow.MaxTraceDistance = 256;
MyShadow.UpdateShadow();
}
}
///////////////////////////////////////////////////////////////////////////////
// If DamageFilter is set,
// and bBlockFilter is false only allow this damage
// else don't allow only this damage
///////////////////////////////////////////////////////////////////////////////
function bool AcceptThisDamage(class<DamageType> damageType)
{
if(bTriggerControlled)
return false;
if(DamageFilter != None)
{
// accept only filter
if(!bBlockFilter)
{
if(!ClassIsChildOf(DamageFilter, damageType))
return false;
}
else // block the filter type
{
if(ClassIsChildOf(DamageFilter, damageType))
return false;
}
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
// If strong enough, it breaks the prop
///////////////////////////////////////////////////////////////////////////////
function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation,
Vector momentum, class<DamageType> damageType)
{
local TimedMarker ADanger;
// Check first if we take this damage
if(!AcceptThisDamage(damageType))
return;
// If so, check to make panic noises for people around us.
// Only panic, if the damage before us *didn't* make some kind of
// panic noise (like a bullet hitting this would, and so would an
// explosion)
if(DangerMarker != None
&& (ClassIsChildOf(damageType, class'CuttingDamage')
|| ClassIsChildOf(damageType, class'BludgeonDamage')))
{
ADanger = spawn(DangerMarker,,,HitLocation);
ADanger.CreatorPawn = FPSPawn(InstigatedBy);
ADanger.OriginActor = self;
// This will cause people to see if they noticed and decide what to do
ADanger.NotifyAndDie();
}
// Only remove health if the singular damage was strong enough
if(damage > DamageThreshold)
{
Health -= damage;
// if you run out of health, break
if(Health <= 0)
{
BlowThisUp(Damage, HitLocation, Momentum);
}
}
}
///////////////////////////////////////////////////////////////////////////////
// Broken
///////////////////////////////////////////////////////////////////////////////
state Broken
{
ignores TakeDamage;
///////////////////////////////////////////////////////////////////////////////
// You've just been freshly broken, generate effects
///////////////////////////////////////////////////////////////////////////////
function BeginState()
{
// Swap the mesh to the broken mesh if you have one
if(BrokenStaticMesh != None)
{
SetDrawType(DT_StaticMesh);
SetStaticMesh(BrokenStaticMesh);
}
else // If we don't have a broken mesh, they don't want to
// see it anymore, so just destroy it
Destroy();
}
}
defaultproperties
{
ParticleColor=(B=34,G=38,R=51)
BreakPct=0.700000
SoundVolume=255
BreakEffectClass=Class'FX.ShatterGlass'
bPawnMovesMe=True
Health=5.000000
DynamicShadow=False
BrokenStaticMesh=StaticMesh'HD4.bottle_perla_crash1'
BreakingSound=Sound'MiscSounds.Glass.glassbreak'
Mass=5.000000
StaticMesh=StaticMesh'HD4.bottle_perla'
CollisionRadius=8.000000
CollisionHeight=20.000000
bUpdateSimulatedPosition=True
SoundRadius=255.000000
Begin Object Class=KarmaParams Name=KarmaParams16
KFriction=0.900000
KMass=1.000000
KStartEnabled=False
Name="KarmaParams16"
End Object
KParams=KarmaParams'R3DFX.KarmaParams16'
}
Jeśli nikt mi nie pomoże to rozwiąże to inaczej (nowy emiter)