Attempting to create a new Weapon.
Hello guys,
I've started learning lua so i can start modding natural selection 2. Now that learning lua is done, I've setup my modding environment and made some really (really) minor modification to the code (such as print something in the console when you shoot with a certain weapon, and stuff like that).
So, yesterday I decided it was time to make something a bit more difficult : I've decided to add a new weapon to the game (modify an existing weapon : i kept the shotgun model and sounds, but tried to modify its properties).
Here is what i've done yet :
--> I've created a new lua file call : WeirdShotgun.lua
--> I added Script.Load("lua/WeirdShotgun.lua") in ModShared.lua
--> In WeirdShotgun.lua, i created a WeirdShotgun class :
Here is the error message i've got when i try to me a weirdshotgun (using the command give weirdshotgun after the commands cheats 1) :
I don't really know where is the mistake (since there are lot of code and i've only been making small mods for approximately 1 week). I hope you guys will help me.
Thankfully Devnunux.
P.S.: Sorry for my English but i'm French and i'm trying to do my best to write correct sentences. I you don't understand something fell free to ask me.
I've started learning lua so i can start modding natural selection 2. Now that learning lua is done, I've setup my modding environment and made some really (really) minor modification to the code (such as print something in the console when you shoot with a certain weapon, and stuff like that).
So, yesterday I decided it was time to make something a bit more difficult : I've decided to add a new weapon to the game (modify an existing weapon : i kept the shotgun model and sounds, but tried to modify its properties).
Here is what i've done yet :
--> I've created a new lua file call : WeirdShotgun.lua
--> I added Script.Load("lua/WeirdShotgun.lua") in ModShared.lua
--> In WeirdShotgun.lua, i created a WeirdShotgun class :
Script.Load("lua/Balance.lua")
Script.Load("lua/LiveMixin.lua")
Script.Load("lua/Weapons/Marine/ClipWeapon.lua")
Script.Load("lua/PickupableWeaponMixin.lua")
Script.Load("lua/PointGiverMixin.lua")
class 'WeirdShotgun' (ClipWeapon)
WeirdShotgun.kMapName = "weirdshotgun"
local kBulletSize = 0.016
local networkVars =
{
emptyPoseParam = "private float (0 to 1 by 0.01)"
}
AddMixinNetworkVars(LiveMixin, networkVars)
// higher numbers reduces the spread
local kSpreadDistance = 10
local kStartOffset = 0
local kSpreadVectors =
{
GetNormalizedVector(Vector(-0.01, 0.01, kSpreadDistance)),
GetNormalizedVector(Vector(-0.45, 0.45, kSpreadDistance)),
GetNormalizedVector(Vector(0.45, 0.45, kSpreadDistance)),
GetNormalizedVector(Vector(0.45, -0.45, kSpreadDistance)),
GetNormalizedVector(Vector(-0.45, -0.45, kSpreadDistance)),
GetNormalizedVector(Vector(-1, 0, kSpreadDistance)),
GetNormalizedVector(Vector(1, 0, kSpreadDistance)),
GetNormalizedVector(Vector(0, -1, kSpreadDistance)),
GetNormalizedVector(Vector(0, 1, kSpreadDistance)),
GetNormalizedVector(Vector(-0.35, 0, kSpreadDistance)),
GetNormalizedVector(Vector(0.35, 0, kSpreadDistance)),
GetNormalizedVector(Vector(0, -0.35, kSpreadDistance)),
GetNormalizedVector(Vector(0, 0.35, kSpreadDistance)),
GetNormalizedVector(Vector(-0.8, -0.8, kSpreadDistance)),
GetNormalizedVector(Vector(-0.8, 0.8, kSpreadDistance)),
GetNormalizedVector(Vector(0.8, 0.8, kSpreadDistance)),
GetNormalizedVector(Vector(0.8, -0.8, kSpreadDistance)),
}
WeirdShotgun.kModelName = PrecacheAsset("models/marine/shotgun/shotgun.model")
local kViewModels = GenerateMarineViewModelPaths("shotgun")
local kAnimationGraph = PrecacheAsset("models/marine/shotgun/shotgun_view.animation_graph")
local kMuzzleEffect = PrecacheAsset("cinematics/marine/shotgun/muzzle_flash.cinematic")
local kMuzzleAttachPoint = "fxnode_shotgunmuzzle"
function WeirdShotgun:OnCreate()
ClipWeapon.OnCreate(self)
InitMixin(self, PickupableWeaponMixin)
InitMixin(self, LiveMixin)
InitMixin(self, PointGiverMixin)
self.emptyPoseParam = 0
end
if Client then
function WeirdShotgun:OnInitialized()
ClipWeapon.OnInitialized(self)
end
end
function WeirdShotgun:GetAnimationGraphName()
return kAnimationGraph
end
function WeirdShotgun:GetViewModelName(sex, variant)
return kViewModels[sex][variant]
end
function WeirdShotgun:GetDeathIconIndex()
return kDeathMessageIcon.Shotgun
end
function WeirdShotgun:GetHUDSlot()
return kPrimaryWeaponSlot
end
function WeirdShotgun:GetClipSize()
return kShotgunClipSize
end
function WeirdShotgun:GetBulletsPerShot()
return kShotgunBulletsPerShot
end
function WeirdShotgun:GetRange()
return 100
end
// Only play weapon effects every other bullet to avoid sonic overload
function WeirdShotgun:GetTracerEffectFrequency()
return 0.5
end
function WeirdShotgun:GetBulletDamage()
return kShotgunDamage
end
function WeirdShotgun:GetHasSecondary(player)
return false
end
function WeirdShotgun:GetPrimaryCanInterruptReload()
return true
end
function WeirdShotgun:GetWeight()
return kShotgunWeight
end
function WeirdShotgun:UpdateViewModelPoseParameters(viewModel)
viewModel:SetPoseParam("empty", self.emptyPoseParam)
end
local function LoadBullet(self)
if self.ammo > 0 and self.clip < self:GetClipSize() then
self.clip = self.clip + 1
self.ammo = self.ammo - 1
end
end
function WeirdShotgun:OnTag(tagName)
PROFILE("Shotgun:OnTag")
local continueReloading = false
if self:GetIsReloading() and tagName == "reload_end" then
continueReloading = true
self.reloading = false
end
if tagName == "end" then
self.primaryAttacking = false
end
ClipWeapon.OnTag(self, tagName)
if tagName == "load_shell" then
LoadBullet(self)
elseif tagName == "reload_shotgun_start" then
self:TriggerEffects("shotgun_reload_start")
elseif tagName == "reload_shotgun_shell" then
self:TriggerEffects("shotgun_reload_shell")
elseif tagName == "reload_shotgun_end" then
self:TriggerEffects("shotgun_reload_end")
end
if continueReloading then
local player = self:GetParent()
if player then
player:Reload()
end
end
end
// used for last effect
function WeirdShotgun:GetEffectParams(tableParams)
tableParams[kEffectFilterEmpty] = self.clip == 1
end
function WeirdShotgun:FirePrimary(player)
local viewAngles = player:GetViewAngles()
viewAngles.roll = NetworkRandom() * math.pi * 2
local shootCoords = viewAngles:GetCoords()
// Filter ourself out of the trace so that we don't hit ourselves.
local filter = EntityFilterTwo(player, self)
local range = self:GetRange()
if GetIsVortexed(player) then
range = 5
end
local numberBullets = self:GetBulletsPerShot()
local startPoint = player:GetEyePos()
/*
local weaponUpgradeLevel = player.GetWeaponUpgradeLevel and player:GetWeaponUpgradeLevel() or 0
local soundEffectName = "shotgun_attack_sound"
if self.clip == 1 then
soundEffectName = "shotgun_attack_sound_last"
elseif weaponUpgradeLevel == 3 then
soundEffectName = "shotgun_attack_sound_max"
elseif weaponUpgradeLevel == 2 then
soundEffectName = "shotgun_attack_sound_medium"
end
DebugPrint("shotgun soundEffectName %s", soundEffectName)
*/
self:TriggerEffects("shotgun_attack_sound")
self:TriggerEffects("shotgun_attack")
for bullet = 1, math.min(numberBullets, #kSpreadVectors) do
if not kSpreadVectors[bullet] then
break
end
local spreadDirection = shootCoords:TransformVector(kSpreadVectors[bullet])
local endPoint = startPoint + spreadDirection * range
startPoint = player:GetEyePos() + shootCoords.xAxis * kSpreadVectors[bullet].x * kStartOffset + shootCoords.yAxis * kSpreadVectors[bullet].y * kStartOffset
local trace = Shared.TraceRay(startPoint, endPoint, CollisionRep.Damage, PhysicsMask.Bullets, filter)
if not trace.entity then
-- Limit the box trace to the point where the ray hit as an optimization.
local boxTraceEndPoint = trace.fraction ~= 1 and trace.endPoint or endPoint
local extents = GetDirectedExtentsForDiameter(spreadDirection, kBulletSize)
trace = Shared.TraceBox(extents, startPoint, boxTraceEndPoint, CollisionRep.Damage, PhysicsMask.Bullets, filter)
end
local damage = 0
/*
// Check prediction
local values = GetPredictionValues(startPoint, endPoint, trace)
if not CheckPredictionData( string.format("attack%d", bullet), true, values ) then
Server.PlayPrivateSound(player, "sound/NS2.fev/marine/voiceovers/game_start", player, 1.0, Vector(0, 0, 0))
end
*/
// don't damage 'air'..
if trace.fraction < 1 or GetIsVortexed(player) then
local direction = (trace.endPoint - startPoint):GetUnit()
local impactPoint = trace.endPoint - direction * kHitEffectOffset
local surfaceName = trace.surface
local effectFrequency = self:GetTracerEffectFrequency()
local showTracer = bullet % effectFrequency == 0
self:ApplyBulletGameplayEffects(player, trace.entity, impactPoint, direction, kShotgunDamage, trace.surface, showTracer)
if Client and showTracer then
TriggerFirstPersonTracer(self, trace.endPoint)
end
end
local client = Server and player:GetClient() or Client
if not Shared.GetIsRunningPrediction() and client.hitRegEnabled then
RegisterHitEvent(player, bullet, startPoint, trace, damage)
end
end
TEST_EVENT("Shotgun primary attack")
end
function WeirdShotgun:OnProcessMove(input)
ClipWeapon.OnProcessMove(self, input)
self.emptyPoseParam = Clamp(Slerp(self.emptyPoseParam, ConditionalValue(self.clip == 0, 1, 0), input.time * 1), 0, 1)
end
function WeirdShotgun:GetAmmoPackMapName()
return ShotgunAmmo.kMapName
end
if Client then
function WeirdShotgun:GetBarrelPoint()
local player = self:GetParent()
if player then
local origin = player:GetEyePos()
local viewCoords= player:GetViewCoords()
return origin + viewCoords.zAxis * 0.4 + viewCoords.xAxis * -0.18 + viewCoords.yAxis * -0.2
end
return self:GetOrigin()
end
function WeirdShotgun:GetUIDisplaySettings()
return { xSize = 256, ySize = 128, script = "lua/GUIShotgunDisplay.lua" }
end
end
function WeirdShotgun:ModifyDamageTaken(damageTable, attacker, doer, damageType)
if damageType ~= kDamageType.Corrode then
damageTable.damage = 0
end
end
function WeirdShotgun:GetCanTakeDamageOverride()
return self:GetParent() == nil
end
if Server then
function WeirdShotgun:OnKill()
DestroyEntity(self)
end
function WeirdShotgun:GetSendDeathMessageOverride()
return false
end
end
Shared.LinkClassToMap("WeirdShotgun", WeirdShotgun.kMapName, networkVars)
Here is the error message i've got when i try to me a weirdshotgun (using the command give weirdshotgun after the commands cheats 1) :
Error: lua/Utility.lua:1719: CreateEntity(weirdshotgun, 27.208578 4.344036 -20.600378, 1) returned nil.
[Server] Script Error #1: lua/Utility.lua:1719: CreateEntity(weirdshotgun, 27.208578 4.344036 -20.600378, 1) returned nil.
Call stack:
#1: error [C]:-1
#2: CreateEntity lua/Utility.lua:1719
mapName = "weirdshotgun"
origin = cdata
teamNumber = 1
extraValues = nil
values = {origin=cdata, teamNumber=1 }
entity = nil
#3: GiveItem lua/Player_Server.lua:629
self = Marine-3811 {activeWeaponId=746, alive=true, animateAngles=false, animateDistance=false, animatePosition=false, animateYOffset=false, animationBlend=0.20000000298023, animationGraphIndex=41, animationGraphNode=20, animationSequence2=28, animationSequence=27, animationSpeed2=1, animationSpeed=1, animationStart2=16.818370819092, animationStart=18.461738586426, armor=30, baseYaw=0, blockPersonalResources=false, bodyYaw=0, bodyYawRun=0, cameraDistance=0, canUseTunnel=true, catpackboost=false, clientIndex=1, collisionRep=0, communicationStatus=1, countingDown=false, crouching=false, currentOrderId=-1, darwinMode=false, desiredCameraAngles=cdata, desiredCameraDistance=0, desiredCameraPosition=cdata, desiredCameraYOffset=0, desiredSprinting=false, enableTunnelEntranceCheck=false, flashlightLastFrame=false, flashlightOn=false, flinchIntensity=0, followingTransition=false, fov=90, frozen=false, fullPrecisionOrigin=cdata, gameEffectsFlags=0, gameStarted=true, giveDamageTime=0, health=100, healthIgnored=false, hotGroupNumber=0, inCombat=false, interruptAim=false, isCorroded=false, isMale=true, isMoveBlocked=false, isOnEntity=false, isUsing=false, jumpHandled=false, jumping=false, lastOrderType=1, lastSpitDirection=cdata, lastTakenDamageAmount=0, lastTakenDamageOrigin=cdata, lastTakenDamageTime=0, lastTargetId=-1, layer1AnimationBlend=0, layer1AnimationGraphNode=163, layer1AnimationSequence2=-1, layer1AnimationSequence=-1, layer1AnimationSpeed2=1, layer1AnimationSpeed=1, layer1AnimationStart2=0, layer1AnimationStart=0, locationId=2, maxArmor=30, maxHealth=100, mode=1, modeTime=-1, modelIndex=59, moveButtonPressed=false, moveTransition=false, nanoShielded=false, onGround=true, onLadder=false, parasited=false, physicsGroup=8, physicsGroupFilterMask=0, physicsType=1, playerLevel=0, playerSkill=0, poisoned=false, primaryAttackLastFrame=false, processMove=true, pushImpulse=cdata, pushTime=0, quickSwitchSlot=2, reinforcedTierNum=0, requireNewSprintPress=false, resetMouse=0, resources=20.10000038147, runningBodyYaw=2.9903495311737, ruptured=false, secondaryAttackLastFrame=false, selectionMask=0, shoulderPadIndex=0, sighted=false, slowAmount=0, sprintButtonDownTime=0, sprintButtonUpTime=0, sprintDownLastFrame=false, sprintMode=false, sprintTimeOnChange=12, sprinting=false, sprintingScalar=0, standingBodyYaw=2.9903495311737, startCameraAngles=cdata, startCameraDistance=0, startCameraPosition=cdata, startCameraYOffset=0, stepAmount=-0.0075645446777344, stepStartTime=18.408294677734, strafeJumped=false, stunTime=0, syncHealth=false, teamNumber=1, teamResources=61, techId=53, timeCatpackboost=0, timeGroundAllowed=0, timeGroundTouched=16.818370819092, timeLastBeacon=0, timeLastHealed=0, timeLastMenu=0, timeLastSpitHit=0, timeOfCrouchChange=0, timeOfLastDrop=0, timeOfLastJump=0, timeOfLastOrderComplete=0, timeOfLastPhase=0, timeOfLastPickUpWeapon=0, timeOfLastUse=0, timeOfLastWeaponSwitch=16.890413284302, timeSprintChange=16.890413284302, timeUntilResourceBlock=0, timeWebEnds=0, transitionDuration=0, transitionStart=0, tunnelNearby=false, tweeningFunction=1, unitStatusPercentage=0, upgrade1=1, upgrade2=1, upgrade3=1, upgrade4=1, upgrade5=1, upgrade6=1, variant=3, velocity=cdata, velocityLength=0, velocityPitch=0, velocityYaw=0, viewModelId=3256, viewPitch=0.160878688097, viewRoll=0, viewYaw=2.9903495311737, visibleClient=false, vortexed=false, weaponUpgradeLevel=0, weaponsWeight=0.12999999523163, webbed=false }
itemMapName = "weirdshotgun"
setActive = true
newItem = nil
#4: lua/NS2ConsoleCommands_Server.lua:424
client = ServerClient { }
itemName = "weirdshotgun"
player = Marine-3811 {activeWeaponId=746, alive=true, animateAngles=false, animateDistance=false, animatePosition=false, animateYOffset=false, animationBlend=0.20000000298023, animationGraphIndex=41, animationGraphNode=20, animationSequence2=28, animationSequence=27, animationSpeed2=1, animationSpeed=1, animationStart2=16.818370819092, animationStart=18.461738586426, armor=30, baseYaw=0, blockPersonalResources=false, bodyYaw=0, bodyYawRun=0, cameraDistance=0, canUseTunnel=true, catpackboost=false, clientIndex=1, collisionRep=0, communicationStatus=1, countingDown=false, crouching=false, currentOrderId=-1, darwinMode=false, desiredCameraAngles=cdata, desiredCameraDistance=0, desiredCameraPosition=cdata, desiredCameraYOffset=0, desiredSprinting=false, enableTunnelEntranceCheck=false, flashlightLastFrame=false, flashlightOn=false, flinchIntensity=0, followingTransition=false, fov=90, frozen=false, fullPrecisionOrigin=cdata, gameEffectsFlags=0, gameStarted=true, giveDamageTime=0, health=100, healthIgnored=false, hotGroupNumber=0, inCombat=false, interruptAim=false, isCorroded=false, isMale=true, isMoveBlocked=false, isOnEntity=false, isUsing=false, jumpHandled=false, jumping=false, lastOrderType=1, lastSpitDirection=cdata, lastTakenDamageAmount=0, lastTakenDamageOrigin=cdata, lastTakenDamageTime=0, lastTargetId=-1, layer1AnimationBlend=0, layer1AnimationGraphNode=163, layer1AnimationSequence2=-1, layer1AnimationSequence=-1, layer1AnimationSpeed2=1, layer1AnimationSpeed=1, layer1AnimationStart2=0, layer1AnimationStart=0, locationId=2, maxArmor=30, maxHealth=100, mode=1, modeTime=-1, modelIndex=59, moveButtonPressed=false, moveTransition=false, nanoShielded=false, onGround=true, onLadder=false, parasited=false, physicsGroup=8, physicsGroupFilterMask=0, physicsType=1, playerLevel=0, playerSkill=0, poisoned=false, primaryAttackLastFrame=false, processMove=true, pushImpulse=cdata, pushTime=0, quickSwitchSlot=2, reinforcedTierNum=0, requireNewSprintPress=false, resetMouse=0, resources=20.10000038147, runningBodyYaw=2.9903495311737, ruptured=false, secondaryAttackLastFrame=false, selectionMask=0, shoulderPadIndex=0, sighted=false, slowAmount=0, sprintButtonDownTime=0, sprintButtonUpTime=0, sprintDownLastFrame=false, sprintMode=false, sprintTimeOnChange=12, sprinting=false, sprintingScalar=0, standingBodyYaw=2.9903495311737, startCameraAngles=cdata, startCameraDistance=0, startCameraPosition=cdata, startCameraYOffset=0, stepAmount=-0.0075645446777344, stepStartTime=18.408294677734, strafeJumped=false, stunTime=0, syncHealth=false, teamNumber=1, teamResources=61, techId=53, timeCatpackboost=0, timeGroundAllowed=0, timeGroundTouched=16.818370819092, timeLastBeacon=0, timeLastHealed=0, timeLastMenu=0, timeLastSpitHit=0, timeOfCrouchChange=0, timeOfLastDrop=0, timeOfLastJump=0, timeOfLastOrderComplete=0, timeOfLastPhase=0, timeOfLastPickUpWeapon=0, timeOfLastUse=0, timeOfLastWeaponSwitch=16.890413284302, timeSprintChange=16.890413284302, timeUntilResourceBlock=0, timeWebEnds=0, transitionDuration=0, transitionStart=0, tunnelNearby=false, tweeningFunction=1, unitStatusPercentage=0, upgrade1=1, upgrade2=1, upgrade3=1, upgrade4=1, upgrade5=1, upgrade6=1, variant=3, velocity=cdata, velocityLength=0, velocityPitch=0, velocityYaw=0, viewModelId=3256, viewPitch=0.160878688097, viewRoll=0, viewYaw=2.9903495311737, visibleClient=false, vortexed=false, weaponUpgradeLevel=0, weaponsWeight=0.12999999523163, webbed=false }
I don't really know where is the mistake (since there are lot of code and i've only been making small mods for approximately 1 week). I hope you guys will help me.
Thankfully Devnunux.
P.S.: Sorry for my English but i'm French and i'm trying to do my best to write correct sentences. I you don't understand something fell free to ask me.
Comments
When you create a new weapon, you need to add it to all the places in lua where there is shotgun. This would include such files as TechTreeConstants.lua, TechData.lua, among many.
In Decoda, do a search for the word Shotgun. look for where it appears, and add your weapon in the appropriate places.
BTW, Welcome to NS2 modding, I hope you'll have a lot of fun and create some great mods
function WeirdShotgun:OnTag(tagName) PROFILE("Shotgun:OnTag")Should be:
function WeirdShotgun:OnTag(tagName) PROFILE("WeirdShotgun:OnTag")Thank you for your answers. Now it's time to try something else.