[This update requires a very recent Q/GZDoom build]

Added per-frame update option to Redeemer Readout.
Began work on blood and gore features (mostly functional at the moment).
This commit is contained in:
Marisa the Magician 2018-11-24 16:46:10 +01:00
commit 830bcff4a7
7 changed files with 401 additions and 70 deletions

View file

@ -1,33 +1,36 @@
user int flak_protomenu = 0; // version of main menu (0: final, 1: 22x betas, 2: same as 1, but with extended menu music)
user bool flak_showmenu = true; // show the UT main menu background whenever the menu is open
server bool flak_pulsereload = false; // pulsegun can reload (features unused animation from early versions)
server bool flak_enforcerreload = false; // enforcer can reload
user bool flak_redeemerreadout = true; // enable target readout, may cause slowdowns on weak CPUs
user int flak_colorprefs = 2; // 0: team color, 1: player color, 2: custom color
user color flak_colorcustom = "00 80 ff"; // custom hud color
user int flak_opacity = 15; // UT's opacity is 1 <-> 16 in steps of 1 (default 15)
// 16 means fully opaque, everything else is just additive with gradually lowering alpha
// status is never fully opaque (clamped under 16)
// currently selected weapon and numbers are fully opaque until 8 opacity (their opacity is bumped by 7 basically)
user bool flak_showweapons = true; // if disabled, frags and ammo are shown centered, with a gap for armor and health
user bool flak_showstatus = true; // if disabled armor and health show on the top right (or center between frags and ammo if weapon display is disabled)
user bool flak_showammo = true; // show ammo counters
user bool flak_showfrags = true; // show kill/frag count
user bool flak_showinfo = true; // show name of aimed at player in mp (and their health if in coop or same team)
user float flak_hudsize = 1.0; // 0.2 <-> 1.0 in steps of 0.2 (default 1.0)
user float flak_weaponsize = 0.8; // 0.2 <-> 1.0 in steps of 0.2 (default 0.8)
user float flak_statussize = 1.0; // 0.5 <-> 1.5 in steps of 0.1 (default 1.0)
user bool flak_footsteps = true; // players make footstep sounds
server bool flak_translocator = false; // translocator is enabled (hello, sequence breaking)
user bool flak_noswitchdeemer = true; // don't switch to redeemer when out of ammo
user bool flak_deemershader = false; // fancy blur/grain/tint shader
server bool flak_classicsshock = false; // classic enhanced shock rifle (no altfire, beams don't have splash damage)
server bool flak_utmovement = false; // emulate UE1's air/ground movement physics
server bool flak_doomspeed = false; // keep Doomguy run speed when using UT movement
server bool flak_doomaircontrol = false; // keep Doom's limited air control when using UT movement
server bool flak_nobosstelefrag = false; // disable telefragging of boss monsters (useful when translocator is enabled)
server bool flak_nowalkdrop = false; // don't drop off ledges while holding walk key (glitchy)
server bool flak_corpsedamage = false; // [WIP/EXPERIMENTAL] allow corpses to take damage and be gibbed, currently just causes a jump to XDeath until gore system is implemented
server bool flak_swingers = true; // weapon recoil that affects player view
server float flak_swingerstrength = 0.5; // strength of visual recoil
server bool flak_radboots = true; // jump boots protect against damaging floors (this is to account for the lack of a radsuit)
user int flak_protomenu = 0; // version of main menu (0: final, 1: 22x betas, 2: same as 1, but with extended menu music)
user bool flak_showmenu = true; // show the UT main menu background whenever the menu is open
server bool flak_pulsereload = false; // pulsegun can reload (features unused animation from early versions)
server bool flak_enforcerreload = false; // enforcer can reload
user bool flak_redeemerreadout = true; // enable target readout, may cause slowdowns on weak CPUs
user bool flak_redeemerreadout_perframe = false; // target readout updates per-frame rather than per-tic. experimental for asmjit performance testing (seems to work well so far)
user int flak_colorprefs = 2; // 0: team color, 1: player color, 2: custom color
user color flak_colorcustom = "00 80 ff"; // custom hud color
user int flak_opacity = 15; // UT's opacity is 1 <-> 16 in steps of 1 (default 15)
// 16 means fully opaque, everything else is just additive with gradually lowering alpha
// status is never fully opaque (clamped under 16)
// currently selected weapon and numbers are fully opaque until 8 opacity (their opacity is bumped by 7 basically)
user bool flak_showweapons = true; // if disabled, frags and ammo are shown centered, with a gap for armor and health
user bool flak_showstatus = true; // if disabled armor and health show on the top right (or center between frags and ammo if weapon display is disabled)
user bool flak_showammo = true; // show ammo counters
user bool flak_showfrags = true; // show kill/frag count
user bool flak_showinfo = true; // show name of aimed at player in mp (and their health if in coop or same team)
user float flak_hudsize = 1.0; // 0.2 <-> 1.0 in steps of 0.2 (default 1.0)
user float flak_weaponsize = 0.8; // 0.2 <-> 1.0 in steps of 0.2 (default 0.8)
user float flak_statussize = 1.0; // 0.5 <-> 1.5 in steps of 0.1 (default 1.0)
user bool flak_footsteps = true; // players make footstep sounds
server bool flak_translocator = false; // translocator is enabled (hello, sequence breaking)
user bool flak_noswitchdeemer = true; // don't switch to redeemer when out of ammo
user bool flak_deemershader = false; // fancy blur/grain/tint shader
server bool flak_classicsshock = false; // classic enhanced shock rifle (no altfire, beams don't have splash damage)
server bool flak_utmovement = false; // emulate UE1's air/ground movement physics
server bool flak_doomspeed = false; // keep Doomguy run speed when using UT movement
server bool flak_doomaircontrol = false; // keep Doom's limited air control when using UT movement
server bool flak_nobosstelefrag = false; // disable telefragging of boss monsters (useful when translocator is enabled)
server bool flak_nowalkdrop = false; // don't drop off ledges while holding walk key (glitchy)
server bool flak_corpsedamage = false; // [WIP/EXPERIMENTAL] allow corpses to take damage and be gibbed, currently just causes a jump to XDeath until gore system is implemented
server bool flak_swingers = true; // weapon recoil that affects player view
server float flak_swingerstrength = 0.5; // strength of visual recoil
server bool flak_radboots = true; // jump boots protect against damaging floors (this is to account for the lack of a radsuit)
server bool flak_blood = true; // use doom tournament blood (disable if using another gore mod)
server bool flak_gibs = true; // use doom tournament gibbing (disable if using another gore mod)

View file

@ -23,6 +23,7 @@ OptionMenu "UTOptionMenu"
Option "Enforcer Reloading", "flak_enforcerreload", "YesNo"
Option "Pulsegun Reloading", "flak_pulsereload", "YesNo"
Option "Redeemer Target Visuals", "flak_redeemerreadout", "YesNo"
Option "Per-Frame Target Updates", "flak_redeemerreadout_perframe", "YesNo"
Option "Redeemer View Shader", "flak_deemershader", "YesNo"
Option "No Redeemer Autoswitch", "flak_noswitchdeemer", "YesNo"
Option "Classic Enh. Shock Rifle", "flak_classicsshock", "YesNo"
@ -58,6 +59,8 @@ OptionMenu "UTOptionMenu"
StaticText " "
StaticText "Misc Options", "Gold"
Option "UT Footsteps", "flak_footsteps", "YesNo"
Option "UT Blood", "flak_blood", "YesNo"
Option "[WIP] UT Gibbing", "flak_gibs", "YesNo"
Option "[WIP] Corpses Take Damage", "flak_corpsedamage", "YesNo"
}

View file

@ -129,15 +129,15 @@ misc/gibbed3 gib3
misc/gibbed4 gib4
misc/gibbed5 gib5
$random misc/gibbed { misc/gibbed1 misc/gibbed2 misc/gibbed3 misc/gibbed4 misc/gibbed5 }
// universal gibs compat
$alias UniversalGibs/Gib misc/gibbed
// droplets compat
misc/gibp1 gibp1
misc/gibp2 gibp3
misc/gibp3 gibp4
misc/gibp4 gibp5
misc/gibp5 gibp6
$random misc/gibp { misc/gibp1 misc/gibp2 misc/gibp3 misc/gibp4 misc/gibp5 }
// universal gibs compat
$alias UniversalGibs/Gib misc/gibbed
// droplets compat
$alias blood/hit misc/gibp
impact/select imppick

