From 74f3afdf4bb9c2fc23a53d4fd14d3c8c74976141 Mon Sep 17 00:00:00 2001 From: ComputerTech312 Date: Wed, 24 Sep 2025 20:26:49 +0100 Subject: [PATCH] Restructure config.json with nested hierarchy and dot notation access - Reorganized config.json into logical sections: connection, duck_spawning, duck_types, player_defaults, gameplay, features, limits - Enhanced get_config() method to support dot notation (e.g., 'duck_types.normal.xp') - Added comprehensive configurable parameters for all game mechanics - Updated player creation to use configurable starting values - Added individual timeout settings per duck type - Made XP rewards, accuracy mechanics, and game limits fully configurable - Fixed syntax errors in duck_spawn_loop function --- .gitignore | 74 ---------------- __pycache__/duckhunt.cpython-312.pyc | Bin 0 -> 2077 bytes config.json | 83 ++++++++++++++---- duckhunt.log | 11 +++ levels.json | 34 +++++--- messages.json | 91 ++++++++++---------- shop.json | 8 ++ src/__pycache__/db.cpython-312.pyc | Bin 5113 -> 12404 bytes src/__pycache__/duckhuntbot.cpython-312.pyc | Bin 32017 -> 44517 bytes src/__pycache__/game.cpython-312.pyc | Bin 10946 -> 18387 bytes src/__pycache__/levels.cpython-312.pyc | Bin 0 -> 10493 bytes src/__pycache__/shop.cpython-312.pyc | Bin 0 -> 14952 bytes src/__pycache__/utils.cpython-312.pyc | Bin 9170 -> 10455 bytes src/db.py | 40 ++++++--- src/duckhuntbot.py | 27 ++++-- src/game.py | 87 +++++++++++++++---- src/levels.py | 15 +++- src/shop.py | 25 +++++- 18 files changed, 306 insertions(+), 189 deletions(-) delete mode 100644 .gitignore create mode 100644 __pycache__/duckhunt.cpython-312.pyc create mode 100644 src/__pycache__/levels.cpython-312.pyc create mode 100644 src/__pycache__/shop.cpython-312.pyc diff --git a/.gitignore b/.gitignore deleted file mode 100644 index eb83e99..0000000 --- a/.gitignore +++ /dev/null @@ -1,74 +0,0 @@ -# Python -__pycache__/ -*.py[cod] -*$py.class -*.so -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# Virtual Environment -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# IDE -.vscode/ -.idea/ -*.swp -*.swo -*~ - -# Logs -*.log -logs/ -duckhunt.log* - -# Database and Runtime Data -duckhunt.json -duckhunt.db -*.db -*.sqlite -*.sqlite3 - -# Configuration (sensitive) -config_local.json -config_backup.json - -# Backups -backup/ -*.backup -*.bak - -# OS -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db -Thumbs.db - -# Temporary files -*.tmp -*.temp -.cache/ \ No newline at end of file diff --git a/__pycache__/duckhunt.cpython-312.pyc b/__pycache__/duckhunt.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..222979153263bfc59fbfbc75e9d3d1e6f0c501a2 GIT binary patch literal 2077 zcmbVNO>7fK6rR~#+iS1w#Skc@KsSUI0>xDeffhlfU=o5*QQJtBVxg`a?>bpy@4B!JQpkf6Z_zb0^ zdQ1zR--{3tIiyGLtP)~W;VN8DX#8B{q?_cTkBqH2A%9)td@Dvy z*tb3}FA&ew$O5vJ&o*l>n#4{kclixIS6fbCpJ9^I1omrZ#@XcKK5lt5$xrb44&UCE z`4`%{uW13F8@$`*Tl1a1)|SBeVteLme&*M(v||)(TPs30dL7xg%waT)F#N83c!3{A zW!#ON?LOOXMB?B_n<3O@7)BMr*|`SUy$;zrJy`#9K0Hok4d;PLVa@L1gm4XA|DVj7 zFezLVDv&KE%eahI&f60n?|LU=n2PSzK#A3WlCy~7-(yxS<5Jc#bH->gZ(F9zvhmyX zE6N(1VnRvfEZ5Y!9%B`C>J zlF8~hw@|3Ky8swz-ncfS42`*tW|d6^oYV<%OAa7MDvE3C#FYTX-0CO9B1e^;1m!H7 z3Z;xQMuYkV!**;MC=qxSYPA9@U~{Nom2{H|>|j)2bxxptA{s1MqoX>Zf??(?8p_xe zGiz9sC$32oXY|U5l_A<`-wT=;Fbeuv%NbxH@EoAw{tH>X^8D5#b@5GD3~!j0s!}aAdury?)zfux z=i@CX9G{OL`bq44@-h&3%+DTgMA02f2nTu_Vr)Ks@MrN*L)yNCxIl+z*jE?#H-KKO zinYYoQbX$S*J{#S-`v6Z_)B$BX(8C2&zb>v`>A~#j{Rw0G!;X4<6Bagzq`9H0h4<; zkcx!v1w%}ab@X%mz3#m*-j9iF+}wTgIDh|m0CXyJc&un?Zb5&Wz&8q-4dikJh9-|O{)^+WupB{HUPRI&iY%h=uZX`aUJ@_Mm*g6* zy)k=a=E&@^nPWG(+o4;b+wv{>J8?mI>-*k?O?`EA;!m_^DcFe*H;*DAIyL@)-}Z|j Pem>CTk {bold}*flap flap*{reset}" + "・゜゜・。。・゜゜\\_O< QUACK!", + "・゜゜・。。・゜゜\\_o< quack~", + "・゜゜・。。・゜゜\\_O> *flap flap*" ], - "duck_flies_away": "The {bold}duck{reset} flies away. ·°'`'°-.,¸¸.·°'`", - "fast_duck_flies_away": "The {cyan}fast duck{reset} quickly flies away! ·°'`'°-.,¸¸.·°'`", - "golden_duck_flies_away": "The {yellow}{bold}golden duck{reset} flies away majestically. ·°'`'°-.,¸¸.·°'`", - "bang_hit": "{nick} > {green}*BANG*{reset} You shot the duck! [{green}+{xp_gained} xp{reset}] [Total ducks: {bold}{ducks_shot}{reset}]", - "bang_hit_golden": "{nick} > {green}*BANG*{reset} You shot a {yellow}{bold}GOLDEN DUCK{reset}! [{yellow}{hp_remaining} HP remaining{reset}] [{green}+{xp_gained} xp{reset}]", - "bang_hit_golden_killed": "{nick} > {green}*BANG*{reset} You killed the {yellow}{bold}GOLDEN DUCK{reset}! [{green}+{xp_gained} xp{reset}] [Total ducks: {bold}{ducks_shot}{reset}]", - "bang_hit_fast": "{nick} > {green}*BANG*{reset} You shot a {cyan}{bold}FAST DUCK{reset}! [{green}+{xp_gained} xp{reset}] [Total ducks: {bold}{ducks_shot}{reset}]", - "bang_miss": "{nick} > {red}*BANG*{reset} You missed the {cyan}duck{reset}!", - "bang_no_duck": "{nick} > {red}*BANG*{reset} What did you shoot at? There is {red}no duck{reset} in the area... [{red}GUN CONFISCATED{reset}]", - "bang_no_ammo": "{nick} > {orange}*click*{reset} You're out of ammo! Use {blue}!reload{reset}", - "bang_gun_jammed": "{nick} > {red}*click*{reset} Your gun jammed! [{red}AMMO WASTED{reset}]", - "bang_not_armed": "{nick} > You are {red}not armed{reset}.", - "bef_success": "{nick} > {orange}*befriend*{reset} You befriended the duck! [{green}+{xp_gained} xp{reset}] [Ducks befriended: {bold}{ducks_befriended}{reset}]", - "bef_failed": "{nick} > {pink}*gentle approach*{reset} The {cyan}duck{reset} doesn't trust you and {yellow}flies away{reset}...", - "bef_no_duck": "{nick} > {pink}*gentle approach*{reset} There is {red}no duck{reset} to befriend in the area...", - "bef_duck_shot": "{nick} > {pink}*gentle approach*{reset} The {cyan}duck{reset} is {red}already dead{reset}! You can't befriend it now...", - "reload_success": "{nick} > {orange}*click*{reset} New magazine loaded! [Ammo: {green}{ammo}{reset}/{green}{max_ammo}{reset}] [Spare magazines: {blue}{chargers}{reset}]", - "reload_already_loaded": "{nick} > Your gun is {green}already loaded{reset}!", - "reload_no_chargers": "{nick} > You're out of {red}spare magazines{reset}!", - "reload_not_armed": "{nick} > You are {red}not armed{reset}.", - "shop_display": "DuckHunt Shop: {items} | You have {green}{xp} XP{reset}", - "shop_item_format": "({blue}{id}{reset}) {cyan}{name}{reset} - {green}{price} XP{reset}", - "help_header": "{blue}DuckHunt Commands:{reset}", - "help_user_commands": "{blue}!bang{reset} - Shoot at ducks | {blue}!bef{reset} - Befriend ducks | {blue}!reload{reset} - Reload your gun | {blue}!shop{reset} - View/buy from shop | {blue}!duckstats{reset} - View your stats and items | {blue}!use{reset} - Use inventory items", - "help_help_command": "{blue}!duckhelp{reset} - Show this help", - "help_admin_commands": "{red}Admin:{reset} {blue}!rearm {reset} | {blue}!disarm {reset} | {blue}!ignore {reset} | {blue}!unignore {reset} | {blue}!ducklaunch{reset}", - "admin_rearm_player": "[{red}ADMIN{reset}] {cyan}{target}{reset} has been rearmed by {blue}{admin}{reset}", - "admin_rearm_all": "[{red}ADMIN{reset}] All players have been rearmed by {blue}{admin}{reset}", - "admin_rearm_self": "[{red}ADMIN{reset}] {blue}{admin}{reset} has rearmed themselves", - "admin_disarm": "[{red}ADMIN{reset}] {cyan}{target}{reset} has been disarmed by {blue}{admin}{reset}", - "admin_ignore": "[{red}ADMIN{reset}] {cyan}{target}{reset} is now ignored by {blue}{admin}{reset}", - "admin_unignore": "[{red}ADMIN{reset}] {cyan}{target}{reset} is no longer ignored by {blue}{admin}{reset}", - "admin_ducklaunch": "[{red}ADMIN{reset}] A {cyan}duck{reset} has been launched by {blue}{admin}{reset}", - "admin_ducklaunch_not_enabled": "[{red}ADMIN{reset}] This channel is {red}not enabled{reset} for duckhunt", - "usage_rearm": "Usage: {blue}!rearm {reset}", - "usage_disarm": "Usage: {blue}!disarm {reset}", - "usage_ignore": "Usage: {blue}!ignore {reset}", - "usage_unignore": "Usage: {blue}!unignore {reset}", - "shop_buy_success": "{nick} > You bought {cyan}{item_name}{reset}! [-{red}{price} XP{reset}] [Remaining: {green}{remaining_xp} XP{reset}]", - "shop_buy_insufficient_xp": "{nick} > You don't have enough {red}XP{reset} to buy {cyan}{item_name}{reset}. Need {red}{price} XP{reset}, you have {green}{current_xp} XP{reset}.", - "shop_buy_invalid_id": "{nick} > {red}Invalid item ID{reset}. Use {blue}!shop{reset} to see available items.", - "shop_buy_usage": "Usage: {blue}!shop buy {reset}", + "duck_flies_away": "The duck flies away. ·°'`'°-.,¸¸.·°'`", + "fast_duck_flies_away": "The fast duck quickly flies away! ·°'`'°-.,¸¸.·°'`", + "golden_duck_flies_away": "The golden duck flies away majestically. ·°'`'°-.,¸¸.·°'`", + "bang_hit": "{nick} > *BANG* You shot the duck! [+{xp_gained} xp] [Total ducks: {ducks_shot}]", + "bang_hit_golden": "{nick} > *BANG* You shot a GOLDEN DUCK! [{hp_remaining} HP remaining] [+{xp_gained} xp]", + "bang_hit_golden_killed": "{nick} > *BANG* You killed the GOLDEN DUCK! [+{xp_gained} xp] [Total ducks: {ducks_shot}]", + "bang_hit_fast": "{nick} > *BANG* You shot a FAST DUCK! [+{xp_gained} xp] [Total ducks: {ducks_shot}]", + "bang_miss": "{nick} > *BANG* You missed the duck!", + "bang_no_duck": "{nick} > *BANG* What did you shoot at? There is no duck in the area... [GUN CONFISCATED]", + "bang_no_ammo": "{nick} > *click* You're out of ammo! Use !reload", + "bang_gun_jammed": "{nick} > *click* Your gun jammed! [AMMO WASTED]", + "bang_not_armed": "{nick} > You are not armed.", + "bef_success": "{nick} > *befriend* You befriended the duck! [+{xp_gained} xp] [Ducks befriended: {ducks_befriended}]", + "bef_failed": "{nick} > *gentle approach* The duck doesn't trust you and flies away...", + "bef_no_duck": "{nick} > *gentle approach* There is no duck to befriend in the area...", + "bef_duck_shot": "{nick} > *gentle approach* The duck is already dead! You can't befriend it now...", + "reload_success": "{nick} > *click* New magazine loaded! [Ammo: {ammo}/{max_ammo}] [Spare magazines: {chargers}]", + "reload_already_loaded": "{nick} > Your gun is already loaded!", + "reload_no_chargers": "{nick} > You're out of spare magazines!", + "reload_not_armed": "{nick} > You are not armed.", + "shop_display": "DuckHunt Shop: {items} | You have {xp} XP", + "shop_item_format": "({id}) {name} - {price} XP", + "help_header": "DuckHunt Commands:", + "help_user_commands": "!bang - Shoot at ducks | !bef - Befriend ducks | !reload - Reload your gun | !shop - View/buy from shop | !duckstats - View your stats and items | !use - Use inventory items", + "help_help_command": "!duckhelp - Show this help", + "help_admin_commands": "Admin: !rearm | !disarm | !ignore | !unignore | !ducklaunch", + "admin_rearm_player": "[ADMIN] {target} has been rearmed by {admin}", + "admin_rearm_all": "[ADMIN] All players have been rearmed by {admin}", + "admin_rearm_self": "[ADMIN] {admin} has rearmed themselves", + "admin_disarm": "[ADMIN] {target} has been disarmed by {admin}", + "admin_ignore": "[ADMIN] {target} is now ignored by {admin}", + "admin_unignore": "[ADMIN] {target} is no longer ignored by {admin}", + "admin_ducklaunch": "[ADMIN] A duck has been launched by {admin}", + "admin_ducklaunch_not_enabled": "[ADMIN] This channel is not enabled for duckhunt", + "usage_rearm": "Usage: !rearm ", + "usage_disarm": "Usage: !disarm ", + "usage_ignore": "Usage: !ignore ", + "usage_unignore": "Usage: !unignore ", + "shop_buy_success": "{nick} > You bought {item_name}! [-{price} XP] [Remaining: {remaining_xp} XP]", + "shop_buy_insufficient_xp": "{nick} > You don't have enough XP to buy {item_name}. Need {price} XP, you have {current_xp} XP.", + "shop_buy_invalid_id": "{nick} > Invalid item ID. Use !shop to see available items.", + "shop_buy_usage": "Usage: !shop buy ", + "use_attract_ducks": "{nick} > You scattered bread around the pond! Ducks will spawn {spawn_multiplier}x faster for {duration} minutes.", "colours": { "white": "\u00030", diff --git a/shop.json b/shop.json index 75facc3..9cc4319 100644 --- a/shop.json +++ b/shop.json @@ -28,6 +28,14 @@ "description": "Clean your gun - decreases jam chance by 10%", "type": "clean_gun", "amount": -10 + }, + "5": { + "name": "Bread", + "price": 50, + "description": "Attract ducks - increases duck spawn rate for 20 minutes", + "type": "attract_ducks", + "duration": 1200, + "spawn_multiplier": 2.0 } } } \ No newline at end of file diff --git a/src/__pycache__/db.cpython-312.pyc b/src/__pycache__/db.cpython-312.pyc index 6dd9be32a57bcf130d09aa6a390d7f657f1a1d14..1f8efe806882a37e2943ff24610ec9821b3e82bc 100644 GIT binary patch literal 12404 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 b1WEse$oUJA^%uhML_0!}IS&a;B`N<4n38d+ literal 5113 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 Q8%~*FJWt^J9b+l|5BgGYCjbBd diff --git a/src/__pycache__/duckhuntbot.cpython-312.pyc b/src/__pycache__/duckhuntbot.cpython-312.pyc index b7c3112df7923d8c11b522b8c7ca76ce28bfc36c..b9f6ff8624fb55dd488f982b8eebedcffddfd645 100644 GIT binary patch literal 44517 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 K9!DiqNQ44!6%r6Eqv`%J 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 K#mGN$ga1GL+_-fB diff --git a/src/__pycache__/game.cpython-312.pyc b/src/__pycache__/game.cpython-312.pyc index bc0d23797a20b2262ccebea1e7522b46547918e1..6b864107223cdaf42da7ac0f71cd5095ef5bf029 100644 GIT binary patch literal 18387 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 delta 3118 zcmZ`*X>e256~6avdV1P7OY$PgvN4v8jqwsMm>6oarA;8LO_QJqKiO8WWq1(g zg}AZd%(O5#h4e>5C+(1y%rxzvEF_c8Rx z==j`w?pf~n&OP_dP0@GuT0gK@6oR8X|KY&;np4(4(v7EXY!b$li0N_ft(vqY7?!xQpD{zv?GMUhZ4 zSuT*Y4L&gh;dk|J{~ZGpVn)>J(_+CKAx}EtChsz@*qM+rryGi3qin4CA0|I&C6oK` zXQ&`){W#3blSM%7CDaGMlwDw7<$|dSv-1%$CXJ9${t+@lf5DH?hzy_0`(dwfmD8$8 zsFhRtQ43q1{g5ib-O;lQQbA?-BWTIj%>h?+TRh zB9DCUovffALYUiU@ptR595~EBt$O@dggnM!w)qL6pJ3ty%ziu0r3}qTD(}a=;|fd# z*T6B4Svk~0NQzEIG9sL+_pl5)5rp*u$%v@8N7oY|?{h~*on5l?^r9_G#9d3 z1?+Tq3_5OF5RNzkP9D+AnN#tk8XbzKQnCIx{M+b-4;*R2yqL+>bY@FB z-$=hX`kT@Du3g!#U9-Dmv%T@TuD-dFzJ=1-`O?O0Y2$0nS4-RSB5LMkQr@scc+W

