294 Commits

Author SHA1 Message Date
7db1b30542 Show: both long and short cmds in help 2020-01-03 20:07:29 -06:00
d267e7ad97 Add: long name for privs 2020-01-03 17:16:16 -06:00
5c46eb1188 Add: long name for motd 2020-01-03 17:15:47 -06:00
d8abcbb05b Add: long name to description cmd 2020-01-03 16:57:27 -06:00
3b1d02fd33 Subcmd: flags cmd 2020-01-02 18:58:16 -06:00
8e2a92b792 Accept: cmds with formatting 2020-01-02 18:57:52 -06:00
d64425ade8 Carefully: override don't show in help 2020-01-02 18:48:49 -06:00
ae09c39950 Fix: crash 2020-01-01 23:13:01 -06:00
ea15d7ef6f Don't: show the next cmd in array 2019-12-31 22:02:48 -06:00
78e6d54576 Add: unclaim as a subcmd 2019-12-31 21:58:08 -06:00
52b9000960 Remove: root 2019-12-31 21:35:08 -06:00
9c4334e19c Count: cmd word spaces 2019-12-31 21:33:28 -06:00
a01d80dd80 Add: subcommands 2019-12-31 20:50:30 -06:00
37050bf225 Update: config 2019-12-31 19:29:10 -06:00
01a13d6b8f Drop: support for colddb 2019-12-31 19:28:24 -06:00
e16e72956f Remove: util 2019-12-31 19:01:15 -06:00
b0301130dc Make: mod into modpack 2019-12-16 18:23:32 -06:00
54389cda26 Fix: error message 2019-10-10 22:01:56 -05:00
ee5763b027 shorten: rank_privileges 2019-09-14 15:44:19 -05:00
15d0d98937 Code: clean up part 0 2019-09-14 14:50:43 -05:00
6f953b27d4 Re-order: register_command params 2019-07-20 18:01:54 -05:00
a98d1893f8 Uncomment: update_data 2019-07-07 16:42:02 -05:00
0a91ad8e6c Add: mod storage database 2019-07-07 16:33:04 -05:00
0dd50e7141 Remove: optional_depends 2019-06-29 14:57:55 -05:00
c531294335 Auto: add missing table properties 2019-06-28 19:52:28 -05:00
5dfd32df1b Remove: ip if player is not in a faction 2019-06-28 19:11:50 -05:00
e962c88309 faction: protect can be bypassed now 2019-06-28 15:49:42 -05:00
d00c120cd5 Remove: whole keys only if empty 2019-06-28 15:43:28 -05:00
db914eec5a Allow: players, claims, and ips to store more data 2019-06-28 13:28:12 -05:00
e63b07cb99 Fix: player error 2019-06-28 09:48:51 -05:00
b911039102 Fix: typo 2019-06-28 09:47:00 -05:00
092be70b6f Allow: player db to store more data 2019-06-28 09:46:15 -05:00
a4a43aef2d Remove: converter code 2019-06-28 09:33:39 -05:00
7bd84b4728 Add: /claim list to help 2019-06-27 17:55:24 -05:00
fd664c6b54 Return: default_is_protected 2019-06-27 13:51:59 -05:00
0008628566 Fix: crash in diplomacy cmds 2019-06-27 12:41:37 -05:00
c8f3528a43 Allow: is_protected to work without player param 2019-05-24 14:40:58 -05:00
7fa6abd4aa Update /f (un)claim help 2019-05-23 16:52:38 -05:00
193828602b Fix: chat cmd not working 2019-05-22 18:43:41 -05:00
dbe7f4aabd Fix: crashing 2019-05-20 21:49:33 -05:00
b504eb6794 Fix: use iterate function 2019-05-20 21:33:59 -05:00
3567fb9e5e Remove: sound_play whoosh 2019-05-20 17:04:42 -05:00
49473f7ee1 Use: new colddb features 2019-05-20 00:03:36 -05:00
cb80681b9f Re-license: mod under MIT 2019-05-16 20:05:49 -05:00
f8c0862357 Update: config 2019-05-16 18:59:18 -05:00
8069ab2443 Make: protection_style a enum 2019-05-16 18:57:15 -05:00
aa6bd52fd2 Add: factions namespace to settingtypes 2019-05-16 18:52:57 -05:00
6bfd210d2c Remove: name from is_player_connected param 2019-05-16 17:57:46 -05:00
a1cebc3a24 Fix: who cmd crashes on invaild faction name 2019-05-07 10:35:42 -05:00
8e98bf8b62 Make: 2d the default protection style 2019-05-06 14:41:09 -05:00
21a854e522 Remove: factions_config from attack_parcel 2019-05-06 14:30:17 -05:00
5b4eee252f Do: not change the sign of max_depth 2019-05-06 12:30:44 -05:00
1d57b3d0af Return: default metadata on move, take, put 2019-05-05 17:23:45 -05:00
7cb2f688a6 Put: depends and description in mod.conf 2019-05-05 13:41:24 -05:00
b4a85766df Fix: crash on /f who when not in a faction 2019-05-04 14:09:20 -05:00
073c2288e3 Fix: crash in player_events 2019-05-03 00:27:59 -05:00
308932b9b5 Major update:
Add new features to claim and unclaim.
Sort help from a-z.
Sort functions into diff lua files.
2019-05-02 23:05:52 -05:00
9f08642b51 Fix: faction ownership not showing on some items 2019-04-02 16:38:18 -05:00
64c32baa13 Remove: player_title priv 2019-04-02 15:03:10 -05:00
28feb2fe54 Add: container perm to moderator rank by def 2019-03-18 12:17:37 -05:00
6049fe0aef Fix: not going to right path 2019-03-15 23:52:17 -05:00
263e863777 Support: new colddb 2019-03-15 23:48:34 -05:00
2e579c3d0c Add: invites cmd 2019-03-12 01:45:33 -05:00
11bc91e21f Remove: todo list 2019-03-11 18:42:41 -05:00
a6318db989 Bug fixes and support for ts_doors 2019-03-11 18:38:03 -05:00
464d68e6d9 Fix: factions crashes on tick 2019-02-05 14:46:55 -06:00
dd88c61009 Bug: you can promote someone in another faction 2019-01-26 13:15:28 -06:00
4e21583536 Fix: name missing from broadcast 2019-01-26 11:03:09 -06:00
87a31a1abb Use: colddb 2019-01-26 00:21:05 -06:00
accba69a15 Bug: join command will not delete your old team 2019-01-22 16:20:35 -06:00
c65bde260e Use: safe_file_write 2019-01-22 16:16:56 -06:00
3e63a1c657 Fix: door texture getting messed up 2019-01-22 16:13:48 -06:00
424ef678e7 Bug: doors had a error on open 2019-01-19 09:14:22 -06:00
fd6bf07064 Fix: chat cmd typo 2019-01-14 17:16:28 -06:00
cc50d94817 Combind diplomacy rank into one 2019-01-04 18:31:30 -06:00
421786121b Make: parcel positions more accurate 2018-12-27 01:22:46 -06:00
916060f34f If no diplomacy then make war by default 2018-12-27 01:16:11 -06:00
6c3d35c9b2 Combind some privs 2018-12-27 01:09:41 -06:00
269690d279 Fix: line 978 had a typo
new factions are neutral with everyone.
2018-12-26 21:26:27 -06:00
73b3fb300d Power-per-player bug fix.
It was not checking ips.
2018-11-02 13:37:51 -05:00
6765f66c6d Add bulk_save
Wait 5 seconds before saving. Just to take it easy on the harddisk. When the last player leaves it saves instantly.
2018-11-01 11:09:29 -05:00
c47102ca8a Update stats command. 2018-11-01 00:22:39 -05:00
186bcfd6ed Power hud display update 2018-10-31 23:55:42 -05:00
bc20ea080e Make the power command explain info better 2018-10-31 23:51:42 -05:00
4a037c538c Rename title to player_title 2018-10-31 23:25:13 -05:00
11b174f8e3 Bug fix.
Not a bad one but it needed to be fixed.
2018-10-31 16:55:53 -05:00
72e1475482 Set right power var 2018-10-31 16:17:24 -05:00
a419cd6c17 Major update 2 2018-10-31 16:15:08 -05:00
9dd577e699 Bug fix rankless.
Forgot to save.
2018-10-31 09:41:34 -05:00
3da45376c2 Safe fail. 2018-10-30 19:17:28 -05:00
235d91368f Add comments to config.lua 2018-10-30 18:44:44 -05:00
4a15fb3646 Add new cmd change_def_rank 2018-10-29 19:36:46 -05:00
e2f9cdb9f2 Add rankless 2018-10-29 19:16:39 -05:00
2d63b64cd3 Wait for the factions file to fully load. 2018-10-28 22:48:29 -05:00
79d38d4210 Store config data
Will help with the converter in the future.
2018-10-28 22:39:29 -05:00
bc54df4925 Fix data converter
I used a old factions version and created two teams with land claims and ranks. It converted fine. Make sure you pick the same parcel size as the old save file because if they are not they don't show up in the same spot or not at all.
2018-10-28 22:03:55 -05:00
c069828a28 Save current version 2018-10-28 00:06:44 -05:00
48e70baa50 Misc mod data
Made for auto converter.
2018-10-27 23:49:28 -05:00
d75c6a24ad Fix ip file not found. 2018-10-27 23:20:53 -05:00
f902419d25 Give is_admin purpose.
If a faction is set as an admin faction it will never be disbanded.
2018-10-27 23:14:52 -05:00
615c9464cc Delay for 5 seconds on all hud. 2018-10-27 22:37:49 -05:00
146df88de2 faction description bug fix.
The first words before a space was not displayed in the description.
2018-10-27 22:29:02 -05:00
6455736ad8 Free some admin commands.
Idea taken from sparky's server.
2018-10-27 22:19:59 -05:00
a9d8b58223 Make faction_user priv off by default 2018-10-27 20:57:15 -05:00
82a96ccea7 Delay creation of parcel hud.
For 5 seconds.
2018-10-27 20:20:01 -05:00
ee23ba96f8 Hud update. 2018-10-27 20:06:48 -05:00
ae678e83ef Add small delay for hud 2018-10-27 15:40:17 -05:00
a7c9d15282 Claim error message fix.
Used to say "Not enough power." for everything.
2018-10-27 14:11:13 -05:00
3bbf84896c Permission bug fix
If a player does not have a rank this function will crash the game.
2018-10-27 14:01:49 -05:00
f75a2ea008 Bug fix delrank
When you delete a rank like member the faction will still give new players that rank and cause errors because the rank is deleted.
2018-10-27 13:40:37 -05:00
e7fff79b78 Player leave bugfix. 2018-10-27 10:51:39 -05:00
33b9d59fa7 Chest bug fix. 2018-10-26 19:43:34 -05:00
80001c9a15 Faction chest bug fix
Faction chests can be dug up even tho they have stuff in them.
2018-10-26 18:42:10 -05:00
932645b5a0 Add set_message_of_the_day command 2018-10-25 00:21:42 -05:00
9f8db0615c New claim error message. 2018-10-22 23:03:11 -05:00
e2e868b802 Bug fix nag text. 2018-10-22 22:55:19 -05:00
338686bcbb Auto-convert old factions file.
And make diplomacy on by def.
2018-10-22 22:21:32 -05:00
2d89de5927 Disband bug fix.
Disband function was clearing out a shared player list.
2018-10-22 18:58:41 -05:00
76edf920fa Remove possible power exploit.
Players could join and leave a faction to regen power.
2018-10-22 16:22:22 -05:00
f5c050e240 Power system redo. 2018-10-22 14:34:12 -05:00
d481a8fa7a Bug fix. 2018-10-22 14:30:11 -05:00
1fa1cdcb0f Update LICENSE 2018-10-18 14:22:43 -05:00
0adf2808e4 Update todo list. 2018-10-18 14:19:26 -05:00
90ef6c54f3 License change. 2018-10-18 13:35:10 -05:00
9131bb4b22 Remove all banner code. 2018-10-18 00:36:28 -05:00
5e3de4e0af Grammer fix. 2018-10-18 00:32:26 -05:00
01e16d70e3 Add diplomacy inbox nag message. 2018-10-18 00:20:05 -05:00
eb6907d405 Change peace to neutral. 2018-10-18 00:15:26 -05:00
091bc27e3a Add default to the depends file. 2018-10-17 23:43:09 -05:00
84c195628b Update readme. 2018-10-17 23:25:05 -05:00
eedb441e9b Remove un-used code line. 2018-10-17 23:20:30 -05:00
047a0a2a2e Fix protection style description. 2018-10-17 23:13:48 -05:00
ed9c0c53ac No_parcel bug fix. 2018-10-17 21:55:06 -05:00
ad2aa093aa Showparcel bug fix. 2018-10-17 21:52:27 -05:00
67494969a3 Better args for protection style. 2018-10-17 21:40:00 -05:00
279d51037b Use onlineplayers table instead. 2018-10-17 21:36:07 -05:00
8d8346939e No-parcel nag message. 2018-10-17 21:31:07 -05:00
663ad93e81 Code clean up and bug fix. 2018-10-17 21:04:46 -05:00
b52f1c6760 Move players to offline onload. 2018-10-17 11:47:53 -05:00
3bf0f99aa4 Remove save func from player j/l. 2018-10-17 11:31:24 -05:00
bec629beb7 Update 1 2018-10-16 21:58:15 -05:00
f73505fe87 Delete doc folder 2018-10-16 21:39:13 -05:00
4353b6a050 Major update. 2018-10-15 10:24:58 -05:00
15f674da93 Bug fix. 2018-10-12 18:28:16 -05:00
1b7f89c0d9 Small update. 2018-10-12 15:27:05 -05:00
3cb5f83959 Remove old register_globalstep timer. 2018-10-12 14:32:03 -05:00
4113d5bab4 Grant new player faction user priv. 2018-10-12 14:30:58 -05:00
b29bdd35f0 Add spaces between sentences. 2018-10-12 13:05:13 -05:00
fff1455137 Add readme and license files. 2018-10-12 13:03:32 -05:00
238e5de342 Remove log file.
Why was this in there?
2018-10-12 12:44:04 -05:00
0cfba002dc Upload from hard disk.
This upload contains many bug fixes.
2018-10-12 12:41:55 -05:00
aaaa3886a1 Merge pull request #33 from shamoanjac/master
Fixes
2016-08-30 09:50:41 -04:00
87c5649bce Fixed global privileges not blocking use of commands 2016-08-30 11:38:52 +02:00
85a50688b9 Fixed /f kick and /f close 2016-08-29 01:41:23 +02:00
9d0920b3d0 Merge pull request #32 from shamoanjac/master
Fixed /f spawn + more admin commands
2016-08-28 16:52:37 -04:00
4165082354 Added /f seen 2016-08-28 12:19:58 +02:00
1e1cb6d65f Fixed /f spawn 2016-08-28 12:07:44 +02:00
79e270c38d Added /f stats 2016-08-28 12:03:12 +02:00
71d95c3ad8 Added /f whoin 2016-08-28 11:59:51 +02:00
853bf88210 Added /f obliterate and /f getspawn 2016-08-28 11:55:16 +02:00
ce8fec854f Added /f resetpower 2016-08-28 11:37:14 +02:00
468ef6c394 Merge pull request #31 from shamoanjac/master
fixes and addons
2016-08-27 18:11:28 -04:00
da37376d20 Added /f setadmin 2016-08-27 23:16:11 +02:00
3ffc31f8f2 Added /f setleader 2016-08-27 22:34:09 +02:00
80be027f88 Added /f which to get a player's faction 2016-08-27 22:10:25 +02:00
919666c7f7 Fixed auto-deletion not working 2016-08-27 19:09:54 +02:00
134ef287af Disabled war 2016-08-27 16:22:44 +02:00
b2aa1e8fa2 Merge pull request #28 from shamoanjac/master
fix + faction chests
2016-08-25 16:55:34 -04:00
b882008c91 Fixed /f invite 2016-08-25 18:31:02 +02:00
d1c4a3e40f Added faction chests 2016-08-24 15:32:08 +02:00
7a54c2e1db Merge pull request #27 from shamoanjac/master
Fix
2016-08-20 19:17:01 -04:00
6525a31260 Avoided apocalypse 2016-08-21 01:15:41 +02:00
d927bfb9bd Added chests 2016-08-21 01:08:45 +02:00
880a3fec96 Merge pull request #26 from shamoanjac/master
Fixed /f invite
2016-08-20 19:04:51 -04:00
529ad8bf4a Fixed /f invite 2016-08-20 09:34:09 +02:00
42505ab744 Update chatcommands.lua 2016-08-19 22:50:39 -04:00
fca049d379 Update factions.lua 2016-08-19 22:48:52 -04:00
c75e6baf5d Merge branch 'shamoanjac-master'
Test
2016-08-19 22:42:42 -04:00
9a38f54caa Merge branch 'master' of https://github.com/shamoanjac/factions into shamoanjac-master
Test
2016-08-19 22:41:53 -04:00
4d53e4cc40 Update code to use new API functions 2016-08-20 00:47:35 +02:00
a4f09c7d8e Added possibility to explain a faction disband 2016-08-20 00:15:45 +02:00
417bbeee60 Factions will now get disbanded after a week 2016-08-20 00:12:40 +02:00
296aeb5cc3 Power required to attack is now 10 2016-08-19 23:10:34 +02:00
7c98a705a8 Yet another protection fix 2016-08-19 23:10:01 +02:00
4f40f1779c Merge pull request #24 from shamoanjac/master
Fixed protection
2016-08-19 10:04:17 -04:00
367879cd4e Merge branch 'master' of https://github.com/shamoanjac/factions 2016-08-19 10:02:57 +02:00
3e3a4c9755 Fixed protection 2016-08-19 10:02:12 +02:00
a46b1323d3 Fixed protection 2016-08-19 10:00:09 +02:00
45590f1d0d Update factions.lua 2016-08-18 21:37:37 -04:00
0d78830d5b Fix kicking 2016-08-18 21:12:31 -04:00
863e7040a0 Static typing == cancer 2016-08-18 21:05:44 -04:00
4049c1aed7 Merge pull request #22 from shamoanjac/master
benis
2016-08-18 19:31:41 -04:00
e8c9fb3f7e Fixed /f kick 2016-08-18 21:38:10 +02:00
0a47417e77 Prevented extra long rank names 2016-08-18 15:29:43 +02:00
c552a58b63 Maximum length to faction names 2016-08-18 15:26:19 +02:00
565608876b Fixed protection to use newer API 2016-08-18 15:21:59 +02:00
4c72e388e8 Updated on_dieplayer and HUD update to newer API 2016-08-18 12:46:21 +02:00
685855e681 Added wrappers for getting factions 2016-08-17 22:28:12 +02:00
6052e0d541 Merge pull request #21 from shamoanjac/master
Fixed broken protection
2016-08-17 15:46:35 -04:00
756e489a7f Fixed broken protection 2016-08-17 08:15:18 +02:00
22c063b949 Merge pull request #20 from shamoanjac/master
Fixed not converting and adding usedpower
2016-08-16 16:13:54 -04:00
b2638a0b78 Fixed not converting and adding usedpower 2016-08-16 22:08:29 +02:00
8ffa199f3f Merge pull request #19 from shamoanjac/master
ebin war fixes
2016-08-16 15:54:21 -04:00
006c032952 Added error message to /f delrank 2016-08-16 21:08:44 +02:00
6deb78483e Fixed delrank checking 2016-08-16 21:05:41 +02:00
82ff53a133 Fixed power exploit, added usedpower, cannot attack parcels with negative power 2016-08-16 15:44:19 +02:00
b763015f3d Fixed members of the attacked faction not being able to edit their chunk 2016-08-15 23:52:12 +02:00
8fcaff614d Merge pull request #18 from shamoanjac/master
Made compatible with mobs mod
2016-08-15 16:05:27 -04:00
7492c88e1d Made compatible with mobs mod 2016-08-15 22:03:22 +02:00
e6f850ce47 Merge pull request #17 from shamoanjac/master
Fixed powercap conversion
2016-08-15 15:47:34 -04:00
3e3b69178c Fixed powercap conversion 2016-08-15 18:31:11 +02:00
e1dbcbf473 Merge pull request #16 from shamoanjac/master
fixes + powercap
2016-08-15 12:12:40 -04:00
f44b059afc Fixed /f promote 2016-08-15 16:39:19 +02:00
7137f09b4c Prepared power and maxpower for model migration 2016-08-15 15:00:57 +02:00
19940d92ee Claiming chunks also lowers the power cap 2016-08-15 14:31:03 +02:00
ad985c681d Updated version 2016-08-15 12:07:32 +02:00
047ae6ae7c Added decrease_maxpower and increase_maxpower 2016-08-15 10:16:12 +02:00
ba012f1c0a Small enhancements and switched from power-only system to power/maxpower 2016-08-15 09:54:28 +02:00
62f3b01498 Merge pull request #15 from shamoanjac/master
Fixed /f setspawn
2016-08-14 19:51:19 -04:00
f5fd22c272 Fixed /f setspawn 2016-08-15 01:50:13 +02:00
bd3c2b4432 Merge pull request #14 from shamoanjac/master
Big fix
2016-08-14 18:57:09 -04:00
c5c540cd01 Fixed faction creation not being broadcasted 2016-08-15 00:47:31 +02:00
07c6968778 Fixed protection checking 2016-08-15 00:37:16 +02:00
95ab0e3bfd Added some extra checks for building permissions + fixed /f promote 2016-08-15 00:24:30 +02:00
c87e691a42 Fixed /f who showing only one person 2016-08-14 23:55:42 +02:00
0670497f94 Small semantic change 2016-08-14 23:27:51 +02:00
631a5b9808 Merge branch 'master' of https://github.com/shamoanjac/factions
Conflicts:
	chatcommands.lua
	factions.lua