View file

@ -176,6 +176,7 @@ Class SniperRifle : UTWeapon
Weapon.AmmoGive 8;
Weapon.Kickback 250;
UTWeapon.DropAmmo 2;
+NOEXTREMEDEATH;
}
States
{

View file

@ -440,23 +440,6 @@ Class UTPlayer : DoomPlayer
}
}
// Random Spawner that passes through dropped status to items
Class RandomSpawner2 : RandomSpawner
{
override void PostSpawn( Actor spawned )
{
if ( !bDROPPED ) return;
if ( spawned is 'Inventory' ) Inventory(spawned).bTOSSED = bDROPPED;
if ( spawned is 'UTWeapon' )
{
spawned.SetState(spawned.ResolveState("Spawn")+1);
Inventory(spawned).bALWAYSPICKUP = true;
if ( UTWeapon(spawned).DropAmmo > 0 )
Weapon(spawned).AmmoGive1 = min(UTWeapon(spawned).DropAmmo,Weapon(spawned).AmmoGive1);
}
}
}
Class UTWeapon : Weapon
{
int DropAmmo;
@ -1378,6 +1361,7 @@ Class UTMainHandler : StaticEventHandler
else if ( e.Replacee == 'YellowSkull' ) e.Replacement = 'UTGoldSkull';
else if ( e.Replacee == 'TeleportFog' ) e.Replacement = 'UTTeleportFog';
else if ( e.Replacee == 'ItemFog' ) e.Replacement = 'UTItemFog';
else if ( flak_blood && (e.Replacee == 'Blood') ) e.Replacement = 'UTBlood';
}
private Actor AddLight( Vector3 pos, Color col, int radius )
@ -1592,6 +1576,28 @@ Class UTMainHandler : StaticEventHandler
override void WorldThingDied( WorldEvent e )
{
if ( e.Thing.bDONTGIB ) return;
// gibbers
if ( flak_gibs && !e.Thing.bNOBLOOD && ((e.Inflictor && e.Inflictor.bEXTREMEDEATH) || (e.Thing.Health < e.Thing.GetGibHealth())) && (!e.Inflictor || !e.Inflictor.bNOEXTREMEDEATH) )
{
// players have special gibbing
if ( e.Thing.player )
{
return;
}
// generic gibbing
let a = Actor.Spawn("UTGibber",e.Thing.pos);
a.vel = e.Thing.vel;
a.Scale = e.Thing.Scale;
a.Translation = e.Thing.BloodTranslation;
if ( e.Thing.BloodColor ) a.SetShade(e.Thing.BloodColor);
else a.SetShade(gameinfo.defaultbloodcolor);
a.A_SetSize(e.Thing.radius,e.Thing.height);
e.Thing.A_XScream();
e.Thing.A_NoBlocking();
e.Thing.A_BossDeath();
e.Thing.Destroy();
return;
}
// attach damage accumulator for corpses
if ( !flak_corpsedamage ) return;
let a = Actor.Spawn("ShredCorpseHitbox",e.Thing.pos);

View file

@ -1,55 +1,351 @@
// Blood
Class UTBlood : Actor
{
Default
{
RenderStyle "Add";
Scale 1.1;
+NOBLOCKMAP;
+NOGRAVITY;
+NOTELEPORT;
+FORCEXYBILLBOARD;
+PUFFGETSOWNER;
}
void A_Bleed( int str = 1 )
{
Scale *= 0.7+0.3*str;
vel *= 0;
let b = Spawn("UTBloodSpurt",pos);
b.angle = angle+FRandom[Blud](-15,15);
b.pitch = pitch+FRandom[Blud](-15,15);
b.translation = translation;
b.args[0] = str;
// transfer blood color for decals
if ( target && target.bloodcolor ) b.SetShade(target.bloodcolor);
else b.SetShade(gameinfo.defaultbloodcolor);
}
States
{
Spawn:
TNT1 A 0 NoDelay A_Bleed(3);
Goto Puff;
TNT1 A 0 A_Bleed(2);
Goto Puff;
TNT1 A 0 A_Bleed(1);
Goto Puff;
Puff:
TNT1 A 0
{
int dec = Random[Blod](0,2);
if ( dec == 1 )
return ResolveState("Puff1");
if ( dec == 2 )
return ResolveState("Puff2");
return ResolveState("Puff3");
}
Puff1:
BPF1 ABCDEFGHIJK 1;
Stop;
Puff2:
BPF2 ABCDEFGH 1;
Stop;
Puff3:
BPF3 ABCDEFGHIJ 1;
Stop;
}
}
// single drop of blod
Class UTBloodDrop : Actor
{
Default
{
Scale 0.24;
Radius 2;
Height 2;
RenderStyle "Translucent";
+MISSILE;
+NOTELEPORT;
+THRUACTORS;
+FORCEXYBILLBOARD;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
SetState(FindState("Spawn")+Random[Blod](0,4));
Scale *= FRandom[Blod](0.6,1.4);
}
void A_BloodDie()
{
// TODO
}
States
{
Spawn:
BDRP ABCDE -1;
Stop;
Death:
TNT1 A 0 A_BloodDie();
Stop;
}
}
// a burst of blod
Class UTBloodSpurt : Actor
{
double str;
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
+NOTELEPORT;
+THRUACTORS;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
str = FRandom[Blood](2.0,3.2)*args[0];
int sz = 7*args[0];
double ang, pt;
for ( int i=0; i<sz; i++ )
{
let d = Spawn("UTBloodDrop",pos);
d.translation = translation;
d.SetShade(fillcolor);
ang = angle+FRandom[Blood](-3,3)*str;
pt = pitch+FRandom[Blood](-3,3)*str;
Vector3 dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),-sin(pt));
d.vel = dir*str*FRandom[Blood](0.8,1.2);
d.vel.z += str*0.8;
d.scale *= str*0.15*FRandom[Blood](0.6,1.4);
}
Destroy();
}
}
// for chunks
Class UTBloodTrail : Actor
{
double str;
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
+NOTELEPORT;
+THRUACTORS;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( !target ) return;
str = FRandom[Blood](2.0,4.0);
}
private bool IsTargetFlying()
{
if ( !target ) return false;
if ( target.InStateSequence(target.CurState,target.FindState("Spawn")) ) return true;
return false;
}
override void Tick()
{
Super.Tick();
if ( level.frozen || globalfreeze ) return;
if ( !target ) return;
SetOrigin(target.pos,true);
double ang, pt;
for ( int i=0; i<3; i++ )
{
let d = Spawn("UTBloodDrop",pos);
d.translation = translation;
d.SetShade(fillcolor);
ang = FRandom[Blood](0,360);
pt = FRandom[Blood](-90,90);
Vector3 dir = -target.vel*0.2;
dir += (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*0.8;
d.vel = dir*str*FRandom[Blood](0.8,1.2);
d.scale *= str*0.15*FRandom[Blood](0.6,1.4);
}
bool flying = IsTargetFlying();
if ( !flying ) Destroy();
}
}
// Poof
Class UTBloodPuff : Actor
{
Default
{
RenderStyle "Add";
Scale 1.1;
Alpha 0.4;
+NOBLOCKMAP;
+NOGRAVITY;
+NOTELEPORT;
+FORCEXYBILLBOARD;
}
States
{
Spawn:
TNT1 A 0 NoDelay
{
int dec = Random[Blod](0,2);
if ( dec == 1 )
return ResolveState("Puff1");
if ( dec == 2 )
return ResolveState("Puff2");
return ResolveState("Puff3");
}
Puff1:
BPF1 ABCDEFGHIJK 2;
Stop;
Puff2:
BPF2 ABCDEFGH 2;
Stop;
Puff3:
BPF3 ABCDEFGHIJ 2;
Stop;
}
}
// Chunkers
Class UTGibber : Actor
{
Actor Gibbed;
int gibcount, gibsize;
color shadecol;
Vector3 rvel;
virtual void BurstGibs()
{
static const class<Actor> gibcls[] = {"UTGenericGib1","UTGenericGib2","UTGenericGib3","UTGenericGib4"};
Actor a;
double ang, pt;
Vector3 dir;
bool dummy;
for ( int i=0; i<gibsize; i++ )
{
let a = Spawn(gibcls[Random[Blod](0,3)],pos+(FRandom[Blod](-0.5,0.5)*radius,FRandom[Blod](-0.5,0.5)*radius,FRandom[Blod](0.2,0.8)*height));
a.translation = translation;
a.SetShade(fillcolor);
a.scale *= FRandom[Blod](1.7,2.3)*scale.x;
ang = FRandom[Blod](0,360);
pt = FRandom[Blod](-90,90);
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
a.vel = rvel*0.6+dir*FRandom[Blod](8.0,12.0);
}
for ( int i=0; i<gibsize; i++ )
{
let a = Spawn("UTBloodPuff",pos+(FRandom[Blod](-0.8,0.8)*radius,FRandom[Blod](-0.8,0.8)*radius,FRandom[Blod](0.1,0.9)*height));
a.translation = translation;
a.SetShade(fillcolor);
a.scale *= FRandom[Blod](1.8,2.3)*scale.x;
ang = FRandom[Blod](0,360);
pt = FRandom[Blod](-90,90);
dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt));
a.vel = rvel*0.2+dir*FRandom[Blod](1.5,3.0);
}
A_CountDown();
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
gibsize = int(min(max(radius,height)/24,3));
reactiontime = int(min(max(radius,height)/10,4));
rvel = vel;
vel *= 0;
}
Default
{
+NOCLIP;
+NOGRAVITY;
Radius 32;
Height 16;
}
States
{
Spawn:
TNT1 A 0 NoDelay A_PlaySound("misc/gibbed");
TNT1 A 1 BurstGibs();
Wait;
}
}
// Chunks
Class UTGib : Actor
{
double rollvel, anglevel, pitchvel;
Default
{
Radius 4;
Height 4;
BounceType "Doom";
BounceFactor 0.5;
WallBounceFactor 0.5;
BounceFactor 0.7;
WallBounceFactor 0.7;
+ROLLSPRITE;
+ROLLCENTER;
+INTERPOLATEANGLES;
+MISSILE;
+SHOOTABLE;
+NODAMAGE;
+THRUACTORS;
+USEBOUNCESTATE;
}
override void Tick()
override void PostBeginPlay()
{
Super.Tick();
// TODO trails and stuff
Super.PostBeginPlay();
let t = Spawn("UTBloodTrail",pos);
t.target = self;
if ( bloodcolor ) t.SetShade(bloodcolor);
else t.SetShade(gameinfo.defaultbloodcolor);
t.translation = bloodtranslation;
rollvel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1);
anglevel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1);
pitchvel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1);
}
void A_HandleBounce()
{
if ( vel.length() > double.epsilon )
vel = (vel.unit()+(FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2))).unit()*vel.length();
A_PlaySound("misc/gibp");
double ang, pt;
for ( int i=0; i<6; i++ )
{
let d = Spawn("UTBloodDrop",pos);
d.translation = bloodtranslation;
if ( bloodcolor ) d.SetShade(bloodcolor);
else d.SetShade(gameinfo.defaultbloodcolor);
ang = FRandom[Blood](0,360);
pt = FRandom[Blood](-90,90);
Vector3 dir = -vel*0.4;
dir += (cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*1.3;
d.vel = dir*FRandom[Blood](0.8,1.2);
d.scale *= 0.75*FRandom[Blood](0.6,1.4);
}
rollvel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1);
anglevel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1);
pitchvel = FRandom[Blod](5,15)*RandomPick[Blod](-1,1);
}
States
{
Spawn:
UGIB A -1;
Stop;
UGIB A 1
{
roll += rollvel;
angle += anglevel;
pitch += pitchvel;
}
Wait;
Bounce:
UGIB A 0;
UGIB A 0 A_HandleBounce();
Goto Spawn;
Death:
UGIB A -1;
Stop;
UGIB A 1 A_SetTics(Random[Blod](12,18)*15);
UGIB A 1 A_FadeOut(0.05);
Wait;
}
}
Class UTGenericGib1 : UTGib {}

