Jump to content

[WIP] Lua Weaponwerks (Now with video!)


TylerH
 Share

Recommended Posts

Key / Legend:

Accept.png - Completed Feature

Stop-silk.png - Feature is on hold / not started

Lightning-silk.png - Feature is in progress

Lightbulb.png - Feature is in concpet / requires feedback and suggestions

Bug-silk.png - Feature is suffering from one or more bugs

Palette.png - Feature is waiting on one or more art pieces

Plugin.png - Feature is implemented in a Lua Game Script, but needs to be moved over to the class script

Text_superscript.png - Feature depends on the WIP Mathwerks Lua Library

 

Feature Tree:

  • Weaponwerks - Lightning-silk.png
    • Bullet Class - Lightning-silk.png
      • Ray Cast via Line Pick - Lightning-silk.png
        • Hit Detection - Accept.png
        • Hit Filtering - Lightbulb.png

        [*]Physical Properties - Lightning-silk.png

        • Origin - Accept.png
        • Position - Accept.png
        • Distance - Accept.png
        • Maximum Distance - Accept.png
        • Velocity - Accept.png
        • Acceleration - Lightning-silk.png, Text_superscript.png
          • Gravity - Accept.png
          • Wind - Lightning-silk.png
          • User-Defined Impulses - Lightbulb.png

          [*]Mass - Accept.png[*]Falloff - Accept.png[*]Force - Accept.png[*]Inertia - Accept.png[*]Impulse - Lightning-silk.png, Text_superscript.png

        [*]Bullet Properties - Lightning-silk.png

        • Damage - Accept.png
        • Minimal Damage - Accept.png
        • Falloff Rate - Accept.png
        • Impact Force - Accept.png
        • Damage Type - Lightning-silk.png
        • Bullet Type - Lightning-silk.png
        • Bullet Add-Ons - Lightbulb.png
          • Armor Piercing - Lightbulb.png
          • Incendiary - Lightbulb.png
          • Generic Tracer - Accept.png
          • Colored Tracer - Lightning-silk.png
          • Glow Trail - Lightbulb.png

        [*]Dynamic Impact Decal System - Lightning-silk.png

        • Per-Entity Impact Type - Accept.png
        • Per-Surface/Per-Material Impact Type - Lightning-silk.png

        [*]Impact Emitter - Accept.png

      [*]Weapon Class - Lightning-silk.png, Plugin.png

      • Weapon Type - Lightning-silk.png
      • Fire Types - Lightning-silk.png
        • Single Shot - Accept.png
        • Shotgun - Lightbulb.png
        • Rapid Fire - Accept.png
        • Plasma - Lightbulb.png

        [*]Fire Modes - Lightning-silk.png

        • Primary - Accept.png
        • Secondary - Lightning-silk.png
        • Attachment - Lightbulb.png
        • Melee - Lightning-silk.png
        • Tactical - Lightbulb.png

        [*]Weapon Properties - Lightning-silk.png

        • Bullet Type - Lightning-silk.png
        • Recoil - Lightning-silk.png
        • Condition - Lightbulb.png

        [*]Weapon Attachments - Lightbulb.png

        • Laser Sight
        • Akimbo
        • Iron Sight
        • Scoped Sight
        • Thermal Scope
        • Night Scope
        • Holographic Sight
        • Flashlight
        • Grip
        • Extended Magazine
        • Bayonet / Tactical Knife
        • Silencer
        • Grenade Launcher
        • Rapid Fire Rate
        • Hair Trigger
        • Box Magazine

        [*]Dynamic Weapon Wearing System - Lightbulb.png

        • Wear and Tear over time (Non-Use)
        • Wear from incoming damage
        • Wear from use
        • Jamming
        • Slow Reload
        • Misfires

        [*]Finite State Machine Logic - Lightning-silk.png

        • States <-> Animation Links - Accept.png
        • States - Lightning-silk.png
          • Idle State - Accept.png
            • Fire State - Accept.png
            • Reload State - Accept.png
            • To Zoom Idle State - Accept.png
            • To Empty Idle State - Accept.png

            [*]Zoom Idle State - Accept.png

            • Zoom Fire State - Accept.png
            • Reload State - Accept.png
            • To Idle State - Accept.png
            • To Empty Idle State - Accept.png

            [*]Fire State - Accept.png

            • To Idle State - Accept.png
            • To Empty Idle State - Accept.png
            • Reload State - Accept.png

            [*]Zoom Fire State - Accept.png

            • To Zoom Idle - Accept.png
            • Reload State - Accept.png

            [*]Reload State - Accept.png

            • Tactical Reload State (Current Ammo >= 0.5*ClipSize) - Accept.png
              • Example: Clip out, Clip in

              [*]Slide Reload State (Current Ammo > 0, Current Ammo < 0.5*ClipSize) - Accept.png

              • Example: Clip out, Clip in, Slide Clicks Forward

              [*]Full Reload State (Current Ammo == 0) - Accept.png

              • Example: Clip out, Clip in, Manual Full Slide ****

              [*]To Idle State - Accept.png[*]To Zoom Idle State - Accept.png

            [*]Empty Idle State - Accept.png

            • Fire State (Dry) - Accept.png
            • Reload State - Accept.png

        [*]Animation Library - Accept.png

        • Table of possible animations - Accept.png
          • Names - Accept.png
          • Frame Range - Accept.png
          • Speed Modifier - Accept.png

        [*]Sound Library - Accept.png

        • Table of possible sounds - Accept.png
          • Animation links - Accept.png
          • Play at Frame 'X' - Accept.png

      [*]Ammo Class - Stop-silk.png[*]Hit Info Class - Stop-silk.png[*]Damage Info Class - Stop-silk.png[*]Unsorted / Feature Creep Ideas

      • Bullet Time - Accept.png
      • Primary Fire / Secondary Fire switches to melee if out of ammo
      • Clip System
        • Penalized for reloading non-empty clips (i.e. your bullet count is organized per clip. You have a clip with 5 and a full clip. You reload when you have half a clip left, and you now have the clip of 5. This is how it would work in real life...)

