Added CLAS, CONT, FACT, LOCK, PROB, REPA and WEAP records.

pull/7/head
Nicolay Korslund 15 years ago
parent fb690cce9b
commit bd71031206

@ -391,7 +391,7 @@ public:
fail("skipHSubSize() mismatch");
}
/* Sub-record head This updates leftRec beyond the current
/* Sub-record header. This updates leftRec beyond the current
sub-record as well. leftSub contains size of current sub-record.
*/
void getSubHeader()
@ -410,6 +410,14 @@ public:
fail("Not enough bytes left in record for this subrecord.");
}
/** Get sub header and check the size
*/
void getSubHeaderIs(int size)
{
getSubHeader();
if(size != leftSub)
fail("getSubHeaderIs(): Sub header mismatch");
}
/*************************************************************************
*

@ -0,0 +1,64 @@
#ifndef _ESM_CLAS_H
#define _ESM_CLAS_H
#include "esm_reader.hpp"
namespace ESM {
/*
* Character class definitions
*/
// These flags tells us which items should be auto-calculated for this
// class
struct Class
{
enum AutoCalc
{
Weapon = 0x00001,
Armor = 0x00002,
Clothing = 0x00004,
Books = 0x00008,
Ingredient = 0x00010,
Lockpick = 0x00020,
Probe = 0x00040,
Lights = 0x00080,
Apparatus = 0x00100,
Repair = 0x00200,
Misc = 0x00400,
Spells = 0x00800,
MagicItems = 0x01000,
Potions = 0x02000,
Training = 0x04000,
Spellmaking = 0x08000,
Enchanting = 0x10000,
RepairItem = 0x20000
};
struct CLDTstruct
{
int attribute[2]; // Attributes that get class bonus
int specialization; // 0 = Combat, 1 = Magic, 2 = Stealth
int skills[5][2]; // Minor and major skills.
int isPlayable; // 0x0001 - Playable class
// I have no idea how to autocalculate these items...
int calc;
}; // 60 bytes
std::string name, description;
CLDTstruct data;
void load(ESMReader &esm)
{
name = esm.getHNString("FNAM");
esm.getHNT(data, "CLDT", 60);
if(data.isPlayable > 1)
esm.fail("Unknown bool value");
description = esm.getHNOString("DESC");
}
};
}
#endif

@ -0,0 +1,64 @@
#ifndef _ESM_CONT_H
#define _ESM_CONT_H
#include "esm_reader.hpp"
namespace ESM {
/*
* Container definition
*/
struct ContItem
{
int count;
NAME32 item;
};
struct InventoryList
{
std::vector<ContItem> list;
void load(ESMReader &esm)
{
ContItem ci;
while(esm.hasMoreSubs())
{
esm.getHNT(ci, "NPCO", 36);
list.push_back(ci);
}
}
};
struct Container
{
enum Flags
{
Organic = 1, // Objects cannot be placed in this container
Respawn = 2, // Respawns after 4 months
Unknown = 8
};
std::string name, model, script;
float weight; // Not sure, might be max total weight allowed?
int flags;
InventoryList inventory;
void load(ESMReader &esm)
{
model = esm.getHNString("MODL");
name = esm.getHNOString("FNAM");
esm.getHNT(weight, "CNDT", 4);
esm.getHNT(flags, "FLAG", 4);
if(flags & 0xf4) esm.fail("Unknown flags");
if(!(flags & 0x8)) esm.fail("Flag 8 not set");
script = esm.getHNOString("SCRI");
inventory.load(esm);
}
};
}
#endif

