First commit
This commit is contained in:
commit
5b48414900
263 changed files with 24830 additions and 0 deletions
146
sources/Resources/NiceResourceManager.uc
Normal file
146
sources/Resources/NiceResourceManager.uc
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
//==============================================================================
|
||||
// NicePack / NiceResourceManager
|
||||
//==============================================================================
|
||||
// Manages resource loading in a way that would allow to avoid loading
|
||||
// the same resource over and over.
|
||||
//==============================================================================
|
||||
// Class hierarchy: Object > NiceResourceManager
|
||||
//==============================================================================
|
||||
// 'Nice pack' source
|
||||
// Do whatever the fuck you want with it
|
||||
// Author: dkanus
|
||||
// E-mail: dkanus@gmail.com
|
||||
//==============================================================================
|
||||
class NiceResourceManager extends Object
|
||||
dependson(NiceResources);
|
||||
|
||||
// Structures and arrays used for storing already loaded resources.
|
||||
struct PathMeshPair{
|
||||
var Mesh myMesh;
|
||||
var string path;
|
||||
};
|
||||
var array<PathMeshPair> loadedMeshes;
|
||||
|
||||
struct PathSoundPair{
|
||||
var Sound mySound;
|
||||
var string path;
|
||||
};
|
||||
var array<PathSoundPair> loadedSounds;
|
||||
|
||||
struct PathMaterialPair{
|
||||
var Material myMaterial;
|
||||
var string path;
|
||||
};
|
||||
var array<PathMaterialPair> loadedMaterials;
|
||||
|
||||
// Used to convert strings to names via 'SetPropertyText'
|
||||
var name nameProperty;
|
||||
|
||||
// Low-level method for loading meshes.
|
||||
function Mesh LoadMeshObject(string path){
|
||||
local int i;
|
||||
local Mesh myMesh;
|
||||
local Object loadO;
|
||||
local PathMeshPair newPair;
|
||||
for(i = 0;i < default.loadedMeshes.length;i ++)
|
||||
if(loadedMeshes[i].path ~= path)
|
||||
return loadedMeshes[i].myMesh;
|
||||
loadO = DynamicLoadObject(path, class'SkeletalMesh');
|
||||
myMesh = SkeletalMesh(loadO);
|
||||
newPair.myMesh = myMesh;
|
||||
newPair.path = path;
|
||||
loadedMeshes[loadedMeshes.length] = newPair;
|
||||
return myMesh;
|
||||
}
|
||||
|
||||
// Low-level method for loading sounds.
|
||||
function Sound LoadSoundObject(string path){
|
||||
local int i;
|
||||
local Sound mySound;
|
||||
local Object loadO;
|
||||
local PathSoundPair newPair;
|
||||
for(i = 0;i < loadedSounds.length;i ++)
|
||||
if(loadedSounds[i].path ~= path)
|
||||
return loadedSounds[i].mySound;
|
||||
loadO = DynamicLoadObject(path, class'Sound');
|
||||
mySound = Sound(loadO);
|
||||
newPair.mySound = mySound;
|
||||
newPair.path = path;
|
||||
loadedSounds[loadedSounds.length] = newPair;
|
||||
return mySound;
|
||||
}
|
||||
|
||||
// Low-level method for loading materials.
|
||||
function Material LoadMaterialObject
|
||||
(
|
||||
string path,
|
||||
optional out NiceResources.MaterialType materialType
|
||||
){
|
||||
local int i;
|
||||
local bool isTypeUnknown;
|
||||
local Material myMaterial;
|
||||
local Object loadO;
|
||||
local PathMaterialPair newPair;
|
||||
for(i = 0;i < loadedMaterials.length;i ++)
|
||||
if(loadedMaterials[i].path ~= path)
|
||||
return loadedMaterials[i].myMaterial;
|
||||
isTypeUnknown = (materialType == MT_Unknown);
|
||||
if(isTypeUnknown || materialType == MT_Combiner){
|
||||
loadO = DynamicLoadObject(path, class'Combiner');
|
||||
myMaterial = Combiner(loadO);
|
||||
materialType = MT_Combiner;
|
||||
}
|
||||
if(myMaterial == none && (isTypeUnknown || materialType == MT_FinalBlend)){
|
||||
loadO = DynamicLoadObject(path, class'FinalBlend');
|
||||
myMaterial = FinalBlend(loadO);
|
||||
materialType = MT_FinalBlend;
|
||||
}
|
||||
if(myMaterial == none && (isTypeUnknown || materialType == MT_Shader)){
|
||||
loadO = DynamicLoadObject(path, class'Shader');
|
||||
myMaterial = Shader(loadO);
|
||||
materialType = MT_Shader;
|
||||
}
|
||||
if(myMaterial == none && (isTypeUnknown || materialType == MT_Texture)){
|
||||
loadO = DynamicLoadObject(path, class'Texture');
|
||||
myMaterial = Texture(loadO);
|
||||
materialType = MT_Texture;
|
||||
}
|
||||
if(myMaterial == none && (isTypeUnknown || materialType == MT_Material)){
|
||||
loadO = DynamicLoadObject(path, class'Material');
|
||||
myMaterial = Material(loadO);
|
||||
materialType = MT_Material;
|
||||
}
|
||||
if(myMaterial == none)
|
||||
materialType = MT_Unknown;
|
||||
newPair.myMaterial = myMaterial;
|
||||
newPair.path = path;
|
||||
loadedMaterials[loadedMaterials.length] = newPair;
|
||||
return myMaterial;
|
||||
}
|
||||
|
||||
// Loads actual mesh resources for given 'NiceMesh'.
|
||||
function LoadMesh(out NiceResources.NiceMesh myMesh){
|
||||
if(myMesh.meshObject != none) return;
|
||||
myMesh.meshObject = LoadMeshObject(myMesh.data.reference);
|
||||
}
|
||||
|
||||
// Loads actual sound resources for given 'NiceSound'.
|
||||
function LoadSound(out NiceResources.NiceSound mySound){
|
||||
if(mySound.soundObject != none) return;
|
||||
mySound.soundObject = LoadSoundObject(mySound.data.reference);
|
||||
}
|
||||
|
||||
// Loads actual animation name for given 'NiceAnimation'.
|
||||
function LoadAnimation(out NiceResources.NiceAnimation myAnimation){
|
||||
if(myAnimation.loadedName != '') return;
|
||||
SetPropertyText("nameProperty", myAnimation.data.nameRef);
|
||||
myAnimation.loadedName = nameProperty;
|
||||
}
|
||||
|
||||
// Loads actual texture resources for given 'NiceMaterial'.
|
||||
function LoadMaterial(out NiceResources.NiceMaterial myMaterial){
|
||||
if(myMaterial.materialObject != none) return;
|
||||
myMaterial.materialObject = LoadMaterialObject(
|
||||
myMaterial.data.reference,
|
||||
myMaterial.data.materialType);
|
||||
}
|
||||
47
sources/Resources/NiceResourceSet.uc
Normal file
47
sources/Resources/NiceResourceSet.uc
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
//==============================================================================
|
||||
// NicePack / NiceResourceSet
|
||||
//==============================================================================
|
||||
// Object for storing resource packs data for 'NicePack'.
|
||||
//==============================================================================
|
||||
// 'Nice pack' source
|
||||
// Do whatever the fuck you want with it
|
||||
// Author: dkanus
|
||||
// E-mail: dkanus@gmail.com
|
||||
//==============================================================================
|
||||
class NiceResourceSet extends Object
|
||||
dependson(NiceResources)
|
||||
PerObjectConfig
|
||||
config(NiceResources);
|
||||
|
||||
// Name of .ini-file where resources are stored
|
||||
// for this class of resource sets.
|
||||
// If you want to separate resources for your mutator into a separate config -
|
||||
// you need to also change this variable.
|
||||
var const string iniName;
|
||||
// If two packs were loaded - on a remote end and locally
|
||||
// (only highest versions are relevant)
|
||||
// and either has this flag set to true - local set will be used.
|
||||
var config bool localAlwaysOverrides;
|
||||
|
||||
// Title for this data set.
|
||||
var NiceResources.Title myTitle;
|
||||
// ID (not expected to be human-readable) of this resource set;
|
||||
// Read from a name of the object it's stored as.
|
||||
//var string ID;
|
||||
// Name of object to which this set relates (like weapon's or zed's name/id).
|
||||
//var config string subject;
|
||||
// Additional (optional) properties this resource set can store.
|
||||
var config array<NicePlainData.DataPair> data;
|
||||
// We wrap loaded properties into this data object for convenience.
|
||||
var NicePlainData.Data properties;
|
||||
|
||||
// Resources stored in a set.
|
||||
var config array<NiceResources.NiceMeshData> meshes;
|
||||
var config array<NiceResources.NiceSoundData> sounds;
|
||||
var config array<NiceResources.NiceMaterialData> materials;
|
||||
var config array<NiceResources.NiceAnimationData> animations;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
iniName="NiceResources"
|
||||
}
|
||||
517
sources/Resources/NiceResources.uc
Normal file
517
sources/Resources/NiceResources.uc
Normal file
|
|
@ -0,0 +1,517 @@
|
|||
//==============================================================================
|
||||
// NicePack / NiceResources
|
||||
//==============================================================================
|
||||
// Class that:
|
||||
// 1. Contains definitions for resources
|
||||
// formats as they're used in a NicePack;
|
||||
// 2. Manages loading resource sets from config files.
|
||||
//==============================================================================
|
||||
// Class hierarchy: Object > NiceResources
|
||||
//==============================================================================
|
||||
// 'Nice pack' source
|
||||
// Do whatever the fuck you want with it
|
||||
// Author: dkanus
|
||||
// E-mail: dkanus@gmail.com
|
||||
//==============================================================================
|
||||
class NiceResources extends Object
|
||||
dependson(NicePlainData);
|
||||
|
||||
// Mesh data used in NicePack.
|
||||
struct NiceMeshData{
|
||||
// ID of this sound;
|
||||
// IDs are aliases necessary to allow us to
|
||||
// reference particular types of resources,
|
||||
// while preserving an ability to swap actual resources on the fly.
|
||||
var string ID;
|
||||
// Reference to the mesh object.
|
||||
var string reference;
|
||||
};
|
||||
|
||||
// Mesh instance used in NicePack.
|
||||
struct NiceMesh{
|
||||
// Sound parameters.
|
||||
var NiceMeshData data;
|
||||
// Variable into which we will load our sound.
|
||||
var Mesh meshObject;
|
||||
};
|
||||
|
||||
// Sound data used in NicePack.
|
||||
struct NiceSoundData{
|
||||
// ID of this sound;
|
||||
// IDs are aliases necessary to allow us to
|
||||
// reference particular types of resources,
|
||||
// while preserving an ability to swap actual resources on the fly.
|
||||
var string ID;
|
||||
// Reference to the sound object.
|
||||
var string reference;
|
||||
// Obvious sound parameters.
|
||||
var float volume;
|
||||
var float radius;
|
||||
var float pitch;
|
||||
};
|
||||
|
||||
// Sound instance used in NicePack.
|
||||
struct NiceSound{
|
||||
// Sound parameters.
|
||||
var NiceSoundData data;
|
||||
// Variable into which we will load our sound.
|
||||
var Sound soundObject;
|
||||
};
|
||||
|
||||
// Animation data used in NicePack.
|
||||
struct NiceAnimationData{
|
||||
// ID of this animation;
|
||||
// IDs are aliases necessary to allow us to
|
||||
// reference particular types of resources,
|
||||
// while preserving an ability to swap actual resources on the fly.
|
||||
var string ID;
|
||||
// String representation of this animation's name.
|
||||
var string nameRef;
|
||||
// Starting point to play animation from.
|
||||
var float start;
|
||||
// End point at which we stop playing the animation;
|
||||
// if 'end' <= 'start' - we consider this animation empty.
|
||||
var float end;
|
||||
// Default rate at which this animation will be played;
|
||||
// '<= 0.0' means '1.0'.
|
||||
var float rate;
|
||||
// Channel on which animation will be played by default.
|
||||
var int defaultChannel;
|
||||
};
|
||||
|
||||
// Animation instance used in NicePack.
|
||||
// Doesn't correspond 1-to-1 to Unreal Engine's counterpart as it can
|
||||
// consist of only a part of Unreal's animation.
|
||||
// This is to allow us construction of animation that correspond to
|
||||
// subset of existing ones that have a meaning distinctive from
|
||||
// all animation (example is segmented weapon reloadings,
|
||||
// - magazine extraction, insertion, etc.)
|
||||
struct NiceAnimation{
|
||||
// Animation parameters.
|
||||
var NiceAnimationData data;
|
||||
// Name of animation from which we'll be playing a segment.
|
||||
var name loadedName;
|
||||
};
|
||||
|
||||
// Type to use to load a particular paint when loading 'NicePaint'.
|
||||
enum MaterialType{
|
||||
MT_Combiner,
|
||||
MT_FinalBlend,
|
||||
MT_Shader,
|
||||
MT_Texture,
|
||||
MT_Material,
|
||||
MT_Unknown
|
||||
};
|
||||
|
||||
// Material data used in NicePack;
|
||||
// can represent more complex things that actual material, including Combiners.
|
||||
struct NiceMaterialData{
|
||||
// ID of this material;
|
||||
// IDs are aliases necessary to allow us to
|
||||
// reference particular types of resources,
|
||||
// while preserving an ability to swap actual resources on the fly.
|
||||
var string ID;
|
||||
// First-person skin textures
|
||||
var string reference;
|
||||
var MaterialType materialType;
|
||||
};
|
||||
|
||||
// Material instance used in NicePack;
|
||||
// can represent more complex things that actual material, including Combiners.
|
||||
struct NiceMaterial{
|
||||
// Material parameters.
|
||||
var NiceMaterialData data;
|
||||
// Variable into which we will load our material.
|
||||
var Material materialObject;
|
||||
};
|
||||
|
||||
// Each set is uniquely determined by 'Title':
|
||||
// ~ a combination 'ID' and 'subject';
|
||||
// ~ further more each such combination can come and
|
||||
// be stored with different versions.
|
||||
// Read from a name of the object it's stored as.
|
||||
struct Title{
|
||||
// ID (not expected to be human-readable) of this resource set;
|
||||
var string ID;
|
||||
// Name of object to which this set relates
|
||||
// (like weapon's or zed's name/id).
|
||||
var config string subject;
|
||||
};
|
||||
|
||||
// We introduce following structures to group loaded resources
|
||||
// via subject and ID:
|
||||
// - Resource sets with same subject and ID
|
||||
struct IDCase{
|
||||
var string ID;
|
||||
var NiceResourceSet resourceSet;
|
||||
};
|
||||
// - Resource sets with same subject, grouped by ID;
|
||||
struct SubjectCase{
|
||||
var string subject;
|
||||
var array<IDCase> cases;
|
||||
};
|
||||
// NICETODO: have to track updates of these things and sync them with server.
|
||||
// Available resource packs:
|
||||
// - loaded from config or define by user during the game;
|
||||
var protected array<SubjectCase> localResourceCases;
|
||||
// - received from the server.
|
||||
var protected array<SubjectCase> remoteResourceCases;
|
||||
|
||||
// Points at the particular resource set collection (array<NiceResourceSet>)
|
||||
// in our cases, made to avoid passing tons of indices and hide details.
|
||||
// Always point at a full (not filtered) resource set.
|
||||
// For internal use only.
|
||||
// Considered invalid if at least one index is pointing at inexistent array.
|
||||
struct CollectionPointer{
|
||||
// Indices for arrays of cases that lead us to
|
||||
// the particular resource set collection (array<NiceResourceSet>).
|
||||
var int subjectIndex;
|
||||
var int idIndex;
|
||||
// Do we point at collection in the local storage?
|
||||
var bool isLocal;
|
||||
};
|
||||
// As 'CollectionPointer' is a set of pointers into nested arrays,
|
||||
// depending on how much of these indices are valid,
|
||||
// we can distinguish several validity levels:
|
||||
// ~ pointer is completely invalid;
|
||||
// (guaranteed to be lowest in value validity value)
|
||||
var const int ptrCompletelyInvalid;
|
||||
// ~ pointer has valid subject index, but invalid id index;
|
||||
// (guaranteed to be between
|
||||
// 'ptrCompletelyInvalid' and 'ptrCompletelyValid')
|
||||
var const int ptrValidSubject;
|
||||
// ~ pointer is completely valid.
|
||||
// (guaranteed to be highest validity value)
|
||||
var const int ptrCompletelyValid;
|
||||
|
||||
// Filtered resource packs, - possibly incomplete copies of
|
||||
// 'localResourceCases' and 'remoteResourceCases'
|
||||
// that are used as temporary storages to
|
||||
// facilitate filters for search queues.
|
||||
var protected array<SubjectCase> localFilteredCases;
|
||||
var protected array<SubjectCase> remoteFilteredCases;
|
||||
/*
|
||||
// Returns level of pointer's validity
|
||||
// (see below definition of 'CollectionPointer').
|
||||
private function int GetPointerValidity(CollectionPointer ptr){
|
||||
local array<SubjectCase> relevantCases;
|
||||
if(isLocal)
|
||||
relevantCases = localResourceCases;
|
||||
else
|
||||
relevantCases = remoteResourceCases;
|
||||
if(ptr.subjectIndex < 0)
|
||||
return ptrCompletelyInvalid;
|
||||
if(relevantCases.length <= ptr.subjectIndex)
|
||||
return ptrCompletelyInvalid;
|
||||
if(ptr.idIndex < 0)
|
||||
return ptrValidSubject;
|
||||
if(relevantCases[ptr.subjectIndex].cases.length <= ptr.idIndex)
|
||||
return ptrValidSubject;
|
||||
return ptrCompletelyValid;
|
||||
}
|
||||
|
||||
// Validates given pointer with given set:
|
||||
// - creates new cases in given collection,
|
||||
// allowing 'toValidate' to point at something;
|
||||
// - subject and id for new cases are taken from 'resourceSet';
|
||||
// - result isn't written in a collection itself, but into a passed array.
|
||||
// Assumes pointers at all cases, not the filtered collections.
|
||||
// Previously invalid indices are overwritten with new ones.
|
||||
private function ValidatePointer( out CollectionPointer toValidate,
|
||||
NiceResourceSet resourceSet,
|
||||
out array<SubjectCase> relevantCases){
|
||||
local int pointerValidityLevel;
|
||||
local SubjectCase newSubjectCase;
|
||||
local IDCase newIDCase;
|
||||
pointerValidityLevel = GetPointerValidity(toValidate);
|
||||
if(pointerValidityLevel < ptrValidSubject){
|
||||
toValidate.subjectIndex = relevantCases.length;
|
||||
newSubjectCase.subject = resourceSet.subject;
|
||||
relevantCases[toValidate.subjectIndex] = newSubjectCase;
|
||||
}
|
||||
if(pointerValidityLevel < ptrCompletelyValid){
|
||||
toValidate.idIndex =
|
||||
relevantCases[toValidate.subjectIndex].cases.length;
|
||||
newIDCase.ID = resourceSet.ID;
|
||||
relevantCases[toValidate.subjectIndex].cases[toValidate.idIndex] =
|
||||
newIDCase;
|
||||
}
|
||||
}
|
||||
|
||||
// Updates given pointer to point at given subject in all cases.
|
||||
// Wipes indices for id case, making pointer invalid.
|
||||
private function CollectionPointer UpdateSubjectIndex
|
||||
(
|
||||
CollectionPointer toUpdate,
|
||||
string subjectName
|
||||
){
|
||||
local int i;
|
||||
local array<SubjectCase> relevantCases;
|
||||
toUpdate.subjectIndex = -1;
|
||||
toUpdate.idIndex = -1;
|
||||
if(toUpdate.isLocal)
|
||||
relevantCases = localResourceCases;
|
||||
else
|
||||
relevantCases = remoteResourceCases;
|
||||
for(i = 0;i < relevantCases.length;i ++){
|
||||
if(relevantCases[i].subject ~= subjectName){
|
||||
toUpdate.subjectIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return toUpdate;
|
||||
}
|
||||
|
||||
// Updates given pointer to point at given id in all cases.
|
||||
// Fails if it points at invalid subject.
|
||||
private function CollectionPointer UpdateIDIndex
|
||||
(
|
||||
CollectionPointer toUpdate,
|
||||
string id
|
||||
){
|
||||
local int i;
|
||||
local array<SubjectCase> relevantCases;
|
||||
toUpdate.idIndex = -1;
|
||||
if(GetPointerValidity(toUpdate) < ptrValidSubject)
|
||||
return toUpdate;
|
||||
if(toUpdate.isLocal)
|
||||
relevantCases = localResourceCases[toUpdate.subjectIndex].cases;
|
||||
else
|
||||
relevantCases = remoteResourceCases[toUpdate.subjectIndex].cases;
|
||||
for(i = 0;i < relevantCases.length;i ++){
|
||||
if(relevantCases[i].id ~= id){
|
||||
toUpdate.idIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return toUpdate;
|
||||
}
|
||||
|
||||
// Returns indices for subject cases corresponding to
|
||||
// subject and id names given by 'NiceResourceSet' argument.
|
||||
// Returns invalid pointer if indices weren't found.
|
||||
private function CollectionPointer FindCaseIndicies(NiceResourceSet resourceSet,
|
||||
bool isLocal){
|
||||
local CollectionPointer ptr;
|
||||
ptr.isLocal = isLocal;
|
||||
ptr.idIndex = -1;
|
||||
ptr = UpdateSubjectIndex(ptr, resourceSet.myTitle.subject);
|
||||
ptr = UpdateIDIndex(ptr, resourceSet.myTitle.id);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// Inserts given data set into our storage.
|
||||
// If a set with the same subject and ID already exists, - method replaces it.
|
||||
private function UpdateResourceSet(NiceResourceSet updatedSet, bool isLocal){
|
||||
local CollectionPointer setPointer;
|
||||
local array<SubjectCase> relevantCases;
|
||||
if(isLocal)
|
||||
relevantCases = localResourceCases;
|
||||
else
|
||||
relevantCases = remoteResourceCases;
|
||||
setPointer = FindCaseIndicies(updatedSet, isLocal);
|
||||
ValidatePointer(setPointer, updatedSet, relevantCases);
|
||||
relevantCases[setPointer.subjectIndex]
|
||||
.cases[setPointer.idIndex].resourceSet = updatedSet;
|
||||
if(isLocal)
|
||||
localResourceCases = relevantCases;
|
||||
else
|
||||
remoteResourceCases = relevantCases;
|
||||
}
|
||||
|
||||
// Forms resource set name as '<subject>/<ID>/<version>'.
|
||||
private function string FormResourceSetName(Title myTitle){
|
||||
local NicePathBuilder pathBuilder;
|
||||
pathBuilder = class'NicePack'.static.GetPathBuilder();
|
||||
return pathBuilder.Flush().AddElement(myTitle.subject)
|
||||
.AddElement(myTitle.ID)
|
||||
.ToString();
|
||||
}
|
||||
|
||||
|
||||
// Parses resource set name in the form '<subject>/<ID>/<version>'.
|
||||
// If there isn't enough fields, 'version' will contain '-1'.
|
||||
private function ParseResourceSetName
|
||||
(
|
||||
string resourceSetName,
|
||||
out Title myTitle
|
||||
){
|
||||
local array<string> pathLiterals;
|
||||
local NicePathBuilder pathBuilder;
|
||||
pathBuilder = class'Nicepack'.static.GetPathBuilder();
|
||||
pathBuilder.Parse(resourceSetName);
|
||||
myTitle.subject = "";
|
||||
myTitle.ID = "";
|
||||
pathLiterals = pathBuilder.GetElements();
|
||||
if(pathLiterals.length >= 1)
|
||||
myTitle.subject = pathLiterals[0];
|
||||
if(pathLiterals.length >= 2)
|
||||
myTitle.ID = pathLiterals[1];
|
||||
}
|
||||
|
||||
// Loads resource set with a given name without checking if it already exist.
|
||||
private function LoadNamedResourceSetFromConfig(string setName){
|
||||
local NicePlainData.Data newData;
|
||||
local NiceResourceSet newSet;
|
||||
newSet = new(none, setName) class'NiceResourceSet';
|
||||
ParseResourceSetName(setName, newSet.myTitle);
|
||||
newData.pairs = newSet.data;
|
||||
newSet.properties = newData;
|
||||
UpdateResourceSet(newSet, true);
|
||||
}
|
||||
|
||||
function LoadResourceSetsFromConfig
|
||||
(
|
||||
optional class<NiceResourceSet> resourceClass
|
||||
){
|
||||
local int i;
|
||||
local array<string> names;
|
||||
if(localResourceCases.length > 0) return;
|
||||
if(resourceClass == none)
|
||||
resourceClass = class'NiceResourceSet';
|
||||
|
||||
names = GetPerObjectNames( resourceClass.default.iniName,
|
||||
string(class'NiceResourceSet'.name));
|
||||
for(i = 0;i < names.length;i ++)
|
||||
LoadNamedResourceSetFromConfig(names[i]);
|
||||
}
|
||||
|
||||
// Wraps mesh data into unloaded mesh object.
|
||||
function static NiceMesh MeshFromData(NiceMeshData data){
|
||||
local NiceMesh newMesh;
|
||||
newMesh.data = data;
|
||||
return newMesh;
|
||||
}
|
||||
|
||||
// Wraps animation data into unloaded animation object.
|
||||
function static NiceSound SoundFromData(NiceSoundData data){
|
||||
local NiceSound newSounds;
|
||||
newSounds.data = data;
|
||||
return newSounds;
|
||||
}
|
||||
|
||||
// Wraps sound data into unloaded sound object.
|
||||
function static NiceAnimation AnimationFromData(NiceAnimationData data){
|
||||
local NiceAnimation newAnimation;
|
||||
newAnimation.data = data;
|
||||
return newAnimation;
|
||||
}
|
||||
|
||||
// Wraps material data into unloaded material object.
|
||||
function static NiceMaterial MaterialFromData(NiceMaterialData data){
|
||||
local NiceMaterial newMaterial;
|
||||
newMaterial.data = data;
|
||||
return newMaterial;
|
||||
}
|
||||
|
||||
// Starts new search through data sets.
|
||||
// NOTE: adding any new data sets requires you to create new search.
|
||||
function NiceResources NewSearch(){
|
||||
localFilteredCases = localResourceCases;
|
||||
remoteFilteredCases = remoteResourceCases;
|
||||
return self;
|
||||
}
|
||||
|
||||
// Leaves only local resource sets in current search.
|
||||
// 'LocalOnly().RemoteOnly()' removes all possible sets from current search.
|
||||
function NiceResources LocalOnly(){
|
||||
remoteFilteredCases.length = 0;
|
||||
}
|
||||
|
||||
// Leaves only remote resource sets in current search.
|
||||
// 'LocalOnly().RemoteOnly()' removes all possible sets from current search.
|
||||
function NiceResources RemoteOnly(){
|
||||
localFilteredCases.length = 0;
|
||||
}
|
||||
|
||||
// Leaves only resource sets with given subject in the current search.
|
||||
function NiceResources OnlySubject(string subject){
|
||||
local int i;
|
||||
local bool foundGoodCase;
|
||||
foundGoodCase = false;
|
||||
for(i = 0;i < localFilteredCases.length;i ++){
|
||||
if(localFilteredCases[i].subject ~= subject){
|
||||
localFilteredCases[0] = localFilteredCases[i];
|
||||
localFilteredCases.length = 1;
|
||||
foundGoodCase = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!foundGoodCase)
|
||||
localFilteredCases.length = 0;
|
||||
foundGoodCase = false;
|
||||
for(i = 0;i < remoteFilteredCases.length;i ++){
|
||||
if(remoteFilteredCases[i].subject ~= subject){
|
||||
remoteFilteredCases[0] = remoteFilteredCases[i];
|
||||
remoteFilteredCases.length = 1;
|
||||
foundGoodCase = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!foundGoodCase)
|
||||
remoteFilteredCases.length = 0;
|
||||
}
|
||||
|
||||
// Leaves only resource sets with given subject in the current search.
|
||||
function NiceResources OnlyID(string id){
|
||||
local int i;
|
||||
for(i = 0;i < localFilteredCases.length;i ++){
|
||||
localFilteredCases[i].cases =
|
||||
FilterIDCases(localFilteredCases[i].cases, id);
|
||||
}
|
||||
for(i = 0;i < localFilteredCases.length;i ++){
|
||||
remoteFilteredCases[i].cases =
|
||||
FilterIDCases(remoteFilteredCases[i].cases, id);
|
||||
}
|
||||
}
|
||||
|
||||
// Filters given array of 'IDCase's by leaving only case with given ID.
|
||||
private function array<SubjectCase> FilterIDCases( array<IDCase> toFilter,
|
||||
string id){
|
||||
local int i;
|
||||
local bool foundGoodCase;
|
||||
foundGoodCase = false;
|
||||
for(i = 0;i < toFilter.length;i ++){
|
||||
if(toFilter[i].id ~= id){
|
||||
toFilter[0] = toFilter[i];
|
||||
toFilter.length = 1;
|
||||
foundGoodCase = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!foundGoodCase)
|
||||
toFilter.length = 0;
|
||||
return toFilter;
|
||||
}
|
||||
|
||||
function array<NiceResourceSet> ToArray(){
|
||||
local int i, j;
|
||||
local array<NiceResourceSet> resultSets;
|
||||
for(i = 0;i < localFilteredCases.length;i ++){
|
||||
for(j = 0;j < localFilteredCases[i].cases.length;j ++){
|
||||
resultSets[resultSets.length] =
|
||||
localFilteredCases[i].cases[j].resourceSet;
|
||||
}
|
||||
}
|
||||
for(i = 0;i < remoteFilteredCases.length;i ++){
|
||||
for(j = 0;j < remoteFilteredCases[i].cases.length;j ++){
|
||||
resultSets[resultSets.length] =
|
||||
remoteFilteredCases[i].cases[j].resourceSet;
|
||||
}
|
||||
}
|
||||
return resultSets;
|
||||
}*/
|
||||
|
||||
private function bool RemoteShouldReplace( NiceResourceSet localSet,
|
||||
NiceResourceSet remoteSet){
|
||||
if(localSet.localAlwaysOverrides || remoteSet.localAlwaysOverrides)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ptrCompletelyInvalid = 0
|
||||
ptrValidSubject = 1
|
||||
ptrCompletelyValid = 2
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue