Jump to content

Custom emote?


Recommended Posts

I'm trying to implement a custom emote and it's working out pretty well except that I can't seem to alter emotes.lua. It works whenever I edit it manually, but whenever I do this in modmain:

global.emotes["dab"] = 
{
    aliases = { "waves", "hi" },
    data = { anim =  "spriter_idle", randomanim = true, mounted = true },
}

it has an error and refers me to the log, which is pretty unspecific. I can supply the log file as well as the mod if anyone wants to see it.

I can't find any other functional emote mods so I suspect that emotes.lua is untouchable for some reason.

Link to comment
Share on other sites

data/scripts/emotes.lua:1-1::

local EMOTES =

It's a local variable, so you can't touch it directly.

 

Look at the bottom of the file to see what the file does with the local variable.

It shoves it in a loop and uses each part for AddUserCommand.

 

So your mod would use AddUserCommand and have its own emote.

Or copy paste the entirety of the emotes file and have the 'EMOTES' table only include your new emotes if you plan on having a lot of emotes.

Link to comment
Share on other sites

Oh thank you! That explanation makes sense! I managed to get it working with:

local EMOTES =
{
    ["dab"] = {
        data = { anim =  "spriter_idle", randomanim = true, mounted = true },
    }
}

for k, v in pairs(EMOTES) do
    AddUserCommand(k, {
        aliases = v.aliases,
        prettyname = function(command) return string.format(STRINGS.UI.BUILTINCOMMANDS.EMOTES.PRETTYNAMEFMT, command.name) end,
        desc = function() return STRINGS.UI.BUILTINCOMMANDS.EMOTES.DESC end,
        permission = "USER",
        params = {},
        emote = true,
        slash = true,
        usermenu = false,
        servermenu = false,
        vote = false,
        serverfn = function(params, caller)
            local player = GLOBAL.UserToPlayer(caller.userid)
            if player ~= nil then
                player:PushEvent("emote", v.data)
            end
        end
    })
end

 

Link to comment
Share on other sites

Ok, so I changed the approach a little bit because some characters seem to require a different animation due to unique body parts. For example, if you try to have Webber do an animation made from Wilson's sprite, Webber's head-legs momentarily vanish. I have this:

Assets = {
    Asset( "ANIM", "anim/dab_anim_webber.zip" ),
    Asset( "ANIM", "anim/dab_anim_wendy.zip" ),
	Asset( "ANIM", "anim/dab_anim_wickerbottom.zip" ),
	Asset( "ANIM", "anim/dab_anim_wilson.zip" )
}

AddUserCommand("dab", {
	prettyname = function(command) return string.format(STRINGS.UI.BUILTINCOMMANDS.EMOTES.PRETTYNAMEFMT, command.name) end,
	desc = function() return STRINGS.UI.BUILTINCOMMANDS.EMOTES.DESC end,
	permission = GLOBAL.COMMAND_PERMISSION.USER,
	params = {},
	emote = true,
	slash = true,
	usermenu = false,
	servermenu = false,
	vote = false,
    localfn = function(params, caller)
	  local player = GLOBAL.UserToPlayer(caller.userid)
	  if player ~= nil then
	   if player.prefab == "webber" then
		player:PushEvent("emote", { anim =  "dab_anim_webber", randomanim = true })
	   elseif player.prefab == "wilson" then
		player:PushEvent("emote", { anim =  "dab_anim_wilson", randomanim = true })
		elseif player.prefab == "wickerbottom" then
		player:PushEvent("emote", { anim =  "dab_anim_wickerbottom", randomanim = true })
		else player:PushEvent("emote", { anim =  "dab_anim_wendy", randomanim = true })
	   end
	  end
    end,
})

