// Blood Class UTBlood : Actor { Default { RenderStyle "Add"; Scale 1.1; +NOBLOCKMAP; +NOGRAVITY; +NOTELEPORT; +DONTSPLASH; +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: Spray: 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; Gravity 0.8; Mass 1; Radius 2; Height 2; RenderStyle "Translucent"; +MISSILE; +NOTELEPORT; +DONTSPLASH; +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 leave decals } 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; +DONTSPLASH; +NOTELEPORT; +THRUACTORS; } override void PostBeginPlay() { Super.PostBeginPlay(); str = FRandom[Blood](2.0,3.2)*args[0]; int sz = 7*args[0]; double ang, pt; if ( !flak_blood ) sz /= 3; for ( int i=0; i gibcls[] = {"UTGenericGib1","UTGenericGib2","UTGenericGib3","UTGenericGib4"}; Actor a; double ang, pt; Vector3 dir; bool dummy; for ( int i=0; i parts[] = {"UTFemaleFoot","UTThigh"}; static const double partofsy[] = {9,8}; static const double partofsz[] = {9,20}; Actor a; double ang, pt; Vector3 dir; if ( !firstgib ) { firstgib = true; for ( int i=0; i<2; i++ ) { Actor a = Spawn(parts[i],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i])); 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](3.0,6.0); } } for ( int i=0; i bossparts[] = {"UTBossArm","UTBossArm","UTBossFoot","UTBossFoot","UTMaleTorso","UTHeadBoss"}; static const class maleparts[] = {"UTMaleArm","UTMaleArm","UTMaleFoot","UTMaleFoot","UTMaleTorso","UTHeadMale"}; static const class femaleparts[] = {"UTFemaleArm","UTFemaleArm","UTFemaleFoot","UTFemaleFoot","UTFemaleTorso","UTHeadFemale"}; static const class extraparts[] = {"UTThigh","UTThigh","UTHeart","UTLiver","UTStomach"}; static const double partofsy[] = { 14, -14, 9, -9, 0, 0, 8, -8, -2, 5, -3 }; static const double partofsz[] = { 36, 36, 9, 9, 32, 48, 20, 20, 40, 32, 35 }; Actor a; double ang, pt; Vector3 dir; if ( !firstgib ) { firstgib = true; for ( int i=0; i<11; i++ ) { if ( (i == 5) && UTPlayer(Gibbed).headless ) continue; if ( (i == 0) && UTPlayer(Gibbed).armlessR ) continue; if ( (i == 1) && UTPlayer(Gibbed).armlessL ) continue; if ( ((i == 2) || (i == 6)) && UTPlayer(Gibbed).leglessR ) continue; if ( ((i == 3) || (i == 7)) && UTPlayer(Gibbed).leglessL ) continue; if ( ((i == 4) || (i > 7)) && UTPlayer(Gibbed).torsoless ) continue; Actor a; if ( i < 6 ) { if ( UTPlayer(Gibbed).DollType == UTPlayer.DOLL_Boss ) a = Spawn(bossparts[i],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i])); else if ( UTPlayer(Gibbed).DollType == UTPlayer.DOLL_Female ) a = Spawn(femaleparts[i],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i])); else a = Spawn(maleparts[i],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i])); } else a = Spawn(extraparts[i-6],Vec3Offset(-partofsy[i]*sin(angle),partofsy[i]*cos(angle),partofsz[i])); ang = FRandom[Blod](0,360); pt = FRandom[Blod](-90,90); if ( a is 'UTHead' ) { pt = FRandom[Blod](-90,-15); if ( UTPlayer(Gibbed).player ) { UTPlayer(Gibbed).player.Camera = a; UTHead(a).headowner = UTPlayer(Gibbed).player; } } dir = (cos(pt)*cos(ang),cos(pt)*sin(ang),sin(-pt)); a.vel = rvel*0.6+dir*FRandom[Blod](3.0,6.0); } } for ( int i=0; i double.epsilon ) vel = (vel.unit()+(FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2),FRandom[Blod](-0.2,0.2))).unit()*spd; if ( BlockingFloor && (vel.xy.length() < 1) ) { ClearBounce(); ExplodeMissile(); } if ( spd < 10 ) { if ( tracer ) tracer.Destroy(); } else if ( spd > 20 ) vel *= 0.8; A_PlaySound("misc/gibp"); double ang, pt; int max = flak_blood?6:2; for ( int i=0; i 0) && (headowner.Camera == self) ) { headowner.Camera = headowner.mo; headowner = null; } } override void OnDestroy() { if ( headowner && (headowner.Camera == self) && headowner.mo ) { headowner.Camera = headowner.mo; headowner = null; } Super.OnDestroy(); } States { Death: UGIB A 1 A_SetTics(Random[Blod](12,18)*15); UGIB A 0 A_JumpIf(headowner,"Death"); UGIB A 1 A_FadeOut(0.05); Wait; } } Class UTHeadFemale : UTHead {} Class UTHeadMale : UTHead {} Class UTHeadBoss : UTHead {}