From 58c1724b8e92675537cb5a8d93eac4f12b9c30d8 Mon Sep 17 00:00:00 2001 From: shamoanjac Date: Sun, 7 Aug 2016 02:11:17 +0200 Subject: [PATCH] Big ass rewrite --- chatcommands.lua | 455 +++++++------------- factionsmod.lua | 1062 ++++++++++------------------------------------ 2 files changed, 377 insertions(+), 1140 deletions(-) diff --git a/chatcommands.lua b/chatcommands.lua index 0ede97c..b779600 100644 --- a/chatcommands.lua +++ b/chatcommands.lua @@ -48,14 +48,6 @@ function factionsmod_chat.init() } ) - minetest.register_chatcommand("af", - { - params = "text", - description = "send message to all factionsmod", - privs = { faction_user=true }, - func = factionsmod_chat.allfactionsmod_chathandler, - } - ) minetest.register_chatcommand("f", { @@ -79,49 +71,55 @@ end ------------------------------------------------------------------------------- function factionsmod_chat.cmdhandler(playername,parameter) + --let's not duplicate code local player = minetest.env:get_player_by_name(playername) local params = parameter:split(" ") local cmd = params[1] + local player_faction = factionsmod[playername] + local player_position = player:getpos() + local chunk = factionsmod.get_chunk(player_position) + local chunkpos = factionsmod.get_chunkpos(player_position) --handle common commands if parameter == nil or parameter == "" then - - local playerfactionsmod = factionsmod.get_factionsmod(player) - - local tosend = "factionsmod: " .. playername .. " factionsmod:" - for i,v in ipairs(playerfactionsmod) do - if i ~= #playerfactionsmod then - tosend = tosend .. " " .. v .. "," - else - tosend = tosend .. " " .. v - end - end - minetest.chat_send_player(playername, tosend, false) + if player_faction then + minetest.chat_send_player(playername, player_faction.description) + else + --TODO: message, no faction + end return end if cmd == "claim" then - local playerfaction = factionsmod.get_factionsmod(player) - if next(playerfaction) ~= nil then - factionsmod.claim(playerfaction[1],player) - end + if player_faction:has_permission(playername, "claim") then + if not chunk then + player_faction:claim_chunk(chunkpos) + else + if chunk == player_faction.name then + --TODO: error (chunk already claimed by faction) + else + --TODO: error (chunk claimed by another faction) + end + end + else + --TODO: error message (no permission to claim) + end return end + if cmd == "unclaim" then - local playerfaction = factionsmod.get_factionsmod(player) - if next(playerfaction) ~= nil then - factionsmod.unclaim(playerfaction[1],player) - end - return - end - if cmd == "takeover" then - local playerfaction = factionsmod.get_factionsmod(player) - if next(playerfaction) ~= nil then - factionsmod.takeover(playerfaction[1],player) - end - return + if player_faction:has_permission(playername, "claim") then + if chunk ~= player_faction.name then + --TODO: error (not your faction's chunk) + else + player_faction:unclaim_chunk(chunkpos) + end + else + --TODO: error (no permission to claim) + end end + --list all known factionsmod if cmd == "list" then local list = factionsmod.get_faction_list() @@ -149,292 +147,146 @@ function factionsmod_chat.cmdhandler(playername,parameter) if params[2] ~= nil then minetest.chat_send_player(playername, "factionsmod: " .. params[2] .. ": " .. - factionsmod.get_description(params[2]), false) + factionsmod.factions[params[2]].description, false) return end end if cmd == "leave" then - if params[2] ~= nil then - if params[3] ~= nil then - local toremove = minetest.env:get_player_by_name(params[3]) - --allowed if faction_admin, admin of faction or player itself - if factionsmod.is_admin(params[2],playername) and - toremove ~= nil then - - factionsmod.member_remove(params[2],toremove) - minetest.chat_send_player(playername, - "factionsmod: " .. params[3] .. " has been removed from " - .. params[2], false) - return - end - else - factionsmod.member_remove(params[2],player) - minetest.chat_send_player(playername, - "factionsmod: You have left " .. params[2], false) - return - end - end + player_faction:remove_player(playername) + --TODO: message? end + + if cmd == "kick" then + if param[2] then + if player_faction:has_permission(playername, "playerlist") then + player_faction:remove_player(playername) + --TODO: message? + else + --TODO: error (no permissions) + end + else + --TODO: error (no player specified) + end + end - --handle superadmin only commands - --if minetest.check_player_privs(playername,{ faction_admin=true }) then - --create new faction - if cmd == "create" then - if params[2] ~= nil then - if factionsmod.add_faction(params[2]) then - minetest.chat_send_player(playername, - "factionsmod: created faction " .. params[2], - false) - if factionsmod.member_add(params[2],minetest.env:get_player_by_name(playername)) then - minetest.chat_send_player(playername, - "factionsmod: " .. playername .. " joined faction " .. - params[2], - false) - end - return - else - minetest.chat_send_player(playername, - "factionsmod: FAILED to created faction " .. params[2], - false) - return - end - end - end - --end + --create new faction + if cmd == "create" then + if params[2] ~= nil then + local factioname = params[2] + if factionsmod.can_create_faction(factionname) then + player_faction = factionsmod.create_faction(faction) + player_faction:add_player(playername) + player_faction:set_leader(playername) + else + --TODO: error (cannot create faction) + end + else + --TODO: error (help message?) + end + end if cmd == "join" then - if params[2] ~= nil then - --check for invitation - if factionsmod.is_invited(params[2],playername) then - if factionsmod.member_add(params[2],player) then - minetest.chat_send_player(playername, - "factionsmod: joined faction " .. - params[2], - false) - return - else - minetest.chat_send_player(playername, - "factionsmod: FAILED to join faction " .. - params[2], - false) - return - end - else - minetest.chat_send_player(playername, - "factionsmod: you are not allowed to join " .. params[2], - false) - return - end + if params[2] then + local factionname = params[2] + local faction = factionsmod.factons[factionname] + if not faction then + --TODO: error (faction doesn't exist) + else + if faction:can_join(playername) then + if player_faction then -- leave old faction + player_faction:remove_player(playername) + --TODO: message + end + faction:add_player(playername) + else + --TODO: error (could not join faction) + end + end end end + + if cmd == "disband" then + if player_faction:has_permission(playername, "disband") then + player_faction:disband() + else + --TODO: error (no permission) + end + end + + if cmd == "close" then + if player_faction:has_permission(playername, "playerlist") then + player_faction:toggle_join_free(false) + else + --TODO: error (no permission) + end + end + + if cmd == "open" then + if player_faction:has_permission(playername, "playerlist") then + player_faction:toggle_join_free(true) + else + --TODO: error (no permission) + end + end + + if cmd == "description" then + if player_faction:has_permission(playername, "description") then + local description = {} + for i=2, #params, 1 do + table.insert(description, params[i]) + end + player_faction:set_description(description.concat(" ")) + else + --TODO: error (no permission) + end + end + + if cmd == "invite" then + if params[2] then + if player_faction:has_permission(playername, "playerlist") then + player_faction:invite_player(params[2]) + else + --TODO: error (no permission) + end + else + --TODO: error (player unspecified) + end + end + + if cmd == "uninvite" then + if params[2] then + if player_faction:has_permission(playername, "playerlist") then + player_faction:revoke_invite(params[2]) + else + --TODO: error (no permission) + end + else + --TODO: error (player unspecified) + end + end --all following commands require at least two parameters - if params[2] ~= nil then - if minetest.check_player_privs(playername,{ faction_admin=true }) or - factionsmod.is_admin(params[2],playername) then + if params[2] then + if minetest.check_player_privs(playername,{ faction_admin=true }) then --delete faction if cmd == "delete" then - factionsmod.member_remove(params[2],player) - if factionsmod.delete_faction(params[2]) then - minetest.chat_send_player(playername, - "factionsmod: deleted faction " .. params[2], - false) - return - else - minetest.chat_send_player(playername, - "factionsmod: FAILED to deleted faction " .. params[2], - false) - return - end + faction = factionsmod.factions[params[2]] + if faction then + faction:disband() + --TODO: message + else + --TODO: error (no such faction) + end end - if cmd == "set_free" then - if params[3] ~= nil and - (params[3] == "true" or params[3] == "false")then - - local value = false - if params[3] == "true" then - value = true - end - - if factionsmod.set_free(params[2],value) then - minetest.chat_send_player(playername, - "factionsmod: free to join for " .. params[2] .. - " has been set to " .. params[3], - false) - else - minetest.chat_send_player(playername, - "factionsmod: FAILED to set free to join for " .. - params[2], - false) - end - end - end - - --set player admin status - if cmd == "admin" then - if params[3] ~= nil and params[4] ~= nil and - (params[4] == "true" or params[4] == "false") then - - local value = false - if params[4] == "true" then - value = true - end - - if factionsmod.set_admin(params[2],params[3],value) then - minetest.chat_send_player(playername, - "factionsmod: adminstate of " .. params[3] .. - " has been set to " .. params[4], - false) - else - minetest.chat_send_player(playername, - "factionsmod: FAILED to set admin privileges for " .. - params[3], - false) - end - end - return - end - - if cmd == "description" and - params[2] ~= nil and - params[3] ~= nil then - - local desc = params[3] - for i=4, #params, 1 do - desc = desc .. " " .. params[i] - end - if factionsmod.set_description(params[2],desc) then - minetest.chat_send_player(playername, - "factionsmod: updated description of faction " .. - params[2], - false) - return - else - minetest.chat_send_player(playername, - "factionsmod: FAILED to update description of faction " .. - params[2], - false) - return - end - end - - if cmd == "invite" and - params[2] ~= nil and - params[3] ~= nil then - if factionsmod.member_invite(params[2],params[3]) then - minetest.chat_send_player(params[3], - "factionsmod: " .. params[3] .. - " you have been invited to join faction " .. params[2], - false) - minetest.chat_send_player(playername, - "factionsmod: " .. params[3] .. - " has been invited to join faction " .. params[2], - false) - return - else - minetest.chat_send_player(playername, - "factionsmod: FAILED to invite " .. params[3] .. - " to join faction " .. params[2], - false) - return - end - end end end factionsmod_chat.show_help(playername) end -------------------------------------------------------------------------------- --- name: allfactionsmod_chathandler(playername,parameter) --- ---! @brief chat handler ---! @memberof factionsmod_chat ---! @private --- ---! @param playername name ---! @param parameter data supplied to command -------------------------------------------------------------------------------- -function factionsmod_chat.allfactionsmod_chathandler(playername,parameter) - - local player = minetest.env:get_player_by_name(playername) - - if player ~= nil then - local recipients = {} - - for faction,value in pairs(factionsmod.get_factionsmod(player)) do - for name,value in pairs(factionsmod.dynamic_data.membertable[faction]) do - local object_to_check = mientest.env:get_player_by_name(name) - - if object_to_check ~= nil then - recipients[name] = true - end - end - end - - for recipient,value in pairs(recipients) do - if recipient ~= playername then - minetest.chat_send_player(recipient,playername ..": " .. parameter,false) - end - end - return - end - factionsmod_chat.show_help(playername) -end - -------------------------------------------------------------------------------- --- name: chathandler(playername,parameter) --- ---! @brief chat handler ---! @memberof factionsmod_chat ---! @private --- ---! @param playername name ---! @param parameter data supplied to command -------------------------------------------------------------------------------- -function factionsmod_chat.chathandler(playername,parameter) - - local player = minetest.env:get_player_by_name(playername) - - if player ~= nil then - local line = parameter:split(" ") - local target_faction = line[1] - - local text = line[2] - for i=3,#line,1 do - text = text .. " " .. line[i] - end - - local valid_faction = false - - for faction,value in pairs(factionsmod.get_factionsmod(player)) do - if target_faction == faction then - valid_faction = true - end - end - - if faction ~= nil and valid_faction and - factionsmod.dynamic_data.membertable[faction] ~= nil then - for name,value in pairs(factionsmod.dynamic_data.membertable[faction]) do - local object_to_check = mientest.env:get_player_by_name(name) - factionsmod_chat.show_help(playername) - if object_to_check ~= nil and - name ~= playername then - minetest.chat_send_player(name,playername ..": " .. text,false) - end - end - else - minetest.chat_send_player(playername, - "factionsmod: you're not a member of " .. dump(faction),false) - end - return - end - factionsmod_chat.show_help(playername) -end - ------------------------------------------------------------------------------- -- name: show_help(playername,parameter) -- @@ -453,10 +305,10 @@ function factionsmod_chat.show_help(playername) MSG("factionsmod mod") MSG("Usage:") MSG("\tUser commands:") - MSG("\t\t/factionsmod -> info on your current factionsmod") + MSG("\t\t/factionsmod -> info on your current faction") MSG("\t\t/factionsmod info -> show description of faction") - MSG("\t\t/factionsmod list -> show list of factionsmod") - MSG("\t\t/factionsmod leave -> leave specified faction") + MSG("\t\t/factionsmod list -> show list of factions") + MSG("\t\t/factionsmod leave -> leave current faction") MSG("\t\t/factionsmod join -> join specified faction") MSG("\t\t/factionsmod version -> show version number of mod") @@ -469,3 +321,4 @@ function factionsmod_chat.show_help(playername) MSG("\t\t/factionsmod admin -> make player admin of faction") MSG("\t\t/factionsmod description -> set description for faction") end + diff --git a/factionsmod.lua b/factionsmod.lua index b0869a2..bb27edb 100644 --- a/factionsmod.lua +++ b/factionsmod.lua @@ -20,11 +20,9 @@ local factionsmod_worldid = minetest.get_worldpath() factionsmod = {} --! @brief runtime data -factionsmod.data = {} -factionsmod.data.factionsmod = {} -factionsmod.data.objects = {} -factionsmod.dynamic_data = {} -factionsmod.dynamic_data.membertable = {} +factionsmod.factions = {} +factionsmod.chunks = {} +factionsmod.players = {} factionsmod.print = function(text) print("factionsmod: " .. dump(text)) @@ -34,6 +32,191 @@ factionsmod.dbg_lvl1 = function() end --factionsmod.print -- errors factionsmod.dbg_lvl2 = function() end --factionsmod.print -- non cyclic trace factionsmod.dbg_lvl3 = function() end --factionsmod.print -- cyclic trace +factionsmod.factions = {} +--- settings +factionsmod.lower_claimable_height = -512 + +--------------------- +--! @brief returns whether a faction can be created or not (allows for implementation of blacklists and the like) +factionsmod.can_create_faction = function(name) + if factionsmod.factions[name] then + return false + else + return true + end, +end + +--------------------- +--! @brief create a faction object +factionsmod.new_faction = function(name) + local faction = { + name = name, + power = 0., + players = {}, + ranks = {["leader"] = {"disband", "claim", "playerlist", "build", "edit"}, + ["member"] = {"build"} + }, + leader = nil, + default_rank = "member", + default_leader_rank = "leader", + description = "Default faction description.", + invited_players = {}, + land = {}, + allies = {}, + enemies = {}, + join_free = false + + ---------------------- + -- methods + increase_power = function(self, power) + self.power = self.power + power + end, + decrease_power = function(self, power) + self.power = self.power - power + end, + add_player = function(self, player, rank) + self.players[player] = rank or self.default_rank + self:on_player_join(player) + self.invited_players[player] = nil + end, + remove_player = function(self, player) + self.players[player] = nil + self:on_player_leave(player) + end, + claim_chunk = function(self, chunkpos) + factionsmod.chunks[chunkpos] = self.name + self.land[chunkpos] = true + self:on_claim_chunk(chunkpos) + end, + unclaim_chunk = function(self, chunkpos) + factionsmod.chunks[chunkpos] = nil + self.land[chunkpos] = nil + self:on_unclaim_chunks(chunkpos) + end, + disband = function(self) + factionsmod.factions[self.name] = nil + for i in ipairs(self.players) do -- remove players affiliation + factionsmod.players[self.players[i]] = nil + end + for k, v in self.land do -- remove chunk claims + factionsmod.chunks[v] = nil + end + self:on_disband() + end, + set_leader = function(self, player) + self.leader = player + self.players[player] = self.default_leader_rank + self:on_new_leader() + end, + has_permission = function(self, player, permission) + local p = self.players[player] + if not p then + return false + end + return table.contains(self.groups[p], permission) + end, + set_description = function(self, new) + self.description = new + self:on_change_description() + end, + invite_player = function(self, player) + self.invited_players[player] = true + self:on_player_invited(player) + end, + revoke_invite = function(self, player) + self.invited_player[player = nil + self:on_revoke_invite(player) + end, + is_invited = function(self, player) + return table.contains(self.invited_players, player) + end, + toggle_join_free = function(self, bool) + self.join_free = bool + self:on_toggle_join_free() + end, + can_join = function(self, player) + return self.join_free or invited_players[player] + end, + new_alliance = function(self, faction) + self.allies[faction] = true + self:on_new_alliance(faction) + if self.enemies[faction] then + self:end_enemy(faction) + end + end, + end_alliance = function(self, faction) + self.allies[faction] = nil + self:on_end_alliance(faction) + end, + new_enemy = function(self, faction) + self.enemies[faction] = true + self:on_new_enemy[faction] + if self.allies[faction] then + self:end_alliance(faction) + end + end, + end_enemy = function(self, faction) + self.enemies[faction] = nil + self:on_end_enemy[faction] + end, + + ----------------------- + -- callbacks for events + on_create = function(self) --! @brief called when the faction is added to the global faction list + --TODO: implement + end, + on_player_leave = function(self, player) + --TODO: implement + end, + on_player_join = function(self, player) + --TODO: implement + end, + on_claim_chunk = function(self, pos) + --TODO: implement + end, + on_unclaim_chunk = function(self, pos) + --TODO: implement + end, + on_disband = function(self, pos) + --TODO: implement + end, + on_new_leader = function(self) + --TODO: implement + end, + on_change_description = function(self) + --TODO: implement + end, + on_player_invited = function(self, player) + --TODO: implement + end, + on_toggle_join_free = function(self, player) + --TODO: implement + end, + on_new_alliance = function(self, faction) + --TODO: implement + end, + on_end_alliance = function(self, faction) + --TODO: implement + end, + } + factionsmod[name] = faction + return faction +end + +--?????????????? +function factionsmod.fix_powercap(name) + factionsmod.data.factionsmod[name].powercap = #factionsmod.dynamic_data.membertable[name] + 10 +end +--?????????????? + +function factionsmod.get_chunk(pos) + return factionsmod.chunks[factionsmod.get_chunkpos(pos)] +end + +function factionsmod.get_chunkpos(pos) + return {math.floor(pos.x / 16.), math.floor(pos.z / 16.)} + + ------------------------------------------------------------------------------- -- name: add_faction(name) -- @@ -43,199 +226,16 @@ factionsmod.dbg_lvl3 = function() end --factionsmod.print -- cyclic trace -- --! @param name of faction to add --! ---! @return true/false (succesfully added faction or not) +--! @return faction object/false (succesfully added faction or not) ------------------------------------------------------------------------------- -function factionsmod.fix_powercap(name) - factionsmod.data.factionsmod[name].powercap = #factionsmod.dynamic_data.membertable[name] + 10 -end function factionsmod.add_faction(name) - - if factionsmod.data.factionsmod[name] == nil then - factionsmod.data.factionsmod[name] = {} - factionsmod.data.factionsmod[name].reputation = {} - factionsmod.data.factionsmod[name].base_reputation = {} - factionsmod.data.factionsmod[name].adminlist = {} - factionsmod.data.factionsmod[name].invitations = {} - factionsmod.data.factionsmod[name].owner = "" - factionsmod.data.factionsmod[name].land = 0 - factionsmod.data.factionsmod[name].power = 10 - factionsmod.data.factionsmod[name].powercap = 10 - factionsmod.data.factionsmod[name].chunk = {} - factionsmod.dynamic_data.membertable[name] = {} - - factionsmod.save() - - return true - end - - return false -end - -------------------------------------------------------------------------------- --- name: set_base_reputation(faction1,faction2,value) --- ---! @brief set base reputation between two factionsmod ---! @memberof factionsmod ---! @public --- ---! @param faction1 first faction ---! @param faction2 second faction ---! @param value value to use ---! ---! @return true/false (succesfully added faction or not) -------------------------------------------------------------------------------- -function factionsmod.set_base_reputation(faction1,faction2,value) - - if factionsmod.data.factionsmod[faction1] ~= nil and - factionsmod.data.factionsmod[faction2] ~= nil then - - factionsmod.data.factionsmod[faction1].base_reputation[faction2] = value - factionsmod.data.factionsmod[faction2].base_reputation[faction1] = value - factionsmod.save() - return true - end - return false -end - -------------------------------------------------------------------------------- --- name: get_base_reputation(faction1,faction2) --- ---! @brief get base reputation between two factionsmod ---! @memberof factionsmod ---! @public --- ---! @param faction1 first faction ---! @param faction2 second faction ---! ---! @return reputation/0 if none set -------------------------------------------------------------------------------- -function factionsmod.get_base_reputation(faction1,faction2) - factionsmod.dbg_lvl3("get_base_reputation: " .. faction1 .. "<-->" .. faction2) - if factionsmod.data.factionsmod[faction1] ~= nil and - factionsmod.data.factionsmod[faction2] ~= nil then - if factionsmod.data.factionsmod[faction1].base_reputation[faction2] ~= nil then - return factionsmod.data.factionsmod[faction1].base_reputation[faction2] - end - end - return 0 -end - -function factionsmod.testifallowed(pos,digger) -if pos.y < -512 then -return true -end -if next(factionsmod.get_faction_list()) ~= nil then - for k,v in pairs(factionsmod.get_faction_list()) do - --minetest.log("warning",v) - if factionsmod.data.factionsmod[v].chunk ~= nil then - for i =1, #factionsmod.data.factionsmod[v].chunk do - if factionsmod.data.factionsmod[v].chunk[i][1] == math.floor(pos.x/16.0) then - if factionsmod.data.factionsmod[v].chunk[i][2] == math.floor(pos.z/16.0) then - print('test') - if digger == nil then - return false - end - if next(factionsmod.get_factionsmod(digger)) == nil then -return false -end - for k2,v2 in pairs(factionsmod.get_factionsmod(digger)) do - print(v2) - if v2 == nil or v2 ~= v then - print('not allowed') - return false - end - end - - end - end - end - end - end - end - return true -end -function factionsmod.findchunkowner(pos) -if pos.y < -512 then -return "" -end -if next(factionsmod.get_faction_list()) ~= nil then - for k,v in pairs(factionsmod.get_faction_list()) do - --minetest.log("warning",v) - if factionsmod.data.factionsmod[v].chunk ~= nil then - for i =1, #factionsmod.data.factionsmod[v].chunk do - if factionsmod.data.factionsmod[v].chunk[i][1] == math.floor(pos.x/16.0) then - if factionsmod.data.factionsmod[v].chunk[i][2] == math.floor(pos.z/16.0) then - return v - - end - end - end - end - end - end - return "" -end -------------------------------------------------------------------------------- --- name: set_description(name,description) --- ---! @brief set description for a faction ---! @memberof factionsmod ---! @public --- ---! @param name of faction ---! @param description text describing a faction ---! ---! @return true/false (succesfully set description) -------------------------------------------------------------------------------- -function factionsmod.set_description(name,description) - - if factionsmod.data.factionsmod[name] ~= nil then - factionsmod.data.factionsmod[name].description = description - factionsmod.save() - return true - end - return false -end - -------------------------------------------------------------------------------- --- name: get_description(name) --- ---! @brief get description for a faction ---! @memberof factionsmod ---! @public --- ---! @param name of faction ---! ---! @return description or "" -------------------------------------------------------------------------------- -function factionsmod.get_description(name) - - if factionsmod.data.factionsmod[name] ~= nil and - factionsmod.data.factionsmod[name].description ~= nil then - return factionsmod.data.factionsmod[name].description - end - return "" -end - -------------------------------------------------------------------------------- --- name: exists(name) --- ---! @brief check if a faction exists ---! @memberof factionsmod ---! @public ---! @param name name to check ---! ---! @return true/false -------------------------------------------------------------------------------- -function factionsmod.exists(name) - - for key,value in pairs(factionsmod.data.factionsmod) do - if key == name then - return true - end - end - - return false + if factionsmod.can_create_faction(name) then + local fac = factionsmod.new_faction(name) + fac:on_create() + return fac + else + return nil + end, end ------------------------------------------------------------------------------- @@ -251,538 +251,13 @@ function factionsmod.get_faction_list() local retval = {} - for key,value in pairs(factionsmod.data.factionsmod) do + for key,value in pairs(factionsmod.factions) do table.insert(retval,key) end return retval end -------------------------------------------------------------------------------- --- name: delete_faction(name) --- ---! @brief delete a faction ---! @memberof factionsmod ---! @public --- ---! @param name of faction to delete ---! ---! @return true/false (succesfully added faction or not) -------------------------------------------------------------------------------- -function factionsmod.delete_faction(name) - - for k,v in pairs(factionsmod.dynamic_data.membertable[name]) do - factionsmod.member_remove(name,v) - end - factionsmod.data.factionsmod[name] = nil - - factionsmod.save() - - if factionsmod.data.factionsmod[name] == nil then - return true - end - - return false -end - -------------------------------------------------------------------------------- --- name: member_add(name,object) --- ---! @brief add an entity or player to a faction ---! @memberof factionsmod ---! @public --- ---! @param name of faction to add object to ---! @param object to add to faction ---! ---! @return true/false (succesfully added faction or not) -------------------------------------------------------------------------------- -function factionsmod.takeover(name,player) -local pos = player:getpos() -local is_not_owned = factionsmod.testifallowed(pos,player) -if is_not_owned == false then -local owner = factionsmod.findchunkowner(pos) -if factionsmod.data.factionsmod[owner].land > factionsmod.data.factionsmod[owner].power then -factionsmod.unclaim(owner,player) -factionsmod.claim(name,player) -end -end -end -function factionsmod.claim(name,player) - --if factionsmod.data.factionsmod[name].chunk ~= nil then - local pos = player:getpos() - local is_not_owned = factionsmod.testifallowed(pos,nil) - if is_not_owned == true then - print(name) - print(player) - print(dump(factionsmod.data.factionsmod)) - table.insert(factionsmod.data.factionsmod[name].chunk,{}) - factionsmod.data.factionsmod[name].chunk[#factionsmod.data.factionsmod[name].chunk][1] = math.floor(pos.x/16.0) - factionsmod.data.factionsmod[name].chunk[#factionsmod.data.factionsmod[name].chunk][2] = math.floor(pos.z/16.0) - end - --end -end -function factionsmod.unclaim(name,player) - local pos = player:getpos() - local is_not_owned = factionsmod.testifallowed(pos,nil) - if is_not_owned == false then - for i =1, #factionsmod.data.factionsmod[name].chunk do - if chunk[i][1] == math.floor(pos.x/16.0) and chunk[i][2] == math.floor(pos.z/16.0) then - table.remove(factionsmod.data.factionsmod[name].chunk,i) - - end - end - - - end -end -function factionsmod.member_add(name, object) - local new_entry = {} - new_entry.factionsmod = {} - - if object.object ~= nil then - object = object.object - end - if next(factionsmod.get_factionsmod(object)) ~= nil then - for k,v in pairs(factionsmod.get_factionsmod(object)) do - if k ~= nil then - factionsmod.member_remove(v,object) - end - end - end - if not factionsmod.exists(name) then - print("Unable to add to NON existant faction >" .. name .. "<") - return false - end - - new_entry.name,new_entry.temporary = factionsmod.get_name(object) - - factionsmod.dbg_lvl2("Adding name=" .. dump(new_entry.name) .. " to faction: " .. name ) - - if new_entry.name ~= nil then - if factionsmod.data.objects[new_entry.name] == nil then - factionsmod.data.objects[new_entry.name] = new_entry - end - - if factionsmod.data.objects[new_entry.name].factionsmod[name] == nil then - factionsmod.data.objects[new_entry.name].factionsmod[name] = true - factionsmod.dynamic_data.membertable[name][new_entry.name] = true - factionsmod.data.factionsmod[name].invitations[new_entry.name] = nil - if factionsmod.data.factionsmod[name].owner == "" then - factionsmod.data.factionsmod[name].owner = object:get_player_name() - factionsmod.set_admin(name,object:get_player_name(), true) - end - factionsmod.data.factionsmod[name].power = factionsmod.data.factionsmod[name].power + 1 - factionsmod.data.factionsmod[name].powercap = factionsmod.data.factionsmod[name].powercap + 1 - factionsmod.save() - return true - end - end - - --return false if no valid object or already member - return false -end - -------------------------------------------------------------------------------- --- name: member_invite(name,playername) --- ---! @brief invite a player for joining a faction ---! @memberof factionsmod ---! @public --- ---! @param name of faction to add object to ---! @param name of player to invite ---! ---! @return true/false (succesfully added invitation or not) -------------------------------------------------------------------------------- -function factionsmod.member_invite(name, playername) - - if factionsmod.data.factionsmod[name] ~= nil and - factionsmod.data.factionsmod[name].invitations[playername] == nil then - factionsmod.data.factionsmod[name].invitations[playername] = true - factionsmod.save() - return true - end - - --return false if not a valid faction or player already invited - return false -end - -------------------------------------------------------------------------------- --- name: member_remove(name,object) --- ---! @brief remove an entity or player to a faction ---! @memberof factionsmod ---! @public --- ---! @param name of faction to add object to ---! @param object to add to faction ---! ---! @return true/false (succesfully added faction or not) -------------------------------------------------------------------------------- -function factionsmod.member_remove(name,object) - - local id,type = factionsmod.get_name(object) - - factionsmod.dbg_lvl2("removing name=" .. dump(id) .. " to faction: " .. name ) - - if id ~= nil and - factionsmod.data.objects[id] ~= nil and - factionsmod.data.objects[id].factionsmod[name] ~= nil then - factionsmod.data.objects[id].factionsmod[name] = nil - factionsmod.dynamic_data.membertable[name][id] = nil - if factionsmod.data.factionsmod[name].owner == object:get_player_name() then - factionsmod.delete_faction(name) - end - factionsmod.data.factionsmod[name].power = factionsmod.data.factionsmod[name].power - 1 - factionsmod.data.factionsmod[name].powercap = factionsmod.data.factionsmod[name].powercap - 1 - factionsmod.save() - return true - end - - if id ~= nil and - factionsmod.data.factionsmod[name].invitations[id] ~= nil then - factionsmod.data.factionsmod[name].invitations[id] = nil - factionsmod.save() - return true - end - - return false -end - -------------------------------------------------------------------------------- --- name: set_admin(name,playername,value) --- ---! @brief set admin priviles for a playername ---! @memberof factionsmod ---! @public --- ---! @param name of faction to add object to ---! @param playername to change rights ---! @param value true/false has or has not admin privileges ---! ---! @return true/false (succesfully changed privileges) -------------------------------------------------------------------------------- -function factionsmod.set_admin(name,playername,value) - --mobf_assert_backtrace(type(playername) == "string") - if factionsmod.data.factionsmod[name] ~= nil then - if value then - factionsmod.data.factionsmod[name].adminlist[playername] = true - factionsmod.save() - return true - else - factionsmod.data.factionsmod[name].adminlist[playername] = nil - factionsmod.save() - return true - end - else - print("factionsmod: no faction >" .. name .. "< found") - end - - return false -end - -------------------------------------------------------------------------------- --- name: set_free(name,value) --- ---! @brief set faction to be joinable by everyone ---! @memberof factionsmod ---! @public --- ---! @param name of faction to add object to ---! @param value true/false has or has not admin privileges ---! ---! @return true/false (succesfully added faction or not) -------------------------------------------------------------------------------- -function factionsmod.set_free(name,value) - - if factionsmod.data.factionsmod[name] ~= nil then - if value then - if factionsmod.data.factionsmod[name].open == nil then - factionsmod.data.factionsmod[name].open = true - factionsmod.save() - return true - else - return false - end - else - if factionsmod.data.factionsmod[name].open == nil then - return false - else - factionsmod.data.factionsmod[name].open = nil - factionsmod.save() - return true - end - end - end - - return false -end - -------------------------------------------------------------------------------- --- name: is_free(name) --- ---! @brief check if a fraction is free to join ---! @memberof factionsmod ---! @public --- ---! @param name of faction to add object to --- ---! @return true/false (free or not) -------------------------------------------------------------------------------- -function factionsmod.is_free(name) - if factionsmod.data.factionsmod[name] ~= nil and - factionsmod.data.factionsmod[name].open then - return true - end - - return false -end - -------------------------------------------------------------------------------- --- name: is_admin(name,playername) --- ---! @brief read admin privilege of player ---! @memberof factionsmod ---! @public --- ---! @param name of faction to check rights ---! @param playername to change rights ---! ---! @return true/false (succesfully added faction or not) -------------------------------------------------------------------------------- -function factionsmod.is_admin(name,playername) - - if factionsmod.data.factionsmod[name] ~= nil and - factionsmod.data.factionsmod[name].adminlist[playername] == true then - return true - end - - return false -end - -------------------------------------------------------------------------------- --- name: is_invited(name,playername) --- ---! @brief read invitation status of player ---! @memberof factionsmod ---! @public --- ---! @param name of faction to check for invitation ---! @param playername to change rights ---! ---! @return true/false (succesfully added faction or not) -------------------------------------------------------------------------------- -function factionsmod.is_invited(name,playername) - - if factionsmod.data.factionsmod[name] ~= nil and - ( factionsmod.data.factionsmod[name].invitations[playername] == true or - factionsmod.data.factionsmod[name].open == true) then - return true - end - - return false -end - -------------------------------------------------------------------------------- --- name: get_factionsmod(object) --- ---! @brief get list of factionsmod for an object ---! @memberof factionsmod ---! @public --- ---! @param object to get list for ---! ---! @return list of factionsmod -------------------------------------------------------------------------------- -function factionsmod.get_factionsmod(object) - - local id,type = factionsmod.get_name(object) - - local retval = {} - if id ~= nil and - factionsmod.data.objects[id] ~= nil then - for key,value in pairs(factionsmod.data.objects[id].factionsmod) do - table.insert(retval,key) - end - end - - return retval -end - -------------------------------------------------------------------------------- --- name: is_member(name,object) --- ---! @brief check if object is member of name ---! @memberof factionsmod ---! @public --- ---! @param name of faction to check ---! @param object to check ---! ---! @return true/false -------------------------------------------------------------------------------- -function factionsmod.is_member(name,object) - - local retval = false - - local id,type = factionsmod.get_name(object) - - if id ~= nil and - factionsmod.data.objects[id] ~= nil then - for key,value in pairs(factionsmod.data.objects[id].factionsmod) do - if key == name then - retval = true - break - end - end - end - - return retval -end - - -------------------------------------------------------------------------------- --- name: get_reputation(name,object) --- ---! @brief get reputation of an object ---! @memberof factionsmod ---! @public --- ---! @param name name of faction to check for reputation ---! @param object object to get reputation for ---! ---! @return number value -100 to 100 0 being neutral, -100 beeing enemy 100 friend -------------------------------------------------------------------------------- -function factionsmod.get_reputation(name,object) - - local id,type = factionsmod.get_name(object) - - factionsmod.dbg_lvl3("get_reputation: " .. name .. "<-->" .. dump(id)) - - if id ~= nil and - factionsmod.data.factionsmod[name] ~= nil then - - factionsmod.dbg_lvl3("get_reputation: object reputation: " .. dump(factionsmod.data.factionsmod[name].reputation[id])) - - if factionsmod.data.factionsmod[name].reputation[id] == nil then - factionsmod.data.factionsmod[name].reputation[id] - = factionsmod.calc_base_reputation(name,object) - end - - return factionsmod.data.factionsmod[name].reputation[id] - else - factionsmod.dbg_lvl3("get_reputation: didn't find any factionsmod for: " .. name) - end - - return 0 -end - -------------------------------------------------------------------------------- --- name: modify_reputation(name,object,delta) --- ---! @brief modify reputation of an object for a faction ---! @memberof factionsmod ---! @public --- ---! @param name name of faction to modify reputation ---! @param object object to change reputation ---! @param delta value to change reputation ---! ---! @return true/false -------------------------------------------------------------------------------- -function factionsmod.modify_reputation(name,object,delta) - - local id,type = factionsmod.get_name(object) - - if factionsmod.data.factionsmod[name] ~= nil then - if factionsmod.data.factionsmod[name].reputation[id] == nil then - factionsmod.data.factionsmod[name].reputation[id] - = factionsmod.calc_base_reputation(name,object) - end - - factionsmod.data.factionsmod[name].reputation[id] - = factionsmod.data.factionsmod[name].reputation[id] + delta - factionsmod.save() - return true - end - - return false -end - -------------------------------------------------------------------------------- --- name: get_name(object) --- ---! @brief get textual name of object ---! @memberof factionsmod ---! @private --- ---! @param object fetch name for this ---! ---! @return name or nil,is temporary element -------------------------------------------------------------------------------- -function factionsmod.get_name(object) - if object == nil then - return nil,true - end - - if object.object ~= nil then - object = object.object - end - - if object:is_player() then - return object:get_player_name(),false - else - local luaentity = object:get_luaentity() - - if luaentity ~= nil then - return tostring(luaentity),true - end - end - - return nil,true -end - -------------------------------------------------------------------------------- --- name: calc_base_reputation(name,object) --- ---! @brief calculate initial reputation of object within a faction ---! @memberof factionsmod ---! @private --- ---! @param name name of faction ---! @param object calc reputation for this ---! ---! @return reputation value -------------------------------------------------------------------------------- -function factionsmod.calc_base_reputation(name,object) - - --calculate initial reputation based uppon all groups - local object_factionsmod = factionsmod.get_factionsmod(object) - local rep_value = 0 - - factionsmod.dbg_lvl3("calc_base_reputation: " .. name .. " <--> " .. tostring(object)) - - if object_factionsmod ~= nil then - factionsmod.dbg_lvl3("calc_base_reputation: " .. tostring(object) .. " is in " .. #object_factionsmod .. " factionsmod") - for k,v in pairs(object_factionsmod) do - if factionsmod.data.factionsmod[v] == nil then - print("factionsmod: warning object is member of faction " .. v .. " which doesn't exist") - else - factionsmod.dbg_lvl3("calc_base_reputation: " .. name .. " <--> " .. v .. " rep=" .. dump(factionsmod.data.factionsmod[v].base_reputation[name])) - if factionsmod.data.factionsmod[v].base_reputation[name] ~= nil then - rep_value = - rep_value + factionsmod.data.factionsmod[v].base_reputation[name] - end - end - end - - rep_value = rep_value / #object_factionsmod - end - - return rep_value -end - ------------------------------------------------------------------------------- -- name: save() -- @@ -790,11 +265,6 @@ end --! @memberof factionsmod --! @private ------------------------------------------------------------------------------- -function factionsmod.enumerateland(name) - if factionsmod.data.factionsmod[name] ~= nil then - factionsmod.data.factionsmod[name].land = #factionsmod.data.factionsmod[name].chunk - end -end function factionsmod.save() --saving is done much more often than reading data to avoid delay @@ -805,7 +275,7 @@ function factionsmod.save() local file,error = io.open(factionsmod_worldid .. "/" .. "factionsmod.conf","w") if file ~= nil then - file:write(minetest.serialize(factionsmod.data)) + file:write(minetest.serialize(factionsmod.factions)) file:close() else minetest.log("error","MOD factionsmod: unable to save factionsmod world specific data!: " .. error) @@ -827,117 +297,31 @@ function factionsmod.load() if file ~= nil then local raw_data = file:read("*a") + factionsmod.factions = minetest.deserialize(raw_data) + for facname, faction in pairs(factionsmod.factions) do + for i in ipairs(faction.players) do + factionsmod.players[faction.players[i]] = facname + end + for chunkpos, val in pairs(faction.land) do + factionsmod.chunks[chunkpos] = val + end + end file:close() - - if raw_data ~= nil and - raw_data ~= "" then - - local raw_table = minetest.deserialize(raw_data) - - - --read object data - local temp_objects = {} - - if raw_table.objects ~= nil then - for key,value in pairs(raw_table.objects) do - - if value.temporary == false then - factionsmod.data.objects[key] = value - else - temp_objects[key] = true - end - end - end - - if raw_table.factionsmod ~= nil then - for key,value in pairs(raw_table.factionsmod) do - factionsmod.data.factionsmod[key] = {} - factionsmod.data.factionsmod[key].base_reputation = value.base_reputation - factionsmod.data.factionsmod[key].adminlist = value.adminlist - factionsmod.data.factionsmod[key].open = value.open - factionsmod.data.factionsmod[key].invitations = value.invitations - factionsmod.data.factionsmod[key].chunk = value.chunk - factionsmod.data.factionsmod[key].power = value.power - factionsmod.data.factionsmod[key].powercap = value.powercap - factionsmod.data.factionsmod[key].owner = value.owner - factionsmod.data.factionsmod[key].land = value.land - factionsmod.data.factionsmod[key].reputation = {} - factionsmod.enumerateland(key) - for repkey,repvalue in pairs(value.reputation) do - if temp_objects[repkey] == nil then - factionsmod.data.factionsmod[key].reputation[repkey] = repvalue - end - end - - factionsmod.dynamic_data.membertable[key] = {} - end - end - - --populate dynamic faction member table - for id,object in pairs(factionsmod.data.objects) do - for name,value in pairs(factionsmod.data.objects[id].factionsmod) do - if value then - factionsmod.dynamic_data.membertable[name][id] = true - end - - end - end - end - else - local file,error = io.open(factionsmod_worldid .. "/" .. "factionsmod.conf","w") - - if file ~= nil then - file:close() - else - minetest.log("error","MOD factionsmod: unable to save factionsmod world specific data!: " .. error) - end - end - - --create special faction players - --factionsmod.add_faction("players") - if next(factionsmod.get_faction_list()) ~= nil then - for k,v in pairs(factionsmod.get_faction_list()) do - factionsmod.fix_powercap(v) - end end - old_is_protected = minetest.is_protected - function minetest.is_protected(pos,name) - local player = minetest.get_player_by_name(name) - if factionsmod.testifallowed(pos,player) ~= true then - return true - end - return old_is_protected(pos,name) - end - --autojoin players to faction players - minetest.register_on_dieplayer( - function(player) - if next(factionsmod.get_factionsmod(object)) ~= nil then - for k,v in pairs(factionsmod.get_factionsmod(object)) do - if v ~= nil then - if factionsmod.data.factionsmod[v].power - 1 >= -factionsmod.data.factionsmod[v].powercap then - factionsmod.data.factionsmod[v].power = factionsmod.data.factionsmod[v].power - 1 - return true - end - end - end - end - end - ) - minetest.register_globalstep( - function(dtime) - if next(factionsmod.get_faction_list()) ~= nil then - for k,v in pairs(factionsmod.get_faction_list()) do - if factionsmod.data.factionsmod[v].power + (dtime/120.0) <= factionsmod.data.factionsmod[v].powercap then - factionsmod.data.factionsmod[v].power = factionsmod.data.factionsmod[v].power + (dtime/120.0) - end - end - end - end) - minetest.register_on_joinplayer( - function(player) - if player:is_player() then - --factionsmod.member_add("players",player) - end - end - ) + end end + +--autojoin players to faction players +minetest.register_on_dieplayer( + function(player) + end +) + +minetest.register_globalstep( + function(dtime) + end +) +minetest.register_on_joinplayer( + function(player) + end +)