Jump to content

[WIP] Lua Weaponwerks (Now with video!)


TylerH
 Share

Recommended Posts

This is all looking very good indeed TylerH.

AMD Bulldozer FX-4 Quad Core 4100 Black Edition

2 x 4GB DDR3 1333Mhz Memory

Gigabyte GeForce GTX 550 Ti OC 1024MB GDDR5

Windows 7 Home 64 bit

 

BlitzMax 1.50 • Lua 5.1 MaxGUI 1.41 • UU3D Pro • MessiahStudio Pro • Silo Pro

3D Coat • ShaderMap Pro • Hexagon 2 • Photoshop, Gimp & Paint.NET

 

LE 2.5/3.4 • Skyline UE4 • CE3 SDK • Unity 5 • Esenthel Engine 2.0

 

Marleys Ghost's YouTube Channel Marleys Ghost's Blog

 

"I used to be alive like you .... then I took an arrow to the head"

Link to comment
Share on other sites

I have a nice update for everyone.

 

I was able to convert everything over to the class-based system nicely. Here is a newer draft-draft pre-alpha weapon.lua script with all the functionality I want currently except Secondary Fire mode, Melee attack, and the handling of automatic fire:

 

Here is the gold_xix.lua first, so you can see how relatively easy it is (this is all you have to do for your gun setup-wise):

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

GoldXIX = { }


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

GoldXIX = CreateWeapon(GoldXIX_WeaponTable)

-- Properties
GoldXIX.Primary.Delay = 400

-- 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_EMPTY_IDLE", 779.0, 804.0, 1.0)

GoldXIX:AddAnimation("WEAPON_MOVE", 304.0, 326.0, 2.0)
GoldXIX:AddAnimation("WEAPON_ZOOM_MOVE", 239.0, 261.0, 2.0)
GoldXIX:AddAnimation("WEAPON_EMPTY_MOVE", 805.0, 829.0, 2.0)

GoldXIX:AddAnimation("WEAPON_TO_ZOOM", 180.0, 187.0, 2.0, true)
GoldXIX:AddAnimation("WEAPON_FROM_ZOOM", 188.0, 194.0, 2.0, true)

GoldXIX:AddAnimation("WEAPON_FIRE", 62.0, 74.0, 3.0, true)
GoldXIX:AddAnimation("WEAPON_ZOOM_FIRE", 262.0, 274.0, 3.0, true)

GoldXIX:AddAnimation("WEAPON_FULL_RELOAD", 82.0, 150.0, 3.0, true)
GoldXIX:AddAnimation("WEAPON_TACTICAL_RELOAD", 640.0, 690.0, 3.0, true)
GoldXIX:AddAnimation("WEAPON_MINIMAL_RELOAD", 581.0, 639.0, 3.0, true)

GoldXIX:AddAnimation("WEAPON_TAKE_OUT", 50.0, 58.0, 1.0, true)
GoldXIX:AddAnimation("WEAPON_PUT_AWAY", 152.0, 159.0, 1.0, true)

-- Initial Animation
GoldXIX:SetState(WEAPON_IDLE)

-- Sounds
GoldXIX:AddSound("Fire", "abstract::fire.ogg", 65)
GoldXIX:AddSound("ZoomFire", "abstract::fire.ogg", 265)
GoldXIX:AddSound("EmptyFire", "abstract::fire.ogg", 697)
GoldXIX:AddSound("WEAPON_DRYFIRE", "abstract::dryfire.ogg", 0)
GoldXIX:AddSound("FullReload", "abstract::reload.ogg", 85)
GoldXIX:AddSound("TacticalReload", "abstract::reload.ogg", 644)
GoldXIX:AddSound("MinimalReload", "abstract::reload.ogg", 585)
GoldXIX:AddSound("FullCock1", "abstract::cock2.ogg", 135)
GoldXIX:AddSound("FullCock2", "abstract::cock2.ogg", 143)
GoldXIX:AddSound("MinimalCock", "abstract::cock2.ogg", 629)

 

And here are the snippets for all that you have to call in your render loop (this will be abstracted into its own little thing and use a simple WeaponSystem:Update() or something to check all weapons in the table):

GoldXIX:Update()

if (KeyHit(KEY_W)-KeyHit(KEY_S) ~= 0 or KeyHit(KEY_A)-KeyHit(KEY_D) ~= 0 and GoldXIX:GetState() == WEAPON_IDLE) then
	GoldXIX.Moving = true