[TODO: Expanding this post over the lifespan of this library]

 

Videos:

 

Bugs:

  1. (SOLVED) Gun disappears when aligned along the X,Y,Z World Axes
    1. Cause: AABB is not aligned properly
    2. Fix: Set mesh.localaabb manually
    3. Will be Fixed: Next Leadwerks update (Josh is adding access to localaabb in Lua script)

  • Upvote 2

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

Right now I am using weapons done by Errant AI at the Game Creators.

 

He is the same guy who made the AK74 Josh uses and calls an "SMG". I like the way he sets up his models with a FIRESPOT bone, BULLET bone, MAGAZINE bone, SLIDE Bone, etc. making it easy to setup any of his guns for use.

 

The video was shot in FRAPs (2.16 GB AVI file), I converted it to 287 MB .mp4 with no loss of quality, stayed up for 2 hours to watch it upload on YouTube, then it failed because YouTube doesn't support the format. I will have to just compress the AVI itself and upload.

 

That also gives me time to port more of the functionality into its own classes instead of a bunch of if...then...elseif...elseif...else...end statements.

  • Upvote 1

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

Making this post probably alone was a lot of work already. If you get this to work, it would be outstanding! Do you need weapons of any kind? I would be happy to help you with that.

 

Sure, I can always use more weapons.

 

The only thing I would really ask is that you make a bone called "FIRESPOT" where the bullet should leave the muzzle. This library is oriented towards artists who want to get their weapons working quickly or anyone who just wants some fun guns working with lots of features.

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

The only thing I would really ask is that you make a bone called "FIRESPOT" where the bullet should leave the muzzle. This library is oriented towards artists who want to get their weapons working quickly or anyone who just wants some fun guns working with lots of features.

