Jump to content

[Help] How to use CheckClientOwnership to get my NPCs to look like DLC characters?


Recommended Posts

^This

I have all the DLCs, and I am trying to create a mod where the playable characters serve as your followers.

However I am having trouble getting my followers to look like DLC characters (The non-DLC ones are easy enough, just use inst.AnimState:SetBuild("wonkey")

I know there is something called CheckClientOwnership that can be used to check your DLC ownership, and I know there is at least one mod "NPCs to play with you https://steamcommunity.com/profiles/76561198136150333/myworkshopfiles/?appid=322330&browsefilter=mysubscriptions" that can successfully use it to make NPCs to look like DLC characters (as long as you own them, otherwise it will just look like wilson). However the codes on this mod is a bit too complicated for me (I'm kinda noob)

Can anyone show me how to properly make my NPCs to look like DLC characters (like wanda)? (Preferably without calling too many functions and just place some codes in the prefab file of the NPC..I'm noob sorry)

@Rickzzs (Trying to get expert's attention here XD)

 

@-t- And also you! :-D Sorry to both of you if I am a bother, bit of desperate atm

Edited by Lyserus
Link to comment
Share on other sites

Use maxwell's puppet function to create NPC other than a controllable character if you want only the shape. Though I am not familiar with such reskinning because I never made a mod in this aspect. So far as I know there is another mod WX Automation that creates and reskins WX-78 puppet.

  • Like 1
Link to comment
Share on other sites

8 minutes ago, Rickzzs said:

Use maxwell's puppet function to create NPC other than a controllable character if you want only the shape. Though I am not familiar with such reskinning because I never made a mod in this aspect. So far as I know there is another mod WX Automation that creates and reskins WX-78 puppet.

 

Thank you for your reply!

Aye I can manage to create the NPC follower as long as they are not DLC characters (for example I can get the look for waxwell, wolfgang etc)

My current lua looks like this:Follower_Friends.zip

I want to have wanda look in this file here: friend_wanda.lua but simply


    inst.AnimState:SetBank("wilson")
    inst.AnimState:SetBuild("wonkey") -- wanda doesn't work here
    inst.AnimState:PlayAnimation("idle")

Doesn't work unfortunately.

I have checking other people's work and see things like

TheInventory:CheckClientOwnership(self.inst.userid, "wanda_none")

SetSkinsOnAnim(inst.AnimState,"wanda","wanda",skins,nil,"normal_skin","wanda") or SetSkinMode

Being utilized, but I haven't managed to do it myself

Edited by Lyserus
Link to comment
Share on other sites

Never attempted anything like this but I tried using SetSkinsOnAnim() and it did work. I ran it in the console like this:

SetSkinsOnAnim(ThePlayer.AnimState, "wanda", "wanda", nil, nil, "normal_skin", "wanda")

You might need to change `ThePlayer` into `inst` depending on where you'd put it. I think it should work fine if you put it inside `fn` in friend_wanda.lua.

  • Like 1
Link to comment
Share on other sites

5 minutes ago, -t- said:

Never attempted anything like this but I tried using SetSkinsOnAnim() and it did work. I ran it in the console like this:

SetSkinsOnAnim(ThePlayer.AnimState, "wanda", "wanda", nil, nil, "normal_skin", "wanda")

You might need to change `ThePlayer` into `inst` depending on where you'd put it. I think it should work fine if you put it inside `fn` in friend_wanda.lua.

Thanks a lot for replying!

 

I put these inside my fn for friend_wanda.lua

    inst.AnimState:SetBank("wilson")
    inst.AnimState:SetBuild("wanda")
    inst.AnimState:PlayAnimation("idle")

    inst:DoTaskInTime(0,function()
        pcall(function()
            local skins = {
                ["feet"] = "",
                ["legs"] = "",
                ["hand"] = "",
                ["base"] = "wanda_none",
                ["body"] = ""
            }
            local userid = inst:GetPlayer().userid 
            TheInventory:CheckClientOwnership(userid, "wanda_none")
            inst.AnimState:AssignItemSkins(userid, skins.base or "", skins.body or "", skins.hand or "", skins.legs or "", skins.feet or "")
            SetSkinsOnAnim(inst.AnimState,"wanda","wanda",skins,nil,"normal_skin","wanda") 
        end)
    end)

It is not crashing or disconnecting my now, but the entity is still invisible (I know the entity is there because it's saying things and help me chop trees

Any obvious errors I am missing here?

Link to comment
Share on other sites

6 minutes ago, -t- said:

Maybe try keeping the build just "wilson". I tested it with wilson and didn't use SetBuild(), only SetSkinsOnAnim().

Thanks for the reply!

Unfortunately removing the setbuild() doesn't quite work (entity is still invisible, if I set it to Wilson then it is just a Wilson)

If it's alright, can you show me the codes you have for testing? Much appreciate!

Link to comment
Share on other sites

22 minutes ago, -t- said:

I simply ran this through the remote console:

SetSkinsOnAnim(ThePlayer.AnimState, "wanda", "wanda", nil, nil, "normal_skin", "wanda")

 

oh..I am actually trying to use it on a NPC not my player.

Anyway to apply this on an entity in remote console?

Link to comment
Share on other sites

Through the remote console I'd imagine it would go something like this:

SetSkinsOnAnim(c_selectnear("your_ent_prefab", "radius").AnimState, "wanda", "wanda", nil, nil, "normal_skin", "wanda")

You can't use c_select() because it only works on the client.

  • Health 1
Link to comment
Share on other sites

5 minutes ago, -t- said:

Through the remote console I'd imagine it would go something like this:

SetSkinsOnAnim(c_selectnear("your_ent_prefab", "radius").AnimState, "wanda", "wanda", nil, nil, "normal_skin", "wanda")

You can't use c_select() because it only works on the client.

Thanks! Will give it a try and update here 

It still may have some problems on code through. I can spawn a Wanda character on console without problem, but I can't simply set build as wanda. But we will see if it works :)

Link to comment
Share on other sites

13 hours ago, -t- said:

Through the remote console I'd imagine it would go something like this:

SetSkinsOnAnim(c_selectnear("your_ent_prefab", "radius").AnimState, "wanda", "wanda", nil, nil, "normal_skin", "wanda")

You can't use c_select() because it only works on the client.

I think I know the problem now, I was not getting the userid. I though GetPlayer is a built in function, but it is actually a function created by the mod I was referencing

I am now trying to get the userid and change skin from the "eye bone" item for my follower, but how do I get the userid based on the item owner?

local function SpawnPet(inst)
    if inst.pet == nil or (inst.pet and not inst.pet:IsValid()) then
    local wanda = SpawnPrefab("friend_wanda")
    local pos = Vector3(inst:GetPosition():Get()) + Vector3(2, 0, 2)
    wanda.Transform:SetPosition(pos:Get())  
               
    inst.pet = wanda     
    local userid = inst.components.inventoryitem.owner.userid
    TheInventory:CheckClientOwnership(userid, "wanda_none")
    inst.pet.AnimState:AssignItemSkins(userid, "wanda_none", "", "", "", "")
    inst.components.leader:AddFollower(wanda)

I was wishing this could work but unfortunately it doesn't

(Remember we are now on the eyebone item's file so the inst is the item

Link to comment
Share on other sites

17 hours ago, -t- said:

Through the remote console I'd imagine it would go something like this:

SetSkinsOnAnim(c_selectnear("your_ent_prefab", "radius").AnimState, "wanda", "wanda", nil, nil, "normal_skin", "wanda")

You can't use c_select() because it only works on the client.

At this moment I got this

inst.AnimState:SetBank("wilson")
inst.AnimState:SetBuild("wilson")
inst:Hide()
inst:DoTaskInTime(0,function()
pcall(function()
local skins = {
["feet"] = "",
["legs"] = "",
["hand"] = "",
["base"] = "wanda_none",
["body"] = ""
}
local leader = inst:GetNearestPlayer(true)
local userid = leader.userid
TheInventory:CheckClientOwnership(userid, "wanda_none")
inst.AnimState:AssignItemSkins(userid, skins.base or "", skins.body or "", skins.hand or "", skins.legs or "", skins.feet or "")
inst:Show()
end)
end)

I moved back to working on wanda_friend.lua

But I only got wilson not wanda still...

Link to comment
Share on other sites

a=c_spawn("pigman")
a.AnimState:SetBank("wilson")
a:AddComponent("skinner")
a.components.skinner:SetupNonPlayerData()
base="wilson_magma"
oldbse=ThePlayer.AnimState:GetBuild()
ThePlayer.AnimState:SetSkin(base,oldbase)
a.components.skinner:CopySkinsFromPlayer(ThePlayer)
ThePlayer.AnimState:SetSkin(oldbase,"wilson")

Very easy to do so, just reskinned a pig.image.png.97b932a2e0b6ea8104b2eb9d29f9c63c.png

Edited by Rickzzs
  • Health 1
Link to comment
Share on other sites

2 hours ago, Rickzzs said:
a=c_spawn("pigman")
a.AnimState:SetBank("wilson")
a:AddComponent("skinner")
a.components.skinner:SetupNonPlayerData()
base="wilson_magma"
oldbse=ThePlayer.AnimState:GetBuild()
ThePlayer.AnimState:SetSkin(base,oldbase)
a.components.skinner:CopySkinsFromPlayer(ThePlayer)
ThePlayer.AnimState:SetSkin(oldbase,"wilson")

Very easy to do so, just reskinned a pig.image.png.97b932a2e0b6ea8104b2eb9d29f9c63c.png

That is one interesting way to do it! I will go ahead and give it a try, thank you!

(btw are you fellow Chinese? :D

Link to comment
Share on other sites

11 hours ago, Rickzzs said:
a=c_spawn("pigman")
a.AnimState:SetBank("wilson")
a:AddComponent("skinner")
a.components.skinner:SetupNonPlayerData()
base="wilson_magma"
oldbse=ThePlayer.AnimState:GetBuild()
ThePlayer.AnimState:SetSkin(base,oldbase)
a.components.skinner:CopySkinsFromPlayer(ThePlayer)
ThePlayer.AnimState:SetSkin(oldbase,"wilson")

Very easy to do so, just reskinned a pig.image.png.97b932a2e0b6ea8104b2eb9d29f9c63c.png

You are the mannnnnnnn!!!!!

I am at one final touch now:

local function OnBuilt(inst, builder)
    if builder and builder.components.leader then
        SpawnPet(inst)
        inst.pet:AddComponent("skinner")
        inst.pet.components.skinner:SetupNonPlayerData()
        local base="wilson_magma"
        local oldbase=inst.components.inventoryitem.owner.AnimState:GetBuild()
        inst.components.inventoryitem.owner.AnimState:SetSkin(base,oldbase)
        inst.pet.components.skinner:CopySkinsFromPlayer(inst.components.inventoryitem.owner)
        inst.components.inventoryitem.owner.AnimState:SetSkin(oldbase,"wilson")
    end 
end

For some reason (I think probably because it is executing too quickly or sth?

(This file is on the "eye bone" item's on built, so inst.components.inventoryitem.owner being the player, and inst.pet being the follower)

When running as is, the player skin actually doesn't change and the follower will copy the original skin of my player.

But if I remove the last two lines,

        inst.pet.components.skinner:CopySkinsFromPlayer(inst.components.inventoryitem.owner)
        inst.components.inventoryitem.owner.AnimState:SetSkin(oldbase,"wilson")

I can actually see my player skin gets updated.

If I remove only the last line only, I can see my player skin gets updated, but the follower still look like my previous original skin

What could be the cause of this? Anyway for me to get around it? (I am thinking some kind of wait command?

 

ADD: one further issue seems to be that the skin is not saved when I exit and reload the game

Edited by Lyserus
Link to comment
Share on other sites

15 hours ago, Rickzzs said:

Very easy to do so, just rskinned a pig.

I went back to the design as my attempt to save the skins got an error related to the ownership check.. so here is what I have now:

x=c_spawn("pigman")  --Spawn a pigman
x.AnimState:SetBank("wilson")
x.AnimState:SetBuild("wilson") --pigman looks like Wilson

SetSkinsOnAnim(x.AnimState, "wilson", "willow", nil, nil, "normal_skin","wilson") --Verified that it works, Pigman now looks like Willow

skin ="wilson_magma"

Player =x:GetNearestPlayer()
print(Player.userid)       --确Verified that I got the userid

Check = TheInventory:CheckClientOwnership(y.userid, skin)
print(Check)  -Verified it being true

SetSkinsOnAnim(x.AnimState, "wilson", "wilson_magma", nil, nil, "normal_skin","wilson") --Nothing happens (if pigman looked like Willow before, it now looks like normal Wilson)

 

I was taking a look at mod NPCs to Play With You, which is the only one mod I know that made DLC character NPC worked.

 

It seems that both of these two are needed:

AnimState:AssignItemSkins and

SetSkinsOnAnim

 

My code above got the SetSkinsOnAnim to work, however, I still dont know how AnimState:AssignItemSkins works, as even my test with player failed:

ThePlayer.AnimState:AssignItemSkins(ThePlayer.userid,"wilson_magma", "","","","")

Can you teach me how to use AssignItemSkins works? Thanks!

Link to comment
Share on other sites

16 hours ago, Rickzzs said:
a=c_spawn("pigman")
a.AnimState:SetBank("wilson")
a:AddComponent("skinner")
a.components.skinner:SetupNonPlayerData()
base="wilson_magma"
oldbse=ThePlayer.AnimState:GetBuild()
ThePlayer.AnimState:SetSkin(base,oldbase)
a.components.skinner:CopySkinsFromPlayer(ThePlayer)
ThePlayer.AnimState:SetSkin(oldbase,"wilson")

Very easy to do so, just reskinned a pig.image.png.97b932a2e0b6ea8104b2eb9d29f9c63c.png

I got it now!!

x=c_spawn("pigman")  
x.AnimState:SetBank("wilson")
x.AnimState:SetBuild("wilson")

skin ="wanda_none"

Player = x:GetNearestPlayer()
print(Player.userid) 

Check = TheInventory:CheckClientOwnership(Player.userid, skin)
print(Check)  -确认为true

x.AnimState:AssignItemSkins(Player.userid,"wanda_none", "","","","")
SetSkinsOnAnim(x.AnimState, "wilson", "wanda", nil, nil, "normal_skin","wilson") 

Just adjust accordingly in the mod file to make it work in mod.

Thanks a bunch for the help along the way!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...