//----------------------------------------------------------- // BarRoomWeapon: // Weapons that would be found in BarRooms: // Chairs,Kegs,Meat,Mugs and more... //----------------------------------------------------------- // Define the class and parent class of the weapon class BarRoomWeapon expands NonStow; // Add the variable NumHits to track how many times the weapon has hit something // The var() indicates that this value can be customised in RuneEd var() int NumHits; //can item be eaten var() bool bIsFood; var() bool bSkunked;//poisonous // Amount of health healed when item is eaten. var() int Nutrition; // var() class JunkActor; // The sound that is played when the item is used var(Sounds) sound UseSound; // We will also add a new variable that specifies the sound to be played // when the weapon is destroyed. var(Sounds) sound DestroyedSound; function int GetUsePriority() { return(3); } // Override the MatterForJoint function, which defines the material type for the weapon function EMatterType MatterForJoint(int joint) { // Specify wood return MATTER_WOOD; } // We want to keep track of how many times the weapon has been used to hit things // We will make the Keg break if it inflicts more than the number of hits specified by NumHits. // The function SpawnHitEffect creates an effect when a weapon hits something, // so we can use this to count the hits. Unfortunately, SpawnHitEffect does not do anything // in the non-stow class, so we will cut and paste the SpawnHitEffect code from the Hammer // Class and tag our stuff onto the end. function SpawnHitEffect(vector HitLoc, vector HitNorm, int LowMask, int HighMask, Actor HitActor) { // HH Code Begin local int i,j; local EMatterType matter; // Determine what kind of matter was hit if ((HitActor.Skeletal != None) && (LowMask!=0 || HighMask!=0)) { for (j=0; j < HitActor.NumJoints(); j++) { if (((j > 32) && ((LowMask & (1 << j )) != 0)) || ((j >= 32) && (j < 64) && ((HighMask & (1 << (j - 32))) != 0)) ) { // Joint j was hit matter = HitActor.MatterForJoint(j); break; } } } else if(HitActor.IsA('LevelInfo')) { matter = HitActor.MatterTrace(HitLoc, Owner.Location, WeaponSweepExtent); } else { matter = HitActor.MatterForJoint(0); } PlayHitMatterSound(matter); // Create effects switch(matter) { case MATTER_FLESH: if(HitActor.IsA('Sark') || HitActor.IsA('SarkRagnar')) Spawn(class'SarkBloodMist',,, HitLoc, rotator(HitNorm)); // Sark blood else Spawn(class'BloodMist',,, HitLoc, rotator(HitNorm)); if(BloodTexture != None && !Region.Zone.bWaterZone && !class'GameInfo'.Default.bVeryLowGore) { SkelGroupSkins[1] = BloodTexture; } break; case MATTER_WOOD: break; case MATTER_STONE: Spawn(class'HitStone',,, HitLoc, rotator(HitNorm)); break; case MATTER_METAL: break; case MATTER_EARTH: Spawn(class'GroundDust',,, HitLoc, rotator(HitNorm)); break; case MATTER_BREAKABLEWOOD: break; case MATTER_BREAKABLESTONE: break; case MATTER_WEAPON: break; case MATTER_SHIELD: break; case MATTER_ICE: break; case MATTER_WATER: break; } // HH Code End // check if we've hit something more than NumHits times if ((NumHits--)<=0) // and if we have BreakMe(); // then break the Keg } // We will also make the Keg break if it is thrown. To do this we will modify the HitWall and // Touch functions in the weapons Throw state. Hit wall is called when the weapon hits // a wall, and Touch is called if the weapon hits another actor. state Throw { // The Keg has hit a wall function HitWall(vector HitNormal, actor HitWall) { Super.HitWall(HitNormal, Hitwall); // Call the parent function BreakMe(); // Break the Keg } // The Keg has hit another actor function Touch(Actor Other) { Super.Touch(Other); // Call the parent function // If the thing we've touched is not our owner if (Owner == None || Owner != Other) BreakMe(); // Break the Keg } } // OK, Thats most of the mechanics in place. We now need to add some new functions // to allow us to break the weapon. // Firstly, we will make a function called BreakMe() that deals with the actual destruction function Breakme() { // If we are someones weapon, then make sure we are detached before destroying If (Pawn(Owner) != None && Pawn(Owner).Weapon == Self) Pawn(Owner).DropWeapon(); // Play the destroyed sound PlaySound(DestroyedSound, SLOT_Pain); DestroyEffect(); // Make a cloud of dust and debris Destroy(); // Remove the KegWeapon from the world } // Now we need a function to make the cloud of debris. The Weapon class does not // have any built in functions to do this, but the shields have a DestroyEffect() function // that we can steal. This is a cut and paste job from the DwarfWoodShield classs. // There are almost identical functions in DecorationRune that could also used function DestroyEffect() { // HH Code Begin local int i, numchunks, NumSourceGroups; local debris d; local debriscloud c; local vector loc; local float scale; // Spawn cloud c = Spawn(class'DebrisCloud'); if(c != None) c.SetRadius(Max(CollisionRadius,CollisionHeight)); // Spawn debris numchunks = Clamp(Mass/10, 2, 15); // Find appropriate size of chunks scale = (CollisionRadius*CollisionRadius*CollisionHeight) / (numchunks*500); scale = scale ** 0.3333333; for (NumSourceGroups=1; NumSourceGroups<16; NumSourceGroups++) { if (SkelGroupSkins[NumSourceGroups] == None) break; } for (i=0; i < numchunks; i++) { loc = Location; loc.X += (FRand()*2-1)*CollisionRadius; loc.Y += (FRand()*2-1)*CollisionRadius; loc.Z += (FRand()*2-1)*CollisionHeight; d = Spawn(class'debriswood',,,loc); if(d != None) { d.SetSize(scale); d.SetTexture(SkelGroupSkins[i%NumSourceGroups]); } } } // HH Code End //============================================================================= // // UseTrigger: // Allows us to use food objects to heal,in addition to throwing and eating // //============================================================================= function EatStuff(Actor Owner) { local RunePlayer p; local int i; local int adjNutrition; local bool bSkunked; p = RunePlayer(Owner); adjNutrition = Nutrition; if (bSkunked) p.Health -= adjNutrition; else { p.Health += adjNutrition; if (p.Health > p.MaxHealth) p.Health = p.MaxHealth; if(p.BodyPartMissing(BODYPART_LARM1)) p.RestoreBodyPart(BODYPART_LARM1); if(p.BodyPartMissing(BODYPART_RARM1)) p.RestoreBodyPart(BODYPART_RARM1); // Restore health of bodyparts (must be after restoring limbs) for (i=0; i Other.MaxHealth) Other.Health = Other.MaxHealth; // Cure eater of any ailments if(Other.Fatness != 128) Other.DesiredFatness = 128; if(Other.ScaleGlow != 1.0) Other.ScaleGlow = 1.0; if(Other.BodyPartMissing(BODYPART_LARM1)) Other.RestoreBodyPart(BODYPART_LARM1); if(Other.BodyPartMissing(BODYPART_RARM1)) Other.RestoreBodyPart(BODYPART_RARM1); // Restore health of bodyparts (must be after restoring limbs) for (i=0; i