/* Hurry Curry! - a game about cooking Copyright 2024 metamuffin This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License only. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ use crate::{sprite_renderer::SpriteRenderer, tilemap::Tilemap}; use hurrycurry_protocol::{ glam::{IVec2, Vec2}, PacketC, PlayerID, TileIndex, }; use log::{info, warn}; use sdl2::rect::FRect; use std::collections::HashMap; pub struct Game { tiles: HashMap, tilemap: Tilemap, players: HashMap, my_id: PlayerID, } pub struct Tile { kind: TileIndex, } pub struct Player { character: i32, position: Vec2, name: String, boosting: bool, rot: f32, } impl Game { pub fn new() -> Self { Self { tiles: HashMap::new(), players: HashMap::new(), tilemap: Tilemap::default(), my_id: PlayerID(0), } } pub fn packet_in(&mut self, packet: PacketC, renderer: &mut SpriteRenderer) { match packet { PacketC::Init { id } => self.my_id = id, PacketC::Data { data } => { self.tilemap.init(&data.tile_names, renderer.metadata()); } PacketC::UpdateMap { tile, kind, neighbors, } => { if let Some(kind) = kind { self.tiles.insert(tile, Tile { kind }); } else { self.tiles.remove(&tile); } self.tilemap.set(tile, kind, neighbors); } PacketC::AddPlayer { id, position, character, name, } => { info!("add player {} {name:?}", id.0); self.players.insert( id, Player { character, position, name, boosting: false, rot: 0., }, ); } PacketC::RemovePlayer { id } => { info!("remove player {}", id.0); self.players.remove(&id); } PacketC::Position { player, pos, rot, boosting, } => { if let Some(p) = self.players.get_mut(&player) { p.position = pos; p.rot = rot; p.boosting = boosting; } } PacketC::MoveItem { from, to } => (), PacketC::SetItem { location, item } => (), PacketC::SetProgress { item, progress, warn, } => (), PacketC::Collide { player, force } => (), PacketC::Communicate { player, message, persist, } => (), PacketC::ServerMessage { text } => (), PacketC::Score { points, demands_failed, demands_completed, time_remaining, } => (), PacketC::SetIngame { state, lobby } => (), PacketC::Error { message } => { warn!("server error: {message:?}") } _ => (), } } pub fn draw(&self, ctx: &mut SpriteRenderer) { self.tilemap.draw(ctx); for p in self.players.values() { let src = ctx.misc_textures().player; let dst = FRect::new( p.position.x - src.width() as f32 / 32. / 2., p.position.y + 1. - src.height() as f32 / 24., src.width() as f32 / 32., src.height() as f32 / 24., ); ctx.draw(((dst.y + dst.h + 1.) * 24.) as i32, src, dst); } } }