And it works fine if the host is doing /dab, but it ignores any clients trying to do so. I suspect this is due to some permissions issue, which is why i changed the permission to GLOBAL.COMMAND_PERMISSION.USER, but that hasn't worked either. This is also harder to test with trail and error because you need to have several people to test if clients can do it. This seems to be the last obstacle before the mod is complete, and I hope that afterwards it could be used as a framework for other custom emotes. More help would be appreciated!

:wilson_vforvictory:

Link to comment
Share on other sites

53 minutes ago, amethystMushroom said:

This is also harder to test with trail and error because you need to have several people to test if clients can do it.

If you need to test only whether an emote works on a client, you can test on your own dedicated server (available under Steam's tools), or host a world with caves (which starts dedicated servers for each shard in the background).

You would likely indeed need more people to test stuff like interaction between players, such as pvp.

Link to comment
Share on other sites

Good news, everyone! :wilson_lightbulb:

After hours of analyzing the code and doing trial and error, I got it to work! Thanks Muche for suggesting using a dedicated server for tests. This is the code i ended up with, complete with frustrated print() statements:

GLOBAL.AddModUserCommand("dab mod", "dab", {
	--aliases = swaggies,
	prettyname = function(command) return "dab emote" end,
	desc = function() return "Perform an emote!" end,
	permission = "USER",
	params = {},
	emote = true,
	slash = true,
	usermenu = false,
	servermenu = false,
	vote = false,
    serverfn = function(params, caller)
		local player = GLOBAL.UserToPlayer(caller.userid)
		print("ASDASDASDASDASDASDASDASDkkkkkkkkskskskksSSKSK")
		if player ~= nil then
			if player.prefab == "webber" then
				player:PushEvent("emote", { anim =  "dab_anim_webber", randomanim = true })
			elseif player.prefab == "wilson" then
				player:PushEvent("emote", { anim =  "dab_anim_wilson", randomanim = true })
			elseif player.prefab == "wickerbottom" then
				player:PushEvent("emote", { anim =  "dab_anim_wickerbottom", randomanim = true })
			else player:PushEvent("emote", { anim =  "dab_anim_wendy", randomanim = true })
			end
		end
    end,
    localfn = function(params, caller)
		local player = GLOBAL.UserToPlayer(caller.userid)
		print("ASDASDASDASDASDASDASDASDkkkkkkkkskskskksSSKSK2")
		if player ~= nil then
			if player.prefab == "webber" then
				player:PushEvent("emote", { anim =  "dab_anim_webber", randomanim = true })
			elseif player.prefab == "wilson" then
				player:PushEvent("emote", { anim =  "dab_anim_wilson", randomanim = true })
			elseif player.prefab == "wickerbottom" then
				player:PushEvent("emote", { anim =  "dab_anim_wickerbottom", randomanim = true })
			else player:PushEvent("emote", { anim =  "dab_anim_wendy", randomanim = true })
			end
		end
    end,
})

The aliases is commented out because for some reason aliases would always crash line 493 in usercommands.lua. I think that's an oversight in the game. There's a comment in builtinusercommands.lua that they're working on the limitations of the system, so it will probably get fixed eventually.

I'm thinking about polishing this up a bit and releasing it as a template for other people to implement emotes and maybe other text commands. Or maybe people can just use my mod as a guide already? It's not terribly complicated, after all. It's just that I couldn't find a single case of anyone using AddModUserCommand even though builtinusercommands.lua says "there is already a mod interface for adding your own commands".

I collaborated with my new friend teri to make this; they made all the animations.

Here is the workshop page!

Link to comment
Share on other sites

@V2C / @Ipsquiggle, I think the crash mentioned above could be fixed by

--- usercommands.lua
+++ usercommands.fix.lua
@@ -490,7 +490,7 @@ function AddModUserCommand(mod, name, data)
     if data.aliases ~= nil then
         for i,alias in ipairs(data.aliases) do
             hash = smallhash(alias)
-            usercommands[mod][hash] = {aliasfor=name}
+            modusercommands[mod][hash] = {aliasfor=name}
         end
     end
 end

 

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