/* * $Id: level.cc,v 1.6 2002/09/18 21:46:22 stefan Exp $ * Copyright (c) 2002, Dominik Schnitzer * * JFK - JFK Fucking Killerz, a massive multiplayer 2d shoot'em-up game * http://relax.ath.cx/jfk/ * * 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 2 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 Library General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include "game.h" #include "level.h" #include "output.h" #include "objects_c.h" #include "sprite.h" #include "debug.h" using namespace std; using namespace JFK::client; level::level(output* output, int width, int height) { LOG(("Initializing a new level with extents: %dx%d", width, height)); out = output; w = width; h = height; load_images(); earth = out->load_image("ground", "waste.png", 0, true); gamefont = new font(out, "console.png"); earthsize = out->get_image_width(earth); } level::~level() { LOG(("Closing the level.")); out->free_image(earth); for (size_t i = 0; i < OBJECT_MAX; i++) { for (size_t j = 0; j < images[i].size(); j++) { delete images[i][j]; } } for (size_t i = 0; i < LAYER_MAX; i++) { for (size_t j = 0; j < layer[i].size(); j++) { delete layer[i][j]; } } delete gamefont; } void level::load_images() { /* ATTENTION: If there are > 1 sprites in one Object section, the order * of loading the images is very important: * They have to be loaded the same way they're enumerated in the according * object header file */ /* The weapons */ images[JFK::OBJECT_WEAPON].push_back( new sprite(out, "object/weapon", "weapon_0.png")); images[JFK::OBJECT_WEAPON].push_back( new sprite(out, "object/weapon", "weapon_1.png")); images[JFK::OBJECT_WEAPON].push_back( new sprite(out, "object/weapon", "weapon_2.png")); images[JFK::OBJECT_WEAPON].push_back( new sprite(out, "object/weapon", "weapon_3.png")); images[JFK::OBJECT_WEAPON].push_back( new sprite(out, "object/weapon", "weapon_4.png")); images[JFK::OBJECT_WEAPON].push_back( new sprite(out, "object/weapon", "weapon_5.png")); /* The player images */ images[JFK::OBJECT_PERSON].push_back( new sprite(out, "object/person", "player_@.png")); /* The items lying around */ images[JFK::OBJECT_ITEM].push_back( new sprite(out, "object/item", "medikit_s.png")); images[JFK::OBJECT_ITEM].push_back( new sprite(out, "object/item", "medikit.png")); images[JFK::OBJECT_ITEM].push_back( new sprite(out, "object/item", "ammo_s.png")); images[JFK::OBJECT_ITEM].push_back( new sprite(out, "object/item", "ammo.png")); images[JFK::OBJECT_ITEM].push_back( new sprite(out, "object/item", "grave_@.png")); images[JFK::OBJECT_ITEM].push_back( new sprite(out, "object/item", "beer.png")); /* Bullets */ images[JFK::OBJECT_BULLET].push_back( new sprite(out, "object/bullet", "weapon_0_bullet_@.png")); /* Those nice explosions */ images[JFK::OBJECT_EXPLOSION].push_back( new sprite(out, "object/explosion", "explode_@.png")); /* Obstacles */ /* TODO: We should load a house here... :) */ images[JFK::OBJECT_OBSTACLE].push_back( new sprite(out, "object/obstacle", "tree_0.png")); /* TODO: We should load a wall here... :) */ images[JFK::OBJECT_OBSTACLE].push_back( new sprite(out, "object/obstacle", "tree_0.png")); images[JFK::OBJECT_OBSTACLE].push_back( new sprite(out, "object/obstacle", "bush_0.png")); images[JFK::OBJECT_OBSTACLE].push_back( new sprite(out, "object/obstacle", "tree_0.png")); images[JFK::OBJECT_OBSTACLE].push_back( new sprite(out, "object/obstacle", "stone_0.png")); images[JFK::OBJECT_OBSTACLE].push_back( new sprite(out, "object/obstacle", "lake_0.png")); } sprite* level::get_image(JFK::object_type otype, int type) { return images[otype][type]; } void level::set_viewport(double x, double y) { if (x < 0) x = 0; if (y < 0) y = 0; if (x + out->get_width()> w) x = w - out->get_width(); if (y + out->get_height() - 96 > h) y = h - out->get_height() + 96; posx = (int) floor(x); posy = (int) floor(y); } void level::draw() { int i, j; /* Do the level specific stuff */ if (player != NULL) set_viewport(player->x-(800/2), player->y-(500/2)); /* Dont forget the panel */ out->set_cliprect(0, 0, out->get_width(), out->get_height() - 96); for (i = -(posx % earthsize); i < out->get_width(); i += earthsize) { for (j = -(posy % earthsize); j < (out->get_height() - 96); j += earthsize) out->draw_image(earth, i, j); } /* Draw all available objects... */ for (size_t i = 0; i < LAYER_MAX; i++) { for (size_t j = 0; j < layer[i].size(); j++) layer[i][j]->draw(); } out->set_cliprect(0, 0, 0, 0); } void level::create_object(const string& s) { object* nobj; istringstream iss(s); string type; string tmp; string rest; unsigned long id; size_t layernr = LAYER_MAX; iss >> type >> id; while (iss >> tmp) rest += ' ' + tmp; if (type == "person") { nobj = new person(this, rest); layernr = LAYER_PERSON; } else if (type == "ownperson") { nobj = new person(this, rest); player = dynamic_cast(nobj); layernr = LAYER_PERSON; } else if (type == "obstacle") { nobj = new obstacle(this, rest); layernr = dynamic_cast(nobj)->type == OBS_LAKE1 ? LAYER_GROUND : LAYER_OBSTACLE; } else if (type == "bullet") { nobj = new bullet(this, rest); layernr = dynamic_cast(nobj)->type == GRENADE ? LAYER_AIR : LAYER_ITEM; } else if (type == "explosion") { nobj = new explosion(this, rest); layernr = LAYER_AIR; } else if (type == "item") { nobj = new item(this, rest); layernr = dynamic_cast(nobj)->type == GRAVE ? LAYER_GRAVE : LAYER_ITEM; } else if (type == "weapon") { nobj = new weapon(this, rest); layernr = LAYER_ITEM; } else { LOG(("Unknown object received: %s", type.c_str())); nobj = NULL; } /* Put the created object in the right drawing layer */ if (nobj) { nobj->id = id; assert(layernr < LAYER_MAX); layer[layernr].push_back(nobj); } } void level::delete_object(unsigned long id) { size_t i, j; for (i = 0; i < LAYER_MAX; i++) { for (j = 0; j < layer[i].size(); j++) { if (layer[i][j]->id == id) { swap(layer[i][j], layer[i].back()); delete layer[i].back(); layer[i].resize(layer[i].size() - 1); return; } } } LOG(("Bad object id")); } void level::update_object(unsigned long id, const string& s) { size_t i, j; for (i = 0; i < LAYER_MAX; i++) { for (j = 0; j < layer[i].size(); j++) { if (layer[i][j]->id == id) { layer[i][j]->fromstring(s); return; } } } LOG(("Bad object id")); } void level::move_objects(unsigned long micsecs) { size_t i, j; for (i = 0; i < LAYER_MAX; i++) { for (j = 0; j < layer[i].size(); j++) layer[i][j]->move(micsecs * JFK::GAME_SPEED); } } vector* level::get_players() { return &layer[LAYER_PERSON]; }