223 Commits

Author SHA1 Message Date
8d184d1160 update xmake.lua
All checks were successful
Linux arm64 / Build (push) Successful in 3m7s
2025-08-29 10:37:54 +02:00
7ddf47a81a Update README.md
All checks were successful
Linux arm64 / Build (push) Successful in 1m18s
2025-03-23 11:47:36 +00:00
7a1db0305d fix build
All checks were successful
Linux arm64 / Build (push) Successful in 1m27s
2025-03-19 19:04:38 +01:00
700a2b0c18 add readme
Some checks failed
Linux arm64 / Build (push) Failing after 1m31s
2025-03-19 18:52:56 +01:00
398439886b Update .gitea/workflows/linux.yaml
All checks were successful
Linux arm64 / Build (push) Successful in 13m32s
2024-05-27 22:33:24 +02:00
7c4ed3910f action: xmake latest
All checks were successful
Linux arm64 / Build (push) Successful in 1m4s
2024-02-24 13:06:56 +01:00
90c834cc49 Squashed commit of the following:
All checks were successful
Linux arm64 / Build (push) Successful in 6m2s
commit a8cbebc8d11d3621924b189a58a4f150d30324e9
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sat Feb 10 14:00:26 2024 +0100

    jsp

commit a00ae1f6d9db33efef5e276bfc7101a1d24cf7d8
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sat Feb 10 13:17:03 2024 +0100

    lol

commit d3dcaf3659251bb8fb0d4984ea188601a058757b
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sat Feb 10 13:02:12 2024 +0100

    zsdf

commit 8ce343ff361ba0618d09d488404ff15c7d19de66
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sat Feb 10 12:55:39 2024 +0100

    caca

commit 9f2a818ee57c751cb1283f12cfcc2c3617a3bd63
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sat Feb 10 12:38:20 2024 +0100

    remove run name

commit b618dc176980ef18ae9a04f43a8abef311ca4329
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sat Feb 10 12:20:35 2024 +0100

    change action name

commit 3092a403fdb2ded81d6f7558f621d0f8ac5dc1f5
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sat Feb 10 12:06:03 2024 +0100

    fix action typo

commit 0cd675ef6c42758bef182307cce55d74aa2959fe
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sat Feb 10 11:56:16 2024 +0100

    add action cache name

    Signed-off-by: Simon Pribylski <sim16.prib@gmail.com>

commit 4a6e6754f0a82a35fa4d6793321c7d27cb3e9f37
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sat Feb 10 11:28:48 2024 +0100

    remove ssl ignore

    Signed-off-by: Simon Pribylski <sim16.prib@gmail.com>

commit 1808ca96ec84390915ace0678bc824d92cc3d1b3
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:29:10 2024 +0100

    change action name

commit 5a966bbe77463a93ab210cd4b6a122ab1d440486
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:22:16 2024 +0100

    cpp standard global

commit 673d1457162dda9018712d0a19ac5b3954ad265f
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:21:36 2024 +0100

    add glew dep

commit b64eb6dd3ef535183dd0620beeeaa99deb323c97
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:16:23 2024 +0100

    confirm

commit 1bf8065179b74f3dd194e05739a064097bdc2ebd
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:15:37 2024 +0100

    remove sudo

commit 2dc4ee69ebba3821916963a96621d6f8b59d4808
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:09:55 2024 +0100

    install apt

commit 69574b9c5a5074c2fdf87dfc8c068d9c64f7704c
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 10:31:11 2024 +0100

    add xmake cache

commit 4d7d04c6722ca8e94d10569f25ae582265866948
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 01:21:45 2024 +0100

    aaaaaaaaaaaaaaaaaa

commit aa7dac26cd9900c676e4662fadb7832700a3363a
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 01:13:08 2024 +0100

    fiiiiiiiiiiiiiix xmake root

commit 3604b44d04f492254911a0508e8555aca61b4d26
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 01:05:43 2024 +0100

    fix xmake root

commit cfcb8d4df46c6febeca47dff2f0447048b8f68ad
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 01:03:56 2024 +0100

    run xmake as root

commit dbef2d27138ccce1124cc1979867baf15e897a7f
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 00:54:54 2024 +0100

    xmake action

commit 42196398ced1e7f38c0234d82dc7cd65ef7aeb6d
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 00:53:29 2024 +0100

    xmake

commit 51256d8c15066120c2df3a72063856a0a47f8b59
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 00:47:35 2024 +0100

    Fix Linux.yaml

    add cert

commit 9c024fa8eb92765aff3fb195ce7c8c10a1b49d0b
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sun Dec 31 22:34:54 2023 +0100

    Add Linux actions
2024-02-10 16:02:51 +01:00
d23761dc10 Squashed commit of the following:
Some checks failed
Linux arm / Build (push) Has been cancelled
commit 1808ca96ec84390915ace0678bc824d92cc3d1b3
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:29:10 2024 +0100

    change action name

commit 5a966bbe77463a93ab210cd4b6a122ab1d440486
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:22:16 2024 +0100

    cpp standard global

commit 673d1457162dda9018712d0a19ac5b3954ad265f
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:21:36 2024 +0100

    add glew dep

commit b64eb6dd3ef535183dd0620beeeaa99deb323c97
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:16:23 2024 +0100

    confirm

commit 1bf8065179b74f3dd194e05739a064097bdc2ebd
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:15:37 2024 +0100

    remove sudo

commit 2dc4ee69ebba3821916963a96621d6f8b59d4808
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 13:09:55 2024 +0100

    install apt

commit 69574b9c5a5074c2fdf87dfc8c068d9c64f7704c
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 10:31:11 2024 +0100

    add xmake cache

commit 4d7d04c6722ca8e94d10569f25ae582265866948
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 01:21:45 2024 +0100

    aaaaaaaaaaaaaaaaaa

commit aa7dac26cd9900c676e4662fadb7832700a3363a
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 01:13:08 2024 +0100

    fiiiiiiiiiiiiiix xmake root

commit 3604b44d04f492254911a0508e8555aca61b4d26
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 01:05:43 2024 +0100

    fix xmake root

commit cfcb8d4df46c6febeca47dff2f0447048b8f68ad
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 01:03:56 2024 +0100

    run xmake as root

commit dbef2d27138ccce1124cc1979867baf15e897a7f
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 00:54:54 2024 +0100

    xmake action

commit 42196398ced1e7f38c0234d82dc7cd65ef7aeb6d
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 00:53:29 2024 +0100

    xmake

commit 51256d8c15066120c2df3a72063856a0a47f8b59
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Mon Jan 1 00:47:35 2024 +0100

    Fix Linux.yaml

    add cert

commit 9c024fa8eb92765aff3fb195ce7c8c10a1b49d0b
Author: Simon Pribylski <sim16.prib@gmail.com>
Date:   Sun Dec 31 22:34:54 2023 +0100

    Add Linux actions
2024-02-10 15:49:25 +01:00
3d8fd2e519 refactor xmake.lua 2023-09-03 11:02:22 +02:00
4bd32e8d0b chore: bump version to alpha-0.4.0 2023-09-02 20:29:51 +02:00
09bba12814 prevent player from joining mid game 2023-09-02 20:27:26 +02:00
bb76e9493f sync player when joining mid game 2023-08-26 11:49:52 +02:00
Simon Pribylski
808ef7b3f6 moved player leave packet 2023-08-26 11:27:05 +02:00
Simon Pribylski
23938a0cb5 fix mob id 2023-08-26 11:21:28 +02:00
Simon Pribylski
5631efcf9e remove mobs on player leave 2023-08-26 10:46:20 +02:00
Simon Pribylski
8e7b446003 add RemoveMobPacket 2023-08-26 10:35:26 +02:00
Simon Pribylski
51ec035490 remove towers on player leave 2023-08-26 10:25:52 +02:00
1f94ae2586 use of SAFE_CHECK 2023-08-15 19:33:09 +02:00
7b8c13612c fix login crash 2023-08-15 19:32:44 +02:00
a36716d8e4 fix player login 2023-08-15 19:20:13 +02:00
debf9e974c useless cam functions 2023-08-15 19:19:54 +02:00
380ecf3a27 fixed server world upload 2023-08-15 13:47:56 +02:00
b3157be641 change lib name 2023-08-15 13:06:31 +02:00
1e3b672897 remove player from team when leaving 2023-08-15 13:01:50 +02:00
d1aa5cd8aa balance team on player join 2023-08-14 18:54:36 +02:00
dbe91b52fd send team update after restart 2023-08-14 18:41:51 +02:00
7ab8c79fdf changed player join/leave message 2023-08-14 18:34:07 +02:00
8f2a22762a fixing button crash 2023-08-14 18:33:41 +02:00
f0c3325141 name randomizer 2023-08-14 18:33:24 +02:00
1d00e0098a fix player sync 2023-08-14 18:18:43 +02:00
ee5a27ac54 show integrated server stats 2023-08-14 18:10:05 +02:00
49a5a09537 add restart command 2023-08-14 17:46:49 +02:00
f9f80fc4fb summon debug 2023-08-14 15:00:05 +02:00
4997715672 players stat reset after game end 2023-08-14 14:59:37 +02:00
3fe480d121 connection removal safety 2023-08-14 14:59:15 +02:00
c46226c1ae disconnect queue 2023-08-14 14:58:26 +02:00
8630421734 set summon menu cooldown 2023-08-14 14:29:41 +02:00
60b81003c0 Don't disconnect when game is over 2023-08-14 14:25:10 +02:00
7986e55846 fix persistent players 2023-08-14 13:59:30 +02:00
0c0fd155ed add client disconnect button 2023-08-14 13:46:10 +02:00
7f650f282c back to lobby state when server ends 2023-08-14 13:35:17 +02:00
118a04cd01 xmake.lua : add lib target 2023-08-14 13:31:52 +02:00
d529c79150 server console input 2023-08-13 13:44:05 +02:00
ddbba997e5 Working server 2023-08-13 12:38:32 +02:00
50c17e8ed1 restructure project 2023-08-13 11:59:13 +02:00
b4836847f5 fix WorldBeginDataPacket 2023-08-12 11:00:30 +02:00
f941862637 Packets Refactor
commit 497a601c424e8e728ef0a8e61f049982f2d4af16
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Sat Aug 12 10:32:52 2023 +0200

    fix warning

commit 1bfd019a1ea00dcdb6323d1f285e2cdd3ebb4020
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Jul 25 19:05:13 2023 +0200

    refactor: update cast

commit 5bbc23a7d37e53eb74a885685f18e714f9448fd9
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Jul 25 19:04:15 2023 +0200

    moved GetImguiTeamColor

commit fd0e2d2470ea5cca3553acf280aa371de5c06f4c
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Jul 25 19:03:37 2023 +0200

    packets forward declaration

commit 06eb9b99a96731f4b9a2167c00ed0bcd03702e3b
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Jul 25 18:30:55 2023 +0200

    remove Protocol.h includes

commit 165f63d2e8b468f3e38992baddc221270010f801
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Jul 25 18:30:30 2023 +0200

    split packets into separate source files

commit f247f146c6c1e804a44b86f65cf3059859c07c6c
Author: Persson-dev <sim16.prib@gmail.com>
Date:   Tue Jul 25 17:45:24 2023 +0200

    split packets into separate headers
2023-08-12 10:41:39 +02:00
36f37b6548 Revert "Merge branch 'discord'"
This reverts commit e7b9a57723, reversing
changes made to 02b4aa3c91.

Revert "moved rapidjson files"

This reverts commit f5012f770c.
2023-06-21 23:36:20 +02:00
1dde1dbf1e fix vertex cache 2023-06-20 16:27:41 +02:00
f5012f770c moved rapidjson files 2023-06-08 12:30:05 +02:00
e7b9a57723 Merge branch 'discord' 2023-06-08 12:21:54 +02:00
02b4aa3c91 xmake add_files 2023-06-08 12:16:50 +02:00
f184982bc1 change release optimization 2023-06-07 12:39:58 +02:00
1cdc738839 refactor: rename zoom function 2023-06-07 12:36:31 +02:00
368bc450ce better cam controls 2023-06-07 12:33:10 +02:00
148b5f397a more vect operators 2023-06-07 12:32:24 +02:00
f62322752d use of td pi 2023-06-06 17:59:48 +02:00
fb9e125f16 refactor: format 2023-06-06 17:58:27 +02:00
b70e8f7790 approximative cam movement 2023-06-06 17:56:19 +02:00
39bdd0a11e remove useless pi digits 2023-06-06 17:17:00 +02:00
c95c8b7fde clamp camera + pi 2023-06-06 17:15:44 +02:00
e984ed9085 fixed cam distance 2023-06-06 17:04:17 +02:00
92035d7b9e remove useless variable 2023-06-06 13:09:02 +02:00
48841fa4e9 camera fixing 2023-06-06 13:07:42 +02:00
83ab8c70f0 cache transpose 2023-06-06 12:45:34 +02:00
ccdcdac7c6 working mouse picking 2023-06-06 12:36:05 +02:00
a2b5424888 fix inverse assert 2023-06-05 18:06:02 +02:00
a4fb56b549 camera yaw and pitch 2023-06-05 13:50:45 +02:00
22e62df04d remove unused variables 2023-06-05 13:17:04 +02:00
faf544f997 basic camera movement 2023-06-05 13:15:27 +02:00
b72f4a7673 fix inverted zoom 2023-06-05 13:12:43 +02:00
19c03010cb remove useless computation 2023-06-05 13:07:56 +02:00
41f8c152eb really bad controls 2023-06-04 13:02:41 +02:00
051c9d8744 fix format error 2023-06-04 12:42:58 +02:00
193e4db651 fix mouse picking 2023-06-03 20:43:40 +02:00
cb5f5a4cf8 fixing transpose 2023-06-03 19:46:37 +02:00
bc7e5914ce invert assert 2023-06-03 19:44:05 +02:00
0365902971 moved Mat4 definition 2023-06-03 19:40:50 +02:00
f2fcc348d7 more maths 2023-06-03 18:22:01 +02:00
95c92ec6c9 rename lookat function 2023-06-03 17:54:59 +02:00
721f15b601 fix tower rendering 2023-06-03 17:49:00 +02:00
3970103b01 kinda 3d 2023-06-03 17:41:46 +02:00
4e866c1032 shaders to 3d 2023-06-03 16:35:17 +02:00
ca268781fd shader better logging 2023-06-03 16:30:32 +02:00
a2d8984199 shader matrix support 2023-06-03 16:30:23 +02:00
e7f9ca2b6c fix maths warning 2023-06-03 16:23:56 +02:00
deb0075aac add maths utils 2023-06-02 17:54:58 +02:00
28b8659e16 fix linux compiling 2023-06-02 16:26:17 +02:00
0b9fc0520e fix compiling mingw 2023-06-02 16:19:42 +02:00
c54017c7be update presence 2023-06-02 13:34:01 +02:00
bbfe341d23 base discord rpc 2023-06-02 13:18:09 +02:00
14efe2cc39 simplified health bar display 2023-01-02 16:58:31 +01:00
fcda12e321 add hit "animation" 2023-01-02 16:37:18 +01:00
1200a6e087 moved TowerUpgradePopop into its own file 2023-01-02 15:56:20 +01:00
512fb23d0e add server mspt (+procotol format) 2023-01-02 15:07:34 +01:00
5a547b6514 move towers implementations 2023-01-02 14:47:02 +01:00
ed45995645 add mob send cooldown 2023-01-02 14:32:37 +01:00
0b6d826eba remove unused glm package 2023-01-02 13:55:54 +01:00
6d0c6be166 server side safe checks 2023-01-02 13:18:49 +01:00
222b79b40a indent with tabs 2023-01-02 13:05:43 +01:00
8f95b1a750 remove format warning 2023-01-02 12:27:08 +01:00
7d30017742 moved Color to Defines.h 2023-01-02 12:21:27 +01:00
386ea5b6ad forward declare Updater 2023-01-02 12:05:20 +01:00
8949c37891 chore: bump version to alpha-0.3.0 2023-01-01 19:42:49 +01:00
019174128c fix: COMPRESSION 2023-01-01 19:40:23 +01:00
4e8b095e31 xmake.lua show wine console output 2022-12-11 13:04:00 +01:00
0e0368cada add wine xmake.lua 2022-12-11 12:59:57 +01:00
Simon Pribylski
6e0923ac75 remove glm dependency 2022-10-13 12:24:15 +02:00
Simon Pribylski
bba9ef8219 Add glm dependency 2022-09-07 18:54:10 +02:00
fd2288ac3c refactor xmake.lua 2022-09-03 16:55:36 +02:00
660952aed3 add example map 2022-07-18 12:12:53 +02:00
243b153309 remove unsed variable 2022-07-18 11:51:52 +02:00
73fa10d8d6 fixing log 2022-07-18 11:50:30 +02:00
0b8a7d8db7 hmmm 2022-07-14 18:42:46 +02:00
e2ec9d6a3b add player getter 2022-07-14 18:40:52 +02:00
eb5b3c8ce2 explicit cast zlib functions 2022-07-14 18:39:28 +02:00
ddbba7399d use of loge 2022-07-14 18:39:06 +02:00
9ce1f4a1a8 add loge 2022-07-14 18:35:11 +02:00
ea4349af4c fix log android 2022-07-14 18:34:26 +02:00
d6fbb58da8 using log calls 2022-07-14 18:32:32 +02:00
66376eaeda allow custom opengl loader 2022-07-14 18:04:13 +02:00
85eb9bbc32 add exp sync 2022-07-14 13:09:38 +02:00
bbb84c0061 add log 2022-07-14 13:08:20 +02:00
2f1161959b remove unused includes 2022-07-14 13:07:41 +02:00
f506307653 refactor databuffer write 2022-07-04 11:17:30 +02:00
40f0d50991 util format function 2022-07-04 11:13:26 +02:00
663ad60ee3 util player methods 2022-07-04 11:13:11 +02:00
3fbb6acac7 fix initial stats 2022-07-04 10:42:31 +02:00
377e98f583 fix warnings 2022-07-04 10:24:18 +02:00
ef9712629f remove use of loops in protocol 2022-06-29 12:42:21 +02:00
ed481de03e add databuffer helper functions 2022-06-29 12:35:36 +02:00
7d667d9c5e add buy packets 2022-06-29 12:13:58 +02:00
16006adc6e fix more warnings 2022-06-27 13:33:24 +02:00
19062b5c77 fix warnings 2022-06-27 13:12:39 +02:00
d3c6ff3988 fix MobSend size 2022-06-27 13:12:20 +02:00
31a0027bfc add namespace comments 2022-06-27 12:29:22 +02:00
d4b1805998 refactor: forgot this one 2022-04-27 19:46:41 +02:00
b84f1fd302 fix: remove useless warning flag 2022-04-27 19:46:09 +02:00
98f73f467d fix: change ChunkCoords hashing 2022-04-27 19:44:16 +02:00
dc8a4ce947 refactor: alpha sort methods 2022-04-27 19:41:03 +02:00
113a831f39 refactor: removed unused semicolon 2022-04-27 19:35:45 +02:00
f906aa1bf0 refactor: more casts 2022-04-27 19:34:45 +02:00
1bbf607b22 refactor: show override 2022-04-27 19:34:12 +02:00
d5b42caf39 refactor: cpp style casts 2022-04-27 19:25:36 +02:00
d3edc0cb6c refactor: spaces instead of tabs 2022-04-27 18:44:22 +02:00
87e4e65843 refactor: remove useless namespace 2022-04-27 18:38:10 +02:00
7509cc1bf2 feat: add player upgrades 2022-04-27 18:37:07 +02:00
6df59b1487 GIGA REFACTOR 2022-03-02 18:51:42 +01:00
553b2f6aad feat: show demo window on debug only 2022-02-17 19:39:07 +01:00
916fa0e7c0 format 2022-02-17 19:35:09 +01:00
bc271bc01e protocol rework + map packet ids removal 2022-02-17 19:35:02 +01:00
97a33e5517 BIG REFACTOR Part 2 2022-02-16 18:34:49 +01:00
bdebabb79e BIG REFACTOR 2022-02-16 17:54:33 +01:00
387cff36ad style: more space 2022-02-16 16:32:05 +01:00
790237a1b5 refactor: changed to PlayerID type 2022-02-16 16:31:18 +01:00
840d5edbe4 refactor: changed exp and money update 2022-02-16 16:18:25 +01:00
36a9e1921c refactor: use of const reference 2022-01-07 18:30:37 +01:00
784c558840 chore: bump version to "alpha-0.2.0" 2021-12-19 18:40:44 +01:00
5d366b6f6c feat: sync game 2021-12-19 18:40:14 +01:00
f70661694b chore: bump version to "alpha-0.1.2" 2021-12-19 11:58:36 +01:00
36a1ab0572 feat: close server when game finished 2021-12-19 11:57:47 +01:00
409268b604 refactor: use of GuiManager 2021-12-19 11:56:41 +01:00
174d144d26 refactor: add default server tps 2021-12-19 11:38:54 +01:00
360258e4cf feat: add end game disconnect 2021-12-13 20:05:20 +01:00
2148c0050c refactor: add game listener 2021-12-13 19:45:01 +01:00
61166023df feat: don't show tile select when tooltip 2021-12-12 16:59:57 +01:00
e7bf22cea6 feat: add pseudo end game 2021-12-12 16:59:35 +01:00
f09f79198d fix: windows build 2021-12-12 16:41:48 +01:00
8c19d3cc3c refactor: removed unused constant 2021-12-12 16:27:59 +01:00
208892d266 chore: update to alpha-0.1.1 2021-12-12 16:17:53 +01:00
4384806cf0 refactor: removed unused comment 2021-12-12 16:14:24 +01:00
1a091baeaf feat: add map background color 2021-12-12 16:13:05 +01:00
43f21ffd44 chore: bump verssion to alpha-0.1.0 2021-12-12 13:33:12 +01:00
24617c539f feat: add castle tooltip 2021-12-12 13:32:39 +01:00
4611a198c9 fix: add mob spawn border 2021-12-12 13:31:01 +01:00
d40ffe8f6c refactor: removed unused include 2021-12-12 11:36:56 +01:00
384b7ad51e chore: bump version to alpha-0.0.5 2021-12-11 20:07:26 +01:00
fd9b448fa4 feat: mob castle damage 2021-12-11 20:06:52 +01:00
c4a2b08416 feat: add mob spawn notification 2021-12-11 19:56:03 +01:00
a241d7691b refactor: mob die event 2021-12-11 19:51:45 +01:00
0af4cd506c refactor: moved mob functions 2021-12-11 19:30:31 +01:00
6b5c56b37d feat: notify when mob touches castle 2021-12-11 18:46:47 +01:00
1474220a77 refactor: separate mob ans world listener 2021-12-11 18:43:49 +01:00
a802b5cef5 fix: windows compilation 2021-12-08 17:24:29 +01:00
7e91b863da bump version to alpha-0.0.4 2021-12-08 15:39:26 +01:00
129bb47286 feat: debug library 2021-12-08 15:38:20 +01:00
e4a9c5f763 feat: remove tower 2021-12-08 15:34:20 +01:00
78cf2d0f18 Merge branch 'master' of 192.168.0.5:repos/Tower-Defense 2021-12-05 12:01:50 +01:00
00d2b5394f refactor: removed unused include 2021-12-05 12:01:17 +01:00
00414abe61 refactor: comment main 2021-12-04 19:09:26 +01:00
cb847d0edd refactor: removed unused declarations 2021-12-04 13:49:50 +01:00
2da0bd9b79 refactor: tower add event processing 2021-12-04 13:44:34 +01:00
cf9633c061 fix: mob spawning repartition 2021-12-03 18:47:55 +01:00
7a6fdc30b6 add fire arrow and fix world events 2021-12-03 18:30:45 +01:00
657fe761ab feat: bump version to alpha-0.0.3 2021-11-30 18:45:42 +01:00
687944bf51 fix: don't call onmobdamage with null damage 2021-11-30 18:45:09 +01:00
93e079ddb3 refactor: archer tower aoe damage 2021-11-30 18:38:40 +01:00
8171a91ed5 feat: add world notifier 2021-11-30 18:36:29 +01:00
0c1824e40b refactor: movd Updater 2021-11-30 18:07:25 +01:00
f91ab4bc83 fix: compilation error 2021-11-30 18:06:33 +01:00
1843fc6f4d feat: add archer tower aoe 2021-11-30 18:01:48 +01:00
6a51638b7e feat: add more shape distances 2021-11-30 18:01:07 +01:00
8351c5d09f refactor: add typo 2021-11-30 18:00:41 +01:00
ee94c811e1 feat: add archer tower damage 2021-11-30 18:00:19 +01:00
50a8269773 feat: add better mob pathing 2021-11-30 11:53:58 +01:00
2996c88d94 feat: add mob coords in tile coords space 2021-11-30 11:23:03 +01:00
55263fa582 fix: changed skel effect immunities 2021-11-29 16:39:29 +01:00
adeddee09d refactor: mob move lock (Castle) 2021-11-29 16:36:27 +01:00
f0115166c0 fix: compiler warning 2021-11-22 19:39:09 +01:00
c1affc36c0 chore: bump version to alpha-0.0.2 2021-11-22 19:36:14 +01:00
6c4ef25abd style: changed tower place popup size 2021-11-22 19:35:50 +01:00
fd0a5e5848 feat: mob stop in front of castle 2021-11-22 19:33:00 +01:00
7fb357e9c8 feat: add working shapes 2021-11-22 19:15:32 +01:00
1d7a8cc66b refactor: removed useless includePath 2021-11-22 18:00:55 +01:00
070749e685 feat: implement shapes for entities 2021-11-21 20:00:35 +01:00
a716e46c64 refactor(Team): moved include to source file 2021-11-21 19:44:20 +01:00
2e2aeb44b9 feat: add shapes 2021-11-21 18:51:54 +01:00
2df76248be chore: use c++17 2021-11-21 18:50:38 +01:00
36f1430ff2 refactor: changed cast type 2021-11-21 17:21:34 +01:00
2e14827f13 refactor: add mob size getter 2021-11-21 17:19:50 +01:00
c7d81de60e feat: add mob size 2021-11-21 17:18:45 +01:00
f48af51dc7 refactor: format project 2021-11-21 17:02:42 +01:00
0f328e6f81 fix: world tile pos calculation 2021-11-20 19:27:06 +01:00
310 changed files with 16414 additions and 8916 deletions

