diff --git a/esm/defs.d b/esm/defs.d index 9c4327d1a..acb426c9c 100644 --- a/esm/defs.d +++ b/esm/defs.d @@ -176,9 +176,6 @@ template LoadTT(T) static if(is(typeof(data.enchant)==int)) proto.setInt("enchant", data.enchant); - - static if(is(typeof(data.health)==int)) - proto.setInt("health", data.health); } } diff --git a/esm/loadarmo.d b/esm/loadarmo.d index fe1d74d63..670b539d2 100644 --- a/esm/loadarmo.d +++ b/esm/loadarmo.d @@ -142,6 +142,8 @@ struct Armor proto.setInt("type", data.type); proto.setInt("armor", data.armor); + + proto.setInt("health", data.health); }} } ListID!(Armor) armors; diff --git a/esm/loadcrea.d b/esm/loadcrea.d index fcfe4b76f..1e9b35951 100644 --- a/esm/loadcrea.d +++ b/esm/loadcrea.d @@ -78,8 +78,7 @@ struct Creature Flags flags; - LoadState state; - char[] id, name; + mixin LoadT; MeshIndex model; @@ -121,6 +120,36 @@ struct Creature //* skipRecord(); //*/ + + makeProto(); + + proto.setInt("level", data.level); + proto.setInt("gold", data.gold); + + proto.setInt("baseStrength", data.strength); + proto.setInt("baseIntelligence", data.intelligence); + proto.setInt("baseWillpower", data.willpower); + proto.setInt("baseAgility", data.agility); + proto.setInt("baseSpeed", data.speed); + proto.setInt("baseEndurance", data.endurance); + proto.setInt("basePersonality", data.personality); + proto.setInt("baseLuck", data.luck); + + proto.setInt("baseMaxHealth", data.health); + proto.setInt("baseMaxMana", data.mana); + proto.setInt("baseMaxFatigue", data.fatigue); + + proto.setInt("combat", data.combat); + proto.setInt("magic", data.magic); + proto.setInt("stealth", data.stealth); + proto.setInt("soul", data.soul); + + proto.setInt("attackMin1", data.attack[0]); + proto.setInt("attackMax1", data.attack[1]); + proto.setInt("attackMin2", data.attack[2]); + proto.setInt("attackMax2", data.attack[3]); + proto.setInt("attackMin3", data.attack[4]); + proto.setInt("attackMax3", data.attack[5]); }} } diff --git a/esm/loadgmst.d b/esm/loadgmst.d index c3455463c..e48f06fc4 100644 --- a/esm/loadgmst.d +++ b/esm/loadgmst.d @@ -28,6 +28,11 @@ import esm.imports; * Game setting */ +// TODO: It's likely that we don't need this struct any longer, given +// that game settings are now stored in Monster code. We will still +// use the loading code and the dirty value cleaning code of course, +// but there's no longer any need to store it in a separate lookup +// list, since Monster variables can be looked up just as fast. struct GameSetting { LoadState state; @@ -79,10 +84,12 @@ struct GameSetting // really shouldn't have to. In this file we choose instead to // reject all the corrupt values at load time. - // Checks if the current game setting is one of the "dirty" ones as - // described above. TODO: I have not checked this against other - // sources yet, do that later. Currently recognizes 22 values for - // tribunal and 50 for bloodmoon. + // These functions checks if the current game setting is one of the + // "dirty" ones as described above. TODO: I have not checked this + // against other sources yet, do that later. Currently recognizes 22 + // values for tribunal and 50 for bloodmoon. Legitimate GMSTs in + // mods (setting values other than the default "dirty" ones) are not + // affected and will work correctly. // Checks for dirty tribunal values. These will be ignored if found // in any file except when they are found in "Tribunal.esm". diff --git a/esm/loadingr.d b/esm/loadingr.d index 52e11defc..a76bddff3 100644 --- a/esm/loadingr.d +++ b/esm/loadingr.d @@ -43,9 +43,8 @@ struct Ingredient IRDTstruct data; - LoadState state; + mixin LoadT; - char[] id, name; MeshIndex model; IconIndex icon; Script *script; @@ -58,6 +57,8 @@ struct Ingredient script = getHNOPtr!(Script)("SCRI", scripts); icon = getOIcon(); + + makeProto(); }} } ListID!(Ingredient) ingreds; diff --git a/esm/loadlevlist.d b/esm/loadlevlist.d index a51a4725f..129343e66 100644 --- a/esm/loadlevlist.d +++ b/esm/loadlevlist.d @@ -27,40 +27,16 @@ import esm.loadcrea; import util.random; -/* Outdated comments: - * +/* * Leveled lists. Since these have identical layout, I only bothered * to implement it once. * * We should later implement the ability to merge leveled lists from * several files. * - * The Item indices can point to several different lists (potions, - * weapons, armor, etc.) and this is a problem also for npcs, - * containers and cells. Deal with it in a uniform way. In fact, we - * won't have to make any difference between the creature and item - * lists. - * - * EDIT 2007.08.18: Looks like DMD is exploding from template forward - * references again. It works for very small cases, so I assume it - * should be legal in our case also, and that this is a BUG. I have - * cut it down and am going to report it. Moving ListItem out of the - * struct helped, but I get the same problem in other places, where it - * is not possible to fix. I should probably cut down the other case - * as well... - * - * EDIT 2007.09.09: In Monster we managed to cut down template - * forwarding with LinkedList by making the list use Value pointers - * instead of Node pointers. If I do the same for HashTable and move - * the value to the top, I JUST might be able to work around this DMD - * bug. - * - * UPDATE: Well, it works now, but only if you compile with DMD using - * the all-files-on-one-line approach. It will not work with DSSS - * until these bugs are gone. */ -// Moved here for template bug reasons... +// Moved here for template / DMD bug reasons... struct _ListItem { Item item; // Definded in records.d diff --git a/esm/loadlocks.d b/esm/loadlocks.d index bae3e5291..cfac77286 100644 --- a/esm/loadlocks.d +++ b/esm/loadlocks.d @@ -45,9 +45,8 @@ struct Tool Data data; - LoadState state; + mixin LoadT; - char[] name, id; MeshIndex model; IconIndex icon; Script* script; @@ -57,13 +56,22 @@ struct Tool model = getMesh(); name = getHNString("FNAM"); - if(isNextSub("LKDT") || isNextSub("PBDT")) - readHExact(&data, data.sizeof); - else - { - getSubNameIs("RIDT"); - readHExact(&data, data.sizeof); + char[] type; + bool isRep = false; + if(isNextSub("LKDT")) type = "Lockpick"; + else if(isNextSub("PBDT")) type = "Probe"; + else + { + getSubNameIs("RIDT"); + type = "RepairItem"; + isRep = true; + } + + readHExact(&data, data.sizeof); + + if(isRep) + { // Swap t.data.quality and t.data.uses (sigh) float tmp = *(cast(float*)&data.uses); data.uses = *(cast(int*)&data.quality); @@ -72,6 +80,11 @@ struct Tool script = getHNOPtr!(Script)("SCRI", scripts); icon = getOIcon(); + + + makeProto(type); + proto.setFloat("quality", data.quality); + proto.setInt("uses", data.uses); }} } ListID!(Tool) lockpicks, probes, repairs; diff --git a/esm/loadmisc.d b/esm/loadmisc.d index 576b5ff30..602c19c80 100644 --- a/esm/loadmisc.d +++ b/esm/loadmisc.d @@ -43,9 +43,7 @@ struct Misc } MCDTstruct data; - char[] id, name; - - LoadState state; + mixin LoadT; MeshIndex model; IconIndex icon; @@ -57,7 +55,10 @@ struct Misc name = getHNOString("FNAM"); readHNExact(&data, data.sizeof, "MCDT"); script = getHNOPtr!(Script)("SCRI", scripts); - icon = getOIcon();; + icon = getOIcon(); + + makeProto(); + proto.setInt("isKey", data.isKey); }} } ListID!(Misc) miscItems; diff --git a/esm/loadnpc.d b/esm/loadnpc.d index 535af9195..3965543fb 100644 --- a/esm/loadnpc.d +++ b/esm/loadnpc.d @@ -79,7 +79,6 @@ struct NPC byte strength, intelligence, willpower, agility, speed, endurance, personality, luck; byte skills[27]; - //byte reputation; // Total confusion! short health, mana, fatigue; byte disposition; byte reputation; // Was "factionID", but that makes no sense. @@ -121,9 +120,7 @@ struct NPC AIDTstruct AI; bool hasAI; - LoadState state; - - char[] name, id; + mixin LoadT; MeshIndex model; Race* race; @@ -166,6 +163,41 @@ struct NPC else hasAI = false; skipRecord(); + + makeProto("Person"); + + // Clean this up a little later, eg. no point in storing the + // structs outside the function any longer. Same goes for most of + // the load*.d structures. + if(npdt52.gold == -10) + { + proto.setInt("level", npdt12.level); + proto.setInt("gold", npdt12.gold); + + proto.setInt("disposition", npdt12.disposition); + proto.setInt("reputation", npdt12.reputation); + proto.setInt("rank", npdt12.rank); + + // TODO: Autocalculate the rest? + } + else + { + proto.setInt("level", npdt52.level); + proto.setInt("gold", npdt52.gold); + + proto.setInt("baseStrength", npdt52.strength); + proto.setInt("baseIntelligence", npdt52.intelligence); + proto.setInt("baseWillpower", npdt52.willpower); + proto.setInt("baseAgility", npdt52.agility); + proto.setInt("baseSpeed", npdt52.speed); + proto.setInt("baseEndurance", npdt52.endurance); + proto.setInt("basePersonality", npdt52.personality); + proto.setInt("baseLuck", npdt52.luck); + + proto.setInt("baseMaxHealth", npdt52.health); + proto.setInt("baseMaxMana", npdt52.mana); + proto.setInt("baseMaxFatigue", npdt52.fatigue); + } }} } ListID!(NPC) npcs; diff --git a/esm/loadskil.d b/esm/loadskil.d index 0d093ca4a..fe3b999cf 100644 --- a/esm/loadskil.d +++ b/esm/loadskil.d @@ -49,7 +49,7 @@ struct Skill SKDTstruct data; - char[] description; // Description + char[] description; void load() { diff --git a/esm/loadstat.d b/esm/loadstat.d index 42556cb9b..5b6092910 100644 --- a/esm/loadstat.d +++ b/esm/loadstat.d @@ -39,14 +39,15 @@ import esm.imports; struct Static { - char[] id; - LoadState state; + mixin LoadT; MeshIndex model; void load() { model = esFile.getMesh(); + + makeProto(); } } diff --git a/esm/loadweap.d b/esm/loadweap.d index 46d46f473..eb56effdf 100644 --- a/esm/loadweap.d +++ b/esm/loadweap.d @@ -91,6 +91,8 @@ struct Weapon proto.setFloat("speed", data.speed); proto.setFloat("reach", data.reach); + + proto.setInt("health", data.health); }} } ListID!(Weapon) weapons; diff --git a/monster/compiler/scopes.d b/monster/compiler/scopes.d index 1fc0e4cfe..4d500778f 100644 --- a/monster/compiler/scopes.d +++ b/monster/compiler/scopes.d @@ -480,7 +480,7 @@ final class PackageScope : Scope // Find a class given its name. The class must be parsed or a file // must exist which can be parsed, otherwise the function - // fails. createScope is also called on the class before it'xs + // fails. createScope is also called on the class before it is // returned. MonsterClass findClass(Token t) { return findClass(t.str, t.loc); } MonsterClass findClass(char[] name, Floc loc = Floc.init) diff --git a/monster/vm/mclass.d b/monster/vm/mclass.d index 277b882da..10eaec58e 100644 --- a/monster/vm/mclass.d +++ b/monster/vm/mclass.d @@ -507,13 +507,23 @@ final class MonsterClass assert(otree.length > 0); + // Create one buffer big enough for all the data segments here, + // and let getObject slice it. TODO: This can be optimized even + // further, by using a freelist or other preallocation, and by + // precalculating the result and the slicing. Not important at + // the moment. + int[] totalData = new int[totalDataSize]; + // Fill the list with objects, and assign the thread. foreach(i, ref obj; otree) { - obj = tree[i].getObject(); + obj = tree[i].getObject(totalData); obj.thread = trd; } + // Make sure we used the entire buffer + assert(totalData.length == 0); + // Pick out the top object MonsterObject* top = otree[$-1]; @@ -549,16 +559,23 @@ final class MonsterClass // Create a new thread CodeThread *trd = threads.getNew(); + // Create one buffer big enough for all the data segments here, + // and let getClone slice it. + int[] totalData = new int[totalDataSize]; + // 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 = obj.cls.getClone(obj, totalData); obj.tree = otree[0..i+1]; obj.thread = trd; } + // Make sure we used the entire buffer + assert(totalData.length == 0); + // Pick out the top object MonsterObject* top = otree[$-1]; assert(top !is null); @@ -697,6 +714,12 @@ final class MonsterClass uint sdSize; // Number of ints reserved for the static data, that // have not yet been used. + // Size of the data segment + uint dataSize; + + // Total for this class + all base classes. + uint totalDataSize; + // Direct parents of this class MonsterClass parents[]; Token parentNames[]; @@ -732,7 +755,8 @@ final class MonsterClass int[] getDataSegment() { assert(sc !is null && sc.isClass(), "Class does not have a class scope"); - int[] data = new int[sc.getDataSize]; + assert(dataSize == sc.getDataSize); + int[] data = new int[dataSize]; int totSize = 0; foreach(VarDeclStatement vds; vardecs) @@ -767,7 +791,7 @@ final class MonsterClass } // Get an object from this class (but do not assign a thread to it) - MonsterObject *getObject() + MonsterObject *getObject(ref int[] dataBuf) { requireCompile(); @@ -787,8 +811,12 @@ final class MonsterClass // to see what sizes are actually used. The entire structure can // reside inside it's own region. - // Copy the data segment - obj.data = data.dup; + // Copy the data segment into the buffer + assert(data.length == dataSize); + assert(dataBuf.length >= dataSize); + obj.data = dataBuf[0..dataSize]; + obj.data[] = data[]; + dataBuf = dataBuf[dataSize..$]; // Point to the static data segment obj.sdata = sdata; @@ -811,7 +839,7 @@ final class MonsterClass } // Clone an existing object - MonsterObject *getClone(MonsterObject *source) + MonsterObject *getClone(MonsterObject *source, ref int[] dataBuf) { assert(source !is null); assert(source.cls is this); @@ -825,9 +853,13 @@ final class MonsterClass // Set the class obj.cls = this; - // TODO: Fix memory management here too. // Copy the data segment from the source - obj.data = source.data.dup; + assert(data.length == dataSize); + assert(dataBuf.length >= dataSize); + assert(dataSize == source.data.length); + obj.data = dataBuf[0..dataSize]; + obj.data[] = source.data[]; + dataBuf = dataBuf[dataSize..$]; // Point to the static data segment obj.sdata = sdata; @@ -1079,7 +1111,8 @@ final class MonsterClass parents.length = parentNames.length; foreach(int i, pName; parentNames) { - // Find the class + // Find the class. findClass guarantees that the returned + // class is scoped. MonsterClass mc = global.findClass(pName); assert(mc !is null); @@ -1162,6 +1195,16 @@ final class MonsterClass foreach(st; statedecs) states[st.st.index] = st.st; + // Set the data segment size and the total data size for all + // base classes. + dataSize = sc.getDataSize(); + + totalDataSize = 0; + foreach(t; tree) + totalDataSize += t.dataSize; + + assert(totalDataSize >= dataSize); + flags.unset(CFlags.InScope); } diff --git a/mscripts/gameobjects/actor.mn b/mscripts/gameobjects/actor.mn new file mode 100644 index 000000000..99fca9baf --- /dev/null +++ b/mscripts/gameobjects/actor.mn @@ -0,0 +1,40 @@ +/* + OpenMW - The completely unofficial reimplementation of Morrowind + Copyright (C) 2008 Nicolay Korslund + Email: < korslund@gmail.com > + WWW: http://openmw.snaptoad.com/ + + This file (actor.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/ . + + */ + +// Actors are a common base class for creatures, NPCs and the player. +class Actor : GameObject; + +// The actor's level +int level; + +// Stats. These are the base values, before any positive or negative +// effects are applied. +int + baseStrength, baseIntelligence, baseWillpower, baseAgility, + baseSpeed, baseEndurance, basePersonality, baseLuck; + +// Maximum health values, before any effects are applied. +int baseMaxHealth, baseMaxMana, baseMaxFatigue; + +// Amount of gold this actor is carrying +int gold; diff --git a/mscripts/gameobjects/creature.mn b/mscripts/gameobjects/creature.mn new file mode 100644 index 000000000..4c1c4f6ba --- /dev/null +++ b/mscripts/gameobjects/creature.mn @@ -0,0 +1,36 @@ +/* + OpenMW - The completely unofficial reimplementation of Morrowind + Copyright (C) 2008 Nicolay Korslund + Email: < korslund@gmail.com > + WWW: http://openmw.snaptoad.com/ + + This file (creature.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 Creature : Actor; + +// Soul gem value +int soul; + +// Not sure how to use these +int combat, magic, stealth; + +// Attack values for various types of attack +int + attackMin1, attackMax1, + attackMin2, attackMax2, + attackMin3, attackMax3; diff --git a/mscripts/gameobjects/gameobject.mn b/mscripts/gameobjects/gameobject.mn index 432aa59a0..1c81713cf 100644 --- a/mscripts/gameobjects/gameobject.mn +++ b/mscripts/gameobjects/gameobject.mn @@ -38,7 +38,7 @@ bool isPlaced; float x, y, z; float r1, r2, r3; -float scale; +float scale = 1.0; char[] name, id; @@ -52,7 +52,7 @@ char[] owner; char[] global; // Reference to a soul trapped creature? -char[] soul; +char[] soulID; // Faction owner? Rank? char[] cnam; diff --git a/mscripts/gameobjects/ingredient.mn b/mscripts/gameobjects/ingredient.mn new file mode 100644 index 000000000..8c34103b5 --- /dev/null +++ b/mscripts/gameobjects/ingredient.mn @@ -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 (ingredient.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/ . + + */ + +// Alchemy ingredients +class Ingredient : InventoryItem; + +// more to come here... diff --git a/mscripts/gameobjects/lockpick.mn b/mscripts/gameobjects/lockpick.mn new file mode 100644 index 000000000..98d5a6d5f --- /dev/null +++ b/mscripts/gameobjects/lockpick.mn @@ -0,0 +1,24 @@ +/* + OpenMW - The completely unofficial reimplementation of Morrowind + Copyright (C) 2008 Nicolay Korslund + Email: < korslund@gmail.com > + WWW: http://openmw.snaptoad.com/ + + This file (lockpick.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 Lockpick : Tool; diff --git a/mscripts/gameobjects/misc.mn b/mscripts/gameobjects/misc.mn new file mode 100644 index 000000000..55ac71803 --- /dev/null +++ b/mscripts/gameobjects/misc.mn @@ -0,0 +1,30 @@ +/* + OpenMW - The completely unofficial reimplementation of Morrowind + Copyright (C) 2008 Nicolay Korslund + Email: < korslund@gmail.com > + WWW: http://openmw.snaptoad.com/ + + This file (misc.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/ . + + */ + +// Misc inventory items, like bottles, pots, pillows, keys etc. They +// are mostly useless (except keys), but may be bought and sold. +class Misc : InventoryItem; + +// Not quite sure what the significance of this is. It is set to +// non-zero for some keys, but not for all. +int isKey; diff --git a/mscripts/gameobjects/person.mn b/mscripts/gameobjects/person.mn new file mode 100644 index 000000000..88ef19634 --- /dev/null +++ b/mscripts/gameobjects/person.mn @@ -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 (person.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 Person : Actor; + +int disposition, reputation, rank; diff --git a/mscripts/gameobjects/probe.mn b/mscripts/gameobjects/probe.mn new file mode 100644 index 000000000..5a6c07759 --- /dev/null +++ b/mscripts/gameobjects/probe.mn @@ -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 (probe.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/ . + + */ + +// Probes - tools used for disarming traps +class Probe : Tool; diff --git a/mscripts/gameobjects/repairitem.mn b/mscripts/gameobjects/repairitem.mn new file mode 100644 index 000000000..275ed229c --- /dev/null +++ b/mscripts/gameobjects/repairitem.mn @@ -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 (repairitem.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/ . + + */ + +// Hammers etc. used to repair weapons and armor +class RepairItem : Tool; diff --git a/mscripts/gameobjects/static.mn b/mscripts/gameobjects/static.mn new file mode 100644 index 000000000..91852b3d5 --- /dev/null +++ b/mscripts/gameobjects/static.mn @@ -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 (static.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/ . + + */ + +// Static meshes - walls, buildings, rocks, etc. +class Static : GameObject; diff --git a/mscripts/gameobjects/tool.mn b/mscripts/gameobjects/tool.mn new file mode 100644 index 000000000..e06d13852 --- /dev/null +++ b/mscripts/gameobjects/tool.mn @@ -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 (tool.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/ . + + */ + +// Common base class for probes, lock picks and repair hammers. +class Tool : InventoryItem; + +float quality; +int uses; diff --git a/openmw.d b/openmw.d index 7e86c9fbb..bfd944efd 100644 --- a/openmw.d +++ b/openmw.d @@ -42,6 +42,7 @@ import core.memory; import core.config; import monster.util.string; +import monster.vm.mobject; import mscripts.object; import sound.audio; @@ -416,4 +417,5 @@ void main(char[][] args) // Write some memory statistics poolSize(); writefln(esmRegion); + writefln("Total objects: ", getTotalObjects); } diff --git a/scene/celldata.d b/scene/celldata.d index f60059b38..ea3778e58 100644 --- a/scene/celldata.d +++ b/scene/celldata.d @@ -140,9 +140,6 @@ class CellData { reg = r; killCell(); // Make sure all data is initialized. - - // Set up the Monster classes if it's not done already - setup(); } // Kills all data and initialize the object for reuse. @@ -259,16 +256,6 @@ class CellData private: - static - MonsterClass gameObjC; - - void setup() - { - if(gameObjC !is null) return; - - gameObjC = MonsterClass.find("GameObject"); - } - void loadReferences() { with(esFile) @@ -308,7 +295,7 @@ class CellData { LiveStatic ls; ls.m = s; - ls.obj = gameObjC.createObject; + ls.obj = s.proto.clone(); mo = ls.obj; statics.insert(ls); stat = true; @@ -318,7 +305,7 @@ class CellData { LiveMisc ls; ls.m = m; - ls.obj = gameObjC.createObject; + ls.obj = m.proto.clone(); mo = ls.obj; miscItems.insert(ls); } @@ -360,7 +347,7 @@ class CellData { LiveActivator ls; ls.m = a; - ls.obj = gameObjC.createObject; + ls.obj = a.proto.clone(); mo = ls.obj; activators.insert(ls); activator = true; @@ -370,7 +357,7 @@ class CellData { LiveNPC ls; ls.m = n; - ls.obj = gameObjC.createObject; + ls.obj = n.proto.clone(); mo = ls.obj; npcs.insert(ls); } @@ -378,7 +365,7 @@ class CellData { LivePotion ls; ls.m = p; - ls.obj = gameObjC.createObject; + ls.obj = p.proto.clone(); mo = ls.obj; potions.insert(ls); } @@ -386,7 +373,7 @@ class CellData { LiveApparatus ls; ls.m = m; - ls.obj = gameObjC.createObject; + ls.obj = m.proto.clone(); mo = ls.obj; appas.insert(ls); } @@ -394,7 +381,7 @@ class CellData { LiveIngredient ls; ls.m = m; - ls.obj = gameObjC.createObject; + ls.obj = m.proto.clone(); mo = ls.obj; ingredients.insert(ls); } @@ -402,7 +389,7 @@ class CellData { LiveArmor ls; ls.m = m; - ls.obj = gameObjC.createObject; + ls.obj = m.proto.clone(); mo = ls.obj; armors.insert(ls); } @@ -418,7 +405,7 @@ class CellData { LiveBook ls; ls.m = m; - ls.obj = gameObjC.createObject; + ls.obj = m.proto.clone(); mo = ls.obj; books.insert(ls); } @@ -426,7 +413,7 @@ class CellData { LiveClothing ls; ls.m = m; - ls.obj = gameObjC.createObject; + ls.obj = m.proto.clone(); mo = ls.obj; clothes.insert(ls); } @@ -434,7 +421,7 @@ class CellData { LiveTool ls; ls.m = m; - ls.obj = gameObjC.createObject; + ls.obj = m.proto.clone(); mo = ls.obj; tools.insert(ls); } @@ -442,7 +429,7 @@ class CellData { LiveTool ls; ls.m = m; - ls.obj = gameObjC.createObject; + ls.obj = m.proto.clone(); mo = ls.obj; tools.insert(ls); } @@ -450,7 +437,7 @@ class CellData { LiveTool ls; ls.m = m; - ls.obj = gameObjC.createObject; + ls.obj = m.proto.clone(); mo = ls.obj; tools.insert(ls); } @@ -458,7 +445,7 @@ class CellData { LiveCreature ls; ls.m = c; - ls.obj = gameObjC.createObject; + ls.obj = c.proto.clone(); mo = ls.obj; creatures.insert(ls); } @@ -469,7 +456,9 @@ class CellData ls.m = l.instCreature(playerData.level); if(ls.m != null) { - ls.obj = gameObjC.createObject; mo = ls.obj; + // Note that this clones a creature object, not a + // leveled list object. + ls.obj = ls.m.proto.clone(); mo = ls.obj; creatures.insert(ls); } } @@ -480,8 +469,9 @@ class CellData with(*mo) { - // Scale - setFloat("scale", getHNOFloat("XSCL", 1.0)); + // Scale. Multiply with the existing scale value. + float scale = getFloat("scale"); + setFloat("scale", scale*getHNOFloat("XSCL", 1.0)); // Statics only need the position data. Skip the // unneeded calls to isNextSub() as an optimization. @@ -495,7 +485,7 @@ class CellData setString8("global", getHNOString("BNAM")); // ID of creature trapped in a soul gem (?) - setString8("soul", getHNOString("XSOL")); + setString8("soulID", getHNOString("XSOL")); // ?? CNAM has a faction name, might be for // objects/beds etc belonging to a faction.