[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Enigma-cvs] enigma/src floors.cc,NONE,1.1 levels.hh,NONE,1.1
From: |
Daniel Heck <address@hidden> |
Subject: |
[Enigma-cvs] enigma/src floors.cc,NONE,1.1 levels.hh,NONE,1.1 |
Date: |
Mon, 20 Oct 2003 08:10:12 +0000 |
Update of /cvsroot/enigma/enigma/src
In directory subversions:/tmp/cvs-serv11282
Added Files:
floors.cc levels.hh
Log Message:
New files
--- NEW FILE: floors.cc ---
/*
* Copyright (C) 2002,2003 Daniel Heck
*
* 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 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.
*
* $Id: floors.cc,v 1.1 2003/10/20 08:10:09 dheck Exp $
*/
#include "game.hh"
#include "objects.hh"
#include "object_mixins.hh"
using namespace world;
using namespace std;
Floor::Floor(const char *kind, double friction_, double mfactor)
: TGridObject<GRID_FLOOR>(kind),
traits (kind, friction_, mfactor, FLOOR_Normal)
{}
Floor::Floor (const FloorTraits &tr)
: TGridObject<GRID_FLOOR>(tr.name.c_str()), traits (tr)
{}
Floor *Floor::clone() {
return this;
}
void Floor::dispose() {
; // do nothing
}
void Floor::message(const string& msg, const Value &/*val*/)
{
}
px::V2 Floor::process_mouseforce (Actor *a, px::V2 force)
{
if (a->int_attrib("controllers") & (1+player::CurrentPlayer()))
return mousefactor() * force;
else
return V2();
}
namespace
{
/* -------------------- Abyss -------------------- */
class Abyss : public Floor {
CLONEOBJ(Abyss);
public:
Abyss() : Floor("fl-abyss", 2.0, 1) {}
private:
// void actor_enter(Actor* a) {SendMessage(a, "fall");}
void actor_contact (Actor* a) {SendMessage(a, "fall");}
bool is_destroyable() const {return false;}
};
/* -------------------- Water -------------------- */
class Water : public Floor {
CLONEOBJ(Water);
public:
Water() : Floor("fl-water", 5, 1) {}
private:
// void actor_enter(Actor *a) {SendMessage(a, "drown");}
void actor_contact(Actor *a) {SendMessage(a, "drown");}
bool is_destroyable() const {return false;}
};
/* -------------------- Swamp -------------------- */
class Swamp : public Floor {
CLONEOBJ(Swamp);
public:
Swamp() : Floor("fl-swamp", 13, 1.0) {}
private:
void actor_contact(Actor *a) { SendMessage(a, "sink"); }
void actor_leave(Actor *a) {
Floor *new_floor = GetFloor(GridPos(a->get_pos()));
if (!new_floor->is_kind("fl-swamp")) {
SendMessage(a, "getout");
}
}
bool is_destroyable() const {return false;}
};
/* -------------------- FallenBox -------------------- */
class FallenBox : public Floor {
CLONEOBJ(FallenBox);
public:
FallenBox(const char *kind)
: Floor(modify_kind(kind), 6.4, 2.0) // uses same traits as fl-wood
{}
private:
const char *modify_kind(const char *kind) {
if (0 == strcmp(kind, "fl-stwood")) {
return enigma::IntegerRand(0, 1) ? "fl-stwood1" : "fl-stwood2";
}
return kind;
}
};
/* -------------------- DummyFloor -------------------- */
class DummyFloor : public Floor {
CLONEOBJ(DummyFloor);
public:
DummyFloor() : Floor("fl-dummy", 4.0, 2.5) {}
private:
void actor_enter(Actor *) {
static int lastCode = -1;
int code = int_attrib("code");
if (lastCode != code) {
fprintf(stderr, "Entering floor 0x%x\n", code);
lastCode = code;
}
}
};
}
//----------------------------------------
// Gradient
//----------------------------------------
/** \page fl-gradient Gradient Floor
This is a sloped floor that accelerates in a particular direction.
\subsection gradienta Attributes
- \b type: number between 0 and 15 (see below)
\subsection gradiente Examples
*/
namespace
{
class Gradient : public Floor {
CLONEOBJ(Gradient);
public:
Gradient(int type=MINTYPE);
private:
int get_type() const;
enum { MINTYPE=1, MAXTYPE=24 };
// GridObject interface.
virtual void init_model();
// Floor interface
virtual px::V2 get_force(Actor *a);
};
}
Gradient::Gradient(int type)
: Floor("fl-gradient", 4, 2)
{
set_attrib ("type", Value(type));
// set_attrib ("force", Value(1.0));
}
int Gradient::get_type() const
{
int t=int_attrib("type");
if (t < MINTYPE || t>MAXTYPE) {
enigma::Log << "Gradient: Illegal type="<< int(t) << endl;
t=MINTYPE;
}
return t;
}
void Gradient::init_model()
{
char mname[20];
sprintf(mname, "fl-gradient%d", get_type());
set_model(mname);
}
px::V2 Gradient::get_force(Actor */*a*/)
{
V2 force;
int t = get_type();
static int xforce[MAXTYPE-MINTYPE+1] = {
0, 0, 1, -1,
1, -1, 1, -1,
1, 1, -1, -1,
-1, -1, 1, 1,
1, -1, 1, -1,
0, 0, 1, -1
};
static int yforce[MAXTYPE-MINTYPE+1] = {
1, -1, 0, 0,
1, 1, -1, -1,
1, -1, 1, -1,
1, -1, 1, -1,
-1, -1, 1, 1,
1, -1, 0, 0
};
force = V2(xforce[t-MINTYPE], yforce[t-MINTYPE]);
force.normalize();
// use enigma::SlopeForce if no "force" attribute is set
double factor = enigma::SlopeForce;
double_attrib("force", &factor);
return factor*force;
}
//----------------------------------------
// Bridge
//----------------------------------------
/** \page fl-bridge Bridge Floor
This Floor can be opened and closed much like a bridge.
The actor can move over this floor if the bridge is closed,
and will fall into abyss when the bridge is open.
\subsection bridgea Attributes
- \b type The type of the bridge, currently only 'a' is possible
\subsection bridgem Messages
- \b open open the bridge so actors cannot pass it
- \b close close the bridge so actors can pass it
- \b openclose toggle the state of the bridge
- \b signal same as \b openclose
*/
namespace
{
class Bridge : public Floor {
CLONEOBJ(Bridge);
public:
Bridge(bool open=true);
private:
enum State {
OPEN, CLOSED, OPENING, CLOSING, // normal states
CLOSING_BYSTONE, CLOSED_BYSTONE // when stones are moved onto the
bridge
} state;
// the BYSTONE-states look like closed, but act like open
char get_type() const {
string type = "a";
string_attrib("type", &type);
return type[0];
}
// void actor_enter(Actor *);
void actor_contact (Actor* a) {if (state!=CLOSED) SendMessage(a,
"fall");}
void message(const string &m, const Value &);
void init_model();
void stone_change(Stone *st);
void change_state( State newstate);
void animcb();
};
}
Bridge::Bridge(bool open) : Floor("fl-bridge", 5, 1)
{
set_attrib("type", "a");
state=open ? OPEN : CLOSED;
}
void Bridge::stone_change(Stone *st) {
if (st && !st->is_floating()) {
if (state == OPEN || state == OPENING) {
change_state(CLOSING_BYSTONE);
}
}
else {
if (state == CLOSED_BYSTONE || state == CLOSING_BYSTONE) {
change_state(OPENING);
}
}
}
void Bridge::message(const string &m, const Value &)
{
if (m == "open" && (state==CLOSED || state==CLOSING))
change_state(OPENING);
else if (m=="close")
switch (state) {
case OPEN:
case OPENING:
case CLOSING_BYSTONE:
change_state(CLOSING);
break;
case CLOSED_BYSTONE:
change_state(CLOSED);
break;
case CLOSED:
case CLOSING:
break; // already closed
}
else if (m=="openclose" || m=="signal")
switch (state) {
case OPEN:
case OPENING:
case CLOSING_BYSTONE:
change_state(CLOSING);
break;
case CLOSED_BYSTONE:
change_state(CLOSED);
break;
case CLOSED:
case CLOSING:
change_state(OPENING);
break;
}
}
// void Bridge::actor_enter(Actor *a)
// {
// if (state != CLOSED)
// SendMessage(a, "fall");
// }
void Bridge::init_model()
{
char mname[25];
sprintf(mname, "fl-bridge%c-%s", get_type(),
(state==OPEN) ? "open" : "closed");
set_model(mname);
}
void Bridge::change_state( State newstate)
{
if (state != newstate) {
string mname = string("fl-bridge")+get_type();
switch( newstate) {
case OPENING: {
Stone *st = GetStone(get_pos());
if (st && !st->is_floating()) {
if (state == CLOSED || state == CLOSED_BYSTONE)
newstate = CLOSED_BYSTONE;
else if (state == CLOSING || state == CLOSING_BYSTONE)
newstate = CLOSING_BYSTONE;
// here the model is already correct!
}
else { // no stone or floating stone :
if( state == CLOSING || state == CLOSING_BYSTONE)
get_model()->reverse();
else
set_anim(mname+"-opening");
}
break;
}
case CLOSING:
case CLOSING_BYSTONE:
if( state == OPENING)
get_model()->reverse();
else if (state != CLOSING && state != CLOSING_BYSTONE)
set_anim(mname+"-closing");
break;
case OPEN:
case CLOSED:
case CLOSED_BYSTONE:
state = newstate;
init_model();
break;
}
state = newstate;
}
}
void Bridge::animcb()
{
switch (state) {
case OPENING: change_state(OPEN); break;
case CLOSING: change_state(CLOSED); break;
case CLOSING_BYSTONE: change_state(CLOSED_BYSTONE); break;
default : assert(0); break;
}
}
//----------------------------------------
// Black and white tiles
//----------------------------------------
namespace
{
class BlackTile : public Floor {
public:
BlackTile() : Floor ("fl-acblack", 5.0, 2.0) {}
px::V2 process_mouseforce (Actor *a, px::V2 force)
{
if (player::CurrentPlayer() == 0) // && player::IsCurrentPlayer(a))
return mousefactor() * force;
else
return V2();
}
};
class WhiteTile : public Floor {
public:
WhiteTile() : Floor ("fl-acwhite", 5.0, 2.0) {}
px::V2 process_mouseforce (Actor *a, px::V2 force)
{
if (player::CurrentPlayer() == 1) // && player::IsCurrentPlayer(a))
return mousefactor() * force;
else
return V2();
}
};
}
void InitFloors()
{
// Floors (most floors are defined in init.lua)
Register(new Abyss);
Register(new Water);
Register(new Swamp);
Register(new DummyFloor);
Register(new FallenBox("fl-stwood"));
Register(new FallenBox("fl-stwood1"));
Register(new FallenBox("fl-stwood2"));
Register(new Bridge);
Register("fl-bridge-open", new Bridge(true));
Register("fl-bridge-closed", new Bridge(false));
Register(new WhiteTile);
Register(new BlackTile);
Register(new Gradient);
Register("fl-gradient1", new Gradient(1));
Register("fl-gradient2", new Gradient(2));
Register("fl-gradient3", new Gradient(3));
Register("fl-gradient4", new Gradient(4));
Register("fl-gradient5", new Gradient(5));
Register("fl-gradient6", new Gradient(6));
Register("fl-gradient7", new Gradient(7));
Register("fl-gradient8", new Gradient(8));
Register("fl-gradient9", new Gradient(9));
Register("fl-gradient10", new Gradient(10));
Register("fl-gradient11", new Gradient(11));
Register("fl-gradient12", new Gradient(12));
Register("fl-gradient13", new Gradient(22));
Register("fl-gradient14", new Gradient(21));
Register("fl-gradient15", new Gradient(24));
Register("fl-gradient16", new Gradient(23));
}
--- NEW FILE: levels.hh ---
/*
* Copyright (C) 2002,2003 Daniel Heck
*
* 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 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.
*
* $Id: levels.hh,v 1.1 2003/10/20 08:10:09 dheck Exp $
*/
#ifndef LEVELS_HH
#define LEVELS_HH
namespace levels
{
/* Enigma can run its own levels but also emulate various versions
of Oxyd. All these games behave similarly, but there are also
quite a few differences in object behaviour, visual appearance,
etc. The game type is set at program startup and cannot be
changed during the game. */
enum GameType {
GAMET_FIRST,
GAMET_ENIGMA = GAMET_FIRST,
GAMET_OXYD1,
GAMET_PEROXYD,
GAMET_OXYDEXTRA,
GAMET_OXYDMAGNUM,
GAMET_LAST = GAMET_OXYDMAGNUM,
GAMET_COUNT,
GAMET_UNKNOWN
};
/* This datastructure contains information about individual
levels. */
struct LevelInfo
{
// Variables.
string filename; // Filename of the level _without_ extension
string name; // Complete name of the level
string author; // Author of the level
GameType type;
int best_time; // Best time in seconds
int revision; // Revision # of this level
string hint1, hint2; // Hints for solving this level
// Methods
enum { DEFAULT_TIME = 99*60+59 };
LevelInfo(const string &fn,
const string &n,
const string &a,
GameType gt,
int par_time = DEFAULT_TIME
)
: filename(fn), name(n), author(a), type(gt), best_time(par_time)
{}
LevelInfo() {
best_time = DEFAULT_TIME;
type = GAMET_ENIGMA;
}
};
struct LevelStatus {
LevelStatus(int easy=-1, int hard=-1, int fin=0, std::time_t solv = 0);
bool operator != (const LevelStatus& other) const;
// Variables.
int time_easy, time_hard; // Best time in seconds (-1: use level
default)
int finished; // Level solved? 0 =
no,1=easy,2=hard,3=easy&hard
std::time_t solved_at; // date when level was solved last time
int solved_revision; // Revision # that was solved
};
class LevelPack {
public:
virtual ~LevelPack() {}
//! Return level pack's name
virtual string get_name() const = 0;
//! Return number of levels
virtual size_t size() const = 0;
/* Load a level into the game engine */
virtual bool load_level (size_t index) = 0;
virtual const LevelInfo *get_info (size_t index) = 0;
virtual px::Surface *load_preview (size_t /*index*/) { return 0; }
//! Return file modification time of level(pack)
virtual std::time_t get_modtime(size_t index) = 0;
//! Return the default SoundSet (see options::SoundSet for meaning)
virtual int get_default_SoundSet() const = 0;
//! returns true if it's a twoplayer levelpack, but has no it-yinyang
// (needed to add it-yinyang to inventory if oxyd-linkgame is played as
single-player)
virtual bool needs_twoplayers() const = 0;
// returns true if LevelPack may have previews
virtual bool may_have_previews() const = 0;
};
}
#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Enigma-cvs] enigma/src floors.cc,NONE,1.1 levels.hh,NONE,1.1,
Daniel Heck <address@hidden> <=