View File

@@ -0,0 +1,46 @@
name: Linux arm64
run-name: Build And Test
on: [push]
jobs:
Build:
runs-on: ubuntu-latest
steps:
- name: Install deps
run : |
apt update
apt install -y libsdl2-dev libglew-dev
- name: Check out repository code
uses: actions/checkout@v3
- name: Prepare XMake
uses: xmake-io/github-action-setup-xmake@v1
with:
xmake-version: latest
actions-cache-folder: '.xmake-cache'
actions-cache-key: 'xmake-ubuntu'
- name: Calc deps hash
uses: seepine/hash-files@v1
id: get-hash
with:
patterns: |
**/xmake.lua
**/xmake/*.lua
- name: Packages cache
uses: actions/cache@v4
with:
path: ~/.xmake
key: ${{ runner.os }}-${{ steps.get-hash.outputs.hash }}
- name: XMake config
run: xmake f -p linux -y --root
- name: Build
run: xmake --root
- name: Test
run: xmake test --root

18
README.md Normal file
View File

@@ -0,0 +1,18 @@
# TowerDefense
Unmaintained multiplayer tower defense game prototype
(OpenGL + TCP)
## Screenshots 🖼
[[screenshots/game.png]]
## Build ⚙️
```
xmake
```
## Run 🏃
```
xmake run
```

56
include/client/Client.h Normal file
View File

@@ -0,0 +1,56 @@
#pragma once
#include "client/ClientConnexion.h"
#include "client/game/ClientGame.h"
#include "td/game/Team.h"
#include "td/game/Player.h"
#include "td/protocol/Protocol.h"
#include "td/protocol/packets/SendMobsPacket.h"
#include "client/render/Renderer.h"
#include "td/network/Network.h"
namespace td {
namespace client {
class Client {
private:
render::Renderer* m_Renderer;
ClientConnexion m_Connexion;
std::unique_ptr<ClientGame> m_Game;
bool m_Connected;
public:
Client(render::Renderer* renderer) : m_Renderer(renderer), m_Game(std::make_unique<ClientGame>(this)), m_Connected(false) {}
const ClientGame& GetGame() const { return *m_Game; }
const ClientConnexion& GetConnexion() const { return m_Connexion; }
render::Renderer* GetRenderer() const { return m_Renderer; }
ClientGame& GetGame() { return *m_Game; }
ClientConnexion& GetConnexion() { return m_Connexion; }
const game::Player* GetPlayer() { return m_Game->GetPlayer(); }
void Tick(std::uint64_t delta);
void Render();
bool Connect(const network::IPAddresses& addresses, std::uint16_t port);
void CloseConnection();
bool IsConnected() const { return m_Connexion.GetSocketStatus() == network::Socket::Connected; }
void SelectTeam(game::TeamColor team);
void SendMobs(const std::vector<protocol::MobSend>& mobSends);
void PlaceTower(game::TowerType type, const Vec2f& position);
void UpgradeTower(game::TowerID tower, game::TowerLevel level);
void RemoveTower(game::TowerID tower);
private:
void Reset();
};
} // namespace client
} // namespace td

View File

@@ -0,0 +1,39 @@
#pragma once
#include "td/protocol/PacketHandler.h"
#include "td/network/TCPSocket.h"
#include "td/network/Connexion.h"
namespace td {
namespace client {
class ClientConnexion : public protocol::Connexion {
private:
std::uint8_t m_ConnectionID;
std::string m_DisconnectReason;
float m_ServerTPS;
float m_ServerMSPT;
int m_Ping = 0;
public:
ClientConnexion();
virtual bool UpdateSocket();
virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet) override;
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
virtual void HandlePacket(const protocol::ServerTpsPacket* packet) override;
const std::string& GetDisconnectReason() const { return m_DisconnectReason; }
float GetServerTPS() const { return m_ServerTPS; }
float GetServerMSPT() const { return m_ServerMSPT; }
int GetServerPing() const { return m_Ping; }
REMOVE_COPY(ClientConnexion);
private:
void RegisterHandlers();
void Login();
};
} // namespace client
} // namespace td

View File

@@ -0,0 +1,57 @@
#pragma once
#include "td/game/BaseGame.h"
#include "td/protocol/PacketHandler.h"
#include "WorldClient.h"
#include "client/render/WorldRenderer.h"
#include "client/render/Renderer.h"
namespace td {
namespace client {
class Client;
class ClientGame : public protocol::PacketHandler, public game::Game {
private:
Client* m_Client;
std::uint8_t m_ConnexionID;
std::uint32_t m_LobbyTime = 0;
game::Player* m_Player = nullptr;
render::Renderer* m_Renderer;
client::WorldClient m_WorldClient;
render::WorldRenderer m_WorldRenderer;
public:
ClientGame(Client* client);
virtual ~ClientGame();
virtual void Tick(std::uint64_t delta);
void RenderWorld();
std::uint32_t GetLobbyTime() const { return m_LobbyTime; }
const game::Player* GetPlayer() const { return m_Player; }
const WorldClient& GetWorld() const { return m_WorldClient; }
Client* GetClient() const { return m_Client; }
render::Renderer* GetRenderer() const { return m_Renderer; }
WorldClient& GetWorldClient() { return m_WorldClient; }
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerJoinPacket* packet) override;
virtual void HandlePacket(const protocol::PlayerLeavePacket* packet) override;
virtual void HandlePacket(const protocol::PlayerListPacket* packet) override;
virtual void HandlePacket(const protocol::UpdatePlayerTeamPacket* packet) override;
virtual void HandlePacket(const protocol::UpdateGameStatePacket* packet) override;
virtual void HandlePacket(const protocol::UpdateLobbyTimePacket* packet) override;
virtual void HandlePacket(const protocol::UpdateMoneyPacket* packet) override;
virtual void HandlePacket(const protocol::UpdateExpPacket* packet) override;
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
virtual void HandlePacket(const protocol::WorldDataPacket* packet) override;
};
} // namespace client
} // namespace td

View File

@@ -0,0 +1,31 @@
#pragma once
#include "td/game/World.h"
#include "td/protocol/PacketHandler.h"
namespace td {
namespace client {
class ClientGame;
class WorldClient : public game::World, public protocol::PacketHandler {
private:
ClientGame* m_Game;
public:
WorldClient(ClientGame* game);
virtual ~WorldClient();
virtual void HandlePacket(const protocol::WorldBeginDataPacket* packet) override;
virtual void HandlePacket(const protocol::WorldDataPacket* packet) override;
virtual void HandlePacket(const protocol::SpawnMobPacket* packet) override;
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet) override;
virtual void HandlePacket(const protocol::RemoveMobPacket* packet) override;
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet) override;
virtual void HandlePacket(const protocol::UpdateMobStatesPacket* packet) override;
virtual void HandlePacket(const protocol::UpdateCastleLifePacket* packet) override;
};
} // namespace client
} // namespace td

View File

@@ -0,0 +1,62 @@
#pragma once
#if !defined(TD_IMPL_OPENGL_ES2) \
&& !defined(TD_IMPL_OPENGL_ES3) \
&& !defined(TD_IMPL_OPENGL_LOADER_GL3W) \
&& !defined(TD_IMPL_OPENGL_LOADER_GLEW) \
&& !defined(TD_IMPL_OPENGL_LOADER_GLAD) \
&& !defined(TD_IMPL_OPENGL_LOADER_GLBINDING2) \
&& !defined(TD_IMPL_OPENGL_LOADER_GLBINDING3) \
&& !defined(TD_IMPL_OPENGL_LOADER_CUSTOM) \
&& !defined(__ANDROID__)
#if defined(__has_include)
#if __has_include(<GL/glew.h>)
#define TD_IMPL_OPENGL_LOADER_GLEW
#elif __has_include(<glad/glad.h>)
#define TD_IMPL_OPENGL_LOADER_GLAD
#elif __has_include(<GL/gl3w.h>)
#define TD_IMPL_OPENGL_LOADER_GL3W
#elif __has_include(<glbinding/glbinding.h>)
#define TD_IMPL_OPENGL_LOADER_GLBINDING3
#elif __has_include(<glbinding/Binding.h>)
#define TD_IMPL_OPENGL_LOADER_GLBINDING2
#else
#error "Cannot detect OpenGL loader!"
#endif
#else
#error "Cannot detect loader with include detection !"
#endif
#endif
// Include correct files
#if defined(__ANDROID__)
#include <GLES3/gl3.h>
#elif defined(TD_IMPL_OPENGL_LOADER_GL3W)
#include <GL/gl3w.h> // Needs to be initialized with gl3wInit() in user's code
#elif defined(TD_IMPL_OPENGL_LOADER_GLEW)
#include <GL/glew.h> // Needs to be initialized with glewInit() in user's code.
#elif defined(TD_IMPL_OPENGL_LOADER_GLAD)
#include <glad/glad.h> // Needs to be initialized with gladLoadGL() in user's code.
#elif defined(TD_IMPL_OPENGL_LOADER_GLBINDING2)
#ifndef GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
#endif
#include <glbinding/Binding.h> // Needs to be initialized with glbinding::Binding::initialize() in user's code.
#include <glbinding/gl/gl.h>
using namespace gl;
#elif defined(TD_IMPL_OPENGL_LOADER_GLBINDING3)
#ifndef GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
#endif
#include <glbinding/glbinding.h>// Needs to be initialized with glbinding::initialize() in user's code.
#include <glbinding/gl/gl.h>
using namespace gl;
#else
#include TD_IMPL_OPENGL_LOADER_CUSTOM
#endif

View File

@@ -0,0 +1,72 @@
#pragma once
#include "td/Defines.h"
#include <memory>
#include "loader/GLLoader.h"
#include "client/render/shaders/WorldShader.h"
#include "client/render/shaders/EntityShader.h"
namespace td {
namespace render {
struct Camera {
Mat4f viewMatrix;
Mat4f projectionMatrix;
Mat4f InvViewMatrix;
Mat4f InvProjectionMatrix;
float CamDistance = 25.0f;
Vec3f CamPos {0, CamDistance, 0};
Vec2f CamLook {};
float m_Yaw = -PI / 2.0f;
float m_Pitch = -PI / 2.0f + 0.0000001f;
};
class Renderer {
public:
static constexpr float m_AnimationSpeed = 2.0f;
static constexpr float m_MouseSensitivity = 200.0f;
struct Model {
GL::VertexArray* vao;
Vec3f positon;
Vec3f color = { 1, 1, 1 };
};
private:
std::unique_ptr<shader::WorldShader> m_WorldShader;
std::unique_ptr<shader::EntityShader> m_EntityShader;
Vec2i m_WindowSize;
Vec3f m_BackgroundColor;
Camera m_Camera {};
public:
Renderer();
~Renderer();
bool Init();
void Prepare();
void Resize(const int width, const int height);
void RenderVAO(const GL::VertexArray& vao);
void RenderModel(const Model& model);
void AddZoom(float zoom);
void SetCamAngularMovement(const Vec2f& mov);
void SetCamMovement(const Vec2f& lastCursorPos, const Vec2f& currentCursorPos);
void SetCamLook(const Vec2f& worldPos);
void ResetCamLook();
void SetBackgroundColor(const Vec3f& color) { m_BackgroundColor = color; }
Vec2f GetCursorWorldPos(const Vec2f& cursorPos, float windowWidth, float windowHeight);
private:
void InitShaders();
void SetCamPos(const Vec3f& newPos);
};
} // namespace render
} // namespace td

View File

@@ -0,0 +1,38 @@
#include <unordered_map>
#include <cstdint>
#include <memory>
#include "client/render/loader/GLLoader.h"
namespace td {
namespace render {
class VertexCache {
typedef std::vector<float> Vector;
struct DataIndex {
Vector position;
Vector color;
};
private:
std::size_t m_VertexCount;
std::unordered_map<std::uint64_t, DataIndex> m_Indexes;
std::unique_ptr<GL::VertexArray> m_VertexArray;
public:
VertexCache() : m_VertexCount(0) {}
void AddData(std::uint64_t index, std::vector<float> positions, std::vector<float> colors);
void RemoveData(std::uint64_t index);
void Clear();
void UpdateVertexArray();
const GL::VertexArray& GetVertexArray() const { return *m_VertexArray; }
bool IsEmpty() const { return m_VertexArray == nullptr; }
};
} // namespace render
} // namespace td

View File

@@ -0,0 +1,82 @@
#pragma once
#include "td/game/World.h"
#include "client/render/Renderer.h"
#include "client/render/VertexCache.h"
#include "client/render/gui/TowerPlacePopup.h"
#include "client/render/gui/TowerUpgradePopup.h"
#include "client/render/gui/MobTooltip.h"
#include "client/render/gui/CastleTooltip.h"
namespace td {
namespace client {
class ClientGame;
} // namespace client
namespace render {
class WorldRenderer : public game::WorldListener {
private:
client::ClientGame* m_Client;
Renderer* m_Renderer;
game::World* m_World;
std::unique_ptr<GL::VertexArray> m_WorldVao, m_MobVao, m_SelectTileVao;
Vec2f m_CamPos;
Vec2f m_CursorPos;
Vec2f m_HoldCursorPos;
Vec2f m_LastClicked;
float m_Zoom;
float m_CamSensibility = 1;
bool m_PopupOpened = false;
VertexCache m_TowersCache;
std::unique_ptr<gui::TowerPlacePopup> m_TowerPlacePopup;
std::unique_ptr<gui::TowerUpgradePopup> m_TowerUpgradePopup;
std::unique_ptr<gui::MobTooltip> m_MobTooltip;
std::unique_ptr<gui::CastleTooltip> m_CastleTooltip;
public:
WorldRenderer(game::World* world, client::ClientGame* client);
~WorldRenderer();
void LoadModels();
void Update();
void Render();
void ResetCam();
void SetCamPos(float camX, float camY);
void MoveCam(float relativeX, float relativeY);
void ChangeZoom(float zoom);
// WorldListener
virtual void OnTowerAdd(game::TowerPtr tower);
virtual void OnTowerRemove(game::TowerPtr tower);
private:
void Click();
void RenderWorld() const;
void RenderTowers() const;
void RenderMobs() const;
void RenderTileSelect() const;
void RenderPopups();
void RenderMobTooltip() const;
void RenderCastleTooltip() const;
void DetectClick();
void DetectMobHovering() const;
void DetectCastleHovering() const;
void RenderTooltips() const;
void RemoveTower();
Vec2f GetCursorWorldPos() const;
Vec2f GetClickWorldPos() const;
void UpdateCursorPos();
};
} // namespace render
} // namespace td

View File

@@ -0,0 +1,28 @@
#pragma once
#include "GuiWidget.h"
namespace td {
namespace game {
class TeamCastle;
} // namespace game
namespace gui {
class CastleTooltip : public GuiWidget {
private:
const game::TeamCastle* m_Castle;
public:
CastleTooltip(client::Client* client);
virtual void Render();
void SetCastle(const game::TeamCastle* castle) { m_Castle = castle; }
bool IsShown() { return m_Castle != nullptr; }
};
} // namespace gui
} // namespace td

View File

@@ -7,13 +7,13 @@ namespace gui {
class FrameMenu : public GuiWidget { class FrameMenu : public GuiWidget {
private: private:
bool m_VSync; bool m_VSync;
bool m_IsometricView; bool m_IsometricView;
bool m_ShowDemoWindow; bool m_ShowDemoWindow;
public: public:
FrameMenu(client::Client* client); FrameMenu(client::Client* client);
virtual void render(); virtual void Render();
}; };
} // namespace gui } // namespace gui

View File

@@ -0,0 +1,29 @@
#pragma once
#include "SummonMenu.h"
#include "td/game/BaseGame.h"
namespace td {
namespace gui {
class GameMenu : public GuiWidget, public game::GameListener {
private:
std::unique_ptr<SummonMenu> m_SummonMenu;
public:
GameMenu(client::Client* client);
virtual void OnGameBegin();
virtual void Render();
private:
void ShowTPS();
void ShowStats();
void ShowPlayers();
void ShowLobbyProgress();
void ShowTeamSelection();
void DisconnectButton();
};
} // namespace gui
} // namespace td

View File

@@ -0,0 +1,29 @@
#pragma once
#include "GuiWidget.h"
#include <vector>
#include <memory>
namespace td {
namespace gui {
class GuiManager {
private:
std::vector<std::unique_ptr<GuiWidget>> m_Widgets;
public:
GuiManager() {}
void RenderWidgets() {
for (auto& widget : m_Widgets) {
widget->Render();
}
}
void AddWidget(std::unique_ptr<GuiWidget>&& widget) {
m_Widgets.push_back(std::move(widget));
}
};
} // namespace gui
} // namespace td

View File

@@ -10,13 +10,13 @@ namespace gui {
class GuiWidget { class GuiWidget {
protected: protected:
client::Client* m_Client; client::Client* m_Client;
public: public:
GuiWidget(client::Client* client) : m_Client(client) {} GuiWidget(client::Client* client) : m_Client(client) {}
client::Client* getClient() { return m_Client; } client::Client* GetClient() { return m_Client; }
virtual void render() = 0; virtual void Render() = 0;
}; };
} // namespace gui } // namespace gui

View File

@@ -0,0 +1,13 @@
#pragma once
#include "client/render/gui/imgui/imgui.h"
#include "td/game/Team.h"
namespace td {
namespace render {
ImVec4 GetImGuiTeamColor(game::TeamColor color);
} // namespace render
} // namespace td

View File

@@ -0,0 +1,9 @@
#pragma once
namespace td {
namespace gui {
extern void RenderLifeProgress(float progress);
} // namespace gui
} // namespace td

View File

@@ -0,0 +1,40 @@
#pragma once
#include "GuiWidget.h"
#include "imgui/imgui_filebrowser.h"
#include "server/Server.h"
#include <memory>
namespace td {
namespace gui {
class ServerGui;
class MainMenu : public GuiWidget {
private:
bool m_TriedToConnect = false;
bool m_TriedToCreate = false;
std::string m_ConnectAddress;
int m_ConnectPort;
int m_ServerPort = 25565;
std::string m_WorldFilePath;
imgui_addons::ImGuiFileBrowser m_FileDialog;
std::unique_ptr<server::Server> m_Server;
std::unique_ptr<ServerGui> m_ServerGui;
public:
MainMenu(client::Client* client);
~MainMenu();
virtual void Render();
const server::Server* GetServer() const { return m_Server.get(); }
private:
bool StartServer();
};
} // namespace gui
} // namespace td

View File

@@ -7,20 +7,21 @@ namespace td {
namespace game { namespace game {
class Mob; class Mob;
} // namespace game } // namespace game
namespace gui { namespace gui {
class MobTooltip : public GuiWidget { class MobTooltip : public GuiWidget {
private: private:
const game::Mob* m_Mob; const game::Mob* m_Mob;
public: public:
MobTooltip(client::Client* client); MobTooltip(client::Client* client);
virtual void render(); virtual void Render();
void setMob(const game::Mob* mob) { m_Mob = mob; } void SetMob(const game::Mob* mob) { m_Mob = mob; }
bool IsShown() { return m_Mob != nullptr; }
}; };
} // namespace gui } // namespace gui

View File

@@ -0,0 +1,19 @@
#pragma once
#include "GuiWidget.h"
#include "server/Server.h"
namespace td {
namespace gui {
class ServerGui : public GuiWidget {
private:
server::Server* m_Server;
public:
ServerGui(client::Client* client, server::Server* server);
virtual void Render();
};
} // namespace gui
} // namespace td

View File

@@ -0,0 +1,30 @@
#pragma once
#include "GuiWidget.h"
#include <array>
#include "td/game/Mobs.h"
namespace td {
namespace gui {
class SummonMenu : public GuiWidget {
private:
bool m_MenuOpened;
int m_ImageWidth = 100;
float m_Cooldown;
float m_LastCooldown;
static constexpr int m_MobTypeCount = static_cast<std::size_t>(td::game::MobType::MOB_COUNT);
std::array<int, static_cast<std::size_t>(m_MobTypeCount)> m_Values;
public:
SummonMenu(client::Client* client);
void SetCooldown(float cooldown);
virtual void Render();
private:
void SetSummonMax(int valueIndex);
};
} // namespace gui
} // namespace td

View File

@@ -0,0 +1,49 @@
/*
* TowerGUI.h
*
* Created on: 5 nov. 2020
* Author: Persson-dev
*/
#pragma once
#include <memory>
#include "client/render/gui/GuiManager.h"
struct SDL_Window;
typedef void* SDL_GLContext;
namespace td {
namespace client {
class Client;
} // namespace client
namespace render {
class Renderer;
class TowerGui {
private:
SDL_Window* m_Window;
SDL_GLContext m_GlContext;
td::render::Renderer* m_Renderer;
td::gui::GuiManager m_GuiManager;
std::unique_ptr<td::client::Client> m_Client;
public:
TowerGui(SDL_Window* wndow, SDL_GLContext glContext, td::render::Renderer* renderer);
~TowerGui();
void Render();
private:
void InitWidgets();
void Tick();
void BeginFrame();
void EndFrame();
};
} // namespace render
} // namespace td

