1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-07-21 05:14:10 +00:00

Started implementing ALL in-game objects as Monster scripts.

git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@72 ea6a568a-9f4f-0410-981a-c910a81bb256
This commit is contained in:
nkorslund 2008-11-17 20:11:55 +00:00
parent c2d992c8f0
commit 76295fbd45
35 changed files with 466 additions and 62 deletions

View file

@ -25,6 +25,7 @@ module esm.defs;
public import std.string; public import std.string;
public import monster.util.string; public import monster.util.string;
import monster.monster;
/* /*
* Types and definitions related to parsing esm and esp files * Types and definitions related to parsing esm and esp files
@ -135,3 +136,50 @@ align(1) struct ENAMstruct
static assert(ENAMstruct.sizeof==24); static assert(ENAMstruct.sizeof==24);
} }
// Common stuff for all the load* structs
template LoadTT(T)
{
LoadState state;
char[] name, id;
MonsterObject *proto;
static MonsterClass mc;
void makeProto(char[] clsName = null)
{
// Use the template type name as the Monster class name if none
// is specified.
if(clsName == "")
{
clsName = typeid(T).toString;
// Remove the module name
int i = clsName.rfind('.');
if(i != -1)
clsName = clsName[i+1..$];
}
// Set up a prototype object
if(mc is null)
mc = MonsterClass.find(clsName);
proto = mc.createObject();
proto.setString8("id", id);
proto.setString8("name", name);
static if(is(typeof(data.weight) == float))
{
proto.setFloat("weight", data.weight);
proto.setInt("value", data.value);
}
static if(is(typeof(data.enchant)==int))
proto.setInt("enchant", data.enchant);
static if(is(typeof(data.health)==int))
proto.setInt("health", data.health);
}
}
template LoadT() { mixin LoadTT!(typeof(*this)); }

View file

@ -1,8 +1,8 @@
module esm.imports; module esm.imports;
/* This is a file that imports common modules used by the load*.d /* This is a file that imports common modules used by the load*.d
record loaders. It is really a cut down version of the start of record loaders. It is really a cut down version of what used to be
records.d. the start of records.d.
This file MUST NOT import records.d - directly or indirectly - This file MUST NOT import records.d - directly or indirectly -
because that will trigger a nice three page long list of template because that will trigger a nice three page long list of template
@ -41,4 +41,7 @@ import esm.loadscpt;
import esm.loadsoun; import esm.loadsoun;
import esm.loadspel; import esm.loadspel;
import esm.loadench; import esm.loadench;
import monster.monster;
} }

View file

@ -36,10 +36,8 @@ import esm.imports;
struct Activator struct Activator
{ {
char[] id; mixin LoadT!();
LoadState state;
char[] name;
Script *script; Script *script;
MeshIndex model; MeshIndex model;
@ -48,6 +46,8 @@ struct Activator
model = getMesh(); model = getMesh();
name = getHNString("FNAM"); name = getHNString("FNAM");
script = getHNOPtr!(Script)("SCRI", scripts); script = getHNOPtr!(Script)("SCRI", scripts);
makeProto();
}} }}
} }
ListID!(Activator) activators; ListID!(Activator) activators;

View file

@ -30,9 +30,6 @@ import esm.imports;
struct Potion struct Potion
{ {
char[] id;
LoadState state;
align(1) struct ALDTstruct align(1) struct ALDTstruct
{ {
float weight; float weight;
@ -43,7 +40,7 @@ struct Potion
ALDTstruct data; ALDTstruct data;
char[] name; mixin LoadT!();
MeshIndex model; MeshIndex model;
IconIndex icon; IconIndex icon;
@ -69,6 +66,8 @@ struct Potion
readHExact(&effects.array[$-1], effects.array[$-1].sizeof); readHExact(&effects.array[$-1], effects.array[$-1].sizeof);
} }
makeProto();
proto.setInt("autoCalc", data.autoCalc);
}} }}
} }
ListID!(Potion) potions; ListID!(Potion) potions;

View file

@ -30,9 +30,6 @@ import esm.imports;
struct Apparatus struct Apparatus
{ {
char[] id, name;
LoadState state;
enum AppaType : int enum AppaType : int
{ {
MortarPestle = 0, MortarPestle = 0,
@ -50,6 +47,8 @@ struct Apparatus
static assert(AADTstruct.sizeof == 16); static assert(AADTstruct.sizeof == 16);
} }
mixin LoadT!();
AADTstruct data; AADTstruct data;
MeshIndex model; MeshIndex model;
IconIndex icon; IconIndex icon;
@ -62,6 +61,11 @@ struct Apparatus
readHNExact(&data, data.sizeof, "AADT"); readHNExact(&data, data.sizeof, "AADT");
script = getHNOPtr!(Script)("SCRI", scripts); script = getHNOPtr!(Script)("SCRI", scripts);
icon = getIcon(); icon = getIcon();
makeProto();
proto.setFloat("quality", data.quality);
proto.setInt("type", data.type);
}} }}
} }
ListID!(Apparatus) appas; ListID!(Apparatus) appas;

View file

@ -116,8 +116,7 @@ struct Armor
AODTstruct data; AODTstruct data;
char[] name, id; mixin LoadT!();
LoadState state;
PartReferenceList parts; PartReferenceList parts;
@ -138,6 +137,11 @@ struct Armor
parts.load(); parts.load();
enchant = getHNOPtr!(Enchantment)("ENAM", enchants); enchant = getHNOPtr!(Enchantment)("ENAM", enchants);
makeProto();
proto.setInt("type", data.type);
proto.setInt("armor", data.armor);
}} }}
} }
ListID!(Armor) armors; ListID!(Armor) armors;

View file

@ -74,8 +74,8 @@ struct BodyPart
BYDTstruct data; BYDTstruct data;
char[] name, id; mixin LoadT;
LoadState state;
MeshIndex model; MeshIndex model;
void load() void load()
@ -83,6 +83,9 @@ struct BodyPart
model = getMesh(); model = getMesh();
name = getHNString("FNAM"); name = getHNString("FNAM");
readHNExact(&data, data.sizeof, "BYDT"); readHNExact(&data, data.sizeof, "BYDT");
// don't need to run makeProto here yet, no BodyPart monster
// class.
}} }}
} }

View file

@ -44,7 +44,9 @@ struct Book
IconIndex icon; IconIndex icon;
Script *script; Script *script;
Enchantment *enchant; Enchantment *enchant;
char[] name, text, id;
mixin LoadT;
char[] text;
LoadState state; LoadState state;
@ -57,6 +59,11 @@ struct Book
icon = getIcon(); icon = getIcon();
text = getHNOString("TEXT"); text = getHNOString("TEXT");
enchant = getHNOPtr!(Enchantment)("ENAM", enchants); enchant = getHNOPtr!(Enchantment)("ENAM", enchants);
makeProto();
proto.setInt("skillID", data.skillID);
proto.setBool("isScroll", data.isScroll != 0);
}} }}
} }
ListID!(Book) books; ListID!(Book) books;

View file

@ -30,9 +30,9 @@ import esm.imports;
struct BirthSign struct BirthSign
{ {
LoadState state; char[] description;
char[] id, name, description; mixin LoadT;
TextureIndex texture; TextureIndex texture;
@ -48,6 +48,8 @@ struct BirthSign
description = getHNOString("DESC"); description = getHNOString("DESC");
powers.load(); powers.load();
// No monster class equivalent yet
}} }}
} }
ListID!(BirthSign) birthSigns; ListID!(BirthSign) birthSigns;

View file

@ -72,8 +72,9 @@ struct Class
static assert(CLDTstruct.sizeof == 60); static assert(CLDTstruct.sizeof == 60);
} }
LoadState state; mixin LoadT;
char[] id, name, description;
char[] description;
CLDTstruct data; CLDTstruct data;
void load() void load()
@ -85,6 +86,8 @@ struct Class
esFile.fail("Unknown bool value"); esFile.fail("Unknown bool value");
description = esFile.getHNOString("DESC"); description = esFile.getHNOString("DESC");
// no makeProto yet
} }
} }
ListID!(Class) classes; ListID!(Class) classes;

View file

@ -50,15 +50,15 @@ struct Clothing
Type type; Type type;
float weight; float weight;
short value; short value;
short enchantPoints; short enchant;
static assert(CTDTstruct.sizeof == 12); static assert(CTDTstruct.sizeof == 12);
} }
CTDTstruct data; CTDTstruct data;
LoadState state; mixin LoadT;
char[] id, name;
PartReferenceList parts; PartReferenceList parts;
MeshIndex model; MeshIndex model;
@ -78,6 +78,9 @@ struct Clothing
parts.load(); parts.load();
enchant = getHNOPtr!(Enchantment)("ENAM", enchants); enchant = getHNOPtr!(Enchantment)("ENAM", enchants);
makeProto();
proto.setInt("type", data.type);
}} }}
} }
ListID!(Clothing) clothes; ListID!(Clothing) clothes;

View file

@ -69,9 +69,6 @@ struct Container
Unknown = 8 Unknown = 8
} }
char[] id, name;
LoadState state;
MeshIndex model; MeshIndex model;
Script *script; Script *script;
@ -79,6 +76,8 @@ struct Container
Flags flags; Flags flags;
InventoryList inventory; InventoryList inventory;
mixin LoadT!();
void load() void load()
{with(esFile){ {with(esFile){
model = getMesh(); model = getMesh();
@ -100,6 +99,9 @@ struct Container
script = getHNOPtr!(Script)("SCRI", scripts); script = getHNOPtr!(Script)("SCRI", scripts);
inventory.load(); inventory.load();
makeProto();
proto.setFloat("weight", weight);
}} }}
} }

View file

@ -30,13 +30,12 @@ import esm.imports;
struct Door struct Door
{ {
LoadState state;
char[] id, name;
MeshIndex model; MeshIndex model;
Script *script; Script *script;
Sound* openSound, closeSound; Sound* openSound, closeSound;
mixin LoadT!();
void load() void load()
{with(esFile){ {with(esFile){
model = getMesh(); model = getMesh();
@ -44,6 +43,8 @@ struct Door
script = getHNOPtr!(Script)("SCRI", scripts); script = getHNOPtr!(Script)("SCRI", scripts);
openSound = getHNOPtr!(Sound)("SNAM", sounds); openSound = getHNOPtr!(Sound)("SNAM", sounds);
closeSound = getHNOPtr!(Sound)("ANAM", sounds); closeSound = getHNOPtr!(Sound)("ANAM", sounds);
makeProto();
}} }}
} }
ListID!(Door) doors; // Break on through ListID!(Door) doors; // Break on through

View file

@ -29,9 +29,6 @@ import esm.imports;
struct Light struct Light
{ {
char[] id;
LoadState state;
enum Flags : uint enum Flags : uint
{ {
Dynamic = 0x001, Dynamic = 0x001,
@ -59,14 +56,14 @@ struct Light
LHDTstruct data; LHDTstruct data;
char[] name; mixin LoadT!();
MeshIndex model;
IconIndex icon;
Sound* sound; Sound* sound;
Script* script; Script* script;
MeshIndex model;
IconIndex icon;
void load() void load()
{with(esFile){ {with(esFile){
model = getMesh(); model = getMesh();
@ -77,6 +74,14 @@ struct Light
script = getHNOPtr!(Script)("SCRI", scripts); script = getHNOPtr!(Script)("SCRI", scripts);
sound = getHNOPtr!(Sound)("SNAM", sounds); sound = getHNOPtr!(Sound)("SNAM", sounds);
// Stash the data in the Monster object prototype
makeProto();
proto.setUint("flags", data.flags);
proto.setFloat("lifetime", data.time);
proto.setInt("radius", data.radius);
}} }}
} }
ListID!(Light) lights; ListID!(Light) lights;

View file

@ -71,8 +71,7 @@ struct Weapon
WPDTstruct data; WPDTstruct data;
LoadState state; mixin LoadT!();
char[] name, id;
MeshIndex model; MeshIndex model;
IconIndex icon; IconIndex icon;
@ -87,6 +86,11 @@ struct Weapon
script = getHNOPtr!(Script)("SCRI", scripts); script = getHNOPtr!(Script)("SCRI", scripts);
icon = getOIcon(); icon = getOIcon();
enchant = getHNOPtr!(Enchantment)("ENAM", enchants); enchant = getHNOPtr!(Enchantment)("ENAM", enchants);
makeProto();
proto.setFloat("speed", data.speed);
proto.setFloat("reach", data.reach);
}} }}
} }
ListID!(Weapon) weapons; ListID!(Weapon) weapons;

View file

@ -393,6 +393,8 @@ struct Assembler
addi(i); addi(i);
} }
void cloneObj() { cmd(BC.Clone); }
// Copy the topmost int on the stack // Copy the topmost int on the stack
void dup() { cmd(BC.Dup); } void dup() { cmd(BC.Dup); }

View file

@ -69,6 +69,12 @@ enum BC
// giving the class index (in the file lookup // giving the class index (in the file lookup
// table) // table)
Clone, // Clones an object - create a new object of
// the same class, then copy variable values
// and state from the old object to the
// new. Replaces the object index on the stack
// with the new index.
Jump, // Jump to given position (int) Jump, // Jump to given position (int)
JumpZ, // Pop a value, if it is zero then jump to JumpZ, // Pop a value, if it is zero then jump to

View file

@ -1004,6 +1004,7 @@ class VariableExpr : MemberExpression
isNext(toks, TT.Identifier) || isNext(toks, TT.Identifier) ||
isNext(toks, TT.Singleton) || isNext(toks, TT.Singleton) ||
isNext(toks, TT.State) || isNext(toks, TT.State) ||
isNext(toks, TT.Clone) ||
isNext(toks, TT.Const); isNext(toks, TT.Const);
} }
@ -1146,6 +1147,9 @@ class VariableExpr : MemberExpression
if(name.type == TT.Const) if(name.type == TT.Const)
fail("Cannot use const as a variable", name.loc); fail("Cannot use const as a variable", name.loc);
if(name.type == TT.Clone)
fail("Cannot use clone as a variable", name.loc);
// These are special cases that work both as properties // These are special cases that work both as properties
// (object.state) and as non-member variables (state=...) inside // (object.state) and as non-member variables (state=...) inside
// class functions / state code. Since we already handle them // class functions / state code. Since we already handle them

View file

@ -159,6 +159,8 @@ class ClassProperties : SimplePropertyScope
{ {
super("ClassProperties"); super("ClassProperties");
insert("clone", "owner", { tasm.cloneObj(); });
// For testing purposes. Makes 'singleton' an alias for the // For testing purposes. Makes 'singleton' an alias for the
// first variable in the data segment. This might actually not // first variable in the data segment. This might actually not
// be far from how the end result would work - the singleton // be far from how the end result would work - the singleton

View file

@ -537,6 +537,41 @@ final class MonsterClass
return top; return top;
} }
// Create a new object based on an existing object
MonsterObject* createClone(MonsterObject *source)
{
requireCompile();
assert(source.tree.length == tree.length);
assert(source.thread.topObj == source,
"createClone can only clone the topmost object");
// Create a new thread
CodeThread *trd = threads.getNew();
// Loop through the objects in the source tree, and clone each
// of them
MonsterObject* otree[] = source.tree.dup;
foreach(i, ref obj; otree)
{
obj = obj.cls.getClone(obj);
obj.tree = otree[0..i+1];
obj.thread = trd;
}
// Pick out the top object
MonsterObject* top = otree[$-1];
assert(top !is null);
// Initialize the thread
trd.initialize(top);
// Set the same state
trd.setState(source.thread.getState(), null);
return top;
}
// Free an object and its thread // Free an object and its thread
void deleteObject(MonsterObject *obj) void deleteObject(MonsterObject *obj)
{ {
@ -757,6 +792,46 @@ final class MonsterClass
// Point to the static data segment // Point to the static data segment
obj.sdata = sdata; obj.sdata = sdata;
obj.extra = null;
// Call the custom native constructor
if(constType != FuncType.Native)
{
fstack.pushNConst(obj);
if(constType == FuncType.NativeDDel)
dg_const();
else if(constType == FuncType.NativeDFunc)
fn_const();
else if(constType == FuncType.NativeCFunc)
c_const();
fstack.pop();
}
return obj;
}
// Clone an existing object
MonsterObject *getClone(MonsterObject *source)
{
assert(source !is null);
assert(source.cls is this);
assert(source.data.length == data.length);
assert(source.sdata.ptr is sdata.ptr);
requireCompile();
MonsterObject *obj = objects.getNew();
// Set the class
obj.cls = this;
// TODO: Fix memory management here too.
// Copy the data segment from the source
obj.data = source.data.dup;
// Point to the static data segment
obj.sdata = sdata;
obj.extra = null;
// Call the custom native constructor // Call the custom native constructor
if(constType != FuncType.Native) if(constType != FuncType.Native)

View file

@ -69,6 +69,7 @@ struct MonsterObject
// the MonsterClass. // the MonsterClass.
MonsterObject* tree[]; MonsterObject* tree[];
/******************************************************* /*******************************************************
* * * *
* Functions for object handling * * Functions for object handling *
@ -98,6 +99,16 @@ struct MonsterObject
cls.deleteObject(this); cls.deleteObject(this);
} }
// Create a clone of this object. Note that this will always clone
// and return the top object (thread.topObj), regardless of which
// object in the list it is called on. In other words, the class
// mo.cls is not always the same as mo.clone().cls.
MonsterObject *clone()
{
auto t = thread.topObj;
return t.cls.createClone(t);
}
/******************************************************* /*******************************************************
* * * *
* Casting / polymorphism functions * * Casting / polymorphism functions *

View file

@ -480,6 +480,10 @@ struct CodeThread
.createObject()); .createObject());
break; break;
case BC.Clone:
stack.pushObject(stack.popObject().clone());
break;
case BC.Jump: case BC.Jump:
code.jump(code.getInt); code.jump(code.getInt);
break; break;

View file

@ -0,0 +1,25 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (activator.mn) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
class Activator : GameObject;

View file

@ -0,0 +1,28 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (apparatus.mn) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
// Covers all alchemy apparatus - mortars, retorts, etc
class Apparatus : InventoryItem;
float quality;
int type;

View file

@ -0,0 +1,28 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (armor.mn) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
// Covers all weapons and projectile weapons you can carry (like
// arrows and throwable items.)
class Armor : Repairable;
int type, armor;

View file

@ -0,0 +1,28 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (book.mn) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
class Book : EnchantItem;
bool isScroll;
int skillID; // Skill that is enhanced by reading this book, if any

View file

@ -0,0 +1,27 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (clothing.mn) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
// All items that can be repaired (weapons and armor)
class Clothing : EnchantItem;
int type;

View file

@ -0,0 +1,26 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (container.mn) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
class Container : LockedObject;
float weight; // Not sure, might be max total weight allowed?

View file

@ -4,7 +4,7 @@
Email: < korslund@gmail.com > Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/ WWW: http://openmw.snaptoad.com/
This file (equipitem.mn) is part of the OpenMW package. This file (enchantitem.mn) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
@ -21,7 +21,7 @@
*/ */
// Anything that can be equiped, like clothes, armor and weapons. // Items that can be enchanted
class EquipItem : InventoryItem; class EnchantItem : InventoryItem;
int enchant; int enchant;