r z_#*SZhODpQHSbkld)|*R<^%9&SEK1>9hTq6_Nv=|Z-54OefQ=j`kcR~i@Zd8I)xu^ zszUZ1aZ^41yVA@i@0QpYt#vZmRlm7`f3J>1rT5lS#y9Yro8V=)m%B~jx9)>hl}qC_ zE)47jHv^@oJ7kzHGEpAtivq0Fq;upYVMQiqs4C6y6C6C@FN4Nzw~1SB3X}k~c;R$+ zHI@O^8Lv+#1(yvgn7>M@dDq2J9_gEM!Twfzx_Xm%QdX;Fk7+&Ht3^QR{ zO-O{#aS2sxz(uVNNlwvs>BTi}@4>nX>3m!bC6b|tSz`r};}glW*35K5jFdBSA0w12q6lsT z4NzI(g7aYsETNLHaTzVuIF6k+!>bazq^g1(Wn2b!-oFm61YPiA$mjb%+cWUA&jXKj zG`L)eCRg_q1$*Iq zh0s@AnvEG_Mm~g1MO$?@9;?m68YNE)2?Q#jdP0)gkh!1+JP9E0+Xn9Z0d@z>mk0yts><;_|mvB6? zagjZiId1fD;cld&se$2iPLB2V9@S#KV~d+myr{B0vaUanNJn^W8(T1r9**|M63Mu# z?Z!FQ{{w89$1U2|k<-4x$XYL3H0sJjiBu|LDcl|z9QFLa&x z)|_cIJlyQ(7JQIwZh@0)GzixDXaw5op66cYFTYt=Lpkkl@Uhzq7sAqIWo?qu<#+Dk za9OccwW_SG$%wL9N7;@jI}l~~liSC1pkrP5UKNW~rK(fqbtoNhZe6YE+2vO<;)3kD z8c9F-cA$;L#}`?$`|(G}Te~)DJMq89-s(m6DW&Z~lCv|+Q_+L*J}rR{BO+F)2@|eF zQ%8Gy@u9o}tHu(ivCJ$3s@$Wtf@_YgM*CukL3><{*!0f1{0d)c4DWl4xh-ZNQbWUP zqAw9wSG-3x#I?{{4=`U*M)ZyvV;t)`+M`G!rZ0i4^}?E_M*9l9S|8im56Px3>DS1n z7T|KzIr<^&XnqC!Eyw7CaHb_};mG@(W2={czld)2UVgvj0!p(;JXyTKX05?n#8yKO)BIk`O3CQ$yNh#97~ ze9gX^i3S)MW8`~~-x4^!4%z3(AB1g7f+UtN*=4b1$?X<5EUgKMol6_3M{HfH-%3U6 z(k`x3wBE|lT2av)%m8cB5lMT2@%mR#h;jOp#lFmSxi-l-eLHKSx8+U*;^<)fe(eW1 pr34?vR3&nGo>F>~+EG02bb62)xic)r| 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 literal 0 HcmV?d00001 diff --git a/src/__pycache__/shop.cpython-312.pyc b/src/__pycache__/shop.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a2baf3eaf86528021f8853a545e082cfdd6123f GIT binary patch literal 14952 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 literal 0 HcmV?d00001 diff --git a/src/__pycache__/utils.cpython-312.pyc b/src/__pycache__/utils.cpython-312.pyc index 73f5132859822d048d99f3382b5b4557d18b0356..ff7e9d9ee3974ca38e34560ae434b72768eb30d9 100644 GIT binary patch delta 1782 zcmZ`&U2Icj82(OA&uP2$|8Hy8veQ5I1C9-60ziujN~7DGbqna4qK3~CX~Y@RXhM_QrF5EknpLoh2x1ju%A-KP;kIYMks)A1 zFhfRAMhT(%oXKMekToW*RfAaYvlL4^(KO;5H9VoinXf2Ws;2Q2Xw48A6j#-9s_bwf z=VZYL)piZOzFO&4{ihOT6p*=VGXr#IGgO-5V6$omG#kfKNx`t$IZ9JCku3F25TR;j zRc4&1Hbe5(G{Kv<3{C^WXtvIY77$y1?M0I?E+S2)mFenyd`M7M?>G+DkGMJlG;j33 z(a$LQ==~%*M~`rBxHQ8uve^V6WlYa5Cz&dcuK!tE_fQ`?@p@FGg9*BH%5s`i&=YMllLw%FrLs zM>o$TQPb0ANc9{JaeSB=I?~TfhIu{|2{U6;++;{#l2KutIWskx;KJkKI3Jx3GhvRK z;+XMJoQ*{t@kq)xa4r!(BZOIo7r1CVvXhBS2~6%=k1LyMADLpNL$N4}IVPcmfl}Za zi=KlU-i7aIoQXx_;U0#ILYpbFqoX6$G*G=F0iuBKU$RZz z#|=UycMuyM%!*QYFA-j$cws*mO>i;nqWDBCDsUm36XDfRGx12Yeg<#RM?CGAfXI+uI6(&nJpqpT#8`)-mrWc|{u7jSchD)gcTm`ImV4@R6mq zr6&2V6)Fp0ea(ujZd~J9eW~lKlV6aG$es>+V0 zOEhM1t*_aU*7h7xRNxo2y=-cHV)8yRd2jAnHtmFAtM#+`3wqhnT|8Fum39|Li-$_n zcSCoN$_+!0)d$N4lekwpo%hNH|Bq__dbUyzM1S$K@C45H4%pFmL>sm{TKe~)duAH& zJ%=r5Liaip7=l&bOgqF5@VAl=q4XHt9}=OvAgPLItMJ| zq7nNS%>>345)&=jHG^Jqv3bv+n|#8$LJjac;~PZ0#cgQhx=( dksm1d3VbnGvfLRe@pAitNB;gb9N1`HJQOcW@SzQF8~ak)$0u5 zrf8Wp`te|3JRVB`na2(oG`hm{1zu)%=~JO+B)37^P=#sZfN>Yw3}zsQ8QB#gK;2o- zwzyLk0L+{jkl789*l@`4mO51eZ4OhI#T=%K>?4qJzq+&{L8Qd;tJzphK}aeovEnAI zNi8FtxSUThuu6nS9BNc6Ehv#X#lzQ5i*G=sSa~^elXj(Ash37vLxL?day{Ry)ug&i z2nk9xgm{7*_pe4fTcr3%0(~Wy3XZ)KYR;bUt4p@a^QP17=;)^_YG*&Cy=O_Eiy*tbA3hKgdA*w0*{M)j%sxJN!BBt^sZ8bmN&>riv`pw?c!5T5; z@$0wDoV7IcWQJ@8`ib8U$pW=yJV-{UzOj)MlathSGkXF^vKELl^iA9k?B(~-Fn#Yw LBKyx7jQ{-yx~{0y diff --git a/src/db.py b/src/db.py index d97eb9a..47daebd 100644 --- a/src/db.py +++ b/src/db.py @@ -12,8 +12,9 @@ import os class DuckDB: """Simplified database management""" - def __init__(self, db_file="duckhunt.json"): + def __init__(self, db_file="duckhunt.json", bot=None): self.db_file = db_file + self.bot = bot self.players = {} self.logger = logging.getLogger('DuckHuntBot.DB') self.load_database() @@ -67,7 +68,9 @@ class DuckDB: sanitized['xp'] = max(0, int(player_data.get('xp', 0))) # Non-negative XP sanitized['ducks_shot'] = max(0, int(player_data.get('ducks_shot', 0))) sanitized['ducks_befriended'] = max(0, int(player_data.get('ducks_befriended', 0))) - sanitized['accuracy'] = max(0, min(100, int(player_data.get('accuracy', 65)))) # 0-100 range + default_accuracy = self.bot.get_config('default_accuracy', 75) if self.bot else 75 + max_accuracy = self.bot.get_config('max_accuracy', 100) if self.bot else 100 + sanitized['accuracy'] = max(0, min(max_accuracy, int(player_data.get('accuracy', default_accuracy)))) # 0-max_accuracy range sanitized['gun_confiscated'] = bool(player_data.get('gun_confiscated', False)) # Ammo system with validation @@ -209,23 +212,38 @@ class DuckDB: return self.create_player(nick) def create_player(self, nick): - """Create a new player with basic stats and validation""" + """Create a new player with configurable starting stats and inventory""" try: # Sanitize nick safe_nick = str(nick)[:50] if nick else 'Unknown' + # Get configurable defaults from bot config + if self.bot: + accuracy = self.bot.get_config('player_defaults.accuracy', 75) + magazines = self.bot.get_config('player_defaults.magazines', 3) + bullets_per_mag = self.bot.get_config('player_defaults.bullets_per_magazine', 6) + jam_chance = self.bot.get_config('player_defaults.jam_chance', 5) + xp = self.bot.get_config('player_defaults.xp', 0) + else: + # Fallback defaults if no bot config available + accuracy = 75 + magazines = 3 + bullets_per_mag = 6 + jam_chance = 5 + xp = 0 + return { 'nick': safe_nick, - 'xp': 0, + 'xp': xp, 'ducks_shot': 0, 'ducks_befriended': 0, - 'current_ammo': 6, # Bullets in current magazine - 'magazines': 3, # Total magazines (including current) - 'bullets_per_magazine': 6, # Bullets per magazine - 'accuracy': 65, - 'jam_chance': 5, # 5% base gun jamming chance + 'current_ammo': bullets_per_mag, # Bullets in current magazine + 'magazines': magazines, # Total magazines (including current) + 'bullets_per_magazine': bullets_per_mag, # Bullets per magazine + 'accuracy': accuracy, # Starting accuracy from config + 'jam_chance': jam_chance, # Base gun jamming chance from config 'gun_confiscated': False, - 'inventory': {}, # {item_id: quantity} + 'inventory': {}, # Empty starting inventory 'temporary_effects': [] # List of temporary effects } except Exception as e: @@ -238,7 +256,7 @@ class DuckDB: 'current_ammo': 6, 'magazines': 3, 'bullets_per_magazine': 6, - 'accuracy': 65, + 'accuracy': 75, 'jam_chance': 5, 'gun_confiscated': False, 'inventory': {}, diff --git a/src/duckhuntbot.py b/src/duckhuntbot.py index 6aa1bf1..4dca482 100644 --- a/src/duckhuntbot.py +++ b/src/duckhuntbot.py @@ -26,7 +26,7 @@ class DuckHuntBot: self.channels_joined = set() self.shutdown_requested = False - self.db = DuckDB() + self.db = DuckDB(bot=self) self.game = DuckGame(self, self.db) self.messages = MessageManager() @@ -97,8 +97,8 @@ class DuckHuntBot: async def connect(self): """Connect to IRC server with comprehensive error handling""" - max_retries = 3 - retry_delay = 5 + max_retries = self.get_config('connection.max_retries', 3) or 3 + retry_delay = self.get_config('connection.retry_delay', 5) or 5 for attempt in range(max_retries): try: @@ -117,7 +117,7 @@ class DuckHuntBot: self.config['port'], ssl=ssl_context ), - timeout=30.0 # 30 second connection timeout + timeout=self.get_config('connection.timeout', 30) or 30.0 # Connection timeout from config ) self.logger.info(f"✅ Successfully connected to {self.config['server']}:{self.config['port']}") @@ -454,7 +454,7 @@ class DuckHuntBot: xp = player.get('xp', 0) ducks_shot = player.get('ducks_shot', 0) ducks_befriended = player.get('ducks_befriended', 0) - accuracy = player.get('accuracy', 65) + accuracy = player.get('accuracy', self.get_config('player_defaults.accuracy', 75)) # Ammo info current_ammo = player.get('current_ammo', 0) @@ -531,13 +531,24 @@ class DuckHuntBot: if not result["success"]: message = f"{nick} > {result['message']}" else: - if result.get("target_affected"): + # Handle specific item effect messages + effect = result.get('effect', {}) + effect_type = effect.get('type', '') + + if effect_type == 'attract_ducks': + # Use specific message for bread + message = self.messages.get('use_attract_ducks', + nick=nick, + spawn_multiplier=effect.get('spawn_multiplier', 2.0), + duration=effect.get('duration', 10) + ) + elif result.get("target_affected"): message = f"{nick} > Used {result['item_name']} on {target_nick}!" else: message = f"{nick} > Used {result['item_name']}!" - # Add remaining count if any - if result.get("remaining_in_inventory", 0) > 0: + # Add remaining count if any (not for bread message which has its own format) + if effect_type != 'attract_ducks' and result.get("remaining_in_inventory", 0) > 0: message += f" ({result['remaining_in_inventory']} remaining)" self.send_message(channel, message) diff --git a/src/game.py b/src/game.py index 3e94ea3..06c3f5f 100644 --- a/src/game.py +++ b/src/game.py @@ -35,8 +35,16 @@ class DuckGame: try: while True: # Wait random time between spawns, but in small chunks for responsiveness - min_wait = self.bot.get_config('duck_spawn_min', 300) # 5 minutes - max_wait = self.bot.get_config('duck_spawn_max', 900) # 15 minutes + min_wait = self.bot.get_config('duck_spawning.spawn_min', 300) # 5 minutes + max_wait = self.bot.get_config('duck_spawning.spawn_max', 900) # 15 minutes + + # Check for active bread effects to modify spawn timing + spawn_multiplier = self._get_active_spawn_multiplier() + if spawn_multiplier > 1.0: + # Reduce wait time when bread is active + min_wait = int(min_wait / spawn_multiplier) + max_wait = int(max_wait / spawn_multiplier) + wait_time = random.randint(min_wait, max_wait) # Sleep in 1-second intervals to allow for quick cancellation @@ -65,12 +73,9 @@ class DuckGame: for channel, ducks in self.ducks.items(): ducks_to_remove = [] for duck in ducks: - # Different timeouts for different duck types + # Get timeout for each duck type from config duck_type = duck.get('duck_type', 'normal') - if duck_type == 'fast': - timeout = self.bot.get_config('fast_duck_timeout', 30) - else: - timeout = self.bot.get_config('duck_timeout', 60) + timeout = self.bot.get_config(f'duck_types.{duck_type}.timeout', 60) if current_time - duck['spawn_time'] > timeout: ducks_to_remove.append(duck) @@ -94,6 +99,9 @@ class DuckGame: for channel in channels_to_clear: if channel in self.ducks and not self.ducks[channel]: del self.ducks[channel] + + # Clean expired effects every loop iteration + self._clean_expired_effects() except asyncio.CancelledError: self.logger.info("Duck timeout loop cancelled") @@ -175,8 +183,8 @@ class DuckGame: 'message_args': {'nick': nick} } - # Check for gun jamming - jam_chance = player.get('jam_chance', 5) / 100.0 # Convert percentage to decimal + # Check for gun jamming using level-based jam chance + jam_chance = self.bot.levels.get_jam_chance(player) / 100.0 # Convert percentage to decimal if random.random() < jam_chance: # Gun jammed! Use ammo but don't shoot player['current_ammo'] = player.get('current_ammo', 1) - 1 @@ -216,7 +224,9 @@ class DuckGame: if duck['current_hp'] > 0: # Still alive, reveal it's golden but don't remove - player['accuracy'] = min(player.get('accuracy', 65) + 1, 100) + accuracy_gain = self.bot.get_config('accuracy_gain_on_hit', 1) + max_accuracy = self.bot.get_config('max_accuracy', 100) + player['accuracy'] = min(player.get('accuracy', self.bot.get_config('default_accuracy', 75)) + accuracy_gain, max_accuracy) self.db.save_database() return { 'success': True, @@ -241,14 +251,16 @@ class DuckGame: else: # Normal duck self.ducks[channel].pop(0) - xp_gained = 10 + xp_gained = self.bot.get_config('normal_duck_xp', 10) message_key = 'bang_hit' # Apply XP and level changes old_level = self.bot.levels.calculate_player_level(player) player['xp'] = player.get('xp', 0) + xp_gained player['ducks_shot'] = player.get('ducks_shot', 0) + 1 - player['accuracy'] = min(player.get('accuracy', 65) + 1, 100) + accuracy_gain = self.bot.get_config('accuracy_gain_on_hit', 1) + max_accuracy = self.bot.get_config('max_accuracy', 100) + player['accuracy'] = min(player.get('accuracy', self.bot.get_config('default_accuracy', 75)) + accuracy_gain, max_accuracy) # Check if player leveled up and update magazines if needed new_level = self.bot.levels.calculate_player_level(player) @@ -272,7 +284,9 @@ class DuckGame: } else: # Miss! Duck stays in the channel - player['accuracy'] = max(player.get('accuracy', 65) - 2, 10) + accuracy_loss = self.bot.get_config('accuracy_loss_on_miss', 2) + min_accuracy = self.bot.get_config('min_accuracy', 10) + player['accuracy'] = max(player.get('accuracy', self.bot.get_config('default_accuracy', 75)) - accuracy_loss, min_accuracy) self.db.save_database() return { 'success': True, @@ -309,8 +323,8 @@ class DuckGame: # Success - befriend the duck duck = self.ducks[channel].pop(0) - # Lower XP gain than shooting (5 instead of 10) - xp_gained = 5 + # Lower XP gain than shooting + xp_gained = self.bot.get_config('befriend_duck_xp', 5) old_level = self.bot.levels.calculate_player_level(player) player['xp'] = player.get('xp', 0) + xp_gained player['ducks_befriended'] = player.get('ducks_befriended', 0) + 1 @@ -407,4 +421,45 @@ class DuckGame: if rearmed_count > 0: self.logger.info(f"Auto-rearmed {rearmed_count} disarmed players after duck shot") except Exception as e: - self.logger.error(f"Error in _rearm_all_disarmed_players: {e}") \ No newline at end of file + self.logger.error(f"Error in _rearm_all_disarmed_players: {e}") + + def _get_active_spawn_multiplier(self): + """Get the current spawn rate multiplier from active bread effects""" + import time + max_multiplier = 1.0 + current_time = time.time() + + try: + for player_name, player_data in self.db.players.items(): + effects = player_data.get('temporary_effects', []) + for effect in effects: + if (effect.get('type') == 'attract_ducks' and + effect.get('expires_at', 0) > current_time): + multiplier = effect.get('spawn_multiplier', 1.0) + max_multiplier = max(max_multiplier, multiplier) + + return max_multiplier + except Exception as e: + self.logger.error(f"Error getting spawn multiplier: {e}") + return 1.0 + + def _clean_expired_effects(self): + """Remove expired temporary effects from all players""" + import time + current_time = time.time() + + try: + for player_name, player_data in self.db.players.items(): + effects = player_data.get('temporary_effects', []) + active_effects = [] + + for effect in effects: + if effect.get('expires_at', 0) > current_time: + active_effects.append(effect) + + if len(active_effects) != len(effects): + player_data['temporary_effects'] = active_effects + self.logger.debug(f"Cleaned expired effects for {player_name}") + + except Exception as e: + self.logger.error(f"Error cleaning expired effects: {e}") \ No newline at end of file diff --git a/src/levels.py b/src/levels.py index d1c1432..ed55b97 100644 --- a/src/levels.py +++ b/src/levels.py @@ -141,7 +141,7 @@ class LevelManager: def get_modified_accuracy(self, player: Dict[str, Any]) -> int: """Get player's accuracy modified by their level""" - base_accuracy = player.get('accuracy', 65) + base_accuracy = player.get('accuracy', 75) # This will be updated by bot config in create_player level_info = self.get_player_level_info(player) modifier = level_info.get('accuracy_modifier', 0) @@ -154,9 +154,20 @@ class LevelManager: level_info = self.get_player_level_info(player) level_rate = level_info.get('befriend_success_rate', base_rate) - # Return as percentage (0-100) + # Return as percentage (0-100) - these will be configurable later if bot reference is available return max(5.0, min(95.0, level_rate)) + def get_jam_chance(self, player: Dict[str, Any]) -> float: + """Get player's gun jam chance based on their level""" + level_info = self.get_player_level_info(player) + level_data = self.get_level_data(level_info['level']) + + if level_data and 'jam_chance' in level_data: + return level_data['jam_chance'] + + # Fallback to old system if no level-specific jam chance + return player.get('jam_chance', 5) + def get_duck_spawn_modifier(self, player_levels: list) -> float: """Get duck spawn speed modifier based on highest level player in channel""" if not player_levels: diff --git a/src/shop.py b/src/shop.py index a6163c5..f5e7626 100644 --- a/src/shop.py +++ b/src/shop.py @@ -178,7 +178,7 @@ class ShopManager: elif item_type == 'accuracy': # Increase accuracy up to 100% - current_accuracy = player.get('accuracy', 65) + current_accuracy = player.get('accuracy', 75) new_accuracy = min(current_accuracy + amount, 100) player['accuracy'] = new_accuracy return { @@ -279,7 +279,7 @@ class ShopManager: elif item_type == 'sabotage_accuracy': # Reduce target's accuracy temporarily - current_acc = player.get('accuracy', 65) + current_acc = player.get('accuracy', 75) new_acc = max(current_acc + amount, 10) # Min 10% accuracy (amount is negative) player['accuracy'] = new_acc @@ -325,6 +325,27 @@ class ShopManager: "new_total": new_jam } + elif item_type == 'attract_ducks': + # Add bread effect to increase duck spawn rate + if 'temporary_effects' not in player: + player['temporary_effects'] = [] + + duration = item.get('duration', 600) # 10 minutes default + spawn_multiplier = item.get('spawn_multiplier', 2.0) # 2x spawn rate default + + effect = { + 'type': 'attract_ducks', + 'spawn_multiplier': spawn_multiplier, + 'expires_at': time.time() + duration + } + player['temporary_effects'].append(effect) + + return { + "type": "attract_ducks", + "spawn_multiplier": spawn_multiplier, + "duration": duration // 60 # return duration in minutes + } + else: self.logger.warning(f"Unknown item type: {item_type}") return {"type": "unknown", "message": f"Unknown effect type: {item_type}"}