• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Lua Subclasses TFS 1.1

Codinablack

Dreamer
Content Editor
Joined
Dec 26, 2013
Messages
1,633
Solutions
11
Reaction score
877
Greetings otland,

I have recently started playing with creation of my own classes and subclasses and seem to have ran into a problem. I don't know how to make my class a subclass of an already predefined (in the source) class. Example of what I mean is say I want to create a new class called Summon, and I want the summon class to have all the properties of the class Monster, which is already defined in our source code.

I already have working classes, but I can't figure out how to make them inherit the properties from a predefined class.

For some reason (I assume it's because I am not creating the object correctly), I can't make my new class actually execute an action outside of the construction. What I mean is like this, first create the class, then constructor, then function for the summon class
Code:
function Summon:say(text, type)
return self:say(text, type)
end
This causes my server to crash.

Even trying it like this
Code:
function Summon:say(text, type)
local creature = Creature(self.cid) --- this is properly saved in summon class constructor
return creature:say:(text, type)
end
causes a crash.

Could someone please show me the proper way to create a sub-class of an already predefined class, because when I create the object, for some reason the object doesn't inherit, and if I try passing the object itself in the class's properties like this :
Code:
self.creature = Creature(param)

When trying to call that object to execute like this:

Code:
function Summon:say(text, type)
return self.creature:say(text, type)
end

All ways crash my server, but if I tried to check it like this

Code:
function Summon:say(text, type)
local creature = Creature(self.cid)
if creature then
print("Yup it passes")
end
end

It will print! Add the execution of creature:say(text, type) and it crashes still, no print.

Few people I know are good with lua, sorry for tagging you guys again, but I really am at a stopping point because of this.

@Limos @Ninja @Printer @Flatlander @Evil Hero @forgee @Evan
 
Sorry for double post, forgot to include someone who is awesome with lua as well... sorry it's been a long night..

@zbizu

Double posted because moderator explained to me editing an original, and adding a tag into it doesn't notify the person.
 
Why don't you just register it in source?

registerClass("Summon", "Monster", LuaScriptInterface::luaSummonCreate);

If not you should just port the LuaScriptInterface::registerClass function to lua or export it itself as a lua function.
There's multiple ways to implement a class system in Lua, you should be consistent with the other classes.
 
Why don't you just register it in source?

registerClass("Summon", "Monster", LuaScriptInterface::luaSummonCreate);

If not you should just port the LuaScriptInterface::registerClass function to lua or export it itself as a lua function.
There's multiple ways to implement a class system in Lua, you should be consistent with the other classes.

I don't make any changes in the source right now simply because I want to be using the master branch at all times during my alpha development. The master branch still has many bugs and milestones to go, features to be added, and while I work on the scripting side (especially since I don't know much about c++) the bugs are still being fixed in the source side and I don't have to do work over again.

There is this in my function list

Code:
-- className = {}

className.__call = newFunction
className.metatable = {}
className.metatable.__index = className
className.metatable.__metatable = className
className.metatable.methodName = func
className.metatable['h'] = hash
className.metatable['p'] = parents
className.metatable['t'] = type

Those are in the source, I just don't understand how to use them though, seeing as how you are @Syntax this is right up your alley, maybe you can help me?
The one that says parents, doesn't that allow me to inherit from the predefined class? Can I do it in any way that you know of? Because I noticed you never told me I couldn't do it... I imagine you are trying to teach me to do it a better way, but right now I need to learn this way for lua, I will move to c++ when my classes for them are over, and I don't start them for another year.

Please, if you can help me, it would be very much appreciated!
 
I've done some of it for you, it's not completely done because I'm not sure how the user data is related to the class system.
I don't currently have the time to tinker with it and research how the system works, but this should get you started.

Code:
function registerClass(baseClass, registerFunction)
    local class = {}
    local metaClass = {
        __index = baseClass or {},
    }

    if registerFunction then
        metaClass.__call = registerFunction
    end

    setmetatable(class, metaClass)
    return class
end

Summon = registerClass(Monster, function(self, master, summonName, extended, force)
    if not master or not summonName then
        return nil
    end

    local position = master:getPosition()
    local monster = Game.createMonster(summonName, position, extended, force)
    if monster then
        monster:setMaster(master)
        -- TODO: relate UserData to summon metatable and return that instead of returning the monster
        -- currently you won't be able to use any subclass functions with this being returned
        return monster
    else
        return nil
    end
end)

local monk = Summon(player, 'monk')
if monk then
    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, 'You summoned a ' .. monk:getName())
end
 
what is the text type? only 2 yellow and orange text type on monsters wont crash the server.

That's not the actual function that is crashing my server, it's the fact that I am trying to get my "object" to actually perform an action, which is the whole point in me starting this topic. I'm pretty sure I know that I should use constants, and make sure the talktype is ok, btw, that was just an example, not the script I am having a problem with.

-- TODO: relate UserData to summon metatable and return that instead of returning the monster -- currently you won't be able to use any subclass functions with this being returned

Like I told whitevo, that is not the actual script I am having a problem with, no, it was just an example, I don't want people doing work for me, I just wanted someone to help me to understand.

You made a working example of how to make one class as a sub-class of another! Thank you very much sir! Now I have some example work to show me how to properly make my classes inherit from another class.

Now the new problem as you said yourself, my object doesn't have it's own userdata and can't perform the subclass methods right? Then I'm kind of in the same boat. I have tested this, your code works, and when I make the monk say something like monk:say() it works, however it won't work when I write out the function Summon:say(). So it's still kind of the same problem, because there is no point in having a class I can't write methods for. Thank you very much for helping me to learn though, please next time I would prefer a little conversation rather than just typing out a function to do what I am asking for, conversation and explanation goes alot further for someone trying to learn.

So can anyone else help me figure out how to make the summon metatable relate the userdata and return that instead of monster?
 
what's point of creating summon class?
you may use creature aswell


I was writing methods for determining whether or not the summon was friendly, and a few other functions, true I can do this for monster, but it's really about the learning experience.
 
Back
Top