View File

@@ -0,0 +1,28 @@
#pragma once
#include "GuiWidget.h"
#include "td/Defines.h"
namespace td {
namespace gui {
class TowerPlacePopup : public GuiWidget {
private:
Vec2f m_ClickWorldPos;
public:
TowerPlacePopup(client::Client* client);
virtual void Render();
void SetClickPos(const Vec2f& worldPos);
private:
static constexpr float m_TowerPopupTileWidth = 200.0f;
static constexpr float m_TowerPopupTileHeight = 200.0f;
static constexpr float m_PlaceTowerButtonWidth = 150.0f;
static constexpr float m_PlaceTowerButtonHeight = 35.0f;
};
} // namespace gui
} // namespace td

View File

@@ -0,0 +1,32 @@
#pragma once
#include "GuiWidget.h"
#include "td/Defines.h"
namespace td {
namespace gui {
class TowerUpgradePopup : public GuiWidget {
private:
Vec2f m_ClickWorldPos;
bool m_ShouldBeClosed;
bool m_Opened;
public:
TowerUpgradePopup(client::Client* client);
virtual void Render();
void SetClickPos(const Vec2f& worldPos);
bool IsPopupOpened();
private:
static constexpr float m_TowerPopupTileWidth = 200.0f;
static constexpr float m_TowerPopupTileHeight = 200.0f;
static constexpr float m_PlaceTowerButtonWidth = 150.0f;
static constexpr float m_PlaceTowerButtonHeight = 35.0f;
};
} // namespace gui
} // namespace td

View File

@@ -0,0 +1,36 @@
#pragma once
#include "GuiWidget.h"
#include <future>
#include <memory>
namespace td {
namespace utils {
class Updater;
} // namespace utils
namespace gui {
class UpdateMenu : public GuiWidget {
private:
bool m_Opened;
std::string m_Error;
std::unique_ptr<utils::Updater> m_Updater;
std::shared_future<bool> m_UpdateAvailable;
public:
UpdateMenu(client::Client* client);
virtual ~UpdateMenu();
virtual void Render();
private:
void CheckUpdates();
bool IsUpdateChecked();
void RenderErrorPopup();
};
} // namespace gui
} // namespace td

View File

@@ -107,8 +107,20 @@ namespace ImGui
} }
*/ */
#ifdef __ANDROID__ #include "client/render/GL.h"
#define IMGUI_IMPL_OPENGL_ES3
#if defined(__ANDROID__)
#define IMGUI_IMPL_OPENGL_LOADER_ES3
#elif defined(TD_IMPL_OPENGL_LOADER_GL3W)
#define IMGUI_IMPL_OPENGL_LOADER_GL3W
#elif defined(TD_IMPL_OPENGL_LOADER_GLEW)
#define IMGUI_IMPL_OPENGL_LOADER_GLEW
#elif defined(TD_IMPL_OPENGL_LOADER_GLAD)
#define IMGUI_IMPL_OPENGL_LOADER_GLAD
#elif defined(TD_IMPL_OPENGL_LOADER_GLBINDING2)
#define IMGUI_IMPL_OPENGL_LOADER_GLBINDING2
#elif defined(TD_IMPL_OPENGL_LOADER_GLBINDING3)
#define IMGUI_IMPL_OPENGL_LOADER_GLBINDING3
#else #else
#define IMGUI_IMPL_OPENGL_LOADER_GLBINDING2 #define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
#endif #endif

View File

@@ -1,7 +1,7 @@
#ifndef IMGUIFILEBROWSER_H #ifndef IMGUIFILEBROWSER_H
#define IMGUIFILEBROWSER_H #define IMGUIFILEBROWSER_H
#include "render/gui/imgui/imgui.h" #include "client/render/gui/imgui/imgui.h"
#include <string> #include <string>
#include <vector> #include <vector>

View File

@@ -17,8 +17,9 @@
namespace GL { namespace GL {
struct VertexAttribPointer { struct VertexAttribPointer {
unsigned int m_Index, m_Size; unsigned int m_Index;
int m_Offset; unsigned int m_Size;
unsigned int m_Offset;
}; };
class VertexBuffer { class VertexBuffer {
@@ -27,6 +28,7 @@ private:
std::vector<VertexAttribPointer> m_VertexAttribs; std::vector<VertexAttribPointer> m_VertexAttribs;
public: public:
REMOVE_COPY(VertexBuffer); REMOVE_COPY(VertexBuffer);
VertexBuffer(VertexBuffer&& other) { VertexBuffer(VertexBuffer&& other) {
m_VertexAttribs = std::move(other.m_VertexAttribs); m_VertexAttribs = std::move(other.m_VertexAttribs);
m_ID = other.m_ID; m_ID = other.m_ID;
@@ -34,12 +36,14 @@ public:
other.m_ID = 0; other.m_ID = 0;
other.m_DataStride = 0; other.m_DataStride = 0;
} }
VertexBuffer(const std::vector<float>& data, unsigned int stride); VertexBuffer(const std::vector<float>& data, unsigned int stride);
~VertexBuffer(); ~VertexBuffer();
void bind() const;
void unbind() const; void Bind() const;
void addVertexAttribPointer(unsigned int index, unsigned int coordinateSize, unsigned int offset); void Unbind() const;
void bindVertexAttribs() const; void AddVertexAttribPointer(unsigned int index, unsigned int coordinateSize, unsigned int offset);
void BindVertexAttribs() const;
}; };
class VertexArray { class VertexArray {
@@ -48,6 +52,7 @@ private:
std::vector<VertexBuffer> m_VertexBuffers; //use to destroy vbos when become unused std::vector<VertexBuffer> m_VertexBuffers; //use to destroy vbos when become unused
public: public:
REMOVE_COPY(VertexArray); REMOVE_COPY(VertexArray);
VertexArray(VertexArray&& other) { VertexArray(VertexArray&& other) {
m_ID = other.m_ID; m_ID = other.m_ID;
m_VertexCount = other.m_VertexCount; m_VertexCount = other.m_VertexCount;
@@ -55,12 +60,14 @@ public:
other.m_VertexCount = 0; other.m_VertexCount = 0;
other.m_ID = 0; other.m_ID = 0;
} }
VertexArray(unsigned int vertexCount); VertexArray(unsigned int vertexCount);
~VertexArray(); ~VertexArray();
unsigned int getVertexCount() const { return m_VertexCount; }
void bindVertexBuffer(VertexBuffer& vbo); unsigned int GetVertexCount() const { return m_VertexCount; }
void bind() const; void BindVertexBuffer(VertexBuffer& vbo);
void unbind() const; void Bind() const;
void Unbind() const;
}; };
} }

View File

@@ -9,7 +9,9 @@
#define RENDER_LOADER_TEXTURELOADER_H_ #define RENDER_LOADER_TEXTURELOADER_H_
namespace TextureLoader { namespace TextureLoader {
const unsigned int loadGLTexture(const char* fileName);
unsigned int LoadGLTexture(const char* fileName);
} }

View File

@@ -0,0 +1,25 @@
#pragma once
#include "td/game/World.h"
#include "GLLoader.h"
namespace td {
namespace render {
namespace WorldLoader {
struct RenderData {
std::vector<float> positions;
std::vector<float> colors;
};
GL::VertexArray LoadMobModel();
GL::VertexArray LoadWorldModel(const td::game::World* world);
GL::VertexArray LoadTileSelectModel();
RenderData LoadTowerModel(game::TowerPtr tower);
} // namespace WorldLoader
} // namespace render
} // namespace td

View File

@@ -0,0 +1,28 @@
#pragma once
#include "ShaderProgram.h"
namespace td {
namespace shader {
class EntityShader : public ShaderProgram {
private:
unsigned int m_LocationProjectionMatrix = 0;
unsigned int m_LocationViewMatrix = 0;
unsigned int m_LocationPosition = 0;
unsigned int m_LocationColorEffect = 0;
protected:
virtual void GetAllUniformLocation();
public:
EntityShader();
void LoadShader();
void SetColorEffect(const Vec3f& color);
void SetProjectionMatrix(const Mat4f& proj) const;
void SetViewMatrix(const Mat4f& view) const;
void SetModelPos(const Vec3f& pos) const;
};
} // namespace shader
} // namespace td

View File

@@ -0,0 +1,43 @@
#pragma once
#include <string>
#include "td/Defines.h"
#include "client/render/GL.h"
namespace td {
namespace shader {
class ShaderProgram {
public:
ShaderProgram();
virtual ~ShaderProgram();
void Start() const;
void Stop() const;
void LoadProgramFile(const std::string& vertexFile, const std::string& fragmentFile);
void LoadProgram(const std::string& vertexSource, const std::string& fragmentSource);
protected:
virtual void GetAllUniformLocation() = 0;
int GetUniformLocation(const std::string& uniformName) const;
void LoadFloat(unsigned int location, float value) const;
void LoadInt(unsigned int location, int value) const;
void LoadVector(unsigned int location, const Vec2f& vector) const;
void LoadVector(unsigned int location, const Vec3f& vector) const;
void LoadBoolean(unsigned int location, bool value) const;
void LoadMat4(unsigned int location, const Mat4f& mat) const;
void CleanUp() const;
private:
unsigned int m_ProgramID;
unsigned int m_VertexShaderID;
unsigned int m_FragmentShaderID;
unsigned int LoadShaderFromFile(const std::string& file, GLenum type);
unsigned int LoadShader(const std::string& source, GLenum type);
};
} // namespace shader
} // namespace td

View File

@@ -0,0 +1,22 @@
#pragma once
#include "ShaderProgram.h"
namespace td {
namespace shader {
class WorldShader : public ShaderProgram {
private:
unsigned int m_LocationProjection = 0, m_LocationView = 0;
protected:
void GetAllUniformLocation();
public:
WorldShader();
void LoadShader();
void SetProjectionMatrix(const Mat4f& proj) const;
void SetViewMatrix(const Mat4f& view) const;
};
} // namespace shader
} // namespace td

View File

@@ -0,0 +1,44 @@
#pragma once
#include "td/misc/DataBuffer.h"
#define TD_VERSION "alpha-0.4.0"
namespace td {
namespace utils {
class Updater {
private:
float m_Progress;
bool m_DownloadComplete;
bool m_FileWrited;
bool m_CancelDownload;
DataBuffer m_FileBuffer;
std::string m_LastVersion;
public:
Updater() : m_Progress(0), m_DownloadComplete(false), m_FileWrited(false), m_CancelDownload(false) {}
bool CheckUpdate();
void DownloadUpdate();
void CancelDownload() { m_CancelDownload = true; m_Progress = 0.0f; m_DownloadComplete = false; }
bool WriteFile();
void ClearCache() { m_FileBuffer.Clear(); }
float GetDownloadProgress() { return m_Progress; }
bool IsDownloadComplete() { return m_DownloadComplete; }
bool IsFileWrited() { return m_FileWrited; }
static std::string GetLocalFilePath();
static void RemoveOldFile();
static std::string GetCurrentVersion() { return TD_VERSION; }
std::string GetLastVersion() { return m_LastVersion; }
bool CanUpdate();
private:
std::string GetDownloadFileURL();
};
} // namespace utils
} // namespace td

View File

@@ -0,0 +1,31 @@
/*
* Display.h
*
* Created on: 4 nov. 2020
* Author: simon
*/
#ifndef WINDOW_DISPLAY_H_
#define WINDOW_DISPLAY_H_
namespace Display {
bool Create();
void Render();
void Update();
void Destroy();
void PollEvents();
bool IsCloseRequested();
bool IsMouseDown(int button);
float GetAspectRatio();
int GetWindowWidth();
int GetWindowHeight();
}
#endif /* WINDOW_DISPLAY_H_ */

View File

@@ -1,55 +0,0 @@
#pragma once
#include "game/Team.h"
#include "game/World.h"
#include "game/Player.h"
namespace td {
namespace game {
enum class GameState : std::uint8_t {
Lobby,
Game,
EndGame,
Disconnected,
};
typedef std::map<std::uint8_t, Player> PlayerList;
class Game {
protected:
World* m_World;
std::array<Team, 2> m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} };
GameState m_GameState = GameState::Lobby;
PlayerList m_Players;
public:
Game(World* world);
virtual ~Game();
virtual void tick(std::uint64_t delta);
Team& getRedTeam() { return m_Teams[(std::uint8_t)TeamColor::Red]; }
const Team& getRedTeam() const { return m_Teams[(std::uint8_t)TeamColor::Red]; }
Team& getBlueTeam() { return m_Teams[(std::uint8_t)TeamColor::Blue]; }
const Team& getBlueTeam() const { return m_Teams[(std::uint8_t)TeamColor::Blue]; }
Team& getTeam(TeamColor team) { return m_Teams[(std::uint8_t)team]; }
const Team& getTeam(TeamColor team) const { return m_Teams[(std::uint8_t)team]; }
GameState getGameState() const { return m_GameState; }
void setGameState(GameState gameState) { m_GameState = gameState; };
const World* getWorld() const { return m_World; }
World* getWorld() { return m_World; }
const PlayerList& getPlayers() const { return m_Players; }
PlayerList& getPlayers() { return m_Players; }
const Player& getPlayerById(PlayerID id) const { return m_Players.find(id)->second; }
Player& getPlayerById(PlayerID id) { return m_Players.find(id)->second; }
};
} // namespace game
} // namespace td

View File

@@ -1,36 +0,0 @@
#pragma once
#include "network/TCPSocket.h"
#include "protocol/PacketHandler.h"
#include "protocol/PacketDispatcher.h"
#include "game/Player.h"
namespace td {
namespace protocol {
class Connexion : public protocol::PacketHandler {
protected:
protocol::PacketDispatcher m_Dispatcher;
private:
network::TCPSocket m_Socket;
public:
Connexion();
Connexion(Connexion&& move);
Connexion(protocol::PacketDispatcher* dispatcher);
Connexion(protocol::PacketDispatcher* dispatcher, network::TCPSocket& socket);
virtual ~Connexion();
virtual bool updateSocket();
void closeConnection();
bool connect(const std::string& address, std::uint16_t port);
network::Socket::Status getSocketStatus() const { return m_Socket.GetStatus(); }
void sendPacket(const protocol::Packet* packet);
REMOVE_COPY(Connexion);
};
} // namespace server
} // namespace td

View File

@@ -1,217 +0,0 @@
#pragma once
#include "Towers.h"
#include "Types.h"
#include <vector>
#include <memory>
namespace td {
namespace game {
enum class EffectType : std::uint8_t {
Slowness = 0,
Stun,
Fire,
Poison,
Heal,
};
enum class MobType : std::uint8_t {
Zombie = 0,
Spider,
Skeleton,
Pigman,
Creeper,
Silverfish,
Blaze,
Witch,
Slime,
Giant,
MOB_COUNT
};
typedef std::uint32_t MobID;
typedef std::uint8_t MobLevel;
typedef std::vector<TowerType> TowerImmunities;
typedef std::vector<EffectType> EffectImmunities;
class MobStats {
private:
float m_Damage;
float m_Speed;
std::uint16_t m_MoneyCost;
std::uint16_t m_ExpCost;
std::uint16_t m_MaxLife;
std::uint16_t m_ExpReward;
public:
MobStats(float damage, float speed, std::uint16_t moneyCost,
std::uint16_t expCost, std::uint16_t expReward,
std::uint16_t maxLife) : m_Damage(damage), m_Speed(speed),
m_MoneyCost(moneyCost), m_ExpCost(expCost), m_MaxLife(maxLife),
m_ExpReward(expReward) {
}
float getDamage() const { return m_Damage; }
float getMovementSpeed() const { return m_Speed; }
std::uint16_t getMoneyCost() const { return m_MoneyCost; }
std::uint16_t getExpCost() const { return m_ExpCost; }
std::uint16_t getExpReward() const { return m_ExpReward; }
std::uint16_t getMaxLife() const { return m_MaxLife; }
};
struct EffectDuration{
EffectType type;
float duration; // in seconds
const Tower* tower; // the tower that gived the effect
};
const MobStats* getMobStats(MobType type, std::uint8_t level);
const TowerImmunities& getMobTowerImmunities(MobType type, std::uint8_t level);
const EffectImmunities& getMobEffectImmunities(MobType type, std::uint8_t level);
class Mob {
protected:
float m_Health;
private:
MobID m_ID;
PlayerID m_Sender;
MobLevel m_Level;
Direction m_Direction;
std::vector<EffectDuration> m_Effects;
const Tower* m_LastDamage; // the tower that damaged the mob
utils::Timer m_EffectFireTimer;
utils::Timer m_EffectPoisonTimer;
utils::Timer m_EffectHealTimer;
float m_X = 0, m_Y = 0;
public:
Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level),
m_EffectFireTimer(1000), m_EffectPoisonTimer(1000), m_EffectHealTimer(1000) {
}
virtual MobType getType() const = 0;
virtual void tick(std::uint64_t delta);
virtual void OnDeath(World* world){}
const TowerImmunities& getTowerImmunities() const { return getMobTowerImmunities(getType(), m_Level); }
const EffectImmunities& getEffectImmunities() const { return getMobEffectImmunities(getType(), m_Level); }
PlayerID getSender() const { return m_Sender; }
MobLevel getLevel() const { return m_Level; }
const MobStats* getStats() const { return getMobStats(getType(), m_Level); }
float getHealth() const { return m_Health; }
bool isDead() const { return m_Health <= 0; }
bool isAlive() const { return m_Health > 0; }
const Tower* getLastDamageTower() { return m_LastDamage; }
void damage(float dmg, const Tower* damager) { m_Health = std::max(0.0f, m_Health - dmg); m_LastDamage = damager; }
void heal(float heal) { m_Health = std::min((float)getStats()->getMaxLife(), m_Health + heal); }
float getX() const { return m_X; }
void setX(float x) { m_X = x; }
float getY() const { return m_Y; }
void setY(float y) { m_Y = y; }
bool isImmuneTo(TowerType type);
bool isImmuneTo(EffectType type);
void addEffect(EffectType type, float durationSec, const Tower* tower);
bool hasEffect(EffectType type);
Direction getDirection() const { return m_Direction; }
void setDirection(Direction dir) { m_Direction = dir; }
protected:
void initHealth() { m_Health = (float)getStats()->getMaxLife(); }
private:
void updateEffects(std::uint64_t delta);
EffectDuration& getEffect(EffectType type);
};
typedef std::shared_ptr<Mob> MobPtr;
class Zombie : public Mob {
public:
Zombie(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); }
virtual MobType getType() const { return MobType::Zombie; }
};
class Spider : public Mob {
public:
Spider(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); }
virtual MobType getType() const { return MobType::Spider; }
};
class Skeleton : public Mob {
public:
Skeleton(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); }
virtual MobType getType() const { return MobType::Skeleton; }
};
class PigMan : public Mob {
public:
PigMan(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); }
virtual MobType getType() const { return MobType::Pigman; }
};
class Creeper : public Mob {
public:
Creeper(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); }
virtual MobType getType() const { return MobType::Creeper; }
};
class Silverfish : public Mob {
public:
Silverfish(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); }
virtual MobType getType() const { return MobType::Silverfish; }
};
class Blaze : public Mob {
public:
Blaze(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); }
virtual MobType getType() const { return MobType::Blaze; }
};
class Witch : public Mob {
public:
Witch(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); }
virtual MobType getType() const { return MobType::Witch; }
};
class Slime : public Mob {
public:
Slime(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); }
virtual MobType getType() const { return MobType::Slime; }
};
class Giant : public Mob {
public:
Giant(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { initHealth(); }
virtual MobType getType() const { return MobType::Giant; }
};
namespace MobFactory {
MobPtr createMob(MobID id, MobType type, std::uint8_t level, PlayerID sender);
std::string getMobName(MobType type);
}
} // namespace game
} // namespace td

View File

@@ -1,57 +0,0 @@
#pragma once
#include <cstdint>
#include <string>
#include "game/Team.h"
namespace td {
namespace game {
class Player {
private:
game::TeamColor m_TeamColor;
std::uint32_t m_Gold;
std::uint32_t m_Exp;
std::string m_Name;
std::uint8_t m_ID;
std::uint8_t m_GoldPerSecond;
bool m_GoldChanged;
bool m_ExpChanged;
public:
Player(std::uint8_t id = 0) : m_TeamColor(game::TeamColor::None), m_Gold(0), m_Exp(0), m_ID(id), m_GoldPerSecond(5),
m_GoldChanged(false), m_ExpChanged(false) {}
const std::string& getName() const { return m_Name; }
void setName(const std::string& name) { m_Name = name; }
game::TeamColor getTeamColor() const { return m_TeamColor; }
void setTeamColor(game::TeamColor teamColor) { m_TeamColor = teamColor; }
std::uint8_t getGoldPerSecond() const { return m_GoldPerSecond; }
void setGoldPerSecond(std::uint8_t goldPerSecond) { m_GoldPerSecond = goldPerSecond; }
std::uint32_t getGold() const { return m_Gold;}
void setGold(std::uint32_t gold) { m_GoldChanged = true; m_Gold = gold; }
void addGold(std::uint32_t gold) { m_GoldChanged = true; m_Gold += gold; }
void removeGold(std::uint32_t gold) { m_GoldChanged = true; m_Gold -= gold; }
std::uint32_t getExp() const { return m_Exp; }
void setExp(std::uint32_t exp) { m_ExpChanged = true; m_Exp = exp; }
void addExp(std::uint32_t exp) { m_ExpChanged = true; m_Exp += exp; }
void removeExp(std::uint32_t exp) { m_ExpChanged = true; m_Exp -= exp; }
bool hasGoldChanged() const { return m_GoldChanged; }
bool hasExpChanged() const { return m_ExpChanged; }
void updateGold() { m_GoldChanged = false; }
void updateExp() { m_ExpChanged = false; }
std::uint8_t getID() const { return m_ID; }
};
} // namespace game
} // namespace td

View File

@@ -1,54 +0,0 @@
#pragma once
#include "Types.h"
#include <vector>
#include <memory>
#include <algorithm>
namespace td {
namespace game {
class Player;
enum class TeamColor : std::int8_t {
None = -1,
Red,
Blue
};
struct Spawn {
Direction direction;
std::int32_t x, y;
};
struct TeamCastle {
std::int32_t x, y;
std::uint16_t life = 1000;
};
class Team {
private:
std::vector<Player*> m_Players;
TeamColor m_Color;
Spawn m_Spawn;
TeamCastle m_TeamCastle;
public:
Team(TeamColor color);
void addPlayer(Player* newPlayer);
void removePlayer(const Player* player);
TeamColor getColor() const;
const Spawn& getSpawn() const { return m_Spawn; }
Spawn& getSpawn() { return m_Spawn; }
const TeamCastle& getCastle() const { return m_TeamCastle; }
TeamCastle& getCastle() { return m_TeamCastle; }
std::uint8_t getPlayerCount() const;
};
} // namespace game
} // namespace td

View File

@@ -1,263 +0,0 @@
#pragma once
#include <cstdint>
#include <string>
#include <memory>
#include "misc/Time.h"
#include "game/Types.h"
namespace td {
namespace game {
class World;
class Mob;
typedef std::shared_ptr<Mob> MobPtr;
enum class TowerType : std::uint8_t {
Archer = 0,
Ice,
Sorcerer,
Zeus,
Mage,
Artillery,
Quake,
Poison,
Leach,
Turret,
Necromancer,
TowerCount
};
enum class TowerSize : std::uint8_t {
Little = 3, // 3x3
Big = 5, // 5x5
};
enum class TowerPath : std::uint8_t {
Top = 0,
Base, // Base Path
Bottom
};
class TowerStats {
private:
float m_Rate;
float m_Damage;
std::uint8_t m_Range;
public:
TowerStats(float rate, float damage, std::uint8_t range) : m_Rate(rate), m_Damage(damage),
m_Range(range) {
}
float getDamageRate() const { return m_Rate; }
float getDamage() const { return m_Damage; }
std::uint8_t getRange() const { return m_Range; }
};
class TowerLevel {
private:
// 1, 2, 3, 4
std::uint8_t m_Level : 3;
// 0 : base path 1 : top path (if there is bottom path) 2 : bottom path (if there is top path)
TowerPath m_Path : 2;
public:
TowerLevel() : m_Level(1), m_Path(TowerPath::Base) {}
TowerLevel(std::uint8_t level, TowerPath path) : m_Level(level), m_Path(path) {}
std::uint8_t getLevel() const { return m_Level; }
TowerPath getPath() const { return m_Path; }
void setLevel(std::uint8_t level) { m_Level = level; }
void setPath(TowerPath path) { m_Path = path; }
// operator to sort maps
friend bool operator<(const TowerLevel& level, const TowerLevel& other) {
return level.getLevel() + static_cast<std::uint8_t>(level.getPath()) * 4 <
other.getLevel() + static_cast<std::uint8_t>(other.getPath()) * 4;
}
};
const TowerStats* getTowerStats(TowerType type, TowerLevel level);
typedef std::uint16_t TowerID;
class Tower {
private:
TowerID m_ID;
TowerType m_Type;
std::int32_t m_X, m_Y;
TowerLevel m_Level{};
PlayerID m_Builder;
protected:
utils::CooldownTimer m_Timer;
public:
Tower(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder) : m_ID(id), m_Type(type), m_X(x), m_Y(y), m_Builder(builder),
m_Timer(getStats()->getDamageRate() * 1000) { // converting seconds to millis
}
virtual TowerType getType() const = 0;
virtual TowerSize getSize() const = 0;
virtual void tick(std::uint64_t delta, World* world) = 0;
void upgrade(std::uint8_t level, TowerPath path) {
m_Level.setLevel(level);
m_Level.setPath(path);
m_Timer.setCooldown(getStats()->getDamageRate() * 1000); // converting seconds to millis
m_Timer.reset();
}
std::uint16_t getID() const { return m_ID; }
std::int32_t getX() const { return m_X; }
std::int32_t getY() const { return m_Y; }
const TowerLevel& getLevel() const { return m_Level; }
const TowerStats* getStats() const { return getTowerStats(m_Type, m_Level); }
PlayerID getBuilder() const { return m_Builder; }
bool isMobInRange(MobPtr mob);
};
typedef std::shared_ptr<Tower> TowerPtr;
namespace TowerFactory {
TowerPtr createTower(TowerType type, TowerID id, std::int32_t x, std::int32_t y, PlayerID builder);
std::string getTowerName(TowerType type);
} // namespace TowerFactory
class TowerInfo {
private:
std::string m_Name, m_Description;
bool m_IsBigTower;
public:
TowerInfo(std::string&& name, std::string&& description, bool big) : m_Name(std::move(name)),
m_Description(std::move(description)), m_IsBigTower(big) {}
const std::string& getName() const { return m_Name; }
const std::string& getDescription() const { return m_Description; }
bool isBigTower() const { return m_IsBigTower; }
};
const TowerInfo& getTowerInfo(TowerType type);
// ---------- Little Towers ----------
class LittleTower : public Tower {
public:
LittleTower(TowerID id, TowerType type, std::uint16_t x, std::uint16_t y, PlayerID builder) : Tower(id, type, x, y, builder) {}
virtual TowerSize getSize() const { return TowerSize::Little; }
virtual TowerType getType() const = 0;
virtual void tick(std::uint64_t delta, World* world) = 0;
};
class ArcherTower : public LittleTower {
public:
ArcherTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Archer; }
virtual void tick(std::uint64_t delta, World* world);
};
class IceTower : public LittleTower {
public:
IceTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Ice; }
virtual void tick(std::uint64_t delta, World* world);
};
class MageTower : public LittleTower {
public:
MageTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Mage; }
virtual void tick(std::uint64_t delta, World* world);
};
class PoisonTower : public LittleTower {
public:
PoisonTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Poison; }
virtual void tick(std::uint64_t delta, World* world);
};
class QuakeTower : public LittleTower {
public:
QuakeTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Quake; }
virtual void tick(std::uint64_t delta, World* world);
};
class ArtilleryTower : public LittleTower {
public:
ArtilleryTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Artillery; }
virtual void tick(std::uint64_t delta, World* world);
};
class SorcererTower : public LittleTower {
public:
SorcererTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Sorcerer; }
virtual void tick(std::uint64_t delta, World* world);
};
class ZeusTower : public LittleTower {
public:
ZeusTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Zeus; }
virtual void tick(std::uint64_t delta, World* world);
};
// ---------- Big Towers ----------
class BigTower : public Tower {
public:
BigTower(TowerID id, TowerType type, std::uint16_t x, std::uint16_t y, PlayerID builder) : Tower(id, type, x, y, builder) {}
virtual TowerSize getSize() const { return TowerSize::Big; }
virtual TowerType getType() const = 0;
virtual void tick(std::uint64_t delta, World* world) = 0;
};
class TurretTower : public BigTower {
public:
TurretTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Turret; }
virtual void tick(std::uint64_t delta, World* world);
};
class NecromancerTower : public BigTower {
public:
NecromancerTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Necromancer; }
virtual void tick(std::uint64_t delta, World* world);
};
class LeachTower : public BigTower {
public:
LeachTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, getType(), x, y, builder) {}
virtual TowerType getType() const { return TowerType::Leach; }
virtual void tick(std::uint64_t delta, World* world);
};
} // namespace game
} // namespace td

View File

@@ -1,199 +0,0 @@
#pragma once
#include <memory>
#include <vector>
#include <map>
#include <unordered_map>
#include <glm/glm.hpp>
#include <array>
#include "Mobs.h"
#include "Team.h"
namespace td {
namespace game {
typedef std::pair<std::int16_t, std::int16_t> ChunkCoord;
}
}
namespace std {
template <>
struct hash<td::game::ChunkCoord> {
std::size_t operator()(const td::game::ChunkCoord& key) const {
// Compute individual hash values for first,
// second and third and combine them using XOR
// and bit shifting:
return ((std::hash<std::int16_t>()(key.first) ^ (std::hash<std::int16_t>()(key.second) << 1)) >> 1);
}
};
}
namespace td {
namespace protocol {
class WorldBeginDataPacket;
class WorldDataPacket;
}
namespace game {
class Game;
enum class TileType : std::uint8_t {
None = 0,
Tower,
Walk,
Decoration,
/*Heal,
Lava,
Bedrock,
Freeze,
Ice,*/
};
struct Color {
std::uint8_t r, g, b;
};
struct Tile {
virtual TileType getType() const = 0;
};
struct TowerTile : Tile {
std::uint8_t color_palette_ref;
TeamColor team_owner;
virtual TileType getType() const { return TileType::Tower; }
};
struct WalkableTile : Tile {
Direction direction;
virtual TileType getType() const { return TileType::Walk; }
};
struct DecorationTile : Tile {
std::uint16_t color_palette_ref;
virtual TileType getType() const { return TileType::Decoration; }
};
typedef std::shared_ptr<Tile> TilePtr;
typedef std::vector<std::uint16_t> ChunkPalette;
typedef std::shared_ptr<WalkableTile> WalkableTilePtr;
typedef std::array<std::uint16_t, 32 * 32> ChunkData;
typedef std::uint32_t TileIndex;
//32 x 32 area
struct Chunk {
enum { ChunkWidth = 32, ChunkHeight = 32, ChunkSize = ChunkWidth * ChunkHeight };
// stores index of tile palette
ChunkData tiles{ 0 };
ChunkPalette palette;
TileIndex getTileIndex(std::uint16_t tileNumber) const {
TileIndex chunkPaletteIndex = tiles.at(tileNumber);
if (chunkPaletteIndex == 0) // index 0 means empty tile index 1 = first tile
return 0;
return palette.at(chunkPaletteIndex);
}
};
typedef std::shared_ptr<Chunk> ChunkPtr;
typedef std::array<Color, 2> TowerTileColorPalette;
typedef std::vector<TilePtr> TilePalette;
typedef std::vector<MobPtr> MobList;
typedef std::array<Color, 2> SpawnColorPalette;
typedef std::vector<TowerPtr> TowerList;
class World {
protected:
TowerTileColorPalette m_TowerPlacePalette;
Color m_WalkablePalette;
std::vector<Color> m_DecorationPalette;
std::unordered_map<ChunkCoord, ChunkPtr> m_Chunks;
SpawnColorPalette m_SpawnColorPalette;
TilePalette m_TilePalette;
MobList m_Mobs;
TowerList m_Towers;
Game* m_Game;
public:
World(Game* game);
bool loadMap(const protocol::WorldBeginDataPacket* worldHeader);
bool loadMap(const protocol::WorldDataPacket* worldData);
bool loadMapFromFile(const std::string& fileName);
bool saveMap(const std::string& fileName) const;
void tick(std::uint64_t delta);
void spawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir);
TowerPtr placeTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder);
TilePtr getTile(std::int32_t x, std::int32_t y) const;
const TowerTileColorPalette& getTowerTileColorPalette() const { return m_TowerPlacePalette; }
const Color& getWalkableTileColor() const { return m_WalkablePalette; }
const std::vector<Color>& getDecorationPalette() const { return m_DecorationPalette; }
const TilePalette& getTilePalette() const { return m_TilePalette; }
TilePtr getTilePtr(TileIndex index) const {
if (index == 0)
return nullptr;
return m_TilePalette.at(index - 1);
}
bool CanPlaceLittleTower(const glm::vec2& worldPos, PlayerID player) const;
bool CanPlaceBigTower(const glm::vec2& worldPos, PlayerID player) const;
TowerPtr getTower(const glm::vec2& position) const; // returns null if no tower is here
const std::unordered_map<ChunkCoord, ChunkPtr>& getChunks() const { return m_Chunks; }
const Color& getSpawnColor(TeamColor color) const { return m_SpawnColorPalette[(std::size_t)color]; }
const SpawnColorPalette& getSpawnColors() const { return m_SpawnColorPalette; }
const MobList& getMobList() const { return m_Mobs; }
MobList& getMobList() { return m_Mobs; }
const Color* getTileColor(TilePtr tile) const;
Team& getRedTeam();
const Team& getRedTeam() const;
Team& getBlueTeam();
const Team& getBlueTeam() const;
Team& getTeam(TeamColor team);
const Team& getTeam(TeamColor team) const;
const TowerList& getTowers() const { return m_Towers; };
TowerPtr getTowerById(TowerID tower);
// Archer Tower
virtual void OnArrowShot(MobPtr target, Tower* shooter);
private:
void moveMobs(std::uint64_t delta);
void tickMobs(std::uint64_t delta);
void cleanDeadMobs();
};
} // namespace game
} // namespace td

View File

@@ -1,50 +0,0 @@
#pragma once
#include "ClientConnexion.h"
#include "ClientGame.h"
#include "game/Team.h"
#include "game/Player.h"
#include "protocol/Protocol.h"
#include "render/Renderer.h"
#include "network/Network.h"
namespace td {
namespace client {
class Client {
private:
render::Renderer* m_Renderer;
ClientConnexion m_Connexion;
ClientGame m_Game;
bool m_Connected;
public:
Client(render::Renderer* renderer) : m_Renderer(renderer), m_Game(this), m_Connected(false) {}
const ClientGame& getGame() const { return m_Game; }
const ClientConnexion& getConnexion() const { return m_Connexion; }
render::Renderer* getRenderer() const { return m_Renderer; }
ClientGame& getGame() { return m_Game; }
ClientConnexion& getConnexion() { return m_Connexion; }
void tick(std::uint64_t delta);
void render();
bool connect(const network::IPAddresses& addresses, std::uint16_t port);
void closeConnection();
bool isConnected() const { return m_Connexion.getSocketStatus() == network::Socket::Connected; }
void selectTeam(game::TeamColor team);
void sendMobs(const std::vector<protocol::MobSend>& mobSends);
void placeTower(game::TowerType type, const glm::vec2& position);
void upgradeTower(game::TowerID tower, game::TowerLevel level);
};
} // namespace client
} // namespace td

View File

@@ -1,37 +0,0 @@
#pragma once
#include "protocol/PacketHandler.h"
#include "network/TCPSocket.h"
#include "game/Connexion.h"
namespace td {
namespace client {
class ClientConnexion : public protocol::Connexion {
private:
std::uint8_t m_ConnectionID;
std::string m_DisconnectReason;
float m_ServerTPS;
int m_Ping = 0;
public:
ClientConnexion();
virtual bool updateSocket();
virtual void HandlePacket(const protocol::KeepAlivePacket* packet);
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet);
virtual void HandlePacket(const protocol::DisconnectPacket* packet);
virtual void HandlePacket(const protocol::ServerTpsPacket* packet);
const std::string& getDisconnectReason() const { return m_DisconnectReason; }
float getServerTPS() const { return m_ServerTPS; }
int getServerPing() const { return m_Ping; }
REMOVE_COPY(ClientConnexion);
private:
void registerHandlers();
void login();
};
} // namespace client
} // namespace td

View File

@@ -1,55 +0,0 @@
#pragma once
#include "game/BaseGame.h"
#include "protocol/PacketHandler.h"
#include "WorldClient.h"
#include "render/WorldRenderer.h"
#include "render/Renderer.h"
namespace td {
namespace client {
class Client;
class ClientGame : public protocol::PacketHandler, public game::Game {
private:
Client* m_Client;
std::uint8_t m_ConnexionID;
std::uint32_t m_LobbyTime = 0;
game::Player* m_Player = nullptr;
render::Renderer* m_Renderer;
client::WorldClient m_WorldClient;
render::WorldRenderer m_WorldRenderer;
public:
ClientGame(Client* client);
virtual ~ClientGame();
virtual void tick(std::uint64_t delta);
void renderWorld();
std::uint32_t getLobbyTime() const { return m_LobbyTime; }
const game::Player* getPlayer() const { return m_Player; }
const WorldClient& getWorld() const { return m_WorldClient; }
Client* getClient() const { return m_Client; }
render::Renderer* getRenderer() const { return m_Renderer; }
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet);
virtual void HandlePacket(const protocol::PlayerJoinPacket* packet);
virtual void HandlePacket(const protocol::PlayerLeavePacket* packet);
virtual void HandlePacket(const protocol::PlayerListPacket* packet);
virtual void HandlePacket(const protocol::UpdatePlayerTeamPacket* packet);
virtual void HandlePacket(const protocol::UpdateGameStatePacket* packet);
virtual void HandlePacket(const protocol::UpdateLobbyTimePacket* packet);
virtual void HandlePacket(const protocol::UpdateMoneyPacket* packet);
virtual void HandlePacket(const protocol::DisconnectPacket* packet);
virtual void HandlePacket(const protocol::WorldDataPacket* packet);
virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet);
};
} // namespace client
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "game/World.h"
#include "protocol/PacketHandler.h"
namespace td {
namespace client {
class ClientGame;
class WorldClient : public game::World, public protocol::PacketHandler {
private:
ClientGame* m_Game;
public:
WorldClient(ClientGame* game);
virtual void HandlePacket(const protocol::WorldBeginDataPacket* packet) override;
virtual void HandlePacket(const protocol::WorldDataPacket* packet) override;
virtual void HandlePacket(const protocol::SpawnMobPacket* packet) override;
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
virtual void OnArrowShot(game::MobPtr target, game::Tower* shooter) override;
};
} // namespace client
} // namespace td

View File

@@ -1,34 +0,0 @@
#pragma once
#include <vector>
#include "misc/Time.h"
namespace td {
namespace server {
class Server;
class Lobby {
private:
Server* m_Server;
bool m_GameStarted = false;
std::uint64_t m_StartTimerTime = 0;
std::vector<std::uint8_t> m_Players;
utils::AutoTimer m_Timer;
public:
Lobby(Server* server);
void OnPlayerJoin(std::uint8_t playerID);
void OnPlayerLeave(std::uint8_t playerID);
void sendTimeRemaining();
void tick();
//static constexpr int LobbyWaitingTime = 2 * 60 * 1000; // in millis
static constexpr int LobbyWaitingTime = 5 * 1000; // in millis
};
} // namespace server
} // namespace td

View File

@@ -1,100 +0,0 @@
#pragma once
#include <cstdint>
#include <map>
#include <thread>
#include "network/TCPListener.h"
#include "protocol/Protocol.h"
#include "protocol/PacketDispatcher.h"
#include "protocol/PacketHandler.h"
#include "ServerGame.h"
#include "ServerConnexion.h"
#include "Lobby.h"
#define SERVER_TPS 20
#define SERVER_TICK 1000 / SERVER_TPS
namespace td {
namespace server {
typedef std::map<std::uint8_t, ServerConnexion> ConnexionMap;
class TickCounter {
private:
float m_TPS;
std::uint64_t m_LastTPSTime;
std::uint8_t m_TickCount;
public:
TickCounter() {}
void reset() {
m_TPS = SERVER_TPS;
m_LastTPSTime = utils::getTime();
m_TickCount = 0;
}
bool update() { // return true when tps is updated
m_TickCount++;
if (m_TickCount >= SERVER_TPS) {
std::uint64_t timeElapsedSinceLast20Ticks = td::utils::getTime() - m_LastTPSTime;
m_TPS = (float)SERVER_TPS / (float)(timeElapsedSinceLast20Ticks / 1000.0f);
m_TickCount = 0;
m_LastTPSTime = td::utils::getTime();
return true;
}
return false;
}
float getTPS() const { return m_TPS; }
};
class Server {
private:
network::TCPListener m_Listener;
ConnexionMap m_Connections;
ServerGame m_Game{ this };
Lobby m_Lobby{ this };
TickCounter m_TickCounter;
std::thread m_Thread;
bool m_ServerRunning;
public:
Server(const std::string& worldFilePath);
virtual ~Server() {}
bool start(std::uint16_t port);
void stop();
void lauchGame();
void removeConnexion(std::uint8_t connexionID);
void broadcastPacket(const protocol::Packet* packet);
float getTPS() const { return m_TickCounter.getTPS(); }
const ServerGame& getGame() const { return m_Game; }
ServerGame& getGame() { return m_Game; }
const Lobby& getLobby() const { return m_Lobby; }
const ConnexionMap& getConnexions() const { return m_Connections; }
ConnexionMap& getConnexions() { return m_Connections; }
const game::PlayerList& getPlayers() const { return m_Game.getPlayers(); }
game::PlayerList& getPlayers() { return m_Game.getPlayers(); }
private:
void accept();
void updateSockets();
void startThread();
void stopThread();
void tick(std::uint64_t delta);
void OnPlayerJoin(std::uint8_t id);
void OnPlayerLeave(std::uint8_t id);
};
} // namespace server
} // namespace td

View File

@@ -1,59 +0,0 @@
#pragma once
#include "network/TCPSocket.h"
#include "protocol/PacketHandler.h"
#include "protocol/PacketDispatcher.h"
#include "game/Player.h"
#include "game/Connexion.h"
namespace td {
namespace server {
class Server;
struct KeepAlive
{
std::uint64_t keepAliveID = 0;
std::uint64_t sendTime;
bool recievedResponse = false;
};
class ServerConnexion : public protocol::Connexion {
private:
Server* m_Server = nullptr;
std::uint8_t m_ID;
KeepAlive m_KeepAlive;
game::Player* m_Player;
public:
ServerConnexion();
ServerConnexion(network::TCPSocket& socket, std::uint8_t id);
ServerConnexion(ServerConnexion&& move);
virtual ~ServerConnexion();
void setServer(Server* server);
virtual void HandlePacket(const protocol::PlayerLoginPacket* packet);
virtual void HandlePacket(const protocol::KeepAlivePacket* packet);
virtual void HandlePacket(const protocol::SelectTeamPacket* packet);
virtual void HandlePacket(const protocol::DisconnectPacket* packet);
virtual void HandlePacket(const protocol::PlaceTowerPacket* packet);
virtual void HandlePacket(const protocol::SendMobsPacket* packet);
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet);
std::uint8_t getID() const { return m_ID; }
const game::Player* getPlayer() const { return m_Player; }
game::Player* getPlayer() { return m_Player; }
virtual bool updateSocket();
REMOVE_COPY(ServerConnexion);
private:
void registerHandlers();
void checkKeepAlive();
void sendKeepAlive();
void initConnection();
};
} // namespace server
} // namespace td

View File

@@ -1,32 +0,0 @@
#pragma once
#include "game/BaseGame.h"
#include "misc/Time.h"
#include "ServerWorld.h"
namespace td {
namespace server {
class Server;
class ServerGame : public game::Game {
private:
Server* m_Server;
ServerWorld m_ServerWorld;
utils::AutoTimer m_GoldMineTimer{ 1000, std::bind(&ServerGame::updateGoldMines, this) };
public:
ServerGame(Server* server);
~ServerGame() {}
ServerWorld* getServerWorld() { return &m_ServerWorld; }
virtual void tick(std::uint64_t delta);
void startGame();
private:
void balanceTeams();
void updateGoldMines();
void updatePlayerStats();
};
} // namespace game
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "game/World.h"
namespace td {
namespace server {
class Server;
class ServerGame;
class ServerWorld : public game::World {
private:
game::MobID m_CurrentMobID;
game::TowerID m_CurrentTowerID;
Server* m_Server;
public:
ServerWorld(Server* server, ServerGame* game);
void spawnMobs(game::MobType type, std::uint8_t level, game::PlayerID sender, std::uint8_t count);
game::TowerPtr placeTowerAt(game::TowerType type, std::int32_t x, std::int32_t y, game::PlayerID builder);
virtual void OnArrowShot(game::MobPtr target, game::Tower* shooter) override;
};
} // namespace server
} // namespace td

View File

@@ -1,167 +0,0 @@
#ifndef MCLIB_COMMON_DATA_BUFFER_H_
#define MCLIB_COMMON_DATA_BUFFER_H_
#include <vector>
#include <algorithm>
#include <cstring>
#include <cassert>
#include <string>
namespace td {
class DataBuffer {
private:
typedef std::vector<std::uint8_t> Data;
Data m_Buffer;
std::size_t m_ReadOffset = 0;
public:
typedef Data::iterator iterator;
typedef Data::const_iterator const_iterator;
typedef Data::reference reference;
typedef Data::const_reference const_reference;
DataBuffer();
DataBuffer(const DataBuffer& other);
DataBuffer(const DataBuffer& other, std::size_t offset);
DataBuffer(DataBuffer&& other);
DataBuffer(const std::string& str);
DataBuffer& operator=(const DataBuffer& other);
DataBuffer& operator=(DataBuffer&& other);
template <typename T>
void Append(T data) {
std::size_t size = sizeof(data);
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + size);
memcpy(&m_Buffer[end_pos], &data, size);
}
template <typename T>
DataBuffer& operator<<(T data) {
// Switch to big endian
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
Append(data);
return *this;
}
DataBuffer& operator<<(std::string str) {
m_Buffer.insert(m_Buffer.end(), str.begin(), str.end());
return *this;
}
DataBuffer& operator<<(DataBuffer& data) {
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
return *this;
}
DataBuffer& operator<<(const DataBuffer& data) {
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
return *this;
}
template <typename T>
DataBuffer& operator>>(T& data) {
assert(m_ReadOffset + sizeof(T) <= GetSize());
data = *(T*)&m_Buffer[m_ReadOffset];
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
m_ReadOffset += sizeof(T);
return *this;
}
DataBuffer& operator>>(DataBuffer& data) {
data.Resize(GetSize() - m_ReadOffset);
std::copy(m_Buffer.begin() + m_ReadOffset, m_Buffer.end(), data.begin());
m_ReadOffset = m_Buffer.size();
return *this;
}
DataBuffer& operator>>(std::string& str) {
std::size_t stringSize = strlen((const char*)m_Buffer.data() + m_ReadOffset) + 1; // including null character
str.resize(stringSize);
std::copy(m_Buffer.begin() + m_ReadOffset, m_Buffer.begin() + m_ReadOffset + stringSize, str.begin());
m_ReadOffset += stringSize;
return *this;
}
void ReadSome(char* buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer);
m_ReadOffset += amount;
}
void ReadSome(std::uint8_t* buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer);
m_ReadOffset += amount;
}
void ReadSome(DataBuffer& buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
buffer.Resize(amount);
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer.begin());
m_ReadOffset += amount;
}
void ReadSome(std::string& buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
buffer.resize(amount);
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer.begin());
m_ReadOffset += amount;
}
void Resize(std::size_t size) {
m_Buffer.resize(size);
}
void Reserve(std::size_t amount) {
m_Buffer.reserve(amount);
}
void erase(iterator it) {
m_Buffer.erase(it);
}
void Clear() {
m_Buffer.clear();
m_ReadOffset = 0;
}
bool IsFinished() const {
return m_ReadOffset >= m_Buffer.size();
}
std::uint8_t* data() {
return m_Buffer.data();
}
const std::uint8_t* data() const {
return m_Buffer.data();
}
std::size_t GetReadOffset() const { return m_ReadOffset; }
void SetReadOffset(std::size_t pos);
std::string ToString() const;
std::size_t GetSize() const;
bool IsEmpty() const;
std::size_t GetRemaining() const;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
reference operator[](Data::size_type i) { return m_Buffer[i]; }
const_reference operator[](Data::size_type i) const { return m_Buffer[i]; }
bool ReadFile(const std::string& fileName);
bool WriteFile(const std::string& fileName);
};
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);
} // ns td
#endif

View File

@@ -1,69 +0,0 @@
#pragma once
namespace td {
namespace utils {
constexpr float PI = 3.14159274101257324219;
/* Sine functions */
float easeInSine(float x);
float easeOutSine(float x);
float easeInOutSine(float x);
/* Cubic functions */
float easeInCubic(float x);
float easeOutCubic(float x);
float easeInOutCubic(float x);
/* Quint functions */
float easeInQuint(float x);
float easeOutQuint(float x);
float easeInOutQuint(float x);
/* Circ functions */
float easeInCirc(float x);
float easeOutCirc(float x);
float easeInOutCirc(float x);
/* Elastic functions */
float easeInElastic(float x);
float easeOutElastic(float x);
float easeInOutElastic(float x);
/* Quad functions */
float easeInQuad(float x);
float easeOutQuad(float x);
float easeInOutQuad(float x);
/* Quart functions */
float easeInQuart(float x);
float easeOutQuart(float x);
float easeInOutQuart(float x);
/* Expo functions */
float easeInExpo(float x);
float easeOutExpo(float x);
float easeInOutExpo(float x);
/* Back functions */
float easeInBack(float x);
float easeOutBack(float x);
float easeInOutBack(float x);
/* Bounce functions */
float easeInBounce(float x);
float easeOutBounce(float x);
float easeInOutBounce(float x);
} // namespace utils
} // namespace td

View File

@@ -1,54 +0,0 @@
#pragma once
namespace td {
namespace utils {
enum class Os {
Windows = 0,
Linux,
Android,
Unknown,
};
enum class Architecture {
x86_64 = 0,
x86,
Arm64,
Armhf,
Unknown,
};
inline Os getSystemOs(){
#if defined(_WIN32) || defined(_WIN64)
return Os::Windows;
#elif defined(__ANDROID__)
return Os::Android;
#elif defined(__unix__)
return Os::Linux;
#else
#pragma message ("Target OS unknown or unsupported !")
return Os::Unknown;
#endif
}
inline Architecture getSystemArchitecture(){
#if defined(_WIN64)
return Architecture::x86_64;
#elif defined(_WIN32)
return Architecture::x86;
#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
return Architecture::x86_64;
#elif defined(_M_IX86) || defined(_X86_) || defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
return Architecture::x86;
#elif defined(__aarch64__)
return Architecture::Arm64;
#elif defined(__arm__) || defined(_M_ARM)
return Architecture::Armhf;
#else
#pragma message ("Target CPU architecture unknown or unsupported !")
return Architecture::Unknown;
#endif
}
} // namespace utils
} // namespace td

View File

@@ -1,25 +0,0 @@
#pragma once
#include <random>
namespace td {
namespace utils {
template<typename NumberType>
NumberType getRandomInt(NumberType min, NumberType max){
std::random_device randomDevice;
std::mt19937 generator(randomDevice());
std::uniform_int_distribution<NumberType> distrib(min, max);
return distrib(generator);
}
template<typename NumberType>
NumberType getRandomReal(NumberType min, NumberType max){
std::random_device randomDevice;
std::mt19937 generator(randomDevice());
std::uniform_real_distribution<NumberType> distrib(min, max);
return distrib(generator);
}
} // namespace utils
} // namespace td

View File

@@ -1,76 +0,0 @@
#pragma once
#include <cstdint>
#include <functional>
namespace td {
namespace utils {
std::uint64_t getTime();
typedef std::function<void()> TimerExecFunction;
// utililty class to call function at regular period of time
class AutoTimer {
private:
std::uint64_t m_Interval;
TimerExecFunction m_Function;
std::uint64_t m_LastTime = getTime();
std::uint64_t m_InternalTime = 0;
public:
AutoTimer() : m_Interval(0), m_Function(nullptr) {}
AutoTimer(std::uint64_t interval) : m_Interval(interval), m_Function(nullptr) {}
AutoTimer(std::uint64_t interval, TimerExecFunction callback) : m_Interval(interval), m_Function(callback) {}
void update();
void update(std::uint64_t delta);
void reset();
void setInterval(std::uint64_t newInterval) { m_Interval = newInterval; }
std::uint64_t getInterval() const { return m_Interval; }
void setCallbackFunction(TimerExecFunction newCallback) { m_Function = newCallback; }
TimerExecFunction getCallbackFunction() const { return m_Function; }
};
// utililty class to call function at regular period of time
class Timer {
private:
std::uint64_t m_Interval;
std::uint64_t m_InternalTime = 0;
public:
Timer() : m_Interval(0) {}
Timer(std::uint64_t interval) : m_Interval(interval) {}
bool update(std::uint64_t delta);
void reset();
void setInterval(std::uint64_t newInterval) { m_Interval = newInterval; }
std::uint64_t getInterval() const { return m_Interval; }
};
// utililty class to call function at regular period of time with a cooldown (used for towers)
class CooldownTimer {
private:
std::uint64_t m_Cooldown;
std::uint64_t m_CooldownTime;
public:
CooldownTimer() : m_Cooldown(0), m_CooldownTime(0) {}
CooldownTimer(std::uint64_t cooldown) : m_Cooldown(0), m_CooldownTime(cooldown) {}
bool update(std::uint64_t delta);
void applyCooldown();
void reset();
void setCooldown(std::uint64_t newCooldown) { m_CooldownTime = newCooldown; }
std::uint64_t getCooldown() const { return m_CooldownTime; }
};
} // namespace utils
} // namespace td

View File

@@ -1,46 +0,0 @@
#pragma once
#include "misc/DataBuffer.h"
#include <ctime>
#define TD_VERSION "alpha-0.0.1"
namespace td {
namespace utils {
class Updater {
private:
float m_Progress;
bool m_DownloadComplete;
bool m_FileWrited;
bool m_CancelDownload;
DataBuffer m_FileBuffer;
std::string m_LastVersion;
public:
Updater() : m_Progress(0), m_DownloadComplete(false), m_FileWrited(false), m_CancelDownload(false) {}
bool checkUpdate();
void downloadUpdate();
void cancelDownload() { m_CancelDownload = true; m_Progress = 0.0f; m_DownloadComplete = false; }
bool writeFile();
void clearCache() { m_FileBuffer.Clear(); }
float getDownloadProgress() { return m_Progress; }
bool isDownloadComplete() { return m_DownloadComplete; }
bool isFileWrited() { return m_FileWrited; }
static std::string getLocalFilePath();
static void removeOldFile();
static std::string getCurrentVersion(){ return TD_VERSION; }
std::string getLastVersion() { return m_LastVersion; }
bool canUpdate();
private:
std::string getDownloadFileURL();
};
} // namespace utils
} // namespace td

View File

@@ -1,56 +0,0 @@
#ifndef NETWORK_IPADDRESS_H_
#define NETWORK_IPADDRESS_H_
#include <string>
#include <iosfwd>
#include <vector>
namespace td {
namespace network {
/* IPv4 address */
class IPAddress {
private:
std::uint32_t m_Address;
bool m_Valid;
public:
/* Create an invalid address */
IPAddress() noexcept;
/* Initialize by string IP */
IPAddress(const std::string& str);
/* Initialize by string IP */
IPAddress(const std::wstring& str);
/* Initialize by octets */
IPAddress(std::uint8_t octet1, std::uint8_t octet2, std::uint8_t octet3, std::uint8_t octet4) noexcept;
/* Get the specific octet. 1-4 */
std::uint8_t GetOctet(std::uint8_t num) const;
/* Set the specific octet. 1-4 */
void SetOctet(std::uint8_t num, std::uint8_t value);
/* Make sure the IP is valid. It will be invalid if the host wasn't found. */
bool IsValid() const noexcept { return m_Valid; }
std::string ToString() const;
static IPAddress LocalAddress();
bool operator==(const IPAddress& right);
bool operator!=(const IPAddress& right);
bool operator==(bool b);
};
typedef std::vector<IPAddress> IPAddresses;
std::ostream& operator<<(std::ostream& os, const IPAddress& addr);
std::wostream& operator<<(std::wostream& os, const IPAddress& addr);
} // ns network
} // ns td
#endif

View File

@@ -1,90 +0,0 @@
#ifndef NETWORK_SOCKET_H_
#define NETWORK_SOCKET_H_
#include <string>
#include <vector>
#include <memory>
#include "misc/DataBuffer.h"
#ifdef _WIN32
#include <ws2tcpip.h>
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/ioctl.h>
#define closesocket close
#endif
#ifndef INVALID_SOCKET
#define INVALID_SOCKET -1
#endif
#define REMOVE_COPY(className) \
className(const className &) = delete;\
className& operator=(const className &) = delete
namespace td {
namespace network {
class IPAddress;
typedef int SocketHandle;
class Socket {
public:
enum Status { Connected, Disconnected, Error };
enum Type { TCP, UDP };
private:
bool m_Blocking;
Type m_Type;
Status m_Status;
protected:
SocketHandle m_Handle;
Socket(Type type);
void SetStatus(Status status);
public:
virtual ~Socket();
Socket(Socket&& rhs) = default;
Socket& operator=(Socket&& rhs) = default;
bool SetBlocking(bool block);
bool IsBlocking() const noexcept;
Type GetType() const noexcept;
Status GetStatus() const noexcept;
SocketHandle GetHandle() const noexcept;
bool Connect(const std::string& ip, std::uint16_t port);
virtual bool Connect(const IPAddress& address, std::uint16_t port) = 0;
void Disconnect();
std::size_t Send(const std::string& data);
std::size_t Send(DataBuffer& buffer);
virtual std::size_t Send(const uint8_t* data, std::size_t size) = 0;
virtual DataBuffer Receive(std::size_t amount) = 0;
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount) = 0;
};
typedef std::shared_ptr<Socket> SocketPtr;
} // ns network
} // ns td
#endif

View File

@@ -1,34 +0,0 @@
#pragma once
#include "TCPSocket.h"
namespace td {
namespace network {
class TCPListener {
int m_Handle;
std::uint16_t m_Port;
int m_MaxConnections;
public:
TCPListener();
~TCPListener();
bool listen(std::uint16_t port, int maxConnections);
bool accept(TCPSocket& newSocket);
void destroy();
bool close();
bool setBlocking(bool blocking);
std::uint16_t getListeningPort() const {
return m_Port;
}
int getMaximumConnections() const {
return m_MaxConnections;
}
REMOVE_COPY(TCPListener);
};
} // namespace network
} // namespace td

View File

@@ -1,39 +0,0 @@
#ifndef NETWORK_TCP_SOCKET_H_
#define NETWORK_TCP_SOCKET_H_
#include "network/IPAddress.h"
#include "network/Socket.h"
#include <cstdint>
namespace td {
namespace network {
class TCPListener;
class TCPSocket : public Socket {
private:
IPAddress m_RemoteIP;
uint16_t m_Port;
sockaddr_in m_RemoteAddr;
public:
TCPSocket();
TCPSocket(TCPSocket&& other);
virtual bool Connect(const IPAddress& address, std::uint16_t port);
virtual std::size_t Send(const std::uint8_t* data, std::size_t size);
virtual DataBuffer Receive(std::size_t amount);
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount);
REMOVE_COPY(TCPSocket);
friend class TCPListener;
};
void SendPacket(const DataBuffer& data, network::TCPSocket& socket);
} // ns network
} // ns td
#endif

View File

@@ -1,29 +0,0 @@
#ifndef NETWORK_UDP_SOCKET_H_
#define NETWORK_UDP_SOCKET_H_
#include "network/IPAddress.h"
#include "network/Socket.h"
#include <cstdint>
namespace td {
namespace network {
class UDPSocket : public Socket {
private:
IPAddress m_RemoteIP;
uint16_t m_Port;
sockaddr_in m_RemoteAddr;
public:
UDPSocket();
bool Connect(const IPAddress& address, std::uint16_t port);
std::size_t Send(const std::uint8_t* data, std::size_t size);
DataBuffer Receive(std::size_t amount);
};
} // ns network
} // ns td
#endif

View File

@@ -1,33 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
#include <map>
#include <vector>
namespace td {
namespace protocol {
class PacketHandler;
class PacketDispatcher {
private:
std::map<PacketType, std::vector<PacketHandler*>> m_Handlers;
public:
PacketDispatcher() = default;
PacketDispatcher(const PacketDispatcher& rhs) = delete;
PacketDispatcher& operator=(const PacketDispatcher& rhs) = delete;
PacketDispatcher(PacketDispatcher&& rhs) = delete;
PacketDispatcher& operator=(PacketDispatcher&& rhs) = delete;
void Dispatch(const PacketPtr& packet);
void RegisterHandler(PacketType type, PacketHandler* handler);
void UnregisterHandler(PacketType type, PacketHandler* handler);
void UnregisterHandler(PacketHandler* handler);
};
} // namespace protocol
} // namespace td

View File

@@ -1,44 +0,0 @@
#pragma once
#include "protocol/Protocol.h"
namespace td {
namespace protocol {
class PacketDispatcher;
class PacketHandler {
private:
PacketDispatcher* m_Dispatcher;
public:
PacketHandler(PacketDispatcher* dispatcher) : m_Dispatcher(dispatcher) {}
virtual ~PacketHandler() {}
PacketDispatcher* GetDispatcher() { return m_Dispatcher; }
virtual void HandlePacket(const PlayerLoginPacket* packet) {}
virtual void HandlePacket(const WorldBeginDataPacket* packet) {}
virtual void HandlePacket(const WorldDataPacket* packet) {}
virtual void HandlePacket(const KeepAlivePacket* packet) {}
virtual void HandlePacket(const UpdateMoneyPacket* packet) {}
virtual void HandlePacket(const UpdateExpPacket* packet) {}
virtual void HandlePacket(const UpdateLobbyTimePacket* packet) {}
virtual void HandlePacket(const UpdateGameStatePacket* packet) {}
virtual void HandlePacket(const PlayerListPacket* packet) {}
virtual void HandlePacket(const PlayerJoinPacket* packet) {}
virtual void HandlePacket(const PlayerLeavePacket* packet) {}
virtual void HandlePacket(const ConnexionInfoPacket* packet) {}
virtual void HandlePacket(const SelectTeamPacket* packet) {}
virtual void HandlePacket(const UpdatePlayerTeamPacket* packet) {}
virtual void HandlePacket(const DisconnectPacket* packet) {}
virtual void HandlePacket(const ServerTpsPacket* packet) {}
virtual void HandlePacket(const SpawnMobPacket* packet) {}
virtual void HandlePacket(const PlaceTowerPacket* packet) {}
virtual void HandlePacket(const WorldAddTowerPacket* packet) {}
virtual void HandlePacket(const WorldRemoveTowerPacket* packet) {}
virtual void HandlePacket(const SendMobsPacket* packet) {}
virtual void HandlePacket(const UpgradeTowerPacket* packet) {}
};
} // namespace protocol
} // namespace td

View File