I'll be looking in to that then. It's isn't a problem to create a few bones btw. However if you have an example of how you prefer it, please send it to me. (an image with the bone placements and names would suffice. I work in 3ds Max) That way I can better understand how you want the weapons to be structured with bones.

Link to comment
Share on other sites

I will upload a screenshot from Model Viewer with the Gold XIX weapon I have been using. I will have bones and hierarchy visible, and Photoshop some labels to the "important" bones.

 

I am at school right now, it is 10 AM EST, I get home and can have the screenshot up around 4 - 4:30 PM EST.

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

I will upload a screenshot from Model Viewer with the Gold XIX weapon I have been using. I will have bones and hierarchy visible, and Photoshop some labels to the "important" bones.

 

I am at school right now, it is 10 AM EST, I get home and can have the screenshot up around 4 - 4:30 PM EST.

 

OK, I'll wait for that. for me it will be tomorrow because of the time difference.

Link to comment
Share on other sites

Thanks for the comments everyone. An AVI-raped video is now up.

 

 

OR

 

 

One of the bugs you will notice is that the gun disappears. In fact, it disappears when it is aligned to any world axis exactly (X,Y,or Z).

 

I am currently searching to see why this is.

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

Some nice improvements:

  • I switched from the velocity model I took from Josh's original implementation: nextpos = currentpos + velocity/60.0 to my own based on one-dimensional kinematics:

-- This code is in the bullet:Update() function called every frame (no FPS impact)
-- HOST_TIMESCALE is 1.0 for normal, 0.5 for half time bullettime, etc.
-- bullet.gravity.y = -9.81 (m/s)
-- bullet.mass = 0.0062 (9mm FMJ in KG) [Thanks to knowledgegranted]

local delta_time = (AppTime() - bullet.starttime)/1000.0 * HOST_TIMESCALE

nextpos.x = bullet.origin.x + (bullet.original_velocity.x * delta_time)
nextpos.y = bullet.origin.y + (bullet.original_velocity.y * delta_time) + (0.5*bullet.gravity.y*bullet.mass*delta_time*delta_time/60.0)
nextpos.z = bullet.origin.z + (bullet.original_velocity.z * delta_time)

  • Bullet time is now implemented via HOST_TIMESCALE. I basically multiply all of the following by it (or some function of it):
    1. Bullet Velocity
    2. Move/Strafe/Jump Velocity
    3. Sound Pitch
    4. Animation Speed

New video is up with a demo of bullet time (audio is stuff because my volume was too high :D)

Reminding everyone this is all debug, and I am aware of many of the things that need polished, like the empty chamber anim is off, muzzleflash comes too soon, locker door fail, etc.

 

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

Here is an image with some generalized "important" bone placement. Feel free to use as many of the bones in the limit as you want to get good animation or whatever. The bones should be named in all caps, just for ease of code.

 

boneplacementgun.png

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

Fascinating how good it looks. Maybe some muzzle flash would perfect it? I notice in STALKER the pistol has a faint heat haze effect, but I don't think that is too important.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Fascinating how good it looks. Maybe some muzzle flash would perfect it? I notice in STALKER the pistol has a faint heat haze effect, but I don't think that is too important.

 

Is there still a way to do sprites in Leadwerks? Or maybe a simple one-shot emitter could do the trick

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

This hard coded state based logic and animation is starting to seem like the wrong idea.

 

How exactly should you handle the logic of weapons?

 

For example, going from Idle to Moving, Firing, Reloading, Zooming (iron sights), etc.

 

Right now I use a large combination of weapon:SetState, weapon:SetAnimation, Get forms of those, etc. Then the weapon's update loop just plays the current animation (which defaults to Idle if nothing is set).

 

This is the DRAFT DRAFT! pre-pre-pre-alpha version of wepaon.lua and the first weapon inheriting it gold_xix. Just note that the functionality you see in the videos and such was implemented using if statements and hackish stuff in the render loop of the fps script. I am porting over to the actual class-based weapon setup, and so far only have states and animation working, with the functionality already more powerful, as you can see from the code:

 

