Jump to content
Angelix

Rush - Development

Recommended Posts

Some time ago I made public back then in ServerDev an idea I had somewhat developed, it was an script for a game mode based on S4 League's "Chaser" mode. It wasn't an exact replica, but it was kinda interesting, so I developed it till my knowledge (a bit limited at that time) finally gave in and due to university, it was left to pick up dust without seeing light.

 

While I personally have my own custom server files based on v2.X structure, I tend to wander off from time to time and develop these kind of things along with complete customization as seen as my last reworks (fairy, upgrade and ticket systems). Anyways, this idea was brought up again by @KONG in this thread/post (link).

 

Back then, I had limited knowledge on how to work on a few things.

* How to handle map copies.

* How to handle player's role with registration NPC for 10 players, in case they disconnected or something else happened.

Edited by Angelix
  • Like 3

Share this post


Link to post
Share on other sites

Somehow I can't post a code tag within the starting post in thread!

 

Anyway, with a bit of help from KONG on said thread, I was wondering if anyone can confirm if the following code can/will work with player's role.

if Rush == nil then
	Rush = {}
	Rush.WaitList = {}
end
Rush.Func = function()
	local Self = {}
	--Size, Rush.WaitList = Size or 0, Rush.WaitList or {}
	Self.Push = function(Player)
		Rush.WaitList[(table.getn(Rush.WaitList) + 1)] = Player
		--[[
		Rush.WaitList[(Size + 1)] = Player
		Size = Size + 1
		]]
	end
	Self.NextInLine = function()
		return Rush.WaitList[1]
		--[[
		return Rush.WaitList[Size]
		]]
	end
	Self.GetPlayer = function()
		return table.remove(Rush.WaitList, 1)
		--[[
		local Player = Rush.WaitList[Size]
		Rush.WaitList[Size] = nil
		Size = Size - 1
		return Player
		]]
	end
	Self.ReturnSize = function()
		return table.getn(Rush.WaitList)
		--[[
		return Size
		]]
	end
	Self.CheckIsEmpty = function()
		return table.getn(Rush.WaitList) == 0
		--[[
		return Size == 0
		]]
	end
	Self.UpdateList = function()
		if Self.CheckIsEmpty == false then
			for a = 1, Self.ReturnSize(), 1 do
				if IsPlayer(Rush.WaitList[a]) ~= 1 or IsPlayer(Rush.WaitList[a]) == nil then
					table.remove(Rush.WaitList, a)
				end
			end
		end
	end
	return Self
end

The commented lines are what KONG helped me with, I tried to modify it a bit to work with the first player in the table, is the one that first registered, if we keep working with last player in table, maybe we will never get to first player in case a really populated server. That's why I modified KONG initial code and was wondering if it will work.

 

Please do note that I have no function to get a player's role with just their name! So I have to store their roles within tables, I created the "UpdateList" function additionally (I don't know if it will work) in order to keep waiting list clean by removing people who are no longer online.

 

Thanks for any help given. 

Edited by Angelix
  • Like 1

Share this post


Link to post
Share on other sites

Your right. A queue (FIFO) is better suited for this operation...

Queue = Queue or {}

Queue.new = function()
    local self = {}
    size, queue = size or 0, queue or {}

    self.enqueue = function(player)
        queue[size+1] = player
        size = size + 1
    end

    self.dequeue = function()
        if self.isEmpty() then
            return
        end
        local a = self.getFront()
        for i = 1, size do
            queue[i] = queue[i+1]
        end
        queue[size] = nil
        size = size - 1
        return a
    end

    self.getFront = function()
        if self.isEmpty() then
            return
        end
        return queue[1]
    end

    self.getSize = function()
        return size
    end

    self.isEmpty = function()
        return size == 0
    end

    return self
end

Which is pretty much the same as yours. 
Edit: Also, the reason i choose not to use table.getn() is because not all Lua version supports that function, especially if upgraded.
if you dont have GetPlayerByName(), i think you can easily use role, as you've provided.


kong.png

a2.png

Share this post


Link to post
Share on other sites

 

Quote

 

* How to handle player's role with registration NPC for 10 players, in case they disconnected or something else happened.

 

 

It is very probably that te player at that point will be released, and then I'm able to hook some events there.

void CGameApp::ReleaseGamePlayer(CPlayer* pPlayer);

That would depend on how complex you want it to be done, I can help with ASM, and isn't hard, but **must be tested with careful.

 

This also maybe has to be handled once the player moves to another map, into the same gameserver.
[map]/[?].lua there should be an event for such purpose, not sure.

 

edit: ---------------------------------------------------

Quote

How to handle map copies.

Dunno, but looking at the source, I found this lua function, which may help

MoveCity( role, "MapName?", N ) -- ???

*I had never used it before.*

Edited by Totoka
  • Like 1

Discord: andresc

Share this post


Link to post
Share on other sites
4 hours ago, KONG said:

That should be all that's left for completion of the map?
If so, show us some gameplay soon !

I got an exam tomorrow and have to turn in some homework by Friday, on the weekend I'll try to adapt the script to work in copies. 

 

Essentially, that's the only two things i can remember having problems back then, if anything arises, I'll ask for help. :P

 

2 hours ago, Totoka said:

 

 

 

It is very probably that te player at that point will be released, and then I'm able to hook some events there.


void CGameApp::ReleaseGamePlayer(CPlayer* pPlayer);

That would depend on how complex you want it to be done, I can help with ASM, and isn't hard, but **must be tested with careful.

 

This also maybe has to be handled once the player moves to another map, into the same gameserver.
[map]/[?].lua there should be an event for such purpose, not sure.

 

edit: ---------------------------------------------------

Dunno, but looking at the source, I found this lua function, which may help

MoveCity( role, "MapName?", N ) -- ???

*I had never used it before.*

I didn't quite get the first thing you talked about, but about the map copies I do have an idea now (I already did some research). 

Share this post


Link to post
Share on other sites

My English still a problem >.<, I'm gonna try again >.>, but shorter

 

Quote

Back then, I had limited knowledge on how to work on a few things.

Past, I get that fact ¬¬

 

In case you need help, due some missing functionality or event; like the one you had problems before (in where the player is being disconnected);

I could try to hook some new lua functions with HEX/ASM into the GameServer.


Cons:
*It may lead to more problems, must be tested with careful.
*everyone who want that feature, must patch the binary.

 

 

  • Like 1

Discord: andresc

Share this post


Link to post
Share on other sites
31 minutes ago, Totoka said:

My English still a problem >.<, I'm gonna try again >.>, but shorter

 

Past, I get that fact ¬¬

 

In case you need help, due some missing functionality or event; like the one you had problems before (in where the player is being disconnected);

I could try to hook some new lua functions with HEX/ASM into the GameServer.


Cons:
*It may lead to more problems, must be tested with careful.
*everyone who want that feature, must patch the binary.

 

 

What's your main language? Haha. 

Anyway, I still have to rewrite almost all the script to adapt it to work on multiple copies of a map. Right now it is based on just one instance, so I'm sure some problems will arise and I'll come back here, haha. I'll use this thread for development and maybe suggestions, when it is done, I'll release it with detailed description on the whole process of what happens inside (as a player) and how to set it on another files. Just hoping everyone will like it. :P

  • Like 1

Share this post


Link to post
Share on other sites
Quote

I got an exam tomorrow

Good luck!

 

Quote

What's your main language?

Spanish O.o

Hola! xD

 

Quote

I'll release it with detailed description on the whole process of what happens inside (as a player) and how to set it on another files. Just hoping everyone will like it.

This project itself sounds good enough.

I will enjoy by looking at the code once you release it; there will new stuff, at least for me, like copy maps in where I haven't any experience


Discord: andresc

Share this post


Link to post
Share on other sites
7 hours ago, KONG said:

Your right. A queue (FIFO) is better suited for this operation...


Queue = Queue or {}

Queue.new = function()
    local self = {}
    size, queue = size or 0, queue or {}

    self.enqueue = function(player)
        queue[size+1] = player
        size = size + 1
    end

    self.dequeue = function()
        if self.isEmpty() then
            return
        end
        local a = self.getFront()
        for i = 1, size do
            queue[i] = queue[i+1]
        end
        queue[size] = nil
        size = size - 1
        return a
    end

    self.getFront = function()
        if self.isEmpty() then
            return
        end
        return queue[1]
    end

    self.getSize = function()
        return size
    end

    self.isEmpty = function()
        return size == 0
    end

    return self
end

Which is pretty much the same as yours. 
Edit: Also, the reason i choose not to use table.getn() is because not all Lua version supports that function, especially if upgraded.
if you dont have GetPlayerByName(), i think you can easily use role, as you've provided.

It seems "table.getn()" was completely removed in Lua 5.3, though think that the server uses 5.1 or 5.2, I have used it before and it works.

57 minutes ago, Totoka said:

Good luck!

 

Spanish O.o

Hola! xD

 

This project itself sounds good enough.

I will enjoy by looking at the code once you release it; there will new stuff, at least for me, like copy maps in where I haven't any experience

Thanks!

 

Por cierto, yo tambien habló español, pero hay que mantener esto en inglés, hahah. 

 

Well, the map copy stuff is pretty easy within v1.x, just a bit more complicated in v2.x because it involves a text file since the function to create copies from v1.x was removes in v2.x, I was having trouble understanding how to correctly modify the text file back then. Now I learned a bit more and managed to get 2 copies working, so I assume I can work with them now. :P

  • Like 2

Share this post


Link to post
Share on other sites

Quick script preview!

function map_run_Rush(Map)
	local CopyID = Rush.AvailableCopy()
	local Func = Rush.WaitFunc()
	if CopyID ~= 0 and Func.ReturnSize() >= Rush.NumPlayer then
		Rush.StartMapCopy(CopyID)
		Rush.MapCopy[CopyID].Time.Init = Rush.Time.Init
		Rush.MapCopy[CopyID].Time.Round = Rush.Time.Round
		Rush.MapCopy[CopyID].Time.Map = Rush.Time.Map
		for a = 1, Rush.NumPlayer, 1 do
			Rush.StartPlayer(Func.GetPlayer(), CopyID)
		end
	end
	Notice("["..Rush.MapName.."]: A new match has started, players in waiting list have been moved into designated map.")
end

I'm merely rewriting the whole script to work with multiple map copies, if you notice something wrong in above script, please do tell me. :P

I'm also making a lot of comments within the script for future release. Currently it's just a rewrite, still need to go through debug testing to see if it fully works.

Share this post


Link to post
Share on other sites

Does anyone know if we can use the "GoTo" function with an applied map copy ID?

 

Somewhat like this:

GoTo(Player, X, Y, Map, MapCopyID)

 

Update: So far everything seems to work fine, I'm just trying to go through debug process by  entering with 2 players instead of 10. Trying to add a bit extra, such as spawning players in a zone with no other players, that's why I need to use a function to send players to some specific coordinates within a specific copy of a map.

Edited by Angelix

Share this post


Link to post
Share on other sites
function GoTo( character, xpos, ypos, mapname )
    if xpos == nil or ypos == nil or mapname == nil then
        MISSDK_NPCSDK_LUA_000056 = GetResString("MISSDK_NPCSDK_LUA_000056")
        return SystemNotice( character, MISSDK_NPCSDK_LUA_000056 )
    end
    return MoveTo( character,  xpos, ypos,  mapname )
end

 

MoveCity( role, "MapName?", N ) 

*that function should do it, but it does not accept coords


Discord: andresc

Share this post


Link to post
Share on other sites
18 minutes ago, Totoka said:

function GoTo( character, xpos, ypos, mapname )
    if xpos == nil or ypos == nil or mapname == nil then
        MISSDK_NPCSDK_LUA_000056 = GetResString("MISSDK_NPCSDK_LUA_000056")
        return SystemNotice( character, MISSDK_NPCSDK_LUA_000056 )
    end
    return MoveTo( character,  xpos, ypos,  mapname )
end

 

MoveCity( role, "MapName?", N ) 

*that function should do it, but it does not accept coords

Yes, that's the problem, haha.

 

I already have setup some spawns for "MoveCity" to work with, but I was trying to add something more. Like if a player gets killed, I wanted to add the option for that player to spawn in another coordinates not surrounded with one or more players so the player doesn't get killed/stunned right away.

Edited by Angelix

Share this post


Link to post
Share on other sites

Maybe by creating a safe-zone instead? dunno how that can be done, but maps like darkblue,garner and magicsea uses these "safe zones"


Discord: andresc

Share this post


Link to post
Share on other sites
31 minutes ago, Totoka said:

Maybe by creating a safe-zone instead? dunno how that can be done, but maps like darkblue,garner and magicsea uses these "safe zones"

Already found a way around it! Create double the spawn points, hahah.

Share this post


Link to post
Share on other sites

Well, reading through S4 League's Chaser mode information again, seems back then I just took the main idea and started adding own ideas, hahah.

 

S4 League's Chaser Mode:

Quote
  • It's a one versus eleven player mode (maybe less if they leave).
  • One player randomly gets chosen as a chaser and gets a buff (attack, maybe defense I guess), can get chosen from many times to none.
  • Chaser must kill every player to get points, two points for killing the target player and two per normal player.
  • Non-chaser players cannot kill each other.
  • Normal players (and target player) get fifteen points for surviving the round, five points per everyother player that survives and two points per X amount of damage dealt to chaser.
  • Normal players may either defend themselves or team up to kill the chaser.
  • The player with highest score (I'm guessing a non-chaser player) will become the target player, when that player dies, the next highest scored player will become the player.

That's what I can gather from internet sources, no telling if the matches ended with chaser being able to kill everyone else or it just keeps going round per round till a match time limit is reached and the winner is based on score gathered.

 

So for my Rush mode, this is what I have:

Quote
  • Amount of players that can enter can vary (a variable that can be changed).
  • A player gets chosen as a chaser, can only be chosen once unless every player has been the chaser once already.
  • Chaser must kill every player, getting X points for target player and Y points per normal player.
  • A player can attack anyone.
  • A target player gets X points for killing the chaser player and Y points per normal player.
  • A normal player gets X points for killing the chaser, Y points for killing the target and Z points per normal player.
  • The highest scored player (non-chaser) becomes the target player, this will get updated often.
  • A match has X amount of time given while a round gets Y amount of time.
  • A round will get terminated once the time ends or the current chaser gets killed.
  • There can be rewards (items, gold, reputation and honor if set) for the chaser, target and normal player.
  • There are two ways to end the match:
    • If the round reaches its time limit and the chaser has killed every player at least once without dying (if he dies, a new round beings with another chaser).
    • The match reaches its time limit, if this happens then the score gets update and no one will get treated as a chaser (no chaser rewards will be given out).

I might be missing something at the base details for the game mode, but I have also included (within scripts) more additional features, such as:

Quote
  • Random respawn can be activated or deactivated, it not active, then player will be revived to a zone where there are no players near by so there won't be an instant kill/stun again.
  • Auto revive function within the map, so players will have to ignore the "revive in town" message for X amount of seconds.
  • A way to remove prolonging effects on players (ex: stealth).

And some more I can't remember right now.

 

So far, what do you guys think is best? I can keep my current script or go for the original (excluding the point per damage given).

  • Like 1

Share this post


Link to post
Share on other sites

Hello @Angelix

 

Quote

A way to remove prolonging effects on players (ex: stealth).

if allows

Quote

Normal players may either defend themselves or team up to kill the chaser.

sounds great; It may also be within map zones, like small traps?

 

 

Quote

Auto revive function within the map, so players will have to ignore the "revive in town" message for X amount of seconds.

1. the map is closed once the match is running?

 

 

Quote
  • If the round reaches its time limit and the chaser has killed every player at least once without dying (if he dies, a new round beings with another chaser).
  • The match reaches its time limit, if this happens then the score gets update and no one will get treated as a chaser (no chaser rewards will be given out).

"If the round reaches its time limit"

Is this rule ignored with -> `he die, a new round begins with another chaser`?

 


Discord: andresc

Share this post


Link to post
Share on other sites

Hello @Totoka!

  • The function to remove certain effects (with duration) is semi implemented, didn't go very much into that detail, yet.
  • This belongs to the original chaser mode from S4 League, not currently in mine.
  • No player can enter the instance once the match has started, players may leave by logging off or using the game's original "revive in town" prompt. This is a multi-instanced map, an instance per match.
  • It was an example, meaning if the match reaches its time limit and the chaser couldn't kill every player within the given time. If the chaser were to die, that means a new round would start if there's still time within the match. I don't know if I explained myself correctly, hahah.

Share this post


Link to post
Share on other sites
Quote

This belongs to the original chaser mode from S4 League, not currently in mine.

Dunno, I had never played it, some friends told me about that game, which they played it before the publisher close the doors to SA, a few years ago (can't remember well that part).

 

Quote

It was an example, meaning if the match reaches its time limit and the chaser couldn't kill every player within the given time. If the chaser were to die, that means a new round would start if there's still time within the match. I don't know if I explained myself correctly, hahah.

Yeah xD

 

I had the idea of an infinite loop before you mentioned that fact >.<


Discord: andresc

Share this post


Link to post
Share on other sites

Well, I might be releasing maybe to a few people to test and help me debug the script, everything should be working so far after many error randomly popping up in lua_err.txt, haha. It's still kinda a messy script with SO MANY functions, I still wonder if they're all necessary, hahah. 

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

×
×
  • Create New...