English Extending native functions

28 replies
Goto Page
To the start Previous 1 2 Next To the start
20.09.13 07:13:36 pm
Up
Livia
User
Offline Off
Hello,

I'm one of those who hate using player(id,value) function. It just makes my code ugly and unreadable. My solution for this is more object-like approach which simplifies the code a lot. Let me give you an example on what we can do with it:

Code:
1
2
3
4
5
6
7
8
9
10
11
12
Hook('say', 'say')
function say(ply, message)

    if message == "cheat" then
        ply.health = 100
        ply.speedmod = 20
        ply.money = ply.money + 1000
        ply.name = ply.name .. " is cheating"
        ply:msg("Have fun ;)")
        return 1
    end
end


You can also assign custom data to player objects because they are really just tables with a common metatable. Even though it has the player(id) constructor, it is still 100% compatible with the old player(id,value) method.

What do you think?

Edit:
Source code: https://github.com/tarjoilija/lapi
edited 3×, last 22.09.13 11:05:27 pm
Software has no limits.
20.09.13 07:35:59 pm
Up
Infinite Rain
Reviewer
Offline Off
Very very useful, but I think that you have uploaded it before.
A thousand may fall at your side, ten thousand at your right hand, but it will not come near you. You will only look with your eyes and see the recompense of the wicked. - Psalm 91:7-8 ESV
20.09.13 08:17:44 pm
Up
Livia
User
Offline Off
@user Infinite Rain: Yes, I uploaded similar script a long time ago but then for some unknown reason I decided to remove it. However I think this one is better.
Software has no limits.
20.09.13 08:22:17 pm
Up
Avo
User
Offline Off
So upload it one more time. US.de needs good files these days.
Trust me, I'm an engineer | user DC approved file cs2d Super extra mod for CS2D (64), yeah!
20.09.13 09:55:48 pm
Up
Livia
User
Offline Off
@user Avo: It's actually included in my message but I'm afraid there's not many people making use of it. I'm also too lazy to write any kind of instructions on how it works.
Software has no limits.
20.09.13 10:07:32 pm
Up
EngiN33R
Moderator
Offline Off
Well, I was trying to find this in the File Archive a while ago to include it in my modding API, and because I didn't find it I wrote a similar system myself. Nice to see this again! It's a really nice script in the spirit of Lua's syntactic sugar.

Also, now that I know why I couldn't find it, and now that it's available again, I'd like to ask you if you would give your permission to include this in my modding API (link one, link two).
I code, therefore I exist. | Visit my blog for Lua tips and other interesting info
20.09.13 10:28:55 pm
Up
Livia
User
Offline Off
Your modding API looks really promising and I think many people could find use for that (if it has dumb-proof video instructions included). My code snippets are always free as in speech and free as in beer so go ahead and spread the love.
Software has no limits.
20.09.13 11:11:35 pm
Up
MikuAuahDark
User
Offline Off
You should only return the address of the table so it can to be edited again by a hook(cs2d lua hook always,cs2d lua hook hit,etc.)

EDIT: i am creating a similar function but the table doesn't updated when event occurs

More >


It has all argument type of cs2d lua cmd player

And at user Livia code, there is a code-writing mistakes at here:
Code:
1
2
3
4
5
6
7
8
9
10
11
elseif key == 'x' then
        self:setpos(value, self.y)
    elseif key == 'tilex' then
        self:setpos(value * 16, self.y)
    elseif key == 'y' then
        self:setpos(self.x, value)
    elseif key == 'tiley' then
        self:setpos(self.x, value * 16)
    else
        rawset(self, key, value)
    end

He/she just put X as Y and Y as X
edited 2×, last 20.09.13 11:56:27 pm
file cs2d LuaJIT for Dedicated Server (13) JIT POWER! | Know your Lua errors! | Part of LÖVE development team since 11.3
21.09.13 01:05:59 am
Up
Livia
User
Offline Off
user MikuAuahDark has written:
You should only return the address of the table so it can to be edited again by a hook(cs2d lua hook always,cs2d lua hook hit,etc.)

Which table? Which return?

user MikuAuahDark has written:
He/she just put X as Y and Y as X

Are you sure? Everything worked fine for me.
Software has no limits.
21.09.13 07:53:27 am
Up
MikuAuahDark
User
Offline Off
user Livia has written:
Which table? Which return?

A table that can be updated by CS2D when special event occurs. Example for health and armor table changing:

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PlayerListTables={}

-- Let's use ID 5 for this simulation
PlayerListTables[5]={100,100}     -- Health 100 and armor 100

addhook("hit","change_table_value_by_address")
function change_table_value_by_address(id,pl,w,hp,ap)
     PlayerListTables[id][1]=player(id,"health")-hp
     PlayerListTables[id][2]=player(id,"armor")-ap
end

-- Let's try
PHealth=PlayerListTables[5]
print(PHealth[1].." "..PHealth[2])     -- 100 100
change_table_value_by_address(5,1,45,5,2)     -- Player with ID 5 is hit. His health and armor decreased by 5 and 2
print(PHealth[1].." "..PHealth[2])     -- 95 98

Code above is still use variable PHealth but it change the table value by cs2d lua hook hit. the table address is stored at PlayerListTables[5] and it's same as PHealth table. So changing value of PHealth variable(not re-create the table) also changing value of PlayerListTables[5] variable.
At-least you doesn't change the table. example for wrong hit code
Code:
1
2
3
4
addhook("hit","change_table_value_by_address")
function change_table_value_by_address(id,pl,w,hp,ap)
     PlayerListTables[id]={player(id,"health")-hp,player(id,"armor")-ap}
end

Code above will invalid and doesn't change the values when someone is hit.

user Livia has written:
Are you sure? Everything worked fine for me.

Nevermind about this. I am doesn't read the code correctly. Now i get it.
file cs2d LuaJIT for Dedicated Server (13) JIT POWER! | Know your Lua errors! | Part of LÖVE development team since 11.3
21.09.13 10:15:46 am
Up
Livia
User
Offline Off
Storing custom data to player objects was actually implemented in the older version. The code was holding player_data table and returning players from there instead of creating a new table every time. However this leaded to at least one problem: who should make sure that custom data is erased when player disconnects? I decided not to use any kind of hooks in my code.
However your point is good. It would be better if it had one table maintaining every player. See the example:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
dofile("sys/lua/player.lua")

addhook('join', 'join')
function join(id)
    local p = player(id)
    
    p.isAdmin = false -- custom variable is set here
end

addhook('say', 'say')
function say(id, message)
    local p = player(id)
    
    if message == "admin" then
        p.isAdmin = true
        p:msg("admin powa")
        return 1
    end
    
    if message == "cheat" and p.isAdmin then
        p.health = 100
        p.money = p.money + 1000
        p.x = p.x + 5
        p.name = p.name .. " IS CHEATER!!!"
        p:msg("Have fun ;)")
        return 1
    end
end


> updated source code here
Spoiler >
Software has no limits.
21.09.13 11:04:54 am
Up
MikuAuahDark
User
Offline Off
Well, i am creating a function similar to it. It's uses 1 table address everytime

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Player={}

for v=1,32 do
     local temp={}
     temp.msg=function(m)
          msg2(v,m)
     end
     temp.equip=function(w)
          parse("equip "..v.." "..w)
     end
     temp.strip=function(w)
          parse("strip "..v.." "..w)
     end
     temp.spawn=function()
          local t=player(v,"team")
          if t>0 then
               if t==3 then t=2 end
               local x,y=randomentity(player(v,"team")-1)
               parse("spawnplayer "..v.." "..(x*32+16).." "..(y*32+16))
          end
     end
     temp.kick=function(r)
          parse("kick "..v.." \""..r.."\"")
     end
     temp.kill=function()
          parse("killplayer "..v)
     end
     temp.
     setmetatable(temp,{
          __index=function(_,var)
               return player(v,var)
          end,
          __newindex=function(_,var,val)
               if var=="name" then parse("setname "..v.." "..val)
               elseif var=="team" then
                    if val==0 then
                         parse("makespec "..v)
                    elseif val==1 then
                         parse("maket "..v)
                    elseif val==2 or val==3 then
                         parse("makect "..v)
                    end
               elseif var=="x" then parse("setpos "..v.." "..val.." "..player(v,"y"))
               elseif var=="y" then parse("setpos "..v.." "..player(v,"x").." "..val)
               elseif var=="tilex" then parse("setpos "..v.." "..(val*32+16).." "..(math.floor(player(v,"y")/32)*32+16))
               elseif var=="tiley" then parse("setpos "..v.." "..(math.floor(player(v,"x")/32)*32+16).." "..(val*32+16))
               elseif var=="health" then parse("sethealth "..v.." "..val)
               elseif var=="armor" then parse("setarmor "..v.." "..val)
               elseif var=="money" then parse("setmoney "..v.." "..val)
               elseif var=="score" then parse("setscore "..v.." "..val)
               elseif var=="deaths" then parse("setdeaths "..v.." "..val)
               elseif var=="speedmod" then parse("speedmod "..v.." "..val)
               elseif var=="maxhealth" then
                    local health=player(v,"health")
                    parse("setmaxhealth "..v.." "..val)
                    parse("sethealth "..v.." "..health)
               end
          end
     })
     Player[v]=temp
