factions/factions.lua

1402 lines
43 KiB
Lua
Raw Normal View History

2016-07-30 07:38:52 +02:00
--read some basic information
2016-08-07 19:31:11 +02:00
local factions_worldid = minetest.get_worldpath()
2016-07-30 07:38:52 +02:00
2016-08-07 19:31:11 +02:00
--! @class factions
--! @brief main class for factions
factions = {}
2016-07-30 07:38:52 +02:00
--! @brief runtime data
2016-08-07 19:31:11 +02:00
factions.factions = {}
2016-08-14 15:53:40 +02:00
factions.parcels = {}
2016-08-07 19:31:11 +02:00
factions.players = {}
2016-07-30 07:38:52 +02:00
2016-08-07 02:11:17 +02:00
---------------------
--! @brief returns whether a faction can be created or not (allows for implementation of blacklists and the like)
2016-08-12 11:16:43 +02:00
--! @param name String containing the faction's name
2016-08-07 19:31:11 +02:00
factions.can_create_faction = function(name)
2018-10-18 04:04:46 +02:00
if #name > factions_config.faction_name_max_length then
2016-08-18 15:26:19 +02:00
return false
elseif factions.factions[name] then
2016-08-07 02:11:17 +02:00
return false
else
return true
2016-08-07 19:36:56 +02:00
end
2016-08-07 02:11:17 +02:00
end
factions.Faction = {
}
util = {
coords3D_string = function(coords)
return coords.x..", "..coords.y..", "..coords.z
end
}
factions.Faction.__index = factions.Faction
2018-10-31 22:15:08 +01:00
starting_ranks = {["leader"] = {"build","door","container","name","description","motd","invite","kick"
,"title","set_spawn","unset_spawn","with_draw","territory","claim","access","disband","flags","create_ranks","edit_ranks","delete_ranks","set_def_ranks","reset_ranks","promote"},
["moderator"] = {"claim","door","build","set_spawn","invite","kick","promote"},
["member"] = {"build","container","door"}
}
2016-08-12 11:16:43 +02:00
-- Faction permissions:
--
-- build: dig and place nodes
2018-10-31 22:15:08 +01:00
-- pain_build: dig and place nodes but take damage doing so
-- door: open/close or dig doors
-- container: be able to use containers like chest
-- name: set the faction's name
-- description: Set the faction description
-- motd: set the faction's message of the day
-- invite: (un)invite players to join the faction
-- kick: kick players off the faction
-- title: set territory titles
-- set_spawn: set the faction's spawn
-- unset_spawn: delete the faction's spawn
-- with_draw: withdraw money from the faction's bank
-- spawn: be able to teleport to the faction's spawn
-- territory: claim or unclaim territory
-- claim: (un)claim parcels of land
-- access: manage access to territory and parcels of land to players or factions
-- disband: disband the faction
-- flags: manage faction's flags
-- create_ranks: create new ranks
-- edit_ranks: edit rank name and permissions
-- delete_ranks: delete ranks
-- set_def_ranks: set the default rank given to new players
-- reset_ranks: reset the ranks back to the default ones
2016-08-12 11:16:43 +02:00
-- promote: set a player's rank
2018-10-31 22:15:08 +01:00
-- declare_war: be able to declare war with another faction
-- neutral: be able to send a neutral request to another faction
-- alliance: be able to send a alliance request to another faction and break alliance treaties too
-- accept_treaty: be able to accept a treaty request from another faction
-- refuse_treaty: be able to refuse a treaty request from another faction
factions.permissions = {"build","pain_build","door","container","name","description","motd","invite","kick"
,"title","set_spawn","unset_spawn","with_draw","territory","claim","access","disband","flags","create_ranks","edit_ranks","delete_ranks","set_def_ranks","reset_ranks","promote"}
factions.permissions_desc = {"dig and place nodes","dig and place nodes but take damage doing so","open/close or dig","be able to use containers like chest","set the faction's name"
,"Set the faction description","set the faction's message of the day","(un)invite players to join the faction","kick players off the faction","set territory titles","set the faction's spawn"
,"delete the faction's spawn","withdraw money from the faction's bank","claim or unclaim territory","(un)claim parcels of land","manage access to territory and parcels of land to players or factions"
,"disband the faction","manage faction's flags","create new ranks","edit rank permissions","delete ranks","set the default rank given to new players","reset the ranks back to the default ones","set a player's rank"}
-- open: can the faction be joined without an invite?
-- monsters: can monsters spawn on your land?
-- tax_kick: will players be kicked for not paying tax?
-- animals: can animals spawn on your land?
factions.flags = {"open","monsters","tax_kick","animals"}
factions.flags_desc = {"can the faction be joined without an invite?","can monsters spawn on your land?(unused)","will players be kicked for not paying tax?(unused)","can animals spawn on your land?(unused)"}
if factions_config.faction_diplomacy == true then
table.insert(factions.permissions,"declare_war")
table.insert(factions.permissions,"neutral")
table.insert(factions.permissions,"alliance")
table.insert(factions.permissions,"accept_treaty")
table.insert(factions.permissions,"refuse_treaty")
table.insert(factions.permissions_desc,"be able to declare war with another faction")
table.insert(factions.permissions_desc,"be able to send a neutral request to another faction")
table.insert(factions.permissions_desc,"be able to send a alliance request to another faction and break alliance treaties too")
table.insert(factions.permissions_desc,"be able to accept a treaty request from another faction")
table.insert(factions.permissions_desc,"be able to refuse a treaty request from another faction")
local lt = starting_ranks["leader"]
table.insert(lt,"declare_war")
table.insert(lt,"neutral")
table.insert(lt,"alliance")
table.insert(lt,"accept_treaty")
table.insert(lt,"refuse_treaty")
starting_ranks["leader"] = lt
end
2018-10-15 17:24:58 +02:00
2018-10-31 22:15:08 +01:00
if factions_config.spawn_teleport == true then
table.insert(factions.permissions,"spawn")
table.insert(factions.permissions_desc,"be able to teleport to the faction's spawn")
table.insert(starting_ranks["leader"],"spawn")
table.insert(starting_ranks["moderator"],"spawn")
table.insert(starting_ranks["member"],"spawn")
2018-10-15 17:24:58 +02:00
end
function factions.Faction:new(faction)
faction = {
2018-10-31 22:15:08 +01:00
name = "",
2016-08-14 15:53:40 +02:00
--! @brief power of a faction (needed for parcel claiming)
2018-10-18 04:04:46 +02:00
power = factions_config.power,
2016-08-12 11:16:43 +02:00
--! @brief maximum power of a faction
2018-10-18 04:04:46 +02:00
maxpower = factions_config.maxpower,
--! @brief power currently in use
usedpower = 0.,
2016-08-12 11:16:43 +02:00
--! @brief list of player names
2016-08-07 02:11:17 +02:00
players = {},
2018-10-17 04:58:15 +02:00
--! @brief list of player names online
onlineplayers = {},
--! @brief list of player names offline
offlineplayers = {},
2016-08-12 11:16:43 +02:00
--! @brief table of ranks/permissions
2018-10-31 22:15:08 +01:00
ranks = starting_ranks,
2016-08-12 11:16:43 +02:00
--! @brief name of the leader
2016-08-07 02:11:17 +02:00
leader = nil,
2018-10-31 22:15:08 +01:00
--! @brief spawn of the faction
spawn = {x=0, y=0, z=0},
2016-08-12 11:16:43 +02:00
--! @brief default joining rank for new members
2016-08-07 02:11:17 +02:00
default_rank = "member",
2016-08-12 11:16:43 +02:00
--! @brief default rank assigned to the leader
2016-08-07 02:11:17 +02:00
default_leader_rank = "leader",
2016-08-12 11:16:43 +02:00
--! @brief faction's description string
2016-08-07 02:11:17 +02:00
description = "Default faction description.",
2018-10-25 07:21:42 +02:00
--! @brief faction's message of the day.
message_of_the_day = "",
2016-08-12 11:16:43 +02:00
--! @brief list of players currently invited (can join with /f join)
2016-08-07 02:11:17 +02:00
invited_players = {},
2016-08-14 15:53:40 +02:00
--! @brief table of claimed parcels (keys are parcelpos strings)
2016-08-07 02:11:17 +02:00
land = {},
2016-08-12 11:16:43 +02:00
--! @brief table of allies
2016-08-07 02:11:17 +02:00
allies = {},
2018-10-15 17:24:58 +02:00
--
request_inbox = {},
2016-08-12 11:16:43 +02:00
--! @brief table of enemies
2016-08-07 02:11:17 +02:00
enemies = {},
2018-10-15 17:24:58 +02:00
--!
2018-10-18 07:15:26 +02:00
neutral = {},
2016-08-14 15:53:40 +02:00
--! @brief table of parcels/factions that are under attack
attacked_parcels = {},
2016-08-12 11:16:43 +02:00
--! @brief whether faction is closed or open (boolean)
2018-10-31 22:15:08 +01:00
join_free = false,
2016-08-17 22:28:12 +02:00
--! @brief gives certain privileges
is_admin = false,
2018-10-30 01:16:39 +01:00
--! @brief if a player on the faction has a nil rank
rankless = false,
--! @brief last time anyone logged on
last_logon = os.time(),
2018-10-15 17:24:58 +02:00
--! @brief how long this has been without parcels
no_parcel = os.time(),
} or faction
setmetatable(faction, self)
return faction
end
2016-08-07 02:11:17 +02:00
2016-08-12 11:16:43 +02:00
--! @brief create a new empty faction
2018-10-31 22:15:08 +01:00
function factions.new_faction(name,do_not_save)
local faction = factions.Faction:new(nil)
faction.name = name
2016-08-07 19:36:56 +02:00
factions.factions[name] = faction
faction:on_create()
2018-10-18 04:31:07 +02:00
minetest.after(1,
function(f)
f:on_no_parcel()
end,faction)
2018-10-31 22:15:08 +01:00
if not do_not_save then
factions.save()
end
2016-08-07 02:11:17 +02:00
return faction
end
function factions.start_diplomacy(name,faction)
2018-10-31 22:15:08 +01:00
for i,fac in pairs(factions.factions) do
if i ~= name and not (faction.neutral[i] or faction.allies[i] or faction.enemies[i]) then
faction:new_enemy(i)
2018-10-31 22:15:08 +01:00
fac:new_enemy(name)
end
end
end
2018-10-31 22:15:08 +01:00
function factions.Faction.set_name(self, name)
local oldname = self.name
local oldfaction = factions.factions[oldname]
self.name = name
for i,fac in pairs(factions.factions) do
if i ~= oldname then
if fac.neutral[oldname] then
fac.neutral[oldname] = nil
fac.neutral[name] = true
end
if fac.allies[oldname] then
fac.allies[oldname] = nil
fac.allies[name] = true
end
if fac.enemies[oldname] then
fac.enemies[oldname] = nil
fac.enemies[name] = true
end
end
end
for parcel in pairs(self.land) do
factions.parcels[parcel] = self.name
end
for playername in pairs(self.players) do
factions.players[playername] = self.name
end
factions.factions[oldname] = nil
factions.factions[name] = oldfaction
factions.factions[name].name = name
for playername in pairs(self.onlineplayers) do
updateFactionName(playername,name)
end
self:on_set_name(oldname)
factions.save()
end
function factions.Faction.increase_power(self, power)
self.power = self.power + power
if self.power > self.maxpower - self.usedpower then
self.power = self.maxpower - self.usedpower
end
2018-10-17 04:58:15 +02:00
for i in pairs(self.onlineplayers) do
updateHudPower(minetest.get_player_by_name(i),self)
end
factions.save()
end
function factions.Faction.decrease_power(self, power)
self.power = self.power - power
2018-10-17 04:58:15 +02:00
for i in pairs(self.onlineplayers) do
updateHudPower(minetest.get_player_by_name(i),self)
end
factions.save()
end
function factions.Faction.increase_maxpower(self, power)
self.maxpower = self.maxpower + power
2018-10-17 04:58:15 +02:00
for i in pairs(self.onlineplayers) do
updateHudPower(minetest.get_player_by_name(i),self)
end
factions.save()
end
function factions.Faction.decrease_maxpower(self, power)
self.maxpower = self.maxpower - power
if self.maxpower < 0. then -- should not happen
self.maxpower = 0.
end
2018-10-17 04:58:15 +02:00
for i in pairs(self.onlineplayers) do
updateHudPower(minetest.get_player_by_name(i),self)
end
end
function factions.Faction.increase_usedpower(self, power)
self.usedpower = self.usedpower + power
2018-10-17 04:58:15 +02:00
for i in pairs(self.onlineplayers) do
updateHudPower(minetest.get_player_by_name(i),self)
end
end
function factions.Faction.decrease_usedpower(self, power)
self.usedpower = self.usedpower - power
if self.usedpower < 0. then
self.usedpower = 0.
end
2018-10-17 04:58:15 +02:00
for i in pairs(self.onlineplayers) do
updateHudPower(minetest.get_player_by_name(i),self)
end
end
-- power-per-players only.
function factions.Faction.check_power(self)
if factions_config.enable_power_per_player then
for player,unused in pairs(self.players) do
local ip = factions_ip.player_ips[player]
local notsame = true
for i,k in pairs(self.players) do
local other_ip = factions_ip.player_ips[k]
if other_ip == ip then
notsame = false
break
end
end
if notsame then
self:increase_maxpower(factions_config.powermax_per_player)
end
end
end
end
function factions.Faction.count_land(self)
local count = 0.
for k, v in pairs(self.land) do
count = count + 1
end
return count
end
2018-10-15 17:24:58 +02:00
minetest.register_on_prejoinplayer(function(name, ip)
factions_ip.player_ips[name] = ip
end)
function factions.Faction.add_player(self, player, rank)
2016-08-10 02:46:54 +02:00
self:on_player_join(player)
self.players[player] = rank or self.default_rank
factions.players[player] = self.name
self.invited_players[player] = nil
2018-10-18 04:04:46 +02:00
if factions_config.enable_power_per_player then
2018-10-15 17:24:58 +02:00
local ip = factions_ip.player_ips[player]
local notsame = true
for i,k in pairs(self.players) do
local other_ip = factions_ip.player_ips[k]
if other_ip == ip then
notsame = false
break
end
end
if notsame then
2018-10-18 04:04:46 +02:00
self:increase_maxpower(factions_config.powermax_per_player)
2018-10-15 17:24:58 +02:00
end
end
2018-10-17 04:58:15 +02:00
local pdata = minetest.get_player_by_name(player)
local ipc = pdata:is_player_connected(player)
if ipc then
createHudFactionName(pdata,self.name)
createHudPower(pdata,self)
self.offlineplayers[player] = nil
self.onlineplayers[player] = 1
else
self.offlineplayers[player] = 1
self.onlineplayers[player] = nil
end
factions.save()
end
function factions.Faction.check_players_in_faction(self)
2018-10-27 17:51:39 +02:00
for i,k in pairs(self.players) do
return true
end
2018-10-27 17:51:39 +02:00
self:disband("Zero players on faction.")
return false
end
function factions.Faction.remove_player(self, player)
self.players[player] = nil
factions.players[player] = nil
self:on_player_leave(player)
self:check_players_in_faction(self)
2018-10-18 04:04:46 +02:00
if factions_config.enable_power_per_player then
2018-10-15 17:24:58 +02:00
local ip = factions_ip.player_ips[player]
local notsame = true
for i,k in pairs(self.players) do
local other_ip = factions_ip.player_ips[k]
if other_ip == ip then
notsame = false
break
end
end
if notsame then
2018-10-18 04:04:46 +02:00
self:decrease_maxpower(factions_config.powermax_per_player)
2018-10-15 17:24:58 +02:00
end
end
2018-10-17 04:58:15 +02:00
local pdata = minetest.get_player_by_name(player)
local ipc = pdata:is_player_connected(player)
if ipc then
removeHud(pdata,"factionName")
removeHud(pdata,"powerWatch")
end
2018-10-17 04:58:15 +02:00
self.offlineplayers[player] = nil
self.onlineplayers[player] = nil
factions.save()
end
2016-08-14 15:53:40 +02:00
--! @param parcelpos position of the wanted parcel
--! @return whether this faction can claim a parcelpos
function factions.Faction.can_claim_parcel(self, parcelpos)
local fac = factions.parcels[parcelpos]
if fac then
2018-10-18 07:15:26 +02:00
if factions.factions[fac].power < 0. and self.power >= factions_config.power_per_parcel and not self.allies[factions.factions[fac].name] and not self.neutral[factions.factions[fac].name] then
return true
else
return false
end
2018-10-18 04:04:46 +02:00
elseif self.power < factions_config.power_per_parcel then
2016-08-08 16:31:11 +02:00
return false
end
return true
end
2016-08-14 15:53:40 +02:00
--! @brief claim a parcel, update power and update global parcels table
function factions.Faction.claim_parcel(self, parcelpos)
-- check if claiming over other faction's territory
2016-08-14 15:53:40 +02:00
local otherfac = factions.parcels[parcelpos]
if otherfac then
local faction = factions.factions[otherfac]
2016-08-14 15:53:40 +02:00
faction:unclaim_parcel(parcelpos)
2018-10-15 17:24:58 +02:00
faction:parcelless_check()
end
2016-08-14 15:53:40 +02:00
factions.parcels[parcelpos] = self.name
self.land[parcelpos] = true
2018-10-18 04:04:46 +02:00
self:decrease_power(factions_config.power_per_parcel)
self:increase_usedpower(factions_config.power_per_parcel)
2016-08-14 15:53:40 +02:00
self:on_claim_parcel(parcelpos)
2018-10-15 17:24:58 +02:00
self:parcelless_check()
factions.save()
end
2016-08-14 15:53:40 +02:00
--! @brief claim a parcel, update power and update global parcels table
function factions.Faction.unclaim_parcel(self, parcelpos)
factions.parcels[parcelpos] = nil
self.land[parcelpos] = nil
2018-10-18 04:04:46 +02:00
self:increase_power(factions_config.power_per_parcel)
self:decrease_usedpower(factions_config.power_per_parcel)
2016-08-14 15:53:40 +02:00
self:on_unclaim_parcel(parcelpos)
2018-10-15 17:24:58 +02:00
self:parcelless_check()
factions.save()
end
2016-08-12 11:16:43 +02:00
2018-10-15 17:24:58 +02:00
function factions.Faction.parcelless_check(self)
if self.land then
local count = 0
for index, value in pairs(self.land) do
count = count + 1
2018-10-23 06:03:11 +02:00
break
2018-10-15 17:24:58 +02:00
end
if count > 0 then
if self.no_parcel ~= -1 then
self:broadcast("Faction " .. self.name .. " will not be disbanded because it now has parcels.")
end
self.no_parcel = -1
else
self.no_parcel = os.time()
2018-10-18 04:31:07 +02:00
self:on_no_parcel()
2018-10-15 17:24:58 +02:00
end
end
end
2016-08-14 15:53:40 +02:00
--! @brief disband faction, updates global players and parcels table
function factions.Faction.disband(self, reason)
if not self.is_admin then
for i,v in pairs(factions.factions) do
if v.name ~= self.name then
if v.enemies[self.name] then
v:end_enemy(self.name)
end
if v.allies[self.name] then
v:end_alliance(self.name)
end
if v.neutral[self.name] then
v:end_neutral(self.name)
end
2018-10-15 17:24:58 +02:00
end
end
for k, _ in pairs(self.players) do -- remove players affiliation
factions.players[k] = nil
end
for k, v in pairs(self.land) do -- remove parcel claims
factions.parcels[k] = nil
end
self:on_disband(reason)
2018-10-31 22:15:08 +01:00
for i,l in pairs(self.onlineplayers) do
removeHud(i,"factionName")
removeHud(i,"powerWatch")
end
factions.factions[self.name] = nil
factions.save()
2018-10-15 17:24:58 +02:00
end
end
2016-08-12 11:16:43 +02:00
--! @brief change the faction leader
function factions.Faction.set_leader(self, player)
2016-08-27 22:34:09 +02:00
if self.leader then
self.players[self.leader] = self.default_rank
end
self.leader = player
self.players[player] = self.default_leader_rank
self:on_new_leader()
factions.save()
end
2016-08-12 11:16:43 +02:00
2018-10-25 07:21:42 +02:00
function factions.Faction.set_message_of_the_day(self,text)
self.message_of_the_day = text
factions.save()
end
2016-08-12 11:16:43 +02:00
--! @brief check permissions for a given player
--! @return boolean indicating permissions. Players not in faction always receive false
function factions.Faction.has_permission(self, player, permission)
local p = self.players[player]
if not p then
return false
end
local perms = self.ranks[p]
if perms then
for i in ipairs(perms) do
if perms[i] == permission then
return true
end
end
2018-10-30 01:36:46 +01:00
else
2018-10-31 15:41:34 +01:00
if not self.rankless then
self.rankless = true
factions.save()
end
end
return false
end
2018-10-22 21:30:11 +02:00
function factions.Faction.set_description(self, new)
self.description = new
self:on_change_description()
factions.save()
end
2016-08-12 11:16:43 +02:00
--! @brief places player in invite list
function factions.Faction.invite_player(self, player)
self.invited_players[player] = true
self:on_player_invited(player)
factions.save()
end
2016-08-12 11:16:43 +02:00
--! @brief removes player from invite list (can no longer join via /f join)
function factions.Faction.revoke_invite(self, player)
self.invited_players[player] = nil
self:on_revoke_invite(player)
factions.save()
end
2016-08-12 11:16:43 +02:00
--! @brief set faction openness
function factions.Faction.toggle_join_free(self, bool)
self.join_free = bool
self:on_toggle_join_free()
factions.save()
end
2016-08-12 11:16:43 +02:00
--! @return true if a player can use /f join, false otherwise
function factions.Faction.can_join(self, player)
return self.join_free or self.invited_players[player]
end
2016-08-12 11:16:43 +02:00
function factions.Faction.new_alliance(self, faction)
self.allies[faction] = true
self:on_new_alliance(faction)
if self.enemies[faction] then
self:end_enemy(faction)
2018-10-15 17:24:58 +02:00
end
2018-10-18 07:15:26 +02:00
if self.neutral[faction] then
self:end_neutral(faction)
end
factions.save()
end
2018-10-22 21:30:11 +02:00
function factions.Faction.end_alliance(self, faction)
self.allies[faction] = nil
self:on_end_alliance(faction)
factions.save()
end
2018-10-22 21:30:11 +02:00
2018-10-18 07:15:26 +02:00
function factions.Faction.new_neutral(self, faction)
self.neutral[faction] = true
self:on_new_neutral(faction)
2018-10-15 17:24:58 +02:00
if self.allies[faction] then
self:end_alliance(faction)
end
if self.enemies[faction] then
self:end_enemy(faction)
end
factions.save()
end
2018-10-22 21:30:11 +02:00
2018-10-18 07:15:26 +02:00
function factions.Faction.end_neutral(self, faction)
self.neutral[faction] = nil
self:on_end_neutral(faction)
2018-10-15 17:24:58 +02:00
factions.save()
end
2018-10-22 21:30:11 +02:00
function factions.Faction.new_enemy(self, faction)
self.enemies[faction] = true
self:on_new_enemy(faction)
if self.allies[faction] then
self:end_alliance(faction)
2018-10-15 17:24:58 +02:00
end
2018-10-18 07:15:26 +02:00
if self.neutral[faction] then
self:end_neutral(faction)
end
factions.save()
end
2018-10-22 21:30:11 +02:00
function factions.Faction.end_enemy(self, faction)
self.enemies[faction] = nil
self:on_end_enemy(faction)
factions.save()
end
2016-08-12 11:16:43 +02:00
--! @brief faction's member will now spawn in a new place
function factions.Faction.set_spawn(self, pos)
2016-08-08 16:31:11 +02:00
self.spawn = {x=pos.x, y=pos.y, z=pos.z}
2016-08-15 01:50:13 +02:00
self:on_set_spawn()
factions.save()
end
2016-08-12 11:16:43 +02:00
2018-10-31 22:15:08 +01:00
function factions.Faction.tp_spawn(self, playername)
player = minetest.get_player_by_name(playername)
if player then
player:moveto(self.spawn, false)
end
end
2016-08-12 11:16:43 +02:00
--! @brief create a new rank with permissions
--! @param rank the name of the new rank
--! @param rank a list with the permissions of the new rank
function factions.Faction.add_rank(self, rank, perms)
self.ranks[rank] = perms
2016-08-08 16:31:11 +02:00
self:on_add_rank(rank)
factions.save()
end
2016-08-12 11:16:43 +02:00
2018-10-31 22:15:08 +01:00
--! @brief replace an rank's permissions
--! @param rank the name of the rank to edit
--! @param add or remove permissions to the rank
function factions.Faction.replace_privs(self, rank, perms)
self.ranks[rank] = perms
self:on_replace_privs(rank)
factions.save()
end
function factions.Faction.remove_privs(self, rank, perms)
local revoked = false
local p = self.ranks[rank]
for index, perm in pairs(p) do
if table_Contains(perms,perm) then
revoked = true
table.remove(p,index)
end
end
self.ranks[rank] = p
if revoked then
self:on_remove_privs(rank,perms)
else
self:broadcast("No privilege was revoked from rank "..rank..".")
end
factions.save()
end
function factions.Faction.add_privs(self, rank, perms)
local added = false
local p = self.ranks[rank]
for index, perm in pairs(perms) do
if not table_Contains(p,perm) then
added = true
table.insert(p,perm)
end
end
self.ranks[rank] = p
if added then
self:on_add_privs(rank,perms)
else
self:broadcast("The rank "..rank.." already has these privileges.")
end
factions.save()
end
function factions.Faction.set_rank_name(self, oldrank, newrank)
local copyrank = self.ranks[oldrank]
self.ranks[newrank] = copyrank
self.ranks[oldrank] = nil
for player, r in pairs(self.players) do
if r == oldrank then
self.players[player] = newrank
end
end
if oldrank == self.default_leader_rank then
self.default_leader_rank = newrank
self:broadcast("The default leader rank has been set to "..newrank)
end
if oldrank == self.default_rank then
self.default_rank = newrank
self:broadcast("The default rank given to new players is set to "..newrank)
end
self:on_set_rank_name(oldrank, newrank)
factions.save()
end
function factions.Faction.set_def_rank(self, rank)
2018-10-30 01:36:46 +01:00
for player, r in pairs(self.players) do
if r == rank or r == nil or not self.ranks[r] then
self.players[player] = rank
end
end
self.default_rank = rank
2018-10-31 22:15:08 +01:00
self:on_set_def_rank(rank)
self.rankless = false
factions.save()
end
function factions.Faction.reset_ranks(self)
self.ranks = starting_ranks
self.default_rank = "member"
self.default_leader_rank_rank = "leader"
for player, r in pairs(self.players) do
if not player == leader and (r == nil or not self.ranks[r]) then
self.players[player] = self.default_rank
elseif player == leader then
self.players[player] = self.default_leader_rank_rank
end
end
self:on_reset_ranks()
self.rankless = false
2018-10-30 01:36:46 +01:00
factions.save()
end
2016-08-12 11:16:43 +02:00
--! @brief delete a rank and replace it
--! @param rank the name of the rank to be deleted
--! @param newrank the rank given to players who were previously "rank"
function factions.Faction.delete_rank(self, rank, newrank)
for player, r in pairs(self.players) do
if r == rank then
self.players[player] = newrank
end
end
self.ranks[rank] = nil
self:on_delete_rank(rank, newrank)
if rank == self.default_leader_rank then
self.default_leader_rank = newrank
self:broadcast("The default leader rank has been set to "..newrank)
end
if rank == self.default_rank then
self.default_rank = newrank
self:broadcast("The default rank given to new players is set to "..newrank)
end
factions.save()
end
2016-08-12 11:16:43 +02:00
--! @brief set a player's rank
function factions.Faction.promote(self, member, rank)
self.players[member] = rank
self:on_promote(member)
end
2016-08-12 11:16:43 +02:00
--! @brief send a message to all members
function factions.Faction.broadcast(self, msg, sender)
local message = self.name.."> "..msg
if sender then
message = sender.."@"..message
end
message = "Faction<"..message
2018-10-18 04:36:07 +02:00
for k, _ in pairs(self.onlineplayers) do
minetest.chat_send_player(k, message)
end
end
2016-08-08 21:09:10 +02:00
--! @brief checks whether a faction has at least one connected player
function factions.Faction.is_online(self)
2018-10-18 04:36:07 +02:00
for playername, _ in pairs(self.onlineplayers) do
if minetest.get_player_by_name(playername) then
return true
end
end
return false
end
2016-08-15 18:31:11 +02:00
function factions.Faction.attack_parcel(self, parcelpos)
2018-10-18 04:04:46 +02:00
if factions_config.attack_parcel then
local attacked_faction = factions.get_parcel_faction(parcelpos)
if attacked_faction then
2018-10-15 17:24:58 +02:00
if not self.allies[attacked_faction.name] then
2018-10-18 04:04:46 +02:00
self.power = self.power - factions_config.power_per_attack
2018-10-15 17:24:58 +02:00
if attacked_faction.attacked_parcels[parcelpos] then
attacked_faction.attacked_parcels[parcelpos][self.name] = true
else
attacked_faction.attacked_parcels[parcelpos] = {[self.name] = true}
end
attacked_faction:broadcast("Parcel ("..parcelpos..") is being attacked by "..self.name.."!!")
if self.power < 0. then -- punish memers
minetest.chat_send_all("Faction "..self.name.." has attacked too much and has now negative power!")
end
factions.save()
else
2018-10-15 17:24:58 +02:00
self:broadcast("You can not attack that parcel because it belongs to an ally.")
end
end
end
2016-08-15 18:31:11 +02:00
end
function factions.Faction.stop_attack(self, parcelpos)
local attacked_faction = factions.parcels[parcelpos]
if attacked_faction then
attacked_faction = factions.factions[attacked_faction]
if attacked_faction.attacked_parcels[parcelpos] then
attacked_faction.attacked_parcels[parcelpos][self.name] = nil
attacked_faction:broadcast("Parcel ("..parcelpos..") is no longer under attack from "..self.name..".")
self:broadcast("Parcel ("..parcelpos..") has been reconquered by "..attacked_faction.name..".")
2016-08-15 18:31:11 +02:00
end
factions.save()
end
end
2016-08-19 10:02:12 +02:00
function factions.Faction.parcel_is_attacked_by(self, parcelpos, faction)
if self.attacked_parcels[parcelpos] then
return self.attacked_parcels[parcelpos][faction.name]
else
return false
end
end
--------------------------
-- callbacks for events --
function factions.Faction.on_create(self) --! @brief called when the faction is added to the global faction list
2016-08-10 02:46:54 +02:00
minetest.chat_send_all("Faction "..self.name.." has been created.")
end
2018-10-31 22:15:08 +01:00
function factions.Faction.on_set_name(self,oldname)
minetest.chat_send_all("Faction "..oldname.." has been changed its name to "..self.name..".")
end
2018-10-18 04:31:07 +02:00
function factions.Faction.on_no_parcel(self)
local now = os.time() - self.no_parcel
local l = factions_config.maximum_parcelless_faction_time
self:broadcast("This faction will disband in "..l-now.." seconds, because it has no parcels.")
end
function factions.Faction.on_player_leave(self, player)
self:broadcast(player.." has left this faction.")
end
function factions.Faction.on_player_join(self, player)
self:broadcast(player.." has joined this faction.")
end
2016-08-14 15:53:40 +02:00
function factions.Faction.on_claim_parcel(self, pos)
2016-08-14 23:27:51 +02:00
self:broadcast("Parcel ("..pos..") has been claimed.")
end
2016-08-14 15:53:40 +02:00
function factions.Faction.on_unclaim_parcel(self, pos)
2016-08-14 23:27:51 +02:00
self:broadcast("Parcel ("..pos..") has been unclaimed.")
end
function factions.Faction.on_disband(self, reason)
local msg = "Faction "..self.name.." has been disbanded."
if reason then
msg = msg.." ("..reason..")"
end
minetest.chat_send_all(msg)
end
function factions.Faction.on_new_leader(self)
self:broadcast(self.leader.." is now the leader of this faction.")
end
function factions.Faction.on_change_description(self)
self:broadcast("Faction description has been modified to: "..self.description)
end
function factions.Faction.on_player_invited(self, player)
minetest.chat_send_player(player, "You have been invited to faction "..self.name)
end
function factions.Faction.on_toggle_join_free(self, player)
2016-08-29 01:41:23 +02:00
if self.join_free then
self:broadcast("This faction is now invite-free.")
else
self:broadcast("This faction is no longer invite-free.")
end
end
function factions.Faction.on_new_alliance(self, faction)
self:broadcast("This faction is now allied with "..faction)
end
function factions.Faction.on_end_alliance(self, faction)
self:broadcast("This faction is no longer allied with "..faction.."!")
end
2018-10-18 07:15:26 +02:00
function factions.Faction.on_new_neutral(self, faction)
self:broadcast("This faction is now neutral with "..faction)
2018-10-15 17:24:58 +02:00
end
2018-10-18 07:15:26 +02:00
function factions.Faction.on_end_neutral(self, faction)
self:broadcast("This faction is no longer neutral with "..faction.."!")
2018-10-15 17:24:58 +02:00
end
function factions.Faction.on_new_enemy(self, faction)
self:broadcast("This faction is now at war with "..faction)
end
function factions.Faction.on_end_enemy(self, faction)
self:broadcast("This faction is no longer at war with "..faction.."!")
end
function factions.Faction.on_set_spawn(self)
2016-08-15 01:50:13 +02:00
self:broadcast("The faction spawn has been set to ("..util.coords3D_string(self.spawn)..").")
end
function factions.Faction.on_add_rank(self, rank)
self:broadcast("The rank "..rank.." has been created with privileges: "..table.concat(self.ranks[rank], ", "))
end
2018-10-31 22:15:08 +01:00
function factions.Faction.on_replace_privs(self, rank)
self:broadcast("The privileges in rank "..rank.." have been delete and changed to: "..table.concat(self.ranks[rank], ", "))
end
function factions.Faction.on_remove_privs(self, rank,privs)
self:broadcast("The privileges in rank "..rank.." have been revoked: "..table.concat(privs, ", "))
end
function factions.Faction.on_add_privs(self, rank,privs)
self:broadcast("The privileges in rank "..rank.." have been added: "..table.concat(privs, ", "))
end
function factions.Faction.on_set_rank_name(self, rank,newrank)
self:broadcast("The name of rank "..rank.." has been changed to "..newrank)
end
function factions.Faction.on_delete_rank(self, rank, newrank)
self:broadcast("The rank "..rank.." has been deleted and replaced by "..newrank)
end
2018-10-31 22:15:08 +01:00
function factions.Faction.on_set_def_rank(self, rank)
2018-10-30 01:36:46 +01:00
self:broadcast("The default rank given to new players has been changed to "..rank)
end
2018-10-31 22:15:08 +01:00
function factions.Faction.on_reset_ranks(self)
self:broadcast("All of the faction's ranks have been reset to the default ones.")
end
function factions.Faction.on_promote(self, member)
minetest.chat_send_player(member, "You have been promoted to "..self.players[member])
end
function factions.Faction.on_revoke_invite(self, player)
minetest.chat_send_player(player, "You are no longer invited to faction "..self.name)
end
2016-08-14 15:53:40 +02:00
function factions.get_parcel_pos(pos)
2018-10-18 04:40:00 +02:00
if factions_config.protection_style == "2d" then
2018-10-18 04:04:46 +02:00
return math.floor(pos.x / factions_config.parcel_size)..","..math.floor(pos.z / factions_config.parcel_size)
2018-10-18 04:40:00 +02:00
elseif factions_config.protection_style == "3d" then
2018-10-18 04:04:46 +02:00
return math.floor(pos.x / factions_config.parcel_size)..","..math.floor(pos.y / factions_config.parcel_size)..","..math.floor(pos.z / factions_config.parcel_size)
2018-10-17 04:58:15 +02:00
end
2016-08-07 19:36:56 +02:00
end
2016-07-30 07:38:52 +02:00
function factions.get_player_faction(playername)
2016-08-17 22:28:12 +02:00
local facname = factions.players[playername]
if facname then
local faction = factions.factions[facname]
return faction
end
return nil
end
function factions.get_parcel_faction(parcelpos)
local facname = factions.parcels[parcelpos]
2016-08-17 22:28:12 +02:00
if facname then
local faction = factions.factions[facname]
return faction
end
return nil
end
function factions.get_faction(facname)
return factions.factions[facname]
end
function factions.get_faction_at(pos)
2018-10-17 04:58:15 +02:00
local y = pos.y
2018-10-18 04:04:46 +02:00
if factions_config.protection_depth_height_limit and (pos.y < factions_config.protection_max_depth or pos.y > factions_config.protection_max_height) then
2018-10-17 04:58:15 +02:00
return nil
end
2016-08-17 22:28:12 +02:00
local parcelpos = factions.get_parcel_pos(pos)
return factions.get_parcel_faction(parcelpos)
end
2016-07-30 07:38:52 +02:00
-------------------------------------------------------------------------------
2016-08-07 02:11:17 +02:00
-- name: add_faction(name)
2016-07-30 07:38:52 +02:00
--
2016-08-07 02:11:17 +02:00
--! @brief add a faction
2016-08-07 19:31:11 +02:00
--! @memberof factions
2016-07-30 07:38:52 +02:00
--! @public
--
2016-08-07 02:11:17 +02:00
--! @param name of faction to add
2016-07-30 07:38:52 +02:00
--!
2016-08-07 02:11:17 +02:00
--! @return faction object/false (succesfully added faction or not)
2016-07-30 07:38:52 +02:00
-------------------------------------------------------------------------------
2016-08-07 19:31:11 +02:00
function factions.add_faction(name)
2016-08-07 19:36:56 +02:00
if factions.can_create_faction(name) then
local fac = factions.new_faction(name)
fac:on_create()
return fac
else
return nil
end
2016-07-30 07:38:52 +02:00
end
-------------------------------------------------------------------------------
-- name: get_faction_list()
--
2016-08-07 19:31:11 +02:00
--! @brief get list of factions
--! @memberof factions
2016-07-30 07:38:52 +02:00
--! @public
--!
2016-08-07 19:31:11 +02:00
--! @return list of factions
2016-07-30 07:38:52 +02:00
-------------------------------------------------------------------------------
2016-08-07 19:31:11 +02:00
function factions.get_faction_list()
2016-07-30 07:38:52 +02:00
2016-08-18 15:21:59 +02:00
local retval = {}
for key,value in pairs(factions.factions) do
table.insert(retval,key)
end
return retval
2016-07-30 07:38:52 +02:00
end
-------------------------------------------------------------------------------
-- name: save()
--
--! @brief save data to file
2016-08-07 19:31:11 +02:00
--! @memberof factions
2016-07-30 07:38:52 +02:00
--! @private
-------------------------------------------------------------------------------
2016-08-07 19:31:11 +02:00
function factions.save()
2016-07-30 07:38:52 +02:00
2016-08-18 15:21:59 +02:00
--saving is done much more often than reading data to avoid delay
--due to figuring out which data to save and which is temporary only
--all data is saved here
--this implies data needs to be cleant up on load
local file,error = io.open(factions_worldid .. "/" .. "factions.conf","w")
if file ~= nil then
file:write(minetest.serialize(factions.factions))
file:close()
else
minetest.log("error","MOD factions: unable to save factions world specific data!: " .. error)
end
2018-10-15 17:24:58 +02:00
factions_ip.save()
2016-07-30 07:38:52 +02:00
end
-------------------------------------------------------------------------------
-- name: load()
--
--! @brief load data from file
2016-08-07 19:31:11 +02:00
--! @memberof factions
2016-07-30 07:38:52 +02:00
--! @private
--
--! @return true/false
-------------------------------------------------------------------------------
2016-08-07 19:31:11 +02:00
function factions.load()
local filename = "factions.conf"
local file,error = io.open(factions_worldid .. "/" .. filename,"r")
2016-08-18 15:21:59 +02:00
if file ~= nil then
local raw_data = file:read("*a")
2018-10-28 05:49:28 +01:00
local current_version = misc_mod_data.data.factions_version
misc_mod_data.load()
2018-10-28 06:06:44 +01:00
local old_version = misc_mod_data.data.factions_version
local tabledata = minetest.deserialize(raw_data)
file:close()
if tabledata then
factions.factions = tabledata
if current_version ~= old_version or factions.is_old_file(tabledata) then
if factions.convert(filename) then
minetest.after(5,
function()
minetest.chat_send_all("Factions successfully converted.")
end)
end
2018-10-18 04:55:06 +02:00
end
for facname, faction in pairs(factions.factions) do
minetest.log("action", facname..","..faction.name)
for player, rank in pairs(faction.players) do
minetest.log("action", player..","..rank)
factions.players[player] = facname
end
for parcelpos, val in pairs(faction.land) do
factions.parcels[parcelpos] = facname
end
setmetatable(faction, factions.Faction)
if not faction.maxpower or faction.maxpower <= 0. then
faction.maxpower = faction.power
if faction.power < 0. then
faction.maxpower = 0.
end
end
if not faction.attacked_parcels then
faction.attacked_parcels = {}
end
if not faction.usedpower then
faction.usedpower = faction:count_land() * factions_config.power_per_parcel
end
if #faction.name > factions_config.faction_name_max_length then
faction:disband()
end
if not faction.last_logon then
faction.last_logon = os.time()
end
if faction.no_parcel ~= -1 then
faction.no_parcel = os.time()
end
if faction:count_land() > 0 then
faction.no_parcel = -1
end
2018-10-31 22:15:08 +01:00
faction.onlineplayers = {}
faction.offlineplayers = {}
if faction.players then
for i, _ in pairs(faction.players) do
faction.offlineplayers[i] = _
end
end
2018-10-17 18:47:53 +02:00
end
misc_mod_data.data.factions_version = current_version
misc_mod_data.save()
factions.save()
else
minetest.after(5,
function()
minetest.chat_send_all("Failed to deserialize saved file.")
end)
end
2016-08-07 02:11:17 +02:00
end
2018-10-15 17:24:58 +02:00
factions_ip.load()
2016-07-30 22:33:10 +02:00
end
2016-08-08 18:51:17 +02:00
function factions.is_old_file(oldfactions)
local tempfaction = factions.Faction:new(nil)
local pass = false
for facname, faction in pairs(oldfactions) do
for ni, nl in pairs(tempfaction) do
pass = false
for key, value in pairs(faction) do
if key == ni then
pass = true
break
end
end
if not pass then
tempfaction = nil
return true
end
end
-- Only check one faction to save time.
if not pass then
tempfaction = nil
return true
else
tempfaction = nil
return false
end
end
tempfaction = nil
return false
end
2016-08-08 18:51:17 +02:00
function factions.convert(filename)
local file, error = io.open(factions_worldid .. "/" .. filename, "r")
if not file then
minetest.chat_send_all("Cannot load file "..filename..". "..error)
return false
end
local raw_data = file:read("*a")
file:close()
2018-10-31 22:15:08 +01:00
2016-08-08 18:51:17 +02:00
local data = minetest.deserialize(raw_data)
2018-10-31 22:15:08 +01:00
local old_permissions = {"disband", "claim", "playerslist", "build", "description", "ranks", "spawn", "promote","diplomacy"}
for facname,faction in pairs(data) do
local newfac = factions.new_faction(facname,true)
for oi, ol in pairs(faction) do
if newfac[oi] then
newfac[oi] = ol
end
end
if faction.players then
newfac.players = faction.players
end
if faction.land then
2018-10-31 22:15:08 +01:00
newfac.land = faction.land
end
if faction.ranks then
newfac.ranks = faction.ranks
end
2018-10-31 01:17:28 +01:00
if faction.rankless then
newfac.rankless = faction.rankless
else
newfac.rankless = false
end
2018-10-31 22:15:08 +01:00
for rank,perm in pairs(faction.ranks) do
for index,value in pairs(perm) do
if value == "playerslist" then
table.remove(faction.ranks[rank],index)
table.insert(faction.ranks[rank],"kick")
table.insert(faction.ranks[rank],"invite")
elseif value == "ranks" then
table.remove(faction.ranks[rank],index)
table.insert(faction.ranks[rank],"create_ranks")
table.insert(faction.ranks[rank],"edit_ranks")
table.insert(faction.ranks[rank],"delete_ranks")
table.insert(faction.ranks[rank],"set_def_ranks")
table.insert(faction.ranks[rank],"reset_ranks")
elseif value == "diplomacy" then
table.remove(faction.ranks[rank],index)
table.insert(faction.ranks[rank],"declare_war")
table.insert(faction.ranks[rank],"neutral")
table.insert(faction.ranks[rank],"alliance")
table.insert(faction.ranks[rank],"accept_treaty")
table.insert(faction.ranks[rank],"refuse_treaty")
elseif value == "spawn" then
if not factions_config.spawn_teleport == true then
table.remove(faction.ranks[rank],index)
end
table.insert(faction.ranks[rank],"set_spawn")
table.insert(faction.ranks[rank],"unset_spawn")
end
end
end
factions.start_diplomacy(facname,newfac)
newfac:check_power()
2016-08-08 18:51:17 +02:00
end
-- Create runtime data.
for facname,faction in pairs(factions.factions) do
if faction.players then
for player, unused in pairs(faction.players) do
factions.players[player] = faction.name
end
end
if faction.land then
for l, unused in pairs(faction.land) do
factions.parcels[l] = facname
end
end
end
2016-08-08 18:51:17 +02:00
return true
end
2016-08-18 15:21:59 +02:00
2016-08-07 02:11:17 +02:00
minetest.register_on_dieplayer(
2016-08-18 15:21:59 +02:00
function(player)
local faction = factions.get_player_faction(player:get_player_name())
if not faction then
return true
2016-08-07 02:11:17 +02:00
end
2018-10-18 04:04:46 +02:00
faction:decrease_power(factions_config.power_per_death)
2016-08-18 15:21:59 +02:00
return true
end
2016-08-07 02:11:17 +02:00
)
2018-10-17 04:58:15 +02:00
function factions.faction_tick()
local now = os.time()
for facname, faction in pairs(factions.factions) do
if faction:is_online() then
2018-10-18 04:04:46 +02:00
if factions_config.enable_power_per_player then
2018-10-17 04:58:15 +02:00
local t = faction.onlineplayers
local count = 0
for _ in pairs(t) do count = count + 1 end
2018-10-18 04:04:46 +02:00
faction:increase_power(factions_config.power_per_player*count)
2018-10-17 04:58:15 +02:00
else
2018-10-18 04:04:46 +02:00
faction:increase_power(factions_config.power_per_tick)
2018-10-15 17:24:58 +02:00
end
end
2018-10-18 04:04:46 +02:00
if now - faction.last_logon > factions_config.maximum_faction_inactivity or (faction.no_parcel ~= -1 and now - faction.no_parcel > factions_config.maximum_parcelless_faction_time) then
faction:disband()
end
end
end
2016-08-07 02:11:17 +02:00
minetest.register_on_joinplayer(
2016-08-18 15:21:59 +02:00
function(player)
local name = player:get_player_name()
2018-10-28 04:37:49 +01:00
minetest.after(5,createHudfactionLand,player)
local faction = factions.get_player_faction(name)
2016-08-21 01:15:41 +02:00
if faction then
faction.last_logon = os.time()
2018-10-28 04:37:49 +01:00
minetest.after(5,createHudFactionName,player,faction.name)
minetest.after(5,createHudPower,player,faction)
2018-10-17 04:58:15 +02:00
faction.offlineplayers[name] = nil
faction.onlineplayers[name] = 1
2018-10-18 04:31:07 +02:00
if faction.no_parcel ~= -1 then
local now = os.time() - faction.no_parcel
local l = factions_config.maximum_parcelless_faction_time
2018-10-23 05:55:19 +02:00
minetest.chat_send_player(name,"This faction will disband in "..l-now.." seconds, because it has no parcels.")
2018-10-18 04:31:07 +02:00
end
2018-10-31 22:15:08 +01:00
if faction:has_permission(name, "accept_treaty") or faction:has_permission(name, "refuse_treaty") then
2018-10-23 05:55:19 +02:00
for _ in pairs(faction.request_inbox) do minetest.chat_send_player(name,"You have diplomatic requests in the inbox.") break end
2018-10-18 07:20:05 +02:00
end
2018-10-30 01:36:46 +01:00
if faction:has_permission(name, "ranks") then
if faction.rankless then
2018-10-31 22:15:08 +01:00
minetest.chat_send_player(name,"You need to reset the default rank because there are rankless players in this faction. reset all the ranks back to default using /f reset_ranks (You will lose all of your custom ranks) or use /f change_def_rank")
2018-10-30 01:36:46 +01:00
end
end
if faction.message_of_the_day and (faction.message_of_the_day ~= "" or faction.message_of_the_day ~= " ") then
2018-10-25 07:21:42 +02:00
minetest.chat_send_player(name,faction.message_of_the_day)
end
2016-08-21 01:15:41 +02:00
end
2016-08-18 15:21:59 +02:00
end
2016-08-07 02:11:17 +02:00
)
minetest.register_on_leaveplayer(
function(player)
2018-10-17 04:58:15 +02:00
local name = player:get_player_name()
local faction = factions.get_player_faction(name)
2018-10-28 02:06:48 +01:00
local id_name1 = name .. "factionLand"
if hud_ids[id_name1] then
hud_ids[id_name1] = nil
end
2018-10-17 04:58:15 +02:00
if faction then
2018-10-28 02:06:48 +01:00
local id_name2 = name .. "factionName"
local id_name3 = name .. "powerWatch"
if hud_ids[id_name2] then
hud_ids[id_name2] = nil
end
if hud_ids[id_name3] then
hud_ids[id_name3] = nil
end
2018-10-17 04:58:15 +02:00
faction.offlineplayers[name] = 1
faction.onlineplayers[name] = nil
2018-10-31 22:15:08 +01:00
factions.save()
2018-10-17 04:58:15 +02:00
end
end
)
2016-08-08 16:31:11 +02:00
minetest.register_on_respawnplayer(
function(player)
2016-08-18 15:21:59 +02:00
local faction = factions.get_player_faction(player:get_player_name())
2016-08-08 16:31:11 +02:00
if not faction then
return false
else
if not faction.spawn then
return false
else
player:setpos(faction.spawn)
return true
end
end
end
)
2016-08-04 07:21:22 +02:00
local default_is_protected = minetest.is_protected
minetest.is_protected = function(pos, player)
2018-10-17 04:58:15 +02:00
local y = pos.y
2018-10-18 04:04:46 +02:00
if factions_config.protection_depth_height_limit and (pos.y < factions_config.protection_max_depth or pos.y > factions_config.protection_max_height) then
return false
end
2016-08-14 15:53:40 +02:00
local parcelpos = factions.get_parcel_pos(pos)
2016-08-18 15:21:59 +02:00
local parcel_faction = factions.get_parcel_faction(parcelpos)
local player_faction = factions.get_player_faction(player)
-- no faction
2016-08-19 23:10:01 +02:00
if not parcel_faction then
return default_is_protected(pos, player)
2016-08-19 23:10:01 +02:00
elseif player_faction then
2016-08-19 03:05:44 +02:00
if parcel_faction.name == player_faction.name then
2018-10-31 22:15:08 +01:00
if parcel_faction:has_permission(player, "pain_build") then
local p = minetest.get_player_by_name(player)
p:set_hp(p:get_hp() - 0.5)
end
return not (parcel_faction:has_permission(player, "build") or parcel_faction:has_permission(player, "pain_build"))
2018-10-15 17:24:58 +02:00
elseif parcel_faction.allies[player_faction.name] then
2018-10-31 22:15:08 +01:00
if player_faction:has_permission(player, "pain_build") then
local p = minetest.get_player_by_name(player)
p:set_hp(p:get_hp() - 0.5)
end
return not (player_faction:has_permission(player, "build") or player_faction:has_permission(player, "pain_build"))
2018-10-15 17:24:58 +02:00
else
return not parcel_faction:parcel_is_attacked_by(parcelpos, player_faction)
end
2016-08-19 23:10:01 +02:00
else
return true
end
end
2018-10-17 04:58:15 +02:00
function factionUpdate()
2018-10-27 22:40:17 +02:00
factions.faction_tick()
minetest.after(factions_config.tick_time,factionUpdate)
end