1 / 51

Sega 500

Sega 500. Making a Flamethrower. Jeff “Ezeikeil” Giles jgiles@artschool.com http://gamestudies.cdis.org/~jgiles. Last day. We laid out the basic template of a weapon and how to modify / create one. Today. I had a real hard time deciding what kind of weapon to make

amalie
Download Presentation

Sega 500

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Sega 500 Making a Flamethrower Jeff “Ezeikeil” Giles jgiles@artschool.com http://gamestudies.cdis.org/~jgiles

  2. Last day • We laid out the basic template of a weapon and how to modify / create one.

  3. Today • I had a real hard time deciding what kind of weapon to make • But being a *bit* of a pyromaniac, I HAD to go for the Flamethrower.

  4. Flamethrowers • So, building on from yesterdays weapon template, creating a flamethrower is relatively easy. • Surprinsingly, we need to modify only 1 file and create a 2nd. • Mod to the projectile • Definition for “napalm”

  5. Flamethrowers • After all that work into setting up our weapon yesterday, one would have expected to have to make modifications to several, if not all of them. • Actually, having to change only one or 2 files this is the bi-product of good ol’object oriented programming.

  6. Flamethrowers • So here’s the plan, We’ll keep using the linkgun mesh as the weapon and we’ll make all our modifications to the projectile. • If you recall, we swapped out the projectile fired by out BoomStick to fire our own version of biogoo. • Hence, we make all our changes there.

  7. Flamethrowers • I no longer wanted all the functionality of BioGel so I changed the parent class to Projectile. class BoomProj extends Projectile; • But most of our core functionality still comes from BioGel, So Cut & paste what you need.

  8. Flamethrowers • In this case most of the variable declarations & defaults with the following changes: DefaultProperties { MyDamageType=class'DamTypeBoomStick‘ BaseDamage=10.0//reduced -eze Damage=10.0 //reduced –eze Skins(0)=FinalBlend'XEffectMat.RedShell'//make the goop red –eze LightHue=4//82 –eze …

  9. Flamethrowers • And we required the PostBeginPlay function to set our initial velocity of the napalm. • So now we shoot red goo.

  10. Flamethrowers • But to this ain’t no flamethrower with out the flames…. • So we add a couple of lines to the function local HitFlameBig BFlame; … //Spawn the flames & bind them to the goop -eze BFlame=spawn(class'HitFlameBig',,,,); BFlame.Setbase(Self);

  11. Flamethrowers • HitFlameBig is an xEmitter (a.k.a. a particle emitter ) and we’ve already seen the spawn function. • But what’s Setbase? And why self?

  12. Flamethrowers • SetBaseintrinsic(298) final function SetBase( actor NewBase );Sets the actor’s Base. A base of None means that the actor moves alone; setting the base to another actor in the world causes this actor to move and rotate along with its base. An example of using a base is standing on a moving platform.

  13. Flamethrowers • Ah! So we bind it to ourselves…which in this case is the projectile. • In effect you’re gluing the particle emitter to the projectile.

  14. Flamethrowers • Hey cool! Flaming goo! • But at this point, it just works on impact damage.

  15. Flamethrowers • So we want to borrow 2 states form bioGel and make some modifications • Flying and on ground. • Most of both of these states I leave unchanged, we’re really interested in the process touch function.

  16. Flamethrowers • State Flying is for when the goo is airborn and has specific functionality for when it hits a wall. • Processtouch we changed to this: simulated function ProcessTouch(Actor Other, Vector HitLocation) { if (Other != Instigator && Other.IsA('Pawn')) { TorchPawn(Pawn(other),HitLocation); //light the contacting pawn on fire.-eze } }

  17. Flamethrowers • We’ll talk about TorchPawn in a sec… • In State onGround, we made a similar change to the process touch. • This state has all the functionality for when the goo is just sitting on a surface. • Notice that it will actually drip from the ceiling.

  18. Flamethrowers • Also notice that the goo takes on different shapes when it airborne or on a wall… • How does it do this?...it’s an animated mesh & we tell specific keyframes of that animation to be played.

  19. Flamethrowers • You can even open them up in the mesh browser. • Notice the ugly Styrofoam texture and the key frames…

  20. Flamethrowers • By changing the skin 0 in the defaults, we can change the look & colour of our goo Skins(0)=FinalBlend'XEffectMat.RedShell‘ • We can then play animations using various latent function calls.

  21. Flamethrowers • For example: PlayAnim('Drip', 0.66); • In short, as long as there is a matching name, an animation will play.

  22. Flamethrowers • The 3 main functions we need to know about for playing animations. All of which are defined in the actor class as: • PlayAnim • LoopAnim • FinishAnim

  23. Flamethrowers • PlayAnimintrinsic(259) final function PlayAnim( name Sequence, optional float Rate, optional float TweenTime );Plays a named animation sequence in the actor’s Mesh once. The optional Rate scales the animation’s default rate. If a nonzero TweenTime is specified, the animation is first tweened from whatever is currently displayed to the start of the named animation sequence, before the animation sequence plays. When the animation playing completes, it stops and calls your optional AnimEnd() event and causes any latent FinishAnim() calls to return.

  24. Flamethrowers • LoopAnimIntrinsic(260) final function LoopAnim( name Sequence, optional float Rate, optional float TweenTime, optional float MinRate );Loops the animation sequence forever. The AnimEnd() is called at the end of the sequence, and FinishAnim() calls return at the end of each iteration of the loop.

  25. Flamethrowers • FinishAnimintrinsic(261) final latent function FinishAnim();Waits for the currently playing or looping animation to reach the end of the sequence

  26. Flamethrowers • And finally, what fun is a flamethrower if you can’t set your friends on fire. • This is where our TorchPawn function comes in. • In essence, this function does just that…set pawns on fire.

  27. Flamethrowers function TorchPawn(Pawn other, vector hitloc) { local StickyFire SFire; SFire=spawn(class'StickyFire',owner,,hitloc,); SFire.ToTorch(other, Instigator, hitloc); SFire.default.lifespan=lifespan; } • StickyFire is a new class we created & we’ll talk about it in a moment. For now, think of it as our napalm.

  28. Flamethrowers • This TorchPawn function is not really that fancy. • In effect, it instantiates the napalm and sticks it to the pawn.

  29. Flamethrowers • Then we call a function in our sticky fire object to set up the pawn for the torching. ….I love mardi-gras…”bon homme carnival!”

  30. Flamethrowers • The Stickyfire class is in fact, our napalm. It’s the fire that we will stick to another pawn in the game. • It’s been placed in it’s own class for 2 reasons. • The first: is for good object orientation of the code…

  31. Flamethrowers • The second: it makes I real easy to have it do damage to the pawn as it now has it’s own “thread” of execution and specific functionality.

  32. Flamethrowers • Derived from pickup… • class StickyFire extends Pickup; • var pawn pother; //who we're stuck to • var HitFlameBig BFlame; // the fire animation • var int burnDamage; // damage per tick

  33. Flamethrowers • I chose to derive form pickup because it made the most sense. If you touch the flaming goo, you “pickup” the flames. • However, we don’t want to spawn anything into the players inventory, after all. It’s not an item per-say. • This is really easy, don’t set the InventoryType and it never adds to the pawns inventory.

  34. Flamethrowers • The first thing to consider is that ToTorch function which is how we light up the pawns: • function ToTorch(actor toTorch, optional vector hitloc) • { • pother=pawn(toTorch); • SetBase(pother); • if(hitloc != vect(0,0,0)) • SetLocation(hitloc); • gotostate('FlameOn'); • }

  35. Flamethrowers • This does nothing more than bind the fire to the pawn & changes states. • function ToTorch(actor toTorch, optional vector hitloc) • { • pother=pawn(toTorch); • SetBase(pother); • if(hitloc != vect(0,0,0)) • SetLocation(hitloc); • gotostate('FlameOn'); • } as in “Flame on Jonny”

  36. Flamethrowers • …sorry…had to make the comic book reference. • Anyway, this 'FlameOn’ state is made up of only 2 functions…Beginstate & Timer.

  37. Flamethrowers • BeginState simply creates the fire effect, binds it to the player, sets how long it burns and the timer resolution. • function Beginstate() • { • BFlame=spawn(class'HitFlameBig',,,,); • BFlame.setlocation(pother.Location); • BFlame.Setbase(pother); • Bflame.default.LifeSpan=lifespan+2; • SetTimer(1,True);//one sec intervals • }

  38. Flamethrowers • SetTimerintrinsic(280) final function SetTimer( float NewTimerRate, bool bLoop );Causes Timer() events every NewTimerRate seconds.

  39. Flamethrowers • And the timer, which gets called with every interval is defined like so: function Timer() { if( BFlame==none) { destroy();//flame has gone out... } //deal damage pother.TakeDamage(burnDamage, Instigator, pother.location, vect(0,0,0), class'DamTypeBoomStick'); }

  40. Flamethrowers • Now we can rain fire from the heavens…. WHEEE!!! I love the smell of naplam…smells like…victory.

  41. Flamethrowers • But we have a problem… Lots of accessed nones…

  42. Flamethrowers • Tracking this thing down takes us into the TorchPawn in our projectile SFire=spawn(class'StickyFire',owner,,hitloc,); SFire.ToTorch(other, hitloc); SFire.default.lifespan=lifespan; if(SFire==none) log("SFIRE");

  43. Flamethrowers • What the heck! • I just created the object & it’s accessing none??? WHAT?!?!

  44. Flamethrowers • I refer you to the spawn function…

  45. Flamethrowers • Spawnintrinsic(278) final function actor Spawn(class<actor> SpawnClass, optional actor SpawnOwner, optional name SpawnTag, optional vector SpawnLocation, optional rotator SpawnRotation);Spawn an actor. Returns an actor of the specified class, not of class Actor (this is hard coded in the compiler). Returns None if the actor could not be spawned (either the actor wouldn't fit in the specified location, or the actor list is full). Defaults to spawning at the spawner's location.

  46. Flamethrowers • So Spawn couldn’t create the object! • …Okay…why? • There’s only a limited number of pickup objects allowed…exactly how many I don’t know.

  47. Flamethrowers • The solution…Change the parent class to actor. • This also solves any inventory problems that could be incurred by defining it as a pickup.

  48. Flamethrowers • There’s only on issue left to solve… • At this point, you can keep piling up the fire on the pawn & this can be expensive on the CPU…So we only want there to be ONE flame attached at any point.

  49. Flamethrowers • In the projectile class, we look for all the other stickyfires in existence, if we find one, we don’t create a new one. • We just insert into the TorchPawn function • local StickyFire SFire,otherfire; • foreach allActors (class'StickyFire',otherfire) • if(otherfire.Base == other ) • { • return; //bail if already burning • }

  50. Flamethrowers • And voila! A pyromaniacs dream.

More Related