end
if (KeyDown(KEY_W)-KeyDown(KEY_S) == 0 and KeyDown(KEY_A)-KeyDown(KEY_D) == 0 and GoldXIX:GetState() == WEAPON_MOVE) then
	GoldXIX.Moving = false
end
if (MouseHit(2) == 1) then
	GoldXIX:ToggleIronsights()
end
if (KeyHit(KEY_1) == 1) then
	GoldXIX:Toggle()
end
if KeyHit(KEY_R)==1 then
	GoldXIX:Reload() 
end
if MouseHit(1)==1 then
	GoldXIX:PrimaryFire()
end

 

The library is pretty robust for the 546 lines that comprise the weapon.lua, and 231 lines in bullet.lua. They will both receive their upgrades as I start working my way through the rest of the feature tree, starting with the core stuff, and working towards eye candy and fun stuff (like akimbo and laz0rs :)).

 

Note that the commandset called in the game-loop is really that easy. The weapon's finite state logic and update loops will handle itself efficiently and properly, and has built in checks for commonly missed things like firing while reloading, etc. though bugs may exist and it will be improved. With permission I will either put a section with an API for this on the Wiki, or in its own thread.

 

weapon.lua:

dofile("scripts/utilities.lua")

-- Defaults

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

-- 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
weapon.Visible = true -- Start with the gun visible
weapon.Selected = true -- Start with the gun selected

-- 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 = 12 -- Number of rounds in the clip
weapon.Primary.Clip = 12 -- Current number of rounds in the clip
weapon.Primary.Ammo = 240 -- 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)

weapon.GunOffset = weapon_table.Offset
weapon.GunScale = weapon_table.Scale

weapon.ViewModel:SetPosition(Vec3(weapon.GunOffset.x*WEAPON_SCALE,weapon.GunOffset.y*WEAPON_SCALE,weapon.GunOffset.z*WEAPON_SCALE),0)
weapon.ViewModel:SetScale(Vec3(weapon.GunScale.x*WEAPON_SCALE,weapon.GunScale.y*WEAPON_SCALE,weapon.GunScale.z*WEAPON_SCALE))
weapon.ViewModel:SetShadowMode(0,1)

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

-- AABB Culling Fix...
weapon.ViewModel.localAABB.x0=-3
weapon.ViewModel.localAABB.x1=3
weapon.ViewModel.localAABB.y0=-3
weapon.ViewModel.localAABB.y1=3
weapon.ViewModel.localAABB.z0=-3
weapon.ViewModel.localAABB.z1=3
weapon.ViewModel: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)

weapon.FireSpot = 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()
	if (not self.Selected and not self.Visible) then return end
	-- Idle State
	if (self:IsIdle()) then
		if (self:IsZoomed() and not self:IsPrimaryClipEmpty()) then				
			if (self:IsMoving()) then
				self:PlayAnimation("WEAPON_ZOOM_MOVE")
			else
				self:PlayAnimation("WEAPON_ZOOM_IDLE")
			end
		else
			if (self:IsMoving()) then
				if (self:IsPrimaryClipEmpty()) then
					self:PlayAnimation("WEAPON_EMPTY_MOVE")
				else
					self:PlayAnimation("WEAPON_MOVE")
				end
			else
				if (self:IsPrimaryClipEmpty()) then
					self:PlayAnimation("WEAPON_EMPTY_IDLE")
				else
					self:PlayAnimation("WEAPON_IDLE")
				end
			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
	-- Reloading State
	elseif (self:IsReloading()) then
		if (self:GetPrimaryClip() == 0) then
			self:PlayAnimation("WEAPON_FULL_RELOAD")
		else
			if (self:GetPrimaryClip() >= self:GetPrimaryClipSize()/2) then
				self:PlayAnimation("WEAPON_TACTICAL_RELOAD")
			else
				self:PlayAnimation("WEAPON_MINIMAL_RELOAD")
			end
		end	
		if (not self:IsAnimating()) then 
			self:SetState(WEAPON_IDLE)

			self:DoReload()
		end
	-- Taking Out State
	elseif (self:IsTakingOut()) then
		self:PlayAnimation("WEAPON_TAKE_OUT")
		if (not self:IsAnimating()) then 
			self:SetState(WEAPON_IDLE)									
		end
	-- Putting Away State
	elseif (self:IsPuttingAway()) then
		self:PlayAnimation("WEAPON_PUT_AWAY")
		if (not self:IsAnimating()) then 
			self:SetState(WEAPON_AWAY)
			self.Selected = false
			self.Visible = false
			self.ViewModel:Hide()				
		end		
	-- No State? (Idle)
	else
		self:PlayAnimation("WEAPON_IDLE")
	end

	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)
	if (self.CurrentAnimation ~= "") then
		self.Animations[self.CurrentAnimation].Running = false
	end
	self.CurrentAnimation = animation
	self.Animations[animation].Running = true
	self.Animating = true
	self.AnimationStartTime = AppTime()
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 ((currentanim.OneShot and self.CurrentAnimationFrame >= currentanim.EndFrame-1.0) 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*HOST_TIMESCALE)
	end

	function sound_table:Play()
		self:Update() -- Update volume and pitch
		self.Source:Play() -- Play source
	end

	self.Sounds[name] = sound_table