weapon.lua

dofile("scripts/utilities.lua")

-- Defaults

-- States
WEAPON_IDLE = 0
WEAPON_TAKE_OUT = 1
WEAPON_PUT_AWAY = 2
WEAPON_FIRE = 3
WEAPON_RELOAD = 4
WEAPON_ZOOM_IDLE = 5
WEAPON_ZOOM_FIRE = 6
WEAPON_TO_ZOOM = 7
WEAPON_TO_NORMAL = 8
WEAPON_MOVING = 9
WEAPON_ZOOM_MOVING = 10

-- Globals
WEAPON_SCALE = 0.6 -- Global scale shared by all weapons. Gun specific scaling is multiplied by this factor. It allows guns of different scales to appear similarly sized.

-- Variables
firstweapon=nil
lastweapon=nil

-- Weapons Table
weapons={}

function CreateWeapon( weapon_table )
local weapon = {}

-- Sub Tables
weapon.Animations = { } -- Table containing all animations
weapon.Sounds = { } -- Table containing all sounds
weapon.Effects = { } -- Table containing all effects (emitter, muzzle flash, brass, etc.)
weapon.Attachments = { } -- Table containing attachments (ironsights, scopes, etc.)

-- Properties
weapon.AnimationBlending = 0.5
weapon.SwayScale = 0 -- X Axis Movement
weapon.BobScale = 0 -- Y Axis Movement
weapon.Zoomed = false
weapon.Moving = false
weapon.AutoReload = false -- Gun will automatically go to reload state if you try to fire with an empty clip

-- Sound
weapon.Volume = 1.0
weapon.Pitch = 1.0

-- Animation
weapon.AnimationStartTime = AppTime()
weapon.CurrentAnimation = ""
weapon.CurrentAnimationFrame = 0
weapon.Animating = false

-- Primary
weapon.Primary = { }
weapon.Primary.ClipSize = 1 -- Number of rounds in the clip
weapon.Primary.Clip = 1 -- Current number of rounds in the clip
weapon.Primary.Ammo = 1 -- Current total ammo (not including current clip)
weapon.Primary.Damage = 0 -- Damage done per round
weapon.Primary.ShotCount = 0 -- Bullets ejected per round
weapon.Primary.Cone = 0 -- Spread cone (X,Y)
weapon.Primary.Delay = 0 -- Time between current shot and next shot
weapon.Primary.NextFire = AppTime() -- Time next shot can be fired

-- Secondary
weapon.Secondary = { }
weapon.Secondary.ClipSize = 0
weapon.Secondary.Clip = 0
weapon.Secondary.Ammo = 0
weapon.Secondary.Damage = 0
weapon.Secondary.ShotCount = 0
weapon.Secondary.Cone = 0
weapon.Secondary.Delay = 0
weapon.Secondary.NextFire = AppTime()

-- Finite State Logic
weapon.State = 0 -- Weapons's current logic state

-- World/View Models
weapon.WorldModel = nil -- World View Model

weapon.ViewModel = LoadMesh(weapon_table.ViewModel) -- First Person View Model
weapon.ViewModel:SetParent(fw.main.camera,0)

local vwep_offset, vwep_scale = weapon_table.Offset, weapon_table.Scale

weapon.ViewModel:SetPosition(Vec3(-0.01*WEAPON_SCALE,-0.005*WEAPON_SCALE,0.05*WEAPON_SCALE),0)
weapon.ViewModel:SetScale(Vec3(0.04*WEAPON_SCALE,0.04*WEAPON_SCALE,0.04*WEAPON_SCALE))
weapon.ViewModel:SetShadowMode(0,1)

AppLog("We loaded and positioned the view model...")

-- Future AABB Random Culling Fix...
--vwep.localaabb.x0=-3
--vwep.localaabb.x1=3
--vwep.localaabb.y0=-3
--vwep.localaabb.y1=3
--vwep.localaabb.z0=-3
--vwep.localaabb.z1=3
--vwep:UpdateAABB()

-- Positioning / Offsets
weapon.Offset = weapon.ViewModel.position:Copy()
local gundisplayposition = weapon.ViewModel:GetPosition()

local positionentity = FindChild(weapon.ViewModel,"FIRESPOT") or weapon.ViewModel -- Entity used for firespot location
local displayposition = EntityPosition(positionentity)

-- Muzzleflash
weapon.Effects.MuzzleFlash = CreatePointLight(3)
weapon.Effects.MuzzleFlash:SetParent( weapon.ViewModel )

local muzzleflash_color = weapon_table.muzzleflash_color or Vec4(1,0.6,0.0,1.0)
weapon.Effects.MuzzleFlash:SetColor(muzzleflash_color)
weapon.Effects.MuzzleFlash:SetPosition( displayposition )
weapon.Effects.MuzzleFlash:SetShadowMode(0)
weapon.Effects.MuzzleFlash:Hide()

function weapon:Update()
	--[[-- Idle State
	if (self:IsIdle()) then
		if (self:IsZoomed()) then				
			self:LoopAnimation("WEAPON_ZOOM_IDLE")
		else
			if (self.IsMoving()) then
				self:LoopAnimation("WEAPON_MOVE")
			else
				self:LoopAnimation("WEAPON_IDLE")
			end
		end			
	-- Fire State
	elseif (self:IsFiring()) then
		-- Zoom Fire State
		if (self:IsZoomed()) then
			self:SetAnimating(true)
			self:PlayAnimation("WEAPON_ZOOM_FIRE")
		-- Normal Fire State
		else
			self:SetAnimating(true)
			self:PlayAnimation("WEAPON_FIRE")
		end
		if (not self:IsAnimating()) then 
			self:SetState(WEAPON_IDLE)				
		end
	-- No State? (Idle)
	else
		self:LoopAnimation("WEAPON_IDLE")
	end]]--

	-- State Correction
	if (self:IsFiring() and not self.Animating) then
		self:SetState(WEAPON_IDLE)
		self:SetAnimation("WEAPON_IDLE")
	end

	self:PlayAnimation(self.CurrentAnimation)
	self.ViewModel:SetPosition(self.Offset:Copy())
	self:UpdateSounds()
end

function weapon:Think()
	-- This can be used for AI, etc. Implement it if you want
end

-- Animation
function weapon:AddAnimation(name,startframe,endframe,speedmodifier,oneshot)
	self.Animations[name] =	{Name = name,
		StartFrame = startframe,
		EndFrame = endframe,
		Length = (endframe-startframe),
		Modifier = speedmodifier,
		OneShot = oneshot or false,
		Running = false}		
end

--[[function weapon:LoopAnimation(animation)
	local time = ((AppTime() - self.AnimationStartTime) / 100.0)

	local currentanim = self.Animations[animation]

	self.CurrentAnimationFrame = ((time * currentanim.Modifier * HOST_TIMESCALE) % currentanim.Length) + currentanim.StartFrame

	if (self.CurrentAnimationFrame < currentanim.StartFrame) then self.CurrentAnimationFrame = currentanim.StartFrame end
	if (self.CurrentAnimationFrame > currentanim.EndFrame) then self.CurrentAnimationFrame = currentanim.EndFrame end

	self.ViewModel:Animate(self.CurrentAnimationFrame, self.AnimationBlending, 0, 1)
end]]

function weapon:SetAnimation(animation)
	self.AnimationStartTime = AppTime()
	self.CurrentAnimation = animation
	self.Animating = true
end