View file

@ -452,8 +452,8 @@ Class RedeemerHUD : HUDMessageBase
double ViewAngle, ViewPitch, ViewRoll, LagRoll, LagRoll2;
TextureID reticle1, reticle2, arrow, mark, readout;
Font whfont;
ThinkerIterator t;
MidTracer tr;
transient ThinkerIterator t;
transient MidTracer tr;
Array<TargetActor> ta;
Shape2D sshape, darrow;
bool dodim;
@ -466,8 +466,6 @@ Class RedeemerHUD : HUDMessageBase
mark = TexMan.CheckForTexture("Crosshr6",TexMan.Type_Any);
readout = TexMan.CheckForTexture("Readout",TexMan.Type_Any);
whfont = Font.GetFont('WHFONT');
t = ThinkerIterator.Create("Actor");
tr = new("MidTracer");
sshape = new("Shape2D");
sshape.PushCoord((0,0));
sshape.PushCoord((1,0));
@ -482,8 +480,10 @@ Class RedeemerHUD : HUDMessageBase
LagRoll = Quat.Normalize180(ViewRoll-LagRoll2);
LagRoll2 += Quat.Normalize180(LagRoll-LagRoll2)*0.1;
// shootable targetting
if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() )
if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() && !CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() )
{
if ( !t ) t = ThinkerIterator.Create("Actor");
if ( !tr ) tr = new("MidTracer");
t.Reinit();
ta.Clear();
Actor a;
@ -511,6 +511,28 @@ Class RedeemerHUD : HUDMessageBase
// shootable targetting
if ( CVar.GetCVar('flak_redeemerreadout',players[consoleplayer]).GetBool() )
{
if ( CVar.GetCVar('flak_redeemerreadout_perframe',players[consoleplayer]).GetBool() )
{
if ( !t ) t = ThinkerIterator.Create("Actor");
if ( !tr ) tr = new("MidTracer");
t.Reinit();
ta.Clear();
Actor a;
Vector3 vdir = (cos(ViewAngle)*cos(ViewPitch),sin(ViewAngle)*cos(ViewPitch),-sin(ViewPitch));
while ( a = Actor(t.Next()) )
{
Vector3 tdir = Level.Vec3Diff(ViewPos,a.Pos+(0,0,a.Height*0.5));
if ( !a.bSHOOTABLE || (a.Health <= 0) || ((Camera is 'GuidedWarShell') && (a == GuidedWarShell(Camera).b)) || (tdir.length() > 2000) || (acos(tdir.unit() dot vdir) > players[consoleplayer].FOV) || tr.Trace(ViewPos,Camera.CurSector,tdir.unit(),tdir.length(),0) ) continue;
Vector3 wpos = ViewPos+tdir;
Vector3 spos = mkCoordUtil.WorldToScreen(wpos,ViewPos,ViewPitch,ViewAngle,ViewRoll,players[consoleplayer].FOV);
if ( spos.z > 1.0 ) continue;
TargetActor te = new("TargetActor");
te.vpos = mkCoordUtil.ToViewport(spos);
te.diststr = String.Format("%f",tdir.length());
te.diststr.Replace(".","");
ta.Push(te);
}
}
for ( int i=0; i<ta.Size(); i++ )
{
Screen.DrawTexture(mark,false,ta[i].vpos.x,ta[i].vpos.y,DTA_RenderStyle,(1|2<<8|1<<16));