Hi. I'm absolutely retarded, have no idea what I'm doing, and my code sucks balls. ![w00t! \o/ \o/](/styles/smilies/handsinair.gif)
[EDIT] System is now working fully, but needs optimization! See second post
Now with that out of the way, I'm working on making a system that allows me to specify custom blood colors for pawns. So far, I have an enum variable in my custom pawn superclass (EXUScriptedPawn) which works fine; decals and blood spurts are the proper colors.
I also have a new CreatureCarcass subclass (EXUCreatureCarcass) and a new CreatureChunks subclass (EXUCreatureChunks) in order to apply custom blood and decals so they match the originating pawn's blood color. So far, I have managed to get the carcass to inherit the originating pawn's (the instigator's) blood color, but I can't seem to pass this info on to the gib chunks when the carcass inevitably explodes into a shower of little pieces.
The whole system I've designed to handle all this is pretty damn gnarly, but when I started off, I used simpler measures that refused to compile, probably because I'm not fully understanding what I'm doing. For instance, BloodEXU used to have a Hemospectrum enum to match EXUScriptedPawn, but setting BloodEXU's hemospectrum value via EXUScriptedPawn never compiled, so I made a bunch of init functions for each blood type and set up the proper textures and stuff from those. Messy, but functional.
Anyway, here's actual code.
First, relevant chunks of EXUScriptedPawn (click for more readable Pastebin links), including the vars I've set up:
And the functions which use them:
As you can see, this is all a hilarious mess. I have the exact same Hemospectrum enum in EXUCreatureCarcass and in EXUCreatureChunks, but if I simply put a b.Hemospectrum = Hemospectrum; line, UCC bitches at me with a "incorrect type in '=' " error message. I'm guessing this is because my enums don't exist across the board in Actor like, say, DrawScale or Style or LightType.
Now, for the real fun times disaster, EXUCreatureCarcass:
And finally, EXUCreatureChunks:
...and there's a lot more ugly horseballs code in there which controls the color of the blood spurts and decals.
The only real problem I'm having with this terrible system is the EXUCreatureChunks phase; Owner always returns none, and trying to change it to Instigator results in compile errors telling me that casting to Pawn will always fail or whatever, probably because the gib class is too far removed from the original pawn that generated the carcass which spawned the gib once destroyed, etc etc etc.
What I don't get is why I can't seem to send these enum values to another class. Being able to write something like Chunk.Hemospectrum = Hemospectrum would save me a lot of ugly lines of code and would be flexible enough to handle modifications to the list of choices in the enum list without requiring tons of code updates every time I add a new color. I guess there's something with enums that doesn't like this? But I also tried setting the enum to a byte value, using numbers in place of a BLOOD_<whatever> choice, and it STILL gave me type mismatch errors when I tried to compile it.
Basically I'm at a loss on where to go from here, and would appreciate any help on either getting this horrific system to work or rewriting it from the ground up so it isn't as ugly!
I also had the same problem with blood decals. Originally, I had all my different colored textures as arrays in a single decal class, set to choose one of the arrays in BeginPlay based on whichever enum choice was sent to the decal, but that never worked. I had to make a dedicated decal class for each blood color, which is just stupid as hell but it worked so whatever. Hopefully I can clean all this crap up because it's really pretty embarrassing.
![w00t! \o/ \o/](/styles/smilies/handsinair.gif)
[EDIT] System is now working fully, but needs optimization! See second post
Now with that out of the way, I'm working on making a system that allows me to specify custom blood colors for pawns. So far, I have an enum variable in my custom pawn superclass (EXUScriptedPawn) which works fine; decals and blood spurts are the proper colors.
I also have a new CreatureCarcass subclass (EXUCreatureCarcass) and a new CreatureChunks subclass (EXUCreatureChunks) in order to apply custom blood and decals so they match the originating pawn's blood color. So far, I have managed to get the carcass to inherit the originating pawn's (the instigator's) blood color, but I can't seem to pass this info on to the gib chunks when the carcass inevitably explodes into a shower of little pieces.
The whole system I've designed to handle all this is pretty damn gnarly, but when I started off, I used simpler measures that refused to compile, probably because I'm not fully understanding what I'm doing. For instance, BloodEXU used to have a Hemospectrum enum to match EXUScriptedPawn, but setting BloodEXU's hemospectrum value via EXUScriptedPawn never compiled, so I made a bunch of init functions for each blood type and set up the proper textures and stuff from those. Messy, but functional.
Anyway, here's actual code.
First, relevant chunks of EXUScriptedPawn (click for more readable Pastebin links), including the vars I've set up:
Code:
var(Combat) enum EXUBloodType // Not in the clinical sense!
{
BLOOD_Red,
BLOOD_Green,
BLOOD_Blue,
BLOOD_Brown, // **** blood? What the ****
BLOOD_White,
BLOOD_MYBLOODvvvISvvvvvvBLACK, // UT3 taunts = hilarious
BLOOD_None // For vehicles and **** if you don't want, say, an oily black discharge (that sounds really nasty)
}
Hemospectrum; // Couldn't resist the Homestuck reference because Homestuck ****ing kicks ass
And the functions which use them:
Code:
//======================================================================================================
// HEMOSPECTRUM CODE: Modified hit code to allow for different blood types
//======================================================================================================
function PlayHit(float Damage, vector HitLocation, name damageType, vector Momentum)
{
local float rnd;
local Bubble1 bub;
local bool bOptionalTakeHit;
local vector BloodOffset;
local BloodEXU b;
if (Damage > 1) //spawn some blood
{
if (damageType == 'Drowned')
{
bub = spawn(class 'Bubble1',,, Location
+ 0.7 * CollisionRadius * vector(ViewRotation) + 0.3 * EyeHeight * vect(0,0,1));
if (bub != None)
bub.DrawScale = FRand()*0.06+0.04;
}
else if ( damageType != 'Corroded' )
{
BloodOffset = 0.2 * CollisionRadius * Normal(HitLocation - Location);
BloodOffset.Z = BloodOffset.Z * 0.5;
if( EXUHitEffect!=none && EXUHitEffectScale>0 )
{
EHF = spawn(EXUHitEffect,self,'', hitLocation);
if(EHF!=none)
EHF.DrawScale = EHF.Default.DrawScale * EXUHitEffectScale;
}
// Guess what folks! We have to do this the ****ING STUPID way because UCC is a HUGE BITCH, BLUH BLUH
if(Hemospectrum!=BLOOD_None)
{
b = spawn(class'BloodBurstEXU',self,'', hitLocation);
if(b!=none)
{
if(Hemospectrum==BLOOD_Red)
b.InitRed();
if(Hemospectrum==BLOOD_Green)
b.InitGreen();
if(Hemospectrum==BLOOD_Blue)
b.InitBlue();
if(Hemospectrum==BLOOD_Brown)
b.InitBrown();
if(Hemospectrum==BLOOD_White)
b.InitWhite();
if(Hemospectrum==BLOOD_MYBLOODvvvISvvvvvvBLACK)
b.InitBlack();
}
if ( Level.bHighDetailMode )
{
spawn(class'BloodPuff',,, hitLocation + BloodOffset);
}
}
}
}
if ( (Weapon != None) && Weapon.bPointing && !bIsPlayer )
{
bFire = 0;
bAltFire = 0;
}
bOptionalTakeHit = bIsWuss || ( (Level.TimeSeconds - LastPainTime > 0.3 + 0.25 * skill)
&& (Damage * FRand() > 0.08 * Health) && (Skill < 3)
&& (GetAnimGroup(AnimSequence) != 'MovingAttack')
&& (GetAnimGroup(AnimSequence) != 'Attack') );
if ( (!bIsPlayer || (Weapon == None) || !Weapon.bPointing)
&& (bOptionalTakeHit || (Momentum.Z > 140) || (bFirstShot && (Damage > 0.015 * (skill + 6) * Health))
|| (Damage * FRand() > (0.17 + 0.04 * skill) * Health)) )
{
PlayTakeHitSound(Damage, damageType, 3);
PlayHitAnim(HitLocation, Damage);
}
else if (NextState == 'TakeHit')
{
PlayTakeHitSound(Damage, damageType, 2);
NextState = '';
}
}
function PlayDeathHit(float Damage, vector HitLocation, name damageType, vector Momentum)
{
local Bubble1 bub;
local BloodEXU b;
if ( Region.Zone.bDestructive && (Region.Zone.ExitActor != None) )
Spawn(Region.Zone.ExitActor);
if (HeadRegion.Zone.bWaterZone)
{
bub = spawn(class 'Bubble1',,, Location
+ 0.3 * CollisionRadius * vector(Rotation) + 0.8 * EyeHeight * vect(0,0,1));
if (bub != None)
bub.DrawScale = FRand()*0.08+0.03;
bub = spawn(class 'Bubble1',,, Location
+ 0.2 * CollisionRadius * VRand() + 0.7 * EyeHeight * vect(0,0,1));
if (bub != None)
bub.DrawScale = FRand()*0.08+0.03;
bub = spawn(class 'Bubble1',,, Location
+ 0.3 * CollisionRadius * VRand() + 0.6 * EyeHeight * vect(0,0,1));
if (bub != None)
bub.DrawScale = FRand()*0.08+0.03;
}
if( (damageType != 'Burned') && (damageType != 'Corroded') && (damageType != 'Drowned') && (damageType != 'Fell') )
{
if( EXUHitEffect!=none && EXUHitEffectScale>0 )
{
EHF = spawn(EXUHitEffect,self,'', hitLocation);
if(EHF!=none)
EHF.DrawScale = EHF.Default.DrawScale * EXUHitEffectScale;
}
if(Hemospectrum!=BLOOD_None)
{
b = spawn(class'BloodBurstEXU',self,'', hitLocation);
if(b!=none)
{
if(Hemospectrum==BLOOD_Red)
b.InitRed();
if(Hemospectrum==BLOOD_Green)
b.InitGreen();
if(Hemospectrum==BLOOD_Blue)
b.InitBlue();
if(Hemospectrum==BLOOD_Brown)
b.InitBrown();
if(Hemospectrum==BLOOD_White)
b.InitWhite();
if(Hemospectrum==BLOOD_MYBLOODvvvISvvvvvvBLACK)
b.InitBlack();
}
}
}
}
As you can see, this is all a hilarious mess. I have the exact same Hemospectrum enum in EXUCreatureCarcass and in EXUCreatureChunks, but if I simply put a b.Hemospectrum = Hemospectrum; line, UCC bitches at me with a "incorrect type in '=' " error message. I'm guessing this is because my enums don't exist across the board in Actor like, say, DrawScale or Style or LightType.
Now, for the real fun times disaster, EXUCreatureCarcass:
Code:
var(CreatureCarcass) enum EXUBloodType // Not in the clinical sense! copied from EXUScriptedPawn
{
BLOOD_Red,
BLOOD_Green,
BLOOD_Blue,
BLOOD_Brown, // **** blood? What the ****
BLOOD_White,
BLOOD_MYBLOODvvvISvvvvvvBLACK, // UT3 taunts = hilarious
BLOOD_None // For vehicles and **** if you don't want, say, an oily black discharge (that sounds really nasty)
}
Hemospectrum; // Couldn't resist the Homestuck reference because Homestuck ****ing kicks ass
simulated function PostBeginPlay()
{
Super.PostBeginPlay();
if(Instigator!=none && Instigator.IsA('EXUScriptedPawn'))
{
if(EXUScriptedPawn(Instigator).Hemospectrum==BLOOD_Red)
Hemospectrum=BLOOD_Red;
if(EXUScriptedPawn(Instigator).Hemospectrum==BLOOD_Green)
Hemospectrum=BLOOD_Green;
if(EXUScriptedPawn(Instigator).Hemospectrum==BLOOD_Blue)
Hemospectrum=BLOOD_Blue;
if(EXUScriptedPawn(Instigator).Hemospectrum==BLOOD_Brown)
Hemospectrum=BLOOD_Brown;
if(EXUScriptedPawn(Instigator).Hemospectrum==BLOOD_White)
Hemospectrum=BLOOD_White;
if(EXUScriptedPawn(Instigator).Hemospectrum==BLOOD_MYBLOODvvvISvvvvvvBLACK)
Hemospectrum=BLOOD_MYBLOODvvvISvvvvvvBLACK;
if(EXUScriptedPawn(Instigator).Hemospectrum==BLOOD_None)
Hemospectrum=BLOOD_None;
// broadcastmessage("Post-process: Instigator is: "$Instigator$" and its Hemospectrum is "$EXUScriptedPawn(Instigator).Hemospectrum$". Carcass Hemospectrum is: "$Hemospectrum);
// log("Post-process: Instigator is: "$Instigator$" and its Hemospectrum is "$EXUScriptedPawn(Instigator).Hemospectrum$". Carcass Hemospectrum is: "$Hemospectrum);
}
}
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation,
Vector Momentum, name DamageType)
{
local BloodSpurtEXU b;
if(Hemospectrum!=BLOOD_None)
{
b = Spawn(class'BloodSpurtEXU',,,HitLocation,rot(16384,0,0));
if(b!=none)
{
// log("Spawned a "$b);
// broadcastmessage("Spawned a "$b);
if(Hemospectrum==BLOOD_Red)
b.InitRed();
if(Hemospectrum==BLOOD_Green)
b.InitGreen();
if(Hemospectrum==BLOOD_Blue)
b.InitBlue();
if(Hemospectrum==BLOOD_Brown)
b.InitBrown();
if(Hemospectrum==BLOOD_White)
b.InitWhite();
if(Hemospectrum==BLOOD_MYBLOODvvvISvvvvvvBLACK)
b.InitBlack();
}
}
if ( !bPermanent )
{
if ( (DamageType == 'Corroded') && (Damage >= 100) )
{
bCorroding = true;
GotoState('Corroding');
}
else
Super.TakeDamage(Damage, instigatedBy, HitLocation, Momentum, DamageType);
}
}
function CreateReplacement()
{
local EXUCreatureChunks carc;
if (bHidden)
return;
if ( bodyparts[0] != None )
carc = Spawn(class'EXUCreatureChunks',self,, Location + ZOffset[0] * CollisionHeight * vect(0,0,1));
if (carc != None)
{
carc.TrailSize = Trails[0];
carc.Mesh = bodyparts[0];
carc.bMasterChunk = true;
carc.Initfor(self);
carc.Bugs = Bugs;
if ( Bugs != None )
Bugs.SetBase(carc);
Bugs = None;
if(Hemospectrum==BLOOD_Red)
carc.Hemospectrum=BLOOD_Red;
if(Hemospectrum==BLOOD_Green)
carc.Hemospectrum=BLOOD_Green;
if(Hemospectrum==BLOOD_Blue)
carc.Hemospectrum=BLOOD_Blue;
if(Hemospectrum==BLOOD_Brown)
carc.Hemospectrum=BLOOD_Brown;
if(Hemospectrum==BLOOD_White)
carc.Hemospectrum=BLOOD_White;
if(Hemospectrum==BLOOD_MYBLOODvvvISvvvvvvBLACK)
carc.Hemospectrum=BLOOD_MYBLOODvvvISvvvvvvBLACK;
if(Hemospectrum==BLOOD_None)
carc.Hemospectrum=BLOOD_None;
}
else if ( Bugs != None )
Bugs.Destroy();
}
simulated function HitWall(vector HitNormal, actor Wall)
{
local BloodSpurtEXU b;
if(Hemospectrum!=BLOOD_None)
{
b = Spawn(class'BloodspurtEXU',,,,Rotator(HitNormal));
if(b!=none)
{
// log("Spawned a "$b);
// broadcastmessage("Spawned a "$b);
if(Hemospectrum==BLOOD_Red)
b.InitRed();
if(Hemospectrum==BLOOD_Green)
b.InitGreen();
if(Hemospectrum==BLOOD_Blue)
b.InitBlue();
if(Hemospectrum==BLOOD_Brown)
b.InitBrown();
if(Hemospectrum==BLOOD_White)
b.InitWhite();
if(Hemospectrum==BLOOD_MYBLOODvvvISvvvvvvBLACK)
b.InitBlack();
b.RemoteRole = ROLE_None;
}
}
Velocity = 0.7 * (Velocity - 2 * HitNormal * (Velocity Dot HitNormal));
Velocity.Z *= 0.9;
if ( Abs(Velocity.Z) < 120 )
{
bBounce = false;
Disable('HitWall');
}
}
And finally, EXUCreatureChunks:
Code:
var(CreatureChunks) enum EXUBloodType // Not in the clinical sense! copied from EXUScriptedPawn
{
BLOOD_Red,
BLOOD_Green,
BLOOD_Blue,
BLOOD_Brown, // **** blood? What the ****
BLOOD_White,
BLOOD_MYBLOODvvvISvvvvvvBLACK, // UT3 taunts = hilarious
BLOOD_None // For vehicles and **** if you don't want, say, an oily black discharge (that sounds really nasty)
}
Hemospectrum; // Couldn't resist the Homestuck reference because Homestuck ****ing kicks ass
simulated function PostBeginPlay()
{
Super.PostBeginPlay();
broadcastmessage("Initializing: Owner is: "$Owner$" and its Hemospectrum is "$EXUCreatureCarcass(Owner).Hemospectrum$". Chunk Hemospectrum is: "$Hemospectrum);
log("Initializing: Owner is: "$Owner$" and its Hemospectrum is "$EXUCreatureCarcass(Owner).Hemospectrum$". Chunk Hemospectrum is: "$Hemospectrum);
if(Owner!=none && Owner.IsA('EXUCreatureCarcass'))
{
if(EXUCreatureCarcass(Owner).Hemospectrum==BLOOD_Red)
Hemospectrum=BLOOD_Red;
if(EXUCreatureCarcass(Owner).Hemospectrum==BLOOD_Green)
Hemospectrum=BLOOD_Green;
if(EXUCreatureCarcass(Owner).Hemospectrum==BLOOD_Blue)
Hemospectrum=BLOOD_Blue;
if(EXUCreatureCarcass(Owner).Hemospectrum==BLOOD_Brown)
Hemospectrum=BLOOD_Brown;
if(EXUCreatureCarcass(Owner).Hemospectrum==BLOOD_White)
Hemospectrum=BLOOD_White;
if(EXUCreatureCarcass(Owner).Hemospectrum==BLOOD_MYBLOODvvvISvvvvvvBLACK)
Hemospectrum=BLOOD_MYBLOODvvvISvvvvvvBLACK;
if(EXUCreatureCarcass(Owner).Hemospectrum==BLOOD_None)
Hemospectrum=BLOOD_None;
broadcastmessage("Post-process: Owner is: "$Owner$" and its Hemospectrum is "$EXUCreatureCarcass(Owner).Hemospectrum$". Chunk Hemospectrum is: "$Hemospectrum);
log("Post-process: Owner is: "$Owner$" and its Hemospectrum is "$EXUCreatureCarcass(Owner).Hemospectrum$". Chunk Hemospectrum is: "$Hemospectrum);
}
}
The only real problem I'm having with this terrible system is the EXUCreatureChunks phase; Owner always returns none, and trying to change it to Instigator results in compile errors telling me that casting to Pawn will always fail or whatever, probably because the gib class is too far removed from the original pawn that generated the carcass which spawned the gib once destroyed, etc etc etc.
What I don't get is why I can't seem to send these enum values to another class. Being able to write something like Chunk.Hemospectrum = Hemospectrum would save me a lot of ugly lines of code and would be flexible enough to handle modifications to the list of choices in the enum list without requiring tons of code updates every time I add a new color. I guess there's something with enums that doesn't like this? But I also tried setting the enum to a byte value, using numbers in place of a BLOOD_<whatever> choice, and it STILL gave me type mismatch errors when I tried to compile it.
Basically I'm at a loss on where to go from here, and would appreciate any help on either getting this horrific system to work or rewriting it from the ground up so it isn't as ugly!
I also had the same problem with blood decals. Originally, I had all my different colored textures as arrays in a single decal class, set to choose one of the arrays in BeginPlay based on whichever enum choice was sent to the decal, but that never worked. I had to make a dedicated decal class for each blood color, which is just stupid as hell but it worked so whatever. Hopefully I can clean all this crap up because it's really pretty embarrassing.
Last edited: