Jump to content

Add forced next map to votemanager


koragg

Recommended Posts

I got this code but I'm not really sure how to edit it so that it works for me. Idea is to show votemanager after a map ends even if next map is set from admin panel or bought from a 3rd-party script. This is the part which needs editing but whatever I try doesn't work. No errors in debug but no votemanager either.

if getResourceFromName('gcshop') and getResourceState(getResourceFromName('gcshop')) == 'running' and exports.gcshop:isAnyMapQueued(true) and skipMapQueue ~= exports.mapmanager:getRunningGamemodeMap() then
		-- GCshop next queued map
		-- [1] = mapName, [2] = mapResName, [3] = gamemode, [4] = playername
		local map = exports.gcshop:getCurrentMapQueued(true)
		local mapRes = getResourceFromName(map[2])
		if map and mapRes then
			local mapName = getResourceInfo(mapRes, "name") or getResourceName(mapRes)
			local mapName = "[Maps-Center] "..mapName

			table.insert(poll, {mapName , 'nextMapVoteResult', getRootElement(), mapRes,map[4]})
			usedGcMapQueue = true
		else-- normal next map
			local mapName = getResourceInfo(_nextMap, "name") or getResourceName(_nextMap)
			table.insert(poll, {mapName , 'nextMapVoteResult', getRootElement(), _nextMap})
		end
	else -- Normal next map
		local mapName = getResourceInfo(_nextMap, "name") or getResourceName(_nextMap)
			table.insert(poll, {mapName , 'nextMapVoteResult', getRootElement(), _nextMap})
	end

The thing that makes this hard for me is that I don't know how to include the next map set from admin panel or by the buymap script  into the votemanager as obviosly "getCurrentMapQueued" belongs to another resource which I cannot use. 

Edited by koragg
racevoting_server.lua btw^
Link to comment
49 minutes ago, LoPollo said:

 

Can't you export it? edit the meta of that resource 

And how are you showing the votemanager? by using executeCommandHandler? i don't even remember if there was a command...

The votemanager is used with this " table.insert" when the current map ends, no commands or anything.

I can't export that function as it uses another server's SQL database and won't work if I export it.

I need the g_ForcedNextMap (I assume) to be added to the votemanager rather than for it starting immediatly after current one ends.

Edited by koragg
Link to comment
15 minutes ago, koragg said:

I can't export that function as it uses another server's SQL database and won't work if I export it.

If you export it shouldn't the enviroment of that function still be the resource that export the function itself? (because i'm sure it's like that)

or the problem is it has a parameter bound to the sql db?

or was just an example?

EDIT: ops i think i now understand: you need an equivalent of that func of gcshop from the admin panel or buyscript. Did i understand right?

Edited by LoPollo
Link to comment
1 hour ago, LoPollo said:

If you export it shouldn't the enviroment of that function still be the resource that export the function itself? (because i'm sure it's like that)

or the problem is it has a parameter bound to the sql db?

or was just an example?

EDIT: ops i think i now understand: you need an equivalent of that func of gcshop from the admin panel or buyscript. Did i understand right?

I think so, here it is.

function getCurrentMapQueued(noRemove)
    if #myQueue == 0 then
        return false
    end
    if not getResourceFromName(myQueue[1][2]) then
        outputChatBox("[Maps-Center] ERROR: QUEUED MAP MAY HAVE BEEN DELETED BEFORE IT WAS PLAYED. CONTACT ADMIN FOR REFUND.", root, 255, 0, 0)
        return false
    end
    local choice = myQueue[1]
    if not noRemove then
        table.remove(myQueue, 1)
        if #myQueue > 0 then
            triggerEvent('onNextmapSettingChange', root, getResourceFromName(myQueue[1][2]))
        end
    end
    return choice
end

Everything there is linked with 1000 other things so it'll be better if we use default mta functions/methods/idk what. But idk how to get the nextmap and put it in the votemanager.

Edited by koragg
Link to comment

In racevoting_server.lua I edited "startNextMapVote()" function to this but still voter isn't showing when a player buys it or admin sets it :\

