game/old/client.py
2020-05-11 19:52:50 -05:00

293 lines
8.0 KiB
Python

import pygame
import os
import random
import recipes
import sys
import select
import blocks
import socket
import pickle
import lib.constants as constants
from lib.gameregistry import GameRegistry
from lib.map import Map
from lib.character import Character
from lib.block import Block
from lib.player import Player
from lib.player_img import PlayerImg
from showstep import show_step
from time import sleep
import pprint
pp=pprint.PrettyPrinter(indent=2)
def recv_str(sock,print_str=True):
str=""
ch=""
while True:
ch=sock.recv(1).decode("utf-8")
if ch=="\n":
break
str+=ch
if print_str:
pass
# print("Got string: "+str)
return str
def send_str(sock,str):
# print("Sending string: "+str)
sock.send((str+"\n").encode("utf-8"))
def recv_hash(sock):
hash={}
len=int(recv_str(sock,False))
for _ in range(len):
key=recv_str(sock,False)
val=recv_str(sock,False)
hash[key]=val
# print("Got hash: "+pp.pformat(hash))
return hash
def recvall(sock):
BUFF_SIZE=4096
data=b''
while True:
part=sock.recv(BUFF_SIZE)
data+=part
if len(part)<BUFF_SIZE:
break
# print("Got data: "+pp.pformat(pickle.loads(data)))
return data
UNAME=input("UNAME:")
pygame.init()
Block.init()
recipes.init()
pygame.display.set_caption(UNAME)
screen=pygame.display.set_mode((constants.WINDWIDTH,constants.WINDHEIGHT))
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# show_step("Connecting to game server")
sock.connect(("localhost",2000))
# show_step("Adding user to server (Sending ADD_USR {})".format(UNAME))
send_str(sock,"ADD_USR")
send_str(sock,UNAME)
# show_step("Recieving UID")
my_uid=int(recv_str(sock))
# show_step("Got UID {}".format(my_uid))
# show_step("Initializing UID map")
uid_map={}
# show_step("Initializing level map")
map=Map(screen,sock,my_uid)
map.tiles={}
# show_step("Retreiving player position and facing (Sending GET_POS_FOR_UID {})".format(my_uid))
send_str(sock,"GET_POS_FOR_UID")
send_str(sock,str(my_uid))
x=int(recv_str(sock))
y=int(recv_str(sock))
fac=recv_str(sock)
# show_step("Got position ({},{}), facing {}".format(x,y,fac))
# show_step("Initializing player")
player=Player(x,y,map,screen,UNAME,"player_local")
player.dir=fac
# show_step("Adding workbench to inventory")
player.inv.addTile("workbench",1)
# show_step("Initializing misc game variables")
others={}
running=True
move=False
inv=False
helvetica_neue=pygame.font.SysFont('Helvetica Neue',constants.FONTSIZE)
key_to_dir={
pygame.K_UP:"up",
pygame.K_DOWN:"down",
pygame.K_LEFT:"left",
pygame.K_RIGHT:"right"
}
while running:
# show_step("Updating game and drawing frame")
send_str(sock,"GET_UID_MAP")
uid_map=recv_hash(sock)
# Will be filled with usernames of connected players
connected=[]
for uname,uid in uid_map.items():
if uname!=UNAME:
send_str(sock,"GET_POS_FOR_UID")
send_str(sock,uid)
x=int(recv_str(sock))
y=int(recv_str(sock))
fac=recv_str(sock)
if uname in others:
others[uname].x=x
others[uname].y=y
else:
others[uname]=PlayerImg(x,y,screen,"player")
others[uname].dir=fac
connected.append(uname)
# Remove all disconnected players
others_copy=others.copy()
for uname,uid in others_copy.items():
if not uname in connected:
del others[uname]
send_str(sock,"GET_CHANGES_FOR")
send_str(sock,str(my_uid))
data=recvall(sock)
changes=pickle.loads(data)
for change in changes:
if change["type"]=="break":
x=change["x"]
y=change["y"]
tile=map.tileAt(x,y)
name=tile.unlocalisedName
if name=="grass":
continue
map.tiles[(x,y)]=None
map.addTile("grass",x,y)
if change["type"]=="place":
x=change["x"]
y=change["y"]
block=change["block"]
map.tiles[(x,y)]=None
map.addTile(block,x,y)
if change["type"]=="interact":
x=change["x"]
y=change["y"]
block_data=change["block_data"]
tile=map.tileAt(x,y)
tile.loadData(block_data)
for s in map.tiles.values():
if s.mp_upd:
data=s.interactData()
send_str(sock,"INTERACT_BLOCK_AT")
send_str(sock,str(my_uid))
send_str(sock,str(s.x))
send_str(sock,str(s.y))
data_string=pickle.dumps(data)
sock.send(data_string)
if select.select([sys.stdin],[],[],0.0)[0]:
cmd=input()
cmd=cmd.split()
if len(cmd)==1:
if cmd[0]=="give":
if len(cmd)==2:
item=cmd[1]
player.inv.addTile(item,1)
elif len(cmd)==3:
item=cmd[1]
count=int(cmd[2])
player.inv.addTile(item,count)
else:
print("give <item> [count]")
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
elif event.type==pygame.KEYDOWN:
print("DOWN")
print(event.key)
if event.key==pygame.K_PERIOD:
coords=player.facingTile()
if coords!=False:
tile=map.tileAt(coords[0],coords[1])
name=tile.unlocalisedName
if name=="grass":
to_place=player.inv.selected
if to_place!="":
send_str(sock,"PLACE_BLOCK_AT")
send_str(sock,str(my_uid))
send_str(sock,str(coords[0]))
send_str(sock,str(coords[1]))
send_str(sock,str(to_place))
player.interact()
else:
player.interact()
tile=map.tileAt(coords[0],coords[1])
data=tile.interactData()
if data!=None:
send_str(sock,"INTERACT_BLOCK_AT")
send_str(sock,str(my_uid))
send_str(sock,str(coords[0]))
send_str(sock,str(coords[1]))
data_string=pickle.dumps(data)
sock.send(data_string)
if event.key==pygame.K_SLASH:
player.attack()
facing=player.facingTile()
print(facing)
if facing!=False:
print("BREAK")
x=facing[0]
y=facing[1]
send_str(sock,"BREAK_BLOCK_AT")
send_str(sock,str(my_uid))
send_str(sock,str(x))
send_str(sock,str(y))
if event.key==pygame.K_j:
player.inv.selPrev()
if event.key==pygame.K_k:
player.inv.clearSel()
if event.key==pygame.K_l:
player.inv.selNext()
if event.key==pygame.K_e:
inv=not inv
if event.key==pygame.K_i:
dy_blocks=blocks.dy_blocks
Block.textures={}
Block.init()
for klass,unName in dy_blocks.items():
Block.registerTexture(unName)
elif event.key in key_to_dir.keys():
move=True
dir=key_to_dir[event.key]
elif event.type==pygame.KEYUP:
move=False
player.frame=1
if move:
player.move(dir)
send_str(sock,"SET_POS_FOR_UID")
send_str(sock,str(my_uid))
send_str(sock,str(player.x))
send_str(sock,str(player.y))
send_str(sock,player.dir)
if inv:
screen.fill([255,255,255])
text=[]
label=[]
for item, count in player.inv.inv.items():
text.append("{} {}".format(count,item))
for line in text:
label.append(helvetica_neue.render(line, True, (0,0,0)))
for line in range(len(label)):
screen.blit(label[line],(1,(line*constants.FONTSIZE)+(2*line)))
pygame.display.flip()
else:
screen.fill([0,0,0])
map.draw(player.x,player.y)
player.draw()
selected=player.inv.selected
if selected!="":
texture=Block.textures[selected]
screen.blit(texture,(0*constants.TILESIZE,constants.PORTHEIGHT*constants.TILESIZE))
topleftx=player.x-constants.CENTERX
toplefty=player.y-constants.CENTERY
x=topleftx
y=toplefty
while True:
other=None
for uname,o in others.items():
if o.x==x and o.y==y:
other=o
break
if other:
other.draw(x-topleftx,y-toplefty)
x+=1
if x==topleftx+constants.PORTWIDTH:
x=topleftx
y+=1
if y==toplefty+constants.PORTHEIGHT:
break
pygame.display.flip()
sleep(0.1)
send_str(sock,"CLOSE")
send_str(sock,UNAME)
sock.close()