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
Should be:
Thank you for your answers. Now it's time to try something else.