@ -0,0 +1,78 @@
#ifndef _ESM_FACT_H
#define _ESM_FACT_H
#include "esm_reader.hpp"
namespace ESM {
/*
* Faction definitions
*/
// Requirements for each rank
struct RankData
{
int attribute1, attribute2; // Attribute level
int skill1, skill2; // Skill level (faction skills given in
// skillID below.) You need one skill at
// level 'skill1' and two skills at level
// 'skill2' to advance to this rank.
int factReaction; // Reaction from faction members
};
struct Faction
{
std::string id, name;
struct FADTstruct
{
// Which attributes we like
int attribute1, attribute2;
RankData rankData[10];
int skillID[6]; // IDs of skills this faction require
int unknown; // Always -1?
int isHidden; // 1 - hidden from player
}; // 240 bytes
FADTstruct data;
struct Reaction
{
std::string faction;
int reaction;
};
std::vector<Reaction> reactions;
// Name of faction ranks (may be empty for NPC factions)
std::string ranks[10];
void load(ESMReader &esm)
{
name = esm.getHNString("FNAM");
// Read rank names. These are optional.
int i = 0;
while(esm.isNextSub("RNAM") && i<10) ranks[i++] = esm.getHString();
// Main data struct
esm.getHNT(data, "FADT", 240);
if(data.isHidden > 1) esm.fail("Unknown flag!");
// Read faction response values
while(esm.hasMoreSubs())
{
Reaction r;
r.faction = esm.getHNString("ANAM");
esm.getHNT(r.reaction, "INTV");
reactions.push_back(r);
}
}
};
}
#endif

@ -0,0 +1,54 @@
#ifndef _ESM_LOCKS_H
#define _ESM_LOCKS_H
#include "esm_reader.hpp"
namespace ESM {
/*
* This file covers lockpicks (LOCK), probes (PROB) and armor repair
* items (REPA). These have nearly identical data structures.
*/
struct Tool
{
struct Data
{
float weight;
int value;
float quality; // And when I say nearly identical structure, I
int uses; // mean perfectly identical except that these two
// variables are swaped for repair items. Don't ask
// me why.
}; // Size = 16
Data data;
std::string name, model, icon, script;
void load(ESMReader &esm)
{
model = esm.getHNString("MODL");
name = esm.getHNString("FNAM");
esm.getSubName();
NAME n = esm.retSubName();
// The data name varies, RIDT for repair items, LKDT for lock
// picks, PBDT for probes
esm.getHT(data, 16);
if(n == "RIDT")
{
// Swap t.data.quality and t.data.uses for repair items (sigh)
float tmp = *((float*)&data.uses);
data.uses = *((int*)&data.quality);
data.quality = tmp;
}
script = esm.getHNOString("SCRI");
icon = esm.getHNOString("ITEX");
}
};
}
#endif

@ -0,0 +1,68 @@
#ifndef _ESM_WEAP_H
#define _ESM_WEAP_H
#include "esm_reader.hpp"
namespace ESM {
/*
* Weapon definition
*/
struct Weapon
{
enum Type
{
ShortBladeOneHand = 0,
LongBladeOneHand = 1,
LongBladeTwoHand = 2,
BluntOneHand = 3,
BluntTwoClose = 4,
BluntTwoWide = 5,
SpearTwoWide = 6,
AxeOneHand = 7,
AxeTwoHand = 8,
MarksmanBow = 9,
MarksmanCrossbow = 10,
MarksmanThrown = 11,
Arrow = 12,
Bolt = 13
};
enum Flags
{
Magical = 0x01,
Silver = 0x02
};
#pragma pack(push)
#pragma pack(1)
struct WPDTstruct
{
float weight;
int value;
short type;
short health;
float speed, reach;
short enchant; // Enchantment points
unsigned char chop[2], slash[2], thrust[2]; // Min and max
int flags;
}; // 32 bytes
#pragma pack(pop)
WPDTstruct data;
std::string name, model, icon, enchant, script;
void load(ESMReader &esm)
{
model = esm.getHNString("MODL");
name = esm.getHNOString("FNAM");
esm.getHNT(data, "WPDT", 32);
script = esm.getHNOString("SCRI");
icon = esm.getHNOString("ITEX");
enchant = esm.getHNOString("ENAM");
}
};
}
#endif

@ -8,13 +8,17 @@
#include "loadbody.hpp"
#include "loadbook.hpp"
#include "loadbsgn.hpp"
#include "loadclas.hpp"
#include "loadclot.hpp"
#include "loadcont.hpp"
#include "loadcrec.hpp"
#include "loaddoor.hpp"
#include "loadench.hpp"
#include "loadfact.hpp"
#include "loadglob.hpp"
#include "loadingr.hpp"
#include "loadligh.hpp"
#include "loadlocks.hpp"
#include "loadmisc.hpp"
#include "loadrace.hpp"
#include "loadskil.hpp"
@ -23,6 +27,7 @@
#include "loadspel.hpp"
#include "loadsscr.hpp"
#include "loadstat.hpp"
#include "loadweap.hpp"
namespace ESM {

@ -1,93 +0,0 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (loadclas.d) 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/ .
*/
module esm.loadclas;
import esm.imports;
import esm.loadskil;
/*
* Character class definitions
*/
// These flags tells us which items should be auto-calculated for this
// class
struct Class
{
enum AutoCalc : uint
{
Weapon = 0x00001,
Armor = 0x00002,
Clothing = 0x00004,
Books = 0x00008,
Ingredient = 0x00010,
Lockpick = 0x00020,
Probe = 0x00040,
Lights = 0x00080,
Apparatus = 0x00100,
Repair = 0x00200,
Misc = 0x00400,
Spells = 0x00800,
MagicItems = 0x01000,
Potions = 0x02000,
Training = 0x04000,
Spellmaking = 0x08000,
Enchanting = 0x10000,
RepairItem = 0x20000
}
align(1) struct CLDTstruct
{
Attribute attribute[2]; // Attributes that get class bonus
Specialization specialization; // 0 = Combat, 1 = Magic, 2 = Stealth
SkillEnum[2][5] skills; // Minor and major skills.
uint isPlayable; // 0x0001 - Playable class
// I have no idea how to autocalculate these items...
AutoCalc calc;
static assert(CLDTstruct.sizeof == 60);
}
mixin LoadT;
char[] description;
CLDTstruct data;
void load()
{
name = esFile.getHNString("FNAM");
esFile.readHNExact(&data, data.sizeof, "CLDT");
if(data.isPlayable > 1)
esFile.fail("Unknown bool value");
description = esFile.getHNOString("DESC");
// no makeProto yet
}
}
ListID!(Class) classes;

@ -1,108 +0,0 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (loadcont.d) 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/ .
*/
module esm.loadcont;
import esm.imports;
/*
* Container definition
*/
struct ContItem
{
Item item;
int count;
}
struct InventoryList
{
RegionBuffer!(ContItem) list;
private static char[32] buffer;
void load()
{
list = esFile.getRegion().getBuffer!(ContItem)(0,10);
while(esFile.isNextSub("NPCO"))
{
esFile.getSubHeaderIs(36);
list.length = list.length + 1;
with(list.array[$-1])
{
esFile.getInt(count);
// String is automatically chopped
item = items.lookup(esFile.getString(buffer));
}
}
}
}
struct Container
{
enum Flags
{
Organic = 1, // Objects cannot be placed in this container
Respawn = 2, // Respawns after 4 months
Unknown = 8
}
MeshIndex model;
Script *script;
float weight; // Not sure, might be max total weight allowed?
Flags flags;
InventoryList inventory;
mixin LoadT!();
void load()
{with(esFile){
model = getMesh();
name = getHNOString("FNAM");
weight = getHNFloat("CNDT");
flags = cast(Flags)getHNUint("FLAG");
if(flags & 0xf4) fail("Unknown flags");
if(!(flags & 0x8)) fail("Flag 8 not set");
/*
if(getFileType == FileType.Savegame)
{
int tmp = getHNInt("INDX");
if(tmp) writefln("WARNING, INDX != 0: ", tmp);
}
*/
script = getHNOPtr!(Script)("SCRI", scripts);
inventory.load();
makeProto();
proto.setFloat("weight", weight);
}}
}
ListID!(Container) containers;

@ -1,106 +0,0 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (loadfact.d) 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/ .
*/
module esm.loadfact;
import esm.imports;
/*
* Faction definitions
*/
// Requirements for each rank
align(1) struct RankData
{
int attribute1, attribute2; // Attribute level
int skill1, skill2; // Skill level (faction skills given in
// skillID below.) You need one skill at
// level 'skill1' and two skills at level
// 'skill2' to advance to this rank.
int factReaction; // Reaction from faction members
}
struct Faction
{
char[] id, name;
LoadState state;
align(1) struct FADTstruct
{
// Which attributes we like
int attribute1, attribute2;
RankData rankData[10];
int skillID[6]; // IDs of skills this faction require
int unknown; // Always -1?
uint isHidden; // 1 - hidden from player
static assert(RankData.sizeof == 20);
static assert(FADTstruct.sizeof == 240);
}
FADTstruct data;
RankData rankData[10];
struct Reaction
{
Faction* faction;
int reaction;
}
RegionBuffer!(Reaction) reactions;
char[] ranks[10]; // Name of faction ranks (may be empty for NPC
// factions)
void load()
{with(esFile){
name = getHNString("FNAM");
// Read rank names. These are optional.
ranks[] = null;
int i = 0;
while(isNextSub("RNAM") && i<10) ranks[i++] = getHString();
if(isNextSub("RNAM")) fail("Too many rank names");
// Main data struct
readHNExact(&data, data.sizeof, "FADT");
if(data.isHidden > 1) fail("Unknown flag!");
// Read faction response values
reactions = getRegion().getBuffer!(Reaction)();
while(hasMoreSubs())
{
Reaction r;
r.faction = getHNPtr!(Faction)("ANAM", factions);
r.reaction = getHNInt("INTV");
reactions ~= r;
}
}}
}
ListID!(Faction) factions;

@ -1,90 +0,0 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (loadlocks.d) 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/ .
*/
module esm.loadlocks;
import esm.imports;
/*
* This file covers lockpicks, probes and armor repair items, since
* these have nearly identical structure.
*/
struct Tool
{
align(1) struct Data
{
float weight;
int value;
float quality; // And when I say nearly identical structure, I
int uses; // mean perfectly identical except that these two
// variables are swaped for repair items. Don't ask
// me why.
}
static assert(Data.sizeof == 16);
Data data;
mixin LoadT;
MeshIndex model;
IconIndex icon;
Script* script;
void load()
{with(esFile){
model = getMesh();
name = getHNString("FNAM");
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);
data.quality = tmp;
}
script = getHNOPtr!(Script)("SCRI", scripts);
icon = getOIcon();
makeProto(type);
proto.setFloat("quality", data.quality);
proto.setInt("uses", data.uses);
}}
}
ListID!(Tool) lockpicks, probes, repairs;

@ -1,98 +0,0 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (loadweap.d) 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/ .
*/
module esm.loadweap;
import esm.imports;
/*
* Weapon definition
*/
struct Weapon
{
enum Type : short
{
ShortBladeOneHand = 0,
LongBladeOneHand = 1,
LongBladeTwoHand = 2,
BluntOneHand = 3,
BluntTwoClose = 4,
BluntTwoWide = 5,
SpearTwoWide = 6,
AxeOneHand = 7,
AxeTwoHand = 8,
MarksmanBow = 9,
MarksmanCrossbow = 10,
MarksmanThrown = 11,
Arrow = 12,
Bolt = 13,
Length
}
enum Flags : uint
{
Magical = 0x01,
Silver = 0x02
}
align(1) struct WPDTstruct
{
float weight;
int value;
Type type;
short health;
float speed, reach;
short enchant; // Enchantment points
ubyte[2] chop, slash, thrust; // Min and max
Flags flags;
static assert(WPDTstruct.sizeof == 32);
}
WPDTstruct data;
mixin LoadT!();
MeshIndex model;
IconIndex icon;
Enchantment* enchant;
Script* script;
void load()
{with(esFile){
model = getMesh();
name = getHNOString("FNAM");
readHNExact(&data, data.sizeof, "WPDT");
script = getHNOPtr!(Script)("SCRI", scripts);
icon = getOIcon();
enchant = getHNOPtr!(Enchantment)("ENAM", enchants);
makeProto();
proto.setFloat("speed", data.speed);
proto.setFloat("reach", data.reach);
proto.setInt("health", data.health);
}}
}
ListID!(Weapon) weapons;
Loading…
Cancel
Save