initial commit
commit
e21880d804
@ -0,0 +1,400 @@
|
||||
hr.py
|
||||
setup.py
|
||||
data/cursors/default.png
|
||||
data/tiles/grass/0.png
|
||||
data/tiles/water/0 watrtl01.pcx/0.png
|
||||
data/tiles/water/0 watrtl01.pcx/1.png
|
||||
data/tiles/water/0 watrtl01.pcx/10.png
|
||||
data/tiles/water/0 watrtl01.pcx/11.png
|
||||
data/tiles/water/0 watrtl01.pcx/2.png
|
||||
data/tiles/water/0 watrtl01.pcx/3.png
|
||||
data/tiles/water/0 watrtl01.pcx/4.png
|
||||
data/tiles/water/0 watrtl01.pcx/5.png
|
||||
data/tiles/water/0 watrtl01.pcx/6.png
|
||||
data/tiles/water/0 watrtl01.pcx/7.png
|
||||
data/tiles/water/0 watrtl01.pcx/8.png
|
||||
data/tiles/water/0 watrtl01.pcx/9.png
|
||||
data/tiles/water/1 watrtl02.pcx/0.png
|
||||
data/tiles/water/1 watrtl02.pcx/1.png
|
||||
data/tiles/water/1 watrtl02.pcx/10.png
|
||||
data/tiles/water/1 watrtl02.pcx/11.png
|
||||
data/tiles/water/1 watrtl02.pcx/2.png
|
||||
data/tiles/water/1 watrtl02.pcx/3.png
|
||||
data/tiles/water/1 watrtl02.pcx/4.png
|
||||
data/tiles/water/1 watrtl02.pcx/5.png
|
||||
data/tiles/water/1 watrtl02.pcx/6.png
|
||||
data/tiles/water/1 watrtl02.pcx/7.png
|
||||
data/tiles/water/1 watrtl02.pcx/8.png
|
||||
data/tiles/water/1 watrtl02.pcx/9.png
|
||||
data/tiles/water/10 watrtl11.pcx/0.png
|
||||
data/tiles/water/10 watrtl11.pcx/1.png
|
||||
data/tiles/water/10 watrtl11.pcx/10.png
|
||||
data/tiles/water/10 watrtl11.pcx/11.png
|
||||
data/tiles/water/10 watrtl11.pcx/2.png
|
||||
data/tiles/water/10 watrtl11.pcx/3.png
|
||||
data/tiles/water/10 watrtl11.pcx/4.png
|
||||
data/tiles/water/10 watrtl11.pcx/5.png
|
||||
data/tiles/water/10 watrtl11.pcx/6.png
|
||||
data/tiles/water/10 watrtl11.pcx/7.png
|
||||
data/tiles/water/10 watrtl11.pcx/8.png
|
||||
data/tiles/water/10 watrtl11.pcx/9.png
|
||||
data/tiles/water/11 watrtl12.pcx/0.png
|
||||
data/tiles/water/11 watrtl12.pcx/1.png
|
||||
data/tiles/water/11 watrtl12.pcx/10.png
|
||||
data/tiles/water/11 watrtl12.pcx/11.png
|
||||
data/tiles/water/11 watrtl12.pcx/2.png
|
||||
data/tiles/water/11 watrtl12.pcx/3.png
|
||||
data/tiles/water/11 watrtl12.pcx/4.png
|
||||
data/tiles/water/11 watrtl12.pcx/5.png
|
||||
data/tiles/water/11 watrtl12.pcx/6.png
|
||||
data/tiles/water/11 watrtl12.pcx/7.png
|
||||
data/tiles/water/11 watrtl12.pcx/8.png
|
||||
data/tiles/water/11 watrtl12.pcx/9.png
|
||||
data/tiles/water/12 watrtl13.pcx/0.png
|
||||
data/tiles/water/12 watrtl13.pcx/1.png
|
||||
data/tiles/water/12 watrtl13.pcx/10.png
|
||||
data/tiles/water/12 watrtl13.pcx/11.png
|
||||
data/tiles/water/12 watrtl13.pcx/2.png
|
||||
data/tiles/water/12 watrtl13.pcx/3.png
|
||||
data/tiles/water/12 watrtl13.pcx/4.png
|
||||
data/tiles/water/12 watrtl13.pcx/5.png
|
||||
data/tiles/water/12 watrtl13.pcx/6.png
|
||||
data/tiles/water/12 watrtl13.pcx/7.png
|
||||
data/tiles/water/12 watrtl13.pcx/8.png
|
||||
data/tiles/water/12 watrtl13.pcx/9.png
|
||||
data/tiles/water/13 watrtl14.pcx/0.png
|
||||
data/tiles/water/13 watrtl14.pcx/1.png
|
||||
data/tiles/water/13 watrtl14.pcx/10.png
|
||||
data/tiles/water/13 watrtl14.pcx/11.png
|
||||
data/tiles/water/13 watrtl14.pcx/2.png
|
||||
data/tiles/water/13 watrtl14.pcx/3.png
|
||||
data/tiles/water/13 watrtl14.pcx/4.png
|
||||
data/tiles/water/13 watrtl14.pcx/5.png
|
||||
data/tiles/water/13 watrtl14.pcx/6.png
|
||||
data/tiles/water/13 watrtl14.pcx/7.png
|
||||
data/tiles/water/13 watrtl14.pcx/8.png
|
||||
data/tiles/water/13 watrtl14.pcx/9.png
|
||||
data/tiles/water/14 watrtl15.pcx/0.png
|
||||
data/tiles/water/14 watrtl15.pcx/1.png
|
||||
data/tiles/water/14 watrtl15.pcx/10.png
|
||||
data/tiles/water/14 watrtl15.pcx/11.png
|
||||
data/tiles/water/14 watrtl15.pcx/2.png
|
||||
data/tiles/water/14 watrtl15.pcx/3.png
|
||||
data/tiles/water/14 watrtl15.pcx/4.png
|
||||
data/tiles/water/14 watrtl15.pcx/5.png
|
||||
data/tiles/water/14 watrtl15.pcx/6.png
|
||||
data/tiles/water/14 watrtl15.pcx/7.png
|
||||
data/tiles/water/14 watrtl15.pcx/8.png
|
||||
data/tiles/water/14 watrtl15.pcx/9.png
|
||||
data/tiles/water/15 watrtl16.pcx/0.png
|
||||
data/tiles/water/15 watrtl16.pcx/1.png
|
||||
data/tiles/water/15 watrtl16.pcx/10.png
|
||||
data/tiles/water/15 watrtl16.pcx/11.png
|
||||
data/tiles/water/15 watrtl16.pcx/2.png
|
||||
data/tiles/water/15 watrtl16.pcx/3.png
|
||||
data/tiles/water/15 watrtl16.pcx/4.png
|
||||
data/tiles/water/15 watrtl16.pcx/5.png
|
||||
data/tiles/water/15 watrtl16.pcx/6.png
|
||||
data/tiles/water/15 watrtl16.pcx/7.png
|
||||
data/tiles/water/15 watrtl16.pcx/8.png
|
||||
data/tiles/water/15 watrtl16.pcx/9.png
|
||||
data/tiles/water/16 watrtl17.pcx/0.png
|
||||
data/tiles/water/16 watrtl17.pcx/1.png
|
||||
data/tiles/water/16 watrtl17.pcx/10.png
|
||||
data/tiles/water/16 watrtl17.pcx/11.png
|
||||
data/tiles/water/16 watrtl17.pcx/2.png
|
||||
data/tiles/water/16 watrtl17.pcx/3.png
|
||||
data/tiles/water/16 watrtl17.pcx/4.png
|
||||
data/tiles/water/16 watrtl17.pcx/5.png
|
||||
data/tiles/water/16 watrtl17.pcx/6.png
|
||||
data/tiles/water/16 watrtl17.pcx/7.png
|
||||
data/tiles/water/16 watrtl17.pcx/8.png
|
||||
data/tiles/water/16 watrtl17.pcx/9.png
|
||||
data/tiles/water/17 watrtl18.pcx/0.png
|
||||
data/tiles/water/17 watrtl18.pcx/1.png
|
||||
data/tiles/water/17 watrtl18.pcx/10.png
|
||||
data/tiles/water/17 watrtl18.pcx/11.png
|
||||
data/tiles/water/17 watrtl18.pcx/2.png
|
||||
data/tiles/water/17 watrtl18.pcx/3.png
|
||||
data/tiles/water/17 watrtl18.pcx/4.png
|
||||
data/tiles/water/17 watrtl18.pcx/5.png
|
||||
data/tiles/water/17 watrtl18.pcx/6.png
|
||||
data/tiles/water/17 watrtl18.pcx/7.png
|
||||
data/tiles/water/17 watrtl18.pcx/8.png
|
||||
data/tiles/water/17 watrtl18.pcx/9.png
|
||||
data/tiles/water/18 watrtl19.pcx/0.png
|
||||
data/tiles/water/18 watrtl19.pcx/1.png
|
||||
data/tiles/water/18 watrtl19.pcx/10.png
|
||||
data/tiles/water/18 watrtl19.pcx/11.png
|
||||
data/tiles/water/18 watrtl19.pcx/2.png
|
||||
data/tiles/water/18 watrtl19.pcx/3.png
|
||||
data/tiles/water/18 watrtl19.pcx/4.png
|
||||
data/tiles/water/18 watrtl19.pcx/5.png
|
||||
data/tiles/water/18 watrtl19.pcx/6.png
|
||||
data/tiles/water/18 watrtl19.pcx/7.png
|
||||
data/tiles/water/18 watrtl19.pcx/8.png
|
||||
data/tiles/water/18 watrtl19.pcx/9.png
|
||||
data/tiles/water/19 watrtl20.pcx/0.png
|
||||
data/tiles/water/19 watrtl20.pcx/1.png
|
||||
data/tiles/water/19 watrtl20.pcx/10.png
|
||||
data/tiles/water/19 watrtl20.pcx/11.png
|
||||
data/tiles/water/19 watrtl20.pcx/2.png
|
||||
data/tiles/water/19 watrtl20.pcx/3.png
|
||||
data/tiles/water/19 watrtl20.pcx/4.png
|
||||
data/tiles/water/19 watrtl20.pcx/5.png
|
||||
data/tiles/water/19 watrtl20.pcx/6.png
|
||||
data/tiles/water/19 watrtl20.pcx/7.png
|
||||
data/tiles/water/19 watrtl20.pcx/8.png
|
||||
data/tiles/water/19 watrtl20.pcx/9.png
|
||||
data/tiles/water/2 watrtl03.pcx/0.png
|
||||
data/tiles/water/2 watrtl03.pcx/1.png
|
||||
data/tiles/water/2 watrtl03.pcx/10.png
|
||||
data/tiles/water/2 watrtl03.pcx/11.png
|
||||
data/tiles/water/2 watrtl03.pcx/2.png
|
||||
data/tiles/water/2 watrtl03.pcx/3.png
|
||||
data/tiles/water/2 watrtl03.pcx/4.png
|
||||
data/tiles/water/2 watrtl03.pcx/5.png
|
||||
data/tiles/water/2 watrtl03.pcx/6.png
|
||||
data/tiles/water/2 watrtl03.pcx/7.png
|
||||
data/tiles/water/2 watrtl03.pcx/8.png
|
||||
data/tiles/water/2 watrtl03.pcx/9.png
|
||||
data/tiles/water/20 watrtl21.pcx/0.png
|
||||
data/tiles/water/20 watrtl21.pcx/1.png
|
||||
data/tiles/water/20 watrtl21.pcx/10.png
|
||||
data/tiles/water/20 watrtl21.pcx/11.png
|
||||
data/tiles/water/20 watrtl21.pcx/2.png
|
||||
data/tiles/water/20 watrtl21.pcx/3.png
|
||||
data/tiles/water/20 watrtl21.pcx/4.png
|
||||
data/tiles/water/20 watrtl21.pcx/5.png
|
||||
data/tiles/water/20 watrtl21.pcx/6.png
|
||||
data/tiles/water/20 watrtl21.pcx/7.png
|
||||
data/tiles/water/20 watrtl21.pcx/8.png
|
||||
data/tiles/water/20 watrtl21.pcx/9.png
|
||||
data/tiles/water/21 watrtl22.pcx/0.png
|
||||
data/tiles/water/21 watrtl22.pcx/1.png
|
||||
data/tiles/water/21 watrtl22.pcx/10.png
|
||||
data/tiles/water/21 watrtl22.pcx/11.png
|
||||
data/tiles/water/21 watrtl22.pcx/2.png
|
||||
data/tiles/water/21 watrtl22.pcx/3.png
|
||||
data/tiles/water/21 watrtl22.pcx/4.png
|
||||
data/tiles/water/21 watrtl22.pcx/5.png
|
||||
data/tiles/water/21 watrtl22.pcx/6.png
|
||||
data/tiles/water/21 watrtl22.pcx/7.png
|
||||
data/tiles/water/21 watrtl22.pcx/8.png
|
||||
data/tiles/water/21 watrtl22.pcx/9.png
|
||||
data/tiles/water/22 watrtl23.pcx/0.png
|
||||
data/tiles/water/22 watrtl23.pcx/1.png
|
||||
data/tiles/water/22 watrtl23.pcx/10.png
|
||||
data/tiles/water/22 watrtl23.pcx/11.png
|
||||
data/tiles/water/22 watrtl23.pcx/2.png
|
||||
data/tiles/water/22 watrtl23.pcx/3.png
|
||||
data/tiles/water/22 watrtl23.pcx/4.png
|
||||
data/tiles/water/22 watrtl23.pcx/5.png
|
||||
data/tiles/water/22 watrtl23.pcx/6.png
|
||||
data/tiles/water/22 watrtl23.pcx/7.png
|
||||
data/tiles/water/22 watrtl23.pcx/8.png
|
||||
data/tiles/water/22 watrtl23.pcx/9.png
|
||||
data/tiles/water/23 watrtl24.pcx/0.png
|
||||
data/tiles/water/23 watrtl24.pcx/1.png
|
||||
data/tiles/water/23 watrtl24.pcx/10.png
|
||||
data/tiles/water/23 watrtl24.pcx/11.png
|
||||
data/tiles/water/23 watrtl24.pcx/2.png
|
||||
data/tiles/water/23 watrtl24.pcx/3.png
|
||||
data/tiles/water/23 watrtl24.pcx/4.png
|
||||
data/tiles/water/23 watrtl24.pcx/5.png
|
||||
data/tiles/water/23 watrtl24.pcx/6.png
|
||||
data/tiles/water/23 watrtl24.pcx/7.png
|
||||
data/tiles/water/23 watrtl24.pcx/8.png
|
||||
data/tiles/water/23 watrtl24.pcx/9.png
|
||||
data/tiles/water/24 watrtl25.pcx/0.png
|
||||
data/tiles/water/24 watrtl25.pcx/1.png
|
||||
data/tiles/water/24 watrtl25.pcx/10.png
|
||||
data/tiles/water/24 watrtl25.pcx/11.png
|
||||
data/tiles/water/24 watrtl25.pcx/2.png
|
||||
data/tiles/water/24 watrtl25.pcx/3.png
|
||||
data/tiles/water/24 watrtl25.pcx/4.png
|
||||
data/tiles/water/24 watrtl25.pcx/5.png
|
||||
data/tiles/water/24 watrtl25.pcx/6.png
|
||||
data/tiles/water/24 watrtl25.pcx/7.png
|
||||
data/tiles/water/24 watrtl25.pcx/8.png
|
||||
data/tiles/water/24 watrtl25.pcx/9.png
|
||||
data/tiles/water/25 watrtl26.pcx/0.png
|
||||
data/tiles/water/25 watrtl26.pcx/1.png
|
||||
data/tiles/water/25 watrtl26.pcx/10.png
|
||||
data/tiles/water/25 watrtl26.pcx/11.png
|
||||
data/tiles/water/25 watrtl26.pcx/2.png
|
||||
data/tiles/water/25 watrtl26.pcx/3.png
|
||||
data/tiles/water/25 watrtl26.pcx/4.png
|
||||
data/tiles/water/25 watrtl26.pcx/5.png
|
||||
data/tiles/water/25 watrtl26.pcx/6.png
|
||||
data/tiles/water/25 watrtl26.pcx/7.png
|
||||
data/tiles/water/25 watrtl26.pcx/8.png
|
||||
data/tiles/water/25 watrtl26.pcx/9.png
|
||||
data/tiles/water/26 watrtl27.pcx/0.png
|
||||
data/tiles/water/26 watrtl27.pcx/1.png
|
||||
data/tiles/water/26 watrtl27.pcx/10.png
|
||||
data/tiles/water/26 watrtl27.pcx/11.png
|
||||
data/tiles/water/26 watrtl27.pcx/2.png
|
||||
data/tiles/water/26 watrtl27.pcx/3.png
|
||||
data/tiles/water/26 watrtl27.pcx/4.png
|
||||
data/tiles/water/26 watrtl27.pcx/5.png
|
||||
data/tiles/water/26 watrtl27.pcx/6.png
|
||||
data/tiles/water/26 watrtl27.pcx/7.png
|
||||
data/tiles/water/26 watrtl27.pcx/8.png
|
||||
data/tiles/water/26 watrtl27.pcx/9.png
|
||||
data/tiles/water/27 watrtl28.pcx/0.png
|
||||
data/tiles/water/27 watrtl28.pcx/1.png
|
||||
data/tiles/water/27 watrtl28.pcx/10.png
|
||||
data/tiles/water/27 watrtl28.pcx/11.png
|
||||
data/tiles/water/27 watrtl28.pcx/2.png
|
||||
data/tiles/water/27 watrtl28.pcx/3.png
|
||||
data/tiles/water/27 watrtl28.pcx/4.png
|
||||
data/tiles/water/27 watrtl28.pcx/5.png
|
||||
data/tiles/water/27 watrtl28.pcx/6.png
|
||||
data/tiles/water/27 watrtl28.pcx/7.png
|
||||
data/tiles/water/27 watrtl28.pcx/8.png
|
||||
data/tiles/water/27 watrtl28.pcx/9.png
|
||||
data/tiles/water/28 watrtl29.pcx/0.png
|
||||
data/tiles/water/28 watrtl29.pcx/1.png
|
||||
data/tiles/water/28 watrtl29.pcx/10.png
|
||||
data/tiles/water/28 watrtl29.pcx/11.png
|
||||
data/tiles/water/28 watrtl29.pcx/2.png
|
||||
data/tiles/water/28 watrtl29.pcx/3.png
|
||||
data/tiles/water/28 watrtl29.pcx/4.png
|
||||
data/tiles/water/28 watrtl29.pcx/5.png
|
||||
data/tiles/water/28 watrtl29.pcx/6.png
|
||||
data/tiles/water/28 watrtl29.pcx/7.png
|
||||
data/tiles/water/28 watrtl29.pcx/8.png
|
||||
data/tiles/water/28 watrtl29.pcx/9.png
|
||||
data/tiles/water/29 watrtl30.pcx/0.png
|
||||
data/tiles/water/29 watrtl30.pcx/1.png
|
||||
data/tiles/water/29 watrtl30.pcx/10.png
|
||||
data/tiles/water/29 watrtl30.pcx/11.png
|
||||
data/tiles/water/29 watrtl30.pcx/2.png
|
||||
data/tiles/water/29 watrtl30.pcx/3.png
|
||||
data/tiles/water/29 watrtl30.pcx/4.png
|
||||
data/tiles/water/29 watrtl30.pcx/5.png
|
||||
data/tiles/water/29 watrtl30.pcx/6.png
|
||||
data/tiles/water/29 watrtl30.pcx/7.png
|
||||
data/tiles/water/29 watrtl30.pcx/8.png
|
||||
data/tiles/water/29 watrtl30.pcx/9.png
|
||||
data/tiles/water/3 watrtl04.pcx/0.png
|
||||
data/tiles/water/3 watrtl04.pcx/1.png
|
||||
data/tiles/water/3 watrtl04.pcx/10.png
|
||||
data/tiles/water/3 watrtl04.pcx/11.png
|
||||
data/tiles/water/3 watrtl04.pcx/2.png
|
||||
data/tiles/water/3 watrtl04.pcx/3.png
|
||||
data/tiles/water/3 watrtl04.pcx/4.png
|
||||
data/tiles/water/3 watrtl04.pcx/5.png
|
||||
data/tiles/water/3 watrtl04.pcx/6.png
|
||||
data/tiles/water/3 watrtl04.pcx/7.png
|
||||
data/tiles/water/3 watrtl04.pcx/8.png
|
||||
data/tiles/water/3 watrtl04.pcx/9.png
|
||||
data/tiles/water/30 watrtl31.pcx/0.png
|
||||
data/tiles/water/30 watrtl31.pcx/1.png
|
||||
data/tiles/water/30 watrtl31.pcx/10.png
|
||||
data/tiles/water/30 watrtl31.pcx/11.png
|
||||
data/tiles/water/30 watrtl31.pcx/2.png
|
||||
data/tiles/water/30 watrtl31.pcx/3.png
|
||||
data/tiles/water/30 watrtl31.pcx/4.png
|
||||
data/tiles/water/30 watrtl31.pcx/5.png
|
||||
data/tiles/water/30 watrtl31.pcx/6.png
|
||||
data/tiles/water/30 watrtl31.pcx/7.png
|
||||
data/tiles/water/30 watrtl31.pcx/8.png
|
||||
data/tiles/water/30 watrtl31.pcx/9.png
|
||||
data/tiles/water/31 watrtl32.pcx/0.png
|
||||
data/tiles/water/31 watrtl32.pcx/1.png
|
||||
data/tiles/water/31 watrtl32.pcx/10.png
|
||||
data/tiles/water/31 watrtl32.pcx/11.png
|
||||
data/tiles/water/31 watrtl32.pcx/2.png
|
||||
data/tiles/water/31 watrtl32.pcx/3.png
|
||||
data/tiles/water/31 watrtl32.pcx/4.png
|
||||
data/tiles/water/31 watrtl32.pcx/5.png
|
||||
data/tiles/water/31 watrtl32.pcx/6.png
|
||||
data/tiles/water/31 watrtl32.pcx/7.png
|
||||
data/tiles/water/31 watrtl32.pcx/8.png
|
||||
data/tiles/water/31 watrtl32.pcx/9.png
|
||||
data/tiles/water/32 watrtl33.pcx/0.png
|
||||
data/tiles/water/32 watrtl33.pcx/1.png
|
||||
data/tiles/water/32 watrtl33.pcx/10.png
|
||||
data/tiles/water/32 watrtl33.pcx/11.png
|
||||
data/tiles/water/32 watrtl33.pcx/2.png
|
||||
data/tiles/water/32 watrtl33.pcx/3.png
|
||||
data/tiles/water/32 watrtl33.pcx/4.png
|
||||
data/tiles/water/32 watrtl33.pcx/5.png
|
||||
data/tiles/water/32 watrtl33.pcx/6.png
|
||||
data/tiles/water/32 watrtl33.pcx/7.png
|
||||
data/tiles/water/32 watrtl33.pcx/8.png
|
||||
data/tiles/water/32 watrtl33.pcx/9.png
|
||||
data/tiles/water/4 watrtl05.pcx/0.png
|
||||
data/tiles/water/4 watrtl05.pcx/1.png
|
||||
data/tiles/water/4 watrtl05.pcx/10.png
|
||||
data/tiles/water/4 watrtl05.pcx/11.png
|
||||
data/tiles/water/4 watrtl05.pcx/2.png
|
||||
data/tiles/water/4 watrtl05.pcx/3.png
|
||||
data/tiles/water/4 watrtl05.pcx/4.png
|
||||
data/tiles/water/4 watrtl05.pcx/5.png
|
||||
data/tiles/water/4 watrtl05.pcx/6.png
|
||||
data/tiles/water/4 watrtl05.pcx/7.png
|
||||
data/tiles/water/4 watrtl05.pcx/8.png
|
||||
data/tiles/water/4 watrtl05.pcx/9.png
|
||||
data/tiles/water/5 watrtl06.pcx/0.png
|
||||
data/tiles/water/5 watrtl06.pcx/1.png
|
||||
data/tiles/water/5 watrtl06.pcx/10.png
|
||||
data/tiles/water/5 watrtl06.pcx/11.png
|
||||
data/tiles/water/5 watrtl06.pcx/2.png
|
||||
data/tiles/water/5 watrtl06.pcx/3.png
|
||||
data/tiles/water/5 watrtl06.pcx/4.png
|
||||
data/tiles/water/5 watrtl06.pcx/5.png
|
||||
data/tiles/water/5 watrtl06.pcx/6.png
|
||||
data/tiles/water/5 watrtl06.pcx/7.png
|
||||
data/tiles/water/5 watrtl06.pcx/8.png
|
||||
data/tiles/water/5 watrtl06.pcx/9.png
|
||||
data/tiles/water/6 watrtl07.pcx/0.png
|
||||
data/tiles/water/6 watrtl07.pcx/1.png
|
||||
data/tiles/water/6 watrtl07.pcx/10.png
|
||||
data/tiles/water/6 watrtl07.pcx/11.png
|
||||
data/tiles/water/6 watrtl07.pcx/2.png
|
||||
data/tiles/water/6 watrtl07.pcx/3.png
|
||||
data/tiles/water/6 watrtl07.pcx/4.png
|
||||
data/tiles/water/6 watrtl07.pcx/5.png
|
||||
data/tiles/water/6 watrtl07.pcx/6.png
|
||||
data/tiles/water/6 watrtl07.pcx/7.png
|
||||
data/tiles/water/6 watrtl07.pcx/8.png
|
||||
data/tiles/water/6 watrtl07.pcx/9.png
|
||||
data/tiles/water/7 watrtl08.pcx/0.png
|
||||
data/tiles/water/7 watrtl08.pcx/1.png
|
||||
data/tiles/water/7 watrtl08.pcx/10.png
|
||||
data/tiles/water/7 watrtl08.pcx/11.png
|
||||
data/tiles/water/7 watrtl08.pcx/2.png
|
||||
data/tiles/water/7 watrtl08.pcx/3.png
|
||||
data/tiles/water/7 watrtl08.pcx/4.png
|
||||
data/tiles/water/7 watrtl08.pcx/5.png
|
||||
data/tiles/water/7 watrtl08.pcx/6.png
|
||||
data/tiles/water/7 watrtl08.pcx/7.png
|
||||
data/tiles/water/7 watrtl08.pcx/8.png
|
||||
data/tiles/water/7 watrtl08.pcx/9.png
|
||||
data/tiles/water/8 watrtl09.pcx/0.png
|
||||
data/tiles/water/8 watrtl09.pcx/1.png
|
||||
data/tiles/water/8 watrtl09.pcx/10.png
|
||||
data/tiles/water/8 watrtl09.pcx/11.png
|
||||
data/tiles/water/8 watrtl09.pcx/2.png
|
||||
data/tiles/water/8 watrtl09.pcx/3.png
|
||||
data/tiles/water/8 watrtl09.pcx/4.png
|
||||
data/tiles/water/8 watrtl09.pcx/5.png
|
||||
data/tiles/water/8 watrtl09.pcx/6.png
|
||||
data/tiles/water/8 watrtl09.pcx/7.png
|
||||
data/tiles/water/8 watrtl09.pcx/8.png
|
||||
data/tiles/water/8 watrtl09.pcx/9.png
|
||||
data/tiles/water/9 watrtl10.pcx/0.png
|
||||
data/tiles/water/9 watrtl10.pcx/1.png
|
||||
data/tiles/water/9 watrtl10.pcx/10.png
|
||||
data/tiles/water/9 watrtl10.pcx/11.png
|
||||
data/tiles/water/9 watrtl10.pcx/2.png
|
||||
data/tiles/water/9 watrtl10.pcx/3.png
|
||||
data/tiles/water/9 watrtl10.pcx/4.png
|
||||
data/tiles/water/9 watrtl10.pcx/5.png
|
||||
data/tiles/water/9 watrtl10.pcx/6.png
|
||||
data/tiles/water/9 watrtl10.pcx/7.png
|
||||
data/tiles/water/9 watrtl10.pcx/8.png
|
||||
data/tiles/water/9 watrtl10.pcx/9.png
|
@ -0,0 +1,2 @@
|
||||
include hr.py
|
||||
recursive-include data/ *
|
@ -0,0 +1,260 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
import random
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, frames):
|
||||
self.frames = frames
|
||||
self.animation = 0
|
||||
|
||||
def get_current_frame(self):
|
||||
return self.frames[self.animation]
|
||||
|
||||
def get_next_frame(self):
|
||||
self.animation = (self.animation+1)%len(self.frames)
|
||||
return self.frames[self.animation]
|
||||
|
||||
class WaterTile(Animation):
|
||||
def __init__(self, tiles, group):
|
||||
super(WaterTile, self).__init__(tiles)
|
||||
self.tiles = tiles
|
||||
self.group = group
|
||||
|
||||
def get_group(self):
|
||||
return self.group
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.get_current_frame().tex_coords
|
||||
|
||||
def get_next_tex_coords(self):
|
||||
return self.get_next_frame().tex_coords
|
||||
|
||||
class GrassTile(object):
|
||||
def __init__(self, tile, group):
|
||||
self.tile = tile
|
||||
self.group = group
|
||||
|
||||
def get_group(self):
|
||||
return self.group
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.tile.tex_coords
|
||||
|
||||
class MapSet(object):
|
||||
def __init__(self, loaded_map):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
self.water_tiles = self._load_water_tiles()
|
||||
self.grass_tiles = self._load_grass_tiles()
|
||||
|
||||
self.tiles = [[None for i in xrange(self.width)] for j in xrange(self.height)]
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == 2: #grass
|
||||
self.tiles[y][x] = GrassTile(self.grass_tiles[tile[1]], self.grass_group)
|
||||
elif tile[0] == 8: #water
|
||||
self.tiles[y][x] = WaterTile(self.water_tiles[tile[1]], self.water_group)
|
||||
|
||||
def _load_grass_tiles(self):
|
||||
atlas = pyglet.image.atlas.TextureAtlas()
|
||||
self.grass_texture = atlas.texture
|
||||
self.grass_group = pyglet.graphics.TextureGroup(atlas.texture)
|
||||
return [atlas.add(pyglet.image.load('data/tiles/grass/0.png'))]
|
||||
|
||||
def _load_water_tiles(self):
|
||||
atlas = pyglet.image.atlas.TextureAtlas(width=384, height=416)
|
||||
self.water_texture = atlas.texture
|
||||
self.water_group = pyglet.graphics.TextureGroup(atlas.texture)
|
||||
return [[atlas.add(pyglet.image.load('data/tiles/water/%d watrtl%d.pcx/%d.png'%(j,j+1,i))) for i in xrange(12)] for j in xrange(20, 32)]
|
||||
|
||||
def get_tile(self, x, y):
|
||||
assert x >= 0 and y >= 0
|
||||
return self.tiles[y][x]
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
self.vertex_lists = {}
|
||||
|
||||
self._init_view()
|
||||
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _init_view(self):
|
||||
for vlist in self.vertex_lists.values():
|
||||
vlist.delete()
|
||||
self.vertex_lists = {}
|
||||
coords = {}
|
||||
textures = {}
|
||||
|
||||
div_y, mod_y = divmod(self.y, 32)
|
||||
div_x, mod_x = divmod(self.x, 32)
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
y1 = mod_y+y*32+48
|
||||
y2 = y1+32
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
x1 = mod_x+x*32
|
||||
x2 = x1+32
|
||||
tile = self.mapset.get_tile(x-div_x, y-div_y)
|
||||
group = tile.get_group()
|
||||
if group not in coords.keys():
|
||||
coords[group] = []
|
||||
textures[group] = []
|
||||
|
||||
coords[group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
textures[group].extend(tile.get_tex_coords())
|
||||
|
||||
for group in coords.keys():
|
||||
self.vertex_lists[group] = self.batch.add((len(coords[group])//8)*4, pyglet.gl.GL_QUADS, group,
|
||||
('v2i', coords[group]),
|
||||
('t3f', textures[group]),
|
||||
('c4B', (255,255,255,255) * (len(coords[group])//8)*4))
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT | pyglet.gl.GL_DEPTH_BUFFER_BIT)
|
||||
self.batch.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
div_y, mod_y = divmod(self.y+dy, 32)
|
||||
div_x, mod_x = divmod(self.x+dx, 32)
|
||||
|
||||
if div_x != self.x//32 or div_y != self.y//32:
|
||||
update_texture = True
|
||||
else:
|
||||
update_texture = False
|
||||
|
||||
self.x += dx
|
||||
self.y += dy
|
||||
if update_texture:
|
||||
self._init_view()
|
||||
else:
|
||||
coords = {}
|
||||
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
y1 = mod_y+y*32+48
|
||||
y2 = y1+32
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
x1 = mod_x+x*32
|
||||
x2 = x1+32
|
||||
|
||||
tile = self.mapset.get_tile(x-div_x, y-div_y)
|
||||
group = tile.get_group()
|
||||
if group not in coords.keys():
|
||||
coords[group] = []
|
||||
coords[group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
for group in coords.keys():
|
||||
self.vertex_lists[group].vertices = coords[group]
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
water_texture = []
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
tile = self.mapset.get_tile(x-self.x//32, y-self.y//32)
|
||||
if tile.get_group() is self.mapset.water_group:
|
||||
water_texture.extend(tile.get_next_tex_coords())
|
||||
self.vertex_lists[self.mapset.water_group].tex_coords = water_texture
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
|
||||
img = pyglet.resource.image("data/cursors/default.png")
|
||||
self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
|
||||
def empty(self, dt):
|
||||
pass
|
||||
|
||||
def main():
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
|
||||
loaded_map = [[[8,random.randint(0,11)] for x in xrange(128)] for y in xrange(128)]
|
||||
loaded_map[10][10] = [2, 0]
|
||||
loaded_map[0] = [[2,0] for y in xrange(128)]
|
||||
for x in xrange(128):
|
||||
loaded_map[x][32] = [2,0]
|
||||
mapset = MapSet(loaded_map)
|
||||
|
||||
mapview = MapView(mapset, window)
|
||||
window.push_handlers(mapview)
|
||||
pyglet.clock.schedule(window.empty)
|
||||
pyglet.app.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,154 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import pyglet
|
||||
import random
|
||||
|
||||
class Map(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
|
||||
#generate map
|
||||
self.water_map = [[random.randint(0,11) for x in xrange(128)] for y in xrange(128)]
|
||||
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.animate = 0
|
||||
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
|
||||
|
||||
self._load_resources()
|
||||
self._init_map()
|
||||
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _load_resources(self):
|
||||
atlas = pyglet.image.atlas.TextureAtlas(width=384, height=416)
|
||||
self.tiles = [[atlas.add(pyglet.image.load('data/tiles/water/%d watrtl%d.pcx/%d.png'%(j,j+1,i))) for i in xrange(12)] for j in xrange(20, 32)]
|
||||
self.water_texture = atlas.texture
|
||||
|
||||
def _init_map(self):
|
||||
try:
|
||||
for row in self.vertex_lists:
|
||||
for vlist in row:
|
||||
vlist.delete()
|
||||
except:
|
||||
raise
|
||||
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
|
||||
group = pyglet.graphics.TextureGroup(self.water_texture)
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
y1 = y*32+48
|
||||
y2 = y1+32
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
x1 = x*32
|
||||
x2 = x1+32
|
||||
tile = self.tiles[self.water_map[y][x]][self.animate]
|
||||
self.vertex_lists[y].append(self.batch.add(4, pyglet.gl.GL_QUADS, group,
|
||||
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
|
||||
('t3f', tile.tex_coords),
|
||||
('c4B', (255,255,255,255) * 4)))
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT | pyglet.gl.GL_DEPTH_BUFFER_BIT)
|
||||
self.batch.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
div_y, mod_y = divmod(self.y+dy, 32)
|
||||
div_x, mod_x = divmod(self.x+dx, 32)
|
||||
|
||||
if div_x != self.x//32 or div_y != self.y//32:
|
||||
update_texture = True
|
||||
else:
|
||||
update_texture = False
|
||||
|
||||
self.x += dx
|
||||
self.y += dy
|
||||
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
y1 = mod_y+y*32+48
|
||||
y2 = y1+32
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
x1 = mod_x+x*32
|
||||
x2 = x1+32
|
||||
self.vertex_lists[y][x].vertices = [x1, y1, x2, y1, x2, y2, x1, y2]
|
||||
|
||||
if update_texture:
|
||||
tile = self.tiles[self.water_map[y-div_y][x-div_x]][self.animate]
|
||||
self.vertex_lists[y][x].tex_coords=tile.tex_coords
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_map()
|
||||
|
||||
def animate_water(self, dt):
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
tile = self.tiles[self.water_map[y-self.y//32][x-self.x//32]][self.animate]
|
||||
self.vertex_lists[y][x].tex_coords=tile.tex_coords
|
||||
self.animate = (self.animate+1)%12
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
|
||||
img = pyglet.resource.image("data/cursors/default.png")
|
||||
self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 4, 28))
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def empty(self, dt):
|
||||
pass
|
||||
|
||||
def main():
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
map = Map(window)
|
||||
window.push_handlers(map)
|
||||
pyglet.clock.schedule(window.empty)
|
||||
pyglet.app.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,120 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
homm3h3mview
|
||||
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import gzip, os
|
||||
import struct
|
||||
import sys
|
||||
import pygame
|
||||
from pygame.locals import *
|
||||
|
||||
class Tile(pygame.sprite.Sprite):
|
||||
def __init__(self, tile_type, tile_seq, x, y, flip_x, flip_y):
|
||||
pygame.sprite.Sprite.__init__(self) #call Sprite initializer
|
||||
try:
|
||||
if tile_type == 8: #water
|
||||
image = pygame.image.load("/home/josch/fheroes3/tests/69 tiles/3229 Watrtl.def/watrtl%02d.pcx"%(tile_seq+1))
|
||||
elif tile_type == 2: #grass
|
||||
print tile_seq,
|
||||
path = "/home/josch/fheroes3/tests/69 tiles/3221 GRASTL.def/tgrs%03d.pcx"
|
||||
if tile_seq == 20:
|
||||
image = pygame.image.load(path%0)
|
||||
elif tile_seq == 21:
|
||||
image = pygame.image.load(path%1)
|
||||
elif tile_seq == 22:
|
||||
image = pygame.image.load(path%2)
|
||||
elif tile_seq == 23:
|
||||
image = pygame.image.load(path%3)
|
||||
elif tile_seq == 24:
|
||||
image = pygame.image.load(path%10)
|
||||
elif tile_seq == 25:
|
||||
image = pygame.image.load(path%11)
|
||||
elif tile_seq == 26:
|
||||
image = pygame.image.load(path%12)
|
||||
elif tile_seq == 27:
|
||||
image = pygame.image.load(path%13)
|
||||
elif tile_seq == 28:
|
||||
image = pygame.image.load(path%20)
|
||||
elif tile_seq == 29:
|
||||
image = pygame.image.load(path%21)
|
||||
elif tile_seq == 30:
|
||||
image = pygame.image.load(path%22)
|
||||
elif tile_seq == 31:
|
||||
image = pygame.image.load(path%23)
|
||||
elif tile_seq == 32:
|
||||
image = pygame.image.load(path%30)
|
||||
elif tile_seq == 33:
|
||||
image = pygame.image.load(path%31)
|
||||
elif tile_seq == 34:
|
||||
image = pygame.image.load(path%32)
|
||||
elif tile_seq == 35:
|
||||
image = pygame.image.load(path%33)
|
||||
else:
|
||||
raise Exception
|
||||
except:
|
||||
image = pygame.image.load("/home/josch/fheroes3/tests/69 tiles/3999 Tshre.def/Tshre10.pcx")
|
||||
image = image.convert()
|
||||
if flip_x or flip_y:
|
||||
image = pygame.transform.flip(image, flip_x, flip_y)
|
||||
self.image = image
|
||||
self.rect = image.get_rect()
|
||||
self.rect.topleft = (32*x,32*y)
|
||||
|
||||
def extract(filename):
|
||||
pygame.init()
|
||||
screen = pygame.display.set_mode((800, 600))
|
||||
pygame.display.set_caption('Heroes Rebirth')
|
||||
pygame.mouse.set_visible(1)
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
|
||||
h3m_data = gzip.open(filename)
|
||||
h3m_data.seek(5)
|
||||
(map_size,) = struct.unpack("i", h3m_data.read(4))
|
||||
h3m_data.seek(390)
|
||||
tiles = []
|
||||
for i in xrange(map_size*map_size):
|
||||
x = i%map_size
|
||||
y = (i-x)/map_size
|
||||
tile = struct.unpack("7B", h3m_data.read(7))
|
||||
flip_x = tile[6] & 0x1
|
||||
flip_y = tile[6] & 0x2
|
||||
tile = Tile(tile[0], tile[1], x, y, flip_x, flip_y)
|
||||
tiles.append(tile)
|
||||
|
||||
allsprites = pygame.sprite.RenderPlain(tiles)
|
||||
|
||||
while 1:
|
||||
for event in pygame.event.get():
|
||||
if event.type == QUIT:
|
||||
return
|
||||
elif event.type == KEYDOWN and event.key == K_ESCAPE:
|
||||
return
|
||||
allsprites.draw(screen)
|
||||
pygame.display.flip()
|
||||
clock.tick(25)
|
||||
|
||||
def main(args):
|
||||
if len(args) != 2:
|
||||
print 'usage: %s file' % args[0]
|
||||
return 2
|
||||
extract(args[1])
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
@ -0,0 +1,212 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
import random
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, frames):
|
||||
self.frames = frames
|
||||
self.animation = 0
|
||||
|
||||
@property
|
||||
def current_frame(self):
|
||||
return self.frames[self.animation]
|
||||
|
||||
@property
|
||||
def next_frame(self):
|
||||
self.animation = (self.animation+1)%len(self.frames)
|
||||
return self.frames[self.animation]
|
||||
|
||||
class WaterTile(Animation):
|
||||
def __init__(self, tiles):
|
||||
super(WaterTile, self).__init__(tiles)
|
||||
self.tiles = tiles
|
||||
|
||||
@property
|
||||
def current_tex_coords(self):
|
||||
return self.current_frame.tex_coords
|
||||
|
||||
@property
|
||||
def next_tex_coords(self):
|
||||
return self.next_frame.tex_coords
|
||||
|
||||
class MapSet(object):
|
||||
def __init__(self, loaded_map):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
self.alt_water = pyglet.image.TextureGrid(pyglet.image.ImageGrid(pyglet.image.load("water.png"), 20, 16))
|
||||
self.water_texture = self.alt_water
|
||||
|
||||
self.tiles = [[None for i in xrange(self.width)] for j in xrange(self.height)]
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
#self.tiles[y][x] = WaterTile(self.water_tiles[tile])
|
||||
self.tiles[y][x] = WaterTile(self.alt_water[(0, tile):(19, tile+1)])
|
||||
|
||||
def __getitem__(self, coords):
|
||||
x, y = coords
|
||||
return self.tiles[y][x]
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
|
||||
|
||||
self._init_view()
|
||||
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _init_view(self):
|
||||
try:
|
||||
for row in self.vertex_lists:
|
||||
for vlist in row:
|
||||
vlist.delete()
|
||||
except:
|
||||
raise
|
||||
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
|
||||
group = pyglet.graphics.TextureGroup(self.mapset.water_texture)
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
y1 = y*32+48
|
||||
y2 = y1+32
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
x1 = x*32
|
||||
x2 = x1+32
|
||||
tile = self.mapset[x, y]
|
||||
self.vertex_lists[y].append(self.batch.add(4, pyglet.gl.GL_QUADS, group,
|
||||
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
|
||||
('t3f', tile.current_tex_coords),
|
||||
('c4B', (255,255,255,255) * 4)))
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT | pyglet.gl.GL_DEPTH_BUFFER_BIT)
|
||||
self.batch.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
div_y, mod_y = divmod(self.y+dy, 32)
|
||||
div_x, mod_x = divmod(self.x+dx, 32)
|
||||
|
||||
if div_x != self.x//32 or div_y != self.y//32:
|
||||
update_texture = True
|
||||
else:
|
||||
update_texture = False
|
||||
|
||||
self.x += dx
|
||||
self.y += dy
|
||||
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
y1 = mod_y+y*32+48
|
||||
y2 = y1+32
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
x1 = mod_x+x*32
|
||||
x2 = x1+32
|
||||
self.vertex_lists[y][x].vertices = [x1, y1, x2, y1, x2, y2, x1, y2]
|
||||
|
||||
if update_texture:
|
||||
tile = self.mapset[x-div_x, y-div_y]
|
||||
self.vertex_lists[y][x].tex_coords=tile.current_tex_coords
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
tile = self.mapset[x-self.x//32, y-self.y//32]
|
||||
self.vertex_lists[y][x].tex_coords=tile.next_tex_coords
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
|
||||
#img = pyglet.resource.image("cursor.png")
|
||||
#self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
|
||||
def empty(self, dt):
|
||||
pass
|
||||
|
||||
def main():
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
|
||||
loaded_map = [[random.randint(0,11) for x in xrange(128)] for y in xrange(128)]
|
||||
mapset = MapSet(loaded_map)
|
||||
|
||||
mapview = MapView(mapset, window)
|
||||
window.push_handlers(mapview)
|
||||
pyglet.clock.schedule(window.empty)
|
||||
pyglet.app.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,237 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
import random
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, frames):
|
||||
self.frames = frames
|
||||
self.animation = 0
|
||||
|
||||
def get_current_frame(self):
|
||||
return self.frames[self.animation]
|
||||
|
||||
def get_next_frame(self):
|
||||
self.animation = (self.animation+1)%len(self.frames)
|
||||
return self.frames[self.animation]
|
||||
|
||||
class WaterTile(Animation):
|
||||
def __init__(self, tiles, group):
|
||||
super(WaterTile, self).__init__(tiles)
|
||||
self.tiles = tiles
|
||||
self.group = group
|
||||
|
||||
def get_group(self):
|
||||
return self.group
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.get_current_frame().tex_coords
|
||||
|
||||
def get_next_tex_coords(self):
|
||||
return self.get_next_frame().tex_coords
|
||||
|
||||
class GrassTile(object):
|
||||
def __init__(self, tile, group):
|
||||
self.tile = tile
|
||||
self.group = group
|
||||
|
||||
def get_group(self):
|
||||
return self.group
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.tile.tex_coords
|
||||
|
||||
class MapSet(object):
|
||||
def __init__(self, loaded_map):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
self.water_tiles = self._load_water_tiles()
|
||||
self.grass_tiles = self._load_grass_tiles()
|
||||
|
||||
self.tiles = [[None for i in xrange(self.width)] for j in xrange(self.height)]
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == 2: #grass
|
||||
self.tiles[y][x] = GrassTile(self.grass_tiles[tile[1]], self.grass_group)
|
||||
elif tile[0] == 8: #water
|
||||
self.tiles[y][x] = WaterTile(self.water_tiles[tile[1]], self.water_group)
|
||||
|
||||
def _load_grass_tiles(self):
|
||||
atlas = pyglet.image.atlas.TextureAtlas()
|
||||
self.grass_texture = atlas.texture
|
||||
self.grass_group = pyglet.graphics.TextureGroup(atlas.texture)
|
||||
return [atlas.add(pyglet.image.load('data/tiles/grass/0.png'))]
|
||||
|
||||
def _load_water_tiles(self):
|
||||
atlas = pyglet.image.atlas.TextureAtlas(width=384, height=416)
|
||||
self.water_texture = atlas.texture
|
||||
self.water_group = pyglet.graphics.TextureGroup(atlas.texture)
|
||||
return [[atlas.add(pyglet.image.load('data/tiles/water/%d watrtl%d.pcx/%d.png'%(j,j+1,i))) for i in xrange(12)] for j in xrange(20, 32)]
|
||||
|
||||
def get_tile(self, x, y):
|
||||
return self.tiles[y][x]
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
|
||||
|
||||
self._init_view()
|
||||
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _init_view(self):
|
||||
try:
|
||||
for row in self.vertex_lists:
|
||||
for vlist in row:
|
||||
vlist.delete()
|
||||
except:
|
||||
raise
|
||||
self.vertex_lists = [[] for x in xrange((self.window.height-48)//32)]
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
y1 = y*32+48
|
||||
y2 = y1+32
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
x1 = x*32
|
||||
x2 = x1+32
|
||||
tile = self.mapset.get_tile(x, y)
|
||||
self.vertex_lists[y].append(self.batch.add(4, pyglet.gl.GL_QUADS, tile.get_group(),
|
||||
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
|
||||
('t3f', tile.get_tex_coords()),
|
||||
('c4B', (255,255,255,255) * 4)))
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT | pyglet.gl.GL_DEPTH_BUFFER_BIT)
|
||||
self.batch.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
div_y, mod_y = divmod(self.y+dy, 32)
|
||||
div_x, mod_x = divmod(self.x+dx, 32)
|
||||
|
||||
if div_x != self.x//32 or div_y != self.y//32:
|
||||
update_texture = True
|
||||
else:
|
||||
update_texture = False
|
||||
|
||||
self.x += dx
|
||||
self.y += dy
|
||||
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
y1 = mod_y+y*32+48
|
||||
y2 = y1+32
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
x1 = mod_x+x*32
|
||||
x2 = x1+32
|
||||
self.vertex_lists[y][x].vertices = [x1, y1, x2, y1, x2, y2, x1, y2]
|
||||
|
||||
if update_texture:
|
||||
tile = self.mapset.get_tile(x-div_x, y-div_y)
|
||||
self.vertex_lists[y][x].tex_coords=tile.get_tex_coords()
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
for y in xrange((self.window.height-48)//32):
|
||||
for x in xrange((self.window.width-192)//32):
|
||||
tile = self.mapset.get_tile(x-self.x//32, y-self.y//32)
|
||||
if isinstance(tile, WaterTile):
|
||||
self.vertex_lists[y][x].tex_coords=tile.get_next_tex_coords()
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
|
||||
img = pyglet.resource.image("data/cursors/default.png")
|
||||
self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
|
||||
def empty(self, dt):
|
||||
pass
|
||||
|
||||
def main():
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
|
||||
loaded_map = [[[8,random.randint(0,11)] for x in xrange(128)] for y in xrange(128)]
|
||||
loaded_map[64][64] = [2, 0]
|
||||
mapset = MapSet(loaded_map)
|
||||
|
||||
mapview = MapView(mapset, window)
|
||||
window.push_handlers(mapview)
|
||||
pyglet.clock.schedule(window.empty)
|
||||
pyglet.app.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,409 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
import random
|
||||
import itertools
|
||||
|
||||
import demjson
|
||||
|
||||
IF_BOTTOM = 48
|
||||
IF_RIGHT = 200
|
||||
IF_TOP = IF_LEFT = 8
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, frames):
|
||||
self.frames = frames
|
||||
self.animation = 0
|
||||
|
||||
def get_current_frame(self):
|
||||
return self.frames[self.animation]
|
||||
|
||||
def get_next_frame(self):
|
||||
self.animation = (self.animation+1)%len(self.frames)
|
||||
return self.frames[self.animation]
|
||||
|
||||
class WaterTile(Animation):
|
||||
def __init__(self, tiles):
|
||||
super(WaterTile, self).__init__(tiles)
|
||||
self.tiles = tiles
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.get_current_frame().tex_coords
|
||||
|
||||
def get_next_tex_coords(self):
|
||||
return self.get_next_frame().tex_coords
|
||||
|
||||
class Tile(object):
|
||||
def __init__(self, tile):
|
||||
self.tile = tile
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.tile.tex_coords
|
||||
|
||||
def get_next_tex_coords(self):
|
||||
return self.tile.tex_coords
|
||||
|
||||
class MapSet(object):
|
||||
def __init__(self, loaded_map):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
atlas = pyglet.image.atlas.TextureAtlas(width=2048, height=2048)
|
||||
self.group = pyglet.graphics.TextureGroup(atlas.texture)
|
||||
self.grass_tiles = [atlas.add(pyglet.image.load('data/tiles/grass/%d.png'%i)) for i in xrange(79)]
|
||||
self.dirt_tiles = [atlas.add(pyglet.image.load('data/tiles/dirt/%d.png'%i)) for i in xrange(46)]
|
||||
self.water_tiles = [[atlas.add(pyglet.image.load('data/tiles/water/%d watrtl%02d.pcx/%d.png'%(j,j+1,i))) for i in xrange(12)] for j in xrange(33)]
|
||||
self.edge_tiles = [atlas.add(pyglet.image.load('data/tiles/edge/%d EDG%d.PCX'%(i, i+1))) for i in xrange(36)]
|
||||
|
||||
self.tiles = [[Tile(self.grass_tiles[0]) for i in xrange(self.width)] for j in xrange(self.height)]
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == -1: #edge
|
||||
self.tiles[y][x] = Tile(self.edge_tiles[tile[1]])
|
||||
elif tile[0] == 0: #dirt
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]])
|
||||
elif tile[0] == 2: #grass
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]])
|
||||
elif tile[0] == 8: #water
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for tile in self.water_tiles[tile[1]]:
|
||||
tiles.append(tile.get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
self.tiles[y][x] = WaterTile(tiles)
|
||||
else:
|
||||
self.tiles[y][x] = WaterTile(self.water_tiles[tile[1]])
|
||||
else:
|
||||
self.tiles[y][x] = GrassTile(self.grass_tiles[0])
|
||||
|
||||
def get_tile(self, x, y):
|
||||
assert x >= 0 and y >= 0
|
||||
return self.tiles[y][x]
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
|
||||
self.vertex_list = None
|
||||
self._init_view()
|
||||
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _init_view(self):
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
|
||||
#drawn tiles
|
||||
self.tiles_x = min((self.viewport_x//32)+2, self.mapset.width)
|
||||
self.tiles_y = min((self.viewport_y//32)+2, self.mapset.height)
|
||||
|
||||
self.center_x = False
|
||||
if self.mapset.width*32 < self.viewport_x:
|
||||
self.center_x = True
|
||||
self.global_x = (self.mapset.width*32)//2-(self.viewport_x//2)
|
||||
self.center_y = False
|
||||
if self.mapset.height*32 < self.viewport_y:
|
||||
self.center_y = True
|
||||
self.global_y = (self.mapset.height*32)//2-(self.viewport_y//2)
|
||||
|
||||
#step half the drawn tiles (minus one tile)
|
||||
self.steps = 32
|
||||
|
||||
#undrawn map size
|
||||
self.undrawn_x = 32*(self.mapset.width-self.tiles_x)
|
||||
self.undrawn_y = 32*(self.mapset.height-self.tiles_y)
|
||||
#size of full undrawn steps
|
||||
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
|
||||
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
|
||||
|
||||
if self.vertex_list is not None:
|
||||
self.vertex_list.delete()
|
||||
else:
|
||||
#do some first time init stuff
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.view_x = 0
|
||||
self.view_y = 0
|
||||
self.global_x = (self.mapset.width*32)//2-(self.viewport_x//2)
|
||||
self.global_y = (self.mapset.height*32)//2-(self.viewport_y//2)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
if trans_global_x < -self.undrawn_steps_x:
|
||||
mod_x = trans_global_x+self.undrawn_x
|
||||
elif trans_global_x < self.steps:
|
||||
mod_x = trans_global_x%self.steps
|
||||
else:
|
||||
mod_x = trans_global_x
|
||||
|
||||
if trans_global_y < -self.undrawn_steps_y:
|
||||
mod_y = trans_global_y+self.undrawn_y
|
||||
elif trans_global_y < self.steps:
|
||||
mod_y = trans_global_y%self.steps
|
||||
else:
|
||||
mod_y = trans_global_y
|
||||
|
||||
div_x = (trans_global_x-mod_x)//32
|
||||
div_y = (trans_global_y-mod_y)//32+self.mapset.height-1
|
||||
|
||||
vertices = []
|
||||
tex_coords = []
|
||||
count = 0
|
||||
|
||||
for y in xrange(self.tiles_y):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
y2 = y1+32
|
||||
for x in xrange(self.tiles_x):
|
||||
x1 = x*32+IF_LEFT
|
||||
x2 = x1+32
|
||||
tile = self.mapset.get_tile(x-div_x, div_y-y)
|
||||
vertices.extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
tex_coords.extend(tile.get_tex_coords())
|
||||
count+=1
|
||||
self.vertex_list = self.batch.add(4*count, pyglet.gl.GL_QUADS, self.mapset.group,
|
||||
('v2i', vertices),
|
||||
('t3f', tex_coords),
|
||||
('c4B', (255,255,255,255)*4*count))
|
||||
self.view_x = mod_x-self.steps
|
||||
self.view_y = mod_y-self.steps
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
|
||||
pyglet.gl.glPushMatrix()
|
||||
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
|
||||
self.batch.draw()
|
||||
pyglet.gl.glPopMatrix()
|
||||
pyglet.gl.glLoadIdentity()
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glColor4f(1, 0, 1, 1)
|
||||
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
|
||||
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
|
||||
|
||||
def _move(self, dx, dy):
|
||||
retex = False
|
||||
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
new_global_x = trans_global_x+dx
|
||||
new_global_y = trans_global_y+dy
|
||||
|
||||
if self.global_x-dx < 0:
|
||||
new_global_x = self.steps
|
||||
if self.global_y-dy < 0:
|
||||
new_global_y = self.steps
|
||||
if dx-self.global_x < -32*self.mapset.width+self.viewport_x:
|
||||
new_global_x = -32*self.mapset.width+self.viewport_x+self.steps
|
||||
if dy-self.global_y < -32*self.mapset.height+self.viewport_y:
|
||||
new_global_y = -32*self.mapset.height+self.viewport_y+self.steps
|
||||
|
||||
if new_global_x < -self.undrawn_steps_x:
|
||||
mod_x = new_global_x+self.undrawn_x
|
||||
if trans_global_x >= -self.undrawn_steps_x:
|
||||
retex = True
|
||||
elif new_global_x < self.steps:
|
||||
div_x, mod_x = divmod(new_global_x, self.steps)
|
||||
retex = div_x != trans_global_x//self.steps or retex
|
||||
else:
|
||||
mod_x = new_global_x
|
||||
|
||||
if new_global_y < -self.undrawn_steps_y:
|
||||
mod_y = new_global_y+self.undrawn_y
|
||||
if trans_global_y >= -self.undrawn_steps_y:
|
||||
retex = True
|
||||
elif new_global_y < self.steps:
|
||||
div_y, mod_y = divmod(new_global_y, self.steps)
|
||||
retex = div_y != trans_global_y//self.steps or retex
|
||||
else:
|
||||
mod_y = new_global_y
|
||||
|
||||
if retex:
|
||||
div_x = (new_global_x-mod_x)//32
|
||||
div_y = (new_global_y-mod_y)//32+self.mapset.height-1
|
||||
tex_coords = []
|
||||
for y in xrange(self.tiles_y):
|
||||
for x in xrange(self.tiles_x):
|
||||
tile = self.mapset.get_tile(x-div_x, div_y-y)
|
||||
tex_coords.extend(tile.get_tex_coords())
|
||||
|
||||
self.vertex_list.tex_coords = tex_coords
|
||||
|
||||
if not self.center_x:
|
||||
self.view_x = mod_x-self.steps
|
||||
self.global_x = self.steps-new_global_x
|
||||
if not self.center_y:
|
||||
self.view_y = mod_y-self.steps
|
||||
self.global_y = self.steps-new_global_y
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
if trans_global_x < -self.undrawn_steps_x:
|
||||
mod_x = trans_global_x+self.undrawn_x
|
||||
elif trans_global_x < self.steps:
|
||||
mod_x = trans_global_x%self.steps
|
||||
else:
|
||||
mod_x = trans_global_x
|
||||
|
||||
if trans_global_y < -self.undrawn_steps_y:
|
||||
mod_y = trans_global_y+self.undrawn_y
|
||||
elif trans_global_y < self.steps:
|
||||
mod_y = trans_global_y%self.steps
|
||||
else:
|
||||
mod_y = trans_global_y
|
||||
div_x = (trans_global_x-mod_x)//32
|
||||
div_y = (trans_global_y-mod_y)//32+self.mapset.height-1
|
||||
tex_coords = []
|
||||
for y in xrange(self.tiles_y):
|
||||
for x in xrange(self.tiles_x):
|
||||
tile = self.mapset.get_tile(x-div_x, div_y-y)
|
||||
tex_coords.extend(tile.get_next_tex_coords())
|
||||
self.vertex_list.tex_coords = tex_coords
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
|
||||
img = pyglet.resource.image("data/cursors/default.png")
|
||||
self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
|
||||
def empty(self, dt):
|
||||
pass
|
||||
|
||||
def main():
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
|
||||
# loaded_map = [[[8,random.randint(0,11)] for x in xrange(32)] for y in xrange(12)]
|
||||
# loaded_map[0] = [[2,0] for y in xrange(32)]
|
||||
# loaded_map[11] = [[2,0] for y in xrange(32)]
|
||||
# for x in xrange(12):
|
||||
# loaded_map[x][0] = [2,0]
|
||||
# for x in xrange(12):
|
||||
# loaded_map[x][31] = [2,0]
|
||||
|
||||
h3m = demjson.decode(open("test.h3m").read())
|
||||
loaded_map = h3m["upper_terrain"]
|
||||
|
||||
edge_map = [[] for i in xrange(len(loaded_map)+16)]
|
||||
for num in xrange(len(edge_map)):
|
||||
if num < 7 or num > len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0])+18)])
|
||||
elif num == 7:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 16, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
|
||||
line.append([-1, 17, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
elif num == len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 19, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
|
||||
line.append([-1, 18, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
else:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend(loaded_map[num-8])
|
||||
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
edge_map[num] = line
|
||||
mapset = MapSet(edge_map)
|
||||
|
||||
mapview = MapView(mapset, window)
|
||||
window.push_handlers(mapview)
|
||||
pyglet.clock.schedule(window.empty)
|
||||
pyglet.app.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,420 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
import random
|
||||
import itertools
|
||||
import sys
|
||||
|
||||
if sys.version_info[:2] >= (2,6):
|
||||
import json
|
||||
else:
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import demjson as json
|
||||
json.loads = json.decode
|
||||
|
||||
IF_BOTTOM = 48
|
||||
IF_RIGHT = 200
|
||||
IF_TOP = IF_LEFT = 8
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, frames):
|
||||
self.frames = frames
|
||||
self.animation = 0
|
||||
|
||||
def get_current_frame(self):
|
||||
return self.frames[self.animation]
|
||||
|
||||
def get_next_frame(self):
|
||||
self.animation = (self.animation+1)%len(self.frames)
|
||||
return self.frames[self.animation]
|
||||
|
||||
class WaterTile(Animation):
|
||||
def __init__(self, tiles):
|
||||
super(WaterTile, self).__init__(tiles)
|
||||
self.tiles = tiles
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.get_current_frame().tex_coords
|
||||
|
||||
def get_next_tex_coords(self):
|
||||
return self.get_next_frame().tex_coords
|
||||
|
||||
class Tile(object):
|
||||
def __init__(self, tile):
|
||||
self.tile = tile
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.tile.tex_coords
|
||||
|
||||
def get_next_tex_coords(self):
|
||||
return self.tile.tex_coords
|
||||
|
||||
class MapSet(object):
|
||||
def __init__(self, loaded_map):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
atlas = pyglet.image.atlas.TextureAtlas(width=2048, height=2048)
|
||||
self.group = pyglet.graphics.TextureGroup(atlas.texture)
|
||||
self.grass_tiles = [atlas.add(pyglet.image.load('data/tiles/grass/%d.png'%i)) for i in xrange(79)]
|
||||
self.snow_tiles = [atlas.add(pyglet.image.load('data/tiles/snow/%d.png'%i)) for i in xrange(79)]
|
||||
self.lava_tiles = [atlas.add(pyglet.image.load('data/tiles/lava/%d.png'%i)) for i in xrange(79)]
|
||||
self.swamp_tiles = [atlas.add(pyglet.image.load('data/tiles/swamp/%d.png'%i)) for i in xrange(79)]
|
||||
self.rough_tiles = [atlas.add(pyglet.image.load('data/tiles/rough/%d.png'%i)) for i in xrange(79)]
|
||||
self.dirt_tiles = [atlas.add(pyglet.image.load('data/tiles/dirt/%d.png'%i)) for i in xrange(46)]
|
||||
self.rock_tiles = [atlas.add(pyglet.image.load('data/tiles/rock/%d.png'%i)) for i in xrange(48)]
|
||||
self.sand_tiles = [atlas.add(pyglet.image.load('data/tiles/sand/%d.png'%i)) for i in xrange(24)]
|
||||
self.water_tiles = [[atlas.add(pyglet.image.load('data/tiles/water/%d watrtl%02d.pcx/%d.png'%(j,j+1,i))) for i in xrange(12)] for j in xrange(33)]
|
||||
self.edge_tiles = [atlas.add(pyglet.image.load('data/tiles/edge/%d EDG%d.PCX'%(i, i+1))) for i in xrange(36)]
|
||||
|
||||
self.tiles = [[Tile(self.grass_tiles[0]) for i in xrange(self.width)] for j in xrange(self.height)]
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == -1: #edge
|
||||
self.tiles[y][x] = Tile(self.edge_tiles[tile[1]])
|
||||
elif tile[0] == 0: #dirt
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]])
|
||||
elif tile[0] == 1: #sand
|
||||
self.tiles[y][x] = Tile(self.sand_tiles[tile[1]])
|
||||
elif tile[0] == 2: #grass
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]])
|
||||
elif tile[0] == 3: #snow
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.snow_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.snow_tiles[tile[1]])
|
||||
elif tile[0] == 4: #swamp
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.swamp_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.swamp_tiles[tile[1]])
|
||||
elif tile[0] == 5: #rough
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.rough_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.rough_tiles[tile[1]])
|
||||
elif tile[0] == 7: #lava
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.lava_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.lava_tiles[tile[1]])
|
||||
elif tile[0] == 8: #water
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for tile in self.water_tiles[tile[1]]:
|
||||
tiles.append(tile.get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
self.tiles[y][x] = WaterTile(tiles)
|
||||
else:
|
||||
self.tiles[y][x] = WaterTile(self.water_tiles[tile[1]])
|
||||
elif tile[0] == 9: #rock
|
||||
self.tiles[y][x] = Tile(self.rock_tiles[tile[1]])
|
||||
else:
|
||||
print tile[0]
|
||||
self.tiles[y][x] = GrassTile(self.grass_tiles[0])
|
||||
|
||||
def get_tile(self, x, y):
|
||||
assert x >= 0 and y >= 0
|
||||
return self.tiles[y][x]
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
|
||||
self._init_view()
|
||||
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _init_view(self):
|
||||
self.tile_size = 32
|
||||
#step one tile
|
||||
self.steps = self.tile_size
|
||||
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
|
||||
#drawn tiles
|
||||
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
|
||||
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
|
||||
|
||||
self.center_x = False
|
||||
if self.mapset.width*self.tile_size < self.viewport_x:
|
||||
self.center_x = True
|
||||
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
|
||||
self.center_y = False
|
||||
if self.mapset.height*self.tile_size < self.viewport_y:
|
||||
self.center_y = True
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
|
||||
|
||||
#undrawn map size
|
||||
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
|
||||
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
|
||||
#size of full undrawn steps
|
||||
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
|
||||
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
|
||||
|
||||
self.vertex_list = [[] for i in xrange(self.tiles_y)]
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.view_x = 0
|
||||
self.view_y = 0
|
||||
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
if trans_global_x < -self.undrawn_steps_x:
|
||||
mod_x = trans_global_x+self.undrawn_x
|
||||
elif trans_global_x < self.steps:
|
||||
mod_x = trans_global_x%self.steps
|
||||
else:
|
||||
mod_x = trans_global_x
|
||||
|
||||
if trans_global_y < -self.undrawn_steps_y:
|
||||
mod_y = trans_global_y+self.undrawn_y
|
||||
elif trans_global_y < self.steps:
|
||||
mod_y = trans_global_y%self.steps
|
||||
else:
|
||||
mod_y = trans_global_y
|
||||
|
||||
self.div_x = (trans_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
|
||||
vertices = []
|
||||
tex_coords = []
|
||||
count = 0
|
||||
|
||||
for y in xrange(self.tiles_y):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
y2 = y1+32
|
||||
for x in xrange(self.tiles_x):
|
||||
x1 = x*32+IF_LEFT
|
||||
x2 = x1+32
|
||||
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
|
||||
self.vertex_list[y].append(self.batch.add(4, pyglet.gl.GL_QUADS, self.mapset.group,
|
||||
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
|
||||
('t3f', tile.get_tex_coords()),
|
||||
('c4B', (255,255,255,255)*4)))
|
||||
self.view_x = mod_x-self.steps
|
||||
self.view_y = mod_y-self.steps
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
|
||||
pyglet.gl.glPushMatrix()
|
||||
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
|
||||
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
|
||||
self.batch.draw()
|
||||
pyglet.gl.glPopMatrix()
|
||||
pyglet.gl.glLoadIdentity()
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glColor4f(1, 0, 1, 1)
|
||||
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
|
||||
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
|
||||
|
||||
def _move(self, dx, dy):
|
||||
retex = False
|
||||
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
new_global_x = trans_global_x+dx
|
||||
new_global_y = trans_global_y+dy
|
||||
|
||||
if self.global_x-dx < 0:
|
||||
new_global_x = self.steps
|
||||
if self.global_y-dy < 0:
|
||||
new_global_y = self.steps
|
||||
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
|
||||
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
|
||||
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
|
||||
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
|
||||
|
||||
if new_global_x < -self.undrawn_steps_x:
|
||||
mod_x = new_global_x+self.undrawn_x
|
||||
if trans_global_x >= -self.undrawn_steps_x:
|
||||
retex = True
|
||||
elif new_global_x < self.steps:
|
||||
div_x, mod_x = divmod(new_global_x, self.steps)
|
||||
retex = div_x != trans_global_x//self.steps or retex
|
||||
else:
|
||||
mod_x = new_global_x
|
||||
|
||||
if new_global_y < -self.undrawn_steps_y:
|
||||
mod_y = new_global_y+self.undrawn_y
|
||||
if trans_global_y >= -self.undrawn_steps_y:
|
||||
retex = True
|
||||
elif new_global_y < self.steps:
|
||||
div_y, mod_y = divmod(new_global_y, self.steps)
|
||||
retex = div_y != trans_global_y//self.steps or retex
|
||||
else:
|
||||
mod_y = new_global_y
|
||||
|
||||
if retex:
|
||||
self.div_x = (new_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
for y in xrange(self.tiles_y):
|
||||
for x in xrange(self.tiles_x):
|
||||
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
|
||||
self.vertex_list[y][x].tex_coords = tile.get_tex_coords()
|
||||
|
||||
if not self.center_x:
|
||||
self.view_x = mod_x-self.steps
|
||||
self.global_x = self.steps-new_global_x
|
||||
if not self.center_y:
|
||||
self.view_y = mod_y-self.steps
|
||||
self.global_y = self.steps-new_global_y
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
for y in xrange(self.tiles_y):
|
||||
for x in xrange(self.tiles_x):
|
||||
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
|
||||
if isinstance(tile, WaterTile):
|
||||
self.vertex_list[y][x].tex_coords = tile.get_next_tex_coords()
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
|
||||
img = pyglet.resource.image("data/cursors/default.png")
|
||||
self.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
|
||||
def empty(self, dt):
|
||||
pass
|
||||
|
||||
def main():
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
|
||||
h3m = json.loads(open("test.h3m").read())
|
||||
loaded_map = h3m["upper_terrain"]
|
||||
|
||||
edge_map = [[] for i in xrange(len(loaded_map)+16)]
|
||||
for num in xrange(len(edge_map)):
|
||||
if num < 7 or num > len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0])+18)])
|
||||
elif num == 7:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 16, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
|
||||
line.append([-1, 17, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
elif num == len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 19, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
|
||||
line.append([-1, 18, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
else:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend(loaded_map[num-8])
|
||||
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
edge_map[num] = line
|
||||
mapset = MapSet(edge_map)
|
||||
|
||||
mapview = MapView(mapset, window)
|
||||
window.push_handlers(mapview)
|
||||
pyglet.clock.schedule(window.empty)
|
||||
pyglet.app.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,516 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import demjson as json
|
||||
json.loads = json.decode
|
||||
json.dumps = json.encode
|
||||
|
||||
IF_BOTTOM = 48
|
||||
IF_RIGHT = 200
|
||||
IF_TOP = IF_LEFT = 8
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, frames):
|
||||
self.frames = frames
|
||||
self.animation = 0
|
||||
|
||||
def get_current_frame(self):
|
||||
return self.frames[self.animation]
|
||||
|
||||
def get_next_frame(self):
|
||||
self.animation = (self.animation+1)%len(self.frames)
|
||||
return self.frames[self.animation]
|
||||
|
||||
class WaterTile(Animation):
|
||||
def __init__(self, tiles):
|
||||
super(WaterTile, self).__init__(tiles)
|
||||
self.tiles = tiles
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.get_current_frame().tex_coords
|
||||
|
||||
def get_next_tex_coords(self):
|
||||
return self.get_next_frame().tex_coords
|
||||
|
||||
class Tile(object):
|
||||
def __init__(self, tile):
|
||||
self.tile = tile
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.tile.tex_coords
|
||||
|
||||
def get_next_tex_coords(self):
|
||||
return self.tile.tex_coords
|
||||
|
||||
class MapSet(object):
|
||||
def __init__(self, loaded_map):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
atlas = pyglet.image.atlas.TextureAtlas(width=2048, height=2048)
|
||||
self.group = pyglet.graphics.TextureGroup(atlas.texture)
|
||||
self.grass_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/grass/%d.png'%i))) for i in xrange(79)]
|
||||
self.snow_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/snow/%d.png'%i))) for i in xrange(79)]
|
||||
self.lava_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/lava/%d.png'%i))) for i in xrange(79)]
|
||||
self.swamp_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/swamp/%d.png'%i))) for i in xrange(79)]
|
||||
self.rough_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/rough/%d.png'%i))) for i in xrange(79)]
|
||||
self.dirt_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/dirt/%d.png'%i))) for i in xrange(46)]
|
||||
self.rock_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/rock/%d.png'%i))) for i in xrange(48)]
|
||||
self.sand_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/sand/%d.png'%i))) for i in xrange(24)]
|
||||
self.water_tiles = [[atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/water/%d watrtl%02d.pcx/%d.png'%(j,j+1,i)))) for i in xrange(12)] for j in xrange(33)]
|
||||
self.edge_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/edge/%d EDG%d.PCX'%(i, i+1)))) for i in xrange(36)]
|
||||
self.tiles = [[Tile(self.grass_tiles[0]) for i in xrange(self.width)] for j in xrange(self.height)]
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == -1: #edge
|
||||
self.tiles[y][x] = Tile(self.edge_tiles[tile[1]])
|
||||
elif tile[0] == 0: #dirt
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.dirt_tiles[tile[1]])
|
||||
elif tile[0] == 1: #sand
|
||||
self.tiles[y][x] = Tile(self.sand_tiles[tile[1]])
|
||||
elif tile[0] == 2: #grass
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.grass_tiles[tile[1]])
|
||||
elif tile[0] == 3: #snow
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.snow_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.snow_tiles[tile[1]])
|
||||
elif tile[0] == 4: #swamp
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.swamp_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.swamp_tiles[tile[1]])
|
||||
elif tile[0] == 5: #rough
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.rough_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.rough_tiles[tile[1]])
|
||||
elif tile[0] == 7: #lava
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[y][x] = Tile(self.lava_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
else:
|
||||
self.tiles[y][x] = Tile(self.lava_tiles[tile[1]])
|
||||
elif tile[0] == 8: #water
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for tile in self.water_tiles[tile[1]]:
|
||||
tiles.append(tile.get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
self.tiles[y][x] = WaterTile(tiles)
|
||||
else:
|
||||
self.tiles[y][x] = WaterTile(self.water_tiles[tile[1]])
|
||||
elif tile[0] == 9: #rock
|
||||
self.tiles[y][x] = Tile(self.rock_tiles[tile[1]])
|
||||
else:
|
||||
print tile[0]
|
||||
self.tiles[y][x] = GrassTile(self.grass_tiles[0])
|
||||
|
||||
def get_tile(self, x, y):
|
||||
assert x >= 0 and y >= 0
|
||||
return self.tiles[y][x]
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
|
||||
self._first_time_init()
|
||||
self._init_view()
|
||||
|
||||
#mouse position
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="",
|
||||
font_size=36,
|
||||
bold=True,
|
||||
color=(128, 128, 128, 128),
|
||||
x=self.window.width-10, y=0,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _first_time_init(self):
|
||||
self.tile_size = 32
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
#center map
|
||||
self.global_x = (self.mapset.width*self.tile_size-self.viewport_x+self.tile_size)//2
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)+(self.tile_size//2)
|
||||
|
||||
self.mouse_x = self.mouse_dx = 0
|
||||
self.mouse_y = self.mouse_dy = 0
|
||||
|
||||
def _init_view(self):
|
||||
#step one tile
|
||||
self.steps = self.tile_size
|
||||
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
|
||||
#center map when viewport is too large, else check if map still fills
|
||||
#whole viewport and if not adjust position accordingly
|
||||
self.center_x = False
|
||||
if self.mapset.width*self.tile_size < self.viewport_x:
|
||||
self.center_x = True
|
||||
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
|
||||
elif self.global_x > self.tile_size*self.mapset.width-self.viewport_x:
|
||||
self.global_x = self.tile_size*self.mapset.width-self.viewport_x
|
||||
elif self.global_x < 0:
|
||||
self.global_x = 0
|
||||
|
||||
self.center_y = False
|
||||
if self.mapset.height*self.tile_size < self.viewport_y:
|
||||
self.center_y = True
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
|
||||
elif self.global_y > self.tile_size*self.mapset.height-self.viewport_y:
|
||||
self.global_y = self.tile_size*self.mapset.height-self.viewport_y
|
||||
elif self.global_y < 0:
|
||||
self.global_y = 0
|
||||
|
||||
#drawn tiles
|
||||
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
|
||||
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
|
||||
|
||||
#undrawn map size
|
||||
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
|
||||
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
|
||||
#size of full undrawn steps
|
||||
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
|
||||
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
|
||||
|
||||
self.vertex_list = [[] for i in xrange(self.tiles_y)]
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.view_x = 0
|
||||
self.view_y = 0
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
if trans_global_x < -self.undrawn_steps_x:
|
||||
mod_x = trans_global_x+self.undrawn_x
|
||||
elif trans_global_x < self.steps:
|
||||
mod_x = trans_global_x%self.steps
|
||||
else:
|
||||
mod_x = trans_global_x
|
||||
|
||||
if trans_global_y < -self.undrawn_steps_y:
|
||||
mod_y = trans_global_y+self.undrawn_y
|
||||
elif trans_global_y < self.steps:
|
||||
mod_y = trans_global_y%self.steps
|
||||
else:
|
||||
mod_y = trans_global_y
|
||||
|
||||
self.div_x = (trans_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
|
||||
vertices = []
|
||||
tex_coords = []
|
||||
count = 0
|
||||
|
||||
for y in xrange(self.tiles_y):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
y2 = y1+32
|
||||
for x in xrange(self.tiles_x):
|
||||
x1 = x*32+IF_LEFT
|
||||
x2 = x1+32
|
||||
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
|
||||
self.vertex_list[y].append(self.batch.add(4, pyglet.gl.GL_QUADS, self.mapset.group,
|
||||
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
|
||||
('t3f', tile.get_tex_coords()),
|
||||
('c4B', (255,255,255,255)*4)))
|
||||
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
|
||||
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
|
||||
pyglet.gl.glPushMatrix()
|
||||
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
|
||||
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
|
||||
self.batch.draw()
|
||||
pyglet.gl.glPopMatrix()
|
||||
pyglet.gl.glLoadIdentity()
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glColor4f(1, 0, 1, 1)
|
||||
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
|
||||
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
|
||||
self.label.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
new_global_x = trans_global_x+dx
|
||||
new_global_y = trans_global_y+dy
|
||||
|
||||
if self.global_x-dx < 0:
|
||||
new_global_x = self.steps
|
||||
if self.global_y-dy < 0:
|
||||
new_global_y = self.steps
|
||||
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
|
||||
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
|
||||
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
|
||||
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
|
||||
|
||||
retex = False
|
||||
|
||||
if new_global_x < -self.undrawn_steps_x:
|
||||
mod_x = new_global_x+self.undrawn_x
|
||||
if trans_global_x >= -self.undrawn_steps_x:
|
||||
retex = True
|
||||
elif new_global_x < self.steps:
|
||||
div_x, mod_x = divmod(new_global_x, self.steps)
|
||||
retex = div_x != trans_global_x//self.steps or retex
|
||||
else:
|
||||
mod_x = new_global_x
|
||||
|
||||
if new_global_y < -self.undrawn_steps_y:
|
||||
mod_y = new_global_y+self.undrawn_y
|
||||
if trans_global_y >= -self.undrawn_steps_y:
|
||||
retex = True
|
||||
elif new_global_y < self.steps:
|
||||
div_y, mod_y = divmod(new_global_y, self.steps)
|
||||
retex = div_y != trans_global_y//self.steps or retex
|
||||
else:
|
||||
mod_y = new_global_y
|
||||
|
||||
if retex:
|
||||
self.div_x = (new_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
for y in xrange(self.tiles_y):
|
||||
for x in xrange(self.tiles_x):
|
||||
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
|
||||
self.vertex_list[y][x].tex_coords = tile.get_tex_coords()
|
||||
|
||||
if not self.center_x:
|
||||
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
|
||||
self.global_x = self.steps-new_global_x
|
||||
if not self.center_y:
|
||||
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
|
||||
self.global_y = self.steps-new_global_y
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
elif self.window.keys[pyglet.window.key.PLUS] and \
|
||||
self.tile_size < 32:
|
||||
self.tile_size+=8
|
||||
self._init_view()
|
||||
elif self.window.keys[pyglet.window.key.MINUS] and \
|
||||
self.tile_size > 16:
|
||||
self.tile_size-=8
|
||||
self._init_view()
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
#mouse position:
|
||||
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
|
||||
self.mouse_x = self.mouse_dx
|
||||
self.mouse_y = self.mouse_dy
|
||||
x = (self.mouse_x-IF_LEFT-self.view_x
|
||||
-(self.tile_size-32)//4)//self.tile_size
|
||||
y = (self.mouse_y-IF_BOTTOM-self.view_y
|
||||
-((self.tile_size-32)*3)//2)//self.tile_size
|
||||
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
for y in xrange(self.tiles_y):
|
||||
for x in xrange(self.tiles_x):
|
||||
tile = self.mapset.get_tile(x-self.div_x, self.div_y-y)
|
||||
if isinstance(tile, WaterTile):
|
||||
self.vertex_list[y][x].tex_coords = tile.get_next_tex_coords()
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(800, 600, resizable=True, vsync=False )
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
pyglet.clock.schedule(lambda dt: None)
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
elif symbol == pyglet.window.key.P:
|
||||
pyglet.image.get_buffer_manager().get_color_buffer().save('screenshot.png')
|
||||
|
||||
class Interface(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
if IF_LEFT < x < (self.window.width-IF_RIGHT):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
if IF_BOTTOM < y < (self.window.height-IF_TOP):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
class LoadScreen(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="Linux Libertine",
|
||||
font_size=28,
|
||||
x=self.window.width-10, y=10,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
backgroundimg = pyglet.image.load("data/interface/gamselb1.pcx")
|
||||
self.background = pyglet.sprite.Sprite(backgroundimg)
|
||||
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
pyglet.clock.schedule_once(self.jsonloader, 0.0)
|
||||
|
||||
def on_draw(self):
|
||||
self.background.draw()
|
||||
self.label.draw()
|
||||
|
||||
def jsonloader(self, dt):
|
||||
h3m = json.loads(open("test.h3m").read())
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
pyglet.clock.schedule_once(self.loader2, 0.0, h3m["upper_terrain"])
|
||||
|
||||
def loader2(self, dt, loaded_map):
|
||||
edge_map = loaded_map
|
||||
# edge_map = [[] for i in xrange(len(loaded_map)+16)]
|
||||
# for num in xrange(len(edge_map)):
|
||||
# if num < 7 or num > len(edge_map)-8:
|
||||
# line = []
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0])+18)])
|
||||
# elif num == 7:
|
||||
# line = []
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# line.append([-1, 16, 0, 0, 0, 0, 0])
|
||||
# line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
|
||||
# line.append([-1, 17, 0, 0, 0, 0, 0])
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# elif num == len(edge_map)-8:
|
||||
# line = []
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# line.append([-1, 19, 0, 0, 0, 0, 0])
|
||||
# line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
|
||||
# line.append([-1, 18, 0, 0, 0, 0, 0])
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# else:
|
||||
# line = []
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
|
||||
# line.extend(loaded_map[num-8])
|
||||
# line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# edge_map[num] = line
|
||||
self.label.text = "INITIATING MAPSET..."
|
||||
pyglet.clock.schedule_once(self.loader3, 0.0, edge_map)
|
||||
|
||||
def loader3(self, dt, edge_map):
|
||||
mapset = MapSet(edge_map)
|
||||
self.label.text = "INITIATING MAPVIEW..."
|
||||
pyglet.clock.schedule_once(self.loader4, 0.0, mapset)
|
||||
|
||||
def loader4(self, dt, mapset):
|
||||
mapview = MapView(mapset, self.window)
|
||||
interface = Interface(self.window)
|
||||
self.window.pop_handlers()
|
||||
self.window.push_handlers(mapview)
|
||||
self.window.push_handlers(interface)
|
||||
img = pyglet.resource.image("data/cursors/0.png")
|
||||
self.window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
|
||||
if __name__ == '__main__':
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
window.push_handlers(LoadScreen(window))
|
||||
img = pyglet.resource.image("data/cursors/1.png")
|
||||
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
pyglet.app.run()
|
@ -0,0 +1,619 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import demjson as json
|
||||
json.loads = json.decode
|
||||
json.dumps = json.encode
|
||||
|
||||
IF_BOTTOM = 48
|
||||
IF_RIGHT = 200
|
||||
IF_TOP = IF_LEFT = 8
|
||||
|
||||
class OrderedTextureGroup(pyglet.graphics.Group):
|
||||
def __init__(self, order, texture, parent=None):
|
||||
super(OrderedTextureGroup, self).__init__(parent)
|
||||
self.texture = texture
|
||||
self.order = order
|
||||
|
||||
def set_state(self):
|
||||
pyglet.gl.glEnable(self.texture.target)
|
||||
pyglet.gl.glBindTexture(self.texture.target, self.texture.id)
|
||||
|
||||
def unset_state(self):
|
||||
pyglet.gl.glDisable(self.texture.target)
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.order, self.texture.target, self.texture.id, self.parent))
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.__class__ is other.__class__ and
|
||||
self.order == other.order and
|
||||
self.texture.target == other.texture.target and
|
||||
self.texture.id == other.texture.id and
|
||||
self.parent == self.parent)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(id=%d)' % (self.__class__.__name__, self.order, self.texture.id)
|
||||
|
||||
def __cmp__(self, other):
|
||||
if isinstance(other, OrderedTextureGroup):
|
||||
return cmp(self.order, other.order)
|
||||
return -1
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, frames):
|
||||
self.__frames = frames
|
||||
self.__animation = 0
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.__frames[self.__animation].tex_coords
|
||||
|
||||
tex_coords = property(get_tex_coords)
|
||||
|
||||
def get_next_tex_coords(self):
|
||||
self.__animation = (self.__animation+1)%len(self.__frames)
|
||||
return self.__frames[self.__animation].tex_coords
|
||||
|
||||
next_tex_coords = property(get_next_tex_coords)
|
||||
|
||||
class MapSet(object):
|
||||
def __init__(self, loaded_map, objects, tunedobj):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
#print len(pyglet.resource._default_loader._index)
|
||||
|
||||
atlas = pyglet.image.atlas.TextureAtlas(width=1024, height=1024)
|
||||
atlas2 = pyglet.image.atlas.TextureAtlas(width=2048, height=2048)
|
||||
self.texture_group = pyglet.graphics.TextureGroup(atlas.texture)
|
||||
self.group = pyglet.graphics.OrderedGroup(0, self.texture_group)
|
||||
self.texture_group2 = pyglet.graphics.TextureGroup(atlas2.texture)
|
||||
self.group_obj = pyglet.graphics.OrderedGroup(1, self.texture_group2)
|
||||
self.grass_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/grastl.def/%d.png'%i))) for i in xrange(79)]
|
||||
self.snow_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/snowtl.def/%d.png'%i))) for i in xrange(79)]
|
||||
self.lava_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/lavatl.def/%d.png'%i))) for i in xrange(79)]
|
||||
self.swamp_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/swmptl.def/%d.png'%i))) for i in xrange(79)]
|
||||
self.rough_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/rougtl.def/%d.png'%i))) for i in xrange(79)]
|
||||
self.dirt_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/dirttl.def/%d.png'%i))) for i in xrange(46)]
|
||||
self.rock_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/rocktl.def/%d.png'%i))) for i in xrange(48)]
|
||||
self.sand_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/sandtl.def/%d.png'%i))) for i in xrange(24)]
|
||||
self.water_tiles = [[atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/watrtl.def/%d/%d.png'%(j,i)))) for i in xrange(12)] for j in xrange(33)]
|
||||
self.edge_tiles = [atlas.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/edg.def/%d.png'%i))) for i in xrange(36)]
|
||||
self.tiles = {}
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == -1: #edge
|
||||
self.tiles[x,y] = Tile(self.edge_tiles[tile[1]])
|
||||
elif tile[0] == 0: #dirt
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[x,y] = self.dirt_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
self.tiles[x,y] = self.dirt_tiles[tile[1]]
|
||||
elif tile[0] == 1: #sand
|
||||
self.tiles[x,y] = self.sand_tiles[tile[1]]
|
||||
elif tile[0] == 2: #grass
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[x,y] = self.grass_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
self.tiles[x,y] = self.grass_tiles[tile[1]]
|
||||
elif tile[0] == 3: #snow
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[x,y] = self.snow_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
self.tiles[x,y] = self.snow_tiles[tile[1]]
|
||||
elif tile[0] == 4: #swamp
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[x,y] = self.swamp_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
self.tiles[x,y] = self.swamp_tiles[tile[1]]
|
||||
elif tile[0] == 5: #rough
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[x,y] = self.rough_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
self.tiles[x,y] = self.rough_tiles[tile[1]]
|
||||
elif tile[0] == 7: #lava
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
self.tiles[x,y] = self.lava_tiles[tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
self.tiles[x,y] = self.lava_tiles[tile[1]]
|
||||
elif tile[0] == 8: #water
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for tile in self.water_tiles[tile[1]]:
|
||||
tiles.append(tile.get_transform(flip_x=flip_x, flip_y=flip_y))
|
||||
self.tiles[x,y] = Animation(tiles)
|
||||
else:
|
||||
self.tiles[x,y] = Animation(self.water_tiles[tile[1]])
|
||||
elif tile[0] == 9: #rock
|
||||
self.tiles[x,y] = self.rock_tiles[tile[1]]
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
images = [(pyglet.image.load(None, file=pyglet.resource.file("data/map_objects/"+obj["filename"]+"/0.png")), i) for i,obj in enumerate(objects)]
|
||||
self.objects = [(atlas2.add(image[0]), image[1]) for image in sorted(images, key=lambda i:i[0].height, reverse=True)]
|
||||
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
|
||||
|
||||
self.tunedobj = {}
|
||||
for obj in [i for i in tunedobj if i["z"]==0]:
|
||||
if self.tunedobj.get((obj["x"], obj["y"]), None) is not None:
|
||||
self.tunedobj[obj["x"],obj["y"]].append(self.objects[obj["id"]])
|
||||
else:
|
||||
self.tunedobj[obj["x"],obj["y"]] = [self.objects[obj["id"]]]
|
||||
|
||||
self.clrrvr = [atlas2.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/0.png'%i))) for i in xrange(13)]
|
||||
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[2] == 1: #clrrvr
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
c = self.clrrvr[tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
c = self.clrrvr[tile[3]]
|
||||
if self.tunedobj.get((x, y), None) is not None:
|
||||
self.tunedobj[x, y].append(c)
|
||||
else:
|
||||
self.tunedobj[x, y] = [c]
|
||||
|
||||
|
||||
self.dirtrd = [atlas2.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/dirtrd.def/%d.png'%i))) for i in xrange(17)]
|
||||
self.gravrd = [atlas2.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/gravrd.def/%d.png'%i))) for i in xrange(17)]
|
||||
self.cobbrd = [atlas2.add(pyglet.image.load(None, file=pyglet.resource.file('data/tiles/cobbrd.def/%d.png'%i))) for i in xrange(17)]
|
||||
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[4] == 1: #dirtrd
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
c = self.dirtrd[tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
c = self.dirtrd[tile[5]]
|
||||
if self.tunedobj.get((x, y), None) is not None:
|
||||
self.tunedobj[x, y].append(c)
|
||||
else:
|
||||
self.tunedobj[x, y] = [c]
|
||||
elif tile[4] == 2: #gravrd
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
c = self.gravrd[tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
c = self.gravrd[tile[5]]
|
||||
if self.tunedobj.get((x, y), None) is not None:
|
||||
self.tunedobj[x, y].append(c)
|
||||
else:
|
||||
self.tunedobj[x, y] = [c]
|
||||
elif tile[4] == 3: #cobbrd
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
c = self.cobbrd[tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
c = self.cobbrd[tile[5]]
|
||||
if self.tunedobj.get((x, y), None) is not None:
|
||||
self.tunedobj[x, y].append(c)
|
||||
else:
|
||||
self.tunedobj[x, y] = [c]
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
|
||||
self._first_time_init()
|
||||
self._init_view()
|
||||
|
||||
#mouse position
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="",
|
||||
font_size=36,
|
||||
bold=True,
|
||||
color=(128, 128, 128, 128),
|
||||
x=self.window.width-10, y=0,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _first_time_init(self):
|
||||
self.tile_size = 32
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
#center map
|
||||
self.global_x = (self.mapset.width*self.tile_size-self.viewport_x+self.tile_size)//2
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)+(self.tile_size//2)
|
||||
|
||||
self.mouse_x = self.mouse_dx = 0
|
||||
self.mouse_y = self.mouse_dy = 0
|
||||
|
||||
def _init_view(self):
|
||||
#step one tile
|
||||
self.steps = self.tile_size
|
||||
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
|
||||
#center map when viewport is too large, else check if map still fills
|
||||
#whole viewport and if not adjust position accordingly
|
||||
self.center_x = False
|
||||
if self.mapset.width*self.tile_size < self.viewport_x:
|
||||
self.center_x = True
|
||||
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
|
||||
elif self.global_x > self.tile_size*self.mapset.width-self.viewport_x:
|
||||
self.global_x = self.tile_size*self.mapset.width-self.viewport_x
|
||||
elif self.global_x < 0:
|
||||
self.global_x = 0
|
||||
|
||||
self.center_y = False
|
||||
if self.mapset.height*self.tile_size < self.viewport_y:
|
||||
self.center_y = True
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
|
||||
elif self.global_y > self.tile_size*self.mapset.height-self.viewport_y:
|
||||
self.global_y = self.tile_size*self.mapset.height-self.viewport_y
|
||||
elif self.global_y < 0:
|
||||
self.global_y = 0
|
||||
|
||||
#drawn tiles
|
||||
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
|
||||
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
|
||||
|
||||
#undrawn map size
|
||||
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
|
||||
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
|
||||
#size of full undrawn steps
|
||||
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
|
||||
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
|
||||
|
||||
self.vertex_list = [[] for i in xrange(self.tiles_y)]
|
||||
self.vl_objects = [[] for i in xrange(self.tiles_y+4)]
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.view_x = 0
|
||||
self.view_y = 0
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
if trans_global_x < -self.undrawn_steps_x:
|
||||
mod_x = trans_global_x+self.undrawn_x
|
||||
elif trans_global_x < self.steps:
|
||||
mod_x = trans_global_x%self.steps
|
||||
else:
|
||||
mod_x = trans_global_x
|
||||
|
||||
if trans_global_y < -self.undrawn_steps_y:
|
||||
mod_y = trans_global_y+self.undrawn_y
|
||||
elif trans_global_y < self.steps:
|
||||
mod_y = trans_global_y%self.steps
|
||||
else:
|
||||
mod_y = trans_global_y
|
||||
|
||||
self.div_x = (trans_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
|
||||
for y in xrange(self.tiles_y-1, -1, -1):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
y2 = y1+32
|
||||
for x in xrange(self.tiles_x-1, -1, -1):
|
||||
x1 = x*32+IF_LEFT
|
||||
x2 = x1+32
|
||||
tile = self.mapset.tiles[x-self.div_x, self.div_y-y]
|
||||
self.vertex_list[y].insert(0, self.batch.add(4, pyglet.gl.GL_QUADS, self.mapset.group,
|
||||
('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
|
||||
('t3f', tile.tex_coords),
|
||||
('c4B', (255,255,255,255)*4)))
|
||||
|
||||
vertices = []
|
||||
tex_coords = []
|
||||
count = 0
|
||||
for y in xrange(self.tiles_y-1, -6, -1):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
for x in xrange(self.tiles_x+5-1, -1, -1):
|
||||
o = self.mapset.tunedobj.get((x-self.div_x, self.div_y-y), None)
|
||||
if(o is not None):
|
||||
for obj in o:
|
||||
x1 = x*32+IF_LEFT-obj.width+32
|
||||
x2 = x1+obj.width
|
||||
y2 = y1+obj.height
|
||||
vertices.extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
tex_coords.extend(obj.tex_coords)
|
||||
count+=4
|
||||
|
||||
self.vl_objects = self.batch.add(count, pyglet.gl.GL_QUADS,
|
||||
self.mapset.group_obj,
|
||||
('v2i', vertices),
|
||||
('t3f', tex_coords),
|
||||
('c4B', (255,255,255,255)*count))
|
||||
|
||||
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
|
||||
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
|
||||
pyglet.gl.glPushMatrix()
|
||||
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
|
||||
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
|
||||
self.batch.draw()
|
||||
pyglet.gl.glPopMatrix()
|
||||
pyglet.gl.glLoadIdentity()
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glColor4f(1, 0, 1, 1)
|
||||
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
|
||||
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
|
||||
self.label.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
new_global_x = trans_global_x+dx
|
||||
new_global_y = trans_global_y+dy
|
||||
|
||||
if self.global_x-dx < 0:
|
||||
new_global_x = self.steps
|
||||
if self.global_y-dy < 0:
|
||||
new_global_y = self.steps
|
||||
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
|
||||
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
|
||||
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
|
||||
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
|
||||
|
||||
retex = False
|
||||
|
||||
if new_global_x < -self.undrawn_steps_x:
|
||||
mod_x = new_global_x+self.undrawn_x
|
||||
if trans_global_x >= -self.undrawn_steps_x:
|
||||
retex = True
|
||||
elif new_global_x < self.steps:
|
||||
div_x, mod_x = divmod(new_global_x, self.steps)
|
||||
retex = div_x != trans_global_x//self.steps or retex
|
||||
else:
|
||||
mod_x = new_global_x
|
||||
|
||||
if new_global_y < -self.undrawn_steps_y:
|
||||
mod_y = new_global_y+self.undrawn_y
|
||||
if trans_global_y >= -self.undrawn_steps_y:
|
||||
retex = True
|
||||
elif new_global_y < self.steps:
|
||||
div_y, mod_y = divmod(new_global_y, self.steps)
|
||||
retex = div_y != trans_global_y//self.steps or retex
|
||||
else:
|
||||
mod_y = new_global_y
|
||||
|
||||
if retex:
|
||||
self.div_x = (new_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
for y in xrange(self.tiles_y-1, -1, -1):
|
||||
for x in xrange(self.tiles_x-1, -1, -1):
|
||||
tile = self.mapset.tiles[x-self.div_x, self.div_y-y]
|
||||
self.vertex_list[y][x].tex_coords = tile.tex_coords
|
||||
vertices = []
|
||||
tex_coords = []
|
||||
count = 0
|
||||
for y in xrange(self.tiles_y-1, -6, -1):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
for x in xrange(self.tiles_x+5-1, -1, -1):
|
||||
o = self.mapset.tunedobj.get((x-self.div_x, self.div_y-y), None)
|
||||
if(o is not None):
|
||||
for obj in o:
|
||||
x1 = x*32+IF_LEFT-obj.width+32
|
||||
x2 = x1+obj.width
|
||||
y2 = y1+obj.height
|
||||
tex_coords.extend(obj.tex_coords)
|
||||
vertices.extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
count+=4
|
||||
self.vl_objects.resize(count)
|
||||
self.vl_objects.tex_coords = tex_coords
|
||||
self.vl_objects.vertices = vertices
|
||||
self.vl_objects.colors = (255,255,255,255)*count
|
||||
|
||||
if not self.center_x:
|
||||
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
|
||||
self.global_x = self.steps-new_global_x
|
||||
if not self.center_y:
|
||||
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
|
||||
self.global_y = self.steps-new_global_y
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
elif self.window.keys[pyglet.window.key.PLUS] and \
|
||||
self.tile_size < 32:
|
||||
self.tile_size+=8
|
||||
self._init_view()
|
||||
elif self.window.keys[pyglet.window.key.MINUS] and \
|
||||
self.tile_size > 16:
|
||||
self.tile_size-=8
|
||||
self._init_view()
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
#mouse position:
|
||||
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
|
||||
self.mouse_x = self.mouse_dx
|
||||
self.mouse_y = self.mouse_dy
|
||||
x = (self.mouse_x-IF_LEFT-self.view_x
|
||||
-(self.tile_size-32)//4)//self.tile_size
|
||||
y = (self.mouse_y-IF_BOTTOM-self.view_y
|
||||
-((self.tile_size-32)*3)//2)//self.tile_size
|
||||
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
for y in xrange(self.tiles_y):
|
||||
for x in xrange(self.tiles_x):
|
||||
tile = self.mapset.tiles[x-self.div_x, self.div_y-y]
|
||||
if isinstance(tile, Animation):
|
||||
self.vertex_list[y][x].tex_coords = tile.next_tex_coords
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(1024, 768, resizable=True, vsync=False )
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
pyglet.clock.schedule(lambda dt: None)
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
elif symbol == pyglet.window.key.P:
|
||||
pyglet.image.get_buffer_manager().get_color_buffer().save('screenshot.png')
|
||||
|
||||
class Interface(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
if IF_LEFT < x < (self.window.width-IF_RIGHT):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
if IF_BOTTOM < y < (self.window.height-IF_TOP):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
class LoadScreen(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="Linux Libertine",
|
||||
font_size=28,
|
||||
x=self.window.width-10, y=10,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
h3m = json.loads(pyglet.resource.file("test.h3m").read())
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
# edge_map = [[] for i in xrange(len(loaded_map)+16)]
|
||||
# for num in xrange(len(edge_map)):
|
||||
# if num < 7 or num > len(edge_map)-8:
|
||||
# line = []
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0])+18)])
|
||||
# elif num == 7:
|
||||
# line = []
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# line.append([-1, 16, 0, 0, 0, 0, 0])
|
||||
# line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
|
||||
# line.append([-1, 17, 0, 0, 0, 0, 0])
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# elif num == len(edge_map)-8:
|
||||
# line = []
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# line.append([-1, 19, 0, 0, 0, 0, 0])
|
||||
# line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(loaded_map[0]))])
|
||||
# line.append([-1, 18, 0, 0, 0, 0, 0])
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# else:
|
||||
# line = []
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
|
||||
# line.extend(loaded_map[num-8])
|
||||
# line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
|
||||
# line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
# edge_map[num] = line
|
||||
self.label.text = "INITIATING MAPSET..."
|
||||
|
||||
mapset = MapSet(h3m["upper_terrain"], h3m["objects"], h3m["tunedobj"])
|
||||
self.label.text = "INITIATING MAPVIEW..."
|
||||
mapview = MapView(mapset, self.window)
|
||||
interface = Interface(self.window)
|
||||
self.window.pop_handlers()
|
||||
self.window.push_handlers(mapview)
|
||||
self.window.push_handlers(interface)
|
||||
self.window.push_handlers(self.window.keys)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
window.push_handlers(LoadScreen(window))
|
||||
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
|
||||
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
pyglet.app.run()
|
@ -0,0 +1,718 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import demjson as json
|
||||
json.loads = json.decode
|
||||
json.dumps = json.encode
|
||||
|
||||
IF_BOTTOM = 48
|
||||
IF_RIGHT = 200
|
||||
IF_TOP = IF_LEFT = 8
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, frames):
|
||||
self.__frames = frames
|
||||
self.__animation = 0
|
||||
self.width = frames[0].width
|
||||
self.height = frames[0].height
|
||||
|
||||
def next_frame(self):
|
||||
self.__animation = (self.__animation+1)%len(self.__frames)
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.__frames[self.__animation].tex_coords
|
||||
|
||||
tex_coords = property(get_tex_coords)
|
||||
|
||||
def get_group(self):
|
||||
return self.__frames[self.__animation].group
|
||||
|
||||
group = property(get_group)
|
||||
|
||||
class MapSet(object):
|
||||
def load_map_object(self, file, order=0):
|
||||
image = pyglet.image.load(None, file=pyglet.resource.file(file))
|
||||
try:
|
||||
texture_region = self.current_atlas.add(image)
|
||||
except pyglet.image.atlas.AllocatorException:
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(2048, 2048)
|
||||
print "atlas"
|
||||
texture_region = self.current_atlas.add(image)
|
||||
ordered_group = pyglet.graphics.OrderedGroup(order)
|
||||
group = pyglet.graphics.TextureGroup(self.current_atlas.texture, ordered_group)
|
||||
|
||||
if group not in self.groups:
|
||||
self.groups.append(group)
|
||||
|
||||
texture_region.group = self.groups.index(group)
|
||||
return texture_region
|
||||
|
||||
def __init__(self, loaded_map, objects, tunedobj):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(2048, 2048)
|
||||
print "atlas"
|
||||
|
||||
self.groups = []
|
||||
|
||||
self.tiles = {}
|
||||
tile_textures = {}
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == -1: #edge
|
||||
if "edg" not in tile_textures.keys():
|
||||
tile_textures["edg"] = [self.load_map_object('data/tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
|
||||
self.tiles[x,y] = [tile_textures["edg"][tile[1]]]
|
||||
elif tile[0] == 0: #dirt
|
||||
if "dirttl" not in tile_textures.keys():
|
||||
tile_textures["dirttl"] = [self.load_map_object('data/tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["dirttl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
|
||||
elif tile[0] == 1: #sand
|
||||
if "sandtl" not in tile_textures.keys():
|
||||
tile_textures["sandtl"] = [self.load_map_object('data/tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
|
||||
self.tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
|
||||
elif tile[0] == 2: #grass
|
||||
if "grastl" not in tile_textures.keys():
|
||||
tile_textures["grastl"] = [self.load_map_object('data/tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["grastl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["grastl"][tile[1]]]
|
||||
elif tile[0] == 3: #snow
|
||||
if "snowtl" not in tile_textures.keys():
|
||||
tile_textures["snowtl"] = [self.load_map_object('data/tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["snowtl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
|
||||
elif tile[0] == 4: #swamp
|
||||
if "swmptl" not in tile_textures.keys():
|
||||
tile_textures["swmptl"] = [self.load_map_object('data/tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["swmptl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
|
||||
elif tile[0] == 5: #rough
|
||||
if "rougtl" not in tile_textures.keys():
|
||||
tile_textures["rougtl"] = [self.load_map_object('data/tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["rougtl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
|
||||
elif tile[0] == 7: #lava
|
||||
if "lavatl" not in tile_textures.keys():
|
||||
tile_textures["lavatl"] = [self.load_map_object('data/tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["lavatl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
|
||||
elif tile[0] == 8: #water
|
||||
if "watrtl" not in tile_textures.keys():
|
||||
tile_textures["watrtl"] = []
|
||||
for j in xrange(33):
|
||||
tile_textures["watrtl"].append([self.load_map_object('data/tiles/watrtl.def/%d/%d.png'%(j,i), 0) for i in xrange(12)])
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for watrtl in tile_textures["watrtl"][tile[1]]:
|
||||
new = watrtl.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = watrtl.group
|
||||
tiles.append(new)
|
||||
self.tiles[x,y] = [Animation(tiles)]
|
||||
else:
|
||||
self.tiles[x,y] = [Animation(tile_textures["watrtl"][tile[1]])]
|
||||
elif tile[0] == 9: #rock
|
||||
if "rocktl" not in tile_textures.keys():
|
||||
tile_textures["rocktl"] = [self.load_map_object('data/tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
|
||||
self.tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
if tile[2] == 0: #no river
|
||||
pass
|
||||
elif tile[2] == 1: #clrrvr
|
||||
if "clrrvr" not in tile_textures.keys():
|
||||
tile_textures["clrrvr"] = [[self.load_map_object('data/tiles/clrrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(12)] for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for clrrvr in tile_textures["clrrvr"][tile[3]]:
|
||||
new = clrrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = clrrvr.group
|
||||
tiles.append(new)
|
||||
self.tiles[x, y].append(Animation(tiles))
|
||||
else:
|
||||
self.tiles[x, y].append(Animation(tile_textures["clrrvr"][tile[3]]))
|
||||
elif tile[2] == 2: #icyrvr
|
||||
if "icyrvr" not in tile_textures.keys():
|
||||
tile_textures["icyrvr"] = [self.load_map_object('data/tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["icyrvr"][tile[3]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
|
||||
elif tile[2] == 3: #mudrvr
|
||||
if "mudrvr" not in tile_textures.keys():
|
||||
tile_textures["mudrvr"] = [[self.load_map_object('data/tiles/mudrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(12)] for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for mudrvr in tile_textures["mudrvr"][tile[3]]:
|
||||
new = mudrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = mudrvr.group
|
||||
tiles.append(new)
|
||||
self.tiles[x, y].append(Animation(tiles))
|
||||
else:
|
||||
self.tiles[x, y].append(Animation(tile_textures["mudrvr"][tile[3]]))
|
||||
elif tile[2] == 4: #lavrvr
|
||||
if "lavrvr" not in tile_textures.keys():
|
||||
tile_textures["lavrvr"] = [[self.load_map_object('data/tiles/lavrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(9)] for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for lavrvr in tile_textures["lavrvr"][tile[3]]:
|
||||
new = lavrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = lavrvr.group
|
||||
tiles.append(new)
|
||||
self.tiles[x, y].append(Animation(tiles))
|
||||
else:
|
||||
self.tiles[x, y].append(Animation(tile_textures["lavrvr"][tile[3]]))
|
||||
else:
|
||||
raise NotImplementedError, tile[2]
|
||||
|
||||
if tile[4] == 0: #no road
|
||||
pass
|
||||
elif tile[4] == 1: #dirtrd
|
||||
if "dirtrd" not in tile_textures.keys():
|
||||
tile_textures["dirtrd"] = [self.load_map_object('data/tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["dirtrd"][tile[5]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
|
||||
elif tile[4] == 2: #gravrd
|
||||
if "gravrd" not in tile_textures.keys():
|
||||
tile_textures["gravrd"] = [self.load_map_object('data/tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["gravrd"][tile[5]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["gravrd"][tile[5]])
|
||||
elif tile[4] == 3: #cobbrd
|
||||
if "cobbrd" not in tile_textures.keys():
|
||||
tile_textures["cobbrd"] = [self.load_map_object('data/tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["cobbrd"][tile[5]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
|
||||
else:
|
||||
raise NotImplementedError, tile[4]
|
||||
|
||||
images = []
|
||||
for order, obj in enumerate(objects):
|
||||
imgs = []
|
||||
i = 0
|
||||
while 1:
|
||||
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/map_objects/"+obj["filename"]+"/%d.png"%i)))
|
||||
i+=1
|
||||
if "data/map_objects/"+obj["filename"]+"/%d.png"%i not in pyglet.resource._default_loader._index.keys():
|
||||
break;
|
||||
images.append((imgs, order))
|
||||
|
||||
self.objects = []
|
||||
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
|
||||
textures = []
|
||||
try:
|
||||
textures = [self.current_atlas.add(img) for img in imgs[0]]
|
||||
except pyglet.image.atlas.AllocatorException:
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(2048, 2048)
|
||||
print "atlas"
|
||||
textures = [self.current_atlas.add(img) for img in imgs[0]]
|
||||
ordered_group = pyglet.graphics.OrderedGroup(2)
|
||||
group = pyglet.graphics.TextureGroup(self.current_atlas.texture, ordered_group)
|
||||
if group not in self.groups:
|
||||
self.groups.append(group)
|
||||
group = self.groups.index(group)
|
||||
for texture in textures:
|
||||
texture.group = group
|
||||
self.objects.append((textures, imgs[1]))
|
||||
|
||||
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
|
||||
|
||||
self.tunedobj = {}
|
||||
for obj in [i for i in tunedobj if i["z"]==0]:
|
||||
if len(self.objects[obj["id"]]) == 1:
|
||||
self.tiles[obj["x"]+9,obj["y"]+8].append(self.objects[obj["id"]][0])
|
||||
else:
|
||||
self.tiles[obj["x"]+9,obj["y"]+8].append(Animation(self.objects[obj["id"]]))
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
|
||||
self._first_time_init()
|
||||
self._init_view()
|
||||
|
||||
#mouse position
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="",
|
||||
font_size=36,
|
||||
bold=True,
|
||||
color=(128, 128, 128, 128),
|
||||
x=self.window.width-10, y=0,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
|
||||
#pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _first_time_init(self):
|
||||
self.tile_size = 32
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
#center map
|
||||
self.global_x = (self.mapset.width*self.tile_size-self.viewport_x+self.tile_size)//2
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)+(self.tile_size//2)
|
||||
|
||||
self.mouse_x = self.mouse_dx = 0
|
||||
self.mouse_y = self.mouse_dy = 0
|
||||
|
||||
def _init_view(self):
|
||||
#step one tile
|
||||
self.steps = self.tile_size
|
||||
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
|
||||
#center map when viewport is too large, else check if map still fills
|
||||
#whole viewport and if not adjust position accordingly
|
||||
self.center_x = False
|
||||
if self.mapset.width*self.tile_size < self.viewport_x:
|
||||
self.center_x = True
|
||||
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
|
||||
elif self.global_x > self.tile_size*self.mapset.width-self.viewport_x:
|
||||
self.global_x = self.tile_size*self.mapset.width-self.viewport_x
|
||||
elif self.global_x < 0:
|
||||
self.global_x = 0
|
||||
|
||||
self.center_y = False
|
||||
if self.mapset.height*self.tile_size < self.viewport_y:
|
||||
self.center_y = True
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
|
||||
elif self.global_y > self.tile_size*self.mapset.height-self.viewport_y:
|
||||
self.global_y = self.tile_size*self.mapset.height-self.viewport_y
|
||||
elif self.global_y < 0:
|
||||
self.global_y = 0
|
||||
|
||||
#drawn tiles
|
||||
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
|
||||
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
|
||||
|
||||
#undrawn map size
|
||||
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
|
||||
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
|
||||
#size of full undrawn steps
|
||||
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
|
||||
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
|
||||
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.view_x = 0
|
||||
self.view_y = 0
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
if trans_global_x < -self.undrawn_steps_x:
|
||||
mod_x = trans_global_x+self.undrawn_x
|
||||
elif trans_global_x < self.steps:
|
||||
mod_x = trans_global_x%self.steps
|
||||
else:
|
||||
mod_x = trans_global_x
|
||||
|
||||
if trans_global_y < -self.undrawn_steps_y:
|
||||
mod_y = trans_global_y+self.undrawn_y
|
||||
elif trans_global_y < self.steps:
|
||||
mod_y = trans_global_y%self.steps
|
||||
else:
|
||||
mod_y = trans_global_y
|
||||
|
||||
self.div_x = (trans_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
|
||||
self.vl_objects = [None for i, value in enumerate(self.mapset.groups)]
|
||||
vertices = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
count = [0 for i, value in enumerate(self.mapset.groups)]
|
||||
|
||||
for y in xrange(self.tiles_y-1, -6, -1):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
for x in xrange(self.tiles_x+5-1, -1, -1):
|
||||
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
|
||||
x1 = x*32+IF_LEFT-obj.width+32
|
||||
x2 = x1+obj.width
|
||||
y2 = y1+obj.height
|
||||
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
tex_coords[obj.group].extend(obj.tex_coords)
|
||||
count[obj.group]+=4
|
||||
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if count[i] != 0:
|
||||
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
|
||||
group,
|
||||
('v2i', vertices[i]),
|
||||
('t3f', tex_coords[i]),
|
||||
('c4B', (255,255,255,255)*count[i]))
|
||||
|
||||
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
|
||||
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
|
||||
pyglet.gl.glPushMatrix()
|
||||
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
|
||||
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
|
||||
self.batch.draw()
|
||||
pyglet.gl.glPopMatrix()
|
||||
pyglet.gl.glLoadIdentity()
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glColor4f(1, 0, 1, 1)
|
||||
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
|
||||
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
|
||||
self.label.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
new_global_x = trans_global_x+dx
|
||||
new_global_y = trans_global_y+dy
|
||||
|
||||
if self.global_x-dx < 0:
|
||||
new_global_x = self.steps
|
||||
if self.global_y-dy < 0:
|
||||
new_global_y = self.steps
|
||||
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
|
||||
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
|
||||
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
|
||||
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
|
||||
|
||||
retex = False
|
||||
|
||||
if new_global_x < -self.undrawn_steps_x:
|
||||
mod_x = new_global_x+self.undrawn_x
|
||||
if trans_global_x >= -self.undrawn_steps_x:
|
||||
retex = True
|
||||
elif new_global_x < self.steps:
|
||||
div_x, mod_x = divmod(new_global_x, self.steps)
|
||||
retex = div_x != trans_global_x//self.steps or retex
|
||||
else:
|
||||
mod_x = new_global_x
|
||||
|
||||
if new_global_y < -self.undrawn_steps_y:
|
||||
mod_y = new_global_y+self.undrawn_y
|
||||
if trans_global_y >= -self.undrawn_steps_y:
|
||||
retex = True
|
||||
elif new_global_y < self.steps:
|
||||
div_y, mod_y = divmod(new_global_y, self.steps)
|
||||
retex = div_y != trans_global_y//self.steps or retex
|
||||
else:
|
||||
mod_y = new_global_y
|
||||
|
||||
if retex:
|
||||
self.div_x = (new_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
vertices = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
count = [0 for i, value in enumerate(self.mapset.groups)]
|
||||
for y in xrange(self.tiles_y-1, -6, -1):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
for x in xrange(self.tiles_x+5-1, -1, -1):
|
||||
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
|
||||
x1 = x*32+IF_LEFT-obj.width+32
|
||||
x2 = x1+obj.width
|
||||
y2 = y1+obj.height
|
||||
tex_coords[obj.group].extend(obj.tex_coords)
|
||||
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
count[obj.group]+=4
|
||||
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if count[i] == 0:
|
||||
if self.vl_objects[i] is None:
|
||||
pass
|
||||
else:
|
||||
self.vl_objects[i].delete()
|
||||
self.vl_objects[i] = None
|
||||
else:
|
||||
if self.vl_objects[i] is None:
|
||||
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
|
||||
group,
|
||||
('v2i', vertices[i]),
|
||||
('t3f', tex_coords[i]),
|
||||
('c4B', (255,255,255,255)*count[i]))
|
||||
else:
|
||||
self.vl_objects[i].resize(count[i])
|
||||
self.vl_objects[i].tex_coords = tex_coords[i]
|
||||
self.vl_objects[i].vertices = vertices[i]
|
||||
self.vl_objects[i].colors = (255,255,255,255)*count[i]
|
||||
|
||||
if not self.center_x:
|
||||
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
|
||||
self.global_x = self.steps-new_global_x
|
||||
if not self.center_y:
|
||||
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
|
||||
self.global_y = self.steps-new_global_y
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
elif self.window.keys[pyglet.window.key.PLUS] and \
|
||||
self.tile_size < 32:
|
||||
self.tile_size+=8
|
||||
self._init_view()
|
||||
elif self.window.keys[pyglet.window.key.MINUS] and \
|
||||
self.tile_size > 16:
|
||||
self.tile_size-=8
|
||||
self._init_view()
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
#mouse position:
|
||||
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
|
||||
self.mouse_x = self.mouse_dx
|
||||
self.mouse_y = self.mouse_dy
|
||||
x = (self.mouse_x-IF_LEFT-self.view_x
|
||||
-(self.tile_size-32)//4)//self.tile_size
|
||||
y = (self.mouse_y-IF_BOTTOM-self.view_y
|
||||
-((self.tile_size-32)*3)//2)//self.tile_size
|
||||
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
for y in xrange(self.tiles_y-1, -6, -1):
|
||||
for x in xrange(self.tiles_x+5-1, -1, -1):
|
||||
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
|
||||
if isinstance(obj, Animation):
|
||||
obj.next_frame()
|
||||
tex_coords[obj.group].extend(obj.tex_coords)
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if len(tex_coords[i]) != 0:
|
||||
self.vl_objects[i].tex_coords = tex_coords[i]
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
pyglet.clock.schedule(lambda dt: None)
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
elif symbol == pyglet.window.key.P:
|
||||
pyglet.image.get_buffer_manager().get_color_buffer().save('screenshot.png', encoder=PNGRGBEncoder())
|
||||
|
||||
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
|
||||
def encode(self, image, file, filename):
|
||||
import Image
|
||||
image = image.get_image_data()
|
||||
format = image.format
|
||||
pitch = -(image.width * len(format))
|
||||
pil_image = Image.fromstring(
|
||||
format, (image.width, image.height), image.get_data(format, pitch))
|
||||
try:
|
||||
#.convert('P', palette=Image.WEB)
|
||||
pil_image.convert("RGB").save(file)
|
||||
except Exception, e:
|
||||
raise ImageEncodeException(e)
|
||||
|
||||
|
||||
class Interface(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
if IF_LEFT < x < (self.window.width-IF_RIGHT):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
if IF_BOTTOM < y < (self.window.height-IF_TOP):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
class LoadScreen(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="Linux Libertine",
|
||||
font_size=28,
|
||||
x=self.window.width-10, y=10,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
h3m = json.loads(pyglet.resource.file("test.h3m").read())
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
edge_map = [[] for i in xrange(len(h3m["upper_terrain"])+16)]
|
||||
for num in xrange(len(edge_map)):
|
||||
if num < 7 or num > len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0])+18)])
|
||||
elif num == 7:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 16, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
|
||||
line.append([-1, 17, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
elif num == len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 19, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
|
||||
line.append([-1, 18, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
else:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend(h3m["upper_terrain"][num-8])
|
||||
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
edge_map[num] = line
|
||||
h3m["upper_terrain"] = edge_map
|
||||
self.label.text = "INITIATING MAPSET..."
|
||||
|
||||
mapset = MapSet(h3m["upper_terrain"], h3m["objects"], h3m["tunedobj"])
|
||||
self.label.text = "INITIATING MAPVIEW..."
|
||||
mapview = MapView(mapset, self.window)
|
||||
interface = Interface(self.window)
|
||||
self.window.pop_handlers()
|
||||
self.window.push_handlers(mapview)
|
||||
self.window.push_handlers(interface)
|
||||
self.window.push_handlers(self.window.keys)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
window.push_handlers(LoadScreen(window))
|
||||
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
|
||||
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
pyglet.app.run()
|
@ -0,0 +1,735 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import demjson as json
|
||||
json.loads = json.decode
|
||||
json.dumps = json.encode
|
||||
|
||||
IF_BOTTOM = 48
|
||||
IF_RIGHT = 200
|
||||
IF_TOP = IF_LEFT = 8
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, frames):
|
||||
self.__frames = frames
|
||||
self.__animation = 0
|
||||
self.width = frames[0].width
|
||||
self.height = frames[0].height
|
||||
|
||||
def next_frame(self):
|
||||
self.__animation = (self.__animation+1)%len(self.__frames)
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.__frames[self.__animation].tex_coords
|
||||
|
||||
tex_coords = property(get_tex_coords)
|
||||
|
||||
def get_group(self):
|
||||
return self.__frames[self.__animation].group
|
||||
|
||||
group = property(get_group)
|
||||
|
||||
class MapSet(object):
|
||||
def load_map_object(self, file, order=0):
|
||||
image = pyglet.image.load(None, file=pyglet.resource.file(file))
|
||||
try:
|
||||
texture_region = self.current_atlas.add(image)
|
||||
except pyglet.image.atlas.AllocatorException:
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(512, 512)
|
||||
print "atlas"
|
||||
texture_region = self.current_atlas.add(image)
|
||||
ordered_group = pyglet.graphics.OrderedGroup(order)
|
||||
group = pyglet.graphics.TextureGroup(self.current_atlas.texture, ordered_group)
|
||||
|
||||
if group not in self.groups:
|
||||
self.groups.append(group)
|
||||
|
||||
texture_region.group = self.groups.index(group)
|
||||
return texture_region
|
||||
|
||||
def __init__(self, loaded_map, objects, tunedobj):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(512, 512)
|
||||
print "atlas"
|
||||
|
||||
self.groups = []
|
||||
|
||||
self.tiles = {}
|
||||
tile_textures = {}
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == -1: #edge
|
||||
if "edg" not in tile_textures.keys():
|
||||
tile_textures["edg"] = [self.load_map_object('data/tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
|
||||
self.tiles[x,y] = [tile_textures["edg"][tile[1]]]
|
||||
elif tile[0] == 0: #dirt
|
||||
if "dirttl" not in tile_textures.keys():
|
||||
tile_textures["dirttl"] = [self.load_map_object('data/tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["dirttl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
|
||||
elif tile[0] == 1: #sand
|
||||
if "sandtl" not in tile_textures.keys():
|
||||
tile_textures["sandtl"] = [self.load_map_object('data/tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
|
||||
self.tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
|
||||
elif tile[0] == 2: #grass
|
||||
if "grastl" not in tile_textures.keys():
|
||||
tile_textures["grastl"] = [self.load_map_object('data/tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["grastl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["grastl"][tile[1]]]
|
||||
elif tile[0] == 3: #snow
|
||||
if "snowtl" not in tile_textures.keys():
|
||||
tile_textures["snowtl"] = [self.load_map_object('data/tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["snowtl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
|
||||
elif tile[0] == 4: #swamp
|
||||
if "swmptl" not in tile_textures.keys():
|
||||
tile_textures["swmptl"] = [self.load_map_object('data/tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["swmptl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
|
||||
elif tile[0] == 5: #rough
|
||||
if "rougtl" not in tile_textures.keys():
|
||||
tile_textures["rougtl"] = [self.load_map_object('data/tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["rougtl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
|
||||
elif tile[0] == 7: #lava
|
||||
if "lavatl" not in tile_textures.keys():
|
||||
tile_textures["lavatl"] = [self.load_map_object('data/tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["lavatl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
|
||||
elif tile[0] == 8: #water
|
||||
if "watrtl" not in tile_textures.keys():
|
||||
tile_textures["watrtl"] = []
|
||||
for j in xrange(33):
|
||||
tile_textures["watrtl"].append([self.load_map_object('data/tiles/watrtl.def/%d/%d.png'%(j,i), 0) for i in xrange(12)])
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for watrtl in tile_textures["watrtl"][tile[1]]:
|
||||
new = watrtl.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = watrtl.group
|
||||
tiles.append(new)
|
||||
self.tiles[x,y] = [Animation(tiles)]
|
||||
else:
|
||||
self.tiles[x,y] = [Animation(tile_textures["watrtl"][tile[1]])]
|
||||
elif tile[0] == 9: #rock
|
||||
if "rocktl" not in tile_textures.keys():
|
||||
tile_textures["rocktl"] = [self.load_map_object('data/tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
|
||||
self.tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
if tile[2] == 0: #no river
|
||||
pass
|
||||
elif tile[2] == 1: #clrrvr
|
||||
if "clrrvr" not in tile_textures.keys():
|
||||
tile_textures["clrrvr"] = [[self.load_map_object('data/tiles/clrrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(12)] for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for clrrvr in tile_textures["clrrvr"][tile[3]]:
|
||||
new = clrrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = clrrvr.group
|
||||
tiles.append(new)
|
||||
self.tiles[x, y].append(Animation(tiles))
|
||||
else:
|
||||
self.tiles[x, y].append(Animation(tile_textures["clrrvr"][tile[3]]))
|
||||
elif tile[2] == 2: #icyrvr
|
||||
if "icyrvr" not in tile_textures.keys():
|
||||
tile_textures["icyrvr"] = [self.load_map_object('data/tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["icyrvr"][tile[3]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
|
||||
elif tile[2] == 3: #mudrvr
|
||||
if "mudrvr" not in tile_textures.keys():
|
||||
tile_textures["mudrvr"] = [[self.load_map_object('data/tiles/mudrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(12)] for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for mudrvr in tile_textures["mudrvr"][tile[3]]:
|
||||
new = mudrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = mudrvr.group
|
||||
tiles.append(new)
|
||||
self.tiles[x, y].append(Animation(tiles))
|
||||
else:
|
||||
self.tiles[x, y].append(Animation(tile_textures["mudrvr"][tile[3]]))
|
||||
elif tile[2] == 4: #lavrvr
|
||||
if "lavrvr" not in tile_textures.keys():
|
||||
tile_textures["lavrvr"] = [[self.load_map_object('data/tiles/lavrvr.def/%d/%d.png'%(i, j), 1) for j in xrange(9)] for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
tiles = []
|
||||
for lavrvr in tile_textures["lavrvr"][tile[3]]:
|
||||
new = lavrvr.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = lavrvr.group
|
||||
tiles.append(new)
|
||||
self.tiles[x, y].append(Animation(tiles))
|
||||
else:
|
||||
self.tiles[x, y].append(Animation(tile_textures["lavrvr"][tile[3]]))
|
||||
else:
|
||||
raise NotImplementedError, tile[2]
|
||||
|
||||
if tile[4] == 0: #no road
|
||||
pass
|
||||
elif tile[4] == 1: #dirtrd
|
||||
if "dirtrd" not in tile_textures.keys():
|
||||
tile_textures["dirtrd"] = [self.load_map_object('data/tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["dirtrd"][tile[5]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
|
||||
elif tile[4] == 2: #gravrd
|
||||
if "gravrd" not in tile_textures.keys():
|
||||
tile_textures["gravrd"] = [self.load_map_object('data/tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["gravrd"][tile[5]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["gravrd"][tile[5]])
|
||||
elif tile[4] == 3: #cobbrd
|
||||
if "cobbrd" not in tile_textures.keys():
|
||||
tile_textures["cobbrd"] = [self.load_map_object('data/tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["cobbrd"][tile[5]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
|
||||
else:
|
||||
raise NotImplementedError, tile[4]
|
||||
|
||||
images = []
|
||||
for order, obj in enumerate(objects):
|
||||
imgs = []
|
||||
i = 0
|
||||
while 1:
|
||||
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/map_objects/"+obj["filename"]+"/%d.png"%i)))
|
||||
i+=1
|
||||
if "data/map_objects/"+obj["filename"]+"/%d.png"%i not in pyglet.resource._default_loader._index.keys():
|
||||
break;
|
||||
images.append((imgs, order))
|
||||
|
||||
self.objects = []
|
||||
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
|
||||
textures = []
|
||||
for img in imgs[0]:
|
||||
try:
|
||||
textures.append(self.current_atlas.add(img))
|
||||
except pyglet.image.atlas.AllocatorException:
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(512, 512)
|
||||
print "atlas"
|
||||
textures.append(self.current_atlas.add(img))
|
||||
ordered_group = pyglet.graphics.OrderedGroup(2)
|
||||
group = pyglet.graphics.TextureGroup(self.current_atlas.texture, ordered_group)
|
||||
if group not in self.groups:
|
||||
self.groups.append(group)
|
||||
group = self.groups.index(group)
|
||||
textures[-1].group = group
|
||||
self.objects.append((textures, imgs[1]))
|
||||
|
||||
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
|
||||
|
||||
self.tunedobj = {}
|
||||
for obj in [i for i in tunedobj if i["z"]==0]:
|
||||
if len(self.objects[obj["id"]]) == 1:
|
||||
self.tiles[obj["x"]+9,obj["y"]+8].append(self.objects[obj["id"]][0])
|
||||
else:
|
||||
self.tiles[obj["x"]+9,obj["y"]+8].append(Animation(self.objects[obj["id"]]))
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
|
||||
self._first_time_init()
|
||||
self._init_view()
|
||||
|
||||
#mouse position
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="",
|
||||
font_size=36,
|
||||
bold=True,
|
||||
color=(128, 128, 128, 128),
|
||||
x=self.window.width-10, y=0,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _first_time_init(self):
|
||||
self.tile_size = 32
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
#center map
|
||||
self.global_x = (self.mapset.width*self.tile_size-self.viewport_x+self.tile_size)//2
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)+(self.tile_size//2)
|
||||
|
||||
self.mouse_x = self.mouse_dx = 0
|
||||
self.mouse_y = self.mouse_dy = 0
|
||||
|
||||
def _init_view(self):
|
||||
#step one tile
|
||||
self.steps = self.tile_size
|
||||
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
|
||||
#center map when viewport is too large, else check if map still fills
|
||||
#whole viewport and if not adjust position accordingly
|
||||
self.center_x = False
|
||||
if self.mapset.width*self.tile_size < self.viewport_x:
|
||||
self.center_x = True
|
||||
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
|
||||
elif self.global_x > self.tile_size*self.mapset.width-self.viewport_x:
|
||||
self.global_x = self.tile_size*self.mapset.width-self.viewport_x
|
||||
elif self.global_x < 0:
|
||||
self.global_x = 0
|
||||
|
||||
self.center_y = False
|
||||
if self.mapset.height*self.tile_size < self.viewport_y:
|
||||
self.center_y = True
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
|
||||
elif self.global_y > self.tile_size*self.mapset.height-self.viewport_y:
|
||||
self.global_y = self.tile_size*self.mapset.height-self.viewport_y
|
||||
elif self.global_y < 0:
|
||||
self.global_y = 0
|
||||
|
||||
#drawn tiles
|
||||
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
|
||||
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
|
||||
|
||||
#undrawn map size
|
||||
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
|
||||
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
|
||||
#size of full undrawn steps
|
||||
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
|
||||
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
|
||||
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.view_x = 0
|
||||
self.view_y = 0
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
if trans_global_x < -self.undrawn_steps_x:
|
||||
mod_x = trans_global_x+self.undrawn_x
|
||||
elif trans_global_x < self.steps:
|
||||
mod_x = trans_global_x%self.steps
|
||||
else:
|
||||
mod_x = trans_global_x
|
||||
|
||||
if trans_global_y < -self.undrawn_steps_y:
|
||||
mod_y = trans_global_y+self.undrawn_y
|
||||
elif trans_global_y < self.steps:
|
||||
mod_y = trans_global_y%self.steps
|
||||
else:
|
||||
mod_y = trans_global_y
|
||||
|
||||
self.div_x = (trans_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
|
||||
self.vl_objects = [None for i, value in enumerate(self.mapset.groups)]
|
||||
vertices = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
count = [0 for i, value in enumerate(self.mapset.groups)]
|
||||
|
||||
for y in xrange(self.tiles_y-1, -6, -1):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
for x in xrange(self.tiles_x+5-1, -1, -1):
|
||||
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
|
||||
x1 = x*32+IF_LEFT-obj.width+32
|
||||
x2 = x1+obj.width
|
||||
y2 = y1+obj.height
|
||||
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
tex_coords[obj.group].extend(obj.tex_coords)
|
||||
count[obj.group]+=4
|
||||
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if count[i] != 0:
|
||||
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
|
||||
group,
|
||||
('v2i', vertices[i]),
|
||||
('t3f', tex_coords[i]),
|
||||
('c4B', (255,255,255,255)*count[i]))
|
||||
|
||||
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
|
||||
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
|
||||
pyglet.gl.glPushMatrix()
|
||||
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
|
||||
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
|
||||
self.batch.draw()
|
||||
pyglet.gl.glPopMatrix()
|
||||
pyglet.gl.glLoadIdentity()
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glColor4f(1, 0, 1, 1)
|
||||
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
|
||||
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
|
||||
self.label.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
new_global_x = trans_global_x+dx
|
||||
new_global_y = trans_global_y+dy
|
||||
|
||||
if self.global_x-dx < 0:
|
||||
new_global_x = self.steps
|
||||
if self.global_y-dy < 0:
|
||||
new_global_y = self.steps
|
||||
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
|
||||
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
|
||||
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
|
||||
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
|
||||
|
||||
retex = False
|
||||
|
||||
if new_global_x < -self.undrawn_steps_x:
|
||||
mod_x = new_global_x+self.undrawn_x
|
||||
if trans_global_x >= -self.undrawn_steps_x:
|
||||
retex = True
|
||||
elif new_global_x < self.steps:
|
||||
div_x, mod_x = divmod(new_global_x, self.steps)
|
||||
retex = div_x != trans_global_x//self.steps or retex
|
||||
else:
|
||||
mod_x = new_global_x
|
||||
|
||||
if new_global_y < -self.undrawn_steps_y:
|
||||
mod_y = new_global_y+self.undrawn_y
|
||||
if trans_global_y >= -self.undrawn_steps_y:
|
||||
retex = True
|
||||
elif new_global_y < self.steps:
|
||||
div_y, mod_y = divmod(new_global_y, self.steps)
|
||||
retex = div_y != trans_global_y//self.steps or retex
|
||||
else:
|
||||
mod_y = new_global_y
|
||||
|
||||
if retex:
|
||||
self.div_x = (new_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
vertices = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
count = [0 for i, value in enumerate(self.mapset.groups)]
|
||||
for y in xrange(self.tiles_y-1, -6, -1):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
for x in xrange(self.tiles_x+5-1, -1, -1):
|
||||
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
|
||||
x1 = x*32+IF_LEFT-obj.width+32
|
||||
x2 = x1+obj.width
|
||||
y2 = y1+obj.height
|
||||
tex_coords[obj.group].extend(obj.tex_coords)
|
||||
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
count[obj.group]+=4
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if count[i] == 0:
|
||||
if self.vl_objects[i] is not None:
|
||||
self.vl_objects[i].delete()
|
||||
self.vl_objects[i] = None
|
||||
elif count[i] != 0 and self.vl_objects[i] is None:
|
||||
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
|
||||
group,
|
||||
('v2i', vertices[i]),
|
||||
('t3f', tex_coords[i]),
|
||||
('c4B', (255,255,255,255)*count[i]))
|
||||
else:
|
||||
self.vl_objects[i].resize(count[i])
|
||||
self.vl_objects[i].tex_coords = tex_coords[i]
|
||||
self.vl_objects[i].vertices = vertices[i]
|
||||
self.vl_objects[i].colors = (255,255,255,255)*count[i]
|
||||
|
||||
if not self.center_x:
|
||||
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
|
||||
self.global_x = self.steps-new_global_x
|
||||
if not self.center_y:
|
||||
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
|
||||
self.global_y = self.steps-new_global_y
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
elif self.window.keys[pyglet.window.key.PLUS] and \
|
||||
self.tile_size < 32:
|
||||
self.tile_size+=8
|
||||
self._init_view()
|
||||
elif self.window.keys[pyglet.window.key.MINUS] and \
|
||||
self.tile_size > 16:
|
||||
self.tile_size-=8
|
||||
self._init_view()
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
#mouse position:
|
||||
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
|
||||
self.mouse_x = self.mouse_dx
|
||||
self.mouse_y = self.mouse_dy
|
||||
x = (self.mouse_x-IF_LEFT-self.view_x
|
||||
-(self.tile_size-32)//4)//self.tile_size
|
||||
y = (self.mouse_y-IF_BOTTOM-self.view_y
|
||||
-((self.tile_size-32)*3)//2)//self.tile_size
|
||||
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
count = [0 for i, value in enumerate(self.mapset.groups)]
|
||||
vertices = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
for y in xrange(self.tiles_y-1, -6, -1):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
for x in xrange(self.tiles_x+5-1, -1, -1):
|
||||
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
|
||||
x1 = x*32+IF_LEFT-obj.width+32
|
||||
x2 = x1+obj.width
|
||||
y2 = y1+obj.height
|
||||
if isinstance(obj, Animation):
|
||||
obj.next_frame()
|
||||
tex_coords[obj.group].extend(obj.tex_coords)
|
||||
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
count[obj.group]+=4
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if count[i] == 0:
|
||||
if self.vl_objects[i] is not None:
|
||||
self.vl_objects[i].delete()
|
||||
self.vl_objects[i] = None
|
||||
elif count[i] != 0 and self.vl_objects[i] is None:
|
||||
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
|
||||
group,
|
||||
('v2i', vertices[i]),
|
||||
('t3f', tex_coords[i]),
|
||||
('c4B', (255,255,255,255)*count[i]))
|
||||
else:
|
||||
self.vl_objects[i].resize(count[i])
|
||||
self.vl_objects[i].tex_coords = tex_coords[i]
|
||||
self.vl_objects[i].vertices = vertices[i]
|
||||
self.vl_objects[i].colors = (255,255,255,255)*count[i]
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
pyglet.clock.schedule(lambda dt: None)
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
elif symbol == pyglet.window.key.P:
|
||||
pyglet.image.get_buffer_manager().get_color_buffer().save('screenshot.png', encoder=PNGRGBEncoder())
|
||||
|
||||
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
|
||||
def encode(self, image, file, filename):
|
||||
import Image
|
||||
image = image.get_image_data()
|
||||
format = image.format
|
||||
pitch = -(image.width * len(format))
|
||||
pil_image = Image.fromstring(
|
||||
format, (image.width, image.height), image.get_data(format, pitch))
|
||||
try:
|
||||
#.convert('P', palette=Image.WEB)
|
||||
pil_image.convert("RGB").save(file)
|
||||
except Exception, e:
|
||||
raise ImageEncodeException(e)
|
||||
|
||||
|
||||
class Interface(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
if IF_LEFT < x < (self.window.width-IF_RIGHT):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
if IF_BOTTOM < y < (self.window.height-IF_TOP):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
class LoadScreen(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="Linux Libertine",
|
||||
font_size=28,
|
||||
x=self.window.width-10, y=10,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
h3m = json.loads(pyglet.resource.file("test.h3m").read())
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
edge_map = [[] for i in xrange(len(h3m["upper_terrain"])+16)]
|
||||
for num in xrange(len(edge_map)):
|
||||
if num < 7 or num > len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0])+18)])
|
||||
elif num == 7:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 16, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
|
||||
line.append([-1, 17, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
elif num == len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 19, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
|
||||
line.append([-1, 18, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
else:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend(h3m["upper_terrain"][num-8])
|
||||
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
edge_map[num] = line
|
||||
h3m["upper_terrain"] = edge_map
|
||||
self.label.text = "INITIATING MAPSET..."
|
||||
|
||||
mapset = MapSet(h3m["upper_terrain"], h3m["objects"], h3m["tunedobj"])
|
||||
self.label.text = "INITIATING MAPVIEW..."
|
||||
mapview = MapView(mapset, self.window)
|
||||
interface = Interface(self.window)
|
||||
self.window.pop_handlers()
|
||||
self.window.push_handlers(mapview)
|
||||
self.window.push_handlers(interface)
|
||||
self.window.push_handlers(self.window.keys)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
window.push_handlers(LoadScreen(window))
|
||||
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
|
||||
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
pyglet.app.run()
|
@ -0,0 +1,775 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet, re
|
||||
from ctypes import create_string_buffer, memmove
|
||||
import itertools
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import demjson as json
|
||||
json.loads = json.decode
|
||||
json.dumps = json.encode
|
||||
|
||||
IF_BOTTOM = 48
|
||||
IF_RIGHT = 200
|
||||
IF_TOP = IF_LEFT = 8
|
||||
|
||||
class OrderedTextureGroup(pyglet.graphics.Group):
|
||||
def __init__(self, order, texture, parent=None):
|
||||
super(OrderedTextureGroup, self).__init__(parent)
|
||||
self.texture = texture
|
||||
self.order = order
|
||||
|
||||
def set_state(self):
|
||||
pyglet.gl.glEnable(self.texture.target)
|
||||
pyglet.gl.glBindTexture(self.texture.target, self.texture.id)
|
||||
|
||||
def unset_state(self):
|
||||
pyglet.gl.glDisable(self.texture.target)
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.order, self.texture.target, self.texture.id,
|
||||
self.parent))
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.__class__ is other.__class__ and
|
||||
self.order == other.order and
|
||||
self.texture.target == other.texture.target and
|
||||
self.texture.id == other.texture.id and
|
||||
self.parent == self.parent)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(id=%d)' % (self.__class__.__name__, self.order,
|
||||
self.texture.id)
|
||||
|
||||
def __cmp__(self, other):
|
||||
if isinstance(other, OrderedTextureGroup):
|
||||
return cmp(self.order, other.order)
|
||||
return -1
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, tex_region, frames, flip_x=False, flip_y=False):
|
||||
self.texgroup = tex_region.group
|
||||
if flip_x or flip_y:
|
||||
self.tex = tex_region.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
self.tex = tex_region
|
||||
self.__frames = []
|
||||
for img in frames:
|
||||
data_pitch = abs(img._current_pitch)
|
||||
buf = create_string_buffer(len(img._current_data))
|
||||
memmove(buf, img._current_data, len(img._current_data))
|
||||
data = buf.raw
|
||||
rows = [data[i:i+abs(data_pitch)] for i in
|
||||
xrange(len(img._current_data)-abs(data_pitch),
|
||||
-1, -abs(data_pitch))]
|
||||
self.__frames.append(''.join(rows))
|
||||
self.__animation = 0
|
||||
self.width = self.tex.width
|
||||
self.height = self.tex.height
|
||||
self.__hash = hash(self.__frames[0])
|
||||
|
||||
def next_frame(self):
|
||||
self.__animation = (self.__animation+1)%len(self.__frames)
|
||||
return self.__frames[self.__animation]
|
||||
|
||||
def get_tex_coords(self):
|
||||
return self.tex.tex_coords
|
||||
|
||||
tex_coords = property(get_tex_coords)
|
||||
|
||||
def get_group(self):
|
||||
return self.texgroup
|
||||
|
||||
group = property(get_group)
|
||||
|
||||
def __hash__(self):
|
||||
return self.__hash
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.__hash == other.__hash
|
||||
|
||||
class MapSet(object):
|
||||
def load_map_object(self, file, order=0):
|
||||
image = pyglet.image.load(None, file=pyglet.resource.file(file))
|
||||
try:
|
||||
texture_region = self.current_atlas.add(image)
|
||||
except pyglet.image.atlas.AllocatorException:
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
texture_region = self.current_atlas.add(image)
|
||||
group = OrderedTextureGroup(order, self.current_atlas.texture)
|
||||
|
||||
if group not in self.groups:
|
||||
self.groups.append(group)
|
||||
|
||||
texture_region.group = self.groups.index(group)
|
||||
return texture_region
|
||||
|
||||
def __init__(self, loaded_map, objects, tunedobj):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
|
||||
self.groups = []
|
||||
|
||||
self.tiles = {}
|
||||
tile_textures = {}
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == -1: #edge
|
||||
if "edg" not in tile_textures.keys():
|
||||
tile_textures["edg"] = [self.load_map_object('data/tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
|
||||
self.tiles[x,y] = [tile_textures["edg"][tile[1]]]
|
||||
elif tile[0] == 0: #dirt
|
||||
if "dirttl" not in tile_textures.keys():
|
||||
tile_textures["dirttl"] = [self.load_map_object('data/tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["dirttl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
|
||||
elif tile[0] == 1: #sand
|
||||
if "sandtl" not in tile_textures.keys():
|
||||
tile_textures["sandtl"] = [self.load_map_object('data/tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
|
||||
self.tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
|
||||
elif tile[0] == 2: #grass
|
||||
if "grastl" not in tile_textures.keys():
|
||||
tile_textures["grastl"] = [self.load_map_object('data/tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["grastl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["grastl"][tile[1]]]
|
||||
elif tile[0] == 3: #snow
|
||||
if "snowtl" not in tile_textures.keys():
|
||||
tile_textures["snowtl"] = [self.load_map_object('data/tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["snowtl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
|
||||
elif tile[0] == 4: #swamp
|
||||
if "swmptl" not in tile_textures.keys():
|
||||
tile_textures["swmptl"] = [self.load_map_object('data/tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["swmptl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
|
||||
elif tile[0] == 5: #rough
|
||||
if "rougtl" not in tile_textures.keys():
|
||||
tile_textures["rougtl"] = [self.load_map_object('data/tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["rougtl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
|
||||
elif tile[0] == 7: #lava
|
||||
if "lavatl" not in tile_textures.keys():
|
||||
tile_textures["lavatl"] = [self.load_map_object('data/tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["lavatl"][tile[1]].group
|
||||
self.tiles[x,y] = [new]
|
||||
else:
|
||||
self.tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
|
||||
elif tile[0] == 8: #water 12 anims
|
||||
if "watrtl" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/tiles/watrtl.def/%d/0.png'%i, 0) for i in xrange(33)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/watrtl.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(33)]
|
||||
tile_textures["watrtl"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>0)&1
|
||||
flip_y = (tile[6]>>1)&1
|
||||
self.tiles[x,y] = [tile_textures["watrtl"][flip_x, flip_y][tile[1]]]
|
||||
elif tile[0] == 9: #rock
|
||||
if "rocktl" not in tile_textures.keys():
|
||||
tile_textures["rocktl"] = [self.load_map_object('data/tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
|
||||
self.tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
if tile[2] == 0: #no river
|
||||
pass
|
||||
elif tile[2] == 1: #clrrvr 12 anims
|
||||
if "clrrvr" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/tiles/clrrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
|
||||
tile_textures["clrrvr"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>2)&1
|
||||
flip_y = (tile[6]>>3)&1
|
||||
self.tiles[x,y].append(tile_textures["clrrvr"][flip_x, flip_y][tile[3]])
|
||||
elif tile[2] == 2: #icyrvr
|
||||
if "icyrvr" not in tile_textures.keys():
|
||||
tile_textures["icyrvr"] = [self.load_map_object('data/tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["icyrvr"][tile[3]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
|
||||
elif tile[2] == 3: #mudrvr
|
||||
if "mudrvr" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/tiles/mudrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
|
||||
tile_textures["mudrvr"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>2)&1
|
||||
flip_y = (tile[6]>>3)&1
|
||||
self.tiles[x,y].append(tile_textures["mudrvr"][flip_x, flip_y][tile[3]])
|
||||
elif tile[2] == 4: #lavrvr
|
||||
if "lavrvr" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/tiles/lavrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(9)] for i in xrange(13)]
|
||||
tile_textures["lavrvr"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>2)&1
|
||||
flip_y = (tile[6]>>3)&1
|
||||
self.tiles[x,y].append(tile_textures["lavrvr"][flip_x, flip_y][tile[3]])
|
||||
else:
|
||||
raise NotImplementedError, tile[2]
|
||||
|
||||
if tile[4] == 0: #no road
|
||||
pass
|
||||
elif tile[4] == 1: #dirtrd
|
||||
if "dirtrd" not in tile_textures.keys():
|
||||
tile_textures["dirtrd"] = [self.load_map_object('data/tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["dirtrd"][tile[5]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
|
||||
elif tile[4] == 2: #gravrd
|
||||
if "gravrd" not in tile_textures.keys():
|
||||
tile_textures["gravrd"] = [self.load_map_object('data/tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["gravrd"][tile[5]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["gravrd"][tile[5]])
|
||||
elif tile[4] == 3: #cobbrd
|
||||
if "cobbrd" not in tile_textures.keys():
|
||||
tile_textures["cobbrd"] = [self.load_map_object('data/tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["cobbrd"][tile[5]].group
|
||||
self.tiles[x, y].append(new)
|
||||
else:
|
||||
self.tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
|
||||
else:
|
||||
raise NotImplementedError, tile[4]
|
||||
|
||||
images = []
|
||||
for order, obj in enumerate(objects):
|
||||
imgs = []
|
||||
i = 0
|
||||
while 1:
|
||||
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/map_objects/"+obj["filename"]+"/%d.png"%i)))
|
||||
i+=1
|
||||
if "data/map_objects/"+obj["filename"]+"/%d.png"%i not in pyglet.resource._default_loader._index.keys():
|
||||
break;
|
||||
images.append((imgs, order))
|
||||
|
||||
self.objects = []
|
||||
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
|
||||
try:
|
||||
texture = self.current_atlas.add(imgs[0][0])
|
||||
except pyglet.image.atlas.AllocatorException:
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
print "atlas"
|
||||
texture = self.current_atlas.add(imgs[0][0])
|
||||
group = OrderedTextureGroup(2, self.current_atlas.texture)
|
||||
if group not in self.groups:
|
||||
self.groups.append(group)
|
||||
group = self.groups.index(group)
|
||||
texture.group = group
|
||||
self.objects.append((Animation(texture, imgs[0]), imgs[1]))
|
||||
|
||||
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
|
||||
|
||||
self.tunedobj = {}
|
||||
for obj in [i for i in tunedobj if i["z"]==0]:
|
||||
self.tiles[obj["x"]+9,obj["y"]+8].append(self.objects[obj["id"]])
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
|
||||
self._first_time_init()
|
||||
self._init_view()
|
||||
|
||||
#mouse position
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="",
|
||||
font_size=36,
|
||||
bold=True,
|
||||
color=(128, 128, 128, 128),
|
||||
x=self.window.width-10, y=0,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _first_time_init(self):
|
||||
self.tile_size = 32
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
#center map
|
||||
self.global_x = (self.mapset.width*self.tile_size-self.viewport_x
|
||||
+self.tile_size)//2
|
||||
self.global_y = (self.mapset.height*self.tile_size-self.viewport_y
|
||||
+self.tile_size)//2
|
||||
|
||||
self.mouse_x = self.mouse_dx = 0
|
||||
self.mouse_y = self.mouse_dy = 0
|
||||
|
||||
def _init_view(self):
|
||||
#step one tile
|
||||
self.steps = self.tile_size
|
||||
|
||||
self.viewport_x = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.viewport_y = self.window.height-IF_BOTTOM-IF_TOP
|
||||
|
||||
#center map when viewport is too large, else check if map still fills
|
||||
#whole viewport and if not adjust position accordingly
|
||||
self.center_x = False
|
||||
if self.mapset.width*self.tile_size < self.viewport_x:
|
||||
self.center_x = True
|
||||
self.global_x = (self.mapset.width*self.tile_size)//2-(self.viewport_x//2)
|
||||
elif self.global_x > self.tile_size*self.mapset.width-self.viewport_x:
|
||||
self.global_x = self.tile_size*self.mapset.width-self.viewport_x
|
||||
elif self.global_x < 0:
|
||||
self.global_x = 0
|
||||
|
||||
self.center_y = False
|
||||
if self.mapset.height*self.tile_size < self.viewport_y:
|
||||
self.center_y = True
|
||||
self.global_y = (self.mapset.height*self.tile_size)//2-(self.viewport_y//2)
|
||||
elif self.global_y > self.tile_size*self.mapset.height-self.viewport_y:
|
||||
self.global_y = self.tile_size*self.mapset.height-self.viewport_y
|
||||
elif self.global_y < 0:
|
||||
self.global_y = 0
|
||||
|
||||
#drawn tiles
|
||||
self.tiles_x = min((self.viewport_x//self.tile_size)+2, self.mapset.width)
|
||||
self.tiles_y = min((self.viewport_y//self.tile_size)+2, self.mapset.height)
|
||||
|
||||
#undrawn map size
|
||||
self.undrawn_x = self.tile_size*(self.mapset.width-self.tiles_x)
|
||||
self.undrawn_y = self.tile_size*(self.mapset.height-self.tiles_y)
|
||||
#size of full undrawn steps
|
||||
self.undrawn_steps_x = self.steps*(self.undrawn_x//self.steps)
|
||||
self.undrawn_steps_y = self.steps*(self.undrawn_y//self.steps)
|
||||
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
|
||||
self.view_x = 0
|
||||
self.view_y = 0
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
if trans_global_x < -self.undrawn_steps_x:
|
||||
mod_x = trans_global_x+self.undrawn_x
|
||||
elif trans_global_x < self.steps:
|
||||
mod_x = trans_global_x%self.steps
|
||||
else:
|
||||
mod_x = trans_global_x
|
||||
|
||||
if trans_global_y < -self.undrawn_steps_y:
|
||||
mod_y = trans_global_y+self.undrawn_y
|
||||
elif trans_global_y < self.steps:
|
||||
mod_y = trans_global_y%self.steps
|
||||
else:
|
||||
mod_y = trans_global_y
|
||||
|
||||
self.div_x = (trans_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (trans_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
|
||||
self.vl_objects = [None for i, value in enumerate(self.mapset.groups)]
|
||||
vertices = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
count = [0 for i, value in enumerate(self.mapset.groups)]
|
||||
self.cur_objects = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
|
||||
for y in xrange(self.tiles_y-1, -6, -1):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
for x in xrange(self.tiles_x+5-1, -1, -1):
|
||||
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
|
||||
x1 = x*32+IF_LEFT-obj.width+32
|
||||
x2 = x1+obj.width
|
||||
y2 = y1+obj.height
|
||||
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
tex_coords[obj.group].extend(obj.tex_coords)
|
||||
count[obj.group]+=4
|
||||
if isinstance(obj, Animation):
|
||||
self.cur_objects[obj.group].append(obj)
|
||||
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if count[i] != 0:
|
||||
self.vl_objects[i] = self.batch.add(count[i], pyglet.gl.GL_QUADS,
|
||||
group,
|
||||
('v2i', vertices[i]),
|
||||
('t3f', tex_coords[i]),
|
||||
('c4B', (255,255,255,255)*count[i]))
|
||||
self.cur_objects[i] = list(set(self.cur_objects[i]))
|
||||
|
||||
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
|
||||
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
|
||||
pyglet.gl.glPushMatrix()
|
||||
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
|
||||
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
|
||||
self.batch.draw()
|
||||
pyglet.gl.glPopMatrix()
|
||||
pyglet.gl.glLoadIdentity()
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glColor4f(1, 0, 1, 1)
|
||||
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
|
||||
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
|
||||
self.label.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
#here we translate the global map position so we can draw with it
|
||||
trans_global_x = self.steps-self.global_x
|
||||
trans_global_y = self.steps-self.global_y
|
||||
|
||||
new_global_x = trans_global_x+dx
|
||||
new_global_y = trans_global_y+dy
|
||||
|
||||
if self.global_x-dx < 0:
|
||||
new_global_x = self.steps
|
||||
if self.global_y-dy < 0:
|
||||
new_global_y = self.steps
|
||||
if dx-self.global_x < -self.tile_size*self.mapset.width+self.viewport_x:
|
||||
new_global_x = -self.tile_size*self.mapset.width+self.viewport_x+self.steps
|
||||
if dy-self.global_y < -self.tile_size*self.mapset.height+self.viewport_y:
|
||||
new_global_y = -self.tile_size*self.mapset.height+self.viewport_y+self.steps
|
||||
|
||||
retex = False
|
||||
|
||||
if new_global_x < -self.undrawn_steps_x:
|
||||
mod_x = new_global_x+self.undrawn_x
|
||||
if trans_global_x >= -self.undrawn_steps_x:
|
||||
retex = True
|
||||
elif new_global_x < self.steps:
|
||||
div_x, mod_x = divmod(new_global_x, self.steps)
|
||||
retex = div_x != trans_global_x//self.steps or retex
|
||||
else:
|
||||
mod_x = new_global_x
|
||||
|
||||
if new_global_y < -self.undrawn_steps_y:
|
||||
mod_y = new_global_y+self.undrawn_y
|
||||
if trans_global_y >= -self.undrawn_steps_y:
|
||||
retex = True
|
||||
elif new_global_y < self.steps:
|
||||
div_y, mod_y = divmod(new_global_y, self.steps)
|
||||
retex = div_y != trans_global_y//self.steps or retex
|
||||
else:
|
||||
mod_y = new_global_y
|
||||
|
||||
if retex:
|
||||
self.div_x = (new_global_x-mod_x)//self.tile_size
|
||||
self.div_y = (new_global_y-mod_y)//self.tile_size+self.mapset.height-1
|
||||
vertices = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
tex_coords = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
count = [0 for i, value in enumerate(self.mapset.groups)]
|
||||
self.cur_objects = [[] for i, value in enumerate(self.mapset.groups)]
|
||||
for y in xrange(self.tiles_y-1, -6, -1):
|
||||
y1 = y*32+IF_BOTTOM
|
||||
for x in xrange(self.tiles_x+5-1, -1, -1):
|
||||
for obj in self.mapset.tiles.get((x-self.div_x, self.div_y-y), []):
|
||||
x1 = x*32+IF_LEFT-obj.width+32
|
||||
x2 = x1+obj.width
|
||||
y2 = y1+obj.height
|
||||
tex_coords[obj.group].extend(obj.tex_coords)
|
||||
vertices[obj.group].extend([x1, y1, x2, y1, x2, y2, x1, y2])
|
||||
count[obj.group]+=4
|
||||
if isinstance(obj, Animation):
|
||||
self.cur_objects[obj.group].append(obj)
|
||||
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if count[i] == 0:
|
||||
if self.vl_objects[i] is None:
|
||||
pass
|
||||
else:
|
||||
self.vl_objects[i].delete()
|
||||
self.vl_objects[i] = None
|
||||
else:
|
||||
if self.vl_objects[i] is None:
|
||||
self.vl_objects[i] = self.batch.add(count[i],
|
||||
pyglet.gl.GL_QUADS,
|
||||
group,
|
||||
('v2i', vertices[i]),
|
||||
('t3f', tex_coords[i]),
|
||||
('c4B', (255,255,255,255)*count[i]))
|
||||
else:
|
||||
self.vl_objects[i].resize(count[i])
|
||||
self.vl_objects[i].tex_coords = tex_coords[i]
|
||||
self.vl_objects[i].vertices = vertices[i]
|
||||
self.vl_objects[i].colors = (255,255,255,255)*count[i]
|
||||
self.cur_objects[i] = list(set(self.cur_objects[i]))
|
||||
|
||||
|
||||
if not self.center_x:
|
||||
self.view_x = mod_x-self.steps-(self.tile_size-32)//4
|
||||
self.global_x = self.steps-new_global_x
|
||||
if not self.center_y:
|
||||
self.view_y = mod_y-self.steps-((self.tile_size-32)*3)//2
|
||||
self.global_y = self.steps-new_global_y
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
elif self.window.keys[pyglet.window.key.PLUS] and \
|
||||
self.tile_size < 32:
|
||||
self.tile_size+=8
|
||||
self._init_view()
|
||||
elif self.window.keys[pyglet.window.key.MINUS] and \
|
||||
self.tile_size > 16:
|
||||
self.tile_size-=8
|
||||
self._init_view()
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
#mouse position:
|
||||
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
|
||||
self.mouse_x = self.mouse_dx
|
||||
self.mouse_y = self.mouse_dy
|
||||
x = (self.mouse_x-IF_LEFT-self.view_x
|
||||
-(self.tile_size-32)//4)//self.tile_size
|
||||
y = (self.mouse_y-IF_BOTTOM-self.view_y
|
||||
-((self.tile_size-32)*3)//2)//self.tile_size
|
||||
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if len(self.cur_objects[i]) > 0:
|
||||
pyglet.gl.glBindTexture(self.cur_objects[i][0].tex.target,
|
||||
self.cur_objects[i][0].tex.id)
|
||||
for obj in self.cur_objects[i]:
|
||||
pyglet.gl.glTexSubImage2D(obj.tex.owner.target,
|
||||
obj.tex.owner.level,
|
||||
obj.tex.x, obj.tex.y,
|
||||
obj.tex.width, obj.tex.height,
|
||||
pyglet.gl.GL_RGBA, pyglet.gl.GL_UNSIGNED_BYTE,
|
||||
obj.next_frame())
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
pyglet.clock.schedule(lambda dt: None)
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
elif symbol == pyglet.window.key.P:
|
||||
pyglet.image.get_buffer_manager().get_color_buffer().save(
|
||||
'screenshot.png', encoder=PNGRGBEncoder())
|
||||
|
||||
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
|
||||
def encode(self, image, file, filename):
|
||||
import Image
|
||||
image = image.get_image_data()
|
||||
format = image.format
|
||||
pitch = -(image.width * len(format))
|
||||
pil_image = Image.fromstring(
|
||||
format, (image.width, image.height), image.get_data(format, pitch))
|
||||
try:
|
||||
#.convert('P', palette=Image.WEB)
|
||||
pil_image.convert("RGB").save(file)
|
||||
except Exception, e:
|
||||
raise ImageEncodeException(e)
|
||||
|
||||
|
||||
class Interface(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
if IF_LEFT < x < (self.window.width-IF_RIGHT):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
if IF_BOTTOM < y < (self.window.height-IF_TOP):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
class LoadScreen(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="Linux Libertine",
|
||||
font_size=28,
|
||||
x=self.window.width-10, y=10,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
h3m = json.loads(pyglet.resource.file("test.h3m").read())
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
edge_map = [[] for i in xrange(len(h3m["upper_terrain"])+16)]
|
||||
for num in xrange(len(edge_map)):
|
||||
if num < 7 or num > len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0])+18)])
|
||||
elif num == 7:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 16, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
|
||||
line.append([-1, 17, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
elif num == len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 19, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
|
||||
line.append([-1, 18, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
else:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend(h3m["upper_terrain"][num-8])
|
||||
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
edge_map[num] = line
|
||||
h3m["upper_terrain"] = edge_map
|
||||
self.label.text = "INITIATING MAPSET..."
|
||||
|
||||
mapset = MapSet(h3m["upper_terrain"], h3m["objects"], h3m["tunedobj"])
|
||||
self.label.text = "INITIATING MAPVIEW..."
|
||||
mapview = MapView(mapset, self.window)
|
||||
interface = Interface(self.window)
|
||||
self.window.pop_handlers()
|
||||
self.window.push_handlers(mapview)
|
||||
self.window.push_handlers(interface)
|
||||
self.window.push_handlers(self.window.keys)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,
|
||||
pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
window.push_handlers(LoadScreen(window))
|
||||
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
|
||||
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
pyglet.app.run()
|
@ -0,0 +1,787 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet, re
|
||||
from ctypes import create_string_buffer, memmove
|
||||
import itertools
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import demjson as json
|
||||
json.loads = json.decode
|
||||
json.dumps = json.encode
|
||||
|
||||
IF_BOTTOM = 0#48
|
||||
IF_RIGHT = 0#200
|
||||
IF_TOP = IF_LEFT = 0#8
|
||||
|
||||
class OrderedTextureGroup(pyglet.graphics.Group):
|
||||
def __init__(self, order, texture, parent=None):
|
||||
super(OrderedTextureGroup, self).__init__(parent)
|
||||
self.texture = texture
|
||||
self.order = order
|
||||
|
||||
def set_state(self):
|
||||
pyglet.gl.glEnable(self.texture.target)
|
||||
pyglet.gl.glBindTexture(self.texture.target, self.texture.id)
|
||||
|
||||
def unset_state(self):
|
||||
pyglet.gl.glDisable(self.texture.target)
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.order, self.texture.target, self.texture.id,
|
||||
self.parent))
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.__class__ is other.__class__ and
|
||||
self.order == other.order and
|
||||
self.texture.target == other.texture.target and
|
||||
self.texture.id == other.texture.id and
|
||||
self.parent == self.parent)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(id=%d)' % (self.__class__.__name__, self.order,
|
||||
self.texture.id)
|
||||
|
||||
def __cmp__(self, other):
|
||||
if isinstance(other, OrderedTextureGroup):
|
||||
return cmp(self.order, other.order)
|
||||
return -1
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, tex_region, frames, flip_x=False, flip_y=False):
|
||||
self.texgroup = tex_region.group
|
||||
if flip_x or flip_y:
|
||||
self.tex = tex_region.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
self.tex = tex_region
|
||||
self.__frames = []
|
||||
for img in frames:
|
||||
data_pitch = abs(img._current_pitch)
|
||||
buf = create_string_buffer(len(img._current_data))
|
||||
memmove(buf, img._current_data, len(img._current_data))
|
||||
data = buf.raw
|
||||
rows = [data[i:i + abs(data_pitch)] for i in
|
||||
xrange(len(img._current_data)-abs(data_pitch),
|
||||
-1, -abs(data_pitch))]
|
||||
self.__frames.append(''.join(rows))
|
||||
self.__animation = 0
|
||||
self.width = self.tex.width
|
||||
self.height = self.tex.height
|
||||
self.__hash = hash(self.__frames[0])
|
||||
|
||||
def next_frame(self):
|
||||
self.__animation = (self.__animation + 1) % len(self.__frames)
|
||||
return self.__frames[self.__animation]
|
||||
|
||||
@property
|
||||
def tex_coords(self):
|
||||
return self.tex.tex_coords
|
||||
|
||||
@property
|
||||
def group(self):
|
||||
return self.texgroup
|
||||
|
||||
def __hash__(self):
|
||||
return self.__hash
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.__hash == other.__hash
|
||||
|
||||
class MapSet(object):
|
||||
def load_map_object(self, file, order=0):
|
||||
image = pyglet.image.load(None, file=pyglet.resource.file(file))
|
||||
try:
|
||||
texture_region = self.current_atlas.add(image)
|
||||
except pyglet.image.atlas.AllocatorException:
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
texture_region = self.current_atlas.add(image)
|
||||
group = OrderedTextureGroup(order, self.current_atlas.texture)
|
||||
|
||||
if group not in self.groups:
|
||||
self.groups.append(group)
|
||||
|
||||
texture_region.group = self.groups.index(group)
|
||||
return texture_region
|
||||
|
||||
def __init__(self, loaded_map, objects, tunedobj):
|
||||
self.width = len(loaded_map[0])
|
||||
self.height = len(loaded_map)
|
||||
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
|
||||
self.groups = []
|
||||
|
||||
self.__tiles = {}
|
||||
tile_textures = {}
|
||||
for y, line in enumerate(loaded_map):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == -1: #edge
|
||||
if "edg" not in tile_textures.keys():
|
||||
tile_textures["edg"] = [self.load_map_object('data/tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
|
||||
self.__tiles[x,y] = [tile_textures["edg"][tile[1]]]
|
||||
elif tile[0] == 0: #dirt
|
||||
if "dirttl" not in tile_textures.keys():
|
||||
tile_textures["dirttl"] = [self.load_map_object('data/tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["dirttl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
|
||||
elif tile[0] == 1: #sand
|
||||
if "sandtl" not in tile_textures.keys():
|
||||
tile_textures["sandtl"] = [self.load_map_object('data/tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
|
||||
self.__tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
|
||||
elif tile[0] == 2: #grass
|
||||
if "grastl" not in tile_textures.keys():
|
||||
tile_textures["grastl"] = [self.load_map_object('data/tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["grastl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["grastl"][tile[1]]]
|
||||
elif tile[0] == 3: #snow
|
||||
if "snowtl" not in tile_textures.keys():
|
||||
tile_textures["snowtl"] = [self.load_map_object('data/tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["snowtl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
|
||||
elif tile[0] == 4: #swamp
|
||||
if "swmptl" not in tile_textures.keys():
|
||||
tile_textures["swmptl"] = [self.load_map_object('data/tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["swmptl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
|
||||
elif tile[0] == 5: #rough
|
||||
if "rougtl" not in tile_textures.keys():
|
||||
tile_textures["rougtl"] = [self.load_map_object('data/tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["rougtl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
|
||||
elif tile[0] == 7: #lava
|
||||
if "lavatl" not in tile_textures.keys():
|
||||
tile_textures["lavatl"] = [self.load_map_object('data/tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["lavatl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
|
||||
elif tile[0] == 8: #water 12 anims
|
||||
if "watrtl" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/tiles/watrtl.def/%d/0.png'%i, 0) for i in xrange(33)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/watrtl.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(33)]
|
||||
tile_textures["watrtl"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>0)&1
|
||||
flip_y = (tile[6]>>1)&1
|
||||
self.__tiles[x,y] = [tile_textures["watrtl"][flip_x, flip_y][tile[1]]]
|
||||
elif tile[0] == 9: #rock
|
||||
if "rocktl" not in tile_textures.keys():
|
||||
tile_textures["rocktl"] = [self.load_map_object('data/tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
|
||||
self.__tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
if tile[2] == 0: #no river
|
||||
pass
|
||||
elif tile[2] == 1: #clrrvr 12 anims
|
||||
if "clrrvr" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/tiles/clrrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
|
||||
tile_textures["clrrvr"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>2)&1
|
||||
flip_y = (tile[6]>>3)&1
|
||||
self.__tiles[x,y].append(tile_textures["clrrvr"][flip_x, flip_y][tile[3]])
|
||||
elif tile[2] == 2: #icyrvr
|
||||
if "icyrvr" not in tile_textures.keys():
|
||||
tile_textures["icyrvr"] = [self.load_map_object('data/tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["icyrvr"][tile[3]].group
|
||||
self.__tiles[x, y].append(new)
|
||||
else:
|
||||
self.__tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
|
||||
elif tile[2] == 3: #mudrvr
|
||||
if "mudrvr" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/tiles/mudrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
|
||||
tile_textures["mudrvr"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>2)&1
|
||||
flip_y = (tile[6]>>3)&1
|
||||
self.__tiles[x,y].append(tile_textures["mudrvr"][flip_x, flip_y][tile[3]])
|
||||
elif tile[2] == 4: #lavrvr
|
||||
if "lavrvr" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/tiles/lavrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(9)] for i in xrange(13)]
|
||||
tile_textures["lavrvr"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>2)&1
|
||||
flip_y = (tile[6]>>3)&1
|
||||
self.__tiles[x,y].append(tile_textures["lavrvr"][flip_x, flip_y][tile[3]])
|
||||
else:
|
||||
raise NotImplementedError, tile[2]
|
||||
|
||||
if tile[4] == 0: #no road
|
||||
pass
|
||||
elif tile[4] == 1: #dirtrd
|
||||
if "dirtrd" not in tile_textures.keys():
|
||||
tile_textures["dirtrd"] = [self.load_map_object('data/tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["dirtrd"][tile[5]].group
|
||||
self.__tiles[x, y].append(new)
|
||||
else:
|
||||
self.__tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
|
||||
elif tile[4] == 2: #gravrd
|
||||
if "gravrd" not in tile_textures.keys():
|
||||
tile_textures["gravrd"] = [self.load_map_object('data/tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["gravrd"][tile[5]].group
|
||||
self.__tiles[x, y].append(new)
|
||||
else:
|
||||
self.__tiles[x, y].append(tile_textures["gravrd"][tile[5]])
|
||||
elif tile[4] == 3: #cobbrd
|
||||
if "cobbrd" not in tile_textures.keys():
|
||||
tile_textures["cobbrd"] = [self.load_map_object('data/tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["cobbrd"][tile[5]].group
|
||||
self.__tiles[x, y].append(new)
|
||||
else:
|
||||
self.__tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
|
||||
else:
|
||||
raise NotImplementedError, tile[4]
|
||||
|
||||
images = []
|
||||
for order, obj in enumerate(objects):
|
||||
imgs = []
|
||||
i = 0
|
||||
while 1:
|
||||
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/map_objects/" + obj["filename"] + "/%d.png"%i)))
|
||||
i += 1
|
||||
if "data/map_objects/" + obj["filename"] + "/%d.png" % i not in pyglet.resource._default_loader._index.keys():
|
||||
break;
|
||||
images.append((imgs, order))
|
||||
|
||||
self.objects = []
|
||||
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
|
||||
try:
|
||||
texture = self.current_atlas.add(imgs[0][0])
|
||||
except pyglet.image.atlas.AllocatorException:
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
print "atlas"
|
||||
texture = self.current_atlas.add(imgs[0][0])
|
||||
group = OrderedTextureGroup(2, self.current_atlas.texture)
|
||||
if group not in self.groups:
|
||||
self.groups.append(group)
|
||||
group = self.groups.index(group)
|
||||
texture.group = group
|
||||
self.objects.append((Animation(texture, imgs[0]), imgs[1]))
|
||||
|
||||
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
|
||||
|
||||
self.tunedobj = {}
|
||||
for obj in [i for i in tunedobj if i["z"]==0]:
|
||||
self.__tiles[obj["x"] + 9,obj["y"] + 8].append(self.objects[obj["id"]])
|
||||
|
||||
def get_tiles(self, tiles_x, tiles_y, div_x, div_y):
|
||||
for y in xrange(tiles_y - 1, -6, -1):
|
||||
y1 = y * 32 + IF_BOTTOM
|
||||
for x in xrange(tiles_x + 5 - 1, -1, -1):
|
||||
for obj in self.__tiles.get((x - div_x, div_y - y), []):
|
||||
x1 = x * 32 + IF_LEFT - obj.width + 32
|
||||
x2 = x1 + obj.width
|
||||
y2 = y1 + obj.height
|
||||
yield obj, [x1, y1, x2, y1, x2, y2, x1, y2]
|
||||
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
self._first_time_init()
|
||||
self._init_view()
|
||||
# mouse position
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="",
|
||||
font_size=36,
|
||||
bold=True,
|
||||
color=(128, 128, 128, 128),
|
||||
x=self.window.width - 10, y=0,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _first_time_init(self):
|
||||
self.tile_size = 32
|
||||
# size of the viewport
|
||||
self.vp_width = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.vp_height = self.window.height-IF_BOTTOM-IF_TOP
|
||||
# center map
|
||||
self.x = (self.mapset.width * self.tile_size - self.vp_width +
|
||||
self.tile_size) // 2
|
||||
self.y = (self.mapset.height * self.tile_size - self.vp_height +
|
||||
self.tile_size) // 2
|
||||
self.mouse_x = self.mouse_dx = 0
|
||||
self.mouse_y = self.mouse_dy = 0
|
||||
|
||||
def _init_view(self):
|
||||
# initiate new batch
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
# initiate new vertex list
|
||||
self.vl_objects = [None for value in self.mapset.groups]
|
||||
# size of the viewport
|
||||
self.vp_width = self.window.width - IF_RIGHT - IF_LEFT
|
||||
self.vp_height = self.window.height - IF_BOTTOM - IF_TOP
|
||||
# center map when viewport is too large, else check if map still fills
|
||||
# whole viewport and if not adjust position accordingly
|
||||
self.center_x = False
|
||||
if self.mapset.width * self.tile_size < self.vp_width:
|
||||
# center the map in x direction
|
||||
self.center_x = True
|
||||
self.x = (self.mapset.width * self.tile_size - self.vp_width) // 2
|
||||
elif self.x > self.tile_size * self.mapset.width - self.vp_width:
|
||||
# move map back to the right
|
||||
self.x = self.tile_size * self.mapset.width - self.vp_width
|
||||
elif self.x < 0:
|
||||
# move map to the left
|
||||
self.x = 0
|
||||
self.center_y = False
|
||||
if self.mapset.height * self.tile_size < self.vp_height:
|
||||
# center the map in y direction
|
||||
self.center_y = True
|
||||
self.y = (self.mapset.height * self.tile_size -
|
||||
self.vp_height) // 2
|
||||
elif self.y > self.tile_size * self.mapset.height - self.vp_height:
|
||||
# move map up
|
||||
self.y = self.tile_size * self.mapset.height - self.vp_height
|
||||
elif self.y < 0:
|
||||
# move map down
|
||||
self.y = 0
|
||||
# tiles to be drawn with the current viewport size
|
||||
self.tiles_x = min((self.vp_width // self.tile_size) + 2,
|
||||
self.mapset.width)
|
||||
self.tiles_y = min((self.vp_height // self.tile_size) + 2,
|
||||
self.mapset.height)
|
||||
# undrawn map size in pixels
|
||||
self.undrawn_x = self.tile_size * (self.mapset.width - self.tiles_x)
|
||||
self.undrawn_y = self.tile_size * (self.mapset.height - self.tiles_y)
|
||||
# reset mouse or keyboard movement
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
# calculate modulo pixel position of the map
|
||||
if self.x - self.tile_size > self.undrawn_x:
|
||||
# dont go right beyond map borders
|
||||
mod_x = self.tile_size - self.x + self.undrawn_x
|
||||
elif self.x > 0:
|
||||
# calculate modulo of current position and tile_size
|
||||
mod_x = (self.tile_size - self.x) % self.tile_size
|
||||
else:
|
||||
# dont go left beyond map borders
|
||||
mod_x = self.tile_size - self.x
|
||||
if self.y - self.tile_size > self.undrawn_y:
|
||||
# dont go up beyond map borders
|
||||
mod_y = self.tile_size - self.y + self.undrawn_y
|
||||
elif self.y > 0:
|
||||
# calculate modulo of current position and tile_size
|
||||
mod_y = (self.tile_size - self.y) % self.tile_size
|
||||
else:
|
||||
# dont go down beyond map borders
|
||||
mod_y = self.tile_size - self.y
|
||||
# calculate tile position of the map, turn y coordinates upside down
|
||||
self.div_x = (self.tile_size - self.x - mod_x) // self.tile_size
|
||||
self.div_y = (self.tile_size - self.y - mod_y) // self.tile_size + \
|
||||
self.mapset.height - 1
|
||||
# update vertex lists with the gathered information
|
||||
self.update_vertex_lists()
|
||||
# update current current position that is to be glTranslated
|
||||
# XXX: dont ask me why i have to add 1/4 and 3/2 but when i do not
|
||||
# there are black borders when zooming out
|
||||
# plz explain wtf is going on there
|
||||
self.view_x = mod_x - self.tile_size - (self.tile_size - 32) // 4
|
||||
self.view_y = mod_y - self.tile_size - ((self.tile_size - 32) * 3) // 2
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
|
||||
pyglet.gl.glPushMatrix()
|
||||
pyglet.gl.glTranslatef(self.view_x, self.view_y, 0)
|
||||
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
|
||||
self.batch.draw()
|
||||
pyglet.gl.glPopMatrix()
|
||||
pyglet.gl.glLoadIdentity()
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glColor4f(1, 0, 1, 1)
|
||||
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
|
||||
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
|
||||
self.label.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
# new map position
|
||||
new_x = self.x - dx
|
||||
new_y = self.y - dy
|
||||
# only update textures and vertices when necessary
|
||||
retex = False
|
||||
# if x or y jump is too big, adjust new position accordingly
|
||||
if new_x < 0:
|
||||
# move map to the left
|
||||
new_x = 0
|
||||
retex = True
|
||||
if new_x > self.tile_size * self.mapset.width - self.vp_width:
|
||||
# move map to the right
|
||||
new_x = self.tile_size * self.mapset.width - self.vp_width
|
||||
retex = True
|
||||
if new_y < 0:
|
||||
# move map down
|
||||
new_y = 0
|
||||
retex = True
|
||||
if new_y > self.tile_size * self.mapset.height - self.vp_height:
|
||||
# move map up
|
||||
new_y = self.tile_size * self.mapset.height - self.vp_height
|
||||
retex = True
|
||||
# find out how many steps and pixels we have to move and wether we have
|
||||
# to retex
|
||||
if new_x - self.tile_size > self.undrawn_x:
|
||||
# we are at the right border
|
||||
mod_x = self.tile_size - new_x + self.undrawn_x
|
||||
# only retex if the last position was not at the border
|
||||
if self.x - self.tile_size <= self.undrawn_x:
|
||||
retex = True
|
||||
elif new_x > 0:
|
||||
# normal movement: calculate the amount of steps and the modulo
|
||||
div_x, mod_x = divmod(self.tile_size - new_x, self.tile_size)
|
||||
# only retex if the number of moved steps is not equal to last
|
||||
if div_x != (self.tile_size - self.x) // self.tile_size:
|
||||
retex = True
|
||||
else:
|
||||
# we are at the left border
|
||||
mod_x = self.tile_size - new_x
|
||||
if new_y - self.tile_size > self.undrawn_y:
|
||||
# we are at the top
|
||||
mod_y = self.tile_size - new_y + self.undrawn_y
|
||||
# only retex if the last position was not at the border
|
||||
if self.y - self.tile_size <= self.undrawn_y:
|
||||
retex = True
|
||||
elif new_y > 0:
|
||||
# normal movement: calculate the amount of steps and the modulo
|
||||
div_y, mod_y = divmod(self.tile_size - new_y, self.tile_size)
|
||||
# only retex if the number of moved steps is not equal to last
|
||||
if div_y != (self.tile_size - self.y) // self.tile_size:
|
||||
retex = True
|
||||
else:
|
||||
# we are at the bottom
|
||||
mod_y = self.tile_size - new_y
|
||||
# if we have to update vertices and textures
|
||||
if retex:
|
||||
# calculate the current position on the tilemap
|
||||
self.div_x = (self.tile_size - new_x - mod_x) // \
|
||||
self.tile_size
|
||||
self.div_y = (self.tile_size - new_y - mod_y) // \
|
||||
self.tile_size + self.mapset.height - 1
|
||||
self.update_vertex_lists()
|
||||
# update position if not centered
|
||||
# XXX: dont ask me why i have to add 1/4 and 3/2 but when i do not
|
||||
# there are black borders when zooming out
|
||||
# plz explain wtf is going on there
|
||||
if not self.center_x:
|
||||
self.view_x = mod_x-self.tile_size-(self.tile_size-32)//4
|
||||
self.x = new_x
|
||||
if not self.center_y:
|
||||
self.view_y = mod_y-self.tile_size-((self.tile_size-32)*3)//2
|
||||
self.y = new_y
|
||||
|
||||
def update_vertex_lists(self):
|
||||
# initiate lists of vertex lists, vertices, texture coords, vertices
|
||||
# counts and map objects for each group
|
||||
vertices = [[] for value in self.mapset.groups]
|
||||
tex_coords = [[] for value in self.mapset.groups]
|
||||
count = [0 for value in self.mapset.groups]
|
||||
self.cur_objects = [[] for value in self.mapset.groups]
|
||||
# for each tile in the viewport, update the list of the specific group
|
||||
for obj, coords in self.mapset.get_tiles(self.tiles_x, self.tiles_y,
|
||||
self.div_x, self.div_y):
|
||||
tex_coords[obj.group].extend(obj.tex_coords)
|
||||
vertices[obj.group].extend(coords)
|
||||
count[obj.group]+=4
|
||||
if isinstance(obj, Animation):
|
||||
self.cur_objects[obj.group].append(obj)
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if count[i] == 0:
|
||||
if self.vl_objects[i] is None:
|
||||
# let the vertex list be None
|
||||
pass
|
||||
else:
|
||||
# there was a vertex list but now no more - delete it
|
||||
self.vl_objects[i].delete()
|
||||
self.vl_objects[i] = None
|
||||
else:
|
||||
if self.vl_objects[i] is None:
|
||||
# there was no vertex list but ther now is one - create it
|
||||
self.vl_objects[i] = self.batch.add(count[i],
|
||||
pyglet.gl.GL_QUADS,
|
||||
group,
|
||||
('v2i', vertices[i]),
|
||||
('t3f', tex_coords[i]),
|
||||
('c4B', (255,255,255,255)*count[i]))
|
||||
else:
|
||||
# there already is a vertex list - resize and refill
|
||||
self.vl_objects[i].resize(count[i])
|
||||
self.vl_objects[i].tex_coords = tex_coords[i]
|
||||
self.vl_objects[i].vertices = vertices[i]
|
||||
self.vl_objects[i].colors = (255,255,255,255)*count[i]
|
||||
# make object list unique
|
||||
self.cur_objects[i] = list(set(self.cur_objects[i]))
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
elif self.window.keys[pyglet.window.key.PLUS] and \
|
||||
self.tile_size < 32:
|
||||
self.tile_size+=8
|
||||
self._init_view()
|
||||
elif self.window.keys[pyglet.window.key.MINUS] and \
|
||||
self.tile_size > 16:
|
||||
self.tile_size-=8
|
||||
self._init_view()
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
# mouse position:
|
||||
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
|
||||
self.mouse_x = self.mouse_dx
|
||||
self.mouse_y = self.mouse_dy
|
||||
x = (self.mouse_x-IF_LEFT-self.view_x
|
||||
-(self.tile_size-32)//4)//self.tile_size
|
||||
y = (self.mouse_y-IF_BOTTOM-self.view_y
|
||||
-((self.tile_size-32)*3)//2)//self.tile_size
|
||||
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if len(self.cur_objects[i]) > 0:
|
||||
pyglet.gl.glBindTexture(self.cur_objects[i][0].tex.target,
|
||||
self.cur_objects[i][0].tex.id)
|
||||
for obj in self.cur_objects[i]:
|
||||
pyglet.gl.glTexSubImage2D(obj.tex.owner.target,
|
||||
obj.tex.owner.level,
|
||||
obj.tex.x, obj.tex.y,
|
||||
obj.tex.width, obj.tex.height,
|
||||
pyglet.gl.GL_RGBA, pyglet.gl.GL_UNSIGNED_BYTE,
|
||||
obj.next_frame())
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
pyglet.clock.schedule(lambda dt: None)
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
elif symbol == pyglet.window.key.P:
|
||||
pyglet.image.get_buffer_manager().get_color_buffer().save(
|
||||
'screenshot.png', encoder=PNGRGBEncoder())
|
||||
|
||||
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
|
||||
def encode(self, image, file, filename):
|
||||
import Image
|
||||
image = image.get_image_data()
|
||||
format = image.format
|
||||
pitch = -(image.width * len(format))
|
||||
pil_image = Image.fromstring(
|
||||
format, (image.width, image.height), image.get_data(format, pitch))
|
||||
try:
|
||||
#.convert('P', palette=Image.WEB)
|
||||
pil_image.convert("RGB").save(file)
|
||||
except Exception, e:
|
||||
raise ImageEncodeException(e)
|
||||
|
||||
|
||||
class Interface(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
if IF_LEFT < x < (self.window.width-IF_RIGHT):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
if IF_BOTTOM < y < (self.window.height-IF_TOP):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
class LoadScreen(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="Linux Libertine",
|
||||
font_size=28,
|
||||
x=self.window.width-10, y=10,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
h3m = json.loads(pyglet.resource.file("test.h3m").read())
|
||||
self.label.text = "PARSING MAP FILE..."
|
||||
edge_map = [[] for i in xrange(len(h3m["upper_terrain"])+16)]
|
||||
for num in xrange(len(edge_map)):
|
||||
if num < 7 or num > len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0])+18)])
|
||||
elif num == 7:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 16, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
|
||||
line.append([-1, 17, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
elif num == len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 19, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m["upper_terrain"][0]))])
|
||||
line.append([-1, 18, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
else:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend(h3m["upper_terrain"][num-8])
|
||||
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
edge_map[num] = line
|
||||
h3m["upper_terrain"] = edge_map
|
||||
self.label.text = "INITIATING MAPSET..."
|
||||
|
||||
mapset = MapSet(h3m["upper_terrain"], h3m["objects"], h3m["tunedobj"])
|
||||
self.label.text = "INITIATING MAPVIEW..."
|
||||
mapview = MapView(mapset, self.window)
|
||||
interface = Interface(self.window)
|
||||
self.window.pop_handlers()
|
||||
self.window.push_handlers(mapview)
|
||||
self.window.push_handlers(interface)
|
||||
self.window.push_handlers(self.window.keys)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,
|
||||
pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
window.push_handlers(LoadScreen(window))
|
||||
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
|
||||
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
pyglet.app.run()
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
homm3hmtest
|
||||
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import gzip, os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
def extract(filename):
|
||||
h3m_data = gzip.open(filename)
|
||||
map_data = {}
|
||||
#read general info
|
||||
(map_data["version"], ) = struct.unpack("<I", h3m_data.read(4))
|
||||
if map_data["version"] == 0x1C:
|
||||
h3m_data.read(1)
|
||||
(size,) = struct.unpack("<I", h3m_data.read(4))
|
||||
print filename, size
|
||||
|
||||
def main(args):
|
||||
for arg in args[1:]:
|
||||
extract(arg)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
heroes renaissance
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
from lib.mapset import *
|
||||
from lib.interface import *
|
||||
from lib.mapview import *
|
||||
from lib.window import Window
|
||||
|
||||
class LoadScreen(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="Linux Libertine",
|
||||
font_size=28,
|
||||
x=self.window.width-10, y=10,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
self.label.text = "INITIATING MAPSET..."
|
||||
mapset = MapSet("Deluge")
|
||||
self.label.text = "INITIATING MAPVIEW..."
|
||||
mapview = MapView(mapset, self.window)
|
||||
interface = Interface(self.window)
|
||||
self.window.pop_handlers()
|
||||
self.window.push_handlers(mapview)
|
||||
self.window.push_handlers(interface)
|
||||
self.window.push_handlers(self.window.keys)
|
||||
|
||||
if __name__ == '__main__':
|
||||
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,
|
||||
pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
window = Window()
|
||||
window.push_handlers(LoadScreen(window))
|
||||
img = pyglet.resource.image("data/cursors/cradvntr.def/0.png")
|
||||
window.set_mouse_cursor(pyglet.window.ImageMouseCursor(img, 0, 40))
|
||||
pyglet.app.run()
|
@ -0,0 +1,596 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
heroes renaissance
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import gzip
|
||||
import struct
|
||||
import pyglet
|
||||
|
||||
def extract(filename):
|
||||
h3m_data = gzip.open(filename)
|
||||
map_data = {}
|
||||
#read general info
|
||||
(map_data["version"], ) = struct.unpack("<I", h3m_data.read(4))
|
||||
if map_data["version"] != 0x1C:
|
||||
return
|
||||
(map_data["hero_present"], map_data["map_size"], map_data["underworld"],
|
||||
) = struct.unpack("<BIB", h3m_data.read(6))
|
||||
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
map_data["map_name"] = h3m_data.read(name_length)
|
||||
(desc_length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
map_data["map_desc"] = h3m_data.read(desc_length)
|
||||
(map_data["difficulty"], map_data["level_limit"],
|
||||
) = struct.unpack("<BB", h3m_data.read(2))
|
||||
|
||||
#player info
|
||||
for color in ("Red", "Blue", "Tan", "Green", "Orange", "Purple", "Teal", "Pink"):
|
||||
map_data[color] = {}
|
||||
(map_data[color]["is_human"], map_data[color]["is_computer"],
|
||||
map_data[color]["behaviour"], map_data[color]["isCityTypesOpt"],
|
||||
map_data[color]["cityTypes"], map_data[color]["randomCity"],
|
||||
) = struct.unpack("<BBBBHB", h3m_data.read(7))
|
||||
(main_city, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if main_city:
|
||||
map_data[color]["main_city"] = {}
|
||||
(map_data[color]["main_city"]["generate_hero"],
|
||||
map_data[color]["main_city"]["type"],
|
||||
) = struct.unpack("<BB", h3m_data.read(2))
|
||||
map_data[color]["main_city"]["coords"] = struct.unpack("<BBB", h3m_data.read(3))
|
||||
(map_data[color]["random_hero"], map_data[color]["hero_type"],
|
||||
) = struct.unpack("<BB", h3m_data.read(2))
|
||||
if map_data[color]["hero_type"] != 0xFF:
|
||||
(map_data[color]["hero_portrait"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
map_data[color]["hero_name"] = h3m_data.read(name_length)
|
||||
h3m_data.read(1) #junk
|
||||
(map_data[color]["heroes_count"], ) = struct.unpack("<I", h3m_data.read(4))
|
||||
if map_data[color]["heroes_count"] > 0:
|
||||
map_data[color]["heroes"] = {}
|
||||
for i in xrange(map_data[color]["heroes_count"]):
|
||||
(map_data[color]["heroes"]["portrait"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
map_data[color]["heroes"]["name"] = h3m_data.read(name_length)
|
||||
|
||||
#special victory condition
|
||||
(map_data["victory_conditions"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if map_data["victory_conditions"] != 0xFF:
|
||||
map_data["victory_conditions"] = {"id":map_data["victory_conditions"]}
|
||||
(map_data["victory_conditions"]["canStandardEnd"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(map_data["victory_conditions"]["canComputer"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if map_data["victory_conditions"]["id"] == 0x00:
|
||||
(map_data["victory_conditions"]["artID"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
elif map_data["victory_conditions"]["id"] == 0x01:
|
||||
(map_data["victory_conditions"]["creatureID"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(map_data["victory_conditions"]["creatureCount"], ) = struct.unpack("<H", h3m_data.read(2))
|
||||
elif map_data["victory_conditions"]["id"] == 0x02:
|
||||
(map_data["victory_conditions"]["resID"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(map_data["victory_conditions"]["resCount"], ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif map_data["victory_conditions"]["id"] == 0x03:
|
||||
raise NotImplementedError
|
||||
elif map_data["victory_conditions"]["id"] in (0x04, 0x05, 0x06, 0x07):
|
||||
(map_data["victory_conditions"]["x"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(map_data["victory_conditions"]["y"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(map_data["victory_conditions"]["z"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
elif map_data["victory_conditions"]["id"] in (0x08, 0x09):
|
||||
pass
|
||||
elif map_data["victory_conditions"]["id"] == 0x0A:
|
||||
raise NotImplementedError
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
#special loss condition
|
||||
(map_data["loss_conditions"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if map_data["loss_conditions"] != 0xFF:
|
||||
map_data["loss_conditions"] = {"id":map_data["loss_conditions"]}
|
||||
if map_data["loss_conditions"]["id"] in (0x00, 0x01):
|
||||
(map_data["loss_conditions"]["x"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(map_data["loss_conditions"]["y"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(map_data["loss_conditions"]["z"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
elif map_data["loss_conditions"]["id"] == 0x02:
|
||||
#to be researched
|
||||
struct.unpack("<B", h3m_data.read(1))
|
||||
struct.unpack("<B", h3m_data.read(1))
|
||||
elif map_data["loss_conditions"]["id"] == 0x03:
|
||||
(map_data["loss_conditions"]["days"], ) = struct.unpack("<H", h3m_data.read(1))
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
#Teams
|
||||
(map_data["commands_count"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if map_data["commands_count"] > 0:
|
||||
map_data["commands"] = struct.unpack("<8B", h3m_data.read(8))
|
||||
|
||||
#Free Heroes
|
||||
h3m_data.read(20) #free heroes
|
||||
h3m_data.read(4) #junk
|
||||
(map_data["heroes_count"], ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if map_data["heroes_count"] > 0:
|
||||
map_data["free_heroes"] = []
|
||||
for i in xrange(map_data["heroes_count"]):
|
||||
(hero_id, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(hero_portrait, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
hero_name = h3m_data.read(name_length)
|
||||
(hero_players, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
map_data["free_heroes"].append({"id": hero_id, "portrait":hero_portrait, "name":hero_name, "players":hero_players})
|
||||
h3m_data.read(31) #junk
|
||||
|
||||
#artefacts
|
||||
h3m_data.read(18)
|
||||
|
||||
#spells
|
||||
h3m_data.read(9)
|
||||
|
||||
#sec skillz
|
||||
h3m_data.read(4)
|
||||
|
||||
#rumors
|
||||
(map_data["rumor_count"], ) = struct.unpack("<I", h3m_data.read(4))
|
||||
if map_data["rumor_count"] > 0:
|
||||
map_data["rumors"] = []
|
||||
for i in xrange(map_data["rumor_count"]):
|
||||
(name_length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
rumor_name = h3m_data.read(name_length)
|
||||
(text_length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
rumor_text = h3m_data.read(text_length)
|
||||
map_data["rumors"].append({"name":rumor_name, "text":rumor_text})
|
||||
|
||||
#hero options
|
||||
for i in xrange(156):
|
||||
(hero_enable, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if hero_enable == 1:
|
||||
(isExp, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isExp == 0x01:
|
||||
(exp, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
(isSecSkill, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isSecSkill == 0x01:
|
||||
(skills_count) = struct.unpack("<I", h3m_data.read(4))
|
||||
for i in xrange(skills_count):
|
||||
(skill_id, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(skill_lvl, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(isArtifact, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isArtifact == 0x01:
|
||||
raise NotImplementedError
|
||||
(isBiography, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isBiography == 0x01:
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
biography = h3m_data.read(length)
|
||||
(gender, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(isSpells, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isSpells == 0x01:
|
||||
spells = struct.unpack("<9B", h3m_data.read(9))
|
||||
(isPrimarySkills, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isPrimarySkills == 0x01:
|
||||
(attack, defense, power, knowledge) = struct.unpack("<4B", h3m_data.read(4))
|
||||
|
||||
map_data["upper_terrain"] = [[] for i in xrange(map_data["map_size"])]
|
||||
#read upper world
|
||||
for i in xrange(map_data["map_size"]**2):
|
||||
x = i%map_data["map_size"]
|
||||
y = (i-x)/map_data["map_size"]
|
||||
map_data["upper_terrain"][y].append(struct.unpack("<7B", h3m_data.read(7)))
|
||||
|
||||
#read underworld
|
||||
if map_data["underworld"]:
|
||||
map_data["lower_terrain"] = [[] for i in xrange(map_data["map_size"])]
|
||||
for i in xrange(map_data["map_size"]**2):
|
||||
x = i%map_data["map_size"]
|
||||
y = (i-x)/map_data["map_size"]
|
||||
map_data["lower_terrain"][y].append(struct.unpack("<7B", h3m_data.read(7)))
|
||||
|
||||
(map_data["object_count"], ) = struct.unpack("<I", h3m_data.read(4))
|
||||
map_data["objects"] = []
|
||||
for i in xrange(map_data["object_count"]):
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
filename = h3m_data.read(length)
|
||||
h3m_data.read(6) #passability
|
||||
h3m_data.read(6) #actions
|
||||
h3m_data.read(2) #landscape
|
||||
h3m_data.read(2) #land_edit_groups
|
||||
(obj_class, ) = struct.unpack("<I", h3m_data.read(4)) #class
|
||||
(obj_number, ) = struct.unpack("<I", h3m_data.read(4)) #number
|
||||
(obj_group, ) = struct.unpack("<B", h3m_data.read(1)) #group
|
||||
h3m_data.read(1) #isOverlay
|
||||
h3m_data.read(16) #junk
|
||||
map_data["objects"].append({"filename":filename.lower(), "class":obj_class,
|
||||
"number":obj_number, "group":obj_group})
|
||||
|
||||
(map_data["tunedobj_count"], ) = struct.unpack("<I", h3m_data.read(4))
|
||||
|
||||
map_data["tunedobj"] = []
|
||||
for i in xrange(map_data["tunedobj_count"]):
|
||||
(x, y, z) = struct.unpack("<3B", h3m_data.read(3))
|
||||
(object_id, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
#print x,y,z,object_id,
|
||||
junk = h3m_data.read(5) #junk
|
||||
if junk != "\x00\x00\x00\x00\x00":
|
||||
for c in junk:
|
||||
print "%02d"%ord(c),
|
||||
break
|
||||
#print i, map_data["objects"][object_id]["filename"],
|
||||
#print map_data["objects"][object_id]["class"]
|
||||
|
||||
map_data["tunedobj"].append({"id":object_id, "x":x, "y":y, "z":z})
|
||||
|
||||
if object_id in (0,1):
|
||||
pass
|
||||
elif map_data["objects"][object_id]["class"] == 53:
|
||||
if map_data["objects"][object_id]["number"] == 7:
|
||||
h3m_data.read(4)
|
||||
else:
|
||||
h3m_data.read(4)
|
||||
elif map_data["objects"][object_id]["class"] in (76, 79):
|
||||
(isText, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isText == 0x01:
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
text = h3m_data.read(length)
|
||||
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isGuards == 0x01:
|
||||
for i in xrange(7):
|
||||
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
|
||||
h3m_data.read(4) #junk
|
||||
(quantity, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
h3m_data.read(4) #junk
|
||||
elif map_data["objects"][object_id]["class"] in (34, 70, 62):
|
||||
(hero_id, color, hero) = struct.unpack("<IBB", h3m_data.read(6))
|
||||
(isName, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isName == 0x01:
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
name = h3m_data.read(length)
|
||||
(isExp, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isExp == 0x01:
|
||||
(exp, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
(isPortrait, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isPortrait == 0x01:
|
||||
(portrait, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(isSecSkill, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isSecSkill == 0x01:
|
||||
(skills_count, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
for i in xrange(skills_count):
|
||||
(skill_id, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(skill_lvl, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(isCreature, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isCreature == 0x01:
|
||||
for i in xrange(7):
|
||||
(guard_id, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
(guard_count, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
(creaturesFormation, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(isArtifact, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isArtifact == 0x01:
|
||||
(headID, shouldersID, neckID, rightHandID, leftHandID,
|
||||
trunkID, rightRingID, leftRingID, legsID, misc1ID, misc2ID,
|
||||
misc3ID, misc4ID, machine1ID, machine2ID, machine3ID,
|
||||
machine4ID, magicbook, misc5ID) \
|
||||
= struct.unpack("<19H", h3m_data.read(38))
|
||||
(knapsack_count, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
if knapsack_count > 0:
|
||||
for i in xrange(knapsack_count):
|
||||
(knapsackID, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
(zoneRadius, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(isBiography, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isBiography == 0x01:
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
biography = h3m_data.read(length)
|
||||
(gender, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(isSpells, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isSpells == 0x01:
|
||||
spells = struct.unpack("<9B", h3m_data.read(9))
|
||||
(isPrimarySkills, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isPrimarySkills == 0x01:
|
||||
(attack, defense, power, knowledge) = struct.unpack("<4B", h3m_data.read(4))
|
||||
h3m_data.read(16) #unknown
|
||||
elif map_data["objects"][object_id]["class"] in (17, 20, 42):
|
||||
(owner, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif map_data["objects"][object_id]["class"] == 93:
|
||||
(isText, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isText == 0x01:
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
text = h3m_data.read(length)
|
||||
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isGuards == 0x01:
|
||||
for i in xrange(7):
|
||||
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
|
||||
h3m_data.read(4) #junk
|
||||
(spell_id, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif map_data["objects"][object_id]["class"] == 216:
|
||||
(owner, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
(junk, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
if junk == 0x00:
|
||||
(towns, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
(minlevel, maxlevel, ) = struct.unpack("<2B", h3m_data.read(2))
|
||||
elif map_data["objects"][object_id]["class"] in (54, 71, 72, 73, 74, 75, 162, 163, 164):
|
||||
(monster_id, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
(monster_count, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
(mood, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(isTreasureOrText, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isTreasureOrText == 0x01:
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
text = h3m_data.read(length)
|
||||
(wood, mercury, ore, sulfur, crystal, gem, gold, artefactID) \
|
||||
= struct.unpack("<7IH", h3m_data.read(30))
|
||||
(mosterNeverRunAway, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(monsterDontGrowUp, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
h3m_data.read(2) #junk
|
||||
elif map_data["objects"][object_id]["class"] in (98, 77):
|
||||
h3m_data.read(4) #junk
|
||||
(owner, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(isName, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isName == 0x01:
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
name = h3m_data.read(length)
|
||||
(isGuard, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isGuard == 0x01:
|
||||
for i in xrange(7):
|
||||
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
|
||||
(formation, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(isBuildings, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isBuildings == 0x01:
|
||||
build = struct.unpack("6B", h3m_data.read(6))
|
||||
active = struct.unpack("6B", h3m_data.read(6))
|
||||
else:
|
||||
(isFort, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
mustSpells = struct.unpack("<9B", h3m_data.read(9))
|
||||
canSpells = struct.unpack("<9B", h3m_data.read(9))
|
||||
(eventQuantity, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
if eventQuantity > 0:
|
||||
for i in xrange(eventQuantity):
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
event_name = h3m_data.read(length)
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
event_text = h3m_data.read(length)
|
||||
(wood, mercury, ore, sulfur, crystal, gem, gold,
|
||||
players_affected, human_affected, ai_affected,
|
||||
day_of_first_event, event_iteration) \
|
||||
= struct.unpack("<7I3B2H", h3m_data.read(35))
|
||||
h3m_data.read(16) #junk
|
||||
buildings = struct.unpack("<6B", h3m_data.read(6))
|
||||
creatures = struct.unpack("<7H", h3m_data.read(14))
|
||||
h3m_data.read(4) #junk
|
||||
h3m_data.read(4) #junk
|
||||
elif map_data["objects"][object_id]["class"] in (5, 65, 66, 67, 68, 69):
|
||||
(isText, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isText == 0x01:
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
text = h3m_data.read(length)
|
||||
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isGuards == 0x01:
|
||||
for i in xrange(7):
|
||||
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
|
||||
h3m_data.read(4) #junk
|
||||
elif map_data["objects"][object_id]["class"] in (33, 219):
|
||||
(color, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
for i in xrange(7):
|
||||
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
|
||||
(undeleteSoldiers, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
h3m_data.read(8)
|
||||
elif map_data["objects"][object_id]["class"] == 87:
|
||||
(owner, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif map_data["objects"][object_id]["class"] == 83:
|
||||
(quest, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
|
||||
if quest == 0x00:
|
||||
pass
|
||||
elif quest == 0x01:
|
||||
(level, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif quest == 0x02:
|
||||
(offence, defence, power, knowledge) = struct.unpack("4B", h3m_data.read(4))
|
||||
elif quest == 0x03:
|
||||
(hero_id, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif quest == 0x04:
|
||||
(monster_id, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif quest == 0x05:
|
||||
(art_quantity, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
for i in xrange(art_quantity):
|
||||
(art, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
elif quest == 0x06:
|
||||
(creatures_quantity, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
for i in xrange(creatures_quantity):
|
||||
(guard_id, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
(guard_count, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
elif quest == 0x07:
|
||||
resources = struct.unpack("7I", h3m_data.read(28))
|
||||
elif quest == 0x08:
|
||||
(hero_id, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
elif quest == 0x09:
|
||||
(player, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
(time_limit, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
quest_begin = h3m_data.read(length)
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
quest_running = h3m_data.read(length)
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
quest_end = h3m_data.read(length)
|
||||
|
||||
(reward, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if reward == 0x00:
|
||||
pass
|
||||
elif reward == 0x01:
|
||||
(exp, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif reward == 0x02:
|
||||
(spell_points, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif reward == 0x03:
|
||||
(morale, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
elif reward == 0x04:
|
||||
(lucky, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
elif reward == 0x05:
|
||||
(resID, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(res_quantity, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif reward == 0x06:
|
||||
(priSkillID, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(priSkillBonus, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
elif reward == 0x07:
|
||||
(secSkillID, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(secSkillBonus, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
elif reward == 0x08:
|
||||
(artID, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
elif reward == 0x09:
|
||||
(spellID, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
elif reward == 0x0A:
|
||||
(creatureID, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
(creatureQuantity, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
h3m_data.read(2) #junk
|
||||
elif map_data["objects"][object_id]["class"] in (91, 59):
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
text = h3m_data.read(length)
|
||||
h3m_data.read(4) #junk
|
||||
elif map_data["objects"][object_id]["class"] == 113:
|
||||
(secSkills, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif map_data["objects"][object_id]["class"] in (88, 89, 90):
|
||||
(spellID, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif map_data["objects"][object_id]["class"] == 215:
|
||||
(quest, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
|
||||
if quest == 0x00:
|
||||
pass
|
||||
elif quest == 0x01:
|
||||
(level, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif quest == 0x02:
|
||||
(offence, defence, power, knowledge) = struct.unpack("4B", h3m_data.read(4))
|
||||
elif quest == 0x03:
|
||||
(hero_id, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif quest == 0x04:
|
||||
(monster_id, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
elif quest == 0x05:
|
||||
(art_quantity, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
for i in xrange(art_quantity):
|
||||
(art, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
elif quest == 0x06:
|
||||
(creatures_quantity, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
for i in xrange(creatures_quantity):
|
||||
(guard_id, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
(guard_count, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
elif quest == 0x07:
|
||||
resources = struct.unpack("7I", h3m_data.read(28))
|
||||
elif quest == 0x08:
|
||||
(hero_id, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
elif quest == 0x09:
|
||||
(player, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
(time_limit, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
quest_begin = h3m_data.read(length)
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
quest_running = h3m_data.read(length)
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
quest_end = h3m_data.read(length)
|
||||
elif map_data["objects"][object_id]["class"] == 36:
|
||||
(radius, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
h3m_data.read(3) #junk
|
||||
elif map_data["objects"][object_id]["class"] == 220:
|
||||
(resources, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
h3m_data.read(3) #junk
|
||||
elif map_data["objects"][object_id]["class"] == 217:
|
||||
(owner, towns) = struct.unpack("<II", h3m_data.read(8))
|
||||
if towns==0x00:
|
||||
(towns,) = struct.unpack("<H", h3m_data.read(2))
|
||||
elif map_data["objects"][object_id]["class"] == 218:
|
||||
(owner, minlvl, maxlvl) = struct.unpack("<IBB", h3m_data.read(6))
|
||||
elif map_data["objects"][object_id]["class"] == 81:
|
||||
(bonus_type, primaryID) = struct.unpack("<BI", h3m_data.read(5))
|
||||
h3m_data.read(3) #junk
|
||||
elif map_data["objects"][object_id]["class"] == 6:
|
||||
(isText, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isText == 0x01:
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
text = h3m_data.read(length)
|
||||
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isGuards == 0x01:
|
||||
for i in xrange(7):
|
||||
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
|
||||
h3m_data.read(4) #junk
|
||||
(exp, spell_points, morals, luck, wood, mercury, ore, sulfur,
|
||||
crystal, gem, gold, offence, defence, power, knowledge) = \
|
||||
struct.unpack("<IIBBIIIIIIIBBBB", h3m_data.read(42))
|
||||
(secSkills, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if secSkills > 0:
|
||||
for i in xrange(secSkills):
|
||||
(skill_id, skill_lvl) = struct.unpack("<BB", h3m_data.read(2))
|
||||
(artefacts, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if artefacts > 0:
|
||||
for i in xrange(artefacts):
|
||||
(artID, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
(spells, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if spells > 0:
|
||||
for i in xrange(spells):
|
||||
(spellID, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(monsters, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if monsters > 0:
|
||||
for i in xrange(monsters):
|
||||
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
|
||||
h3m_data.read(8) #junk
|
||||
elif map_data["objects"][object_id]["class"] == 26:
|
||||
(isText, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isText == 0x01:
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
text = h3m_data.read(length)
|
||||
(isGuards, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if isGuards == 0x01:
|
||||
for i in xrange(7):
|
||||
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
|
||||
h3m_data.read(4) #junk
|
||||
(exp, spell_points, morals, luck, wood, mercury, ore, sulfur,
|
||||
crystal, gem, gold, offence, defence, power, knowledge) = \
|
||||
struct.unpack("<IIBBIIIIIIIBBBB", h3m_data.read(42))
|
||||
(secSkills, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if secSkills > 0:
|
||||
for i in xrange(secSkills):
|
||||
(skill_id, skill_lvl) = struct.unpack("<BB", h3m_data.read(2))
|
||||
(artefacts, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if artefacts > 0:
|
||||
for i in xrange(artefacts):
|
||||
(artID, ) = struct.unpack("<H", h3m_data.read(2))
|
||||
(spells, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if spells > 0:
|
||||
for i in xrange(spells):
|
||||
(spellID, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(monsters, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
if monsters > 0:
|
||||
for i in xrange(monsters):
|
||||
(guard_id, guard_count) = struct.unpack("<HH", h3m_data.read(4))
|
||||
h3m_data.read(8) #junk
|
||||
(players, isAICan, disableAfterFirstDay) = struct.unpack("<BBB", h3m_data.read(3))
|
||||
h3m_data.read(4) #junk
|
||||
|
||||
try:
|
||||
(gevents_count, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
for i in xrange(gevents_count):
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
name = h3m_data.read(length)
|
||||
(length, ) = struct.unpack("<I", h3m_data.read(4))
|
||||
text = h3m_data.read(length)
|
||||
h3m_data.read(7*4) #resources
|
||||
(players_affected, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(human_affected, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(ai_affected, ) = struct.unpack("<B", h3m_data.read(1))
|
||||
(day_of_first_event,) = struct.unpack("<H", h3m_data.read(2))
|
||||
(event_iteration,) = struct.unpack("<H", h3m_data.read(2))
|
||||
h3m_data.read(16) #junk
|
||||
except:
|
||||
print "d'ough...'"
|
||||
|
||||
h3m_data.read(124) #junk
|
||||
|
||||
return map_data
|
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
heroes renaissance
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
|
||||
IF_BOTTOM = 48
|
||||
IF_RIGHT = 200
|
||||
IF_TOP = IF_LEFT = 8
|
||||
|
||||
class Interface(object):
|
||||
def __init__(self, window):
|
||||
self.window = window
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
if IF_LEFT < x < (self.window.width-IF_RIGHT):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
if IF_BOTTOM < y < (self.window.height-IF_TOP):
|
||||
pass
|
||||
else:
|
||||
return pyglet.event.EVENT_HANDLED
|
@ -0,0 +1,382 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
heroes renaissance
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
from ctypes import create_string_buffer, memmove
|
||||
from lib import h3m
|
||||
import os
|
||||
|
||||
class OrderedTextureGroup(pyglet.graphics.Group):
|
||||
def __init__(self, order, texture, parent=None):
|
||||
super(OrderedTextureGroup, self).__init__(parent)
|
||||
self.texture = texture
|
||||
self.order = order
|
||||
|
||||
def set_state(self):
|
||||
pyglet.gl.glEnable(self.texture.target)
|
||||
pyglet.gl.glBindTexture(self.texture.target, self.texture.id)
|
||||
|
||||
def unset_state(self):
|
||||
pyglet.gl.glDisable(self.texture.target)
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.order, self.texture.target, self.texture.id,
|
||||
self.parent))
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.__class__ is other.__class__ and
|
||||
self.order == other.order and
|
||||
self.texture.target == other.texture.target and
|
||||
self.texture.id == other.texture.id and
|
||||
self.parent == self.parent)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(id=%d)' % (self.__class__.__name__, self.order,
|
||||
self.texture.id)
|
||||
|
||||
def __cmp__(self, other):
|
||||
if isinstance(other, OrderedTextureGroup):
|
||||
return cmp(self.order, other.order)
|
||||
return -1
|
||||
|
||||
class Animation(object):
|
||||
def __init__(self, tex_region, frames, flip_x=False, flip_y=False):
|
||||
self.texgroup = tex_region.group
|
||||
if flip_x or flip_y:
|
||||
self.tex = tex_region.get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
else:
|
||||
self.tex = tex_region
|
||||
self.__frames = []
|
||||
for img in frames:
|
||||
data_pitch = abs(img._current_pitch)
|
||||
buf = create_string_buffer(len(img._current_data))
|
||||
memmove(buf, img._current_data, len(img._current_data))
|
||||
data = buf.raw
|
||||
rows = [data[i:i + abs(data_pitch)] for i in
|
||||
xrange(len(img._current_data)-abs(data_pitch),
|
||||
-1, -abs(data_pitch))]
|
||||
self.__frames.append(''.join(rows))
|
||||
self.__animation = 0
|
||||
self.width = self.tex.width
|
||||
self.height = self.tex.height
|
||||
self.__hash = hash(self.__frames[0])
|
||||
|
||||
def next_frame(self):
|
||||
self.__animation = (self.__animation + 1) % len(self.__frames)
|
||||
return self.__frames[self.__animation]
|
||||
|
||||
@property
|
||||
def tex_coords(self):
|
||||
return self.tex.tex_coords
|
||||
|
||||
@property
|
||||
def group(self):
|
||||
return self.texgroup
|
||||
|
||||
def __hash__(self):
|
||||
return self.__hash
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.__hash == other.__hash
|
||||
|
||||
class MapSet(object):
|
||||
def load_map_object(self, file, order=0):
|
||||
image = pyglet.image.load(None, file=pyglet.resource.file(file))
|
||||
try:
|
||||
texture_region = self.current_atlas.add(image)
|
||||
except pyglet.image.atlas.AllocatorException:
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
texture_region = self.current_atlas.add(image)
|
||||
group = OrderedTextureGroup(order, self.current_atlas.texture)
|
||||
|
||||
if group not in self.groups:
|
||||
self.groups.append(group)
|
||||
|
||||
texture_region.group = self.groups.index(group)
|
||||
return texture_region
|
||||
|
||||
def __init__(self, map_name):
|
||||
h3m_data = h3m.extract(os.path.join(pyglet.resource._default_loader._script_home,"maps","%s.h3m" % map_name))
|
||||
edge_map = [[] for i in xrange(len(h3m_data["upper_terrain"])+16)]
|
||||
for num in xrange(len(edge_map)):
|
||||
if num < 7 or num > len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(len(h3m_data["upper_terrain"][0])+18)])
|
||||
elif num == 7:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 16, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 20+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m_data["upper_terrain"][0]))])
|
||||
line.append([-1, 17, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
elif num == len(edge_map)-8:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 19, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 28+i%4, 0, 0, 0, 0, 0] for i in xrange(len(h3m_data["upper_terrain"][0]))])
|
||||
line.append([-1, 18, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
else:
|
||||
line = []
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
line.append([-1, 32+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend(h3m_data["upper_terrain"][num-8])
|
||||
line.append([-1, 24+num%4, 0, 0, 0, 0, 0])
|
||||
line.extend([[-1, 0+(i-1)%4+4*(num%4), 0, 0, 0, 0, 0] for i in xrange(8)])
|
||||
edge_map[num] = line
|
||||
h3m_data["upper_terrain"] = edge_map
|
||||
|
||||
self.width = len(h3m_data["upper_terrain"][0])
|
||||
self.height = len(h3m_data["upper_terrain"])
|
||||
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
|
||||
self.groups = []
|
||||
|
||||
self.__tiles = {}
|
||||
tile_textures = {}
|
||||
for y, line in enumerate(h3m_data["upper_terrain"]):
|
||||
for x, tile in enumerate(line):
|
||||
if tile[0] == -1: #edge
|
||||
if "edg" not in tile_textures.keys():
|
||||
tile_textures["edg"] = [self.load_map_object('data/advmap_tiles/edg.def/%d.png'%i, 100) for i in xrange(36)]
|
||||
self.__tiles[x,y] = [tile_textures["edg"][tile[1]]]
|
||||
elif tile[0] == 0: #dirt
|
||||
if "dirttl" not in tile_textures.keys():
|
||||
tile_textures["dirttl"] = [self.load_map_object('data/advmap_tiles/dirttl.def/%d.png'%i, 0) for i in xrange(46)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["dirttl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["dirttl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["dirttl"][tile[1]]]
|
||||
elif tile[0] == 1: #sand
|
||||
if "sandtl" not in tile_textures.keys():
|
||||
tile_textures["sandtl"] = [self.load_map_object('data/advmap_tiles/sandtl.def/%d.png'%i, 0) for i in xrange(24)]
|
||||
self.__tiles[x,y] = [tile_textures["sandtl"][tile[1]]]
|
||||
elif tile[0] == 2: #grass
|
||||
if "grastl" not in tile_textures.keys():
|
||||
tile_textures["grastl"] = [self.load_map_object('data/advmap_tiles/grastl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["grastl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["grastl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["grastl"][tile[1]]]
|
||||
elif tile[0] == 3: #snow
|
||||
if "snowtl" not in tile_textures.keys():
|
||||
tile_textures["snowtl"] = [self.load_map_object('data/advmap_tiles/snowtl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["snowtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["snowtl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["snowtl"][tile[1]]]
|
||||
elif tile[0] == 4: #swamp
|
||||
if "swmptl" not in tile_textures.keys():
|
||||
tile_textures["swmptl"] = [self.load_map_object('data/advmap_tiles/swmptl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["swmptl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["swmptl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["swmptl"][tile[1]]]
|
||||
elif tile[0] == 5: #rough
|
||||
if "rougtl" not in tile_textures.keys():
|
||||
tile_textures["rougtl"] = [self.load_map_object('data/advmap_tiles/rougtl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["rougtl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["rougtl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["rougtl"][tile[1]]]
|
||||
elif tile[0] == 7: #lava
|
||||
if "lavatl" not in tile_textures.keys():
|
||||
tile_textures["lavatl"] = [self.load_map_object('data/advmap_tiles/lavatl.def/%d.png'%i, 0) for i in xrange(79)]
|
||||
flip_x = bool(tile[6] & 1)
|
||||
flip_y = bool(tile[6] & 2)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["lavatl"][tile[1]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["lavatl"][tile[1]].group
|
||||
self.__tiles[x,y] = [new]
|
||||
else:
|
||||
self.__tiles[x,y] = [tile_textures["lavatl"][tile[1]]]
|
||||
elif tile[0] == 8: #water 12 anims
|
||||
if "watrtl" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/advmap_tiles/watrtl.def/%d/0.png'%i, 0) for i in xrange(33)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/watrtl.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(33)]
|
||||
tile_textures["watrtl"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>0)&1
|
||||
flip_y = (tile[6]>>1)&1
|
||||
self.__tiles[x,y] = [tile_textures["watrtl"][flip_x, flip_y][tile[1]]]
|
||||
elif tile[0] == 9: #rock
|
||||
if "rocktl" not in tile_textures.keys():
|
||||
tile_textures["rocktl"] = [self.load_map_object('data/advmap_tiles/rocktl.def/%d.png'%i, 0) for i in xrange(48)]
|
||||
self.__tiles[x,y] = [tile_textures["rocktl"][tile[1]]]
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
if tile[2] == 0: #no river
|
||||
pass
|
||||
elif tile[2] == 1: #clrrvr 12 anims
|
||||
if "clrrvr" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/advmap_tiles/clrrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
|
||||
tile_textures["clrrvr"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>2)&1
|
||||
flip_y = (tile[6]>>3)&1
|
||||
self.__tiles[x,y].append(tile_textures["clrrvr"][flip_x, flip_y][tile[3]])
|
||||
elif tile[2] == 2: #icyrvr
|
||||
if "icyrvr" not in tile_textures.keys():
|
||||
tile_textures["icyrvr"] = [self.load_map_object('data/advmap_tiles/icyrvr.def/%d.png'%i, 1) for i in xrange(13)]
|
||||
flip_x = bool(tile[6] & 4)
|
||||
flip_y = bool(tile[6] & 8)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["icyrvr"][tile[3]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["icyrvr"][tile[3]].group
|
||||
self.__tiles[x, y].append(new)
|
||||
else:
|
||||
self.__tiles[x, y].append(tile_textures["icyrvr"][tile[3]])
|
||||
elif tile[2] == 3: #mudrvr
|
||||
if "mudrvr" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/advmap_tiles/mudrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(12)] for i in xrange(13)]
|
||||
tile_textures["mudrvr"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>2)&1
|
||||
flip_y = (tile[6]>>3)&1
|
||||
self.__tiles[x,y].append(tile_textures["mudrvr"][flip_x, flip_y][tile[3]])
|
||||
elif tile[2] == 4: #lavrvr
|
||||
if "lavrvr" not in tile_textures.keys():
|
||||
textures = [self.load_map_object('data/advmap_tiles/lavrvr.def/%d/0.png'%i, 1) for i in xrange(13)]
|
||||
images = [[pyglet.image.load(None, file=pyglet.resource.file('data/advmap_tiles/clrrvr.def/%d/%d.png'%(i,j))) for j in xrange(9)] for i in xrange(13)]
|
||||
tile_textures["lavrvr"] = {
|
||||
(0,0):[Animation(texture, images[i]) for i, texture in enumerate(textures)],
|
||||
(1,0):[Animation(texture, images[i], flip_x=True) for i, texture in enumerate(textures)],
|
||||
(0,1):[Animation(texture, images[i], flip_y=True) for i, texture in enumerate(textures)],
|
||||
(1,1):[Animation(texture, images[i], flip_x=True, flip_y=True) for i, texture in enumerate(textures)],
|
||||
}
|
||||
flip_x = (tile[6]>>2)&1
|
||||
flip_y = (tile[6]>>3)&1
|
||||
self.__tiles[x,y].append(tile_textures["lavrvr"][flip_x, flip_y][tile[3]])
|
||||
else:
|
||||
raise NotImplementedError, tile[2]
|
||||
|
||||
if tile[4] == 0: #no road
|
||||
pass
|
||||
elif tile[4] == 1: #dirtrd
|
||||
if "dirtrd" not in tile_textures.keys():
|
||||
tile_textures["dirtrd"] = [self.load_map_object('data/advmap_tiles/dirtrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["dirtrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["dirtrd"][tile[5]].group
|
||||
self.__tiles[x, y].append(new)
|
||||
else:
|
||||
self.__tiles[x, y].append(tile_textures["dirtrd"][tile[5]])
|
||||
elif tile[4] == 2: #gravrd
|
||||
if "gravrd" not in tile_textures.keys():
|
||||
tile_textures["gravrd"] = [self.load_map_object('data/advmap_tiles/gravrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["gravrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["gravrd"][tile[5]].group
|
||||
self.__tiles[x, y].append(new)
|
||||
else:
|
||||
self.__tiles[x, y].append(tile_textures["gravrd"][tile[5]])
|
||||
elif tile[4] == 3: #cobbrd
|
||||
if "cobbrd" not in tile_textures.keys():
|
||||
tile_textures["cobbrd"] = [self.load_map_object('data/advmap_tiles/cobbrd.def/%d.png'%i, 1) for i in xrange(17)]
|
||||
flip_x = bool(tile[6] & 16)
|
||||
flip_y = bool(tile[6] & 32)
|
||||
if flip_x or flip_y:
|
||||
new = tile_textures["cobbrd"][tile[5]].get_transform(flip_x=flip_x, flip_y=flip_y)
|
||||
new.group = tile_textures["cobbrd"][tile[5]].group
|
||||
self.__tiles[x, y].append(new)
|
||||
else:
|
||||
self.__tiles[x, y].append(tile_textures["cobbrd"][tile[5]])
|
||||
else:
|
||||
raise NotImplementedError, tile[4]
|
||||
|
||||
images = []
|
||||
for order, obj in enumerate(h3m_data["objects"]):
|
||||
imgs = []
|
||||
i = 0
|
||||
while 1:
|
||||
imgs.append(pyglet.image.load(None, file=pyglet.resource.file("data/advmap_objects/" + obj["filename"] + "/%d.png"%i)))
|
||||
i += 1
|
||||
if "data/advmap_objects/" + obj["filename"] + "/%d.png" % i not in pyglet.resource._default_loader._index.keys():
|
||||
break;
|
||||
images.append((imgs, order))
|
||||
|
||||
self.objects = []
|
||||
for imgs in sorted(images, key=lambda i:i[0][0].height, reverse=True):
|
||||
try:
|
||||
texture = self.current_atlas.add(imgs[0][0])
|
||||
except pyglet.image.atlas.AllocatorException:
|
||||
self.current_atlas = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
texture = self.current_atlas.add(imgs[0][0])
|
||||
group = OrderedTextureGroup(2, self.current_atlas.texture)
|
||||
if group not in self.groups:
|
||||
self.groups.append(group)
|
||||
group = self.groups.index(group)
|
||||
texture.group = group
|
||||
self.objects.append((Animation(texture, imgs[0]), imgs[1]))
|
||||
|
||||
self.objects = [i[0] for i in sorted(self.objects, key=lambda i:i[1])]
|
||||
|
||||
self.tunedobj = {}
|
||||
for obj in [i for i in h3m_data["tunedobj"] if i["z"]==0]:
|
||||
self.__tiles[obj["x"] + 9,obj["y"] + 8].append(self.objects[obj["id"]])
|
||||
|
||||
def get_tiles(self, tiles_x, tiles_y, div_x, div_y):
|
||||
for y in xrange(tiles_y - 1, -6, -1):
|
||||
y1 = y * 32
|
||||
for x in xrange(tiles_x + 5 - 1, -1, -1):
|
||||
for obj in self.__tiles.get((x - div_x, div_y - y), []):
|
||||
x1 = x * 32 - obj.width + 32
|
||||
x2 = x1 + obj.width
|
||||
y2 = y1 + obj.height
|
||||
yield obj, [x1, y1, x2, y1, x2, y2, x1, y2]
|
@ -0,0 +1,335 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
heroes renaissance
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
from lib.interface import *
|
||||
from lib.mapset import *
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, mapset, window):
|
||||
self.window = window
|
||||
self.mapset = mapset
|
||||
self._first_time_init()
|
||||
self._init_view()
|
||||
# mouse position
|
||||
self.label = pyglet.text.Label('',
|
||||
font_name="",
|
||||
font_size=36,
|
||||
bold=True,
|
||||
color=(128, 128, 128, 128),
|
||||
x=self.window.width - 10, y=0,
|
||||
anchor_x='right', anchor_y='bottom')
|
||||
pyglet.clock.schedule_interval(self.animate_water, 1/6.0)
|
||||
pyglet.clock.schedule_interval(self.update, 1/60.0)
|
||||
|
||||
def _first_time_init(self):
|
||||
self.tile_size = 32
|
||||
# size of the viewport
|
||||
self.vp_width = self.window.width-IF_RIGHT-IF_LEFT
|
||||
self.vp_height = self.window.height-IF_BOTTOM-IF_TOP
|
||||
# center map
|
||||
self.x = (self.mapset.width * self.tile_size - self.vp_width +
|
||||
self.tile_size) // 2
|
||||
self.y = (self.mapset.height * self.tile_size - self.vp_height +
|
||||
self.tile_size) // 2
|
||||
self.mouse_x = self.mouse_dx = 0
|
||||
self.mouse_y = self.mouse_dy = 0
|
||||
|
||||
def _init_view(self):
|
||||
# initiate new batch
|
||||
self.batch = pyglet.graphics.Batch()
|
||||
# initiate new vertex list
|
||||
self.vl_objects = [None for value in self.mapset.groups]
|
||||
# size of the viewport
|
||||
self.vp_width = self.window.width - IF_RIGHT - IF_LEFT
|
||||
self.vp_height = self.window.height - IF_BOTTOM - IF_TOP
|
||||
# center map when viewport is too large, else check if map still fills
|
||||
# whole viewport and if not adjust position accordingly
|
||||
self.center_x = False
|
||||
if self.mapset.width * self.tile_size < self.vp_width:
|
||||
# center the map in x direction
|
||||
self.center_x = True
|
||||
self.x = (self.mapset.width * self.tile_size - self.vp_width) // 2
|
||||
elif self.x > self.tile_size * self.mapset.width - self.vp_width:
|
||||
# move map back to the right
|
||||
self.x = self.tile_size * self.mapset.width - self.vp_width
|
||||
elif self.x < 0:
|
||||
# move map to the left
|
||||
self.x = 0
|
||||
self.center_y = False
|
||||
if self.mapset.height * self.tile_size < self.vp_height:
|
||||
# center the map in y direction
|
||||
self.center_y = True
|
||||
self.y = (self.mapset.height * self.tile_size -
|
||||
self.vp_height) // 2
|
||||
elif self.y > self.tile_size * self.mapset.height - self.vp_height:
|
||||
# move map up
|
||||
self.y = self.tile_size * self.mapset.height - self.vp_height
|
||||
elif self.y < 0:
|
||||
# move map down
|
||||
self.y = 0
|
||||
# tiles to be drawn with the current viewport size
|
||||
self.tiles_x = min((self.vp_width // self.tile_size) + 2,
|
||||
self.mapset.width)
|
||||
self.tiles_y = min((self.vp_height // self.tile_size) + 2,
|
||||
self.mapset.height)
|
||||
# undrawn map size in pixels
|
||||
self.undrawn_x = self.tile_size * (self.mapset.width - self.tiles_x)
|
||||
self.undrawn_y = self.tile_size * (self.mapset.height - self.tiles_y)
|
||||
# reset mouse or keyboard movement
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
# calculate modulo pixel position of the map
|
||||
if self.x - self.tile_size > self.undrawn_x:
|
||||
# dont go right beyond map borders
|
||||
mod_x = self.tile_size - self.x + self.undrawn_x
|
||||
elif self.x > 0:
|
||||
# calculate modulo of current position and tile_size
|
||||
mod_x = (self.tile_size - self.x) % self.tile_size
|
||||
else:
|
||||
# dont go left beyond map borders
|
||||
mod_x = self.tile_size - self.x
|
||||
if self.y - self.tile_size > self.undrawn_y:
|
||||
# dont go up beyond map borders
|
||||
mod_y = self.tile_size - self.y + self.undrawn_y
|
||||
elif self.y > 0:
|
||||
# calculate modulo of current position and tile_size
|
||||
mod_y = (self.tile_size - self.y) % self.tile_size
|
||||
else:
|
||||
# dont go down beyond map borders
|
||||
mod_y = self.tile_size - self.y
|
||||
# calculate tile position of the map, turn y coordinates upside down
|
||||
self.div_x = (self.tile_size - self.x - mod_x) // self.tile_size
|
||||
self.div_y = (self.tile_size - self.y - mod_y) // self.tile_size + \
|
||||
self.mapset.height - 1
|
||||
# update vertex lists with the gathered information
|
||||
self.update_vertex_lists()
|
||||
# update current current position that is to be glTranslated
|
||||
# XXX: dont ask me why i have to add 1/4 and 3/2 but when i do not
|
||||
# there are black borders when zooming out
|
||||
# plz explain wtf is going on there
|
||||
self.view_x = mod_x - self.tile_size - (self.tile_size - 32) // 4
|
||||
self.view_y = mod_y - self.tile_size - ((self.tile_size - 32) * 3) // 2
|
||||
|
||||
def on_draw(self):
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
|
||||
pyglet.gl.glPushMatrix()
|
||||
pyglet.gl.glTranslatef(self.view_x+IF_LEFT, self.view_y+IF_BOTTOM, 0)
|
||||
pyglet.gl.glScalef(self.tile_size/32.0, self.tile_size/32.0, 0.0)
|
||||
self.batch.draw()
|
||||
pyglet.gl.glPopMatrix()
|
||||
pyglet.gl.glLoadIdentity()
|
||||
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
|
||||
pyglet.gl.glColor4f(1, 0, 1, 1)
|
||||
pyglet.gl.glRectf(0, 0, self.window.width, IF_BOTTOM)
|
||||
pyglet.gl.glRectf(self.window.width-IF_RIGHT, 0, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, self.window.height-IF_TOP, self.window.width, self.window.height)
|
||||
pyglet.gl.glRectf(0, 0, IF_LEFT, self.window.height)
|
||||
self.label.draw()
|
||||
|
||||
def _move(self, dx, dy):
|
||||
# new map position
|
||||
new_x = self.x - dx
|
||||
new_y = self.y - dy
|
||||
# only update textures and vertices when necessary
|
||||
retex = False
|
||||
# if x or y jump is too big, adjust new position accordingly
|
||||
if new_x < 0:
|
||||
# move map to the left
|
||||
new_x = 0
|
||||
retex = True
|
||||
if new_x > self.tile_size * self.mapset.width - self.vp_width:
|
||||
# move map to the right
|
||||
new_x = self.tile_size * self.mapset.width - self.vp_width
|
||||
retex = True
|
||||
if new_y < 0:
|
||||
# move map down
|
||||
new_y = 0
|
||||
retex = True
|
||||
if new_y > self.tile_size * self.mapset.height - self.vp_height:
|
||||
# move map up
|
||||
new_y = self.tile_size * self.mapset.height - self.vp_height
|
||||
retex = True
|
||||
# find out how many steps and pixels we have to move and wether we have
|
||||
# to retex
|
||||
if new_x - self.tile_size > self.undrawn_x:
|
||||
# we are at the right border
|
||||
mod_x = self.tile_size - new_x + self.undrawn_x
|
||||
# only retex if the last position was not at the border
|
||||
if self.x - self.tile_size <= self.undrawn_x:
|
||||
retex = True
|
||||
elif new_x > 0:
|
||||
# normal movement: calculate the amount of steps and the modulo
|
||||
div_x, mod_x = divmod(self.tile_size - new_x, self.tile_size)
|
||||
# only retex if the number of moved steps is not equal to last
|
||||
if div_x != (self.tile_size - self.x) // self.tile_size:
|
||||
retex = True
|
||||
else:
|
||||
# we are at the left border
|
||||
mod_x = self.tile_size - new_x
|
||||
if new_y - self.tile_size > self.undrawn_y:
|
||||
# we are at the top
|
||||
mod_y = self.tile_size - new_y + self.undrawn_y
|
||||
# only retex if the last position was not at the border
|
||||
if self.y - self.tile_size <= self.undrawn_y:
|
||||
retex = True
|
||||
elif new_y > 0:
|
||||
# normal movement: calculate the amount of steps and the modulo
|
||||
div_y, mod_y = divmod(self.tile_size - new_y, self.tile_size)
|
||||
# only retex if the number of moved steps is not equal to last
|
||||
if div_y != (self.tile_size - self.y) // self.tile_size:
|
||||
retex = True
|
||||
else:
|
||||
# we are at the bottom
|
||||
mod_y = self.tile_size - new_y
|
||||
# if we have to update vertices and textures
|
||||
if retex:
|
||||
# calculate the current position on the tilemap
|
||||
self.div_x = (self.tile_size - new_x - mod_x) // \
|
||||
self.tile_size
|
||||
self.div_y = (self.tile_size - new_y - mod_y) // \
|
||||
self.tile_size + self.mapset.height - 1
|
||||
self.update_vertex_lists()
|
||||
# update position if not centered
|
||||
# XXX: dont ask me why i have to add 1/4 and 3/2 but when i do not
|
||||
# there are black borders when zooming out
|
||||
# plz explain wtf is going on there
|
||||
if not self.center_x:
|
||||
self.view_x = mod_x-self.tile_size-(self.tile_size-32)//4
|
||||
self.x = new_x
|
||||
if not self.center_y:
|
||||
self.view_y = mod_y-self.tile_size-((self.tile_size-32)*3)//2
|
||||
self.y = new_y
|
||||
|
||||
def update_vertex_lists(self):
|
||||
# initiate lists of vertex lists, vertices, texture coords, vertices
|
||||
# counts and map objects for each group
|
||||
vertices = [[] for value in self.mapset.groups]
|
||||
tex_coords = [[] for value in self.mapset.groups]
|
||||
count = [0 for value in self.mapset.groups]
|
||||
self.cur_objects = [[] for value in self.mapset.groups]
|
||||
# for each tile in the viewport, update the list of the specific group
|
||||
for obj, coords in self.mapset.get_tiles(self.tiles_x, self.tiles_y,
|
||||
self.div_x, self.div_y):
|
||||
tex_coords[obj.group].extend(obj.tex_coords)
|
||||
vertices[obj.group].extend(coords)
|
||||
count[obj.group]+=4
|
||||
if isinstance(obj, Animation):
|
||||
self.cur_objects[obj.group].append(obj)
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if count[i] == 0:
|
||||
if self.vl_objects[i] is None:
|
||||
# let the vertex list be None
|
||||
pass
|
||||
else:
|
||||
# there was a vertex list but now no more - delete it
|
||||
self.vl_objects[i].delete()
|
||||
self.vl_objects[i] = None
|
||||
else:
|
||||
if self.vl_objects[i] is None:
|
||||
# there was no vertex list but ther now is one - create it
|
||||
self.vl_objects[i] = self.batch.add(count[i],
|
||||
pyglet.gl.GL_QUADS,
|
||||
group,
|
||||
('v2i', vertices[i]),
|
||||
('t3f', tex_coords[i]),
|
||||
('c4B', (255,255,255,255)*count[i]))
|
||||
else:
|
||||
# there already is a vertex list - resize and refill
|
||||
self.vl_objects[i].resize(count[i])
|
||||
self.vl_objects[i].tex_coords = tex_coords[i]
|
||||
self.vl_objects[i].vertices = vertices[i]
|
||||
self.vl_objects[i].colors = (255,255,255,255)*count[i]
|
||||
# make object list unique
|
||||
self.cur_objects[i] = list(set(self.cur_objects[i]))
|
||||
|
||||
def update(self, dt):
|
||||
try:
|
||||
if self.window.keys[pyglet.window.key.LCTRL] and \
|
||||
any([self.window.keys[pyglet.window.key.UP],
|
||||
self.window.keys[pyglet.window.key.DOWN],
|
||||
self.window.keys[pyglet.window.key.LEFT],
|
||||
self.window.keys[pyglet.window.key.RIGHT]]):
|
||||
|
||||
if self.window.keys[pyglet.window.key.LEFT]:
|
||||
x = 1
|
||||
elif self.window.keys[pyglet.window.key.RIGHT]:
|
||||
x = -1
|
||||
else:
|
||||
x = 0
|
||||
|
||||
if self.window.keys[pyglet.window.key.UP]:
|
||||
y = -1
|
||||
elif self.window.keys[pyglet.window.key.DOWN]:
|
||||
y = 1
|
||||
else:
|
||||
y = 0
|
||||
self.dx += x*8
|
||||
self.dy += y*8
|
||||
elif self.window.keys[pyglet.window.key.PLUS] and \
|
||||
self.tile_size < 32:
|
||||
self.tile_size+=8
|
||||
self._init_view()
|
||||
elif self.window.keys[pyglet.window.key.MINUS] and \
|
||||
self.tile_size > 16:
|
||||
self.tile_size-=8
|
||||
self._init_view()
|
||||
except KeyError:
|
||||
pass
|
||||
if self.dx or self.dy:
|
||||
self._move(self.dx, self.dy)
|
||||
self.dx = 0
|
||||
self.dy = 0
|
||||
# mouse position:
|
||||
if self.mouse_x != self.mouse_dx or self.mouse_y != self.mouse_dy:
|
||||
self.mouse_x = self.mouse_dx
|
||||
self.mouse_y = self.mouse_dy
|
||||
x = (self.mouse_x-IF_LEFT-self.view_x
|
||||
-(self.tile_size-32)//4)//self.tile_size
|
||||
y = (self.mouse_y-IF_BOTTOM-self.view_y
|
||||
-((self.tile_size-32)*3)//2)//self.tile_size
|
||||
self.label.text = "%03d %03d"%(x-self.div_x, self.div_y-y)
|
||||
|
||||
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
|
||||
self.dx += dx
|
||||
self.dy += dy
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_mouse_motion(self, x, y, dx, dy):
|
||||
self.mouse_dx = x
|
||||
self.mouse_dy = y
|
||||
return pyglet.event.EVENT_HANDLED
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self._init_view()
|
||||
|
||||
def animate_water(self, dt):
|
||||
for i, group in enumerate(self.mapset.groups):
|
||||
if len(self.cur_objects[i]) > 0:
|
||||
pyglet.gl.glBindTexture(self.cur_objects[i][0].tex.target,
|
||||
self.cur_objects[i][0].tex.id)
|
||||
for obj in self.cur_objects[i]:
|
||||
pyglet.gl.glTexSubImage2D(obj.tex.owner.target,
|
||||
obj.tex.owner.level,
|
||||
obj.tex.x, obj.tex.y,
|
||||
obj.tex.width, obj.tex.height,
|
||||
pyglet.gl.GL_RGBA, pyglet.gl.GL_UNSIGNED_BYTE,
|
||||
obj.next_frame())
|
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
heroes renaissance
|
||||
copyright 2008 - Johannes 'josch' Schauer <j.schauer@email.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import pyglet
|
||||
|
||||
class Window(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(1280, 1024, resizable=True, vsync=False)
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
self.push_handlers(self.keys)
|
||||
self.fps = pyglet.clock.ClockDisplay()
|
||||
pyglet.clock.schedule(lambda dt: None)
|
||||
|
||||
def on_draw(self):
|
||||
self.fps.draw()
|
||||
|
||||
def on_key_press(self, symbol, modifiers):
|
||||
if symbol == pyglet.window.key.F11:
|
||||
self.set_fullscreen(fullscreen=not self.fullscreen)
|
||||
elif symbol == pyglet.window.key.P:
|
||||
pyglet.image.get_buffer_manager().get_color_buffer().save(
|
||||
'screenshot.png', encoder=PNGRGBEncoder())
|
||||
|
||||
class PNGRGBEncoder(pyglet.image.codecs.ImageEncoder):
|
||||
def encode(self, image, file, filename):
|
||||
import Image
|
||||
image = image.get_image_data()
|
||||
format = image.format
|
||||
pitch = -(image.width * len(format))
|
||||
pil_image = Image.fromstring(
|
||||
format, (image.width, image.height), image.get_data(format, pitch))
|
||||
try:
|
||||
#.convert('P', palette=Image.WEB)
|
||||
pil_image.convert("RGB").save(file)
|
||||
except Exception, e:
|
||||
raise ImageEncodeException(e)
|
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# An example setup.py that can be used to create both standalone Windows
|
||||
# executables (requires py2exe) and Mac OS X applications (requires py2app).
|
||||
#
|
||||
# On Windows::
|
||||
#
|
||||
# python setup.py py2exe
|
||||
#
|
||||
# On Mac OS X::
|
||||
#
|
||||
# python setup.py py2app
|
||||
#
|
||||
|
||||
from distutils.core import setup
|
||||
|
||||
import os
|
||||
|
||||
# The main entry point of the program
|
||||
script_file = 'hr.py'
|
||||
|
||||
# Setup args that apply to all setups, including ordinary distutils.
|
||||
setup_args = dict(
|
||||
data_files=[]
|
||||
)
|
||||
|
||||
# py2exe options
|
||||
try:
|
||||
import py2exe
|
||||
setup_args.update(dict(
|
||||
windows=[dict(
|
||||
script=script_file,
|
||||
icon_resources=[(1, 'assets/app.ico')],
|
||||
)],
|
||||
))
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# py2app options
|
||||
try:
|
||||
import py2app
|
||||
setup_args.update(dict(
|
||||
app=[script_file],
|
||||
options=dict(py2app=dict(
|
||||
argv_emulation=True,
|
||||
iconfile='assets/app.icns',
|
||||
)),
|
||||
))
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
setup(**setup_args)
|
||||
|
||||
"""
|
||||
Metadata-Version: 1.0
|
||||
Name: UNKNOWN
|
||||
Version: 0.0.0
|
||||
Summary: UNKNOWN
|
||||
Home-page: UNKNOWN
|
||||
Author: UNKNOWN
|
||||
Author-email: UNKNOWN
|
||||
License: UNKNOWN
|
||||
Description: UNKNOWN
|
||||
Platform: UNKNOWN
|
||||
"""
|
@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import pyglet
|
||||
|
||||
atlas1 = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
atlas2 = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
atlas3 = pyglet.image.atlas.TextureAtlas(1024, 1024)
|
||||
|
||||
texture_group1 = pyglet.graphics.TextureGroup(atlas1.texture)
|
||||
texture_group2 = pyglet.graphics.TextureGroup(atlas2.texture)
|
||||
texture_group3 = pyglet.graphics.TextureGroup(atlas3.texture)
|
||||
|
||||
tile1 = atlas1.add(pyglet.image.load(None, file=pyglet.resource.file('test.png')))
|
||||
tile2 = atlas2.add(pyglet.image.load(None, file=pyglet.resource.file('test.png')))
|
||||
tile3 = atlas3.add(pyglet.image.load(None, file=pyglet.resource.file('test.png')))
|
||||
|
||||
tile2.blit_into(pyglet.image.load(None, file=pyglet.resource.file('test2.png')), 0, 0, 0)
|
||||
|
||||
batch = pyglet.graphics.Batch()
|
||||
vertex_list = []
|
||||
|
||||
window = pyglet.window.Window(800, 600, vsync=False)
|
||||
fps = pyglet.clock.ClockDisplay()
|
||||
|
||||
@window.event
|
||||
def on_draw():
|
||||
pyglet.gl.glClear(pyglet.gl.GL_COLOR_BUFFER_BIT)
|
||||
batch.draw()
|
||||
fps.draw()
|
||||
|
||||
pyglet.clock.schedule(lambda dt: None)
|
||||
|
||||
def add_one(dt):
|
||||
vertex_list.append(batch.add(4, pyglet.gl.GL_QUADS, texture_group1,
|
||||
('v2i', [0, 0, 32, 0, 32, 32, 0, 32]),
|
||||
('t3f', tile1.tex_coords),
|
||||
('c4B', (255,255,255,255)*4)))
|
||||
|
||||
def add_two(dt):
|
||||
vertex_list.append(batch.add(4, pyglet.gl.GL_QUADS, texture_group2,
|
||||
('v2i', [8, 8, 40, 8, 40, 40, 8, 40]),
|
||||
('t3f', tile2.tex_coords),
|
||||
('c4B', (255,255,255,255)*4)))
|
||||
|
||||
def add_three(dt):
|
||||
vertex_list.append(batch.add(4, pyglet.gl.GL_QUADS, texture_group3,
|
||||
('v2i', [16, 16, 48, 16, 48, 48, 16, 48]),
|
||||
('t3f', tile3.tex_coords),
|
||||
('c4B', (255,255,255,255)*4)))
|
||||
|
||||
pyglet.clock.schedule_once(add_one, 4.0)
|
||||
pyglet.clock.schedule_once(add_two, 8.0)
|
||||
pyglet.clock.schedule_once(add_three, 12.0)
|
||||
|
||||
pyglet.app.run()
|
@ -0,0 +1,272 @@
|
||||
from __future__ import division
|
||||
from random import randint, choice
|
||||
from itertools import chain, repeat
|
||||
from logging import getLogger
|
||||
|
||||
from pyglet import gl
|
||||
from pyglet import clock
|
||||
from pyglet.event import EventDispatcher
|
||||
from pyglet.resource import Loader
|
||||
from pyglet.image import ImageGrid, TextureGrid, Animation
|
||||
from pyglet.sprite import Sprite
|
||||
from pyglet.graphics import Batch, TextureGroup
|
||||
|
||||
LOGGER = getLogger("defence.tilemap")
|
||||
TILE_LOADER = Loader(["graphics/tiles"])
|
||||
|
||||
class TileLayerGroup(TextureGroup):
|
||||
def __init__(self, texture, translation=(0, 0), rotation=0):
|
||||
super(TileLayerGroup, self).__init__(texture)
|
||||
self.translation = translation
|
||||
self.rotation = rotation
|
||||
|
||||
def set_state(self):
|
||||
super(TileLayerGroup, self).set_state()
|
||||
|
||||
gl.glPushAttrib(gl.GL_COLOR_BUFFER_BIT)
|
||||
gl.glEnable(gl.GL_BLEND)
|
||||
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||
|
||||
x, y = self.translation
|
||||
|
||||
gl.glPushMatrix()
|
||||
gl.glTranslatef(x, y, 0)
|
||||
gl.glRotatef(self.rotation, 0, 0, 1)
|
||||
|
||||
#gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
|
||||
#gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)
|
||||
#gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP)
|
||||
#gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP)
|
||||
#gl.glTexParameterfv(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_BORDER_COLOR, (1, 1, 1, 1))
|
||||
|
||||
def unset_state(self):
|
||||
super(TileLayerGroup, self).unset_state()
|
||||
gl.glPopMatrix()
|
||||
gl.glPopAttrib()
|
||||
|
||||
def __eq__(self, other):
|
||||
return (super(TileLayerGroup, self).__eq__(other)
|
||||
and self.translation == other.translation
|
||||
and self.rotation == other.rotation)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(id=%d, transformation=%s, rotation=%d)' % (
|
||||
self.__class__.__name__,
|
||||
self.texture.id,
|
||||
self.translation,
|
||||
self.rotation)
|
||||
|
||||
|
||||
class Animator(object):
|
||||
def __init__(self, delay):
|
||||
self.delay = delay
|
||||
self.paused = False
|
||||
self.tiles = set()
|
||||
|
||||
def animate(self, dt):
|
||||
for tile in self.tiles:
|
||||
pass
|
||||
|
||||
class Tileset(object):
|
||||
def __init__(self, graphic, tilesize=16, framedelay=1):
|
||||
rows, columns = graphic.height // tilesize, graphic.width // tilesize
|
||||
grid = TextureGrid(ImageGrid(graphic, rows, columns))
|
||||
|
||||
self.texture = grid.texture
|
||||
|
||||
self.frames = rows
|
||||
self.animated = self.frames > 1
|
||||
self.framedelay = framedelay
|
||||
|
||||
self.subtiles = [grid[(0, x):(grid.rows, x+1)] for x in xrange(grid.columns)]
|
||||
self.texcoords = [[frame.tex_coords for frame in subtile] for subtile in self.subtiles]
|
||||
|
||||
def __getitem__(self, index):
|
||||
return self.subtiles[index]
|
||||
|
||||
class Tile(object):
|
||||
def __init__(self, tileset, frame=0):
|
||||
self.tileset = tileset
|
||||
self.frame = frame
|
||||
|
||||
#self.subtiles = (2, 3, 0, 1)
|
||||
self.subtiles = [randint(0, 3) for x in xrange(4)]
|
||||
self.subtiles = [randint(12, 15) for x in xrange(4)]
|
||||
|
||||
def vertices(self, offset=(0, 0)):
|
||||
"""x, y = offset
|
||||
|
||||
vertices = (
|
||||
x, y, x+1, y, x+1, y+1, x, y+1,
|
||||
x+1, y, x+2, y, x+2, y+1, x+1, y+1,
|
||||
x, y+1, x+1, y+1, x+1, y+2, x, y+2,
|
||||
x+1, y+1, x+2, y+1, x+2, y+2, x+1, y+2)"""
|
||||
|
||||
vertices = (
|
||||
0, 0, 1, 0, 1, 1, 0, 1,
|
||||
1, 0, 2, 0, 2, 1, 1, 1,
|
||||
0, 1, 1, 1, 1, 2, 0, 2,
|
||||
1, 1, 2, 1, 2, 2, 1, 2)
|
||||
|
||||
"""vertices = (
|
||||
0, 0, 0, 1, 0, 3, 1, 1, 5, 0, 1, 0,
|
||||
1, 0, 1, 2, 0, 5, 2, 1, 2, 1, 1, 4,
|
||||
0, 1, 9, 1, 1, 0, 1, 2, 1, 0, 2, 5,
|
||||
1, 1, 4, 2, 1, 3, 2, 2, 0, 1, 2, 1)
|
||||
|
||||
offset = list(offset)
|
||||
offset.append(0)"""
|
||||
|
||||
return ((coord * 16) + offset[i%2] for i, coord in enumerate(vertices))
|
||||
|
||||
@property
|
||||
def texcoords(self):
|
||||
for subtile in self.subtiles:
|
||||
for coord in self.tileset.texcoords[subtile][self.frame]:
|
||||
yield coord
|
||||
|
||||
@property
|
||||
def colours(self):
|
||||
return repeat(255, 4*4*4)
|
||||
|
||||
tilesets = {
|
||||
"#": Tileset(TILE_LOADER.image("grass.png")),
|
||||
"~": Tileset(TILE_LOADER.image("water.png"))}
|
||||
|
||||
class TileLayer(EventDispatcher):
|
||||
def __init__(self, tileset, tiles):
|
||||
self.tileset = tileset
|
||||
self._tiles = tiles
|
||||
|
||||
def __getitem__(self, coords):
|
||||
x, y = coords
|
||||
return self._tiles[y][x]
|
||||
|
||||
def __len__(self):
|
||||
return len(list(self.tiles))
|
||||
|
||||
def animate(self, dt):
|
||||
for tile in self.tiles:
|
||||
tile.frame += 1# random.randint(0, 2)
|
||||
if tile.frame >= tile.tileset.frames:
|
||||
tile.frame = 0
|
||||
|
||||
self.dispatch_event("on_animate")
|
||||
|
||||
"""return
|
||||
start = index*(3*4*4)
|
||||
end = (index+1)*(3*4*4)
|
||||
|
||||
self.tempcoords[start:end]=tile.texcoords
|
||||
#self.vlists[0].tex_coords[start:end]=tile.texcoords
|
||||
self.vlists[0].tex_coords=self.tempcoords"""
|
||||
|
||||
@property
|
||||
def tiles(self):
|
||||
for row in self._tiles:
|
||||
for tile in row:
|
||||
if tile is not None:
|
||||
yield tile
|
||||
|
||||
def coordtiles(self):
|
||||
for y, row in enumerate(self.tilelayer):
|
||||
for x, tile in enumerate(row):
|
||||
yield (x, y), tile
|
||||
TileLayer.register_event_type('on_animate')
|
||||
|
||||
class LayerView(object):
|
||||
def __init__(self, mapview, tilelayer):
|
||||
self.tilelayer = tilelayer
|
||||
self.group = TileLayerGroup(self.tilelayer.tileset.texture)
|
||||
self.mapview = mapview
|
||||
self.vlist = None
|
||||
|
||||
def rotate(dt):
|
||||
self.group.rotation += 0.5
|
||||
|
||||
self.tilelayer.push_handlers(self)
|
||||
#clock.schedule_interval(rotate, 0.01)
|
||||
|
||||
def refresh(self):
|
||||
if self.vlist is not None:
|
||||
self.vlist.delete()
|
||||
|
||||
vertices = []
|
||||
for y, row in enumerate(self.tilelayer._tiles):
|
||||
for x, tile in enumerate(row):
|
||||
if tile is not None:
|
||||
vertices.extend(tile.vertices((x*32, y*32)))
|
||||
|
||||
texcoords = list(chain(*(tile.texcoords for tile in self.tilelayer.tiles)))
|
||||
colours = list(chain(*(tile.colours for tile in self.tilelayer.tiles)))
|
||||
|
||||
self.vlist = self.mapview.batch.add(
|
||||
len(self.tilelayer)*16, gl.GL_QUADS, self.group,
|
||||
('v2i', vertices),
|
||||
('t3f', texcoords),
|
||||
('c4B', colours))
|
||||
|
||||
def on_animate(self):
|
||||
def tex():
|
||||
for tile in self.tilelayer.tiles:
|
||||
for texcoord in tile.texcoords:
|
||||
yield texcoord
|
||||
|
||||
self.vlist.tex_coords = list(tex())
|
||||
|
||||
class TileMap(object):
|
||||
def __init__(self, layers):
|
||||
self.layers = [
|
||||
TileLayer(tilesets["#"], [[Tile(tilesets["#"]) for x in xrange(20)] for y in xrange(15)]),
|
||||
TileLayer(tilesets["~"], [[choice((Tile(tilesets["~"]), None)) for x in xrange(20)] for y in xrange(15)])]
|
||||
|
||||
def animate(self, dt):
|
||||
for layer in self.layers:
|
||||
if layer.tileset.animated:
|
||||
layer.animate(dt)
|
||||
|
||||
class MapView(object):
|
||||
def __init__(self, tilemap):
|
||||
self.tilemap = tilemap
|
||||
self.batch = Batch()
|
||||
|
||||
self.layerviews = [LayerView(self, layer) for layer in tilemap.layers]
|
||||
|
||||
self.refresh()
|
||||
|
||||
def refresh(self):
|
||||
for layerview in self.layerviews:
|
||||
layerview.refresh()
|
||||
|
||||
def draw(self):
|
||||
self.batch.draw()
|
||||
|
||||
def move(self, movement):
|
||||
dx, dy = movement
|
||||
for layerview in self.layerviews:
|
||||
x, y = layerview.group.translation
|
||||
layerview.group.translation = (x+dx, y+dy)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import pyglet
|
||||
|
||||
window = pyglet.window.Window(640, 480, "Defence", vsync=False)
|
||||
tmap = TileMap(None)
|
||||
view = MapView(tmap)
|
||||
|
||||
fps = pyglet.clock.ClockDisplay()
|
||||
|
||||
@window.event
|
||||
def on_draw():
|
||||
window.clear()
|
||||
view.draw()
|
||||
fps.draw()
|
||||
|
||||
@window.event
|
||||
def on_mouse_drag(x, y, dx, dy, buttons, modifiers):
|
||||
view.move((dx, dy))
|
||||
|
||||
pyglet.clock.schedule_interval(tmap.animate, 1/10.0)
|
||||
pyglet.clock.schedule(lambda dt: None)
|
||||
pyglet.app.run()
|
||||
|
Loading…
Reference in New Issue