PDA

View Full Version : LUA server "plugins"


Agent Buckshot Moose
06-15-2013, 12:42 AM
Is it possible to:

1. Make a lua file that affects all maps of a certain game mode, either by a specially recognized filename, a symbolic link, etc?
2. Make a plugin that does things based on number of players in the server, e.g. if number of player is >= X, do action Y. If number of players is < X, do action Z?

squeek.
06-15-2013, 04:41 AM
1. A few possibilities:

map .cfg files (cfg/ff_dustbowl.cfg, cfg/ff_ksour.cfg, etc) that set sv_globalluascript and a server.cfg that resets it to blank or something else
add an IncludeScript() line to the gametype's base include (base_ad, etc) that includes your file
maybe more than I can't think of right now

2. Absolutely. This will count only players on a playable team (blue through green):

local numplayers = 0
for team_id = Team.kBlue, Team.kGreen do
numplayers += GetTeam( team_id ):GetNumPlayers()
end

Including spectators:

local numplayers = 0
for team_id = Team.kSpectator, Team.kGreen do
numplayers += GetTeam( team_id ):GetNumPlayers()
end

Including spectators and unassigned:

local numplayers = 0
for team_id = Team.kUnassigned, Team.kGreen do
numplayers += GetTeam( team_id ):GetNumPlayers()
end


EDIT: To react to changes in player number immediately, you can use the callback functions player_disconnected( player ) and player_switchteam( player, old_team_id, new_team_id )

Agent Buckshot Moose
06-15-2013, 02:05 PM
Next question: looking at the documentation for SetTeamClassLimit and SetSmartClassLimit, it says those must go in the startup() function. Is it possible to change class limits via the callback?

Edit: like a simple function that sets a server-side cvar. I see one that sets player cvar, but not one that sets server cvars.

squeek.
06-15-2013, 06:54 PM
Class limits can be changed anytime using those functions. The "must be in startup" thing is just for setting up the initial class limits.

To set a server cvar, you can use SetConvar( convar, value )

EDIT: Changing class limits won't immediately enforce those limits (it'll just make it so players wouldn't be able to choose/switch to that class afterwards). To enforce the limit immediately, you'd have to manually switch players playing the now-forbidden class(es) using ApplyToPlayer( player, { AT.kChangeClassSolder, AT.kRespawnPlayers } ) or something like that.

This sort of thing is done in ff_ksour to disable scouts on Defense.

EDIT#2: The ksour code:
in player_spawn:
-- wtf, scout or med on d? are you mental?
if (player:GetClass() == Player.kScout or player:GetClass() == Player.kMedic) and (player:GetTeamId() == defenders) then
local classt = "Scout"
if player:GetClass() == Player.kMedic then classt = "Medic" end
local id = player:GetId()
AddSchedule("force_changemessage"..id, 2, schedulechangemessage, player, "No "..classt.."s on defense. Autoswitching to Soldier." )
AddSchedule("force_change"..id, 2.5, forcechange, player)
end

The scheduled forcechange function:

-- force a scout/med to switch to soli if they haven't
function forcechange( player )
if (player:GetClass() == Player.kScout or player:GetClass() == Player.kMedic) and (player:GetTeamId() == defenders) then
ApplyToPlayer( player, { AT.kChangeClassSoldier, AT.kRespawnPlayers } )
end
end

squeek.
06-15-2013, 07:08 PM
By the way, for this sort of thing, understanding and using the concepts in this thread: Altering functions without overwriting them (http://forums.fortress-forever.com/showthread.php?t=23070) is quite important.

If done right, it'll allow you to use the Lua on any map without breaking anything. If you overwrite an important function like startup, though, things could really break (or if you copy+paste a specific startup function then it'll only work for some maps).

It's still not a perfect system, and the base includes should be restructured to allow for easier/more robust manipulating, but that hasn't happened yet.