View file

@ -40,6 +40,8 @@ float r1, r2, r3;
float scale; float scale;
char[] name, id;
// Various variables that are currently unused. Most of the strings // Various variables that are currently unused. Most of the strings
// will be replaced by object references at some point. // will be replaced by object references at some point.

View file

@ -26,5 +26,6 @@ class Light : InventoryItem;
// Time left in seconds (for carried lights) // Time left in seconds (for carried lights)
float lifetime; float lifetime;
// Is this a carryable light? int radius;
bool carry; uint flags;

View file

@ -0,0 +1,26 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (potion.mn) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
class Potion : InventoryItem;
int autoCalc;

View file

@ -0,0 +1,27 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (repairable.mn) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
// All items that can be repaired (weapons and armor)
class Repairable : EnchantItem;
int health;

View file

@ -21,11 +21,11 @@
*/ */
// Weapons (This is just an example, it's not used for anything yet.) // Covers all weapons and carry-able projectiles.
class Weapon : EquipItem; class Weapon : Repairable;
float speed, reach; float speed, reach;
// Not set yet.
bool magical, silver; bool magical, silver;
bool isTwohanded; bool twoHanded;

View file

@ -39,7 +39,8 @@ import sound.audio;
import scene.player; import scene.player;
// Generic version of a "live" object // Generic version of a "live" object. Do we even need this at all?
// No, I don't think so.
struct GenLive(T) struct GenLive(T)
{ {
// Instance of class GameObject or a derived class (depending on // Instance of class GameObject or a derived class (depending on
@ -259,16 +260,13 @@ class CellData
private: private:
static static
MonsterClass gameObjC, doorC, lightC, lockedC; MonsterClass gameObjC;
void setup() void setup()
{ {
if(gameObjC !is null) return; if(gameObjC !is null) return;
gameObjC = new MonsterClass("GameObject"); gameObjC = MonsterClass.find("GameObject");
doorC = new MonsterClass("Door");
lightC = new MonsterClass("Light");
lockedC = new MonsterClass("LockedObject");
} }
void loadReferences() void loadReferences()
@ -329,24 +327,20 @@ class CellData
{ {
LiveLight ls; LiveLight ls;
ls.m = m; ls.m = m;
ls.obj = lightC.createObject; ls.obj = m.proto.clone();
mo = ls.obj; mo = ls.obj;
mo.setFloat("lifetime", m.data.time);
bool carry = (m.data.flags&Light.Flags.Carry) != 0; bool carry = (m.data.flags&Light.Flags.Carry) != 0;
mo.setBool("carry", carry);
if(carry) if(carry)
lights.insert(ls); lights.insert(ls);
else else
statLights.insert(ls); statLights.insert(ls);
} }
else if(Container *c = it.getContainer()) else if(Container *c = it.getContainer())
{ {
LiveContainer ls; LiveContainer ls;
ls.m = c; ls.m = c;
ls.obj = lockedC.createObject; ls.obj = c.proto.clone();
mo = ls.obj; mo = ls.obj;
containers.insert(ls); containers.insert(ls);
container = true; container = true;
@ -356,7 +350,7 @@ class CellData
{ {
LiveDoor ls; LiveDoor ls;
ls.m = d; ls.m = d;
ls.obj = doorC.createObject; ls.obj = d.proto.clone();
mo = ls.obj; mo = ls.obj;
doors.insert(ls); doors.insert(ls);
door = true; door = true;
@ -416,7 +410,7 @@ class CellData
{ {
LiveWeapon ls; LiveWeapon ls;
ls.m = m; ls.m = m;
ls.obj = gameObjC.createObject; ls.obj = m.proto.clone();
mo = ls.obj; mo = ls.obj;
weapons.insert(ls); weapons.insert(ls);
} }