@@ -1,517 +0,0 @@
#pragma once
#include "misc/DataBuffer.h"
#include "game/World.h"
#include "game/BaseGame.h"
#include <memory>
namespace td {
namespace protocol {
class PacketHandler;
enum class PacketType : std::uint8_t {
// client --> server
PlayerLogin = 0,
SelectTeam,
SpawnMob,
SendMobs,
PlaceTower,
// client <-- server
PlayerJoin,
PlayerLeave,
WorldBeginData,
WorldData,
UpdateMoney,
UpdateEXP,
UpdateLobbyTime,
UpdateGameState,
PlayerList,
ConnectionInfo,
UpdatePlayerTeam,
ServerTps,
WorldAddTower,
WorldRemoveTower,
// client <--> server
KeepAlive,
Disconnect,
UpgradeTower,
};
struct WorldHeader {
game::TowerTileColorPalette m_TowerPlacePalette;
game::Color m_WalkablePalette;
std::vector<game::Color> m_DecorationPalette;
game::SpawnColorPalette m_SpawnColorPalette;
game::TilePalette m_TilePalette;
game::Spawn m_RedSpawn, m_BlueSpawn;
game::TeamCastle m_RedCastle, m_BlueCastle;
const game::World* m_World;
};
struct WorldData {
std::unordered_map<game::ChunkCoord, game::ChunkPtr> m_Chunks;
};
class Packet {
public:
Packet() {}
virtual ~Packet() {}
virtual DataBuffer Serialize() const = 0;
virtual void Deserialize(DataBuffer& data) = 0;
virtual void Dispatch(PacketHandler* handler) const = 0;
virtual PacketType getType() const = 0;
std::uint8_t getID() const { return (std::uint8_t)getType(); }
};
typedef std::unique_ptr<Packet> PacketPtr;
class KeepAlivePacket : public Packet {
private:
std::uint64_t m_AliveID;
public:
KeepAlivePacket() {}
KeepAlivePacket(std::uint64_t aliveID) : m_AliveID(aliveID) {}
virtual ~KeepAlivePacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint64_t getAliveID() const { return m_AliveID; }
virtual PacketType getType() const { return PacketType::KeepAlive; }
};
class PlayerLoginPacket : public Packet {
private:
std::string m_PlayerName;
public:
PlayerLoginPacket() {}
PlayerLoginPacket(std::string playerName) : m_PlayerName(playerName) {}
virtual ~PlayerLoginPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType getType() const { return PacketType::PlayerLogin; }
const std::string& getPlayerName() const { return m_PlayerName; }
};
class WorldBeginDataPacket : public Packet {
private:
WorldHeader m_Header;
public:
WorldBeginDataPacket() {}
WorldBeginDataPacket(const game::World* world) {
m_Header.m_World = world;
}
virtual ~WorldBeginDataPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType getType() const { return PacketType::WorldBeginData; }
const game::TowerTileColorPalette& getTowerTilePalette() const { return m_Header.m_TowerPlacePalette; }
const game::Color& getWalkableTileColor() const { return m_Header.m_WalkablePalette; }
const std::vector<game::Color>& getDecorationPalette() const { return m_Header.m_DecorationPalette; }
const game::Spawn& getRedSpawn() const { return m_Header.m_RedSpawn; }
const game::Spawn& getBlueSpawn() const { return m_Header.m_BlueSpawn; }
const game::SpawnColorPalette& getSpawnPalette() const { return m_Header.m_SpawnColorPalette; }
const game::TeamCastle& getRedCastle() const { return m_Header.m_RedCastle; }
const game::TeamCastle& getBlueCastle() const { return m_Header.m_BlueCastle; }
const game::TilePalette getTilePalette() const { return m_Header.m_TilePalette; }
DataBuffer SerializeCustom() const; // allow serialisation with invalid World member
void setWorldHeader(const WorldHeader& header) { m_Header = header; }
};
class WorldDataPacket : public Packet {
private:
WorldData m_WorldData;
const game::World* m_World;
public:
WorldDataPacket() {}
WorldDataPacket(const game::World* world) : m_World(world) {}
virtual ~WorldDataPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType getType() const { return PacketType::WorldData; }
const std::unordered_map<game::ChunkCoord, game::ChunkPtr>& getChunks() const { return m_WorldData.m_Chunks; }
DataBuffer SerializeCustom() const; // allow serialisation with invalid World member
void setWorldData(const WorldData& worldData) { m_WorldData = worldData; }
};
class UpdateMoneyPacket : public Packet {
private:
std::uint32_t m_NewAmount;
public:
UpdateMoneyPacket() {}
UpdateMoneyPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {}
virtual ~UpdateMoneyPacket() {}
std::uint32_t getGold() const { return m_NewAmount; }
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType getType() const { return PacketType::UpdateMoney; }
};
class UpdateExpPacket : public Packet {
private:
std::uint32_t m_NewAmount;
public:
UpdateExpPacket() {}
UpdateExpPacket(std::uint32_t newAmount) : m_NewAmount(newAmount) {}
virtual ~UpdateExpPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
virtual PacketType getType() const { return PacketType::UpdateEXP; }
};
class UpdateLobbyTimePacket : public Packet {
private:
std::uint32_t m_RemainingTime;
public:
UpdateLobbyTimePacket() {}
UpdateLobbyTimePacket(std::uint32_t remainingTime) : m_RemainingTime(remainingTime) {}
virtual ~UpdateLobbyTimePacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint32_t getRemainingTime() const { return m_RemainingTime; }
virtual PacketType getType() const { return PacketType::UpdateLobbyTime; }
};
class UpdateGameStatePacket : public Packet {
private:
game::GameState m_GameState;
public:
UpdateGameStatePacket() {}
UpdateGameStatePacket(game::GameState gameState) : m_GameState(gameState) {}
virtual ~UpdateGameStatePacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::GameState getGameState() const { return m_GameState; }
virtual PacketType getType() const { return PacketType::UpdateGameState; }
};
struct PlayerInfo {
std::string name;
game::TeamColor team;
};
class PlayerListPacket : public Packet {
private:
std::map<std::uint8_t, PlayerInfo> m_Players;
public:
PlayerListPacket() {}
PlayerListPacket(std::map<std::uint8_t, PlayerInfo> players) : m_Players(players) {}
virtual ~PlayerListPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const std::map<std::uint8_t, PlayerInfo>& getPlayers() const { return m_Players; }
virtual PacketType getType() const { return PacketType::PlayerList; }
};
class PlayerJoinPacket : public Packet {
private:
std::uint8_t m_PlayerID;
std::string m_PlayerName;
public:
PlayerJoinPacket() {}
PlayerJoinPacket(std::uint8_t playerID, const std::string& playerName) : m_PlayerID(playerID), m_PlayerName(playerName) {}
virtual ~PlayerJoinPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint8_t getPlayerID() const { return m_PlayerID; }
const std::string& getPlayerName() const { return m_PlayerName; }
virtual PacketType getType() const { return PacketType::PlayerJoin; }
};
class PlayerLeavePacket : public Packet {
private:
std::uint8_t m_PlayerID;
public:
PlayerLeavePacket() {}
PlayerLeavePacket(std::uint8_t playerID) : m_PlayerID(playerID) {}
virtual ~PlayerLeavePacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint8_t getPlayerID() const { return m_PlayerID; }
virtual PacketType getType() const { return PacketType::PlayerLeave; }
};
class ConnexionInfoPacket : public Packet {
private:
std::uint8_t m_ConnectionID;
public:
ConnexionInfoPacket() {}
ConnexionInfoPacket(std::uint8_t connectionID) : m_ConnectionID(connectionID) {}
virtual ~ConnexionInfoPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint8_t getConnectionID() const { return m_ConnectionID; }
virtual PacketType getType() const { return PacketType::ConnectionInfo; }
};
class SelectTeamPacket : public Packet {
private:
game::TeamColor m_SelectedTeam;
public:
SelectTeamPacket() {}
SelectTeamPacket(game::TeamColor selectedTeam) : m_SelectedTeam(selectedTeam) {}
virtual ~SelectTeamPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TeamColor getSelectedTeam() const { return m_SelectedTeam; }
virtual PacketType getType() const { return PacketType::SelectTeam; }
};
class UpdatePlayerTeamPacket : public Packet {
private:
std::uint8_t m_PlayerID;
game::TeamColor m_SelectedTeam;
public:
UpdatePlayerTeamPacket() {}
UpdatePlayerTeamPacket(std::uint8_t playerID, game::TeamColor selectedTeam) : m_PlayerID(playerID), m_SelectedTeam(selectedTeam) {}
virtual ~UpdatePlayerTeamPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TeamColor getSelectedTeam() const { return m_SelectedTeam; }
std::uint8_t getPlayerID() const { return m_PlayerID; }
virtual PacketType getType() const { return PacketType::UpdatePlayerTeam; }
};
class DisconnectPacket : public Packet {
private:
std::string m_Reason; // only when sent from server
public:
DisconnectPacket() {}
DisconnectPacket(std::string reason) : m_Reason(reason) {}
virtual ~DisconnectPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const std::string& getReason() const { return m_Reason; }
virtual PacketType getType() const { return PacketType::Disconnect; }
};
class ServerTpsPacket : public Packet {
private:
float m_TPS;
std::uint64_t m_PacketSendTime; // used to calculate ping
public:
ServerTpsPacket() {}
ServerTpsPacket(float tps, std::uint64_t sendTime) : m_TPS(tps), m_PacketSendTime(sendTime) {}
virtual ~ServerTpsPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
float getTPS() const { return m_TPS; }
std::uint64_t getPacketSendTime() const { return m_PacketSendTime; }
virtual PacketType getType() const { return PacketType::ServerTps; }
};
struct MobSend { // represents a mob send
game::MobType mobType;
game::MobLevel mobLevel;
std::uint8_t mobCount; // the max is 12
};
class SendMobsPacket : public Packet {
private:
std::vector<MobSend> m_MobSends;
public:
SendMobsPacket() {}
SendMobsPacket(const std::vector<MobSend>& mobSends) : m_MobSends(mobSends) {}
virtual ~SendMobsPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
const std::vector<MobSend>& getMobSends() const { return m_MobSends; }
virtual PacketType getType() const { return PacketType::SendMobs; }
};
class SpawnMobPacket : public Packet {
private:
game::MobID m_MobID;
game::MobType m_MobType;
game::MobLevel m_MobLevel;
game::Direction m_MobDirection;
game::PlayerID m_Sender;
float m_MobX, m_MobY;
public:
SpawnMobPacket() {}
SpawnMobPacket(game::MobID id, game::MobType type, std::uint8_t level, game::PlayerID sender,
float x, float y, game::Direction dir) : m_MobID(id), m_MobType(type), m_MobLevel(level),
m_MobDirection(dir), m_Sender(sender), m_MobX(x), m_MobY(y) {}
virtual ~SpawnMobPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::MobID getMobID() const { return m_MobID; }
game::MobType getMobType() const { return m_MobType; }
game::MobLevel getMobLevel() const { return m_MobLevel; }
game::Direction getMobDirection() const { return m_MobDirection; }
game::PlayerID getSender() const { return m_Sender; }
float getMobX() const { return m_MobX; }
float getMobY() const { return m_MobY; }
virtual PacketType getType() const { return PacketType::SpawnMob; }
};
class PlaceTowerPacket : public Packet {
private:
std::int32_t m_TowerX, m_TowerY;
game::TowerType m_TowerType;
public:
PlaceTowerPacket() {}
PlaceTowerPacket(std::int32_t x, std::int32_t y, game::TowerType type) :
m_TowerX(x), m_TowerY(y), m_TowerType(type) {}
virtual ~PlaceTowerPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::int32_t getTowerX() const { return m_TowerX; }
std::int32_t getTowerY() const { return m_TowerY; }
game::TowerType getTowerType() const { return m_TowerType; }
virtual PacketType getType() const { return PacketType::PlaceTower; }
};
class WorldAddTowerPacket : public Packet {
private:
game::TowerID m_TowerID;
std::int32_t m_TowerX, m_TowerY;
game::TowerType m_TowerType;
game::PlayerID m_Builder;
public:
WorldAddTowerPacket() {}
WorldAddTowerPacket(game::TowerID id, std::int32_t x, std::int32_t y, game::TowerType type, game::PlayerID player) :
m_TowerID(id), m_TowerX(x), m_TowerY(y), m_TowerType(type), m_Builder(player) {}
virtual ~WorldAddTowerPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TowerID getTowerID() const { return m_TowerID; }
std::int32_t getTowerX() const { return m_TowerX; }
std::int32_t getTowerY() const { return m_TowerY; }
game::TowerType getTowerType() const { return m_TowerType; }
game::PlayerID getBuilder() const { return m_Builder; }
virtual PacketType getType() const { return PacketType::WorldAddTower; }
};
class WorldRemoveTowerPacket : public Packet {
private:
game::TowerID m_TowerID;
public:
WorldRemoveTowerPacket() {}
WorldRemoveTowerPacket(game::TowerID id) : m_TowerID(id) {}
virtual ~WorldRemoveTowerPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TowerID getTowerID() const { return m_TowerID; }
virtual PacketType getType() const { return PacketType::WorldRemoveTower; }
};
class UpgradeTowerPacket : public Packet {
private:
game::TowerID m_TowerID;
game::TowerLevel m_TowerLevel;
public:
UpgradeTowerPacket() {}
UpgradeTowerPacket(game::TowerID tower, game::TowerLevel level) : m_TowerID(tower), m_TowerLevel(level) {}
virtual ~UpgradeTowerPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
game::TowerID getTowerID() const { return m_TowerID; }
game::TowerLevel getTowerLevel() const { return m_TowerLevel; }
virtual PacketType getType() const { return PacketType::UpgradeTower; }
};
}
}

View File

@@ -1,8 +0,0 @@
#pragma once
#ifdef __ANDROID__
#include <GLES3/gl3.h>
#else
#include "glbinding/gl/gl.h"
using namespace gl;
#endif

View File

@@ -1,62 +0,0 @@
/*
* Renderer.h
*
* Created on: 4 nov. 2020
* Author: simon
*/
#ifndef RENDER_RENDERER_H_
#define RENDER_RENDERER_H_
#include <glm/glm.hpp>
#include <memory>
#include "loader/GLLoader.h"
#include "render/shaders/WorldShader.h"
#include "render/shaders/EntityShader.h"
namespace td {
namespace render {
class Renderer {
public:
static constexpr float m_AnimationSpeed = 2.0f;
struct Model {
GL::VertexArray* vao;
glm::vec2 positon;
};
private:
std::unique_ptr<WorldShader> m_WorldShader;
std::unique_ptr<EntityShader> m_EntityShader;
bool m_IsometricView = true;
float m_IsometricShade = m_IsometricView;
glm::vec2 m_CamPos{};
public:
Renderer();
~Renderer();
bool init();
void prepare();
void resize(const int width, const int height);
void renderVAO(const GL::VertexArray& vao);
void renderModel(const Model& model);
void setZoom(float zoom);
void setCamMovement(const glm::vec2& mov);
void setCamPos(const glm::vec2& newPos);
void setIsometricView(bool isometric); // false = 2D true = Isometric
glm::vec2 getCursorWorldPos(const glm::vec2& cursorPos, float aspectRatio, float zoom, float windowWidth, float windowHeight);
private:
void updateIsometricView();
void updateIsometricFade();
void initShader();
};
} // namespace render
} // namespace td
#endif /* RENDER_RENDERER_H_ */

View File

@@ -1,34 +0,0 @@
#include <unordered_map>
#include <cstdint>
#include <memory>
#include "render/loader/GLLoader.h"
namespace td {
namespace render {
class VertexCache {
typedef std::vector<float> Vector;
typedef std::pair<Vector::iterator, Vector::iterator> ElementsIndex;
typedef std::pair<ElementsIndex, ElementsIndex> DataIndex;
private:
Vector m_Positions;
Vector m_Colors;
std::unordered_map<std::uint64_t, DataIndex> m_Indexes;
std::unique_ptr<GL::VertexArray> m_VertexArray;
public:
void addData(std::uint64_t index, std::vector<float> positions, std::vector<float> colors);
void removeData(std::uint64_t index);
void clear();
void updateVertexArray();
const GL::VertexArray& getVertexArray() const { return *m_VertexArray; }
bool isEmpty() const { return m_VertexArray == nullptr; }
};
} // namespace render
} // namespace td

View File

@@ -1,79 +0,0 @@
#pragma once
#include "game/World.h"
#include "render/Renderer.h"
#include "render/VertexCache.h"
#include "render/gui/TowerPlacePopup.h"
#include "render/gui/MobTooltip.h"
#include "render/gui/imgui/imgui.h"
#include <glm/glm.hpp>
namespace td {
namespace client {
class ClientGame;
} // namespace client
namespace render {
class WorldRenderer {
private:
client::ClientGame* m_Client;
Renderer* m_Renderer;
game::World* m_World;
std::unique_ptr<GL::VertexArray> m_WorldVao, m_MobVao, m_SelectTileVao;
glm::vec2 m_CamPos;
glm::vec2 m_CursorPos;
glm::vec2 m_HoldCursorPos;
glm::vec2 m_LastClicked;
float m_Zoom;
float m_CamSensibility = 1;
bool m_PopupOpened = false;
VertexCache m_TowersCache;
std::unique_ptr<gui::TowerPlacePopup> m_TowerPlacePopup;
std::unique_ptr<gui::MobTooltip> m_MobTooltip;
public:
WorldRenderer(game::World* world, client::ClientGame* client);
~WorldRenderer();
void loadModels();
void addTower(game::TowerPtr tower);
void removeTower(game::TowerPtr tower);
static ImVec4 getImGuiTeamColor(game::TeamColor color);
void update();
void render();
void setCamPos(float camX, float camY);
void moveCam(float relativeX, float relativeY, float aspectRatio);
void changeZoom(float zoom);
private:
void click();
void renderWorld() const;
void renderTowers() const;
void renderMobs() const;
void renderTileSelect() const;
void renderPopups();
void renderTowerUpgradePopup();
void renderMobTooltip() const;
void detectClick();
void detectMobHovering() const;
glm::vec2 getCursorWorldPos() const;
glm::vec2 getClickWorldPos() const;
void updateCursorPos();
};
} // namespace render
} // namespace td

View File

@@ -1,24 +0,0 @@
#pragma once
#include "SummonMenu.h"
namespace td {
namespace gui {
class GameMenu : public GuiWidget {
private:
std::unique_ptr<SummonMenu> m_SummonMenu;
public:
GameMenu(client::Client* client);
virtual void render();
private:
void showTPS();
void showStats();
void showPlayers();
void showLobbyProgress();
void showTeamSelection();
};
} // namespace gui
} // namespace td

View File

@@ -1,27 +0,0 @@
#pragma once
#include "GuiWidget.h"
#include <vector>
#include <memory>
namespace td {
namespace gui {
class GuiManager {
private:
std::vector<std::shared_ptr<GuiWidget>> m_Widgets;
public:
void renderWidgets(){
for(auto widget : m_Widgets){
widget->render();
}
}
void addWidgets(const std::shared_ptr<GuiWidget>& widget){
m_Widgets.push_back(std::move(widget));
}
};
} // namespace gui
} // namespace td

View File

@@ -1,37 +0,0 @@
#pragma once
#include "GuiWidget.h"
#include "imgui/imgui_filebrowser.h"
#include "game/server/Server.h"
#include <memory>
namespace td {
namespace gui {
class MainMenu : public GuiWidget {
private:
bool m_TriedToConnect = false;
bool m_TriedToCreate = false;
std::string m_ConnectAddress;
int m_ConnectPort;
int m_ServerPort = 25565;
std::string m_WorldFilePath;
imgui_addons::ImGuiFileBrowser m_FileDialog;
std::unique_ptr<server::Server> m_Server;
public:
MainMenu(client::Client* client);
~MainMenu();
virtual void render();
const server::Server* getServer() const { return m_Server.get(); }
private:
bool startServer();
};
} // namespace gui
} // namespace td

View File

@@ -1,26 +0,0 @@
#pragma once
#include "GuiWidget.h"
#include <array>
#include "game/Mobs.h"
namespace td {
namespace gui {
class SummonMenu : public GuiWidget{
private:
bool m_MenuOpened;
int m_ImageWidth = 100;
static constexpr int m_MobTypeCount = static_cast<std::size_t>(td::game::MobType::MOB_COUNT);
std::array<int, static_cast<std::size_t>(m_MobTypeCount)> m_Values;
public:
SummonMenu(client::Client* client);
virtual void render();
private:
void setSummonMax(int valueIndex);
};
} // namespace gui
} // namespace td

View File

@@ -1,59 +0,0 @@
/*
* TowerGUI.h
*
* Created on: 5 nov. 2020
* Author: Persson-dev
*/
#pragma once
#include <memory>
struct SDL_Window;
typedef void *SDL_GLContext;
namespace td {
namespace client {
class Client;
} // namespace client
namespace gui {
class MainMenu;
class GameMenu;
class FrameMenu;
class UpdateMenu;
} // namespace gui
namespace render {
class Renderer;
class TowerGui {
private:
SDL_Window* m_Window;
SDL_GLContext m_GlContext;
td::render::Renderer* m_Renderer;
std::unique_ptr<td::client::Client> m_Client;
std::unique_ptr<td::gui::MainMenu> m_MainMenu;
std::unique_ptr<td::gui::GameMenu> m_GameMenu;
std::unique_ptr<td::gui::FrameMenu> m_FrameMenu;
std::unique_ptr<td::gui::UpdateMenu> m_UpdateMenu;
public:
TowerGui(SDL_Window* wndow, SDL_GLContext glContext, td::render::Renderer* renderer);
~TowerGui();
void render();
private:
void initWidgets();
void tick();
void beginFrame();
void endFrame();
};
} // namespace render
} // namespace td

View File

@@ -1,28 +0,0 @@
#pragma once
#include "GuiWidget.h"
#include <glm/glm.hpp>
namespace td {
namespace gui {
class TowerPlacePopup : public GuiWidget {
private:
glm::vec2 m_ClickWorldPos;
public:
TowerPlacePopup(client::Client* client);
virtual void render();
void setClickPos(const glm::vec2& worldPos);
private:
static constexpr float m_TowerPopupTileWidth = 250.0f;
static constexpr float m_TowerPopupTileHeight = 250.0f;
static constexpr float m_PlaceTowerButtonWidth = 200.0f;
static constexpr float m_PlaceTowerButtonHeight = 45.0f;
};
} // namespace gui
} // namespace td

View File

@@ -1,29 +0,0 @@
#pragma once
#include "GuiWidget.h"
#include "misc/Updater.h"
#include <future>
namespace td {
namespace gui {
class UpdateMenu : public GuiWidget {
private:
bool m_Opened;
std::string m_Error;
utils::Updater m_Updater;
std::shared_future<bool> m_UpdateAvailable;
public:
UpdateMenu(client::Client* client);
virtual void render();
private:
void checkUpdates();
bool isUpdateChecked();
void renderErrorPopup();
};
} // namespace gui
} // namespace td

View File

@@ -1,25 +0,0 @@
#pragma once
#include "game/World.h"
#include "GLLoader.h"
namespace td {
namespace render {
namespace WorldLoader {
struct RenderData {
std::vector<float> positions;
std::vector<float> colors;
};
GL::VertexArray loadMobModel();
GL::VertexArray loadWorldModel(const td::game::World* world);
GL::VertexArray loadTileSelectModel();
RenderData loadTowerModel(game::TowerPtr tower);
} // namespace WorldLoader
} // namespace render
} // namespace td

View File

@@ -1,18 +0,0 @@
#pragma once
#include "ShaderProgram.h"
class EntityShader : public ShaderProgram {
private:
unsigned int location_cam = 0, location_zoom = 0, location_aspect_ratio = 0, location_translation = 0, location_viewtype = 0;
protected:
void getAllUniformLocation();
public:
EntityShader();
void loadShader();
void setCamPos(const glm::vec2& camPos);
void setZoom(float zoom);
void setAspectRatio(float aspectRatio);
void setModelPos(const glm::vec2& modelPos);
void setIsometricView(float isometric);
};

View File

@@ -1,44 +0,0 @@
/*
* ShaderProgram.h
*
* Created on: 31 janv. 2020
* Author: simon
*/
#ifndef RENDER_SHADERS_SHADERPROGRAM_H_
#define RENDER_SHADERS_SHADERPROGRAM_H_
#include <string>
#include <glm/glm.hpp>
#include "render/GL.h"
class ShaderProgram {
public:
ShaderProgram();
virtual ~ShaderProgram();
void start() const;
void stop() const;
void loadProgramFile(const std::string& vertexFile, const std::string& fragmentFile);
void loadProgram(const std::string& vertexSource, const std::string& fragmentSource);
protected:
virtual void getAllUniformLocation() = 0;
int getUniformLocation(const std::string& uniformName)const;
void loadFloat(const int location, const float value)const;
void loadInt(const int& location, const int& value)const;
void loadVector(const int& location, const glm::vec2& vector)const;
void loadVector(const int& location, const glm::vec3& vector)const;
void loadVector(const int& location, const glm::vec4& vector)const;
void loadBoolean(const int& location, const bool& value)const;
void loadMatrix(const int& location, const glm::mat4& matrix);
void cleanUp() const;
private:
unsigned int programID;
unsigned int vertexShaderID;
unsigned int fragmentShaderID;
int loadShaderFromFile(const std::string& file, GLenum type);
int loadShader(const std::string& source, GLenum type);
};
#endif /* RENDER_SHADERS_SHADERPROGRAM_H_ */

View File

@@ -1,27 +0,0 @@
/*
* GameShader.h
*
* Created on: 4 nov. 2020
* Author: simon
*/
#ifndef RENDER_SHADERS_GAMESHADER_H_
#define RENDER_SHADERS_GAMESHADER_H_
#include "ShaderProgram.h"
class WorldShader : public ShaderProgram {
private:
unsigned int location_cam = 0, location_zoom = 0, location_aspect_ratio = 0, location_viewtype = 0;
protected:
void getAllUniformLocation();
public:
WorldShader();
void loadShader();
void setCamPos(const glm::vec2& camPos);
void setZoom(float zoom);
void setAspectRatio(float aspectRatio);
void setIsometricView(float isometric);
};
#endif /* RENDER_SHADERS_GAMESHADER_H_ */

36
include/server/Lobby.h Normal file
View File

@@ -0,0 +1,36 @@
#pragma once
#include <vector>
#include "td/misc/Time.h"
namespace td {
namespace server {
class Server;
class Lobby {
private:
Server* m_Server;
bool m_LobbyOpened = false;
std::uint64_t m_StartTimerTime = 0;
std::vector<std::uint8_t> m_Players;
utils::AutoTimer m_Timer;
public:
Lobby(Server* server);
void OnPlayerJoin(std::uint8_t playerID);
void OnPlayerLeave(std::uint8_t playerID);
void OpenLobby();
void SendTimeRemaining();
void Tick();
//static constexpr int LobbyWaitingTime = 2 * 60 * 1000; // in millis
static constexpr int LobbyWaitingTime = 5 * 1000; // in millis
};
} // namespace server
} // namespace td

112
include/server/Server.h Normal file
View File

@@ -0,0 +1,112 @@
#pragma once
#include <map>
#include <thread>
#include "td/network/TCPListener.h"
#include "td/protocol/Protocol.h"
#include "td/protocol/PacketDispatcher.h"
#include "td/protocol/PacketHandler.h"
#include "server/game/ServerGame.h"
#include "server/ServerConnexion.h"
#include "server/Lobby.h"
#define SERVER_TPS 20
#define SERVER_TICK 1000 / SERVER_TPS
namespace td {
namespace server {
typedef std::map<std::uint8_t, ServerConnexion> ConnexionMap;
class TickCounter {
private:
float m_TPS;
float m_MSPT;
std::uint64_t m_LastTPSTime;
std::uint8_t m_TickCount;
public:
TickCounter() {}
void Reset() {
m_TPS = SERVER_TPS;
m_LastTPSTime = utils::GetTime();
m_TickCount = 0;
}
bool Update() { // return true when tps is updated
m_TickCount++;
if (m_TickCount >= SERVER_TPS) {
std::uint64_t timeElapsedSinceLast20Ticks = td::utils::GetTime() - m_LastTPSTime;
m_TPS = static_cast<float>(SERVER_TPS) / static_cast<float>(timeElapsedSinceLast20Ticks / 1000.0f);
m_TickCount = 0;
m_LastTPSTime = td::utils::GetTime();
return true;
}
return false;
}
float GetTPS() const { return m_TPS; }
float GetMSPT() const { return m_MSPT; }
void SetMSPT(float mspt) { m_MSPT = mspt; }
};
class Server {
private:
network::TCPListener m_Listener;
ConnexionMap m_Connections;
ServerGame m_Game{ this };
Lobby m_Lobby{ this };
TickCounter m_TickCounter;
std::thread m_Thread;
bool m_ServerRunning;
public:
Server();
virtual ~Server();
bool Start(std::uint16_t port, bool blocking);
void Stop(); // force the server to stop
void Close(); // at the end of a game
void Restart(); // go back to lobby state
bool LoadMap(const std::string& worldFilePath);
bool IsMapLoaded();
void RemoveConnexion(std::uint8_t connexionID);
void BroadcastPacket(const protocol::Packet* packet);
float GetMSPT() const { return m_TickCounter.GetMSPT(); }
float GetTPS() const { return m_TickCounter.GetTPS(); }
bool IsRunning() { return m_ServerRunning; }
const ServerGame& GetGame() const { return m_Game; }
ServerGame& GetGame() { return m_Game; }
const Lobby& GetLobby() const { return m_Lobby; }
const ConnexionMap& GetConnexions() const { return m_Connections; }
ConnexionMap& GetConnexions() { return m_Connections; }
const game::PlayerList& GetPlayers() const { return m_Game.GetPlayers(); }
game::PlayerList& GetPlayers() { return m_Game.GetPlayers(); }
private:
void Accept();
void UpdateSockets();
void Clean();
void StartThread();
void StopThread();
void ServerLoop();
void Tick(std::uint64_t delta);
void OnPlayerJoin(std::uint8_t id);
void OnPlayerLeave(std::uint8_t id);
};
} // namespace server
} // namespace td

View File

@@ -0,0 +1,59 @@
#pragma once
#include "td/network/TCPSocket.h"
#include "td/protocol/PacketHandler.h"
#include "td/protocol/PacketDispatcher.h"
#include "td/game/Player.h"
#include "td/network/Connexion.h"
namespace td {
namespace server {
class Server;
struct KeepAlive {
std::uint64_t keepAliveID = 0;
std::uint64_t sendTime;
bool recievedResponse = false;
};
class ServerConnexion : public protocol::Connexion {
private:
Server* m_Server = nullptr;
std::uint8_t m_ID;
KeepAlive m_KeepAlive;
game::Player* m_Player;
public:
ServerConnexion();
ServerConnexion(network::TCPSocket& socket, std::uint8_t id);
ServerConnexion(ServerConnexion&& move);
virtual ~ServerConnexion();
void SetServer(Server* server);
virtual void HandlePacket(const protocol::PlayerLoginPacket* packet) override;
virtual void HandlePacket(const protocol::KeepAlivePacket* packet) override;
virtual void HandlePacket(const protocol::SelectTeamPacket* packet) override;
virtual void HandlePacket(const protocol::DisconnectPacket* packet) override;
virtual void HandlePacket(const protocol::PlaceTowerPacket* packet) override;
virtual void HandlePacket(const protocol::SendMobsPacket* packet) override;
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet) override;
std::uint8_t GetID() const { return m_ID; }
const game::Player* GetPlayer() const { return m_Player; }
game::Player* GetPlayer() { return m_Player; }
virtual bool UpdateSocket();
REMOVE_COPY(ServerConnexion);
private:
void RegisterHandlers();
void CheckKeepAlive();
void SendKeepAlive();
void InitConnection();
};
} // namespace server
} // namespace td

View File

@@ -0,0 +1,48 @@
#pragma once
#include "td/game/BaseGame.h"
#include "td/misc/Time.h"
#include "ServerWorld.h"
namespace td {
namespace server {
class Server;
class ServerGame : public game::Game, public game::GameListener {
private:
Server* m_Server;
ServerWorld m_ServerWorld;
utils::AutoTimer m_GoldMineTimer;
utils::AutoTimer m_MobStatesTimer;
utils::CooldownTimer m_EndGameCooldown;
public:
ServerGame(Server* server);
~ServerGame() {}
ServerWorld* GetServerWorld() { return &m_ServerWorld; }
virtual void Tick(std::uint64_t delta);
virtual void Reset() override;
void StartGame();
// GameListener
virtual void OnGameStateUpdate(game::GameState newState) override;
virtual void OnGameBegin() override;
virtual void OnGameEnd() override;
virtual void OnGameClose() override;
virtual void OnPlayerJoin(game::PlayerID id) override;
virtual void OnPlayerLeave(game::PlayerID id) override;
private:
void BalanceTeams();
void InitPlayerStats();
void UpdateMobStates();
void UpdateGoldMines();
void UpdatePlayerStats();
};
} // namespace game
} // namespace td

View File

@@ -0,0 +1,30 @@
#pragma once
#include "td/game/World.h"
namespace td {
namespace server {
class Server;
class ServerGame;
class ServerWorld : public game::World {
private:
game::MobID m_CurrentMobID;
game::TowerID m_CurrentTowerID;
Server* m_Server;
public:
static constexpr float MobSpawnBorder = 0.01f;
ServerWorld(Server* server, ServerGame* game);
void SpawnMobs(game::MobType type, std::uint8_t level, game::PlayerID sender, std::uint8_t count);
game::TowerPtr PlaceTowerAt(game::TowerType type, std::int32_t x, std::int32_t y, game::PlayerID builder);
virtual void OnMobDie(game::Mob* mob) override;
virtual void OnMobCastleDamage(game::Mob* damager, game::TeamCastle* enemyCastle, float damage) override;
};
} // namespace server
} // namespace td

151
include/td/Defines.h Normal file
View File

@@ -0,0 +1,151 @@
#pragma once
#include <cstdint>
#define SAFE_CHECK(expr) if(!(expr)) return
namespace td {
static constexpr float PI = 3.141592653f;
template<typename T>
struct Vec2 {
union {
T x;
T r;
};
union {
T y;
T g;
};
constexpr Vec2(T X = 0, T Y = 0) : x(X), y(Y) {}
};
template<typename T>
inline bool operator==(const Vec2<T>& vec2, const Vec2<T>& other) {
return vec2.x == other.x && vec2.y == other.y;
}
template<typename T>
struct Vec3 {
union {
T x;
T r;
};
union {
T y;
T g;
};
union {
T z;
T b;
};
constexpr Vec3(T X = 0, T Y = 0, T Z = 0) : x(X), y(Y), z(Z) {}
};
template<typename T>
inline bool operator==(const Vec3<T>& vec3, const Vec3<T>& other) {
return vec3.x == other.x && vec3.y == other.y && vec3.z == other.z;
}
template<typename T>
struct Vec4 {
union {
T x;
T r;
};
union {
T y;
T g;
};
union {
T z;
T b;
};
union {
T w;
T a;
};
constexpr Vec4(Vec3<T> vec, T W = 1) : x(vec.x), y(vec.y), z(vec.z), w(W) {}
constexpr Vec4(T X = 0, T Y = 0, T Z = 0, T W = 0) : x(X), y(Y), z(Z), w(W) {}
};
template<typename T>
inline bool operator==(const Vec4<T>& vec4, const Vec4<T>& other) {
return vec4.x == other.x && vec4.y == other.y && vec4.z == other.z && vec4.w = other.w;
}
using Vec2i = Vec2<int>;
using Vec2u = Vec2<unsigned int>;
using Vec2f = Vec2<float>;
using Vec2d = Vec2<double>;
using Vec3i = Vec3<int>;
using Vec3u = Vec3<unsigned int>;
using Vec3f = Vec3<float>;
using Vec3d = Vec3<double>;
using Vec4i = Vec4<int>;
using Vec4u = Vec4<unsigned int>;
using Vec4f = Vec4<float>;
using Vec4d = Vec4<double>;
using Color = Vec3<unsigned char>;
template<typename T>
struct Mat4 {
static const std::size_t MATRIX_SIZE = 4;
T x0, x1, x2, x3;
T y0, y1, y2, y3;
T z0, z1, z2, z3;
T w0, w1, w2, w3;
T operator[] (std::size_t offset) const {
return reinterpret_cast<const T*>(this)[offset];
}
T& operator[] (std::size_t offset) {
return reinterpret_cast<T*>(this)[offset];
}
T* data() {
return reinterpret_cast<T*>(this);
}
const T* data() const{
return reinterpret_cast<const T*>(this);
}
T at(std::size_t row, std::size_t column) const {
return operator[](row * MATRIX_SIZE + column);
}
T& at(std::size_t row, std::size_t column) {
return operator[](row * MATRIX_SIZE + column);
}
};
typedef Mat4<float> Mat4f;
typedef Mat4<int> Mat4i;
typedef Mat4<double> Mat4d;
template<typename T>
inline bool operator==(const Mat4<T>& mat, const Mat4<T>& other) {
return mat.x0 == other.x0 && mat.y0 == other.y0 && mat.z0 == other.z0 && mat.w0 == other.w0 &&
mat.x1 == other.x1 && mat.y1 == other.y1 && mat.z1 == other.z1 && mat.w1 == other.w1 &&
mat.x2 == other.x2 && mat.y2 == other.y2 && mat.z2 == other.z2 && mat.w2 == other.w2 &&
mat.x3 == other.x3 && mat.y3 == other.y3 && mat.z3 == other.z3 && mat.w3 == other.w3;
}
} // namespace td

View File

@@ -0,0 +1,75 @@
#pragma once
#include "td/game/Team.h"
#include "td/game/World.h"
#include "td/game/Player.h"
namespace td {
namespace game {
enum class GameState : std::uint8_t {
Lobby,
Game,
EndGame,
Disconnected,
Closed
};
typedef std::map<std::uint8_t, Player> PlayerList;
class GameListener {
public:
virtual void OnPlayerJoin(PlayerID player) {}
virtual void OnPlayerLeave(PlayerID player) {}
virtual void OnGameStateUpdate(GameState newState) {}
virtual void OnGameBegin() {}
virtual void OnGameEnd() {}
virtual void OnGameClose() {}
};
typedef utils::ObjectNotifier<GameListener> GameNotifier;
class Game : public GameNotifier {
protected:
World* m_World;
TeamList m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} };
GameState m_GameState = GameState::Lobby;
PlayerList m_Players;
public:
Game(World* world);
virtual ~Game();
virtual void Tick(std::uint64_t delta);
virtual void Reset();
Team& GetRedTeam() { return m_Teams[static_cast<std::uint8_t>(TeamColor::Red)]; }
const Team& GetRedTeam() const { return m_Teams[static_cast<std::uint8_t>(TeamColor::Red)]; }
Team& GetBlueTeam() { return m_Teams[static_cast<std::uint8_t>(TeamColor::Blue)]; }
const Team& GetBlueTeam() const { return m_Teams[static_cast<std::uint8_t>(TeamColor::Red)]; }
Team& GetTeam(TeamColor team) { return m_Teams[static_cast<std::uint8_t>(team)]; }
const Team& GetTeam(TeamColor team) const { return m_Teams[static_cast<std::uint8_t>(team)]; }
GameState GetGameState() const { return m_GameState; }
void SetGameState(GameState gameState) { m_GameState = gameState; };
const World* GetWorld() const { return m_World; }
World* GetWorld() { return m_World; }
const PlayerList& GetPlayers() const { return m_Players; }
PlayerList& GetPlayers() { return m_Players; }
const Player* GetPlayerById(PlayerID id) const;
Player* GetPlayerById(PlayerID id);
const TeamList& GetTeams() const { return m_Teams; }
void RemovePlayer(PlayerID pId);
};
} // namespace game
} // namespace td

View File

@@ -10,12 +10,12 @@
namespace GameManager { namespace GameManager {
void render(); void Render();
void init(); void Init();
void destroy(); void Destroy();
void tick(); void Tick();
void startServer(); void StartServer();
} }

262
include/td/game/Mobs.h Normal file
View File