2016-08-14 15:57:18 +02:00
4df6d0357b Replaced "chunk" with "parcel" 2016-08-14 15:53:40 +02:00
53e0398558 Replaced all references to "chunks" with the term "parcel" 2016-08-14 15:46:35 +02:00
a38c82a4e7 Fixed player_faction being used instead of faction 2016-08-14 15:43:53 +02:00
df97039e3f Merge pull request #13 from shamoanjac/master
Fixed brackets bug
2016-08-12 11:19:27 -04:00
4c3e5025d6 Fixed brackets bug 2016-08-12 17:18:09 +02:00
048e0a1d6d Merge pull request #12 from shamoanjac/master
Verbosity
2016-08-12 11:14:32 -04:00
2d7237692a Added faction name to /f who and to /f 2016-08-12 17:09:43 +02:00
abe814f195 Added /f chat command 2016-08-12 11:34:39 +02:00
9931060c71 Enhanced doxygen comments 2016-08-12 11:16:43 +02:00
da573828f7 Merge pull request #11 from shamoanjac/master
fixes
2016-08-09 20:49:32 -04:00
be791384bd Fixed add_player() and on_create 2016-08-10 02:46:54 +02:00
3ec12936d6 Fixed formatting on /f newrank callback 2016-08-10 02:43:31 +02:00
1f67d1ed01 Fixed newrank bug 2016-08-10 02:42:31 +02:00
167a245244 Fixed on_spawn bug 2016-08-10 02:13:40 +02:00
746573abec Merge pull request #10 from shamoanjac/master
Fixed /f where bug
2016-08-09 20:07:46 -04:00
0dc86e2076 Fixed /f where bug 2016-08-10 02:01:50 +02:00
1ff7e6069e Merge pull request #9 from shamoanjac/master
Fixed chunpos bug + faction broadcast name bug
2016-08-09 20:00:26 -04:00
e5baf22d52 Fixed chunpos bug + faction broadcast name bug 2016-08-10 01:54:18 +02:00
c2cef304da Merge pull request #8 from shamoanjac/master
Fixes + verbose events
2016-08-09 19:28:22 -04:00
1326104d28 Implemented callbacks for faction events 2016-08-09 23:00:53 +02:00
8ee4238893 Merge pull request #7 from shamoanjac/master
Fixes
2016-08-09 06:08:09 -04:00
69ff206590 Underpowered factions' chunks can now be claimed 2016-08-09 04:39:40 +02:00
b41f7bda72 Added /f free for admins 2016-08-08 23:42:20 +02:00
719b39d99b Fixed infinite claiming bug 2016-08-08 23:36:56 +02:00
b28ee1a336 Merge pull request #6 from shamoanjac/master
Added /f promote and removed faction_user requirement
2016-08-08 17:30:13 -04:00
48139c5877 Added /f promote and removed faction_user requirement 2016-08-08 23:25:31 +02:00
a2d491d4f7 Merge pull request #5 from shamoanjac/master
Added convert function and command
2016-08-08 16:50:03 -04:00
3445066913 Added banners support 2016-08-08 21:09:10 +02:00
4568785238 Prepared for war 2016-08-08 19:23:39 +02:00
bacec849db Added convert function and command 2016-08-08 18:51:17 +02:00
d9a18d48ca Merge pull request #4 from shamoanjac/master
JustWerks(tm)
2016-08-08 11:45:21 -04:00
4d28033aa2 Added HUD which displays name of faction whose land you're in 2016-08-08 17:14:39 +02:00
169076e8fe Fixed moar bugs including spawn 2016-08-08 16:31:11 +02:00
c678fd55e2 Fixed tons of bugs 2016-08-08 13:46:42 +02:00
f67406cd65 Fixed disbanding factions not clearing players and chunks tables 2016-08-08 11:48:37 +02:00
b1b84740b1 Set version number to global and updated to 0.7.0 2016-08-08 11:44:25 +02:00
903abc15b6 Fixed unclaim bug, switched to metatables for factions 2016-08-08 03:30:29 +02:00
2ac24e091c Merge pull request #3 from shamoanjac/master
Enhanced commands system
2016-08-07 20:14:37 -04:00
55fe191cfd Fixed a shitton of bugs + added command "where" to check chunk ownership 2016-08-08 01:10:47 +02:00
a52fe6a6bf Fixed all syntax errors 2016-08-07 19:36:56 +02:00
37b948f1f6 Fixed dofile() 2016-08-07 19:32:27 +02:00
62b8f82c6a Renamed mod to "factions" 2016-08-07 19:31:11 +02:00
1145203353 Added commands to delete and add ranks, set spawn, and added check for wether a player is in a faction or not 2016-08-07 19:22:31 +02:00
418f67ff7e Enhanced commands system 2016-08-07 15:17:33 +02:00
9eba676c3b Merge pull request #2 from shamoanjac/master
Big ass rewrite
2016-08-06 20:27:17 -04:00
58c1724b8e Big ass rewrite 2016-08-07 02:11:17 +02:00
299f575e14 Bugfixes 2016-08-04 16:15:44 -04:00
c6872edd53 Closer. 2016-08-04 01:40:49 -04:00
e82a034462 v is not a thing 2016-08-04 01:31:36 -04:00
d3ac13793f Updates, and takeovers 2016-08-04 01:21:22 -04:00
e3068026a4 Finished most things 2016-07-31 11:43:04 -04:00
63254c55fc Claiming 2016-07-30 23:59:16 -04:00
8f773c0a73 Pushed updates. 2016-07-30 17:20:48 -04:00
be5c4b08a5 Fix 2016-07-30 17:05:47 -04:00
2abfd2de59 attempt at fixing claim 2016-07-30 17:00:10 -04:00
41c8a64394 Try on claiming 2016-07-30 16:33:10 -04:00
1b1465e1fb Attempt callback 2016-07-30 12:23:57 -04:00
be4bf2cd2a Loyalty. 2016-07-30 11:23:00 -04:00
d4b0240cd7 Fixed 2016-07-30 01:50:04 -04:00
64962da71f Now named factionsmod! 2016-07-30 01:38:52 -04:00
3145cdea9c Loyalty? 2016-07-30 01:09:07 -04:00
fc2b27abf1 Fixes 2016-07-30 00:50:36 -04:00
670787bee0 Attempted fix 2016-07-30 00:43:43 -04:00
5a7d08e75f : 2016-07-30 00:40:27 -04:00
e82a02e3c9 Fixed syntax errors 2016-07-30 00:22:28 -04:00
97a3bab635 Fixing bullshit 2016-07-30 00:11:04 -04:00
dba04e2e5a Anyone can create a faction, and when you create a faction, you join iy. 2016-07-29 23:21:23 -04:00
37 changed files with 3962 additions and 3049 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Coder12
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

4
README.md Normal file
View File

@ -0,0 +1,4 @@
# factions
modpack for minetest
Mods for handling in game factions.

View File