function startNextMapVote()

	exports.votemanager:stopPoll()

	-- Handle forced nextmap setting
	if maybeApplyForcedNextMap() then
		return
	end

	
	local poll = {
		title="Next or Play again?",
		visibleTo=getRootElement(),
		percentage=51,
		timeout=5,
		allowchange=true;
		}
	
	local usedGcMapQueue = false
	
	if getResourceFromName('scoringsystem') and getResourceState(getResourceFromName('scoringsystem')) == 'running' then
		if g_ForcedNextMap and getResourceFromName(g_ForcedNextMap) then
			local mapName = getResourceInfo(getResourceFromName(g_ForcedNextMap), "name") or getResourceName(getResourceFromName(g_ForcedNextMap))
			local mapName = "[Maps-Center] "..mapName
			table.insert(poll, {mapName , 'nextMapVoteResult', getRootElement(), getResourceFromName(g_ForcedNextMap)})
		else-- normal next map
			local mapName = getResourceInfo(_nextMap, "name") or getResourceName(_nextMap)
			table.insert(poll, {mapName , 'nextMapVoteResult', getRootElement(), _nextMap})
		end
	else -- Normal next map
		local mapName = getResourceInfo(_nextMap, "name") or getResourceName(_nextMap)
		table.insert(poll, {mapName , 'nextMapVoteResult', getRootElement(), _nextMap})
	end
	
	local currentMap = exports.mapmanager:getRunningGamemodeMap()
	local currentRes = currentMap
	if currentMap then
		if not times[currentMap] or times[currentMap] < maxPlayAgain+1 then
			table.insert(poll, {"Play again", 'nextMapVoteResult', getRootElement(), currentMap})
		elseif usedGcMapQueue then -- Start GC mapcenter map
			outputChatBox('Maximum \'Play Again\' times('..maxPlayAgain..') has been reached. Changing to next map in Maps-Center queue ...')
			
			local map = exports.gcshop:getCurrentMapQueued()
			if not exports.mapmanager:changeGamemodeMap ( getResourceFromName(map[2]), nil, true ) then
				outputWarning( 'Forced next map failed' )
				startRandomMap()
			else
				outputChatBox("[Maps-Center] Starting queued map for " .. map[4], root, 0, 255, 0)
			end
			skipMapQueue = getResourceFromName(map[2])
			return
		else
			outputChatBox('Maximum \'Play Again\' times('..maxPlayAgain..') has been reached. Changing to random ...')
			startRandomMap()
			return
		end	
	end

	-- Allow addons to modify the poll
	g_Poll = poll
	triggerEvent('onPollStarting', g_Root, poll )
	poll = g_Poll
	g_Poll = nil

	local pollDidStart = exports.votemanager:startPoll(poll)

	if pollDidStart then
		gotoState('NextMapVote')
		addEventHandler("onPollEnd", getRootElement(), chooseRandomMap)
	end

	return pollDidStart
end

The things I did are from line 21 to line 33.

Edited by koragg
Link to comment
  • 2 weeks later...

I got almost everything working, but there is one bug I can't seem to fix myself.

When a player buys a map, it gets imported into the map voter forever meaning every time it's the same map as a voting choice.

setElementData(resourceRoot, "keepnextmap", g_ForcedNextMap)

This^ is how I got the bought map to include it into the voter system.

setElementData(resourceRoot, "keepnextmap", nil)

This^ resets the map data but I don't know where to put it (or what condition to create) so that when the bought map starts and players finish it, voter would work as normal and show a random map into it.

Here is the part of code I made:

if not getElementData(resourceRoot, "keepnextmap") then
		local mapName = getResourceInfo(_nextMap, "name") or getResourceName(_nextMap)
		table.insert(poll, {mapName , 'nextMapVoteResult', getRootElement(), _nextMap})
	end
	
	local currentMap = exports.mapmanager:getRunningGamemodeMap()
	local currentRes = currentMap
	if currentMap then
		if not times[currentMap] or times[currentMap] < maxPlayAgain+1 then
			if getElementData(resourceRoot, "keepnextmap") then
				local NextMapData = getElementData(resourceRoot, "keepnextmap")
				local NextMapFix = getResourceInfo(NextMapData, "name") or getResourceName(NextMapData)
				NextMapFix = "[Maps-Center] "..NextMapFix
				table.insert(poll, {NextMapFix , 'nextMapVoteResult', getRootElement(), NextMapData})
			end
			table.insert(poll, {"Play Again", 'nextMapVoteResult', getRootElement(), currentMap})
		elseif times[currentMap] >= maxPlayAgain+1 then
			if getElementData(resourceRoot, "keepnextmap") then
				local NextMapData = getElementData(resourceRoot, "keepnextmap")
				local NextMapFix = getResourceName(NextMapData)
				local StartNextMap = getResourceFromName(NextMapFix)
				startResource(StartNextMap)
				setElementData(resourceRoot, "keepnextmap", nil)
				outputChatBox("Maximum 'Play Again' times ("..maxPlayAgain..") was reached. Starting next map from Maps-Center.", root, 255, 255, 255, true)
			else
				startRandomMap()
				setElementData(resourceRoot, "keepnextmap", nil)
				outputChatBox("Maximum 'Play Again' times ("..maxPlayAgain..") was reached. Changing to a random map...", root, 255, 255, 255, true)
				return
			end
		end
	end

Hope I get some help with this, the above thing is the only bug left :)

 

PS I tried to compare "currentMap" with "getElementData(resourceRoot, "keepnextmap")" but didn't work.

Edited by koragg
[race]-racevoting_server.lua
Link to comment

So you fixed the problem of "importing" the map in the votemanager? contrats!

EDIT: deleted part of the post, stupid things were said there...

So you want to reset the keepnextmap data when the race specified in keepnextmap is played and finished (not when a (general) race is finished)

Off topic: But are you sure keepnextmap will not get overwritten?

 

on topic: What's printed outputting the values you get getting the element data?

Edited by LoPollo
Link to comment
--If no map is set as next
--	insert into the poll some map
--/
--If a map is running do something...
--	if it hasn't reached the max play times
--		let's do the poll
--		 if there's a nextmap kept as data
--			add that map to the poll
--		add to the poll the "play again" since the current map can be played again
--	otherwise, if the map is at max plays number,
--		we must start a map, regardeless of the poll
--		so if there's a next map kept,
--			start it
--		otherwise
--			start a random map
--		/
--	/
--/

Is this logic right?

Edited by LoPollo
Link to comment
2 hours ago, LoPollo said:

--If no map is set as next
--	insert into the poll some map
--/
--If a map is running do something...
--	if it hasn't reached the max play times
--		let's do the poll
--		 if there's a nextmap kept as data
--			add that map to the poll
--		add to the poll the "play again" since the current map can be played again
--	otherwise, if the map is at max plays number,
--		we must start a map, regardeless of the poll
--		so if there's a next map kept,
--			start it
--		otherwise
--			start a random map
--		/
--	/
--/

Is this logic right?

Yes, everything that you described works. It's just that, for example:

I am currently playing a map called "Warm Up 2", I win it and buy another map called "An Xmas Present". When the map vote window shows the two options are "[Maps-Center] An Xmas Present" and "Play Again". This works perfectly.

I am currently playing a map called "Warm Up 2", I buy a map ("An Xmas Present"), but people vote for play again on the current map. When the second round of the map "Warm Up 2" ends, the votemanager puts "[Maps-Center] An Xmas Present" and "Play Again" as vote options. This works perfectly.

And now, I am playing the map "Warm Up 2", which was bought by someone. There is no next map bought now. When "Warm Up 2" ends, the votemanager puts as vote options the following things: "[Maps-Center] Warm Up 2" and "Play Again". Now this is the problem I'm facing. I need the elementdata to reset to 'nil' when a map other than the bought one starts.

 

Explanation: If I have bought a map but people vote 1 and that map does not get replayed 2 times (which in most cases it won't), after that the voter should show a randomly picked map as the first option. Right now it always adds the bought map as next until it gets replayed 2 times and a random one auto-starts (then the elementdata becomes 'nil').

Edited by koragg
yes I'm sure "keepnextmap" won't get overwritten as I made it specifically for this use only. And nothing gets printed when I output the elementdata (says 'string expected, got resource-data')
Link to comment
if not getElementData(resourceRoot, "keepnextmap") then
	local mapName = getResourceInfo(_nextMap, "name") or getResourceName(_nextMap)
	table.insert(poll, {mapName , 'nextMapVoteResult', getRootElement(), _nextMap})
end

The problem may be here (quote above) or in the poll end: do you set the keepnextmap to nil when that map is voted?

For example, if the map setted as nextmap (keepnextmap) is "premiumMap", this "premiumMap" map will get inserted into the poll (assume the current map hasn't reached the play number limit). When the poll ends, out of "premiumMap" and "Play again", the voted map is "premiumMap". 

If the keepnextmap is not resetted here (when the map starts/poll ends) or when the map ends (race finished) then the data is present when the poll starts again, and the current map has NOT reached the limit (number of plays).

 

If you set the data to nil in the case related to the above example, then the code in the quote will get executed, which will add to the poll _nextMap. Double check that _nextMap is NOT the resource of the map in the map previously stored under key keepnextmap.

 

PS: forgive for any errors, here it's 2326 and i'm tired. So in case of stupid things i'm sorry (i say a lot of stupid things because i easily forget little, but still important things)

Link to comment
11 minutes ago, LoPollo said:

if not getElementData(resourceRoot, "keepnextmap") then
	local mapName = getResourceInfo(_nextMap, "name") or getResourceName(_nextMap)
	table.insert(poll, {mapName , 'nextMapVoteResult', getRootElement(), _nextMap})
end

do you set the keepnextmap to nil when that map is voted?

I don't, no. If I set it to 'nil' on vote end then what if current map gets replayed 2 times. The bought one will get reset to nil after the first time current map ends so rip coins for player who bought map + the map he bought just won't start then as data will be 'nil'. By not setting data to 'nil' on pol end, i assure people that their map will continue to be the vote option even if the current map gets played 2 times in a roll :) But yea...infinitely same vote bug happens then. Can't i try to somehow compare the maps? Like: 

if currentmap ~= getElementData(blahblah) then

setelementdata(resroot, nil)

end

Here is 00:44 so you forgive me for the lazy code typing xD I'm sleepy..

Link to comment

You only nil the data if the winner map is the same as the one in keepnextmap

 

8 hours ago, koragg said:

if currentmap ~= getElementData(blahblah) then

setelementdata(resroot, nil)

end

Yes it will work, but the currentmap and the data should be EQUAL and not different.

It's the basically same thing of what i was saying:

- on poll end, pick the winner map, nil the data IF the winner map is the one in keepnextmap, start the map

vs

- on map start check if currentMap is the same as the keepnextmap, and if true nil the data.

 

It's the third time i write this since i'm at school and the connection here sucks -.- sorry if i omitted something and let me know

  • Like 1
Link to comment
addEvent("onMapStarting") 
function nilMapData()
	if exports.mapmanager:getRunningGamemodeMap() == getElementData(resourceRoot, "keepnextmap") then
		setElementData(resourceRoot, "keepnextmap", nil)
	end
end
addEventHandler("onMapStarting", getRootElement(), nilMapData)

This worked :)

  • Like 1
Link to comment

OK, now if I buy a map and we replay the current one, another player can just buy other map when we're at the second round of the current map and rip mine wtf xD

This is how people buy maps:

addEvent("onPlayerFinish", true)
addEventHandler("onPlayerFinish", getRootElement(),
function(rank)
	if rank == 1 then
		for i,v in ipairs(getElementsByType("player"))do
			setElementData(v, "data.hasWon", false)
			setElementData(source, "data.hasBoughtNextmap", false)
		end
		setElementData(source, "data.hasWon", true)
		setElementData(source, "data.hasBoughtNextmap", false)
	end
end)
-------------------------------------------------------------------------------------------------------------------------
function setNextMap(mapName)
	local playername = getPlayerName(source)
	local playeraccount = getPlayerAccount(source)
	local res = getResourceFromName("cw")
	if getResourceState(res) == "running" then
	outputChatBox("You are not allowed to buy maps while the ClanWarSystem is active!", source, 255, 0, 0, true)
	return
	end
	if isGuestAccount(playeraccount) then
	outputChatBox("You need to register and login in order to buy a map as next!", source, 255,153,0)
	return
	end
	if not isGuestAccount(playeraccount) then
	    if not getElementData(source, "data.hasWon") then
	    outputChatBox("You need to win in order to buy a map as next!", source, 255,153,0)
		return
	    end
		if ( playeraccount ) and not isGuestAccount ( playeraccount ) then
		coins = tonumber(getAccountData(playeraccount, "knightcoins") or 0)
		
      if getElementData(source, "data.hasBoughtNextmap") == false then
		if coins >= 500 then
			coins = coins - 500
			executeCommandHandler("mapSatinAl", source, mapName)
			setAccountData ( playeraccount, "knightcoins", coins )
			setElementData ( source ,"data.knightcoins", coins, true)
			setElementData(source, "data.hasBoughtNextmap", true)
		else
			outputChatBox("You don't have enough KnightCoins to buy a map as next!", source, 255,153,0)
			setElementData(source, "data.hasBoughtNextmap", false)
		end
	  else
	  outputChatBox("A map is already set. Please wait until it's played first!", source, 255,153,0)
	  end
	  end
	end
end
addEvent("mapSatinAlServer", true)
addEventHandler("mapSatinAlServer", getRootElement(),setNextMap)

Don't think I can compare maps as before here (tried and didn't work, no errors though).

Edited by koragg
Link to comment
18 hours ago, LoPollo said:

Off topic: But are you sure keepnextmap will not get overwritten?

Lol

This includes: what if 2 maps are bought (even before starting the first time a bought map)?

 

I think there are a huge numbers of ways to "solve" this. Disabling buying maps if a bough map is running? nexmap is no more a variable but a table which is used as a queue? Simply letting the previous map get overwritten and maybe a refund? Let 2 maps be bought and simply ignore the one which is not voted (basically it can become a waste of money)? there are hunderds of solutions...

 

A very simple solution* is that you pay for playing the map once, seeing the "play again" as a chance to get that map replayed. If it will be played only once cause another map is bought, then you still had what you paid for.

 

*There's still a problem. as above,  what if 2 maps are bought before starting for the first time a bought map?

Edited by LoPollo
Link to comment
43 minutes ago, LoPollo said:

This includes: what if 2 maps are bought (even before starting the first time a bought map)?

if getElementData(source, "data.hasBoughtNextmap") == false then
	take coins
	buy map and set as next
else
	 outputChatBox("A map is already set. Please wait until it's played first!", source, 255,153,0)
end

Thanks to this part of the code noone can buy a map as long as there is a bought one waiting to be played. (But this gets reset on map start)

Well yea, I need some easy way to just show a chatbox msg saying that a map cannot be bought before the already bought one starts.

Edited by koragg
Link to comment

@LoPollo, I meant normal chatbox msg ;d

Easy way to cancel buying map and to show chatbox msg if a player tries to buy a map but the already bought one (by somebody else) has not started yet.

That way nobody will be able to buy a map unless the already bought one (by somebody else) starts, then data for boughtmap goes to nil and pretty much as in the votemanager thing.

Edited by koragg
nice resource though (:
Link to comment

OK I didn't wanna do this but it left me no choice. I merged the file responsible for buying maps into racevoting_server.lua, did few conditions and now works perfect! :) But I'm pretty sure I'll forget where everything is, that's why I didn't want to merge it but, oh well, fixed.

Link to comment
50 minutes ago, LoPollo said:

A note: since it's in a default resource, keep a copy of the merged resource. It's possible that with an update the defaults resources will be overwritten.

Yea, I just commented the other file, didn't delete it, but thx for the tip :)

Edited by koragg
The only way I can update my server is manually though, as I have different MTA for playing.
Link to comment

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...