XML:BINA/PAR3
PAR3 : Particle v3 | ||
---|---|---|
XML
AKEV << Other file types >> CONS ONIE << Other BINA >> SABD |
File structure
<?xml version="1.0" encoding="utf-8"?> <Oni> <Particle Name="particle_file_name"> <Options> <Lifetime></Lifetime> <DisableDetailLevel>[... see HERE for possible flags]</DisableDetailLevel> <Decorative></Decorative> [...] </Options> <Properties> [...] </Properties> <Appearance> <DisplayType>[... see HERE for possible flags]</DisplayType> [...] </Appearance> <Attractor> <Target>[... see HERE for possible flags]</Target> <Selector>[... see HERE for possible flags]</Selector> <Class /> [...] </Attractor> <Variables> [...] </Variables> <Emitters> <Emitter> [... see HERE for emitter data] </Emitter> </Emitters> <Events> [... see HERE for <event_type_tag>] [... see HERE for <action_type_tag>] [... see HERE for <parameter_tag>value</parameter_tag>] <action_type_tag> </event_type_tag> </Events> </Particle> </Oni>
Options
XML tag | Content type | Description |
---|---|---|
<Lifetime> | float | Particle exists for X seconds.
|
<DisableDetailLevel> | flag | Particle is not created if detail level is too low.
|
<Decorative> | flag | Lower priority for engine; a decorative particle might not always be updated.
|
<CollideWithWalls> | flag | Needed if the particle uses the HitWall event type.
|
<CollideWithChars> | flag | Needed if the particle uses the HitCharacter event type.
|
<InitiallyHidden> | flag | Hides the particle upon creation.
|
<DrawAsSky> | flag | Draws the particle before everything else, supposedly.
|
<DontAttractThroughWalls> | flag | Particle will not detect potential attractor if there is a wall between it and the particle.
|
<ExpireOnCutscene> | flag | Ends the lifetime of a particle on cutscene start.
|
<DieOnCutscene> | flag | Kills the particle on cutscene start.
|
<LockPositionToLink> | flag | Locks the position of the particle to its link.
|
<CollisionRadius> | float | Distance from which HitWall and HitCharacter events are activated. |
<AIDodgeRadius> | float | Distance from which AI will avoid this particle. |
<AIAlertRadius> | float | Distance from which AI will be aware of the danger of the particle. |
<FlyBySoundName /> | link | Sound used when the particle passes by you. To check: does the engine apply the Doppler effect or is it in the sound file itself?
|
Properties
XML tag | Content type | Description |
---|---|---|
<HasVelocity> | flag | Needed if the particle is to move.
|
<HasOrientation> | flag | Needed if the particle is to be able to turn?
|
<HasPositionOffset> | flag | Used with LockPositionToLink???
|
<HasAttachmentMatrix> | flag | Used if the particle is to be stuck to a character or wall.
|
<HasUnknown> | flag | ???
|
<HasDecalState> | flag | Used if the particle is a Decal.
|
<HasTextureStartTick> | flag | Used with animated particles. (Documentation Needed)
|
<HasTextureTick> | flag | Used with animated particles. (Documentation Needed)
|
<HasDamageOwner> | flag | Used for particles to either:
For this to work properly, the parent of the character must have this set, and the parent of said parent, etc., up to the original particle.
|
Appearance
XML tag | Content type | Description |
---|---|---|
<DisplayType> | flag | How the particle is displayed. (Documentation needed.)
|
<TexGeom> | link | The texture or model that this particle uses.
|
<Invisible> | flag | Can't be seen.
|
<IsContrailEmitter> | flag | Emits a contrail.
|
<ScaleToVelocity> | flag | Scales the particle based on the speed it is going.
|
<Scale> | float | The size of the particle. |
<UseSeparateYScale> | flag | Stretches the particle along the Y axis if set.
|
<YScale> | float | Needs <UseSeparateYScale>true</UseSeparateYScale> to be enabled. |
<Rotation> | ? | The rotation of the particle. |
<Alpha> | float / integer | Transparency (0 = fully invisible, 1 or 255 = fully visible)
|
<XOffset> | float | |
<XShorten> | float | |
<UseSpecialTint> | flag | Research note: "true" can be found in BINA3RAPbarab_p02.xml
|
<Tint> | integer | Color. R G B A means Red Green Blue Alpha.
|
<FadeOutOnEdge> | flag |
|
<OneSidedEdgeFade> | flag |
|
<EdgeFadeMin> | float | |
<EdgeFadeMax> | float | |
<MaxContrailDistance> | ||
<LensFlare> | flag |
|
<LensFlareDistance> | float | |
<LensFlareFadeInFrames> | integer | |
<LensFlareFadeOutFrames> | integer | |
<DecalFullBrightness> | flag |
|
<MaxDecals> | integer | Seems to be a bit broken (someone please test this again). |
<DecalFadeFrames> | integer | The number of frames it takes for a decal particle to fade after it reaches the maximum number of decals. |
<DecalWrapAngle> | float | Degrees. Decal isn't cut off for any connecting planes which meet at an angle equal to or less than this value. |
Attractor
XML tag | Content type | Description |
---|---|---|
<Target> | flag |
|
<Selector> | flag |
|
<Class /> | float | Name of a particle that this particle is attracted to. |
<MaxDistance> | float | Maximum distance the particle will detect an attractor from (if using Distance selection). |
<MaxAngle> | float | Maximum angle the particle will detect an attractor from (if using Angle selection). |
<AngleSelectMin> | float | |
<AngleSelectMax> | float | |
<AngleSelectWeight> | float |
Variable storage types
XML tag | Description |
---|---|
<Float Name="variable">float_value</Float> | A float. |
<Color Name="variable">R G B [A]</Color> | A color. |
<PingPongState Name="variable">?</PingPongState> | A float from 0.0-1.0, describes where in the ping-pong state the event is (if my memory is correct). |
Parameter value types
Grey is additional for variable section.
0 - variable; variable name follows |
<Float Name="variable">variable</Float> |
1 - none (action parameters use this to indicate an unused parameter) |
? |
3 - float; constant; 1 float value follows 4 - float; random; 2 float values follow (min, max) 5 - float; bell curve; 2 float values follow (mean, stddev) |
<Float Name="variable">float_value</Float> <Float Name="variable"><Random Min="float_value" Max="float_value" /></Float> <Float Name="variable"><BellCurve Mean="float_value" StdDev="float_value" /></Float> |
6 - instance; instance name follows |
? |
7 - color; constant; 1 color follows 8 - color; random; 2 colors follow (min, max) 9 - color; bell curve; 2 colors follow (mean, stddev) |
<Color Name="variable">R G B</Color> <Color Name="variable"><Random Min="R G B" Max="R G B" /></Color> <Color Name="variable"><BellCurve Mean="? ? ? ?" StdDev="? ? ? ?" /></Color> |
0A - int32; constant; int32 follows |
? |
0B - time cycle; 2 float values follow (cycle length, scale) |
<TimeCycle Length="..." Scale="..." /> |
Emitter
XML tag | Content type | Description |
---|---|---|
<Class> | link | BINA3RAPfile_name.oni (without file prefix and suffix) |
<Flags> | flag |
Research notes - files with Unknown0020 flag: BINA3RAPw8_mbo_p07, BINA3RAPw8_mbo_e03, BINA3RAPw12_ba2_e03, BINA3RAPw10_sni_p01, BINA3RAPpstream_flicker, BINA3RAPheadlight02, BINA3RAPheadlightStart, BINA3RAPheadlight01 |
<TurnOffTreshold> | integer | Tag contains the number (threshold) of particle which must be reached before emitter gets turned off. Threshold needs two flags to be set: IncreaseParticleCount and TurnOffAtTreshold. |
<Probability> | float |
Let's say threshold was set to 10 and probability to 0.5: then you might get 5 particles emitted, sometimes less, sometimes more; it's an average. (threshold * probability = emitted particle) |
<Copies> | integer | It's actually a multiplier; set it to 0 and no particle will be emitted. Copies doesn't affect the threshold counting. The copies are emitted at the same place as the original particle so you might not see any difference (because they overlap each other) until they have a random movement. |
<LinkTo> | flag |
|
<Rate> | - | Interval in seconds. |
<Continous> | - | |
<Interval> | float | |
<Random> | - | |
<MinInterval> | float | |
<MaxInterval> | float | |
<Instant /> | - | |
<Distance> | - | |
<Distance> | float | |
<Attractor> | - | |
<RechargeTime> | float | |
<CheckInterval> | float | |
<Position> | - | |
<Point /> | - | |
<Line> | - | |
<Radius> | float | |
<Circle> | - | |
<InnerRadius> | float | |
<OuterRadius> | float | |
<Sphere> | - | |
<InnerRadius> | float | |
<OuterRadius> | float | |
<Cylinder> | - | |
<Height> | float | |
<InnerRadius> | float | |
<OuterRadius> | float | |
<BodySurface> | - | |
<OffsetRadius> | float | |
<BodyBones> | - | |
<OffsetRadius> | float | |
<Direction> | ||
<Straight /> | - | |
<Random /> | - | |
<Cone> | - | |
<Angle> | float | |
<CenterBias> | float | |
<Ring> | - | |
<Angle> | float | |
<Offset> | float | |
<Offset> | - | |
<X> | float | |
<Y> | float | |
<Z> | float | |
<Inaccurate> | - | |
<BaseAngle> | float | |
<Inaccuracy> | float | |
<CenterBias> | float | |
<Attractor /> | - | |
<Speed> | - | |
<Uniform> | - | |
<Speed> | float | |
<Stratified> | - | |
<Speed1> | float | |
<Speed2> | float | |
<Orientation> | flag |
|
<OrientationUp> | flag | same flags as <OrientationUp> |
Event types
- Update
- Pulse
- Start
- Stop
- BackgroundFxStart
- BackgroundFxStop
- HitWall
- HitCharacter
- Lifetime
- Explode
- BrokenLink
- Create
- Die
- NewAttractor
- DelayStart
- DelayStop
schemata 1 <Event> <action_tag_without_parameter /> </Event> |
example 1 <HitWall> <Die /> </HitWall> |
schemata 2 <Event> <action_tag_with_parameter> <parameter_tag>value_or_variable</parameter_tag> </action_tag_with_parameter> </Event> |
example 2 <Update> <SuperParticle> <Variable>emit_rate</Variable> <VaseValue>0.25</VaseValue> <DeltaValue>-0.1</DeltaValue> <MinValue>0.1</MinValue> <MaxValue>20</MaxValue> </SuperParticle> </Update> |
Action types and parameters
A dark gray background marks the start of an action type. |
Normal gray background is used for child tags. |
XML tag | Content type | Description |
---|---|---|
<AnimateLinear> | - | |
<Target> | float | |
<Rate> | float | |
<AnimateAccelerated> | - | |
<Target> | float | |
<Velocity> | float | |
<Acceleration> | float | |
<AnimateRandom> | - | |
<Target> | float | |
<Min> | float | |
<Max> | float | |
<Rate> | float | |
<AnimatePingPong> | - | |
<Target> | float | |
<State> | ||
<Min> | float | |
<Max> | float | |
<Rate> | float | |
<AnimateLoop> | - | |
<Target> | float | |
<Min> | float | |
<Max> | float | |
<Rate> | float | |
<AnimateToValue> | - | |
<Target> | float | |
<Rate> | float | |
<Value> | float | |
<ColorInterpolate> | - | |
<Target> | ||
<Color0> | ||
<Color1> | ||
<Amount> | float | |
<FadeOut> | - | |
<TimeToDie> | float | Particle gets killed after X seconds; it fades out during that time. |
<EnableAtTime> | - | ??? Update event only ??? |
<Action> | integer | Has action X as target in Update event section. |
<Lifetime> | float | Lifetime of the particle MINUS the value stored in this field yields the delay from the particle's spawn until the targeted action (action from the "Action" tag) starts operating. Till that moment, the targeted action is held inactive. Example: If the lifetime of the particle is set to be 3.0, then it counts down from 3.0 to 0.0 (at 0.0, Lifetime event is called). Now, if the lifetime of the particle is set to be 3.0 and the value here in this tag is 1.0, then from the moment the particle is spawned, this EnableAtTime's targeted action (the action inside the "Action" tag) will be disabled and will activate only after the particle's lifetime goes from 3.0 to 1.0, that is, in 2.0 seconds. That means the targeted action will activate 2 seconds after the particle was spawned. This mechanism is quite counter-intuitive, hence the detailed description. |
<DisableAtTime> | - | ??? Update event only ??? |
<Action> | integer | Has action X as target in Update event section. |
<Lifetime> | float | Lifetime of the particle MINUS the value stored in this field yields the delay from the particle's spawn until the targeted action (action from the "Action" tag) stops operating. Till that moment, the targeted action is kept active. Example: If the lifetime of the particle is set to be 3.0, then it counts down from 3.0 to 0.0 (at 0.0, Lifetime event is called). Now, if lifetime of the particle is set to be 3.0 and value here in this tag is 1.0, then from the moment the particle is spawned, this EnableAtTime's targeted action (the action inside "Action" tag) will be operating and will deactivate only after the particle's lifetime goes from 3.0 to 1.0, that is, in 2.0 seconds. That means the targeted action will deactivate 2 seconds after the particle was spawned. This mechanism is quite counter-intuitive, hence the detailed description. |
<Die /> | - | This action triggers the Die event. |
<SetLifetime> | - | |
float | Particle gets killed after X seconds. | |
<EmitActivate> | - | |
<Emitter> | integer | Enables emitter X. Note that first emitter is 0, second is 1, third is 2, and so on. |
<EmitDeactivate> | - | |
<Emitter> | integer | Disables emitter X. Note that first emitter is 0, second is 1, third is 2, and so on. |
<EmitParticles> | - | |
<Emitter> | integer | Starts emitter X. Note that first emitter is 0, second is 1, third is 2, and so on. |
<Particles> | float | Integer recommended. Number of particle to be emitted. |
<ChangeClass> | - | |
<Emitter> | integer | Note that first emitter is 0, second is 1, third is 2, and so on. |
<KillLastEmitted> | - | |
<Emitter> | integer | ?; Note that first emitter is 0, second is 1, third is 2, and so on. |
<ExplodeLastEmitted> | - | |
<Emitter> | integer | ?; Note that first emitter is 0, second is 1, third is 2, and so on. |
<AmbientSound> | - | |
<Sound> | link | OSBDfile_name.amb.oni (file prefix "OSBD" and suffix ".amb.oni" are not included) |
<EndAmbientSound /> | - | |
<ImpulseSound> | - | |
<Sound> | link | OSBDfile_name.imp.oni (file prefix "OSBD" and suffix ".imp.oni" are not included) |
<DamageChar> | - | |
<Damage> | float | Integer recommended. Negative damage values don't work. |
<StunDamage> | float | Adds the value specified here to the StunDamage sum variable. StunDamage has visible effect only for DamageTypes 1, 2 and 6. |
<KnockBack> | float | Character gets moved from its current position by "knockback value", in game world units with 0.1 precision. (Example: If value here is 100, char gets moved ~99.9 units) Negative values work as well -- instead of being "knocked back", the character is "drawn in". |
<DamageType> | flag |
|
<SelfImmune> | flag |
|
<CanHitMultiple> | flag | Tag is missing if value is 0.
|
<DamageBlast> | - | |
<Damage> | float | Integer recommended. Negative damage values don't work. |
<StunDamage> | float | Same as the DamageChar's StunDamage. |
<KnockBack> | float | Same as the DamageChar's Knockback. |
<Radius> | float | Radius of the damaging sphere. (Example: If value here is 100, character gets damaged if its distance from the position of the damaging particle is less than or equal to 100 game world units. |
<FallOff> | flag |
Example: this flag is set, Radius is 200, Damage is 400, StunDamage is 600 and Knocback is 800. |
<DamageType> |
| |
<SelfImmune> | flag |
Same as the DamageChar's SelfImmune |
<DamageEnvironment> | flag | This tag is not exported if the data field in the .oni file is "00". It is exported when "0A" was set.
|
<Explode /> | - | This action triggers the Explode event. |
<DamageEnvironment> | - | |
<Damage> | float | Integer used. |
<GlassCharge> | - | |
<BlastVelocity> | float | |
<Radius> | float | |
<Stop /> | - | This action triggers the Stop event. |
<RotateX> | - | |
<Space> | ||
<Rate> | float | |
<RotateVelocity> | flag |
|
<RotateY> | - | |
<Space> | ||
<Rate> | float | |
<RotateVelocity> | flag |
|
<RotateZ> | ||
<Space> | ||
<Rate> | float | |
<RotateVelocity> | flag |
|
<FindAttractor> | - | |
<DelayTime> | float | |
<AttractGravity> | - | |
<Gravity> | float | |
<MaxG> | float | |
<HorizontalOnly> | flag |
|
<AttractHoming> | - | |
<TurnSpeed> | float | |
<PredictPosition> | flag |
|
<HorizontalOnly> | flag |
|
<AttractSpring> | - | |
<AccelRate> | float | |
<MaxAccel> | float | |
<DesiredDistance> | float | |
<MoveLine /> | - | |
<MoveGravity> | - | |
<Fraction> | float | |
<MoveSpiral> | - | |
<Theta> | float | |
<Radius> | float | |
<RotateSpeed> | float | |
<MoveResistance> | - | |
<Resistance> | float | |
<MinimumVelocity> | float | |
<MoveDrift> | - | |
<Acceleration> | float | |
<MaxSpeed> | float | |
<SidewaysDecay> | float | |
<DirX> | float | |
<DirY> | float | |
<DirZ> | float | |
<Space> | ||
<SetVelocity> | - | |
<Speed> | float | |
<Space> | ||
<NoSideways> | flag |
|
<SpiralTangent> | - | |
<Theta> | float | |
<Radius> | float | |
<Rotate_speed> | float | |
<KillBeyondPoint> | - | |
<Direction> | ||
<Value> | float | |
<CollisionEffect> | - | |
<Effect> | ||
<WallOffset> | float | |
<Orientation> | ||
<Attach> | flag |
|
<SitckToWall /> | - | |
<Bounce> | - | |
<ElasticDirect> | float | |
<ElasticGlancing> | float | |
<Chop /> | - | This action kills the particle without triggering the Die event. |
<ImpactEffect> | ||
<ImpactType> | Name of impact, registered in ONIE. The looked-up material is known from the colliding particle. Impt and Mtrl files must exist. | |
<ImpactModifier> | ||
<Show /> | - | Unhide particle. |
<Hide /> | - | Hide particle; cannot collide with characters anymore, emitters stay active. |
<SetTextureTick> | - | |
<Tick> | float | |
<RandomTextureFrame /> | - | |
<SetVariable> | - | |
<Target> | float | |
<Value> | float | |
<RecalculateAll /> | - | |
<EnableAbove> | - | |
<Action> | integer | |
<Var> | float | |
<Threshold> | float | |
<EnableBelow> | - | |
<Action> | integer | |
<Var> | float | |
<Threshold> | float | |
<EnableNow> | - | |
<Action> | integer | Enables action X in Update event section. |
<DisableNow> | - | |
<Action> | integer | Disables action X in Update event section. |
<SuperBallTrigger> | - | |
<Emitter> | integer | |
<FuseTime> | float | |
<StopIfBreakable /> | - | ??? HitWall event only ??? Within the HitWall PAR3 event, stops the exection of all PAR3 actions listed BELOW this PAR3 action if the HitWall was called against a breakable material (in vanilla Oni, the only breakable material is glass). Example: If inside the HitWall event there are actions in this order: |
<AvoidWalls> | - | |
<AxisX> | float | |
<AxisY> | float | |
<AxisZ> | float | |
<CurrentAngle> | float | |
<TimeUntilCheck> | float | |
<SenseDistance> | float | |
<TurningSpeed> | float | |
<TurningDecay> | float | |
<RandomSwirl> | - | |
<SwirlAngle> | float | |
<SwirlBaseRate> | float | |
<SwirlDeltaRate> | float | |
<SwirlSpeed> | float | |
<FloatAbovePlayer> | ||
<Height> | float | |
<StopIfSlow> | - | |
<Speed> | float | |
<SuperParticle> | - | |
<Variable> | float | |
<VaseValue> | float | |
<DeltaValue> | float | |
<MinValue> | float | |
<MaxValue> | float | |
<StopLink /> | - | |
<CheckLink /> | - | Checks if the particle's attractor link is still valid. If the link is no longer valid, BrokenLink event is called. |
<BreakLink /> | - |
Glass-piercing bullets
In the original game, w1_tap goes through normal glass and loses its dangerousness, while a bullet of w8_mbo stays dangerous.
Particle can perform actions if a hit wall event occurs (<CollideWithWalls> must be true). If the particle hits a breakable material (glass), then <StopIfBreakable /> stops the actions that come after StopIfBreakable. The particle continues to fly. If it then hits a non-breakable material, all actions are executed.
If you want to break glass, put <DamageEnvironment> before <StopIfBreakable />.
BINA3RAPw1_tap_p01.xml | BINA3RAPw8_mbo_p01.xml |
---|---|
<HitWall> <ImpactEffect> <ImpactType>w1_tap</ImpactType> <ImpactModifier>3</ImpactModifier> </ImpactEffect> <DamageEnvironment> <Damage>13</Damage> </DamageEnvironment> <Chop /> </HitWall> |
<HitWall> <DamageEnvironment> <Damage>50</Damage> </DamageEnvironment> <StopIfBreakable /> <ImpactEffect> <ImpactType>w8_mbo</ImpactType> <ImpactModifier>2</ImpactModifier> </ImpactEffect> <Die /> </HitWall> |
Notes on locklights
[...] <Tint>color</Tint> [...] <Variables> <Color Name="color">0 0 0</Color> <Float Name="blend">0</Float> </Variables> <Emitters /> <Events> <Update> <ColorInterpolate> <Target>color</Target> <Color0>255 0 0</Color0> <Color1>0 255 0</Color1> <Amount>blend</Amount> </ColorInterpolate> <SetVariable> <Target>blend</Target> <Value>0</Value> </SetVariable> <SetVariable> <Target>blend</Target> <Value>1</Value> </SetVariable> </Update> <Start> <DisableNow> <Action>1</Action> </DisableNow> <EnableNow> <Action>2</Action> </EnableNow> </Start> <Stop> <DisableNow> <Action>2</Action> </DisableNow> <EnableNow> <Action>1</Action> </EnableNow> </Stop> </Events> |
Locklights are the particles which indicate whether a door is locked or not. They are present in ONLV (ENVP section) with different names, but are all called from "BINA3RAPlocklight.xml" and "BINA3RAPlocklight2.xml". The locklight is created on level start. The Update event has three actions: the first one has ID 0, the second has ID 1, and the third has ID 2.
|
The vanilla BINA3RAPlocklight file doesn't allow new events because of its buggy behavior. Gumby solved the problem by putting the "SetVariable" code into the start and stop event. Additional testing discovered that particles identify doors as characters. A small vid can be seen here.
<?xml version="1.0" encoding="utf-8"?> <Oni Version="0.9.52.0"> <Particle Name="locklight"> <Options> <Lifetime>0</Lifetime> <DisableDetailLevel>Never</DisableDetailLevel> <Decorative>true</Decorative> <CollideWithWalls>false</CollideWithWalls> <CollideWithChars>true</CollideWithChars> <InitiallyHidden>false</InitiallyHidden> <DrawAsSky>false</DrawAsSky> <DontAttractThroughWalls>false</DontAttractThroughWalls> <ExpireOnCutscene>false</ExpireOnCutscene> <DieOnCutscene>false</DieOnCutscene> <LockPositionToLink>false</LockPositionToLink> <CollisionRadius>7</CollisionRadius> <AIDodgeRadius>0</AIDodgeRadius> <AIAlertRadius>0</AIAlertRadius> <FlyBySoundName /> </Options> <Properties> <HasVelocity>false</HasVelocity> <HasOrientation>true</HasOrientation> <HasPositionOffset>false</HasPositionOffset> <HasAttachmentMatrix>true</HasAttachmentMatrix> <HasUnknown>false</HasUnknown> <HasDecalState>false</HasDecalState> <HasTextureStartTick>false</HasTextureStartTick> <HasTextureTick>false</HasTextureTick> <HasDamageOwner>false</HasDamageOwner> <HasContrailData>false</HasContrailData> <HasLensFlareState>true</HasLensFlareState> <HasAttractor>false</HasAttractor> <HasCollisionCache>true</HasCollisionCache> </Properties> <Appearance> <DisplayType>RotatedSprite</DisplayType> <TexGeom>lensflare11</TexGeom> <Invisible>false</Invisible> <IsContrailEmitter>false</IsContrailEmitter> <ScaleToVelocity>false</ScaleToVelocity> <Scale>2</Scale> <UseSeparateYScale>false</UseSeparateYScale> <YScale>1</YScale> <Rotation>0</Rotation> <Alpha> <Random Min="0.8" Max="0.9" /> </Alpha> <XOffset>0</XOffset> <XShorten>0</XShorten> <UseSpecialTint>false</UseSpecialTint> <Tint>color</Tint> <FadeOutOnEdge>false</FadeOutOnEdge> <OneSidedEdgeFade>false</OneSidedEdgeFade> <EdgeFadeMin>0.2</EdgeFadeMin> <EdgeFadeMax>1</EdgeFadeMax> <MaxContrailDistance>0</MaxContrailDistance> <LensFlare>true</LensFlare> <LensFlareDistance>2</LensFlareDistance> <LensFlareFadeInFrames>5</LensFlareFadeInFrames> <LensFlareFadeOutFrames>10</LensFlareFadeOutFrames> <DecalFullBrightness>false</DecalFullBrightness> <MaxDecals>100</MaxDecals> <DecalFadeFrames>60</DecalFadeFrames> <DecalWrapAngle>60</DecalWrapAngle> </Appearance> <Attractor> <Target>None</Target> <Selector>Distance</Selector> <Class /> <MaxDistance>150</MaxDistance> <MaxAngle>30</MaxAngle> <AngleSelectMin>3</AngleSelectMin> <AngleSelectMax>20</AngleSelectMax> <AngleSelectWeight>3</AngleSelectWeight> </Attractor> <Variables> <Color Name="color">0 0 0</Color> <Float Name="blend">0</Float> </Variables> <Emitters> <Emitter> <Class>h2h_ninflash_e01</Class> <Flags>IncreaseParticleCount TurnOffAtTreshold</Flags> <TurnOffTreshold>1</TurnOffTreshold> <Probability>1</Probability> <Copies>1</Copies> <LinkTo /> <Rate> <Instant /> </Rate> <Position> <Point /> </Position> <Direction> <Straight /> </Direction> <Speed> <Uniform> <Speed>0</Speed> </Uniform> </Speed> <Orientation>LocalPosY</Orientation> <OrientationUp>LocalPosZ</OrientationUp> </Emitter> </Emitters> <Events> <Update> <ColorInterpolate> <Target>color</Target> <Color0>255 0 0</Color0> <Color1>0 255 0</Color1> <Amount>blend</Amount> </ColorInterpolate> </Update> <Start> <SetVariable> <Target>blend</Target> <Value>1</Value> </SetVariable> </Start> <Stop> <SetVariable> <Target>blend</Target> <Value>0</Value> </SetVariable> </Stop> <HitCharacter> <EmitActivate> <Emitter>0</Emitter> </EmitActivate> </HitCharacter> </Events> </Particle> </Oni>
How to set up decorative decals
What are decals?
- Decals are images glued onto a wall or ground.
- They are used for additional level design and to show weapon damage on surroundings.
- The following steps will show you how to place a decorative texture (poster/warning sign/whatever) into a level.
Step 1 - extending the particle collection
- Particle collections are level specific.
- <Position> .. Choose a position for your decal.
- The maximum tolerance distance counts 10 units. Let's say the ground height (y) is 45 and the particle is spawned at 55: then this is the maximum tolerance; 56 wouldn't work.
- "chr_debug_characters = 1" helps you. But note that the y value is not the head or pelvis height -- it is at the lowest point of the feet.
- <Rotation> .. see "decal facing"
- <Class> .. this is your particle file
- <Tag> .. optional; used when you want to activate or deactivate decals or other particle via BSL
- <Flags> .. "not initially created" flag (2) or nothing (1; 4; 8)
- <XScale> .. Scaling of decal's X dimension on an individual level (you can use the 3RAP's own scaling (<Scale>) for accumulative scaling (this would affect all decals in the collection))
<Object Id="11291" Type="PART"> <Header> <Flags>0</Flags> <Position>-988 65 1521</Position> <Rotation>270 180 0</Rotation> </Header> <OSD> <Class>decal_particle_name</Class> <Tag>decal_BSL_name</Tag> <Flags>8</Flags> <Decal> <XScale>20</XScale> <YScale>20</YScale> </Decal> </OSD> </Object>
Decal facing
- Face the point where you want to have the decal. It's important that your body's facing is accurate, not your head. Then type "chr_debug_characters = 1" into the developer console and you will know the facing. Write it down, compare with the right table and chose your xyz rotation.
- PS: When it comes to spawning/displaying, the exact rotation is not needed. Oni has a 66 degree tolerance.
- PPS: <DecalWrapAngle> (in BINA3RAP file) is usually set to 60. For hard edges you might want to increase the value.
wall decals
x y z facing 0 degree: 270 | 0 | 0 facing 90 degree: 270 | 90 | 0 facing 180 degree: 270 | 180 | 0 facing 270 degree: 270 | 270 | 0
ground decals
x y z facing 0 degree: 0 | 0 | 0 facing 90 degree: 0 | 90 | 0 facing 180 degree: 0 | 180 | 0 facing 270 degree: 0 | 270 | 0
Step 2 - creating BINA3RAP file
- file name in this example: "BINA3RAPdecal_particle_name.xml"
- <CollideWithChars> .. is ignored by decals
- <HasDecalState>true .. is needed
- <DisplayType>Decal .. is needed
- <TexGeom> .. links to TXMP file
- <Alpha> .. alpha level is ignored when TXMP has adaptiveAlpha flag
- <Tint> .. is ignored by decals
<?xml version="1.0" encoding="utf-8"?> <Oni> <Particle Name="decal_particle_name"> <Options> <Lifetime>0</Lifetime> <DisableDetailLevel>Never</DisableDetailLevel> <Decorative>true</Decorative> <CollideWithWalls>false</CollideWithWalls> <CollideWithChars>false</CollideWithChars> <InitiallyHidden>false</InitiallyHidden> <DrawAsSky>false</DrawAsSky> <DontAttractThroughWalls>false</DontAttractThroughWalls> <ExpireOnCutscene>false</ExpireOnCutscene> <DieOnCutscene>false</DieOnCutscene> <LockPositionToLink>false</LockPositionToLink> <CollisionRadius>0</CollisionRadius> <AIDodgeRadius>0</AIDodgeRadius> <AIAlertRadius>0</AIAlertRadius> <FlyBySoundName /> </Options> <Properties> <HasVelocity>false</HasVelocity> <HasOrientation>false</HasOrientation> <HasPositionOffset>false</HasPositionOffset> <HasAttachmentMatrix>false</HasAttachmentMatrix> <HasUnknown>false</HasUnknown> <HasDecalState>true</HasDecalState> <HasTextureStartTick>false</HasTextureStartTick> <HasTextureTick>false</HasTextureTick> <HasDamageOwner>false</HasDamageOwner> <HasContrailData>false</HasContrailData> <HasLensFlareState>false</HasLensFlareState> <HasAttractor>false</HasAttractor> <HasCollisionCache>false</HasCollisionCache> </Properties> <Appearance> <DisplayType>Decal</DisplayType> <TexGeom>animated_texture</TexGeom> <Invisible>false</Invisible> <IsContrailEmitter>false</IsContrailEmitter> <ScaleToVelocity>false</ScaleToVelocity> <Scale>1</Scale> <UseSeparateYScale>false</UseSeparateYScale> <YScale>1</YScale> <Rotation>0</Rotation> <Alpha>1</Alpha> <XOffset>0</XOffset> <XShorten>0</XShorten> <UseSpecialTint>false</UseSpecialTint> <Tint>255 255 255</Tint> <FadeOutOnEdge>false</FadeOutOnEdge> <OneSidedEdgeFade>false</OneSidedEdgeFade> <EdgeFadeMin>0</EdgeFadeMin> <EdgeFadeMax>0.5</EdgeFadeMax> <MaxContrailDistance>0</MaxContrailDistance> <LensFlare>false</LensFlare> <LensFlareDistance>0</LensFlareDistance> <LensFlareFadeInFrames>0</LensFlareFadeInFrames> <LensFlareFadeOutFrames>0</LensFlareFadeOutFrames> <DecalFullBrightness>false</DecalFullBrightness> <MaxDecals>100</MaxDecals> <DecalFadeFrames>60</DecalFadeFrames> <DecalWrapAngle>60</DecalWrapAngle> </Appearance> <Attractor> <Target>None</Target> <Selector>Distance</Selector> <Class /> <MaxDistance>150</MaxDistance> <MaxAngle>30</MaxAngle> <AngleSelectMin>3</AngleSelectMin> <AngleSelectMax>20</AngleSelectMax> <AngleSelectWeight>3</AngleSelectWeight> </Attractor> <Variables /> <Emitters /> <Events /> </Particle> </Oni>
Step 3 - creating TXMP file
- file name in this example: "TXMPanimated_texture.xml"
- Of course the particle file doesn't have to contain an animated image. It's just meant to remind you that this is an option.
<?xml version="1.0" encoding="utf-8"?> <Oni> <Texture> <Flags>HasMipMaps AnimUseLocalTime AnimBackToBack AdditiveBlend</Flags> <Format>RGB555</Format> <Speed>4</Speed> <Image>TXMPanimated_tex_part_000.tga</Image> <Image>TXMPanimated_tex_part_001.tga</Image> <Image>TXMPanimated_tex_part_002.tga</Image> <Image>TXMPanimated_tex_part_003.tga</Image> <Image>TXMPanimated_tex_part_004.tga</Image> <Image>TXMPanimated_tex_part_005.tga</Image> <Image>TXMPanimated_tex_part_006.tga</Image> <Image>TXMPanimated_tex_part_007.tga</Image> <Image>TXMPanimated_tex_part_008.tga</Image> <Image>TXMPanimated_tex_part_009.tga</Image> <Image>TXMPanimated_tex_part_010.tga</Image> </Texture> </Oni>
Step 4 - show or hide decals via BSL
Fork "respawnable_decals" in your main function
var bool first = 1; func respawnable_decals { chr_debug_characters = 1 dmsg "( punch to hide a few decals now )" ### decal is already present so we begin with stop function fork kill_decal } func kill_decal { sleep 30 chr_wait_animtype 0 punch dmsg "( punch detected; [r.deactivating decals now] )" ### has effect at all particle with chosen tag ### in the vid, obviously the two decals use the same tag particle decal_BSL_name kill if (first eq 1) { dmsg "( kick to show a few decals now )" first = 0; sleep 60 } fork create_decal } func create_decal { sleep 30 chr_wait_animtype 0 kick dmsg "( kick detected; [b.activating decals now] )" particle decal_BSL_name create fork kill_decal }
How to set up decorative character items
Based on geyser's "silly world" experiment.
Marks, bags, goggles, decorative LSIs, flashlights, and other equipment could individualize characters by using a (BSL-triggered) particle workaround.
Step 1: ONCC modifications
First we need to create a connection to the character. For this, we use the Daodan particle system.
<HasDaodanPowers>1</HasDaodanPowers>
Now it's enabled for this character. Next we register our item (the holding particle) in the ONCP section.
<ONCPParticle> <Name>super_shades</Name> <Type>silly_shades</Type> <BodyPart>10</BodyPart> </ONCPParticle>
<Name> As long as super stands at beginning, the further naming is unimportant.
<Type> This is a link to the particle file.
<BodyPart> This is the body part where the particle is attached to. Position fine tuning can be done in M3GM's PNTA section, <Positions>.
Step 2: creating the item files
- BINA3RAPsilly_glasses.xml
- Needed modifications:
<Lifetime>0</Lifetime> <HasAttachmentMatrix>true</HasAttachmentMatrix> <DisplayType>Geometry</DisplayType> <TexGeom>silly_shades</TexGeom> <Events> <Start> <Show /> </Start> <Stop> <Hide /> </Stop> </Events>
- M3GMsilly_shades.xml
<Texture>TXMPsilly_shades_tex</Texture>
- TXMPsilly_shades_tex.xml
Step 3: preparing the BSL stuff
- BINACJBOCharacter.xml
<Spawn>silly_setup</Spawn>
- shpadoinkle.bsl
#character spawn function func silly_setup(string name) { chr_lock_active(name) chr_super(name, 1) sleep 2 chr_super(name, 0) }
- silly_setup will be triggered every time a character is spawned with this link in BINACJBOCharacter.xml
- Only the AI would need chr_lock_active.
- chr_super becomes disabled again to prevent other Daodan effects (in case our character has a chenille or other visuals). We don't have to worry about the item, its lifetime was set to 0 (infinity). ("chr_super 0" only hides the particle, it doesn't kill it.)
func main { # [...] p3_callevent silly_glasses 2 # [...] }
2 corresponds to <Start> tag and 3 corresponds to <Stop> tag in BINA3RAPsilly_shades.xml This can switch the item on and off. Other effects could be triggered by the free remaining numbers. A collection of events and their numbers can be seen HERE.
Extra demo
For all Gundam Seed fans out there: Phase Shift shades. ^_^ Nope, the texture of an object cannot be replaced by another. But by using three different pairs of shades, we can create this illusion. There are blue shades. A pair that uses an animated texture. And a red pair. The animated pair is only temporarily used. Here's a vid.
func spawn_karen { chr_super karen 1 ### all three shades particles created sleep 2 ### now but we need to hide them chr_super karen 0 ### show only blue shades for the start p3_callevent shades_blue 2 } func phase_shift_shades { p3_callevent shades_blue 3 p3_callevent shades_blue_red 2 sleep 20 p3_callevent shades_blue_red 3 p3_callevent shades_red 2 }