@@ -0,0 +1,262 @@
#pragma once
#include "td/Defines.h"
#include "Towers.h"
#include "Types.h"
#include "Team.h"
#include "td/misc/ObjectNotifier.h"
#include <vector>
#include <memory>
namespace td {
namespace game {
struct WalkableTile;
enum class EffectType : std::uint8_t {
Slowness = 0,
Stun,
Fire,
Poison,
Heal,
};
enum class MobType : std::uint8_t {
Zombie = 0,
Spider,
Skeleton,
Pigman,
Creeper,
Silverfish,
Blaze,
Witch,
Slime,
Giant,
MOB_COUNT
};
typedef std::uint32_t MobID;
typedef std::uint8_t MobLevel;
typedef std::vector<TowerType> TowerImmunities;
typedef std::vector<EffectType> EffectImmunities;
class MobStats {
private:
float m_Damage;
float m_Speed;
Vec2f m_Size;
std::uint16_t m_MoneyCost;
std::uint16_t m_ExpCost;
std::uint16_t m_MaxLife;
std::uint16_t m_ExpReward;
public:
MobStats(float damage, float speed, Vec2f size, std::uint16_t moneyCost,
std::uint16_t expCost, std::uint16_t expReward,
std::uint16_t maxLife) : m_Damage(damage), m_Speed(speed),
m_Size(size), m_MoneyCost(moneyCost), m_ExpCost(expCost),
m_MaxLife(maxLife), m_ExpReward(expReward) {
}
float GetDamage() const { return m_Damage; }
float GetMovementSpeed() const { return m_Speed; }
const Vec2f& GetSize() const { return m_Size; }
std::uint16_t GetMoneyCost() const { return m_MoneyCost; }
std::uint16_t GetExpCost() const { return m_ExpCost; }
std::uint16_t GetExpReward() const { return m_ExpReward; }
std::uint16_t GetMaxLife() const { return m_MaxLife; }
};
struct EffectDuration {
EffectType type;
float duration; // in seconds
Tower* tower; // the tower that gived the effect
};
const MobStats* GetMobStats(MobType type, std::uint8_t level);
const TowerImmunities& GetMobTowerImmunities(MobType type, std::uint8_t level);
const EffectImmunities& GetMobEffectImmunities(MobType type, std::uint8_t level);
class Mob : public utils::shape::Rectangle {
protected:
float m_Health;
private:
MobID m_ID;
PlayerID m_Sender;
MobLevel m_Level;
Direction m_Direction;
std::vector<EffectDuration> m_Effects;
const Tower* m_LastDamage; // the last tower that damaged the mob
float m_HitCooldown;
utils::Timer m_EffectFireTimer;
utils::Timer m_EffectPoisonTimer;
utils::Timer m_EffectHealTimer;
TeamCastle* m_CastleTarget;
utils::CooldownTimer m_AttackTimer;
public:
Mob(MobID id, MobLevel level, PlayerID sender) : m_ID(id), m_Sender(sender), m_Level(level),
m_HitCooldown(0), m_EffectFireTimer(1000), m_EffectPoisonTimer(1000),
m_EffectHealTimer(1000), m_CastleTarget(nullptr), m_AttackTimer(1000) {
}
virtual MobType GetType() const = 0;
virtual void Tick(std::uint64_t delta, World* world);
virtual bool OnDeath(World* world) { return true; }
MobID GetMobID() const { return m_ID; }
const TowerImmunities& GetTowerImmunities() const { return GetMobTowerImmunities(GetType(), m_Level); }
const EffectImmunities& GetEffectImmunities() const { return GetMobEffectImmunities(GetType(), m_Level); }
PlayerID GetSender() const { return m_Sender; }
MobLevel GetLevel() const { return m_Level; }
const MobStats* GetStats() const { return GetMobStats(GetType(), m_Level); }
void SetHealth(float newHealth) { m_Health = newHealth; }
float GetHealth() const { return m_Health; }
bool IsDead() const { return m_Health <= 0; }
bool IsAlive() const { return m_Health > 0; }
const Tower* GetLastDamageTower() { return m_LastDamage; }
bool HasReachedEnemyCastle() { return m_CastleTarget != nullptr; }
void Damage(float dmg, const Tower* damager) {
m_Health = std::max(0.0f, m_Health - dmg);
m_LastDamage = damager;
m_HitCooldown = 0.1;
}
void Heal(float heal) {
m_Health = std::min(static_cast<float>(GetStats()->GetMaxLife()), m_Health + heal);
}
void SetMobReachedCastle(TeamCastle* castle) { m_CastleTarget = castle; } // used when mob is in front of the castle
bool IsImmuneTo(TowerType type);
bool IsImmuneTo(EffectType type);
void AddEffect(EffectType type, float durationSec, Tower* tower);
bool HasEffect(EffectType type);
bool HasTakenDamage() { return m_HitCooldown > 0; }
float GetTileX() { return GetCenterX() - static_cast<float>(static_cast<std::int32_t>(GetCenterX())); } // returns a float between 0 and 1 excluded
float GetTileY() { return GetCenterY() - static_cast<float>(static_cast<std::int32_t>(GetCenterY())); } // returns a float between 0 and 1 excluded
Direction GetDirection() const { return m_Direction; }
void SetDirection(Direction dir) { m_Direction = dir; }
protected:
void InitMob() {
m_Health = static_cast<float>(GetStats()->GetMaxLife());
SetSize(GetStats()->GetSize().x, GetStats()->GetSize().y);
}
private:
void UpdateEffects(std::uint64_t delta, World* world);
void AttackCastle(std::uint64_t delta, World* world);
void Move(std::uint64_t delta, World* world);
void Walk(std::uint64_t delta, World* world);
void MoveBack(const TeamCastle& castle, World* world);
void ChangeDirection(const WalkableTile& tile, World* world);
bool IsTouchingCastle(const TeamCastle& castle) const;
EffectDuration& GetEffect(EffectType type);
};
typedef std::shared_ptr<Mob> MobPtr;
class Zombie : public Mob {
public:
Zombie(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
virtual MobType GetType() const { return MobType::Zombie; }
};
class Spider : public Mob {
public:
Spider(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
virtual MobType GetType() const { return MobType::Spider; }
};
class Skeleton : public Mob {
public:
Skeleton(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
virtual MobType GetType() const { return MobType::Skeleton; }
};
class PigMan : public Mob {
public:
PigMan(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
virtual MobType GetType() const { return MobType::Pigman; }
};
class Creeper : public Mob {
public:
Creeper(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
virtual MobType GetType() const { return MobType::Creeper; }
};
class Silverfish : public Mob {
public:
Silverfish(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
virtual MobType GetType() const { return MobType::Silverfish; }
};
class Blaze : public Mob {
public:
Blaze(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
virtual MobType GetType() const { return MobType::Blaze; }
};
class Witch : public Mob {
public:
Witch(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
virtual MobType GetType() const { return MobType::Witch; }
};
class Slime : public Mob {
public:
Slime(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
virtual MobType GetType() const { return MobType::Slime; }
};
class Giant : public Mob {
public:
Giant(MobID id, std::uint8_t level, PlayerID sender) : Mob(id, level, sender) { InitMob(); }
virtual MobType GetType() const { return MobType::Giant; }
};
namespace MobFactory {
MobPtr CreateMob(MobID id, MobType type, std::uint8_t level, PlayerID sender);
std::string GetMobName(MobType type);
}
class MobListener {
public:
virtual void OnMobSpawn(Mob* mob) {}
virtual void OnMobDie(Mob* mob) {}
virtual void OnMobDamage(Mob* target, float damage, Tower* damager) {}
virtual void OnMobTouchCastle(Mob* damager, TeamCastle* enemyCastle) {}
virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) {}
};
typedef utils::ObjectNotifier<MobListener> MobNotifier;
} // namespace game
} // namespace td

51
include/td/game/Player.h Normal file
View File

@@ -0,0 +1,51 @@
#pragma once
#include <string>
#include "td/game/Team.h"
#include "td/game/PlayerUpgrades.h"
namespace td {
namespace game {
class Player {
private:
TeamColor m_TeamColor;
PlayerUpgrades m_Upgrades;
std::uint32_t m_Gold;
std::uint32_t m_Exp;
std::string m_Name;
PlayerID m_ID;
public:
Player(std::uint8_t id = 0) : m_TeamColor(TeamColor::None), m_Gold(0), m_Exp(0), m_ID(id) {}
const std::string& GetName() const { return m_Name; }
void SetName(const std::string& name) { m_Name = name; }
TeamColor GetTeamColor() const { return m_TeamColor; }
void SetTeamColor(TeamColor teamColor) { m_TeamColor = teamColor; }
std::uint32_t GetGold() const { return m_Gold; }
void SetGold(std::uint32_t gold) { m_Gold = gold; }
void AddGold(std::uint32_t gold) { m_Gold += gold; }
void RemoveGold(std::uint32_t gold) { m_Gold -= gold; }
std::uint32_t GetExp() const { return m_Exp; }
void SetExp(std::uint32_t exp) { m_Exp = exp; }
void AddExp(std::uint32_t exp) { m_Exp += exp; }
void RemoveExp(std::uint32_t exp) { m_Exp -= exp; }
const PlayerUpgrades& getUpgrades() const { return m_Upgrades; }
PlayerUpgrades& getUpgrades() { return m_Upgrades; }
bool HasEnoughGold(std::uint32_t gold) const { return m_Gold >= gold; }
bool HasEnoughExp(std::uint32_t exp) const { return m_Exp >= exp; }
PlayerID GetID() const { return m_ID; }
};
} // namespace game
} // namespace td

View File

@@ -0,0 +1,34 @@
#pragma once
#include "Mobs.h"
namespace td {
namespace game {
class PlayerUpgrades {
private:
std::uint8_t m_ClickerLevel;
std::uint8_t m_GoldPerSecond;
std::array<std::uint8_t, static_cast<std::size_t>(MobType::MOB_COUNT)> m_MobsUpgradeLevel;
public:
static const int MAX_MOB_LEVEL = 5;
static const int MAX_CLICKER_LEVEL = 3;
PlayerUpgrades() : m_ClickerLevel(1), m_GoldPerSecond(5) {}
std::uint8_t GetClickerLevel() const { return m_ClickerLevel; }
std::uint8_t GetMobUpgradeLevel(MobType mob) const { return m_MobsUpgradeLevel.at(static_cast<std::size_t>(mob)); }
std::uint8_t GetGoldPerSecond() const { return m_GoldPerSecond; }
void UpgradeMob(MobType mob) {
std::uint8_t& mobLevel = m_MobsUpgradeLevel.at(static_cast<std::size_t>(mob));
mobLevel = std::min(mobLevel + 1, MAX_MOB_LEVEL);
}
void UpgradeClicker() { m_ClickerLevel = std::min(m_ClickerLevel + 1, MAX_CLICKER_LEVEL); }
void SetGoldPerSecond(std::uint8_t goldPerSecond) { m_GoldPerSecond = goldPerSecond; }
};
} // namespace game
} // namespace td

93
include/td/game/Team.h Normal file
View File

@@ -0,0 +1,93 @@
#pragma once
#include "Types.h"
#include "td/misc/Shapes.h"
#include <vector>
#include <memory>
#include <cmath>
namespace td {
namespace game {
class Player;
enum class TeamColor : std::int8_t {
None = -1,
Red,
Blue
};
class Spawn : public utils::shape::Rectangle {
private:
Direction m_Direction;
public:
Spawn() {
SetWidth(5);
SetHeight(5);
}
Direction GetDirection() const { return m_Direction; }
void SetDirection(Direction direction) { m_Direction = direction; }
};
class Team;
class TeamCastle : public utils::shape::Rectangle {
private:
const Team* m_Team;
float m_Life;
public:
static constexpr int CastleMaxLife = 1000;
TeamCastle(const Team* team) : m_Team(team), m_Life(CastleMaxLife) {
SetWidth(5);
SetHeight(5);
}
TeamCastle() : TeamCastle(nullptr) {}
float GetLife() const { return m_Life; }
const Team* GetTeam() const { return m_Team; }
void SetTeam(const Team* team) { m_Team = team; }
void SetLife(float life) { m_Life = life; }
void Damage(float damage) { m_Life = std::max(0.0f, m_Life - damage); }
void SetShape(utils::shape::Rectangle rect) {
SetCenter(rect.GetCenter());
SetSize(rect.GetSize());
}
};
class Team {
private:
std::vector<Player*> m_Players;
TeamColor m_Color;
Spawn m_Spawn;
TeamCastle m_TeamCastle;
public:
Team(TeamColor color);
void AddPlayer(Player* newPlayer);
void RemovePlayer(const Player* player);
void ClearPlayers();
TeamColor GetColor() const;
const Spawn& GetSpawn() const { return m_Spawn; }
Spawn& GetSpawn() { return m_Spawn; }
const TeamCastle& GetCastle() const { return m_TeamCastle; }
TeamCastle& GetCastle() { return m_TeamCastle; }
std::uint8_t GetPlayerCount() const;
};
typedef std::array<Team, 2> TeamList;
} // namespace game
} // namespace td

266
include/td/game/Towers.h Normal file
View File

@@ -0,0 +1,266 @@
#pragma once
#include <string>
#include <memory>
#include "td/misc/Time.h"
#include "td/misc/Shapes.h"
#include "td/game/Types.h"
namespace td {
namespace game {
class World;
class Mob;
typedef std::shared_ptr<Mob> MobPtr;
enum class TowerType : std::uint8_t {
Archer = 0,
Ice,
Sorcerer,
Zeus,
Mage,
Artillery,
Quake,
Poison,
Leach,
Turret,
Necromancer,
TowerCount
};
enum class TowerSize : std::uint8_t {
Little = 3, // 3x3
Big = 5, // 5x5
};
enum class TowerPath : std::uint8_t {
Top = 0,
Base, // Base Path
Bottom
};
class TowerStats {
private:
float m_Rate;
float m_Damage;
std::uint8_t m_Range;
public:
TowerStats(float rate, float damage, std::uint8_t range) : m_Rate(rate), m_Damage(damage),
m_Range(range) {
}
float GetDamageRate() const { return m_Rate; }
float GetDamage() const { return m_Damage; }
std::uint8_t GetRange() const { return m_Range; }
};
class TowerLevel {
private:
// 1, 2, 3, 4
std::uint8_t m_Level : 3;
// 0 : base path 1 : top path (if there is bottom path) 2 : bottom path (if there is top path)
TowerPath m_Path : 2;
public:
TowerLevel() : m_Level(1), m_Path(TowerPath::Base) {}
TowerLevel(std::uint8_t level, TowerPath path) : m_Level(level), m_Path(path) {}
std::uint8_t GetLevel() const { return m_Level; }
TowerPath GetPath() const { return m_Path; }
void SetLevel(std::uint8_t level) { m_Level = level; }
void SetPath(TowerPath path) { m_Path = path; }
// operator to sort maps
friend bool operator<(const TowerLevel& level, const TowerLevel& other) {
return level.GetLevel() + static_cast<std::uint8_t>(level.GetPath()) * 4 <
other.GetLevel() + static_cast<std::uint8_t>(other.GetPath()) * 4;
}
};
const TowerStats* GetTowerStats(TowerType type, TowerLevel level);
typedef std::uint16_t TowerID;
class Tower : public utils::shape::Circle {
private:
TowerID m_ID;
TowerType m_Type;
TowerLevel m_Level{};
PlayerID m_Builder;
protected:
utils::CooldownTimer m_Timer;
public:
Tower(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder) : utils::shape::Circle(x + 0.5f, y + 0.5f, 0), m_ID(id), m_Type(type), m_Builder(builder),
m_Timer(GetStats()->GetDamageRate() * 1000) { // converting seconds to millis
SetRadius(GetStats()->GetRange());
}
virtual TowerType GetType() const = 0;
virtual TowerSize GetSize() const = 0;
virtual void Tick(std::uint64_t delta, World* world) = 0;
void Upgrade(std::uint8_t level, TowerPath path) {
m_Level.SetLevel(level);
m_Level.SetPath(path);
m_Timer.SetCooldown(GetStats()->GetDamageRate() * 1000); // converting seconds to millis
m_Timer.Reset();
SetRadius(GetStats()->GetRange());
}
std::uint16_t GetID() const { return m_ID; }
const TowerLevel& GetLevel() const { return m_Level; }
const TowerStats* GetStats() const { return GetTowerStats(m_Type, m_Level); }
PlayerID GetBuilder() const { return m_Builder; }
bool IsMobInRange(MobPtr mob);
};
typedef std::shared_ptr<Tower> TowerPtr;
namespace TowerFactory {
TowerPtr CreateTower(TowerType type, TowerID id, std::int32_t x, std::int32_t y, PlayerID builder);
std::string GetTowerName(TowerType type);
} // namespace TowerFactory
class TowerInfo {
private:
std::string m_Name, m_Description;
bool m_IsBigTower;
public:
TowerInfo(std::string&& name, std::string&& description, bool big) : m_Name(std::move(name)),
m_Description(std::move(description)), m_IsBigTower(big) {
}
const std::string& GetName() const { return m_Name; }
const std::string& GetDescription() const { return m_Description; }
bool IsBigTower() const { return m_IsBigTower; }
};
const TowerInfo& GetTowerInfo(TowerType type);
// ---------- Little Towers ----------
class LittleTower : public Tower {
public:
LittleTower(TowerID id, TowerType type, std::uint16_t x, std::uint16_t y, PlayerID builder) : Tower(id, type, x, y, builder) {}
virtual TowerSize GetSize() const { return TowerSize::Little; }
virtual TowerType GetType() const = 0;
virtual void Tick(std::uint64_t delta, World* world) = 0;
};
class ArcherTower : public LittleTower {
public:
ArcherTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
constexpr static float ExplosionRadius = 1.5f;
constexpr static float FireDurationSec = 10.0f;
virtual TowerType GetType() const { return TowerType::Archer; }
virtual void Tick(std::uint64_t delta, World* world);
};
class IceTower : public LittleTower {
public:
IceTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
virtual TowerType GetType() const { return TowerType::Ice; }
virtual void Tick(std::uint64_t delta, World* world);
};
class MageTower : public LittleTower {
public:
MageTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
virtual TowerType GetType() const { return TowerType::Mage; }
virtual void Tick(std::uint64_t delta, World* world);
};
class PoisonTower : public LittleTower {
public:
PoisonTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
virtual TowerType GetType() const { return TowerType::Poison; }
virtual void Tick(std::uint64_t delta, World* world);
};
class QuakeTower : public LittleTower {
public:
QuakeTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
virtual TowerType GetType() const { return TowerType::Quake; }
virtual void Tick(std::uint64_t delta, World* world);
};
class ArtilleryTower : public LittleTower {
public:
ArtilleryTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
virtual TowerType GetType() const { return TowerType::Artillery; }
virtual void Tick(std::uint64_t delta, World* world);
};
class SorcererTower : public LittleTower {
public:
SorcererTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
virtual TowerType GetType() const { return TowerType::Sorcerer; }
virtual void Tick(std::uint64_t delta, World* world);
};
class ZeusTower : public LittleTower {
public:
ZeusTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : LittleTower(id, GetType(), x, y, builder) {}
virtual TowerType GetType() const { return TowerType::Zeus; }
virtual void Tick(std::uint64_t delta, World* world);
};
// ---------- Big Towers ----------
class BigTower : public Tower {
public:
BigTower(TowerID id, TowerType type, std::uint16_t x, std::uint16_t y, PlayerID builder) : Tower(id, type, x, y, builder) {}
virtual TowerSize GetSize() const { return TowerSize::Big; }
virtual TowerType GetType() const = 0;
virtual void Tick(std::uint64_t delta, World* world) = 0;
};
class TurretTower : public BigTower {
public:
TurretTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {}
virtual TowerType GetType() const { return TowerType::Turret; }
virtual void Tick(std::uint64_t delta, World* world);
};
class NecromancerTower : public BigTower {
public:
NecromancerTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {}
virtual TowerType GetType() const { return TowerType::Necromancer; }
virtual void Tick(std::uint64_t delta, World* world);
};
class LeachTower : public BigTower {
public:
LeachTower(TowerID id, std::uint16_t x, std::uint16_t y, PlayerID builder) : BigTower(id, GetType(), x, y, builder) {}
virtual TowerType GetType() const { return TowerType::Leach; }
virtual void Tick(std::uint64_t delta, World* world);
};
} // namespace game
} // namespace td

View File

@@ -2,14 +2,17 @@
#include <cstdint> #include <cstdint>
// include Log for every files
#include "td/misc/Log.h"
namespace td { namespace td {
namespace game { namespace game {
enum class Direction : std::uint8_t { enum class Direction : std::uint8_t {
PositiveX = 1 << 0, PositiveX = 1 << 0,
NegativeX = 1 << 1, NegativeX = 1 << 1,
PositiveY = 1 << 2, PositiveY = 1 << 2,
NegativeY = 1 << 3, NegativeY = 1 << 3,
}; };
typedef std::uint8_t PlayerID; typedef std::uint8_t PlayerID;

250
include/td/game/World.h Normal file
View File

@@ -0,0 +1,250 @@
#pragma once
#include <memory>
#include <vector>
#include <map>
#include <unordered_map>
#include <array>
#include "Mobs.h"
#include "Team.h"
namespace td {
namespace game {
struct ChunkCoord {
std::int16_t x, y;
friend bool operator==(const td::game::ChunkCoord& first, const td::game::ChunkCoord& other) {
return first.x == other.x && first.y == other.y;
}
};
}
}
namespace std {
template <>
struct hash<td::game::ChunkCoord> {
std::size_t operator()(const td::game::ChunkCoord& key) const noexcept {
return std::hash<std::int16_t>()(key.x << 16 | key.y);
}
};
}
namespace td {
namespace protocol {
class WorldBeginDataPacket;
class WorldDataPacket;
}
namespace game {
class Game;
enum class TileType : std::uint8_t {
None = 0,
Tower,
Walk,
Decoration,
/*Heal,
Lava,
Bedrock,
Freeze,
Ice,*/
};
static constexpr Color BLACK{ 0, 0, 0 };
static constexpr Color WHITE{ 255, 255, 255 };
static constexpr Color RED{ 255, 0, 0 };
static constexpr Color GREEN{ 0, 255, 0 };
static constexpr Color BLUE{ 0, 0, 255 };
struct Tile {
virtual TileType GetType() const = 0;
};
struct TowerTile : Tile {
std::uint8_t color_palette_ref;
TeamColor team_owner;
virtual TileType GetType() const { return TileType::Tower; }
};
struct WalkableTile : Tile {
Direction direction;
virtual TileType GetType() const { return TileType::Walk; }
};
struct DecorationTile : Tile {
std::uint16_t color_palette_ref;
virtual TileType GetType() const { return TileType::Decoration; }
};
typedef std::shared_ptr<Tile> TilePtr;
typedef std::vector<std::uint16_t> ChunkPalette;
typedef std::shared_ptr<WalkableTile> WalkableTilePtr;
typedef std::uint32_t TileIndex;
//32 x 32 area
struct Chunk {
enum { ChunkWidth = 32, ChunkHeight = 32, ChunkSize = ChunkWidth * ChunkHeight };
typedef std::array<std::uint16_t, ChunkSize> ChunkData;
// stores index of tile palette
ChunkData tiles{ 0 };
ChunkPalette palette;
TileIndex GetTileIndex(std::uint16_t tileNumber) const {
TileIndex chunkPaletteIndex = tiles.at(tileNumber);
if (chunkPaletteIndex == 0) // index 0 means empty tile index 1 = first tile
return 0;
return palette.at(chunkPaletteIndex);
}
};
typedef std::shared_ptr<Chunk> ChunkPtr;
typedef std::array<Color, 2> TowerTileColorPalette;
typedef std::vector<TilePtr> TilePalette;
typedef std::vector<MobPtr> MobList;
typedef std::array<Color, 2> SpawnColorPalette;
typedef std::vector<TowerPtr> TowerList;
class WorldListener {
public:
WorldListener() {}
virtual void OnTowerAdd(TowerPtr tower) {}
virtual void OnTowerRemove(TowerPtr tower) {}
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter) {}
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) {}
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) {}
};
typedef utils::ObjectNotifier<WorldListener> WorldNotifier;
class World : public WorldListener, public MobListener {
protected:
TowerTileColorPalette m_TowerPlacePalette;
Color m_WalkablePalette;
std::vector<Color> m_DecorationPalette;
Color m_Background;
std::unordered_map<ChunkCoord, ChunkPtr> m_Chunks;
SpawnColorPalette m_SpawnColorPalette;
TilePalette m_TilePalette;
MobList m_Mobs;
TowerList m_Towers;
Game* m_Game;
WorldNotifier m_WorldNotifier;
MobNotifier m_MobNotifier;
public:
World(Game* game);
bool LoadMap(const protocol::WorldBeginDataPacket* worldHeader);
bool LoadMap(const protocol::WorldDataPacket* worldData);
bool LoadMapFromFile(const std::string& fileName);
bool SaveMap(const std::string& fileName) const;
void Tick(std::uint64_t delta);
void Reset(); // clear mobs and towers
void SpawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir);
MobPtr RemoveMob(MobID id);
TowerPtr PlaceTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder);
TowerPtr RemoveTower(TowerID id);
TilePtr GetTile(std::int32_t x, std::int32_t y) const;
const TowerTileColorPalette& GetTowerTileColorPalette() const { return m_TowerPlacePalette; }
const Color& GetWalkableTileColor() const { return m_WalkablePalette; }
const std::vector<Color>& GetDecorationPalette() const { return m_DecorationPalette; }
const Color& GetBackgroundColor() const { return m_Background; }
const TilePalette& GetTilePalette() const { return m_TilePalette; }
TilePtr GetTilePtr(TileIndex index) const {
if (index == 0)
return nullptr;
return m_TilePalette.at(index - 1);
}
bool CanPlaceLittleTower(const Vec2f& worldPos, PlayerID player) const;
bool CanPlaceBigTower(const Vec2f& worldPos, PlayerID player) const;
TowerPtr GetTower(const Vec2f& position) const; // returns null if no tower is here
const std::unordered_map<ChunkCoord, ChunkPtr>& GetChunks() const { return m_Chunks; }
const Color& GetSpawnColor(TeamColor color) const { return m_SpawnColorPalette[static_cast<std::size_t>(color)]; }
const SpawnColorPalette& GetSpawnColors() const { return m_SpawnColorPalette; }
const MobList& GetMobList() const { return m_Mobs; }
MobList& GetMobList() { return m_Mobs; }
const Color* GetTileColor(TilePtr tile) const;
Team& GetRedTeam();
const Team& GetRedTeam() const;
Team& GetBlueTeam();
const Team& GetBlueTeam() const;
Team& GetTeam(TeamColor team);
const Team& GetTeam(TeamColor team) const;
const TeamList& GetTeams() const;
TowerList& GetTowers() { return m_Towers; }
const TowerList& GetTowers() const { return m_Towers; }
TowerPtr GetTowerById(TowerID tower);
const Player* GetPlayerById(PlayerID id) const;
WorldNotifier& GetWorldNotifier() { return m_WorldNotifier; }
MobNotifier& GetMobNotifier() { return m_MobNotifier; }
// WorldListener
virtual void OnArcherTowerShot(MobPtr target, ArcherTower* shooter) override;
virtual void OnArrowShot(MobPtr target, bool fire, Tower* shooter) override;
virtual void OnExplosion(utils::shape::Circle explosion, float centerDamage, Tower* shooter) override;
// MobListener
virtual void OnMobDamage(Mob* target, float damage, Tower* source) override;
virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) override;
private:
void TickMobs(std::uint64_t delta);
void CleanDeadMobs();
};
} // namespace game
} // namespace td

4465
include/td/misc/Backward.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,14 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include "misc/DataBuffer.h" #include "DataBuffer.h"
namespace td { namespace td {
namespace utils { namespace utils {
std::uint64_t Inflate(const std::string& source, std::string& dest);
std::uint64_t Deflate(const std::string& source, std::string& dest);
DataBuffer Compress(const DataBuffer& buffer); DataBuffer Compress(const DataBuffer& buffer);
DataBuffer Decompress(DataBuffer& buffer); DataBuffer Decompress(DataBuffer& buffer);
DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength); DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength);

View File

@@ -0,0 +1,178 @@
#pragma once
#include <vector>
#include <algorithm>
#include <cstring>
#include <cassert>
#include <string>
#include <cstdint>
namespace td {
class DataBuffer {
private:
typedef std::vector<std::uint8_t> Data;
Data m_Buffer;
std::size_t m_ReadOffset;
public:
typedef Data::iterator iterator;
typedef Data::const_iterator const_iterator;
typedef Data::reference reference;
typedef Data::const_reference const_reference;
DataBuffer();
DataBuffer(const DataBuffer& other);
DataBuffer(const DataBuffer& other, Data::difference_type offset);
DataBuffer(DataBuffer&& other);
DataBuffer(const std::string& str);
DataBuffer& operator=(const DataBuffer& other);
DataBuffer& operator=(DataBuffer&& other);
template <typename T>
void Append(T data) {
std::size_t size = sizeof(data);
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + size);
memcpy(&m_Buffer[end_pos], &data, size);
}
template <typename T>
DataBuffer& operator<<(T data) {
// Switch to big endian
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
Append(data);
return *this;
}
DataBuffer& operator<<(std::string str) {
m_Buffer.insert(m_Buffer.end(), str.begin(), str.end());
return *this;
}
DataBuffer& operator<<(DataBuffer& data) {
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
return *this;
}
DataBuffer& operator<<(const DataBuffer& data) {
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
return *this;
}
template <typename T>
DataBuffer& operator>>(T& data) {
assert(m_ReadOffset + sizeof(T) <= GetSize());
data = *(reinterpret_cast<T*>(&m_Buffer[m_ReadOffset]));
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
m_ReadOffset += sizeof(T);
return *this;
}
DataBuffer& operator>>(DataBuffer& data) {
data.Resize(GetSize() - m_ReadOffset);
std::copy(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), m_Buffer.end(), data.begin());
m_ReadOffset = m_Buffer.size();
return *this;
}
DataBuffer& operator>>(std::string& str) {
std::size_t stringSize = strlen(reinterpret_cast<const char*>(m_Buffer.data()) + m_ReadOffset) + 1; // including null character
str.resize(stringSize);
std::copy(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset),
m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset + stringSize), str.begin());
m_ReadOffset += stringSize;
return *this;
}
void WriteSome(const char* buffer, std::size_t amount) {
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + amount);
memcpy(m_Buffer.data() + end_pos, buffer, amount);
}
void WriteSome(const std::uint8_t* buffer, std::size_t amount) {
std::size_t end_pos = m_Buffer.size();
m_Buffer.resize(m_Buffer.size() + amount);
memcpy(m_Buffer.data() + end_pos, buffer, amount);
}
void ReadSome(char* buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer);
m_ReadOffset += amount;
}
void ReadSome(std::uint8_t* buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer);
m_ReadOffset += amount;
}
void ReadSome(DataBuffer& buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
buffer.Resize(amount);
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer.begin());
m_ReadOffset += amount;
}
void ReadSome(std::string& buffer, std::size_t amount) {
assert(m_ReadOffset + amount <= GetSize());
buffer.resize(amount);
std::copy_n(m_Buffer.begin() + static_cast<Data::difference_type>(m_ReadOffset), amount, buffer.begin());
m_ReadOffset += amount;
}
void Resize(std::size_t size) {
m_Buffer.resize(size);
}
void Reserve(std::size_t amount) {
m_Buffer.reserve(amount);
}
void erase(iterator it) {
m_Buffer.erase(it);
}
void Clear() {
m_Buffer.clear();
m_ReadOffset = 0;
}
bool IsFinished() const {
return m_ReadOffset >= m_Buffer.size();
}
std::uint8_t* data() {
return m_Buffer.data();
}
const std::uint8_t* data() const {
return m_Buffer.data();
}
std::size_t GetReadOffset() const { return m_ReadOffset; }
void SetReadOffset(std::size_t pos);
std::string ToString() const;
std::size_t GetSize() const;
bool IsEmpty() const;
std::size_t GetRemaining() const;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
reference operator[](Data::size_type i) { return m_Buffer[i]; }
const_reference operator[](Data::size_type i) const { return m_Buffer[i]; }
bool ReadFile(const std::string& fileName);
bool WriteFile(const std::string& fileName);
};
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);
} // ns td

Some files were not shown because too many files have changed in this diff Show More