function weapon:PlayAnimation(animation)
	if (not self.Animating) then return end
	if (animation == nil or animation == "") then return end

	local time = (AppTime() - self.AnimationStartTime) / 100.0

	local currentanim = self.Animations[animation]
	currentanim.Running = true
	if (not self.Animating) then
		currentanim.Running = false			
	end

	self.CurrentAnimationFrame = (time * currentanim.Modifier * HOST_TIMESCALE) % currentanim.Length + currentanim.StartFrame

	if (self.CurrentAnimationFrame < currentanim.StartFrame) then self.CurrentAnimationFrame = currentanim.StartFrame end
	if (self.CurrentAnimationFrame > currentanim.EndFrame) then self.CurrentAnimationFrame = currentanim.EndFrame end

	self.ViewModel:Animate(self.CurrentAnimationFrame, self.AnimationBlending, 0, 1)

	if ((self.CurrentAnimationFrame > currentanim.EndFrame-0.5 and currentanim.OneShot) or currentanim.Running == false) then
		self.Animating = false	
		currentanim.Running = false
	end
end

-- Sound
function weapon:AddSound(name,soundfile,frame)
	local sound = LoadSound(soundfile)

	local sound_table = {Name = name,
		Frame = frame,
		Sound = sound,
		Source = CreateSource(sound)}

	local Weapon = self
	function sound_table:Update()
		self.Source:SetVolume(Weapon.Volume)
		self.Source:SetPitch(Weapon.Pitch)
	end

	table.insert(self.Sounds,sound_table)
end

function weapon:UpdateSounds()
	for k,v in pairs(self.Sounds) do
		if (v.Frame == self.CurrentFrame) then
			v.Source:Play()
			v:Update()
		end
	end
end

-- States
function weapon:GetState()
	return self.State
end

function weapon:SetState(state)
	self.State = state
end

function weapon:IsIdle()
	return self.State == WEAPON_IDLE or self.State == WEAPON_ZOOM_IDLE
end

function weapon:IsFiring()
	return self.State == WEAPON_FIRE
end

function weapon:IsReloading()
	return self.State == WEAPON_RELOAD
end

function weapon:IsZoomed()
	return self.State == WEAPON_ZOOM_IDLE or self.State == WEAPON_ZOOM_FIRE or self.Zoomed
end

function weapon:IsEmpty()
	return self:IsPrimaryClipEmpty()
end

function weapon:IsAnimating()
	return self.Animating
end

function weapon:IsMoving()
	return ((KeyDown(KEY_W) - KeyDown(KEY_S)) ~= 0) or ((KeyDown(KEY_A) - KeyDown(KEY_D)) ~= 0)
end

function weapon:SetAnimating(anim)
	self.Animating = anim
end

-- Weapon Functionality

-- Reload
function weapon:Reload()
	if (not self:IsIdle()) then return end

	self:SetState(WEAPON_RELOAD)
end

-- Primary Fire Mode
function weapon:GetPrimaryClip()
	return self.Primary.Clip
end

function weapon:GetPrimaryClipSize()
	return self.Primary.ClipSize
end

function weapon:GetPrimaryAmmo()
	return self.Primary.Ammo
end

function weapon:IsPrimaryClipEmpty()
	return self.Primary.Clip <= 0
end

function weapon:CanPrimaryFire()
	return (AppTime() >= self:GetNextPrimaryFire()) and (self:IsIdle() or self.IsMoving()) and (not self:IsPrimaryClipEmpty())
end

function weapon:SetNextPrimaryFire(time)
	self.Primary.NextFire = time
end

function weapon:GetNextPrimaryFire()
	return self.Primary.NextFire
end

function weapon:TakePrimaryAmmo(num)
	self.Primary.Clip = self.Primary.Clip - num
end

function weapon:PrimaryFire()
	if (not self:CanPrimaryFire()) then return end -- We can not perform a primary fire

	self:SetNextPrimaryFire(AppTime() + self.Primary.Delay)
	self:SetNextSecondaryFire(AppTime() + self.Secondary.Delay)

	self:SetState(WEAPON_FIRE)
	self:SetAnimation("WEAPON_FIRE")