end

setmetatable(Player,{
__call=function(_,id)
     if _[id].exists then
          return _[id]
     end
end
})

It's only uses 1 table address/player, not to create the table anytime. So it uses 32 static table. When player disconnects, the table doesn't erased.

Example for static table address:
Code:
1
2
3
AuahDark=Player(1)
print(AuahDark)     -- table: xxxxxxxx
print(AuahDark==Player(1))     -- true


user Livia has written:
who should make sure that custom data is erased when player disconnects?

You don't need to erase it. That's why cs2d lua cmd player(id,"exists") is useful for this.
file cs2d LuaJIT for Dedicated Server (13) JIT POWER! | Know your Lua errors! | Part of LÖVE development team since 11.3
21.09.13 11:32:43 am
Up
VADemon
User
Offline Off
@user MikuAuahDark: Don't forget that most usernames contain special characters.
21.09.13 11:33:48 am
Up
MikuAuahDark
User
Offline Off
What's wrong with the special characters?
file cs2d LuaJIT for Dedicated Server (13) JIT POWER! | Know your Lua errors! | Part of LÖVE development team since 11.3
21.09.13 11:41:53 am
Up
VADemon
User
Offline Off
I misunderstood you and thought that you're going to use player names as table names
21.09.13 05:13:15 pm
Up
Livia
User
Offline Off
Now it's getting interesting. I've continued working on the player class and so far you can easily return tables of player objects.

Edit: Here's some more cool stuff!
Edit2: Also added custom hook wrapper which will call functions with player objects instead of player ids.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
dofile('sys/lua/lapi/lapi.lua')

Hook.add('join', 'hook_join')
function hook_join(p)
    p.is_admin = false              -- custom data added to player object
end

Hook.add('say', 'hook_say')
function hook_say(p, message)

    if message == 'admin' then
        p.is_admin = true
        p:msg("Admin :3")
        return 1
    end
    
    if message == 'I am poor' then
        p.money = p.money + 1000
    end
    
    if message == 'arm' and p.is_admin then
        p.weapons = {3, 45, 51, 32} -- automatically strip and equip weapons
        p.weapon = 45               -- switch current weapon
        p.speedmod = 100            -- cheat
        p:msg('Laser power!')       -- send message to the player
        return 1
    end

    if message == "kill_t" then
        local tbl = Player.team1living -- returns a table with all living terrorists
        for k,v in pairs(tbl) do
            v:kill()
        end
        p:msg("You just killed "..#tbl.." terrorists!")
        return 1
    end
end

Source code: https://github.com/tarjoilija/lapi/
Documentation: https://github.com/tarjoilija/lapi/blob/master/DOCUMENTATION
edited 5×, last 22.09.13 04:59:51 pm
Software has no limits.
22.09.13 01:21:15 pm
Up
Infinite Rain
Reviewer
Offline Off
Dude, it's epic! Expecting more work from you. Do the same to objects!
A thousand may fall at your side, ten thousand at your right hand, but it will not come near you. You will only look with your eyes and see the recompense of the wicked. - Psalm 91:7-8 ESV
22.09.13 05:50:52 pm
Up
Livia
User
Offline Off
user Infinite Rain has written:
Dude, it's epic! Expecting more work from you. Do the same to objects!


Do you mean something like this?
Spoiler >
Software has no limits.
22.09.13 06:11:36 pm
Up
Infinite Rain
Reviewer
Offline Off
@user Livia:
Yep, just like that. You're genius.
A thousand may fall at your side, ten thousand at your right hand, but it will not come near you. You will only look with your eyes and see the recompense of the wicked. - Psalm 91:7-8 ESV
23.09.13 02:18:34 pm
Up
Livia
User
Offline Off
Yet another update. Here's a simple hat script for you showing plenty of the features of Love API.
Spoiler >


Edit: Added file saving/loading plugin.
Spoiler >

Edit2: Okay, I had to add hat plugin too
Spoiler >

Always up-to-date source code here.
edited 3×, last 23.09.13 10:39:46 pm
Software has no limits.
To the start Previous 1 2 Next To the start