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; } } }