Add MissileConfig

and some clean up.
This commit is contained in:
Joris 2012-04-18 12:16:22 +02:00
parent 5e5fca8fd0
commit 50e5390ca7
10 changed files with 220 additions and 146 deletions

View file

@ -195,6 +195,7 @@ set(missile_SRCS
src/missile/missile_stay.cpp
src/missile/missile_tracer.cpp
src/missile/missile_whirlwind.cpp
src/missile/missileconfig.cpp
src/missile/script_missile.cpp
)
source_group(missile FILES ${missile_SRCS})
@ -463,6 +464,7 @@ set(stratagus_generic_HDRS
src/include/menus.h
src/include/minimap.h
src/include/missile.h
src/include/missileconfig.h
src/include/movie.h
src/include/myendian.h
src/include/netconnect.h

View file

@ -153,28 +153,16 @@
**
** Determines The Splash damage divisor, see Range
**
** MissileType::ImpactName
** MissileType::Impact
**
** The name of the next (other) missile to generate, when this
** The config of the next (other) missile to generate, when this
** missile reached its end point or its life time is over. So it
** can be used to generate a chain of missiles.
** @note Used and should only be used during configuration and
** startup.
**
** MissileType::ImpactMissile
** MissileType::Smoke
**
** Pointer to the impact missile-type. Used during run time.
**
** MissileType::SmokeName
**
** The name of the next (other) missile to generate a trailing smoke. So it
** The config of the next (other) missile to generate a trailing smoke. So it
** can be used to generate a chain of missiles.
** @note Used and should only be used during configuration and
** startup.
**
** MissileType::SmokeMissile
**
** Pointer to the smoke missile-type. Used during run time.
**
** MissileType::Sprite
**
@ -314,6 +302,7 @@
-- Includes
----------------------------------------------------------------------------*/
#include "missileconfig.h"
#include "unitptr.h"
#include "unitsound.h"
#include "vec2i.h"
@ -369,6 +358,8 @@ public:
void Init();
void DrawMissileType(int frame, const PixelPos &pos) const;
void Load(lua_State *l);
int Width() const { return size.x; }
int Height() const { return size.y; }
@ -398,10 +389,8 @@ public:
int Range; /// missile damage range
int SplashFactor; /// missile splash divisor
std::string ImpactName; /// impact missile-type name
MissileType *ImpactMissile;/// missile produces an impact
std::string SmokeName; /// impact missile-type name
MissileType *SmokeMissile; /// Trailling missile
MissileConfig Impact; /// missile produces an impact
MissileConfig Smoke; /// Trailling missile
LuaCallback *ImpactParticle; /// impact particle
// --- FILLED UP ---
@ -432,6 +421,8 @@ public:
void NextMissileFrameCycle();
void MissileNewHeadingFromXY(const PixelPos &delta);
//private:
PixelPos source; /// Missile source position
PixelPos position; /// missile pixel position
PixelPos destination; /// missile pixel destination

View file

@ -0,0 +1,57 @@
// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
// \/ \/ \//_____/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// Stratagus - A free fantasy real time strategy game engine
//
/**@name missileconfig.h - The missile config headerfile. */
//
// (c) Copyright 2012 by Joris Dauphin
//
// 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; only version 2 of the License.
//
// 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.
//
#ifndef MISSILE_CONFIG_H
#define MISSILE_CONFIG_H
//@{
#include <string>
class MissileType;
/**
** Missile type definition (used in config tables)
**
** @todo Move this to missile.h?
*/
class MissileConfig {
public:
MissileConfig() : Missile(NULL) {}
bool MapMissile();
public:
std::string Name; /// Config missile name
MissileType *Missile; /// Identifier to use to run time
};
//@}
#endif // MISSILE_CONFIG_H

View file

@ -534,6 +534,7 @@
#include "icons.h"
#endif
#include "missileconfig.h"
#include "vec2i.h"
/*----------------------------------------------------------------------------
@ -559,19 +560,6 @@ enum GroupSelectionMode {
SELECT_ALL
};
/**
** Missile type definition (used in config tables)
**
** @todo Move this to missle.h?
*/
class MissileConfig {
public:
MissileConfig() : Missile(NULL) {}
std::string Name; /// Config missile name
MissileType *Missile; /// Identifier to use to run time
};
class ResourceInfo {
public:
ResourceInfo() : WaitAtResource(0), ResourceStep(0),

View file

@ -694,9 +694,9 @@ int PointToPointMissile(Missile &missile)
const PixelPos diff = (missile.destination - missile.source);
missile.position = missile.source + diff * missile.CurrentStep / missile.TotalStep;
if (missile.Type->SmokeMissile && missile.CurrentStep) {
if (missile.Type->Smoke.Missile && missile.CurrentStep) {
const PixelPos position = missile.position + missile.Type->size / 2;
MakeMissile(*missile.Type->SmokeMissile, position, position);
MakeMissile(*missile.Type->Smoke.Missile, position, position);
}
return 0;
}
@ -771,8 +771,8 @@ void Missile::MissileHit()
//
// The impact generates a new missile.
//
if (mtype.ImpactMissile) {
MakeMissile(*mtype.ImpactMissile, pixelPos, pixelPos);
if (mtype.Impact.Missile) {
MakeMissile(*mtype.Impact.Missile, pixelPos, pixelPos);
}
if (mtype.ImpactParticle) {
mtype.ImpactParticle->pushPreamble();
@ -1104,11 +1104,11 @@ void Missile::SaveMissile(CFile &file) const
*/
void SaveMissiles(CFile &file)
{
std::vector<Missile *>::const_iterator i;
file.printf("\n--- -----------------------------------------\n");
file.printf("--- MODULE: missiles\n\n");
std::vector<Missile *>::const_iterator i;
for (i = GlobalMissiles.begin(); i != GlobalMissiles.end(); ++i) {
(*i)->SaveMissile(file);
}
@ -1125,8 +1125,8 @@ void MissileType::Init()
// Resolve impact missiles and sounds.
this->FiredSound.MapSound();
this->ImpactSound.MapSound();
this->ImpactMissile = MissileTypeByIdent(this->ImpactName);
this->SmokeMissile = MissileTypeByIdent(this->SmokeName);
this->Impact.MapMissile();
this->Smoke.MapMissile();
}
/**
@ -1134,12 +1134,6 @@ void MissileType::Init()
*/
void InitMissileTypes()
{
#if 0
// Rehash.
for (std::vector<MissileType *>::iterator i = MissileTypes.begin(); i != MissileTypes.end(); ++i) {
MissileTypeMap[(*i)->Ident] = *i;
}
#endif
for (std::vector<MissileType *>::iterator i = MissileTypes.begin(); i != MissileTypes.end(); ++i) {
(*i)->Init();
}
@ -1153,13 +1147,10 @@ MissileType::MissileType(const std::string &ident) :
DrawLevel(0), SpriteFrames(0), NumDirections(0),
CorrectSphashDamage(false), Flip(false), CanHitOwner(false), FriendlyFire(false),
AlwaysFire(false), Class(), NumBounces(0), StartDelay(0), Sleep(0), Speed(0),
Range(0), SplashFactor(0), ImpactMissile(NULL),
SmokeMissile(NULL), ImpactParticle(NULL), G(NULL)
Range(0), SplashFactor(0), ImpactParticle(NULL), G(NULL)
{
size.x = 0;
size.y = 0;
FiredSound.Sound = NULL;
ImpactSound.Sound = NULL;
}
/**

View file

@ -73,9 +73,9 @@ static int ParabolicMissile(Missile &missile)
missile.position.x += z * zprojToX / 64;
missile.position.y += z * zprojToY / 64;
missile.MissileNewHeadingFromXY(missile.position - orig_pos);
if (missile.Type->SmokeMissile && missile.CurrentStep) {
if (missile.Type->Smoke.Missile && missile.CurrentStep) {
const PixelPos position = missile.position + missile.Type->size / 2;
MakeMissile(*missile.Type->SmokeMissile, position, position);
MakeMissile(*missile.Type->Smoke.Missile, position, position);
}
return 0;
}

View file

@ -65,9 +65,9 @@ static int TracerMissile(Missile &missile)
const PixelPos diff = (missile.destination - missile.source);
missile.position = missile.source + diff * missile.CurrentStep / missile.TotalStep;
if (missile.Type->SmokeMissile && missile.CurrentStep) {
if (missile.Type->Smoke.Missile && missile.CurrentStep) {
const PixelPos position = missile.position + missile.Type->size / 2;
MakeMissile(*missile.Type->SmokeMissile, position, position);
MakeMissile(*missile.Type->Smoke.Missile, position, position);
}
return 0;
}

View file

@ -0,0 +1,44 @@
// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
// \/ \/ \//_____/ \/
// ______________________ ______________________
// T H E W A R B E G I N S
// Stratagus - A free fantasy real time strategy game engine
//
/**@name missileconfig.cpp - The missile config. */
//
// (c) Copyright 2012 by Joris Dauphin
//
// 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; only version 2 of the License.
//
// 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.
//
//@{
#include "stratagus.h"
#include "missileconfig.h"
#include "missile.h"
bool MissileConfig::MapMissile()
{
this->Missile = MissileTypeByIdent(this->Name);
return this->Missile != NULL;
}
//@}

View file

@ -80,6 +80,93 @@ static const char *MissileClassNames[] = {
-- Functions
----------------------------------------------------------------------------*/
void MissileType::Load(lua_State *l)
{
this->NumDirections = 1;
this->Flip = true;
// Ensure we don't divide by zero.
this->SplashFactor = 100;
// Parse the arguments
std::string file;
for (lua_pushnil(l); lua_next(l, 2); lua_pop(l, 1)) {
const char *value = LuaToString(l, -2);
if (!strcmp(value, "File")) {
file = LuaToString(l, -1);
} else if (!strcmp(value, "Size")) {
if (!lua_istable(l, -1) || lua_objlen(l, -1) != 2) {
LuaError(l, "incorrect argument");
}
lua_rawgeti(l, -1, 1);
this->size.x = LuaToNumber(l, -1);
lua_pop(l, 1);
lua_rawgeti(l, -1, 2);
this->size.y = LuaToNumber(l, -1);
lua_pop(l, 1);
} else if (!strcmp(value, "Frames")) {
this->SpriteFrames = LuaToNumber(l, -1);
} else if (!strcmp(value, "Flip")) {
this->Flip = LuaToBoolean(l, -1);
} else if (!strcmp(value, "NumDirections")) {
this->NumDirections = LuaToNumber(l, -1);
} else if (!strcmp(value, "Transparency")) {
this->Transparency = LuaToNumber(l, -1);
} else if (!strcmp(value, "FiredSound")) {
this->FiredSound.Name = LuaToString(l, -1);
} else if (!strcmp(value, "ImpactSound")) {
this->ImpactSound.Name = LuaToString(l, -1);
} else if (!strcmp(value, "Class")) {
const char *className = LuaToString(l, -1);
unsigned int i = 0;
for (; MissileClassNames[i]; ++i) {
if (!strcmp(className, MissileClassNames[i])) {
this->Class = i;
break;
}
}
if (!MissileClassNames[i]) {
LuaError(l, "Unsupported class: %s" _C_ value);
}
} else if (!strcmp(value, "NumBounces")) {
this->NumBounces = LuaToNumber(l, -1);
} else if (!strcmp(value, "Delay")) {
this->StartDelay = LuaToNumber(l, -1);
} else if (!strcmp(value, "Sleep")) {
this->Sleep = LuaToNumber(l, -1);
} else if (!strcmp(value, "Speed")) {
this->Speed = LuaToNumber(l, -1);
} else if (!strcmp(value, "DrawLevel")) {
this->DrawLevel = LuaToNumber(l, -1);
} else if (!strcmp(value, "Range")) {
this->Range = LuaToNumber(l, -1);
} else if (!strcmp(value, "ImpactMissile")) {
this->Impact.Name = LuaToString(l, -1);
} else if (!strcmp(value, "SmokeMissile")) {
this->Smoke.Name = LuaToString(l, -1);
} else if (!strcmp(value, "ImpactParticle")) {
this->ImpactParticle = new LuaCallback(l, -1);
} else if (!strcmp(value, "CanHitOwner")) {
this->CanHitOwner = LuaToBoolean(l, -1);
} else if (!strcmp(value, "AlwaysFire")) {
this->AlwaysFire = LuaToBoolean(l, -1);
} else if (!strcmp(value, "FriendlyFire")) {
this->FriendlyFire = LuaToBoolean(l, -1);
} else if (!strcmp(value, "SplashFactor")) {
this->SplashFactor = LuaToNumber(l, -1);
} else if (!strcmp(value, "CorrectSphashDamage")) {
this->CorrectSphashDamage = LuaToBoolean(l, -1);
} else {
LuaError(l, "Unsupported tag: %s" _C_ value);
}
}
if (!file.empty()) {
this->G = CGraphic::New(file, this->Width(), this->Height());
}
}
/**
** Parse missile-type.
**
@ -101,90 +188,7 @@ static int CclDefineMissileType(lua_State *l)
} else {
mtype = NewMissileTypeSlot(str);
}
mtype->NumDirections = 1;
mtype->Flip = true;
// Ensure we don't divide by zero.
mtype->SplashFactor = 100;
// Parse the arguments
std::string file;
for (lua_pushnil(l); lua_next(l, 2); lua_pop(l, 1)) {
const char *value = LuaToString(l, -2);
if (!strcmp(value, "File")) {
file = LuaToString(l, -1);
} else if (!strcmp(value, "Size")) {
if (!lua_istable(l, -1) || lua_objlen(l, -1) != 2) {
LuaError(l, "incorrect argument");
}
lua_rawgeti(l, -1, 1);
mtype->size.x = LuaToNumber(l, -1);
lua_pop(l, 1);
lua_rawgeti(l, -1, 2);
mtype->size.y = LuaToNumber(l, -1);
lua_pop(l, 1);
} else if (!strcmp(value, "Frames")) {
mtype->SpriteFrames = LuaToNumber(l, -1);
} else if (!strcmp(value, "Flip")) {
mtype->Flip = LuaToBoolean(l, -1);
} else if (!strcmp(value, "NumDirections")) {
mtype->NumDirections = LuaToNumber(l, -1);
} else if (!strcmp(value, "Transparency")) {
mtype->Transparency = LuaToNumber(l, -1);
} else if (!strcmp(value, "FiredSound")) {
mtype->FiredSound.Name = LuaToString(l, -1);
} else if (!strcmp(value, "ImpactSound")) {
mtype->ImpactSound.Name = LuaToString(l, -1);
} else if (!strcmp(value, "Class")) {
const char *className = LuaToString(l, -1);
unsigned int i = 0;
for (; MissileClassNames[i]; ++i) {
if (!strcmp(className, MissileClassNames[i])) {
mtype->Class = i;
break;
}
}
if (!MissileClassNames[i]) {
LuaError(l, "Unsupported class: %s" _C_ value);
}
} else if (!strcmp(value, "NumBounces")) {
mtype->NumBounces = LuaToNumber(l, -1);
} else if (!strcmp(value, "Delay")) {
mtype->StartDelay = LuaToNumber(l, -1);
} else if (!strcmp(value, "Sleep")) {
mtype->Sleep = LuaToNumber(l, -1);
} else if (!strcmp(value, "Speed")) {
mtype->Speed = LuaToNumber(l, -1);
} else if (!strcmp(value, "DrawLevel")) {
mtype->DrawLevel = LuaToNumber(l, -1);
} else if (!strcmp(value, "Range")) {
mtype->Range = LuaToNumber(l, -1);
} else if (!strcmp(value, "ImpactMissile")) {
mtype->ImpactName = LuaToString(l, -1);
} else if (!strcmp(value, "SmokeMissile")) {
mtype->SmokeName = LuaToString(l, -1);
} else if (!strcmp(value, "ImpactParticle")) {
mtype->ImpactParticle = new LuaCallback(l, -1);
} else if (!strcmp(value, "CanHitOwner")) {
mtype->CanHitOwner = LuaToBoolean(l, -1);
} else if (!strcmp(value, "AlwaysFire")) {
mtype->AlwaysFire = LuaToBoolean(l, -1);
} else if (!strcmp(value, "FriendlyFire")) {
mtype->FriendlyFire = LuaToBoolean(l, -1);
} else if (!strcmp(value, "SplashFactor")) {
mtype->SplashFactor = LuaToNumber(l, -1);
} else if (!strcmp(value, "CorrectSphashDamage")) {
mtype->CorrectSphashDamage = LuaToBoolean(l, -1);
} else {
LuaError(l, "Unsupported tag: %s" _C_ value);
}
}
if (!file.empty()) {
mtype->G = CGraphic::New(file, mtype->Width(), mtype->Height());
}
mtype->Load(l);
return 0;
}

View file

@ -619,15 +619,12 @@ void LoadUnitTypes()
// Lookup icons.
type.Icon.Load();
// Lookup missiles.
type.Missile.Missile = MissileTypeByIdent(type.Missile.Name);
if (!type.Explosion.Name.empty()) {
type.Explosion.Missile = MissileTypeByIdent(type.Explosion.Name);
}
type.Missile.MapMissile();
type.Explosion.MapMissile();
// Lookup impacts
for (int i = 0; i < ANIMATIONS_DEATHTYPES + 2; ++i) {
if (!type.Impact[i].Name.empty()) {
type.Impact[i].Missile = MissileTypeByIdent(type.Impact[i].Name);
}
type.Impact[i].MapMissile();
}
// Lookup corpse.
if (!type.CorpseName.empty()) {