@ -1,465 +0,0 @@
-------------------------------------------------------------------------------
-- factions Mod by Sapier
--
-- License WTFPL
--
--! @file chatcommnd.lua
--! @brief factions chat interface
--! @copyright Sapier
--! @author Sapier
--! @date 2013-05-08
--
-- Contact sapier a t gmx net
-------------------------------------------------------------------------------
--! @class factions_chat
--! @brief chat interface class
factions_chat = {}
-------------------------------------------------------------------------------
-- name: init()
--
--! @brief initialize chat interface
--! @memberof factions_chat
--! @public
-------------------------------------------------------------------------------
function factions_chat.init()
minetest.register_privilege("faction_user",
{
description = "this user is allowed to interact with faction mod",
give_to_singleplayer = true,
}
)
minetest.register_privilege("faction_admin",
{
description = "this user is allowed to create or delete factions",
give_to_singleplayer = true,
}
)
minetest.register_chatcommand("factions",
{
params = "<cmd> <parameter 1> .. <parameter n>",
description = "faction administration functions",
privs = { faction_user=true },
func = factions_chat.cmdhandler,
}
)
minetest.register_chatcommand("af",
{
params = "text",
description = "send message to all factions",
privs = { faction_user=true },
func = factions_chat.allfactions_chathandler,
}
)
minetest.register_chatcommand("f",
{
params = "<factionname> text",
description = "send message to a specific faction",
privs = { faction_user=true },
func = factions_chat.chathandler,
}
)
end
-------------------------------------------------------------------------------
-- name: cmdhandler(playername,parameter)
--
--! @brief chat command handler
--! @memberof factions_chat
--! @private
--
--! @param playername name
--! @param parameter data supplied to command
-------------------------------------------------------------------------------
function factions_chat.cmdhandler(playername,parameter)
local player = minetest.get_player_by_name(playername)
local params = parameter:split(" ")
local cmd = params[1]
--handle common commands
if parameter == nil or
parameter == "" then
local playerfactions = factions.get_factions(player)
local tosend = "Factions: " .. playername .. " factions:"
for i,v in ipairs(playerfactions) do
if i ~= #playerfactions then
tosend = tosend .. " " .. v .. ","
else
tosend = tosend .. " " .. v
end
end
minetest.chat_send_player(playername, tosend, false)
return
end
--list all known factions
if cmd == "list" then
local list = factions.get_faction_list()
local tosend = "Factions: current available factions:"
for i,v in ipairs(list) do
if i ~= #list then
tosend = tosend .. " " .. v .. ","
else
tosend = tosend .. " " .. v
end
end
minetest.chat_send_player(playername, tosend, false)
return
end
--show factions mod version
if cmd == "version" then
minetest.chat_send_player(playername, "Factions: version " .. factions.version , false)
return
end
--show description of faction
if cmd == "info" then
if params[2] ~= nil then
minetest.chat_send_player(playername,
"Factions: " .. params[2] .. ": " ..
factions.get_description(params[2]), false)
return
end
end
if cmd == "leave" then
if params[2] ~= nil then
if params[3] ~= nil then
local toremove = minetest.get_player_by_name(params[3])
--allowed if faction_admin, admin of faction or player itself
if minetest.check_player_privs(playername,{ faction_admin=true }) or
factions.is_admin(params[2],playername) and
toremove ~= nil then
factions.member_remove(params[2],toremove)
minetest.chat_send_player(playername,
"Factions: " .. params[3] .. " has been removed from "
.. params[2], false)
return
end
else
factions.member_remove(params[2],player)
minetest.chat_send_player(playername,
"Factions: You have left " .. params[2], false)
return
end
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 factions.add_faction(params[2]) then
minetest.chat_send_player(playername,
"Factions: created faction " .. params[2],
false)
return
else
minetest.chat_send_player(playername,
"Factions: FAILED to created faction " .. params[2],
false)
return
end
end
end
end
if cmd == "join" then
if params[2] ~= nil then
if params[3] ~= nil and
minetest.check_player_privs(playername,{ faction_admin=true }) then
local toadd = minetest.get_player_by_name(params[3])
if toadd ~= nil then
if factions.member_add(params[2],toadd) then
minetest.chat_send_player(playername,
"Factions: " .. params[3] .. " joined faction " ..
params[2],
false)
return
end
end
minetest.chat_send_player(playername,
"Factions: " .. params[3] .. " FAILED to join faction " ..
params[2],
false)
return
else
--check for invitation
if factions.is_invited(params[2],playername) then
if factions.member_add(params[2],player) then
minetest.chat_send_player(playername,
"Factions: joined faction " ..
params[2],
false)
return
else
minetest.chat_send_player(playername,
"Factions: FAILED to join faction " ..
params[2],
false)
return
end
else
minetest.chat_send_player(playername,
"Factions: you are not allowed to join " .. params[2],
false)
return
end
end
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
factions.is_admin(params[2],playername) then
--delete faction
if cmd == "delete" then
if factions.delete_faction(params[2]) then
minetest.chat_send_player(playername,
"Factions: deleted faction " .. params[2],
false)
return
else
minetest.chat_send_player(playername,
"Factions: FAILED to deleted faction " .. params[2],
false)
return
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 factions.set_free(params[2],value) then
minetest.chat_send_player(playername,
"Factions: free to join for " .. params[2] ..
" has been set to " .. params[3],
false)
else
minetest.chat_send_player(playername,
"Factions: 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 factions.set_admin(params[2],params[3],value) then
minetest.chat_send_player(playername,
"Factions: adminstate of " .. params[3] ..
" has been set to " .. params[4],
false)
else
minetest.chat_send_player(playername,
"Factions: 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 factions.set_description(params[2],desc) then
minetest.chat_send_player(playername,
"Factions: updated description of faction " ..
params[2],
false)
return
else
minetest.chat_send_player(playername,
"Factions: 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 factions.member_invite(params[2],params[3]) then
minetest.chat_send_player(params[3],
"Factions: " .. params[3] ..
" you have been invited to join faction " .. params[2],
false)
minetest.chat_send_player(playername,
"Factions: " .. params[3] ..
" has been invited to join faction " .. params[2],
false)
return
else
minetest.chat_send_player(playername,
"Factions: FAILED to invite " .. params[3] ..
" to join faction " .. params[2],
false)
return
end
end
end
end
factions_chat.show_help(playername)
end
-------------------------------------------------------------------------------
-- name: allfactions_chathandler(playername,parameter)
--
--! @brief chat handler
--! @memberof factions_chat
--! @private
--
--! @param playername name
--! @param parameter data supplied to command
-------------------------------------------------------------------------------
function factions_chat.allfactions_chathandler(playername,parameter)
local player = minetest.get_player_by_name(playername)
if player ~= nil then
local recipients = {}
for faction,value in pairs(factions.get_factions(player)) do
for name,val in pairs(factions.dynamic_data.membertable[value]) do
local object_to_check = minetest.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
factions_chat.show_help(playername)
end
-------------------------------------------------------------------------------
-- name: chathandler(playername,parameter)
--
--! @brief chat handler
--! @memberof factions_chat
--! @private
--
--! @param playername name
--! @param parameter data supplied to command
-------------------------------------------------------------------------------
function factions_chat.chathandler(playername,parameter)
local player = minetest.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(factions.get_factions(player)) do
if target_faction == value then
valid_faction = true
end
end
if target_faction ~= nil and valid_faction and
factions.dynamic_data.membertable[target_faction] ~= nil then
for name,value in pairs(factions.dynamic_data.membertable[target_faction]) do
local object_to_check = minetest.get_player_by_name(name)
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,
"Factions: you're not a member of " .. dump(target_faction),false)
end
return
end
factions_chat.show_help(playername)
end
-------------------------------------------------------------------------------
-- name: show_help(playername,parameter)
--
--! @brief send help message to player
--! @memberof factions_chat
--! @private
--
--! @param playername name
-------------------------------------------------------------------------------
function factions_chat.show_help(playername)
local MSG = function(text)
minetest.chat_send_player(playername,text,false)
end
MSG("Factions mod")
MSG("Usage:")
MSG("\tUser commands:")
MSG("\t\t/factions -> info on your current factions")
MSG("\t\t/factions info <factionname> -> show description of faction")
MSG("\t\t/factions list -> show list of factions")
MSG("\t\t/factions leave <factionname> -> leave specified faction")
MSG("\t\t/factions join <factionname> -> join specified faction")
MSG("\t\t/factions version -> show version number of mod")
MSG("\tAdmin commands:")
MSG("\t\t/factions create <factionname> -> create a new faction")
MSG("\t\t/factions delete <factionname> -> delete a faction")
MSG("\t\t/factions join <factionname> <playername> -> join player to faction")
MSG("\t\t/factions leave <factionname> <playername> -> remove player from faction")
MSG("\t\t/factions invite <factionname> <playername> -> invite player to faction")
MSG("\t\t/factions set_free <factionname> <true|false> -> set faction free to join")
MSG("\t\t/factions admin <factionname> <playername> <true|false> -> make player admin of faction")
MSG("\t\t/factions description <factionname> <text> -> set description for faction")
end

File diff suppressed because it is too large Load Diff

484
fac/init.lua Normal file
View File

@ -0,0 +1,484 @@
---------------------
--! @brief returns whether a faction can be created or not (allows for implementation of blacklists and the like)
--! @param name String containing the faction's name
factions.can_create_faction = function(name)
if #name > factions_config.faction_name_max_length then
return false
elseif factions.factions.get(name) ~= nil then
return false
else
return true
end
end
starting_ranks = {["leader"] = {"build", "door", "container", "name", "description", "motd", "invite", "kick"
, "spawn", "with_draw", "territory", "claim", "access", "disband", "flags", "ranks", "promote"},
["moderator"] = {"claim", "door", "build", "spawn", "invite", "kick", "promote", "container"},
["member"] = {"build", "container", "door"}}
-- Faction permissions:
--
-- build: dig and place nodes
-- 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
-- spawn: set the faction's spawn
-- with_draw: withdraw money from the faction's bank
-- 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
-- ranks: create, edit, and delete ranks
-- promote: set a player's rank
-- diplomacy: be able to control the faction's diplomacy
factions.permissions = {}
factions.permissions["build"] = "dig and place nodes"
factions.permissions["pain_build"] = "dig and place nodes but take damage doing so"
factions.permissions["door"] = "open, close, or dig faction doors"
factions.permissions["container"] = "be able to interact with containers on claimed parcels"
factions.permissions["name"] = "set the faction's name"
factions.permissions["description"] = "Set the faction description"
factions.permissions["motd"] = "set the faction's message of the day"
factions.permissions["invite"] = "(un)invite players to join the faction"
factions.permissions["kick"] = "kick players off the faction"
factions.permissions["spawn"] = "set the faction's spawn"
factions.permissions["with_draw"] = "withdraw money from the faction's bank"
factions.permissions["territory"] = "claim or unclaim territory"
factions.permissions["claim"] = "(un)claim parcels of land"
factions.permissions["access"] = "manage access to territory and parcels of land to players or factions"
factions.permissions["disband"] = "disband the faction"
factions.permissions["flags"] = "manage the faction's flags"
factions.permissions["ranks"] = "create, edit, or delete ranks"
factions.permissions["promote"] = "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 = {}
factions.flags["open"] = "can the faction be joined without an invite?"
factions.flags["monsters"] = "can monsters spawn on your land?(unused)"
factions.flags["tax_kick"] = "will players be kicked for not paying tax?(unused)"
factions.flags["animals"] = "can animals spawn on your land?(unused)"
if factions_config.faction_diplomacy == true then
factions.permissions["diplomacy"] = "be able to control the faction's diplomacy"
local lt = starting_ranks["leader"]
table.insert(lt, "diplomacy")
starting_ranks["leader"] = lt
end
--! @brief create a new empty faction
function factions.new_faction(name)
local faction = factions.create_faction_table()
faction.name = name
factions.factions.set(name, faction)
factions.on_create(name)
minetest.after(1,
function(name)
factions.on_no_parcel(name)
end, name)
factions.onlineplayers[name] = {}
return faction
end
function factions.set_name(oldname, name)
local faction = factions.factions.get(oldname)
faction.name = name
for v, i in factions.factions.iterate() do
if v ~= oldname then
local fac = factions.factions.get(v)
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
if fac.request_inbox[oldname] then
local value = fac.request_inbox[oldname]
fac.request_inbox[oldname] = nil
fac.request_inbox[name] = value
end
factions.factions.set(v, fac)
end
end
for parcel in pairs(faction.land) do
local data = factions.create_parcel_table()
data.faction = name
factions.parcels.set(parcel, data)
end
for playername in pairs(faction.players) do
local data = factions.players.get(playername) or factions.create_player_table()
data.faction = name
factions.players.set(playername, data)
end
for playername in pairs(factions.onlineplayers[oldname]) do
updateFactionName(playername, name)
end
factions.onlineplayers[name] = factions.onlineplayers[oldname]
factions.onlineplayers[oldname] = nil
factions.factions.remove(oldname)
factions.factions.set(name, faction)
factions.on_set_name(name, oldname)
end
function factions.count_land(name)
local count = 0.
for k, v in pairs(factions.factions.get(name).land) do
count = count + 1
end
return count
end
function factions.add_player(name, player, rank)
local faction = factions.factions.get(name)
if factions.onlineplayers[name] == nil then
factions.onlineplayers[name] = {}
end
factions.onlineplayers[name][player] = true
factions.on_player_join(name, player)
if factions_config.enable_power_per_player then
local ip = factions.player_ips.get(player)
local notsame = true
for i, k in pairs(faction.players) do
local other_ip = factions.player_ips.get(i)
if other_ip == ip then
notsame = false
break
end
end
if notsame then
factions.increase_maxpower(name, factions_config.powermax_per_player)
end
end
faction.players[player] = rank or faction.default_rank
local data = factions.players.get(player) or factions.create_player_table()
data.faction = name
factions.players.set(player, data)
faction.invited_players[player] = nil
local pdata = minetest.get_player_by_name(player)
if pdata then
local ipc = pdata:is_player_connected()
if ipc then
createHudFactionName(pdata, name)
createHudPower(pdata, faction)
end
end
factions.factions.set(name, faction)
end
function factions.check_players_in_faction(name)
for i, k in pairs(factions.factions.get(name).players) do
return true
end
factions.disband(name, "Zero players on faction.")
return false
end
function factions.remove_player(name, player)
local faction = factions.factions.get(name)
if factions.onlineplayers[name] == nil then
factions.onlineplayers[name] = {}
end
factions.onlineplayers[name][player] = nil
faction.players[player] = nil
factions.factions.set(name, faction)
factions.remove_key(factions.players, player, nil, "faction", true)
factions.on_player_leave(name, player)
if factions_config.enable_power_per_player then
local ip = factions.player_ips.get(player)
local notsame = true
for i,k in pairs(faction.players) do
local other_ip = factions.player_ips.get(i)
if other_ip == ip then
notsame = false
break
end
end
if notsame then
factions.decrease_maxpower(name, factions_config.powermax_per_player)
end
end
local pdata = minetest.get_player_by_name(player)
if pdata then
local ipc = pdata:is_player_connected()
if ipc then
removeHud(pdata,"factionName")
removeHud(pdata,"powerWatch")
end
end
factions.check_players_in_faction(name)
end
local parcel_size = factions_config.parcel_size
--! @brief disband faction, updates global players and parcels table
function factions.disband(name, reason)
local faction = factions.factions.get(name)
if not faction.is_admin then
for v, i in factions.factions.iterate() do
local fac = factions.factions.get(v)
if fac ~= nil and fac.name ~= name then
if fac.enemies[name] then
factions.end_enemy(fac.name, name)
end
if fac.allies[name] then
factions.end_alliance(fac.name, name)
end
if fac.neutral[name] then
factions.end_neutral(fac.name, name)
end
if fac.request_inbox[name] then
fac.request_inbox[name] = nil
end
end
factions.factions.set(v, fac)
end
for k, _ in pairs(faction.players) do -- remove players affiliation
factions.remove_key(factions.players, k, nil, "faction", true)
end
for k, v in pairs(faction.land) do -- remove parcel claims
factions.remove_key(factions.parcels, k, nil, "faction", true)
end
factions.on_disband(name, reason)
if factions.onlineplayers ~= nil and factions.onlineplayers[name] ~= nil then
for i, l in pairs(factions.onlineplayers[name]) do
removeHud(i, "factionName")
removeHud(i, "powerWatch")
end
factions.onlineplayers[name] = nil
end
factions.factions.remove(name)
end
end
--! @brief change the faction leader
function factions.set_leader(name, player)
local faction = factions.factions.get(name)
if faction.leader then
faction.players[faction.leader] = faction.default_rank
end
faction.leader = player
faction.players[player] = faction.default_leader_rank
factions.on_new_leader()
factions.factions.set(name, faction)
end
function factions.set_message_of_the_day(name, text)
local faction = factions.factions.get(name)
faction.message_of_the_day = text
factions.factions.set(name, faction)
end
--! @brief check permissions for a given player
--! @return boolean indicating permissions. Players not in faction always receive false
function factions.has_permission(name, player, permission)
local faction = factions.factions.get(name)
local p = faction.players[player]
if not p then
return false
end
local perms = faction.ranks[p]
if perms then
for i in ipairs(perms) do
if perms[i] == permission then
return true
end
end
else
return false
end
end
function factions.set_description(name, new)
local faction = factions.factions.get(name)
faction.description = new
factions.on_change_description(name)
factions.factions.set(name, faction)
end
--! @brief set faction openness
function factions.toggle_join_free(name, bool)
local faction = factions.factions.get(name)
faction.join_free = bool
factions.on_toggle_join_free(name)
factions.factions.set(name, faction)
end
--! @return true if a player can use /f join, false otherwise
function factions.can_join(name, player)
local faction = factions.factions.get(name)
return faction.join_free or faction.invited_players[player]
end
--! @brief faction's member will now spawn in a new place
function factions.set_spawn(name, pos)
local faction = factions.factions.get(name)
faction.spawn = {x = pos.x, y = pos.y, z = pos.z}
factions.on_set_spawn(name)
factions.factions.set(name, faction)
end
function factions.tp_spawn(name, playername)
local faction = factions.factions.get(name)
player = minetest.get_player_by_name(playername)
if player then
player:set_pos(faction.spawn)
end
end
--! @brief send a message to all members
function factions.broadcast(name, msg, sender)
if factions.onlineplayers[name] == nil then
factions.onlineplayers[name] = {}
end
local message = name .. "> ".. msg
if sender then
message = sender .. "@" .. message
end
message = "Faction<" .. message
minetest.log(message)
for k, _ in pairs(factions.onlineplayers[name]) do
minetest.chat_send_player(k, message)
end
end
--! @brief checks whether a faction has at least one connected player
function factions.is_online(name)
if factions.onlineplayers[name] == nil then
factions.onlineplayers[name] = {}
end
for playername, _ in pairs(factions.onlineplayers[name]) do
return true
end
return false
end
function factions.get_parcel_pos(pos)
if factions_config.protection_style == "3d" then
return math.floor(pos.x / parcel_size) * parcel_size .. "," .. math.floor(pos.y / parcel_size) * parcel_size .. "," .. math.floor(pos.z / parcel_size) * parcel_size
else
return math.floor(pos.x / parcel_size) * parcel_size .. "," .. math.floor(pos.z / parcel_size) * parcel_size
end
end
function factions.get_player_faction(playername)
local data = factions.players.get(playername)
if data then
local facname = data.faction
local faction = factions.factions.get(facname)
return faction, facname
end
return nil
end
function factions.get_faction(facname)
return factions.factions.get(facname)
end
function factions.get_faction_at(pos)
local y = pos.y
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 nil
end
local parcelpos = factions.get_parcel_pos(pos)
return factions.get_parcel_faction(parcelpos)
end
function factions.faction_tick()
local now = os.time()
for facname, i in factions.factions.iterate() do
local faction = factions.factions.get(facname)
if faction ~= nil then
if factions.is_online(facname) then
if factions_config.enable_power_per_player then
local count = 0
for _ in pairs(factions.onlineplayers[facname]) do count = count + 1 end
factions.increase_power(facname, factions_config.power_per_player * count)
else
factions.increase_power(facname, factions_config.power_per_tick)
end
end
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
local r = ""
if now - faction.last_logon > factions_config.maximum_faction_inactivity then
r = "inactivity"
else
r = "no parcel claims"
end
factions.disband(facname, r)
end
end
end
end
function factionUpdate()
factions.faction_tick()
minetest.after(factions_config.tick_time, factionUpdate)
end
minetest.after(factions_config.tick_time, factionUpdate)

2
fac/mod.conf Normal file
View File

@ -0,0 +1,2 @@
name = fac
depends = fac_config

1214
fac_chat/commands.lua Normal file

File diff suppressed because it is too large Load Diff

293
fac_chat/init.lua Normal file
View File

@ -0,0 +1,293 @@
factions_chat = {}
factions.commands = {}
local function register_command(cmd_name, cmd)
factions.commands[cmd_name] = { -- default command
name = cmd_name,
faction_permissions = {},
global_privileges = {},
format = {},
infaction = true,
description = "This command has no description.",
ignore_param_limit = false,
or_perm = false,
dont_show_in_help = false,
run = function(self, player, argv)
if self.global_privileges then
local tmp = {}
for i in ipairs(self.global_privileges) do
tmp[self.global_privileges[i]] = true
end
local bool, missing_privs = minetest.check_player_privs(player, tmp)
if not bool then
minetest.chat_send_player(player, "Unauthorized.")
return false
end
end
-- checks argument formats
local args = {
factions = {},
players = {},
strings = {},
unknowns = {},
other = {}
}
if not self.ignore_param_limit then
if #argv < #(self.format) then
minetest.chat_send_player(player, "Not enough parameters.")
return false
end
else
if self.format[1] then
local fm = self.format[1]
for i in ipairs(argv) do
if #argv > #(self.format) then
table.insert(self.format, fm)
else
break
end
end
end
end
for i in ipairs(self.format) do
local argtype = self.format[i]
local arg = argv[i]
if argtype == "faction" then
local fac = factions.get_faction(arg)
if not fac then
minetest.chat_send_player(player, "Specified faction " .. arg .. " does not exist")
return false
else
table.insert(args.factions, fac)
end
elseif argtype == "player" then
local data = minetest.get_auth_handler().get_auth(arg)
if data then
table.insert(args.players, arg)
else
minetest.chat_send_player(player, "Player does not exist.")
return false
end
elseif argtype == "string" then
table.insert(args.strings, arg)
else
table.insert(args.unknowns, arg)
end
end
for i=2, #argv do
if argv[i] then
table.insert(args.other, argv[i])
end
end
-- checks permissions
local player_faction, facname = factions.get_player_faction(player)
if self.infaction and not player_faction then
minetest.chat_send_player(player, "This command is only available within a faction")
return false
end
local one_p = false
if self.faction_permissions then
for i in ipairs(self.faction_permissions) do
local perm = self.faction_permissions[i]
if not self.or_perm and not factions.has_permission(facname, player, perm) then
minetest.chat_send_player(player, "You do not have the faction permission " .. perm)
return false
elseif self.or_perm and factions.has_permission(facname, player, perm) then
one_p = true
break
end
end
end
if self.or_perm and one_p == false then
minetest.chat_send_player(player, "You do not have any of faction permissions required.")
return false
end
-- get some more data
local pos = minetest.get_player_by_name(player):get_pos()
local parcelpos = factions.get_parcel_pos(pos)
return self.on_success(player, player_faction, pos, parcelpos, args)
end,
on_success = function(player, faction, pos, parcelpos, args)
minetest.chat_send_player(player, "Not implemented yet!")
end
}
-- count cmd spaces.
local words = cmd_name:split(" ")
local word_spaces = 0
for k in pairs(words) do
word_spaces = word_spaces + 1
end
cmd.word_spaces = word_spaces
-- override defaults
for k, v in pairs(cmd) do
factions.commands[cmd_name][k] = v
end
end
function factions.register_command(cmd_name, cmd)
local cmd_type = type(cmd_name)
local next = false
if cmd_type == "string" then
register_command(cmd_name, cmd)
elseif cmd_type == "table" then
for k, v in pairs(cmd_name) do
if next and cmd.dont_show_in_help == nil then
cmd.dont_show_in_help = true
end
register_command(v, cmd)
next = true
end
end
end
local init_commands
init_commands = function()
if factions_config.faction_user_priv == true then
minetest.register_privilege("faction_user",
{
description = "this user is allowed to interact with faction mod",
give_to_singleplayer = true,
}
)
end
minetest.register_privilege("faction_admin",
{
description = "this user is allowed to create or delete factions",
give_to_singleplayer = true,
}
)
local def_privs = {interact = true}
if factions_config.faction_user_priv == true then
def_privs.faction_user = true
end
minetest.register_chatcommand("f",
{
params = "<command> parameters",
description = "Factions commands. Type /f help for available commands.",
privs = def_privs,
func = factions_chat.cmdhandler,
}
)
minetest.register_chatcommand("faction",
{
params = "<command> parameters",
description = "Factions commands. Type /faction help for available commands.",
privs = def_privs,
func = factions_chat.cmdhandler,
}
)
end
local def_global_privileges = nil
if factions_config.faction_user_priv == true then
minetest.register_on_newplayer(function(player)
local name = player:get_player_name()
local privs = minetest.get_player_privs(name)
privs.faction_user = true
minetest.set_player_privs(name, privs)
end)
def_global_privileges = {"faction_user"}
end
local path = minetest.get_modpath("fac_chat")
dofile(path .. "/commands.lua")
dofile(path .. "/subcommands.lua")
-------------------------------------------------------------------------------
-- name: cmdhandler(playername, parameter)
--
--! @brief chat command handler
--! @memberof factions_chat
--! @private
--
--! @param playername name
--! @param parameter data supplied to command
-------------------------------------------------------------------------------
function factions_chat.cmdhandler(playername, parameter)
local player = minetest.env:get_player_by_name(playername)
local params = parameter:split(" ")
local player_faction, facname = factions.get_player_faction(playername)
if parameter == nil or parameter == "" then
if player_faction then
minetest.chat_send_player(playername, "You are in faction " .. player_faction.name .. ". Type /f help for a list of commands.")
else
minetest.chat_send_player(playername, "You are part of no faction")
end
return
end
local cmd = factions.commands[parameter]
if not cmd then
local cmd_text = ""
for i = 1, #params, 1 do
if cmd_text == "" then
cmd_text = params[i]
else
cmd_text = cmd_text .. " " .. params[i]
end
if factions.commands[cmd_text] then
cmd = factions.commands[cmd_text]
end
end
if not cmd then
minetest.chat_send_player(playername, "Unknown command.")
return false
end
end
local argv = {}
for i = 1 + cmd.word_spaces, #params, 1 do
table.insert(argv, params[i])
end
cmd:run(playername, argv)
end
function table_Contains(t, v)
for k, a in pairs(t) do
if a == v then
return true
end
end
return false
end
local premade_help = ""
local premade_help_admin = ""
local a_z = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e"
, "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
function factions.create_help_text()
for l, j in pairs(a_z) do
for k, v in pairs(factions.commands) do
if k:sub(1, 1) == j then
if not v.dont_show_in_help then
if not table_Contains(v.global_privileges, "faction_admin") then
premade_help = premade_help .. "\t/f " .. v.name .. v.description_arg .. " " .. v.description .. "\n"
end
premade_help_admin = premade_help_admin .. "\t/f " .. v.name .. v.description_arg .. " " .. v.description .. "\n"
end
end
end
end
end
minetest.register_on_mods_loaded(function()
factions.create_help_text()
end)
-------------------------------------------------------------------------------
-- name: show_help(playername, parameter)
--
--! @brief send help message to player
--! @memberof factions_chat
--! @private
--
--! @param playername name
-------------------------------------------------------------------------------
function factions_chat.show_help(playername)
local msg = "factions mod\nUsage:\n"
local has, missing = minetest.check_player_privs(playername, {faction_admin = true})
if has then
msg = msg .. premade_help_admin
else
msg = msg .. premade_help
end
minetest.chat_send_player(playername, msg, false)
end
init_commands()

1
fac_chat/mod.conf Normal file
View File

@ -0,0 +1 @@
name = fac_chat

220
fac_chat/subcommands.lua Normal file
View File

@ -0,0 +1,220 @@
local def_global_privileges = nil
if factions_config.faction_user_priv == true then
def_global_privileges = {"faction_user"}
end
factions.register_command({"claim o", "claim one"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
return claim_helper(player, faction, parcelpos)
end
})
factions.register_command({"claim a", "claim auto"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
factions.claim_auto(player, faction)
end
})
factions.register_command({"claim f", "claim fill"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
factions.claim_fill(player, faction)
end
})
factions.register_command({"claim s", "claim square"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
format = {"string"},
on_success = function(player, faction, pos, parcelpos, args)
local arg = args.strings[1]
if arg then
local r = tonumber(arg)
if not r then
minetest.chat_send_player(player, "Only use numbers in the second cmd parameter [0-9].")
return
end
factions.claim_square(player, faction, r)
else
factions.claim_square(player, faction, 3)
end
end
})
factions.register_command({"claim c", "claim circle"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
format = {"string"},
on_success = function(player, faction, pos, parcelpos, args)
local arg = args.strings[1]
if arg then
local r = tonumber(arg)
if not r then
minetest.chat_send_player(player, "Only use numbers in the second cmd parameter [0-9].")
return
end
factions.claim_circle(player, faction, r)
else
factions.claim_circle(player, faction, 3)
end
end
})
factions.register_command("claim all", {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
factions.claim_all(player, faction)
end
})
factions.register_command({"claim l", "claim list"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
local aclaims = "All claims:\n"
for i in pairs(faction.land) do
aclaims = aclaims .. i .. "\n"
end
minetest.chat_send_player(player, aclaims)
end
})
factions.register_command({"claim h", "claim help"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
factions.claim_help(player, arg_two)
end
})
factions.register_command({"unclaim o", "unclaim one"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
return unclaim_helper(player, faction, parcelpos)
end
})
factions.register_command ({"unclaim a", "unclaim auto"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
factions.unclaim_auto(player, faction)
end
})
factions.register_command({"unclaim f", "unclaim fill"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
factions.unclaim_fill(player, faction)
end
})
factions.register_command({"unclaim s", "unclaim square"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
format = {"string"},
on_success = function(player, faction, pos, parcelpos, args)
local arg = args.strings[1]
if arg then
local r = tonumber(arg)
if not r then
minetest.chat_send_player(player, "Only use numbers in the second cmd parameter [0-9].")
return
end
factions.unclaim_square(player, faction, r)
else
factions.unclaim_square(player, faction, 3)
end
end
})
factions.register_command({"unclaim c", "unclaim circle"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
format = {"string"},
on_success = function(player, faction, pos, parcelpos, args)
local arg = args.strings[1]
if arg then
local r = tonumber(arg)
if not r then
minetest.chat_send_player(player, "Only use numbers in the second cmd parameter [0-9].")
return
end
factions.unclaim_circle(player, faction, r)
else
factions.unclaim_circle(player, faction, 3)
end
end
})
factions.register_command("unclaim all", {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
factions.unclaim_all(player, faction)
end
})
factions.register_command({"unclaim l", "unclaim list"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
local aclaims = "All claims:\n"
for i in pairs(faction.land) do
aclaims = aclaims .. i .. "\n"
end
minetest.chat_send_player(player, aclaims)
end
})
factions.register_command({"unclaim h", "unclaim help"}, {
faction_permissions = {"claim"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
factions.unclaim_help(player, arg_two)
end
})
factions.register_command({"flag help", "flag flags"}, {
faction_permissions = {"flags"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
on_success = function(player, faction, pos, parcelpos, args)
local msg = ""
for i, k in pairs(factions.flags) do
msg = msg .. i .. ": " .. k .. "\n"
end
minetest.chat_send_player(player, msg)
end
})
factions.register_command("flag open", {
faction_permissions = {"flags"},
global_privileges = def_global_privileges,
dont_show_in_help = true,
format = {"string"},
on_success = function(player, faction, pos, parcelpos, args)
local bool = args.strings[1]
if bool then
local yes = false
if bool == "yes" then
yes = true
elseif bool == "no" then
yes = false
else
minetest.chat_send_player(player, "Set the flags only to yes or no.")
return false
end
factions.toggle_join_free(faction.name, yes)
end
end
})

24
fac_config/init.lua Normal file
View File

@ -0,0 +1,24 @@
factions_config = {}
factions_config.protection_max_depth = tonumber(minetest.settings:get("factions.protection_max_depth")) or -512
factions_config.protection_max_height = tonumber(minetest.settings:get("factions.protection_max_height")) or 10000
factions_config.power_per_parcel = tonumber(minetest.settings:get("factions.power_per_parcel")) or 1
factions_config.power_per_death = tonumber(minetest.settings:get("factions.power_per_death")) or 1
factions_config.power_per_tick = tonumber(minetest.settings:get("factions.power_per_tick")) or 2
factions_config.tick_time = tonumber(minetest.settings:get("factions.tick_time")) or 60
factions_config.power_per_attack = tonumber(minetest.settings:get("factions.power_per_attack")) or 10
factions_config.faction_name_max_length = tonumber(minetest.settings:get("factions.faction_name_max_length")) or 50
factions_config.rank_name_max_length = tonumber(minetest.settings:get("factions.rank_name_max_length")) or 25
factions_config.maximum_faction_inactivity = tonumber(minetest.settings:get("factions.maximum_faction_inactivity")) or 604800
factions_config.maximum_parcelless_faction_time = tonumber(minetest.settings:get("factions.maximum_parcelless_faction_time")) or 10800
factions_config.power = tonumber(minetest.settings:get("factions.power")) or 12
factions_config.maxpower = tonumber(minetest.settings:get("factions.maxpower")) or 0
factions_config.power_per_player = tonumber(minetest.settings:get("factions.power_per_player")) or 1
factions_config.powermax_per_player = tonumber(minetest.settings:get("factions.powermax_per_player")) or 12
factions_config.parcel_size = tonumber(minetest.settings:get("factions.parcel_size")) or 16
factions_config.protection_depth_height_limit = minetest.settings:get_bool("factions.protection_depth_height_limit") or true
factions_config.enable_power_per_player = minetest.settings:get_bool("factions.power_per_playerb") or true
factions_config.attack_parcel = minetest.settings:get_bool("factions.attack_parcel") or false
factions_config.faction_diplomacy = minetest.settings:get_bool("factions.faction_diplomacy") or true
factions_config.spawn_teleport = minetest.settings:get_bool("factions.spawn_teleport") or false
factions_config.protection_style = minetest.settings:get("factions.protection_style") or "2d"
factions_config.faction_user_priv = minetest.settings:get("factions.faction_user_priv") or false

1
fac_config/mod.conf Normal file
View File

@ -0,0 +1 @@
name = fac_config

View File

@ -0,0 +1,57 @@
[ValueSettings]
# The max depth of protection from a parcel.
factions.protection_max_depth (Protection max depth) float 512
# The max height of protection from a parcel.
factions.protection_max_height (Protection max height) float 10000
# Cost of power to claim a parcel of land.
factions.power_per_parcel (Power-per-parcel) float 1
# Power lost on death.
factions.power_per_death (Power-per-death) float 1
# Power regeneration rate.
factions.power_per_tick (Power-per-tick) float 2
# Faction timer. This timer regenerates power.
factions.tick_time (Faction timer) float 60
# Not in use.
factions.power_per_attack (Power-per-attack) float 10
# Limit how long a faction name can be.
factions.faction_name_max_length (Faction name max) int 50
# Limit how long a rank name can be.
factions.rank_name_max_length (Rank name max length) int 25
# The maximum amount of inactivity before disbanning a faction.
factions.maximum_faction_inactivity (Maximum faction inactivity) int 604800
# The maximum amount of time for a parcelless faction to disban.
factions.maximum_parcelless_faction_time (Maximum parcelless faction time) int 10800
# Power of a starting faction (needed for parcel claiming).
factions.power (Starting power) float 12
# Maximum power of a starting faction.
factions.maxpower (Starting Maximum power) float 0
# How much power the players make.
factions.power_per_player (power-per-player) float 1
# How much max power is created per new player.
factions.powermax_per_player (powermax-per-player) float 12
# parcel size
factions.parcel_size (parcel-size) float 16
[BoolSettings]
# Enable or disabled power-per-player.
factions.power_per_playerb (Enable power-per-player) bool true
# Enable or disabled attack_parcel function.
factions.attack_parcel (Enable attack parcel) bool false
# Enable or disabled faction diplomacy.
factions.faction_diplomacy (Enable faction diplomacy) bool true
# Enable or disabled the max depth and height limit for a parcel
factions.protection_depth_height_limit (Enable protection depth height limit) bool true
# Enable or disabled faction spawn teleport
factions.spawn_teleport (Enable spawn teleport) bool false
# Enable or disabled the need for faction_user priv
factions.faction_user_priv (Enable faction user priv) bool false
# Enable or disabled Store player ips to prevent players from gaining more max power from alts
factions.store_ip (store player ip) bool true
[StringSettings]
# Set the way that the parcel protection works (2d, 3d).
# 2d limits how far x and z can go but protection on the y goes up and down far.
# 3d limits all three axis.
factions.protection_style (Protection style) enum 2d 3d,2d

159
fac_database/init.lua Normal file
View File

@ -0,0 +1,159 @@
--! @class factions
--! @brief main class for factions
factions = {}
-- database
factions.factions = {}
factions.parcels = {}
factions.players = {}
factions.player_ips = {}
dofile(minetest.get_modpath("fac_database") .. "/storagedb.lua")
factions.factions = storagedb.Storagedb("factions")
factions.parcels = storagedb.Storagedb("parcels")
factions.players = storagedb.Storagedb("players")
factions.player_ips = storagedb.Storagedb("ips")
-- Memory only storage.
factions.onlineplayers = {}
-- Table creation.
-- Create a empty faction.
function factions.create_faction_table()
local table = {
name = "",
--! @brief power of a faction (needed for parcel claiming)
power = factions_config.power,
--! @brief maximum power of a faction
maxpower = factions_config.maxpower,
--! @brief power currently in use
usedpower = 0,
--! @brief list of player names
players = {},
--! @brief table of ranks/permissions
ranks = starting_ranks,
--! @brief name of the leader
leader = nil,
--! @brief spawn of the faction
spawn = {x = 0, y = 0, z = 0},
--! @brief default joining rank for new members
default_rank = "member",
--! @brief default rank assigned to the leader
default_leader_rank = "leader",
--! @brief faction's description string
description = "Default faction description.",
--! @brief faction's message of the day.
message_of_the_day = "",
--! @brief list of players currently invited (can join with /f join)
invited_players = {},
--! @brief table of claimed parcels (keys are parcelpos strings)
land = {},
--! @brief table of allies
allies = {},
--
request_inbox = {},
--! @brief table of enemies
enemies = {},
--!
neutral = {},
--! @brief table of parcels/factions that are under attack
attacked_parcels = {},
--! @brief whether faction is closed or open (boolean)
join_free = false,
--! @brief gives certain privileges
is_admin = false,
--! @brief last time anyone logged on
last_logon = os.time(),
--! @brief how long this has been without parcels
no_parcel = os.time(),
--! @brief access table
access = {players = {}, factions = {}},
}
return table
end
-- Create a empty ip table.
function factions.create_ip_table()
local table = {
ip = ""
}
return table
end
-- Create a empty player table.
function factions.create_player_table()
local table = {
faction = ""
}
return table
end
-- Create a empty claim table.
function factions.create_parcel_table()
local table = {
faction = ""
}
return table
end
-- helper functions
function factions.db_is_empty(table)
for k, v in pairs(table) do
return false
end
return true
end
function factions.remove_key(db, db_name, db_data, key, write)
if not db_data then
db_data = db.get(db_name)
end
db_data[key] = nil
if factions.db_is_empty(db_data) then
db.remove(db_name)
return nil
end
if write then
db.set(db_name, db_data)
end
return db_data
end
-- faction data check on load
local function update_data(db, db_name, db_data, empty_table, write)
local needs_update = false
if not db_data then
db_data = db.get(db_name)
end
for k, v in pairs(empty_table) do
if db_data[k] == nil then
db_data[k] = v
needs_update = true
minetest.log("Adding property " .. k .. " to " .. db_name .. " file.")
end
end
if write and needs_update then
db.set(db_name, db_data)
end
return db_data
end
minetest.register_on_mods_loaded(function()
minetest.log("Checking faction files.")
for k, v in factions.factions.iterate() do
update_data(factions.factions, k, nil, factions.create_faction_table(), true)
end
minetest.log("Checking parcel files.")
for k, v in factions.parcels.iterate() do
update_data(factions.parcels, k, nil, factions.create_parcel_table(), true)
end
minetest.log("Checking player files.")
for k, v in factions.players.iterate() do
update_data(factions.players, k, nil, factions.create_player_table(), true)
end
minetest.log("Checking ip files.")
for k, v in factions.player_ips.iterate() do
update_data(factions.player_ips, k, nil, factions.create_ip_table(), true)
end
end)

2
fac_database/mod.conf Normal file
View File

@ -0,0 +1,2 @@
name = fac_database
depends = fac_config

192
fac_database/storagedb.lua Normal file
View File

@ -0,0 +1,192 @@
local storage = minetest.get_mod_storage()
storagedb = {}
function storagedb.Storagedb(dir)
local self = {}
local directory = dir
local mem_pool = {}
local mem_pool_del = {}
local add_to_mem_pool = true
local serializer = minetest.serialize
local deserializer = minetest.deserialize
-- make tables weak so the garbage-collector will remove unused data
setmetatable(mem_pool, {__mode = "kv"})
setmetatable(mem_pool_del, {__mode = "kv"})
local function storekey(key)
local list = deserializer(storage:get_string(directory))
if not list then
list = {}
list[key] = key
else
list[key] = key
end
storage:set_string(directory, serializer(list))
end
local function removekey(key)
local list = deserializer(storage:get_string(directory))
if not list then
list = {}
else
list[key] = nil
end
storage:set_string(directory, serializer(list))
end
local function getkeys()
local list = deserializer(storage:get_string(directory))
if not list then
list = {}
end
return list
end
local function load_into_mem(name, _table)
if add_to_mem_pool then
mem_pool[name] = {mem = _table}
end
end
local function load_table(name)
local f = storage:get_string(string.format("%s/%s", directory, name))
if f then
local data = deserializer(f)
return data
end
return nil
end
local function save_table(name, _table)
if save_table == nil or name == nil then
return false
end
storekey(name)
storage:set_string(string.format("%s/%s", directory, name), serializer(_table))
end
local function save_key(name)
storage:set_string(string.format("%s/%s", directory, name), "")
end
local function load_key(name)
local f = storage:get_string(string.format("%s/%s", directory, name))
if f ~= "" then
return true
end
return false
end
self.get_memory_pool = function()
return mem_pool
end
self.set_memory_pool = function(pool)
mem_pool = pool
end
self.add_to_memory_pool = function(value)
if value then
add_to_mem_pool = value
end
return add_to_mem_pool
end
self.get_serializer = function()
return serializer, deserializer
end
self.set_serializer = function(coder, decoder)
serializer = coder
deserializer = decoder
end
self.set_mem = function(name, _table)
load_into_mem(name, _table)
mem_pool_del[name] = nil
end
self.save_mem = function(name)
if mem_pool[name] ~= nil then
save_table(name, mem_pool[name].mem)
end
mem_pool_del[name] = nil
end
self.clear_mem = function(name)
mem_pool[name] = nil
mem_pool_del[name] = nil
end
self.set = function(name, _table)
save_table(name, _table)
if add_to_mem_pool then
load_into_mem(name, _table)
end
mem_pool_del[name] = nil
end
self.set_key = function(name)
save_key(name)
if add_to_mem_pool then
load_into_mem(name, "")
end
mem_pool_del[name] = nil
end
self.get = function(name, callback)
if mem_pool_del[name] then
if callback then
callback(nil)
end
return nil
end
local pm = mem_pool[name]
if pm then
if callback then
callback(pm.mem)
end
return pm.mem
else
local _table = load_table(name)
if _table then
load_into_mem(name, _table)
if callback then
callback(_table)
end
return _table
end
end
mem_pool_del[name] = true
return nil
end
self.remove = function(name)
mem_pool[name] = nil
mem_pool_del[name] = true
removekey(name)
storage:set_string(string.format("%s/%s", directory, name), "")
end
self.sub_database = function(path)
local db = storagedb.Storagedb(dir .. "/" .. path)
return db
end
self.to_array = function()
local entries = {}
for k, v in pairs(getkeys()) do
entries[#entries + 1] = v
end
return entries
end
self.to_table = function()
local entries = {}
for k, v in pairs(getkeys()) do
entries[v] = true
end
return entries
end
self.iterate = function()
local entries = {}
for k, v in pairs(getkeys()) do
entries[v] = true
end
return pairs(entries)
end
return self
end

375
fac_events/claim_events.lua Normal file
View File

@ -0,0 +1,375 @@
--! @param parcelpos position of the wanted parcel
--! @return whether this faction can claim a parcelpos
function factions.can_claim_parcel(name, parcelpos)
local fn = factions.parcels.get(parcelpos)
if fn == nil then
return true
end
local faction = factions.factions.get(name)
if fn then
local fac = factions.factions.get(fn.faction)
if fac.power < 0. and faction.power >= factions_config.power_per_parcel and not faction.allies[fn] and not faction.neutral[fn] then
return true
else
return false
end
elseif faction.power < factions_config.power_per_parcel then
return false
end
return true
end
--! @brief claim a parcel, update power and update global parcels table
function factions.claim_parcel(name, parcelpos)
-- check if claiming over other faction's territory
local otherfac = factions.parcels.get(parcelpos)
if otherfac then
local otherfac_name = otherfac.faction
factions.unclaim_parcel(otherfac_name, parcelpos)
factions.parcelless_check(otherfac_name)
end
local data = factions.create_parcel_table()
data.faction = name
factions.parcels.set(parcelpos, data)
local faction = factions.factions.get(name)
faction.land[parcelpos] = true
factions.factions.set(name, faction)
factions.decrease_power(name, factions_config.power_per_parcel)
factions.increase_usedpower(name, factions_config.power_per_parcel)
factions.on_claim_parcel(name, parcelpos)
factions.parcelless_check(name)
end
--! @brief claim a parcel, update power and update global parcels table
function factions.unclaim_parcel(name, parcelpos)
factions.remove_key(factions.parcels, parcelpos, nil, "faction", true)
local faction = factions.factions.get(name)
faction.land[parcelpos] = nil
factions.factions.set(name, faction)
factions.increase_power(name, factions_config.power_per_parcel)
factions.decrease_usedpower(name, factions_config.power_per_parcel)
factions.on_unclaim_parcel(name, parcelpos)
factions.parcelless_check(name)
end
function factions.parcelless_check(name)
local faction = factions.factions.get(name)
if faction.land then
local count = 0
for index, value in pairs(faction.land) do
count = count + 1
break
end
if count > 0 then
if faction.no_parcel ~= -1 then
factions.broadcast(name, "Faction " .. name .. " will not be disbanded because it now has parcels.")
end
faction.no_parcel = -1
else
faction.no_parcel = os.time()
factions.on_no_parcel(name)
end
factions.factions.set(name, faction)
end
end
function factions.get_parcel_faction(parcelpos)
local data = factions.parcels.get(parcelpos)
if data then
local facname = data.faction
local faction = factions.factions.get(facname)
return faction, facname
end
return nil
end
function claim_helper(player, faction, parcelpos, no_msgs)
faction = factions.factions.get(faction.name)
if not faction then
return false
end
if faction.power < factions_config.power_per_parcel then
if not no_msgs then
minetest.chat_send_player(player, "Not enough power.")
end
return false
end
local p = parcelpos
local can_claim = factions.can_claim_parcel(faction.name, p)
if can_claim then
minetest.chat_send_player(player, "Claming parcel " .. p)
factions.claim_parcel(faction.name, p)
return true
else
local parcel_faction = factions.get_parcel_faction(p)
if parcel_faction and parcel_faction.name == faction.name then
if not no_msgs then
minetest.chat_send_player(player, "This parcel already belongs to your faction")
end
return false
elseif parcel_faction and parcel_faction.name ~= faction.name then
if not no_msgs then
minetest.chat_send_player(player, "This parcel belongs to another faction")
end
return false
else
if not no_msgs then
minetest.chat_send_player(player, "Your faction cannot claim any (more) parcel(s).")
end
return false
end
end
end
function unclaim_helper(player, faction, parcelpos, no_msgs)
faction = factions.factions.get(faction.name)
if not faction then
return false
end
local parcel_faction = factions.get_parcel_faction(parcelpos)
if not parcel_faction then
if not no_msgs then
minetest.chat_send_player(player, "This parcel does not exist.")
end
return false
end
if parcel_faction.name ~= faction.name then
if not no_msgs then
minetest.chat_send_player(player, "This parcel does not belong to you.")
end
return false
else
factions.unclaim_parcel(faction.name, parcelpos)
return true
end
end
local parcel_size = factions_config.parcel_size
function factions.claim_square(player, faction, r)
local rplayer = minetest.get_player_by_name(player)
local pos = vector.round(rplayer:get_pos())
pos.x = math.floor(pos.x / parcel_size) * parcel_size
pos.z = math.floor(pos.z / parcel_size) * parcel_size
pos.x = pos.x - (parcel_size * (r - math.floor(r / 2)))
pos.z = pos.z - (parcel_size * (r - math.floor(r / 2)))
local timer = 0
for i = 1, r do
for l = 1, r do
local p = {x = pos.x + (parcel_size * l), y = pos.y, z = pos.z + (parcel_size * i)}
minetest.after(timer, claim_helper, player, faction, factions.get_parcel_pos(p), true)
timer = timer + 0.1
end
end
end
local auto_list = {}
local function _claim_auto(player, faction)
if auto_list[player] then
local rplayer = minetest.get_player_by_name(player)
local parcelpos = vector.round(rplayer:get_pos())
claim_helper(player, faction, factions.get_parcel_pos(parcelpos), true)
minetest.after(0.1, _claim_auto, player, faction)
end
end
function factions.claim_auto(player, faction)
if auto_list[player] then
auto_list[player] = nil
minetest.chat_send_player(player, "Auto claim disabled.")
else
auto_list[player] = true
minetest.chat_send_player(player, "Auto claim enabled.")
_claim_auto(player, faction)
end
end
local function _claim_fill(player, faction, pos)
if claim_helper(player, faction, factions.get_parcel_pos(pos), true) then
local pos1 = {x = pos.x - parcel_size, y = pos.y, z = pos.z}
minetest.after(math.random(0, 11) / 10, _claim_fill, player, faction, pos1)
local pos2 = {x = pos.x + parcel_size, y = pos.y, z = pos.z}
minetest.after(math.random(0, 11) / 10, _claim_fill, player, faction, pos2)
local pos3 = {x = pos.x, y = pos.y, z = pos.z - parcel_size}
minetest.after(math.random(0, 11) / 10, _claim_fill, player, faction, pos3)
local pos4 = {x = pos.x, y = pos.y, z = pos.z + parcel_size}
minetest.after(math.random(0, 11) / 10, _claim_fill, player, faction, pos4)
end
end
function factions.claim_fill(player, faction)
local rplayer = minetest.get_player_by_name(player)
local pos = vector.round(rplayer:get_pos())
pos.x = math.floor(pos.x / parcel_size) * parcel_size
pos.z = math.floor(pos.z / parcel_size) * parcel_size
_claim_fill(player, faction, pos)
end
local parcel_size_center = parcel_size / 2
function factions.claim_circle(player, faction, r)
local rplayer = minetest.get_player_by_name(player)
local pos = vector.round(rplayer:get_pos())
pos.x = (math.floor(pos.x / parcel_size) * parcel_size) + parcel_size_center
pos.z = (math.floor(pos.z / parcel_size) * parcel_size) + parcel_size_center
for i = 1, 360 do
local angle = i * math.pi / 180
local rpos = {x = pos.x + r * math.cos(angle), y = pos.y, z = pos.z + r * math.sin(angle)}
claim_helper(player, faction, factions.get_parcel_pos(rpos), true)
end
end
local function _claim_all(player, faction, pos)
if faction.power >= factions_config.power_per_parcel then
claim_helper(player, faction, factions.get_parcel_pos(pos), true)
local pos1 = {x = pos.x - parcel_size, y = pos.y, z = pos.z}
minetest.after(math.random(0, 11) / 10, _claim_all, player, faction, pos1)
local pos2 = {x = pos.x + parcel_size, y = pos.y, z = pos.z}
minetest.after(math.random(0, 11) / 10, _claim_all, player, faction, pos2)
local pos3 = {x = pos.x, y = pos.y, z = pos.z - parcel_size}
minetest.after(math.random(0, 11) / 10, _claim_all, player, faction, pos3)
local pos4 = {x = pos.x, y = pos.y, z = pos.z + parcel_size}
minetest.after(math.random(0, 11) / 10, _claim_all, player, faction, pos4)
end
end
function factions.claim_all(player, faction)
local rplayer = minetest.get_player_by_name(player)
local pos = vector.round(rplayer:get_pos())
pos.x = math.floor(pos.x / parcel_size) * parcel_size
pos.z = math.floor(pos.z / parcel_size) * parcel_size
_claim_all(player, faction, pos)
end
function factions.claim_help(player, func)
local text = "All params for /f claim: <o,one, a,auto, f,fill, s,square, c,circle, all, l,list, h,help>, <none, number>"
if func == "o" or func == "one" then
text = "/f claim o\n/f claim one\n Claim one parcel."
elseif func == "a" or func == "auto" then
text = "/f claim a\n/f claim auto\nClaim as you walk around."
elseif func == "f" or func == "fill" then
text = "/f claim f\n/f claim fill\nClaim by filling."
elseif func == "s" or func == "square" then
text = "/f claim s <number>\n/f claim square <number>\nClaim by square and radius."
elseif func == "c" or func == "circle" then
text = "/f claim c <number>\n/f claim circle <number>\nClaim by circle and radius."
elseif func == "l" or func == "list" then
text = "/f claim l\n/f claim list\nList all the faction's claimed land."
elseif func == "all" then
text = "/f claim all\nClaim all faction land."
end
minetest.chat_send_player(player, text)
end
function factions.unclaim_square(player, faction, r)
local rplayer = minetest.get_player_by_name(player)
local pos = vector.round(rplayer:get_pos())
pos.x = math.floor(pos.x / parcel_size) * parcel_size
pos.z = math.floor(pos.z / parcel_size) * parcel_size
pos.x = pos.x - (parcel_size * (r - math.floor(r / 2)))
pos.z = pos.z - (parcel_size * (r - math.floor(r / 2)))
local timer = 0
for i = 1, r do
for l = 1, r do
local p = {x = pos.x + (parcel_size * l), y = pos.y, z = pos.z + (parcel_size * i)}
minetest.after(timer, unclaim_helper, player, faction, factions.get_parcel_pos(p), true)
timer = timer + 0.1
end
end
end
local function _unclaim_auto(player, faction)
if auto_list[player] then
local rplayer = minetest.get_player_by_name(player)
local parcelpos = vector.round(rplayer:get_pos())
unclaim_helper(player, faction, factions.get_parcel_pos(parcelpos), true)
minetest.after(0.1, _unclaim_auto, player, faction)
end
end
function factions.unclaim_auto(player, faction)
if auto_list[player] then
auto_list[player] = nil
minetest.chat_send_player(player, "Auto unclaim disabled.")
else
auto_list[player] = true
minetest.chat_send_player(player, "Auto unclaim enabled.")
_unclaim_auto(player, faction)
end
end
local function _unclaim_fill(player, faction, pos)
if unclaim_helper(player, faction, factions.get_parcel_pos(pos), true) then
local pos1 = {x = pos.x - parcel_size, y = pos.y, z = pos.z}
minetest.after(math.random(0, 11) / 10, _unclaim_fill, player, faction, pos1)
local pos2 = {x = pos.x + parcel_size, y = pos.y, z = pos.z}
minetest.after(math.random(0, 11) / 10, _unclaim_fill, player, faction, pos2)
local pos3 = {x = pos.x, y = pos.y, z = pos.z - parcel_size}
minetest.after(math.random(0, 11) / 10, _unclaim_fill, player, faction, pos3)
local pos4 = {x = pos.x, y = pos.y, z = pos.z + parcel_size}
minetest.after(math.random(0, 11) / 10, _unclaim_fill, player, faction, pos4)
end
end
function factions.unclaim_fill(player, faction)
local rplayer = minetest.get_player_by_name(player)
local pos = vector.round(rplayer:get_pos())
pos.x = math.floor(pos.x / parcel_size) * parcel_size
pos.z = math.floor(pos.z / parcel_size) * parcel_size
_unclaim_fill(player, faction, pos)
end
local parcel_size_center = parcel_size / 2
function factions.unclaim_circle(player, faction, r)
local rplayer = minetest.get_player_by_name(player)
local pos = vector.round(rplayer:get_pos())
pos.x = (math.floor(pos.x / parcel_size) * parcel_size) + parcel_size_center
pos.z = (math.floor(pos.z / parcel_size) * parcel_size) + parcel_size_center
for i = 1, 360 do
local angle = i * math.pi / 180
local rpos = {x = pos.x + r * math.cos(angle), y = pos.y, z = pos.z + r * math.sin(angle)}
unclaim_helper(player, faction, factions.get_parcel_pos(rpos), true)
end
end
local function _unclaim_all(player, faction)
local timer = 0
for i in pairs(faction.land) do
minetest.after(timer, factions.unclaim_parcel, faction.name, i)
timer = timer + 0.1
end
end
function factions.unclaim_all(player, faction)
local rplayer = minetest.get_player_by_name(player)
local pos = vector.round(rplayer:get_pos())
pos.x = math.floor(pos.x / parcel_size) * parcel_size
pos.z = math.floor(pos.z / parcel_size) * parcel_size
_unclaim_all(player, faction, pos)
end
function factions.unclaim_help(player, func)
local text = "All params for /f unclaim: <o,one, a,auto, f,fill, s,square, c,circle, all, l,list, h,help>, <none, number>"
if func == "o" or func == "one" then
text = "/f unclaim o\n/f unclaim one\n Unclaim one parcel."
elseif func == "a" or func == "auto" then
text = "/f unclaim a\n/f unclaim auto\nUnclaim as you walk around."
elseif func == "f" or func == "fill" then
text = "/f unclaim f\n/f unclaim fill\nUnclaim by filling."
elseif func == "s" or func == "square" then
text = "/f unclaim s <number>\n/f unclaim square <number>\nUnclaim by square and radius."
elseif func == "c" or func == "circle" then
text = "/f unclaim c <number>\n/f unclaim circle <number>\nUnclaim by circle and radius."
elseif func == "l" or func == "list" then
text = "/f claim l\n/f claim list\nList all the faction's claimed land."
elseif func == "all" then
text = "/f unclaim all\nUnclaim all faction land."
end
minetest.chat_send_player(player, text)
end
minetest.register_on_leaveplayer(function(player)
auto_list[player:get_player_name()] = nil
end)

View File

@ -0,0 +1,74 @@
function factions.start_diplomacy(name, faction)
for l, i in factions.factions.iterate() do
local fac = factions.factions.get(l)
if l ~= name and not (faction.neutral[l] or faction.allies[l] or faction.enemies[l]) then
if factions_config.faction_diplomacy == true then
factions.new_neutral(name, l)
factions.new_neutral(l, name)
else
factions.new_enemy(name, l)
factions.new_enemy(l, name)
end
end
end
end
function factions.new_alliance(name, faction)
local bfaction = factions.factions.get(name)
bfaction.allies[faction] = true
factions.on_new_alliance(name, faction)
if bfaction.enemies[faction] then
factions.end_enemy(name, faction)
end
if bfaction.neutral[faction] then
factions.end_neutral(name, faction)
end
factions.factions.set(name, bfaction)
end
function factions.end_alliance(name, faction)
local bfaction = factions.factions.get(name)
bfaction.allies[faction] = nil
factions.on_end_alliance(name, faction)
factions.factions.set(name, bfaction)
end
function factions.new_neutral(name, faction)
local bfaction = factions.factions.get(name)
bfaction.neutral[faction] = true
factions.on_new_neutral(name, faction)
if bfaction.allies[faction] then
factions.end_alliance(name, faction)
end
if bfaction.enemies[faction] then
factions.end_enemy(name, faction)
end
factions.factions.set(name, bfaction)
end
function factions.end_neutral(name, faction)
local bfaction = factions.factions.get(name)
bfaction.neutral[faction] = nil
factions.on_end_neutral(name, faction)
factions.factions.set(name, bfaction)
end
function factions.new_enemy(name, faction)
local bfaction = factions.factions.get(name)
bfaction.enemies[faction] = true
factions.on_new_enemy(name, faction)
if bfaction.allies[faction] then
factions.end_alliance(name, faction)
end
if bfaction.neutral[faction] then
factions.end_neutral(name, faction)
end
factions.factions.set(name, bfaction)
end
function factions.end_enemy(name, faction)
local bfaction = factions.factions.get(name)
bfaction.enemies[faction] = nil
factions.on_end_enemy(name, faction)
factions.factions.set(name, bfaction)
end

View File

@ -0,0 +1,107 @@
function factions.on_create(name) --! @brief called when the faction is added to the global faction list
minetest.chat_send_all("Faction " .. name .. " has been created.")
end
function factions.on_set_name(name, oldname)
minetest.chat_send_all("Faction " .. oldname .. " has been changed its name to ".. name ..".")
end
function factions.on_no_parcel(name)
local faction = factions.factions.get(name)
local now = os.time() - faction.no_parcel
local l = factions_config.maximum_parcelless_faction_time
factions.broadcast(name, "This faction will disband in " .. l - now .. " seconds, because it has no parcels.")
end
function factions.on_player_leave(name, player)
factions.broadcast(name, player .. " has left this faction")
end
function factions.on_player_join(name, player)
factions.broadcast(name, player .. " has joined this faction")
end
function factions.on_claim_parcel(name, pos)
factions.broadcast(name, "Parcel (" .. pos .. ") has been claimed.")
end
function factions.on_unclaim_parcel(name, pos)
factions.broadcast(name, "Parcel ("..pos..") has been unclaimed.")
end
function factions.on_disband(name, reason)
local msg = "Faction " .. name .. " has been disbanded."
if reason then
msg = msg .. " (" .. reason .. ")"
end
minetest.chat_send_all(msg)
end
function factions.on_new_leader(name)
local faction = factions.factions.get(name)
factions.broadcast(name, faction.leader .. " is now the leader of this faction")
end
function factions.on_change_description(name)
local faction = factions.factions.get(name)
factions.broadcast(name, "Faction description has been modified to: " .. faction.description)
end
function factions.on_player_invited(name, player)
local faction = factions.factions.get(name)
minetest.chat_send_player(player, "You have been invited to faction " .. faction.name)
end
function factions.on_toggle_join_free(name, player)
local faction = factions.factions.get(name)
if faction.join_free then
factions.broadcast(name, "This faction is now invite-free.")
else
factions.broadcast(name, "This faction is no longer invite-free.")
end
end
function factions.on_new_alliance(name, faction)
factions.broadcast(name, "This faction is now allied with " .. faction)
end
function factions.on_end_alliance(name, faction)
factions.broadcast(name, "This faction is no longer allied with " .. faction .. "!")
end
function factions.on_new_neutral(name, faction)
factions.broadcast(name, "This faction is now neutral with ".. faction)
end
function factions.on_end_neutral(name, faction)
factions.broadcast(name, "This faction is no longer neutral with " .. faction .. "!")
end
function factions.on_new_enemy(name, faction)
factions.broadcast(name, "This faction is now at war with " .. faction)
end
function factions.on_end_enemy(name, faction)
factions.broadcast(name, "This faction is no longer at war with " .. faction .. "!")
end
function factions.on_set_spawn(name)
local faction = factions.factions.get(name)
local spawn_str = faction.spawn.x .. ", " .. faction.spawn.y .. ", " .. faction.spawn.z
factions.broadcast(name, "The faction spawn has been set to (" .. spawn_str .. ").")
end
function factions.on_add_rank(name, rank)
local faction = factions.factions.get(name)
factions.broadcast(name, "The rank " .. rank .. " has been created with privileges: " .. table.concat(faction.ranks[rank], ", "))
end
function factions.on_replace_privs(name, rank)
local faction = factions.factions.get(name)
factions.broadcast(name, "The privileges in rank " .. rank .. " have been delete and changed to: " .. table.concat(faction.ranks[rank], ", "))
end
function factions.on_remove_privs(name, rank, privs)
factions.broadcast(name, "The privileges in rank " .. rank .. " have been revoked: " .. table.concat(privs, ", "))
end
function factions.on_add_privs(name, rank, privs)
factions.broadcast(name, "The privileges in rank " .. rank .. " have been added: " .. table.concat(privs, ", "))
end
function factions.on_set_rank_name(name, rank,newrank)
factions.broadcast(name, "The name of rank " .. rank .. " has been changed to " .. newrank)
end
function factions.on_delete_rank(name, rank, newrank)
factions.broadcast(name, "The rank " .. rank .. " has been deleted and replaced by " .. newrank)
end
function factions.on_set_def_rank(name, rank)
factions.broadcast(name, "The default rank given to new players has been changed to " .. rank)
end
function factions.on_reset_ranks(name)
factions.broadcast(name, "All of the faction's ranks have been reset to the default ones.")
end
function factions.on_promote(name, member)
local faction = factions.factions.get(name)
minetest.chat_send_player(member, "You have been promoted to " .. faction.players[member])
end
function factions.on_revoke_invite(name, player)
minetest.chat_send_player(player, "You are no longer invited to faction " .. name)
end

8
fac_events/init.lua Normal file
View File

@ -0,0 +1,8 @@
local path = minetest.get_modpath("fac_events")
dofile (path .. "/claim_events.lua")
dofile (path .. "/diplomacy_events.lua")
dofile (path .. "/eventcallbacks.lua")
dofile (path .. "/invite_events.lua")
dofile (path .. "/player_events.lua")
dofile (path .. "/power_events.lua")
dofile (path .. "/rank_events.lua")

View File

@ -0,0 +1,15 @@
--! @brief places player in invite list
function factions.invite_player(name, player)
local faction = factions.factions.get(name)
faction.invited_players[player] = true
factions.on_player_invited(name, player)
factions.factions.set(name, faction)
end
--! @brief removes player from invite list (can no longer join via /f join)
function factions.revoke_invite(name, player)
local faction = factions.factions.get(name)
faction.invited_players[player] = nil
factions.on_revoke_invite(name, player)
factions.factions.set(name, faction)
end

2
fac_events/mod.conf Normal file
View File

@ -0,0 +1,2 @@
name = fac_events
depends = fac

View File

@ -0,0 +1,85 @@
local on_death = {}
minetest.register_on_prejoinplayer(function(name, ip)
local data = factions.create_ip_table()
data.ip = ip
factions.player_ips.set(name, data)
end)
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
minetest.after(5, createHudfactionLand, player)
local faction, facname = factions.get_player_faction(name)
if faction then
if factions.onlineplayers[facname] == nil then
factions.onlineplayers[facname] = {}
end
factions.onlineplayers[facname][name] = true
faction.last_logon = os.time()
factions.factions.set(facname, faction)
minetest.after(5, createHudFactionName, player, facname)
minetest.after(5, createHudPower, player, faction)
if faction.no_parcel ~= -1 then
local now = os.time() - faction.no_parcel
local l = factions_config.maximum_parcelless_faction_time
minetest.chat_send_player(name, "This faction will disband in " .. l - now .. " seconds, because it has no parcels.")
end
if factions.has_permission(facname, name, "diplomacy") then
for _ in pairs(faction.request_inbox) do minetest.chat_send_player(name, "You have diplomatic requests in the inbox.") break end
end
if faction.message_of_the_day and (faction.message_of_the_day ~= "" or faction.message_of_the_day ~= " ") then
minetest.chat_send_player(name, faction.message_of_the_day)
end
end
end)
minetest.register_on_leaveplayer(function(player)
local name = player:get_player_name()
local faction, facname = factions.get_player_faction(name)
local id_name1 = name .. "factionLand"
if hud_ids[id_name1] then
hud_ids[id_name1] = nil
end
if faction then
faction.last_logon = os.time()
factions.factions.set(facname, faction)
factions.onlineplayers[facname][name] = nil
hud_ids[name .. "factionName"] = nil
hud_ids[name .. "powerWatch"] = nil
else
factions.remove_key(factions.player_ips, name, nil, "ip", true)
end
on_death[name] = nil
end)
minetest.register_on_respawnplayer(function(player)
local name = player:get_player_name()
local faction, facname = factions.get_player_faction(name)
if not faction then
return false
else
on_death[name] = nil
if not faction.spawn then
return false
else
player:set_pos(faction.spawn)
return true
end
end
end)
minetest.register_on_dieplayer(function(player)
local pname = player:get_player_name()
if on_death[pname] then
return
end
local faction, name = factions.get_player_faction(pname)
if not faction then
return
end
factions.decrease_power(name, factions_config.power_per_death)
on_death[pname] = true
return
end
)

View File

@ -0,0 +1,62 @@
function factions.increase_power(name, power)
local faction = factions.factions.get(name)
faction.power = faction.power + power
if faction.power > faction.maxpower - faction.usedpower then
faction.power = faction.maxpower - faction.usedpower
end
for i in pairs(factions.onlineplayers[name]) do
updateHudPower(minetest.get_player_by_name(i), faction)
end
factions.factions.set(name, faction)
end
function factions.decrease_power(name, power)
local faction = factions.factions.get(name)
faction.power = faction.power - power
for i in pairs(factions.onlineplayers[name]) do
updateHudPower(minetest.get_player_by_name(i), faction)
end
factions.factions.set(name, faction)
end
function factions.increase_maxpower(name, power)
local faction = factions.factions.get(name)
faction.maxpower = faction.maxpower + power
for i in pairs(factions.onlineplayers[name]) do
updateHudPower(minetest.get_player_by_name(i), faction)
end
factions.factions.set(name, faction)
end
function factions.decrease_maxpower(name, power)
local faction = factions.factions.get(name)
faction.maxpower = faction.maxpower - power
if faction.maxpower < 0 then -- should not happen
faction.maxpower = 0
end
for i in pairs(factions.onlineplayers[name]) do
updateHudPower(minetest.get_player_by_name(i), faction)
end
factions.factions.set(name, faction)
end
function factions.increase_usedpower(name, power)
local faction = factions.factions.get(name)
faction.usedpower = faction.usedpower + power
for i in pairs(factions.onlineplayers[name]) do
updateHudPower(minetest.get_player_by_name(i), faction)
end
factions.factions.set(name, faction)
end
function factions.decrease_usedpower(name, power)
local faction = factions.factions.get(name)
faction.usedpower = faction.usedpower - power
if faction.usedpower < 0 then
faction.usedpower = 0
end
for i in pairs(factions.onlineplayers[name]) do
updateHudPower(minetest.get_player_by_name(i), faction)
end
factions.factions.set(name, faction)
end

138
fac_events/rank_events.lua Normal file
View File

@ -0,0 +1,138 @@
--! @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.add_rank(name, rank, perms)
local faction = factions.factions.get(name)
faction.ranks[rank] = perms
factions.on_add_rank(name, rank)
factions.factions.set(name, faction)
end
--! @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.replace_privs(name, rank, perms)
local faction = factions.factions.get(name)
faction.ranks[rank] = perms
factions.on_replace_privs(name, rank)
factions.factions.set(name, faction)
end
function factions.remove_privs(name, rank, perms)
local faction = factions.factions.get(name)
local revoked = false
local p = faction.ranks[rank]
for index, perm in pairs(p) do
if table_Contains(perms, perm) then
revoked = true
table.remove(p, index)
end
end
faction.ranks[rank] = p
if revoked then
factions.on_remove_privs(name, rank, perms)
else
factions.broadcast(name, "No privilege was revoked from rank " .. rank .. ".")
end
factions.factions.set(name, faction)
end
function factions.add_privs(name, rank, perms)
local faction = factions.factions.get(name)
local added = false
local p = faction.ranks[rank]
for index, perm in pairs(perms) do
if not table_Contains(p, perm) then
added = true
table.insert(p, perm)
end
end
faction.ranks[rank] = p
if added then
factions.on_add_privs(name, rank, perms)
else
factions.broadcast(name, "The rank " .. rank .. " already has these privileges.")
end
factions.factions.set(name, faction)
end
function factions.set_rank_name(name, oldrank, newrank)
local faction = factions.factions.get(name)
local copyrank = faction.ranks[oldrank]
faction.ranks[newrank] = copyrank
faction.ranks[oldrank] = nil
for player, r in pairs(faction.players) do
if r == oldrank then
faction.players[player] = newrank
end
end
if oldrank == faction.default_leader_rank then
faction.default_leader_rank = newrank
factions.broadcast(name, "The default leader rank has been set to " .. newrank)
end
if oldrank == faction.default_rank then
faction.default_rank = newrank
factions.broadcast(name, "The default rank given to new players is set to " .. newrank)
end
factions.on_set_rank_name(name, oldrank, newrank)
factions.factions.set(name, faction)
end
function factions.set_def_rank(name, rank)
local faction = factions.factions.get(name)
for player, r in pairs(faction.players) do
if r == rank or r == nil or not faction.ranks[r] then
faction.players[player] = rank
end
end
faction.default_rank = rank
factions.on_set_def_rank(name, rank)
factions.factions.set(name, faction)
end
function factions.reset_ranks(name)
local faction = factions.factions.get(name)
faction.ranks = starting_ranks
faction.default_rank = "member"
faction.default_leader_rank_rank = "leader"
for player, r in pairs(faction.players) do
if not player == leader and (r == nil or not faction.ranks[r]) then
faction.players[player] = faction.default_rank
elseif player == leader then
faction.players[player] = faction.default_leader_rank_rank
end
end
factions.on_reset_ranks(name)
factions.factions.set(name, faction)
end
--! @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.delete_rank(name, rank, newrank)
local faction = factions.factions.get(name)
for player, r in pairs(faction.players) do
if r == rank then
faction.players[player] = newrank
end
end
faction.ranks[rank] = nil
factions.on_delete_rank(name, rank, newrank)
if rank == faction.default_leader_rank then
faction.default_leader_rank = newrank
factions.broadcast(name, "The default leader rank has been set to "..newrank)
end
if rank == faction.default_rank then
faction.default_rank = newrank
factions.broadcast(name, "The default rank given to new players is set to "..newrank)
end
factions.factions.set(name, faction)
end
--! @brief set a player's rank
function factions.promote(name, member, rank)
local faction = factions.factions.get(name)
faction.players[member] = rank
factions.on_promote(name, member)
factions.factions.set(name, faction)
end

126
fac_hud/init.lua Normal file
View File

@ -0,0 +1,126 @@
hud_ids = {}
function createHudfactionLand(player)
if player then
local name = player:get_player_name()
local id_name = name .. "factionLand"
if not hud_ids[id_name] then
hud_ids[id_name] = player:hud_add({
hud_elem_type = "text",
name = "factionLand",
number = 0xFFFFFF,
position = {x=0.1, y = .98},
text = "Parcel:",
scale = {x=1, y=1},
alignment = {x=0, y=0},
})
end
end
end
function createHudFactionName(player, factionname)
if player and factionname then
local name = player:get_player_name()
local id_name = name .. "factionName"
if not hud_ids[id_name] then
hud_ids[id_name] = player:hud_add({
hud_elem_type = "text",
name = "factionName",
number = 0xFFFFFF,
position = {x=1, y = 0},
text = "Faction " .. factionname,
scale = {x=1, y=1},
alignment = {x=-1, y=0},
offset = {x = -20, y = 20}
})
end
end
end
function createHudPower(player, faction)
if player and faction then
local name = player:get_player_name()
local id_name = name .. "powerWatch"
if not hud_ids[id_name] then
hud_ids[id_name] = player:hud_add({
hud_elem_type = "text",
name = "powerWatch",
number = 0xFFFFFF,
position = {x=0.9, y = .98},
text = "Power: " .. faction.power .. " / " .. faction.maxpower - faction.usedpower,
scale = {x=1, y=1},
alignment = {x=-1, y=0},
offset = {x = 0, y = 0}
})
end
end
end
function removeHud(player, hudname)
local name = ""
local p = {}
if type(player) ~= "string" then
name = player:get_player_name()
p = player
else
name = player
p = minetest.get_player_by_name(player)
end
local id_name = name .. hudname
if hud_ids[id_name] then
p:hud_remove(hud_ids[id_name])
hud_ids[id_name] = nil
end
end
function updateHudPower(player, faction)
local name = player:get_player_name()
local id_name = name .. "powerWatch"
if hud_ids[id_name] then
player:hud_change(hud_ids[id_name], "text", "Power: " .. faction.power .. " / " .. faction.maxpower - faction.usedpower)
end
end
function updateFactionName(player, factionname)
local name = ""
local p = {}
if type(player) ~= "string" then
name = player:get_player_name()
p = player
else
name = player
p = minetest.get_player_by_name(player)
end
local id_name = name .. "factionName"
if hud_ids[id_name] then
p:hud_change(hud_ids[id_name], "text", "Faction " .. factionname)
end
end
function hudUpdateClaimInfo()
local playerslist = minetest.get_connected_players()
for i in pairs(playerslist) do
local player = playerslist[i]
local name = player:get_player_name()
local faction, facname = factions.get_faction_at(player:get_pos())
local id_name = name .. "factionLand"
if hud_ids[id_name] then
local display = "Parcel:"
if facname then
display = display .. facname
end
player:hud_change(hud_ids[id_name], "text", display)
end
end
minetest.after(3, hudUpdateClaimInfo)
end
hudUpdateClaimInfo()

1
fac_hud/mod.conf Normal file
View File

@ -0,0 +1 @@
name = fac_hud

248
fac_objects/init.lua Normal file
View File

@ -0,0 +1,248 @@
function factions.can_use_node(pos, player, permission)
if not player then
return false
end
local parcel_faction = factions.get_faction_at(pos)
if not parcel_faction then
return true
end
local player_faction, facname = factions.get_player_faction(player)
if player_faction and (parcel_faction.name == facname or parcel_faction.allies[facname]) and factions.has_permission(facname, player, permission) then
return true
end
end
minetest.register_on_mods_loaded(function()
-- Make default chest the faction chest.
if minetest.registered_nodes["default:chest"] then
local dc = minetest.registered_nodes["default:chest"]
local def_on_rightclick = dc.on_rightclick
local after_place_node = function(pos, placer)
local parcel_faction = factions.get_faction_at(pos)
if parcel_faction then
local meta = minetest.get_meta(pos)
local name = parcel_faction.name
meta:set_string("faction", name)
meta:set_string("infotext", "Faction Container (owned by faction " ..
name .. ")")
end
end
local can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("main") and
factions.can_use_node(pos, player:get_player_name(), "container")
end
local allow_metadata_inventory_move
local def_allow_metadata_inventory_move = dc.allow_metadata_inventory_move
if def_allow_metadata_inventory_move then
allow_metadata_inventory_move = function(pos, from_list, from_index,
to_list, to_index, count, player)
if not factions.can_use_node(pos, player:get_player_name(), "container") and not minetest.check_player_privs(player, "protection_bypass") then
return 0
end
return def_allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
end
else
allow_metadata_inventory_move = function(pos, from_list, from_index,
to_list, to_index, count, player)
if not factions.can_use_node(pos, player:get_player_name(), "container") and not minetest.check_player_privs(player, "protection_bypass") then
return 0
end
return count
end
end
local allow_metadata_inventory_put
local def_allow_metadata_inventory_put = dc.allow_metadata_inventory_put
if def_allow_metadata_inventory_put then
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if not factions.can_use_node(pos, player:get_player_name(), "container") and not minetest.check_player_privs(player, "protection_bypass") then
return 0
end
return def_allow_metadata_inventory_put(pos, listname, index, stack, player)
end
else
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if not factions.can_use_node(pos, player:get_player_name(), "container") and not minetest.check_player_privs(player, "protection_bypass") then
return 0
end
return stack:get_count()
end
end
local allow_metadata_inventory_take
local def_allow_metadata_inventory_take = dc.allow_metadata_inventory_take
if def_allow_metadata_inventory_take then
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if not factions.can_use_node(pos, player:get_player_name(), "container") and not minetest.check_player_privs(player, "protection_bypass") then
return 0
end
return def_allow_metadata_inventory_take(pos, listname, index, stack, player)
end
else
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if not factions.can_use_node(pos, player:get_player_name(), "container") and not minetest.check_player_privs(player, "protection_bypass") then
return 0
end
return stack:get_count()
end
end
local on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
if not factions.can_use_node(pos, clicker:get_player_name(), "container") and not minetest.check_player_privs(clicker, "protection_bypass") then
return itemstack
end
return def_on_rightclick(pos, node, clicker, itemstack, pointed_thing)
end
minetest.override_item("default:chest", {after_place_node = after_place_node,
can_dig = can_dig,
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
on_rightclick = on_rightclick})
end
local door_items = {"doors:door_wood", "doors:door_steel", "doors:door_glass", "doors:door_obsidian_glass", "doors:woodglass_door", "doors:slide_door",
"doors:screen_door", "doors:rusty_prison_door", "doors:prison_door", "doors:japanese_door", "ts_doors:door_default_aspen_wood", "ts_doors:door_full_default_aspen_wood",
"ts_doors:door_default_pine_wood", "ts_doors:door_full_default_pine_wood", "ts_doors:door_default_acacia_wood", "ts_doors:door_full_default_acacia_wood",
"ts_doors:door_default_wood", "ts_doors:door_full_default_wood", "ts_doors:door_default_junglewood", "ts_doors:door_full_default_junglewood",
"ts_doors:door_default_bronzeblock", "ts_doors:door_full_default_bronzeblock", "ts_doors:door_default_copperblock", "ts_doors:door_full_default_copperblock",
"ts_doors:door_default_diamondblock", "ts_doors:door_full_default_diamondblock", "ts_doors:door_full_default_goldblock", "ts_doors:door_default_steelblock", "ts_doors:door_full_default_steelblock"}
local trapdoor_items = {"doors:trapdoor", "doors:trapdoor_steel", "ts_doors:trapdoor_default_aspen_wood", "ts_doors:trapdoor_full_default_aspen_wood",
"ts_doors:trapdoor_default_wood", "ts_doors:trapdoor_full_default_wood", "ts_doors:trapdoor_default_acacia_wood", "ts_doors:trapdoor_full_default_acacia_wood",
"ts_doors:trapdoor_default_bronzeblock", "ts_doors:trapdoor_full_default_bronzeblock", "ts_doors:trapdoor_default_copperblock", "ts_doors:trapdoor_full_default_copperblock", "ts_doors:trapdoor_full_default_diamondblock",
"ts_doors:door_default_goldblock", "ts_doors:trapdoor_default_steelblock", "ts_doors:trapdoor_full_default_steelblock", "ts_doors:trapdoor_default_pine_wood", "ts_doors:trapdoor_full_default_pine_wood",
"ts_doors:trapdoor_full_default_goldblock", "ts_doors:trapdoor_default_junglewood", "ts_doors:trapdoor_full_default_junglewood",
"ts_doors:trapdoor_default_diamondblock", "ts_doors:trapdoor_default_goldblock"}
-- Edit default doors and trapdoors to make them require the door permission.
local doors = {}
local all_items = {}
local item_count = 1
local old_i = 0
for i, l in ipairs(door_items) do
doors[item_count] = l .. "_a"
doors[item_count + 1] = l .. "_b"
all_items[i] = l
item_count = item_count + 2
old_i = old_i + 1
end
for i, l in ipairs(trapdoor_items) do
doors[item_count] = l
doors[item_count + 1] = l .. "_open"
all_items[old_i + i] = l
item_count = item_count + 2
end
for i, l in ipairs(doors) do
local dw = minetest.registered_nodes[l]
if dw then
local def_on_rightclick = dw.on_rightclick
local def_can_dig = dw.can_dig
local on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
if factions.can_use_node(pos, clicker:get_player_name(), "door") or minetest.check_player_privs(clicker, "protection_bypass") then
def_on_rightclick(pos, node, clicker, itemstack, pointed_thing)
end
return itemstack
end
local can_dig = nil
if def_can_dig then
can_dig = function(pos, digger)
if factions.can_use_node(pos, digger:get_player_name(), "door") then
return def_can_dig(pos, digger)
end
return false
end
else
can_dig = function(pos, digger)
if factions.can_use_node(pos, digger:get_player_name(), "door") then
return true
end
return false
end
end
minetest.override_item(l, {on_rightclick = on_rightclick,
can_dig = can_dig})
end
end
for i, l in ipairs(all_items) do
local it = minetest.registered_items[l]
if it then
local def_on_place = it.on_place
if def_on_place ~= nil then
local on_place = function(itemstack, placer, pointed_thing)
local r = def_on_place(itemstack, placer, pointed_thing)
local pos = pointed_thing.above
local parcel_faction = factions.get_faction_at(pos)
if parcel_faction then
local meta = minetest.get_meta(pos)
local name = parcel_faction.name
meta:set_string("faction", name)
meta:set_string("infotext", "Faction Door (owned by faction " ..
name .. ")")
end
return r
end
minetest.override_item(l, {on_place = on_place})
end
end
end
end)
-- Code below was copied from TenPlus1's protector mod(MIT) and changed up a bit.
local x = math.floor(factions_config.parcel_size / 2.1)
minetest.register_node("fac_objects:display_node", {
tiles = {"factions_display.png"},
use_texture_alpha = true,
walkable = false,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
-- sides
{-(x+.55), -(x+.55), -(x+.55), -(x+.45), (x+.55), (x+.55)},
{-(x+.55), -(x+.55), (x+.45), (x+.55), (x+.55), (x+.55)},
{(x+.45), -(x+.55), -(x+.55), (x+.55), (x+.55), (x+.55)},
{-(x+.55), -(x+.55), -(x+.55), (x+.55), (x+.55), -(x+.45)},
-- top
{-(x+.55), (x+.45), -(x+.55), (x+.55), (x+.55), (x+.55)},
-- bottom
{-(x+.55), -(x+.55), -(x+.55), (x+.55), -(x+.45), (x+.55)},
-- middle (surround parcel)
{-.55,-.55,-.55, .55,.55,.55},
},
},
selection_box = {
type = "regular",
},
paramtype = "light",
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
drop = "",
})
minetest.register_entity("fac_objects:display", {
physical = false,
collisionbox = {0, 0, 0, 0, 0, 0},
visual = "wielditem",
visual_size = {x = 1.0 / 1.5, y = 1.0 / 1.5},
textures = {"fac_objects:display_node"},
timer = 0,
on_step = function(self, dtime)
self.timer = self.timer + dtime
if self.timer > 6 then
self.object:remove()
end
end,
})
-- End

2
fac_objects/mod.conf Normal file
View File

@ -0,0 +1,2 @@
name = fac_objects
depends = fac

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

View File

@ -0,0 +1,2 @@
following Textures created by Coder12a (CC BY-SA 3.0):
factions_display.png

41
fac_protect/init.lua Normal file
View File

@ -0,0 +1,41 @@
local default_is_protected = minetest.is_protected
minetest.is_protected = function(pos, player)
if minetest.check_player_privs(player, "protection_bypass") then
return default_is_protected(pos, player)
end
local y = pos.y
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 default_is_protected(pos, player)
end
local parcelpos = factions.get_parcel_pos(pos)
local parcel_faction, parcel_fac_name = factions.get_parcel_faction(parcelpos)
local player_faction
local player_fac_name
if player then
player_faction, player_fac_name = factions.get_player_faction(player)
end
-- no faction
if not parcel_faction then
return default_is_protected(pos, player)
elseif player_faction then
if parcel_faction.name == player_faction.name then
if factions.has_permission(parcel_fac_name, player, "pain_build") then
local p = minetest.get_player_by_name(player)
p:set_hp(p:get_hp() - 0.5)
end
return not (factions.has_permission(parcel_fac_name, player, "build") or factions.has_permission(parcel_fac_name, player, "pain_build"))
elseif parcel_faction.allies[player_faction.name] then
if factions.has_permission(player_fac_name, player, "pain_build") then
local p = minetest.get_player_by_name(player)
p:set_hp(p:get_hp() - 0.5)
end
return not (factions.has_permission(player_fac_name, player, "build") or factions.has_permission(player_fac_name, player, "pain_build"))
else
return true
end
else
return true
end
return default_is_protected(pos, player)
end

1
fac_protect/mod.conf Normal file
View File

@ -0,0 +1 @@
name = fac_protect

View File

@ -1,778 +0,0 @@
-------------------------------------------------------------------------------
-- factions Mod by Sapier
--
-- License WTFPL
--
--! @file factions.lua
--! @brief factions core file containing datastorage
--! @copyright Sapier
--! @author Sapier
--! @date 2013-05-08
--
-- Contact sapier a t gmx net
-------------------------------------------------------------------------------
--read some basic information
local factions_worldid = minetest.get_worldpath()
--! @class factions
--! @brief main class for factions
factions = {}
--! @brief runtime data
factions.data = {}
factions.data.factions = {}
factions.data.objects = {}
factions.dynamic_data = {}
factions.dynamic_data.membertable = {}
factions.print = function(text)
print("Factions: " .. dump(text))
end
factions.dbg_lvl1 = function() end --factions.print -- errors
factions.dbg_lvl2 = function() end --factions.print -- non cyclic trace
factions.dbg_lvl3 = function() end --factions.print -- cyclic trace
-------------------------------------------------------------------------------
-- name: add_faction(name)
--
--! @brief add a faction
--! @memberof factions
--! @public
--
--! @param name of faction to add
--!
--! @return true/false (succesfully added faction or not)
-------------------------------------------------------------------------------
function factions.add_faction(name)
if factions.data.factions[name] == nil then
factions.data.factions[name] = {}
factions.data.factions[name].reputation = {}
factions.data.factions[name].base_reputation = {}
factions.data.factions[name].adminlist = {}
factions.data.factions[name].invitations = {}
factions.dynamic_data.membertable[name] = {}
factions.save()
return true
end
return false
end
-------------------------------------------------------------------------------
-- name: set_base_reputation(faction1,faction2,value)
--
--! @brief set base reputation between two factions
--! @memberof factions
--! @public
--
--! @param faction1 first faction
--! @param faction2 second faction
--! @param value value to use
--!
--! @return true/false (succesfully added faction or not)
-------------------------------------------------------------------------------
function factions.set_base_reputation(faction1,faction2,value)
if factions.data.factions[faction1] ~= nil and
factions.data.factions[faction2] ~= nil then
factions.data.factions[faction1].base_reputation[faction2] = value
factions.data.factions[faction2].base_reputation[faction1] = value
factions.save()
return true
end
return false
end
-------------------------------------------------------------------------------
-- name: get_base_reputation(faction1,faction2)
--
--! @brief get base reputation between two factions
--! @memberof factions
--! @public
--
--! @param faction1 first faction
--! @param faction2 second faction
--!
--! @return reputation/0 if none set
-------------------------------------------------------------------------------
function factions.get_base_reputation(faction1,faction2)
factions.dbg_lvl3("get_base_reputation: " .. faction1 .. "<-->" .. faction2)
if factions.data.factions[faction1] ~= nil and
factions.data.factions[faction2] ~= nil then
if factions.data.factions[faction1].base_reputation[faction2] ~= nil then
return factions.data.factions[faction1].base_reputation[faction2]
end
end
return 0
end
-------------------------------------------------------------------------------
-- name: set_description(name,description)
--
--! @brief set description for a faction
--! @memberof factions
--! @public
--
--! @param name of faction
--! @param description text describing a faction
--!
--! @return true/false (succesfully set description)
-------------------------------------------------------------------------------
function factions.set_description(name,description)
if factions.data.factions[name] ~= nil then
factions.data.factions[name].description = description
factions.save()
return true
end
return false
end
-------------------------------------------------------------------------------
-- name: get_description(name)
--
--! @brief get description for a faction
--! @memberof factions
--! @public
--
--! @param name of faction
--!
--! @return description or ""
-------------------------------------------------------------------------------
function factions.get_description(name)
if factions.data.factions[name] ~= nil and
factions.data.factions[name].description ~= nil then
return factions.data.factions[name].description
end
return ""
end
-------------------------------------------------------------------------------
-- name: exists(name)
--
--! @brief check if a faction exists
--! @memberof factions
--! @public
--! @param name name to check
--!
--! @return true/false
-------------------------------------------------------------------------------
function factions.exists(name)
for key,value in pairs(factions.data.factions) do
if key == name then
return true
end
end
return false
end
-------------------------------------------------------------------------------
-- name: get_faction_list()
--
--! @brief get list of factions
--! @memberof factions
--! @public
--!
--! @return list of factions
-------------------------------------------------------------------------------
function factions.get_faction_list()
local retval = {}
for key,value in pairs(factions.data.factions) do
table.insert(retval,key)
end
return retval
end
-------------------------------------------------------------------------------
-- name: delete_faction(name)
--
--! @brief delete a faction
--! @memberof factions
--! @public
--
--! @param name of faction to delete
--!
--! @return true/false (succesfully added faction or not)
-------------------------------------------------------------------------------
function factions.delete_faction(name)
factions.data.factions[name] = nil
factions.save()
if factions.data.factions[name] == nil then
return true
end
return false
end
-------------------------------------------------------------------------------
-- name: member_add(name,object)
--
--! @brief add an entity or player to a faction
--! @memberof factions
--! @public
--
--! @param name of faction to add object to
--! @param object to add to faction
--!
--! @return true/false (succesfully added faction or not)
-------------------------------------------------------------------------------
function factions.member_add(name, object)
local new_entry = {}
new_entry.factions = {}
if object.object ~= nil then
object = object.object
end
if not factions.exists(name) then
print("Unable to add to NON existant faction >" .. name .. "<")
return false
end
new_entry.name,new_entry.temporary = factions.get_name(object)
factions.dbg_lvl2("Adding name=" .. dump(new_entry.name) .. " to faction: " .. name )
if new_entry.name ~= nil then
if factions.data.objects[new_entry.name] == nil then
factions.data.objects[new_entry.name] = new_entry
end
if factions.data.objects[new_entry.name].factions[name] == nil then
factions.data.objects[new_entry.name].factions[name] = true
factions.dynamic_data.membertable[name][new_entry.name] = true
factions.data.factions[name].invitations[new_entry.name] = nil
factions.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 factions
--! @public
--
--! @param name of faction to add object to
--! @param name of player to invite
--!
--! @return true/false (succesfully added invitation or not)
-------------------------------------------------------------------------------
function factions.member_invite(name, playername)
if factions.data.factions[name] ~= nil and
factions.data.factions[name].invitations[playername] == nil then
factions.data.factions[name].invitations[playername] = true
factions.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 factions
--! @public
--
--! @param name of faction to add object to
--! @param object to add to faction
--!
--! @return true/false (succesfully added faction or not)
-------------------------------------------------------------------------------
function factions.member_remove(name,object)
local id,type = factions.get_name(object)
factions.dbg_lvl2("removing name=" .. dump(id) .. " to faction: " .. name )
if id ~= nil and
factions.data.objects[id] ~= nil and
factions.data.objects[id].factions[name] ~= nil then
factions.data.objects[id].factions[name] = nil
factions.dynamic_data.membertable[name][id] = nil
factions.save()
return true
end
if id ~= nil and
factions.data.factions[name].invitations[id] ~= nil then
factions.data.factions[name].invitations[id] = nil
factions.save()
return true
end
return false
end
-------------------------------------------------------------------------------
-- name: set_admin(name,playername,value)
--
--! @brief set admin priviles for a playername
--! @memberof factions
--! @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 factions.set_admin(name,playername,value)
--mobf_assert_backtrace(type(playername) == "string")
if factions.data.factions[name] ~= nil then
if value then
factions.data.factions[name].adminlist[playername] = true
factions.save()
return true
else
factions.data.factions[name].adminlist[playername] = nil
factions.save()
return true
end
else
print("FACTIONS: no faction >" .. name .. "< found")
end
return false
end
-------------------------------------------------------------------------------
-- name: set_free(name,value)
--
--! @brief set faction to be joinable by everyone
--! @memberof factions
--! @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 factions.set_free(name,value)
if factions.data.factions[name] ~= nil then
if value then
if factions.data.factions[name].open == nil then
factions.data.factions[name].open = true
factions.save()
return true
else
return false
end
else
if factions.data.factions[name].open == nil then
return false
else
factions.data.factions[name].open = nil
factions.save()
return true
end
end
end
return false
end
-------------------------------------------------------------------------------
-- name: is_free(name)
--
--! @brief check if a fraction is free to join
--! @memberof factions
--! @public
--
--! @param name of faction to add object to
--
--! @return true/false (free or not)
-------------------------------------------------------------------------------
function factions.is_free(name)
if factions.data.factions[name] ~= nil and
factions.data.factions[name].open then
return true
end
return false
end
-------------------------------------------------------------------------------
-- name: is_admin(name,playername)
--
--! @brief read admin privilege of player
--! @memberof factions
--! @public
--
--! @param name of faction to check rights
--! @param playername to change rights
--!
--! @return true/false (succesfully added faction or not)
-------------------------------------------------------------------------------
function factions.is_admin(name,playername)
if factions.data.factions[name] ~= nil and
factions.data.factions[name].adminlist[playername] == true then
return true
end
return false
end
-------------------------------------------------------------------------------
-- name: is_invited(name,playername)
--
--! @brief read invitation status of player
--! @memberof factions
--! @public
--
--! @param name of faction to check for invitation
--! @param playername to change rights
--!
--! @return true/false (succesfully added faction or not)
-------------------------------------------------------------------------------
function factions.is_invited(name,playername)
if factions.data.factions[name] ~= nil and
( factions.data.factions[name].invitations[playername] == true or
factions.data.factions[name].open == true) then
return true
end
return false
end
-------------------------------------------------------------------------------
-- name: get_factions(object)
--
--! @brief get list of factions for an object
--! @memberof factions
--! @public
--
--! @param object to get list for
--!
--! @return list of factions
-------------------------------------------------------------------------------
function factions.get_factions(object)
local id,type = factions.get_name(object)
local retval = {}
if id ~= nil and
factions.data.objects[id] ~= nil then
for key,value in pairs(factions.data.objects[id].factions) do
table.insert(retval,key)
end
end
return retval
end
-------------------------------------------------------------------------------
-- name: is_member(name,object)
--
--! @brief check if object is member of name
--! @memberof factions
--! @public
--
--! @param name of faction to check
--! @param object to check
--!
--! @return true/false
-------------------------------------------------------------------------------
function factions.is_member(name,object)
local retval = false
local id,type = factions.get_name(object)
if id ~= nil and
factions.data.objects[id] ~= nil then
for key,value in pairs(factions.data.objects[id].factions) 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 factions
--! @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 factions.get_reputation(name,object)
local id,type = factions.get_name(object)
factions.dbg_lvl3("get_reputation: " .. name .. "<-->" .. dump(id))
if id ~= nil and
factions.data.factions[name] ~= nil then
factions.dbg_lvl3("get_reputation: object reputation: " .. dump(factions.data.factions[name].reputation[id]))
if factions.data.factions[name].reputation[id] == nil then
factions.data.factions[name].reputation[id]
= factions.calc_base_reputation(name,object)
end
return factions.data.factions[name].reputation[id]
else
factions.dbg_lvl3("get_reputation: didn't find any factions for: " .. name)
end
return 0
end
-------------------------------------------------------------------------------
-- name: modify_reputation(name,object,delta)
--
--! @brief modify reputation of an object for a faction
--! @memberof factions
--! @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 factions.modify_reputation(name,object,delta)
local id,type = factions.get_name(object)
if factions.data.factions[name] ~= nil then
if factions.data.factions[name].reputation[id] == nil then
factions.data.factions[name].reputation[id]
= factions.calc_base_reputation(name,object)
end
factions.data.factions[name].reputation[id]
= factions.data.factions[name].reputation[id] + delta
factions.save()
return true
end
return false
end
-------------------------------------------------------------------------------
-- name: get_name(object)
--
--! @brief get textual name of object
--! @memberof factions
--! @private
--
--! @param object fetch name for this
--!
--! @return name or nil,is temporary element
-------------------------------------------------------------------------------
function factions.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 factions
--! @private
--
--! @param name name of faction
--! @param object calc reputation for this
--!
--! @return reputation value
-------------------------------------------------------------------------------
function factions.calc_base_reputation(name,object)
--calculate initial reputation based uppon all groups
local object_factions = factions.get_factions(object)
local rep_value = 0
factions.dbg_lvl3("calc_base_reputation: " .. name .. " <--> " .. tostring(object))
if object_factions ~= nil then
factions.dbg_lvl3("calc_base_reputation: " .. tostring(object) .. " is in " .. #object_factions .. " factions")
for k,v in pairs(object_factions) do
if factions.data.factions[v] == nil then
print("FACTIONS: warning object is member of faction " .. v .. " which doesn't exist")
else
factions.dbg_lvl3("calc_base_reputation: " .. name .. " <--> " .. v .. " rep=" .. dump(factions.data.factions[v].base_reputation[name]))
if factions.data.factions[v].base_reputation[name] ~= nil then
rep_value =
rep_value + factions.data.factions[v].base_reputation[name]
end
end
end
rep_value = rep_value / #object_factions
end
return rep_value
end
-------------------------------------------------------------------------------
-- name: save()
--
--! @brief save data to file
--! @memberof factions
--! @private
-------------------------------------------------------------------------------
function factions.save()
--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.data))
file:close()
else
minetest.log("error","MOD factions: unable to save factions world specific data!: " .. error)
end
end
-------------------------------------------------------------------------------
-- name: load()
--
--! @brief load data from file
--! @memberof factions
--! @private
--
--! @return true/false
-------------------------------------------------------------------------------
function factions.load()
local file,error = io.open(factions_worldid .. "/" .. "factions.conf","r")
if file ~= nil then
local raw_data = file:read("*a")
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
factions.data.objects[key] = value
else
temp_objects[key] = true
end
end
end
if raw_table.factions ~= nil then
for key,value in pairs(raw_table.factions) do
factions.data.factions[key] = {}
factions.data.factions[key].base_reputation = value.base_reputation
factions.data.factions[key].adminlist = value.adminlist
factions.data.factions[key].open = value.open
factions.data.factions[key].invitations = value.invitations
factions.data.factions[key].description = value.description
factions.data.factions[key].reputation = {}
for repkey,repvalue in pairs(value.reputation) do
if temp_objects[repkey] == nil then
factions.data.factions[key].reputation[repkey] = repvalue
end
end
factions.dynamic_data.membertable[key] = {}
end
end
--populate dynamic faction member table
for id,object in pairs(factions.data.objects) do
for name,value in pairs(factions.data.objects[id].factions) do
if value then
if factions.dynamic_data.membertable[name] then -- One of the indexes above is nil. Which one? No idea. //MFF(Mg|07/29/15)
factions.dynamic_data.membertable[name][id] = true
end
end
end
end
end
else
local file,error = io.open(factions_worldid .. "/" .. "factions.conf","w")
if file ~= nil then
file:close()
else
minetest.log("error","MOD factions: unable to save factions world specific data!: " .. error)
end
end
--create special faction players
factions.add_faction("players")
--autojoin players to faction players
minetest.register_on_joinplayer(
function(player)
if player:is_player() then
factions.member_add("players",player)
end
end
)
end

View File

@ -1,30 +0,0 @@
-------------------------------------------------------------------------------
-- factions Mod by Sapier
--
-- License WTFPL
--
--! @file init.lua
--! @brief factions mod to be used by other mods
--! @copyright Sapier
--! @author Sapier
--! @date 2013-05-08
--!
-- Contact sapier a t gmx net
-------------------------------------------------------------------------------
local factions_version = "0.1.6"
core.log("action", "MOD: factions (by sapier) loading ...")
--!path of mod
factions_modpath = minetest.get_modpath("factions")
dofile (factions_modpath .. "/factions.lua")
dofile (factions_modpath .. "/chatcommands.lua")
factions.version = factions_version
factions.load()
factions_chat.init()
core.log("action","MOD: factions (by sapier) " .. factions_version .. " loaded.")

View File

@ -1,2 +0,0 @@
name = factions
description = Mod for handling in game factions and reputation

1
modpack.conf Normal file
View File

@ -0,0 +1 @@
name = factions