package CharacterExport
{
import flash.display.*;
import Defs.CharacterDef;
import djarts.core.*;
import djarts.display.*;
import flash.geom.*;
import flash.utils.*;
public class CharacterTypeGraphic extends MovieClip
{
protected var graphicId;
protected var characterDef:CharacterDef;
protected var force;
protected var sequence;
protected var sequenceLabel;
protected var graphic:MovieClip;
protected var length;
public override function get totalFrames():int
{
return length;
}
protected var externalAnimationData:ExternalAnimationInfo;
public function CharacterTypeGraphic(graphicId, characterDef:CharacterDef, force, sequence, externalAnimationData:ExternalAnimationInfo)
{
this.graphicId = graphicId;
this.characterDef = characterDef;
this.force = force;
this.sequence = sequence;
this.externalAnimationData = externalAnimationData;
this.graphic = GraphicFactory.Instance().GetGraphicByID(graphicId);
if (externalAnimationData)
{
PrepareAnimationPieces();
}
addChild(graphic);
}
public function GetGraphicChildren():Array
{
var ret:Array = [];
for (var i = 0; i < graphic.numChildren; i++)
{
ret.push(graphic.getChildAt(i));
}
return ret;
}
protected var lastFrameSetPieces:Dictionary = new Dictionary();
public function IsForcedPiece(clip:DisplayObject)
{
return (clip in lastFrameSetPieces);
}
public function SetFrame(frame)
{
frame = Math.max(1, Math.min(length, frame));
if (externalAnimationData)
{
CacheManager.Instance().ProcessAnimationData(graphic, sequence, frame, this.externalAnimationData, false, force);
} else {
lastFrameSetPieces = new Dictionary();
makeAllChildrenGoToFrame(graphic, frame, null, graphic, force);
}
}
public function PrepareAnimationPieces()
{
if (externalAnimationData.UsingSingleSequence)
{
for (var i = 0; i < graphic.numChildren; i++)
{
graphic.getChildAt(i).visible = false;
}
for (var i in externalAnimationData.Data[sequence])
{
graphic[externalAnimationData.PieceName(sequence, i)].visible = true;
}
} else {
Utils.RecursivelyStop(graphic, sequence + 1);
}
sequenceLabel = graphic.currentFrameLabel;
if (externalAnimationData.UsingSingleSequence) sequenceLabel = externalAnimationData.SeqNames[sequence];
for (var i in externalAnimationData.Data[sequence])
{
var subclip = graphic[externalAnimationData.PieceName(sequence, i)];
if (subclip)
{
var clipName = null;
for (var j = 0; j < externalAnimationData.Data[sequence][i].name.length; j++)
{
if (externalAnimationData.Data[sequence][i].name[j] != "")
{
clipName = externalAnimationData.Data[sequence][i].name[j];
break;
}
}
var checked = false;
if (clipName != null)
{
checked = this.CheckClipName(subclip, clipName, force, graphic, null, sequence + 1, sequenceLabel);
}
if (subclip is MovieClip && subclip.visible && !checked)
{
this.makeAllChildrenGoToFrame(subclip, sequence + 1, null, graphic, force, sequenceLabel);
}
}
}
this.length = externalAnimationData.Data[sequence][0].present.length;
}
protected function CheckClipName(mc:MovieClip, clipName, force, rootClip, mat:Matrix, frame, rootLabel, keepGoing = true)
{
var nextExceptClip = null;
if (clipName == null) clipName = mc.name;
if (force != null && force[clipName] && force[clipName].hasOwnProperty("color")) {
var ct:ColorTransform = mc.transform.colorTransform;
ct.color = force[clipName].color;
mc.transform.colorTransform = ct;
}
if (force != null && force[clipName] && force[clipName].hasOwnProperty("frame")) {
this.lastFrameSetPieces[mc] = true;
var cForce = force[clipName];
var cFrame = cForce.frame;
var totalTransform:Matrix = mc.transform.matrix.clone();
if (mat) totalTransform.concat(mat);
if (cFrame is String)
{
var l = FindLabel(mc, cFrame);
if (l == -1)
{
var additional = null; //NoFrameCallback(mc, force[clipName],rootLabel);
// def = cForce
// rootLabel = lowerLabel
var lowerLabel = rootLabel.toLowerCase();
try {
mc.gotoAndStop(cForce.blank);
Utils.RecursivelyStop(mc, cForce.blank);
} catch (e:Error)
{
}
if (cFrame != "Default")
{
var additional = GraphicFactory.Instance().GetGraphic(cFrame);
if (!GraphicFactory.Instance().LoadedOK(additional))
{
// problem! this should have been loaded already...
additional = null;
throw new Error("Tried a custom clip that wasn't already loaded!");
} else {
additional = FixClip(additional, cForce, lowerLabel);
additional.name = "wrap_clip_no_play_" + additional.currentFrame;
force["wrap_clip_no_play_" + additional.currentFrame] = {frame:additional.currentFrame, keep_going:false};
}
}
if (additional)
{
var belowChildren:Array;
var aboveChildren:Array;
if (force.search_for_subreplacing && clipName in force.search_for_subreplacing)
{
var testField = "__copy_clips_for_" + clipName + "__";
if (testField in mc)
{
belowChildren = mc[testField].below;
aboveChildren = mc[testField].above;
} else {
for (var f = 1; f <= mc.totalFrames; f++)
{
Utils.RecursivelyStop(mc, f);
if (mc.currentFrameLabel != cForce.blank)
{
for (var i = 0; i < mc.numChildren; i++)
{
var child = mc.getChildAt(i);
if (child is MovieClip)
{
var childName = child.name;
if (child.name in force)
{
if (!belowChildren) belowChildren = [];
belowChildren.push({name:child.name,
transform:child.transform,
tag:"__only_frame_label_" + force[child.name].blank});
}
} else {
break;
}
}
if (i < mc.numChildren)
{
for (var i = mc.numChildren - 1; i >= 0; i--)
{
var child = mc.getChildAt(i);
if (child is MovieClip)
{
var childName = child.name;
if (child.name in force)
{
if (!aboveChildren) aboveChildren = [];;
aboveChildren.push({name:child.name,
transform:child.transform,
tag:"__only_frame_label_" + force[child.name].blank});
}
} else {
break;
}
}
}
break;
}
}
mc[testField] = {above:aboveChildren, below:belowChildren};
}
}
if (cForce.blank)
{
try {
mc.gotoAndStop(cForce.blank);
} catch (e:Error) {}
if (mc.currentFrameLabel == cForce.blank)
{
for (var i = 0; i < mc.numChildren; i++)
{
var child = mc.getChildAt(i);
if (child is MovieClip && child.name in cForce)
{
// leave it!
} else {
mc.removeChildAt(i);
i--;
}
}
}
}
var prevChild = mc.getChildByName(additional.name);
if (prevChild)
{
mc.removeChild(prevChild);
}
if (belowChildren)
{
var tmp = additional;
additional = new MovieClip();
for (var i = 0; i < belowChildren.length; i++)
{
var newClip:MovieClip = new MovieClip();
newClip.name = belowChildren[i].name;
newClip.transform = belowChildren[i].transform;
newClip[belowChildren[i].tag] = true;
additional.addChild(newClip);
}
additional.addChild(tmp);
additional[tmp.name] = tmp;
nextExceptClip = tmp;
} else {
mc[additional.name] = additional;
nextExceptClip = additional;
}
if (aboveChildren)
{
for (var i = aboveChildren.length - 1; i >= 0; i--)
{
var newClip:MovieClip = new MovieClip();
newClip.name = aboveChildren[i].name;
newClip.transform = aboveChildren[i].transform;
newClip[aboveChildren[i].tag] = true;
additional.addChild(newClip);
}
}
mc.addChild(additional);
if (force[clipName].keep_going)
{
makeAllChildrenGoToFrame(additional, frame, totalTransform, rootClip, force, rootLabel, nextExceptClip);
}
nextExceptClip = additional;
} else {
Utils.RecursivelyStop(mc, 1);
}
} else {
if (l != -1) mc.gotoAndStop(l);
}
} else {
mc.gotoAndStop(force[clipName].frame);
}
if (force[clipName].keep_going && keepGoing)
{
makeAllChildrenGoToFrame(mc, frame, totalTransform, rootClip, force, "", nextExceptClip);
}
return true;
}
return false;
}
/* m: clip to set all children to a certain frame
* f: frame to set the children to
* mat: the current total transform to reach this point in the hierarchy
* force: same as above
*/
private function makeAllChildrenGoToFrame(m:MovieClip, f:int, mat:Matrix, rootClip, force = null, rootLabel = "", exceptClip = null):void
{
for (var i:int = 0; i < m.numChildren; i++) {
var c:* = m.getChildAt(i);
if (c is MovieClip && c != exceptClip) {
var mc:MovieClip = c as MovieClip;
// the total transformation applied to this clip from all parent transforms
var totalTransform:Matrix;
if (!CheckClipName(mc, null, force, rootClip, mat, f, rootLabel))
{
// this clip wasn't specified as being on any particular frame
if (!c.frameAdded) c.frameAdded = f;
c.gotoAndStop(((f - c.frameAdded) % c.totalFrames) + 1);
totalTransform = mc.transform.matrix.clone();
if (mat) totalTransform.concat(mat);
makeAllChildrenGoToFrame(c, f, totalTransform, rootClip, force, rootLabel);
// we upscale the clip before rendering just in case
// the clip has been scaled up (we don't want to lose resolution)
var upscale = 2.0;
if (mc.name.indexOf("SEPARATE") != -1) {
throw new Error("SEPARATE not supported!");
/*
var n = mc.name;
var localTransform = new Matrix(1.0 / upscale, 0, 0, 1.0 / upscale);
localTransform.concat(totalTransform);
if (!cacheSeparate.hasOwnProperty(n)) {
if (mc.name.indexOf("BYFRAME") != -1)
{
cacheSeparate[n] = new CacheByFrame();
cacheSeparate[n].buildCacheFromClip(mc, -1, null, new Matrix(upscale, 0, 0, upscale));
} else {
cacheSeparate[n] = new CachedMovieClip();
cacheSeparate[n].buildCacheFromClip(mc, -1, true, null, new Matrix(upscale, 0, 0, upscale));
}
// render this clip as if it has not been transformed
cacheSeparate[n].gotoAndPlay(1);
positionData[n] = [];
cacheSeparate[n].name = n;
addChild(cacheSeparate[n]);
if (n.indexOf("BACK") != -1) {
setChildIndex(cacheSeparate[n], 0);
}
cacheSeparate[n].transform.matrix = localTransform;
this[n] = cacheSeparate[n];
this.setPropertyIsEnumerable(n, true);
}
positionData[n][currentFrame] = localTransform;
mc.visible = false;
*/
}
}
}
}
}
protected function FindLabel(mc:MovieClip, name)
{
var l:Array = mc.currentLabels;
for (var i in l)
{
if (l[i].name == name) return l[i].frame;
}
if (("__only_frame_label_" + name) in mc)
{
return 1;
}
return -1;
}
protected function FixClip(mc, def, rootLabel)
{
if (rootLabel.indexOf("right") != -1 || rootLabel.indexOf("left") != -1)
{
mc.gotoAndStop(1);
}
if (rootLabel.indexOf("back") != -1)
{
mc.gotoAndStop(2);
}
if (rootLabel.indexOf("front") != -1)
{
mc.gotoAndStop(3);
}
return mc;
}
}
}