end

function weapon:UpdateSounds()
	for k,v in pairs(self.Sounds) do
		if (v.Frame == math.floor(self.CurrentAnimationFrame)) then
			v:Play()				
		end
	end
end

function weapon:PlaySound(name)
	if (self.Sounds[name] ~= nil) then
		self.Sounds[name]:Play()
	end
end

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

function weapon:SetState(state)
	self.State = state
	self.AnimationStartTime = AppTime()
	self.Animating = true
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:IsTakingOut()
	return self.State == WEAPON_TAKE_OUT
end

function weapon:IsPuttingAway()
	return self.State == WEAPON_PUT_AWAY
end

function weapon:IsAway()
	return self.State == WEAPON_AWAY
end

function weapon:IsSelected()
	return self.Selected
end

function weapon:IsVisible()
	return self.Visible
end

function weapon:Toggle()
	if (self:GetState() == WEAPON_IDLE) then
		self:SetState(WEAPON_PUT_AWAY)			
	else
		self.Selected = true
		self.Visible = true	
		self.ViewModel:Show()		
		self:SetState(WEAPON_TAKE_OUT)			
	end
end

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

-- Weapon Functionality

-- Reload
function weapon:CanDoReload()
	return (weapon:IsIdle() and weapon:GetPrimaryClip()<weapon:GetPrimaryClipSize())
end

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

	self:SetState(WEAPON_RELOAD)		
end

-- Performs actual clip reloading math
function weapon:DoReload()
	if (self:GetPrimaryAmmo() >= self:GetPrimaryClipSize()) then
		if (self.Zoomed) then self:ToggleIronsights() end
		self.Primary.Clip = self:GetPrimaryClipSize()
		self.Primary.Ammo = self.Primary.Ammo - self:GetPrimaryClipSize()
	elseif (self:GetPrimaryAmmo() > 0) then
		if (self.Zoomed) then self:ToggleIronsights() end
		self.Primary.Clip = self:GetPrimaryAmmo()
		self.Primary.Ammo = 0
	end
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 (not self:IsReloading()) 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
		if (self:IsEmpty() and not self:IsReloading()) then self:PlaySound("WEAPON_DRYFIRE") end
		if (self.AutoReload and self:GetPrimaryAmmo() > 0) then
			self:Reload()
		else
			return -- We can not perform a primary fire
		end
	end

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

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

	self:TakePrimaryAmmo(1)

	if (HOST_TIMESCALE == 1.0) then
		CreateBullet(self.FireSpot:GetPosition(1), fw.main.camera.mat:K():Scale(100))
	else
		CreateBullet(self.FireSpot:GetPosition(1), fw.main.camera.mat:K():Scale(50*HOST_TIMESCALE))
	end
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

-- Melee Fire Mode
function weapon:PrimaryMeleeAttack()
	-- TODO: Implement melee state, animation, sounds, and functionality
end

function weapon:SecondaryMeleeAttack()
	-- TODO: Implement melee state, animation, sounds, and functionality
end

-- Ironsights / Zoom
function weapon:ToggleIronsights()
	if (self:IsPrimaryClipEmpty()) then
		self.Zoomed = false
	else
		if (self.Zoomed) then
			self.Zoomed = false
			self:SetAnimation("WEAPON_FROM_ZOOM")
		else
			self.Zoomed = true
			self:SetAnimation("WEAPON_TO_ZOOM")
		end
	end
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

 

Questions? Comments? Concerns? etc.?

 

A demo will be out soon, think within the week-ish. Another video will precede the demo.

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

For anyone curious about the current setup:

CreateWeapon takes a table that needs to have a .ViewModel string, .Offset vec3, and .Scale vec3.

 

AddAnimation takes a unique name (the ones you see there are what the internal system will be looking for, though I may add the ability to set them custom soon). The second and third parameters are start and end frames. The 4th is a speed modifier, and the last is an optional "one shot" boolean. Things like idle and move are looped, so it defaults to false, but things like reload and fire are done once per state before the state changes.

 

