How to implement a new alien class?

countbasiecountbasie Join Date: 2008-12-27 Member: 65884Members
<div class="IPBDescription">Noob trying to mod</div>Hey,

I want to add a new alien class. Basically just to have another model for the skulk. I know how to implement the model, but I can only apply it to the original skulk.
I want a lua file called like 'skulk1' and a console command to choose it in cheats mode. So that I can have an original skulk and the other skulk standing next to it. Any ideas?

I tried changing
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->class 'Skulk' (Alien)


Skulk.kMapName = "skulk"<!--c2--></div><!--ec2-->
to
<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->class 'Skulk1' (Alien)


Skulk.kMapName = "skulk1"<!--c2--></div><!--ec2-->
But it doesn't work - is there a file that defines all classes that are in the game?

Comments

  • Soul_RiderSoul_Rider Mod Bean Join Date: 2004-06-19 Member: 29388Members, Constellation, Squad Five Blue
    edited September 2012
    I have loads of invented classes in various mods....

    If you want to have a different skulk model, you just change the model in the skulk file to the name of the new model.

    If you want to create a new alien based off the skulk, then copy the file, and rename it entirely to skulk1.

    For example, just fixing what you have done above:

    <!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->class 'Skulk1' (Alien)

    Skulk1.kMapName = "skulk1"

    Skulk1.kModelName = PrecacheAsset("models/alien/skulk/skulk1.model")
    local kViewModelName = PrecacheAsset("models/alien/skulk/skulk1_view.model")
    local kSkulkAnimationGraph = PrecacheAsset("models/alien/skulk/skulk1.animation_graph")

    if Server then
        Script.Load("lua/Skulk1_Server.lua", true)
    elseif Client then
        Script.Load("lua/Skulk1_Client.lua", true)
    end


    Skulk1.kAirAcceleration = 40

    function Skulk1:OnCreate()<!--c2--></div><!--ec2-->

    Gives you an idea of what you'll be editing etc. I've deleted a lot of line here, as this is just to demonstrate...

    Then you need to go into TechData.lua and add the Tech data for the new skulk, goto to TechTree Constants, to add the skulk1, also you need to go to the alien team and add skulk1 there, and so on throughout the neccesary files..

    If you want to do it this way it is a lot of work, or you could just point the skulk at a different model for the simple fix.

    As a special bonus here is one of my customised aliens, although It isn't an alien, because I have changed the base class as well.... It is a Gorge created for v2 of GorgeCraft. Note this is not an alien anymore, it is a Fort1. (Yes I have designed new Teams and Player Classes for GorgeCraft v2, as well as new game modes.)

    Here is a code box incorporating the code, so you can get an idea of what you would need to do to create a new skulk. This is still a vanilla Gorge in code at teh moment, yet to amend it though..

    <div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>
    // ======= Copyright © 2003-2011, Unknown Worlds Entertainment, Inc. All rights reserved. =======
    //
    // lua\FortsGorge.lua
    //
    // Created by: Andy Wilson for GorgeCraft (soulrider@modbeans.com)
    //
    // ========= For more information, visit us at <a href="http://www.unknownworlds.com" target="_blank">http://www.unknownworlds.com</a> =====================

    Script.Load("lua/Utility.lua")
    Script.Load("lua/Fort1.lua")
    Script.Load("lua/Weapons/Alien/SpitSpray.lua")
    Script.Load("lua/Weapons/Alien/InfestationAbility.lua")
    Script.Load("lua/Weapons/Alien/DropStructureAbility.lua")
    Script.Load("lua/Weapons/Alien/DropStructureAbility2.lua")
    Script.Load("lua/Weapons/Alien/DropStructureAbility3.lua")
    Script.Load("lua/Weapons/Alien/WebStalk.lua")
    Script.Load("lua/Weapons/Alien/BileBomb.lua")
    Script.Load("lua/Weapons/Alien/Absorb.lua")
    Script.Load("lua/Mixins/BaseMoveMixin.lua")
    Script.Load("lua/Mixins/GroundMoveMixin.lua")
    Script.Load("lua/Mixins/CameraHolderMixin.lua")
    Script.Load("lua/DissolveMixin.lua")

    class 'FortsGorge' (Fort1)

    if Server then
    Script.Load("lua/FortsGorge_Server.lua")
    end

    local networkVars =
    {
    bellyYaw = "private float",
    timeSlideEnd = "private time",
    startedSliding = "private boolean",
    sliding = "boolean"
    }

    AddMixinNetworkVars(BaseMoveMixin, networkVars)
    AddMixinNetworkVars(GroundMoveMixin, networkVars)
    AddMixinNetworkVars(CameraHolderMixin, networkVars)
    AddMixinNetworkVars(DissolveMixin, networkVars)

    FortsGorge.kMapName = "fortsgorge"

    FortsGorge.kModelName = PrecacheAsset("models/alien/gorge/gorge.model")
    local kViewModelName = PrecacheAsset("models/alien/gorge/gorge_view.model")
    local kGorgeAnimationGraph = PrecacheAsset("models/alien/gorge/gorge.animation_graph")

    FortsGorge.kSlideLoopSound = PrecacheAsset("sound/NS2.fev/alien/gorge/slide_loop")
    FortsGorge.kBuildSoundInterval = .5
    FortsGorge.kBuildSoundName = PrecacheAsset("sound/NS2.fev/alien/gorge/build")

    FortsGorge.kXZExtents = 0.5
    FortsGorge.kYExtents = 0.475

    local kMass = 80
    local kJumpHeight = 2.4
    local kInfestationStartSlideForce = 7.5
    local kStartSlideForce = 7
    local kViewOffsetHeight = 0.6
    local kMaxGroundSpeed = 9
    local kMaxSlidingSpeed = 17
    local kSlidingMoveInputScalar = 0.1
    local kBuildingModeMovementScalar = 0.001
    local kSlideCoolDown = 0.5

    FortsGorge.kAirZMoveWeight = 2.5
    FortsGorge.kAirStrafeWeight = 2.5
    FortsGorge.kAirBrakeWeight = 0.1

    local kGorgeBellyYaw = "belly_yaw"
    local kGorgeLeanSpeed = 2

    function FortsGorge:OnCreate()

    InitMixin(self, BaseMoveMixin, { kGravity = Player.kGravity })
    InitMixin(self, GroundMoveMixin)
    InitMixin(self, CameraHolderMixin, { kFov = kGorgeFov })

    Fort1.OnCreate(self)

    InitMixin(self, DissolveMixin)

    self.bellyYaw = 0
    self.timeSlideEnd = 0
    self.startedSliding = false
    self.sliding = false
    self.verticalVelocity = 0

    end

    function FortsGorge:OnInitialized()

    Fort1.OnInitialized(self)

    self:SetModel(FortsGorge.kModelName, kGorgeAnimationGraph)

    if Server then

    self.slideLoopSound = Server.CreateEntity(SoundEffect.kMapName)
    self.slideLoopSound:SetAsset(FortsGorge.kSlideLoopSound)
    self.slideLoopSound:SetParent(self)

    else

    self:AddHelpWidget("GUIGorgeHealHelp", 2)
    self:AddHelpWidget("GUIGorgeBellySlideHelp", 2)

    end

    end

    function FortsGorge:GetInfestationBonus()
    return kGorgeInfestationSpeedBonus
    end

    function FortsGorge:GetCeleritySpeedModifier()
    return kGorgeCeleritySpeedModifier
    end

    function FortsGorge:GetCarapaceSpeedReduction()
    return kGorgeCarapaceSpeedReduction
    end

    if Client then

    local kGorgeHealthbarOffset = Vector(0, 0.7, 0)
    function Gorge:GetHealthbarOffset()
    return kGorgeHealthbarOffset
    end

    function FortsGorge:OverrideInput(input)

    local activeWeapon = self:GetActiveWeapon()
    if activeWeapon and (activeWeapon:isa("DropStructureAbility") or activeWeapon:isa("DropStructureAbility2")or activeWeapon:isa("DropStructureAbility3")) then
    input = activeWeapon:OverrideInput(input)
    end

    Player.OverrideInput(self, input)

    end

    end

    function FortsGorge:GetBaseArmor()
    return kGorgeArmor
    end

    function FortsGorge:GetArmorFullyUpgradedAmount()
    return kGorgeArmorFullyUpgradedAmount
    end

    function FortsGorge:GetMaxViewOffsetHeight()
    return kViewOffsetHeight
    end

    function FortsGorge:GetCrouchShrinkAmount()
    return 0
    end

    function FortsGorge:GetExtentsCrouchShrinkAmount()
    return 0
    end

    function FortsGorge:GetViewModelName()
    return kViewModelName
    end

    function FortsGorge:GetJumpHeight()
    return kJumpHeight
    end

    function FortsGorge:GetIsBellySliding()
    return self.sliding
    end

    function FortsGorge:HandleJump(input, velocity)

    if not self:GetIsBellySliding() then
    return Fort1.HandleJump(self, input, velocity)
    end

    return false

    end

    local function GetIsSlidingDesired(self, input)

    if bit.band(input.commands, Move.MovementModifier) == 0 then
    return false
    end

    if self.crouching then
    return false
    end

    if self:GetVelocity():GetLengthXZ() < 3 then

    if self:GetIsBellySliding() then
    return false
    end

    else

    local zAxis = self:GetViewCoords().zAxis
    zAxis.y = 0
    zAxis:Normalize()

    if GetNormalizedVectorXZ(self:GetVelocity()):DotProduct( zAxis ) < 0.2 then
    return false
    end

    end

    return true

    end

    // Handle transitions between starting-sliding, sliding, and ending-sliding
    local function UpdateGorgeSliding(self, input)

    PROFILE("FortsGorge:UpdateGorgeSliding")

    local slidingDesired = GetIsSlidingDesired(self, input)
    if slidingDesired and not self.sliding and self.timeSlideEnd + kSlideCoolDown < Shared.GetTime() and self:GetIsOnGround() and self:GetEnergy() >= kBellySlideCost then

    self.sliding = true
    self.startedSliding = true

    if Server then
    if not GetHasSilenceUpgrade(self) then
    self.slideLoopSound:Start()
    end
    end

    self:DeductAbilityEnergy(kBellySlideCost)

    end

    if not slidingDesired and self.sliding then

    self.sliding = false

    if Server then
    self.slideLoopSound:Stop()
    end

    self.timeSlideEnd = Shared.GetTime()

    end

    // Have Gorge lean into turns depending on input. He leans more at higher rates of speed.
    if self:GetIsBellySliding() then

    local desiredBellyYaw = 2 * (-input.move.x / kSlidingMoveInputScalar) * (self:GetVelocity():GetLength() / self:GetMaxSpeed())
    self.bellyYaw = Slerp(self.bellyYaw, desiredBellyYaw, input.time * kGorgeLeanSpeed)

    end

    end

    function FortsGorge:GetCanRepairOverride(target)
    return true
    end

    function FortsGorge:HandleButtons(input)

    PROFILE("FortsGorge:HandleButtons")

    Fort1.HandleButtons(self, input)

    UpdateGorgeSliding(self, input)

    end

    function FortsGorge:OnUpdatePoseParameters(viewModel)

    PROFILE("FortsGorge:OnUpdatePoseParameters")

    Fort1.OnUpdatePoseParameters(self, viewModel)

    self:SetPoseParam(kGorgeBellyYaw, self.bellyYaw * 45)

    end

    function FortsGorge:ConstrainMoveVelocity(moveVelocity)

    Fort1.ConstrainMoveVelocity(self, moveVelocity)

    if self:GetIsBellySliding() then
    moveVelocity:Scale(0)
    end

    end

    function FortsGorge:GetGroundFrictionForce()

    if self:GetIsBellySliding() then
    return ConditionalValue(self:GetGameEffectMask(kGameEffect.OnInfestation), 0.1, 0.3)
    end

    return Fort1.GetGroundFrictionForce(self)
    end

    function FortsGorge:SetCrouchState(newCrouchState)
    self.crouching = newCrouchState
    end

    function FortsGorge:GetMaxSpeed(possible)

    if possible then
    return kMaxGroundSpeed
    end

    return kMaxGroundSpeed * self:GetMovementSpeedModifier()

    end

    function FortsGorge:GetMass()
    return kMass
    end

    function FortsGorge:OnUpdateAnimationInput(modelMixin)

    PROFILE("FortsGorge:OnUpdateAnimationInput")

    Fort1.OnUpdateAnimationInput(self, modelMixin)

    if self:GetIsBellySliding() then
    modelMixin:SetAnimationInput("move", "belly")
    end

    end

    function FortsGorge:GetAirMoveScalar()
    return 0
    end

    function FortsGorge:GetCanCloakOverride()
    return not self:GetIsBellySliding()
    end

    FortsGorge.kSlideControl = 1

    function FortsGorge:ModifyVelocity(input, velocity)

    Fort1.ModifyVelocity(self, input, velocity)

    if not self:GetIsOnGround() and input.move:GetLength() ~= 0 or self:GetIsBellySliding() then

    local moveLengthXZ = velocity:GetLengthXZ()
    local previousY = velocity.y
    local adjustedZ = false
    local bellySliding = self:GetIsBellySliding()

    if input.move.z ~= 0 then

    local redirectedVelocityZ = GetNormalizedVectorXZ(self:GetViewCoords().zAxis) * input.move.z

    if input.move.z < 0 then

    redirectedVelocityZ = GetNormalizedVectorXZ(velocity)
    redirectedVelocityZ:Normalize()

    local xzVelocity = Vector(velocity)
    xzVelocity.y = 0

    VectorCopy(velocity - (xzVelocity * input.time * FortsGorge.kAirBrakeWeight), velocity)

    else

    redirectedVelocityZ = redirectedVelocityZ * input.time * ConditionalValue(bellySliding, FortsGorge.kSlideControl, FortsGorge.kAirZMoveWeight) + GetNormalizedVectorXZ(velocity)
    redirectedVelocityZ:Normalize()
    redirectedVelocityZ:Scale(moveLengthXZ)
    redirectedVelocityZ.y = previousY
    VectorCopy(redirectedVelocityZ, velocity)
    adjustedZ = true

    end

    end

    if input.move.x ~= 0 then

    local redirectedVelocityX = GetNormalizedVectorXZ(self:GetViewCoords().xAxis) * input.move.x

    if adjustedZ then
    redirectedVelocityX = redirectedVelocityX * input.time * ConditionalValue(bellySliding, FortsGorge.kSlideControl, FortsGorge.kAirStrafeWeight) + GetNormalizedVectorXZ(velocity)
    else
    redirectedVelocityX = redirectedVelocityX * input.time * ConditionalValue(bellySliding, FortsGorge.kSlideControl, 2) + GetNormalizedVectorXZ(velocity)
    end

    redirectedVelocityX:Normalize()
    redirectedVelocityX:Scale(moveLengthXZ)
    redirectedVelocityX.y = previousY
    VectorCopy(redirectedVelocityX, velocity)

    end

    end

    // Give a little push forward to make sliding useful
    if self.startedSliding then

    if self:GetIsOnGround() then

    local pushDirection = GetNormalizedVectorXZ(self:GetViewCoords().zAxis)
    local force = ConditionalValue(self:GetGameEffectMask(kGameEffect.OnInfestation), kInfestationStartSlideForce, kStartSlideForce) * self:GetSlowSpeedModifier()

    local impulse = pushDirection * force

    velocity.x = velocity.x * 0.7 + impulse.x
    velocity.y = velocity.y * 0.7 + impulse.y
    velocity.z = velocity.z * 0.7 + impulse.z

    end

    self.startedSliding = false

    end

    end

    function FortsGorge:GetPitchSmoothRate()
    return 1
    end

    function FortsGorge:GetPitchRollRate()
    return 3
    end

    local kMaxSlideRoll = math.rad(20)

    function FortsGorge:GetDesiredAngles()

    local desiredAngles = Alien.GetDesiredAngles(self)

    if self:GetIsBellySliding() then
    desiredAngles.pitch = - self.verticalVelocity / 10
    desiredAngles.roll = GetNormalizedVectorXZ(self:GetVelocity()):DotProduct(self:GetViewCoords().xAxis) * kMaxSlideRoll
    end

    return desiredAngles

    end

    function FortsGorge:PreUpdateMove(input, runningPrediction)

    self.prevY = self:GetOrigin().y

    end

    function FortsGorge:PostUpdateMove(input, runningPrediction)

    if self:GetIsBellySliding() and self:GetIsOnGround() then

    local velocity = self:GetVelocity()

    local yTravel = self:GetOrigin().y - self.prevY
    local xzSpeed = velocity:GetLengthXZ()

    xzSpeed = xzSpeed + yTravel * -4

    if xzSpeed < kMaxSlidingSpeed or yTravel > 0 then

    local directionXZ = GetNormalizedVectorXZ(velocity)
    directionXZ:Scale(xzSpeed)

    velocity.x = directionXZ.x
    velocity.z = directionXZ.z

    self:SetVelocity(velocity)

    end

    self.verticalVelocity = yTravel / input.time

    end

    end

    if Client then

    function FortsGorge:OnProcessMove(input)

    Fort1.OnProcessMove(self, input)

    self.currentTechId = nil
    self.ghostStructureCoords = nil
    self.ghostStructureValid = false
    self.showGhostModel = false

    local weapon = self:GetActiveWeapon()

    if weapon and (weapon:isa("DropStructureAbility") or weapon:isa("DropStructureAbility2") or weapon:isa("DropStructureAbility3")) then

    self.currentTechId = weapon:GetActiveStructure():GetDropStructureId()
    self.ghostStructureCoords = weapon:GetGhostModelCoords()
    self.ghostStructureValid = weapon:GetIsPlacementValid()
    self.showGhostModel = weapon:GetShowGhostModel()

    end

    end

    function FortsGorge:GetShowGhostModel()
    return self.showGhostModel
    end

    function FortsGorge:GetGhostModelTechId()
    return self.currentTechId
    end

    function FortsGorge:GetGhostModelCoords()
    return self.ghostStructureCoords
    end

    function FortsGorge:GetIsPlacementValid()
    return self.ghostStructureValid
    end

    end

    function FortsGorge:GetCanAttack()
    return Fort1.GetCanAttack(self) and not self:GetIsBellySliding()
    end

    Shared.LinkClassToMap("FortsGorge", FortsGorge.kMapName, networkVars)</div>
  • JibrailJibrail Join Date: 2009-04-16 Member: 67200Members
    I just want to ask were you able to import the model into the game successfully? I am having a hard time making my model work.
  • countbasiecountbasie Join Date: 2008-12-27 Member: 65884Members
    edited September 2012
    Soul_Rider:

    Thanks a lot mate! I'll check it out.

    Jibrail:

    I didn't apply a new model yet, I just checked if I can replace the Skulk model with the Lerk one. That works pretty well, of course. (Just replace the paths in here
    <!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->Skulk.kModelName = PrecacheAsset("models/alien/skulk/skulk.model")
    local kViewModelName = PrecacheAsset("models/alien/skulk/skulk_view.model")
    local kSkulkAnimationGraph = PrecacheAsset("models/alien/skulk/skulk.animation_graph")<!--c2--></div><!--ec2-->
    Since I'm completely new to modding I will try to get an own model in it sometime, but not now :D
Sign In or Register to comment.