end

-- Secondary Fire Mode
function weapon:GetSecondaryClip()
	return self.Secondary.Clip
end

function weapon:GetSecondaryClipSize()
	return self.Secondary.ClipSize
end

function weapon:GetSecondaryAmmo()
	return self.Secondary.Ammo
end

function weapon:IsSecondaryClipEmpty()
	return self.Secondary.Clip <= 0
end

function weapon:CanSecondaryFire()
	return (AppTime() >= self:GetNextSecondaryFire()) and (self:IsIdle()) and (not self:IsSecondaryClipEmpty())
end

function weapon:SetNextSecondaryFire(time)
	self.Secondary.NextFire = time
end

function weapon:GetNextSecondaryFire()
	return self.Secondary.NextFire
end

function weapon:TakeSecondaryAmmo(num)
	self.Secondary.Clip = self.Secondary.Clip - num
end

function weapon:SecondaryFire()
	if (not self:CanSecondaryFire()) then return end -- We can not perform a secondary fire

	self:SetNextPrimaryFire(AppTime() + self.Primary.Delay)
	self:SetNextSecondaryFire(AppTime() + self.Secondary.Delay)
end

-- Weapons Table Hierarchy		
if lastweapon==nil then
	firstweapon=weapon
	lastweapon=weapon
else
	lastweapon.next=weapon
	weapon.prev=lastweapon
end

weapons[weapon]=weapon

function weapon:Free()
	weapons[self]=nil	
end

-- All weapons created from CreateWeapon inherit the base functionality implemented in this file
weapon.Base = weapon

return weapon
end

 

gold xix:

dofile("scripts/classes/weapon.lua")

GoldXIX = { }


GoldXIX_WeaponTable = {
ViewModel = "abstract::HUD.gmf",
Offset = Vec3(-0.01,-0.005,0.05),
Scale = Vec3(0.04,0.04,0.04)
}

GoldXIX = CreateWeapon(GoldXIX_WeaponTable)

-- Animations
GoldXIX:AddAnimation("WEAPON_IDLE", 277.0, 302.0, 1.0)
GoldXIX:AddAnimation("WEAPON_ZOOM_IDLE", 212.0, 238.0, 1.0)
GoldXIX:AddAnimation("WEAPON_MOVE", 304.0, 326.0, 2.0)
GoldXIX:AddAnimation("WEAPON_FIRE", 62.0, 74.0, 3.0, true)
GoldXIX:AddAnimation("WEAPON_ZOOM_FIRE", 262.0, 274.0, 3.0, true)

GoldXIX:SetAnimation("WEAPON_IDLE")
GoldXIX:SetState(WEAPON_IDLE)

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

There are obvious sacrifices between the approaches. The state based approach makes it piss easy to do things like align sound frames exactly with animation frames, fire bullets at exact frames, etc.

 

Not having states wouldn't make hardly any difference, and are kind of redundant since the weapon only really reacts based on the animation being set.

 

How else would you handle it?

52t__nvidia.png nVidia 530M cpu.gif Intel Core i7 - 2.3Ghz 114229_30245_16_hardware_memory_ram_icon.png 8GB DDR3 RAM Windows7_Start.gif Windows 7 Ultimate (64x)

-----

IconVisualStudio16.png Visual Studio 2010 Ultimate google-Chrome.png Google Chrome PhotoshopLinkIndicator.png Creative Suite 5 icon28.gif FL Studio 10 MicrosoftOfficeLive.png Office 15

-----

csharp.png Expert cpp.png Professional lua_icon.png Expert BMX Programmer

-----

i-windows-live-messenger-2009.pngskype-icon16.pngaim_online.pnggmail.pngicon_48x48_prism-facebook.pngtunein-web.pngyahoo.giftwitter16.png

Link to comment
Share on other sites

The approach you've taken in the code you've posted is pretty much how I've done it in my player/weapon class, it works well enough for me!

Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...