AddSound takes a unique name (the system is designed to play them by frame, but I added WEAPON_DRYFIRE in at the last second along with a weapon:PlaySound(name) command for custom effects not linked to animation), the sound file string location (it handles creating the sound and source), and the frame of animation it should be played at.

 

I basically tried to take the FPS Creator form of setting up guns via their gunspec.txt files, and implement it in a Lua fashion, though my system offers more customization and can be expanded by the user.

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

No, I hadn't. I will work that into the condition system.

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 have successfully implemented hierarchical bullet ricochet, skimming, and skewing.

 

Right now, the system will use this little bit of code:

-- Process ricochets if they should still occur
			if (bullet.ricochetcount < 3) then

				local I = bullet.velocity--Subtract3(pick.position,bullet.origin)
				local N = pick.normal--:Normalize()

				local angle = 180 - math.deg(math.acos(Dot3(I,N)/(I:Length()*N:Length())))

				if (angle < (60)) then return end

				local R = Subtract3(I,N:Scale(2 * Dot3(I,N)))--:Scale(bullet.velocity:Length()*HOST_TIMESCALE)

				local ricochet = CreateBullet(pick.position, R, Vec3(0.0,0.0,0.0), ricochets)
				ricochet.ricochetcount = bullet.ricochetcount + 1
			end

 

Which grabs the bullet velocity (our incident vector), the normal of the surface we hit (the normal), calculates the angle between these two (which will be obtuse, so we subtract from 180 to get an acute angle that is easier to run comparisons on relative the bullet and player).

 

Presently it is hardcoded to ignore impacts for ricochet if the incident angle is less than 60 degrees. To explain, when you think of a protractor, where the far right flat line is 0, as you move up towards the top is goes from 0 to 90 , this is backwards of how the system works. The Normal is 0 degrees, and as the bullet angle towards the impact point gets close to parallel with the surface that the normal is from, it gets closer to 90. It is checking to see the angle between the normal plane of the object you hit, and the bullet velocity.

 

This has worked and given realistic results (minus that I didn't add friction, velocity fall off, etc. physical effects), and appears to be how this would work in real life.

 

The next thing I want to work on is bullet penetration through surfaces, but I am not entirely sure how this is done, and wouldn't mind some suggestions or ideas on how to do this.

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

It was fun to remove the ricochet count and angle checks, and just have 12 bullets flying around making ricochets forever. With 12 on screen, I got about 30 FPS, down from 60 FPS, which is believable, for the amount of math I am doing per bullet.

 

Needless to say, I already know about 5 ways to optimize what I have currently, I already made a few changes and gained loads of frames I didn't know had ever been lost ;)

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

Yep, I was able to push that up to 120 bullets on screen, running bullet logic, keeping 60 FPS.

 

I also made the gun shoot a non-tracer bullet by default, and will be implementing some logic for either every nth bullet being a tracer, or a tracer is fired to let you know you have n bullets remaining (i.e. either every 4 rounds, or say when you have 5 rounds left in the current clip).

 

I also implemented colored tracers, so if you want crazy looking tracers, they will be as easy as setting weapon.TracerColor ;)

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

  • 2 weeks later...

This is on hold for a number of bugs in 2.3 single state:

1) Half of the sounds no longer play at the proper frame / at all

2) Animations are running as if the FPS is 5, when the FPS is 60 to 80.

 

Not sure what is causing this.

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

  • 3 weeks later...

Possibly, I assume I have you on Windows Messenger already?

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

  • 2 weeks later...

Just to let everyone know I am BACK to working on this wonderful little project.

 

I found that the bugs were infact that issue with the editor and AppSpeed starting to become a little messed up after a while (seems like after opening and closing Leadwerks Editor or Leadwerks-based app 25 or so times it occurs), but a simple restart or even log off and re-logon fixes it, so I can continue bug free where I left off: Bullet Penetration.

 

I had also kind of been tied up experimenting and porting some stuff to UDK for a new project experiment, and it was taking up a bit of time.

 

Cheers,

Tyler

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

  • 3 months later...

For real back on working on this. No joke this time.

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

  • 4 months later...
  • 1 year later...

Maybe once my summer break in college hits I'll be back on my programming grind.

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

  • 2 weeks later...
  • 3 weeks later...

Well I'll have spring break here starting March 19th, gives me 2 weeks to get my antiquated code and apps installed on the new computer. Summer break is the end of May.

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

  • 2 weeks later...

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...