// This function will parse a possible series of tags void Parse(string eS, PT_XMLHashtable eH) { eS = eS.Trim(); while(eS.Length > 0) { eS = ParseTag(eS, eH); eS = eS.Trim(); } }
public PT_XMLReader xmlr; // Just like Deck, this has an PT_XMLReader #endregion Fields #region Methods // This function is called to read in the LayoutXML.xml file public void ReadLayout(string xmlText) { xmlr = new PT_XMLReader(); xmlr.Parse(xmlText); // The XML is parsed xml = xmlr.xml["xml"][0]; // And xml is set as a shortcut to the XML // Read in the multiplier, which sets card spacing multiplier.x = float.Parse(xml["multiplier"][0].att("x")); multiplier.y = float.Parse(xml["multiplier"][0].att("y")); // Read in the slots SlotDef tSD; // slotsX is used as a shortcut to all the <slot>s PT_XMLHashList slotsX = xml["slot"]; for (int i=0; i<slotsX.Count; i++) { tSD = new SlotDef(); // Create a new SlotDef instance if (slotsX[i].HasAtt("type")) { // If this <slot> has a type attribute parse it tSD.type = slotsX[i].att("type"); } else { // If not, set its type to "slot" tSD.type = "slot"; } // Various attributes are parsed into numerical values tSD.x = float.Parse( slotsX[i].att("x") ); tSD.y = float.Parse( slotsX[i].att("y") ); tSD.pos = new Vector3( tSD.x*multiplier.x, tSD.y*multiplier.y, 0 ); // Sorting Layers tSD.layerID = int.Parse( slotsX[i].att("layer") ); // In this game, the Sorting Layers are named 1, 2, 3, ...through 10 // This converts the number of the layerID into a text layerName tSD.layerName = tSD.layerID.ToString(); // The layers are used to make sure that the correct cards are // on top of the others. In Unity 2D, all of our assets are // effectively at the same Z depth, so sorting layers are used // to differentiate between them. // pull additional attributes based on the type of each <slot> switch (tSD.type) { case "slot": // ignore slots that are just of the "slot" type break; case "drawpile": // The drawPile xstagger is read but not actually used in Bartok tSD.stagger.x = float.Parse( slotsX[i].att("xstagger") ); drawPile = tSD; break; case "discardpile": discardPile = tSD; break; case "target": // The target card has a different layer from discardPile target = tSD; break; case "hand": // Information for each player's hand tSD.player = int.Parse( slotsX[i].att("player") ); tSD.rot = float.Parse( slotsX[i].att("rot") ); slotDefs.Add (tSD); break; } } }
public PT_XMLReader xmlr; // Just like Deck, this has a PT_XMLReader #endregion Fields #region Methods // This function is called to read in the LayoutXML.xml file public void ReadLayout(string xmlText) { xmlr = new PT_XMLReader(); xmlr.Parse(xmlText); // The XML is parsed xml = xmlr.xml["xml"][0]; // And xml is set as a shortcut to the XML // Read in the multiplier, which sets card spacing multiplier.x = float.Parse(xml["multiplier"][0].att("x")); multiplier.y = float.Parse(xml["multiplier"][0].att("y")); // Read in the slots SlotDef tSD; // slotsX is used as a shortcut to all the <slot>s PT_XMLHashList slotsX = xml["slot"]; for (int i=0; i<slotsX.Count; i++) { tSD = new SlotDef(); // Create a new SlotDef instance if (slotsX[i].HasAtt("type")) { // If this <slot> has a type attribute parse it tSD.type = slotsX[i].att("type"); } else { // If not, set its type to "slot"; it's a tableau card tSD.type = "slot"; } // Various attributes are parsed into numerical values tSD.x = float.Parse( slotsX[i].att("x") ); tSD.y = float.Parse( slotsX[i].att("y") ); tSD.layerID = int.Parse( slotsX[i].att("layer") ); // This converts the number of the layerID into a text layerName tSD.layerName = sortingLayerNames[ tSD.layerID ]; // The layers are used to make sure that the correct cards are // on top of the others. In Unity 2D, all of our assets are // effectively at the same Z depth, so the layer is used // to differentiate between them. switch (tSD.type) { // pull additional attributes based on the type of this <slot> case "slot": tSD.faceUp = (slotsX[i].att("faceup") == "1"); tSD.id = int.Parse( slotsX[i].att("id") ); if (slotsX[i].HasAtt("hiddenby")) { string[] hiding = slotsX[i].att("hiddenby").Split(','); foreach( string s in hiding ) { tSD.hiddenBy.Add ( int.Parse(s) ); } } slotDefs.Add(tSD); break; case "drawpile": tSD.stagger.x = float.Parse( slotsX[i].att("xstagger") ); drawPile = tSD; break; case "discardpile": discardPile = tSD; break; } } }
public void ReadLayout(string xmlText) { xmlr = new PT_XMLReader (); xmlr.Parse (xmlText); xml = xmlr.xml ["xml"][0]; multiplier.x = float.Parse (xml ["multiplier"] [0].att ("x")); multiplier.y = float.Parse (xml ["multiplier"] [0].att ("y")); SlotDef tSD; PT_XMLHashList slotsX = xml ["slot"]; for (int i = 0; i < slotsX.Count; i++) { tSD = new SlotDef (); if(slotsX[i].HasAtt("type")){ tSD.type = slotsX[i].att("type"); }else{ tSD.type = "slot"; } tSD.x = float.Parse(slotsX[i].att("x")); tSD.y = float.Parse(slotsX[i].att("y")); tSD.layerID = int.Parse(slotsX[i].att("layer")); tSD.layerName = sortLayerNames[tSD.layerID]; switch(tSD.type){ case "slot": tSD.faceUp = (slotsX[i].att ("faceup") == "1"); tSD.id = int.Parse (slotsX[i].att ("id")); if(slotsX[i].HasAtt ("hiddenby")){ string[] hiding = slotsX[i].att ("hiddenby").Split (','); foreach(string s in hiding){ tSD.hiddenBy.Add(int.Parse(s)); } } slotDefs.Add (tSD); break; case "drawpile": tSD.stagger.x = float.Parse( slotsX[i].att ("xstagger") ); drawPile = tSD; break; case "discardpile": discardPile = tSD; break; } } }
public void ReadLayout(string xmlText) { xmlr = new PT_XMLReader (); xmlr.Parse (xmlText); xml = xmlr.xml ["xml"] [0]; multiplier.x = float.Parse(xml["multiplier"][0].att ("x")); multiplier.y = float.Parse(xml["multiplier"][0].att ("y")); SlotDef tSD; PT_XMLHashList slotsX = xml ["slot"]; for (int i = 0; i < slotsX.Count; i++) { tSD = new SlotDef(); if(slotsX[i].HasAtt("type")) tSD.type = slotsX[i].att("type"); else tSD.type = "slot"; tSD.x = float.Parse (slotsX[i].att("x")); tSD.y = float.Parse (slotsX[i].att("y")); tSD.pos = new Vector3 (tSD.x * multiplier.x, tSD.y * multiplier.y, 0); tSD.layerID = int.Parse ( slotsX[i].att ("layer")); tSD.layerName = tSD.layerID.ToString(); switch(tSD.type){ case "slot": break; case "drawpile": tSD.stagger.x = float.Parse(slotsX[i].att("xstagger")); drawPile = tSD; break; case "discardpile": discardPile = tSD; break; case "target": target = tSD; break; case "hand": tSD.player = int.Parse(slotsX[i].att ("player")); tSD.rot = float.Parse(slotsX[i].att ("rot")); slotDefs.Add(tSD); break; } } }
static public Shot ParseShotXML(PT_XMLHashtable xHT) { Shot sh = new Shot (); sh.position.x = float.Parse(xHT.att("x")); sh.position.y = float.Parse(xHT.att("y")); sh.position.z = float.Parse(xHT.att("z")); sh.rotation.x = float.Parse(xHT.att("qx")); sh.rotation.y = float.Parse(xHT.att("qy")); sh.rotation.z = float.Parse(xHT.att("qz")); sh.rotation.w = float.Parse(xHT.att("qw")); sh.target.x = float.Parse(xHT.att("tx")); sh.target.y = float.Parse(xHT.att("ty")); sh.target.z = float.Parse(xHT.att("tz")); return (sh); }
public void Add(PT_XMLHashtable eH) { list.Add(eH); }
public void Parse(string eS) { xmlText = eS; xml = new PT_XMLHashtable(); Parse(eS, xml); }
// Build a room from an XML <room> entry public void BuildRoom(PT_XMLHashtable room) { // Destroy any old Tiles foreach (Transform t in tileAnchor) // Clear out old tiles // ^ You can iterate over a Transform to get its children { Destroy(t.gameObject); } // Move the Mage out of the way Mage.S.pos = Vector3.left * 1000; // ^ This keeps the Mage from accidentally triggering OnTriggerExit() on // a Portal. In my testing, I found that OnTriggerExit was being called // at strange times. Mage.S.ClearInput(); // Cancel any active mouse input and drags string rNumStr = room.att("num"); // Get the texture names for the floors and walls from <room> attributes string floorTexStr = room.att("floor"); string wallTexStr = room.att("wall"); // Split the room into rows of tiles based on carriage returns in the // Rooms.xml file string[] roomRows = room.text.Split('\n'); // Trim tabs from the beginnings of lines. However, we're leaving spaces // and underscores to allow for non-rectangular rooms. for (int i = 0; i < roomRows.Length; i++) { roomRows[i] = roomRows[i].Trim('\t'); } // Clear the tiles Array tiles = new Tile[100, 100]; // Arbitrary max room size is 100x100 // Declare a number of local fields that we'll use later Tile ti; string type, rawType, tileTexStr; GameObject go; int height; float maxY = roomRows.Length - 1; List <Portal> portals = new List <Portal>(); // These loops scan through each tile of each row of the room for (int y = 0; y < roomRows.Length; y++) { for (int x = 0; x < roomRows[y].Length; x++) { // Set defaults height = 0; tileTexStr = floorTexStr; // Get the character representing the tile type = rawType = roomRows[y][x].ToString(); switch (rawType) { case " ": // empty space case "_": // empty space // Just skip over empty space continue; case ".": // default floor // Keep type="." break; case "|": // default wall height = 1; break; default: // Anything else will be interpreted as floor type = "."; break; } // Set the texture for floor or wall based on <room> attributes if (type == ".") { tileTexStr = floorTexStr; } else if (type == "|") { tileTexStr = wallTexStr; } // Instantiate a new TilePrefab go = Instantiate(tilePrefab) as GameObject; ti = go.GetComponent <Tile>(); // Set the parent Transform to tileAnchor ti.transform.parent = tileAnchor; // Set the position of the tile ti.pos = new Vector3(x, maxY - y, 0); tiles[x, y] = ti; // Add ti to the tiles 2D Array // Set the type, height, and texture of the Tile ti.type = type; ti.height = height; ti.tex = tileTexStr; // More to come here... // If the type is still rawType, continue to the next iteration if (rawType == type) { continue; } // Check for specific entities in the room switch (rawType) // 1 { case "X": // Starting position for the Mage // Mage.S.pos = ti.pos; // Uses the Mage Singleton if (firstRoom) { Mage.S.pos = ti.pos; // Uses the Mage Singleton roomNumber = rNumStr; // ^ Setting roomNumber now keeps any portals from // moving the Mage to them in this first room. firstRoom = false; } break; case "0": // Numbers are room portals (up to F in hexadecimal) case "1": // This allows portals to be placed in the Rooms.xml file case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": case "A": case "B": case "C": case "D": case "E": case "F": // Instantiate a Portal GameObject pGO = Instantiate(portalPrefab) as GameObject; Portal p = pGO.GetComponent <Portal>(); p.pos = ti.pos; p.transform.parent = tileAnchor; // ^ Attaching this to the tileAnchor means that the Portal // will be Destroyed when a new room is built p.toRoom = rawType; portals.Add(p); break; default: // Try to see if there's an Enemy for that letter Enemy en = EnemyFactory(rawType); if (en == null) { break; // If there's not one, break out } // Set up the new Enemy en.pos = ti.pos; // Make en a child of tileAnchor so it's deleted when the // next room is loaded. en.transform.parent = tileAnchor; en.typeString = rawType; break; } /// will be more } } // Position the Mage foreach (Portal p in portals) { // If p.toRoom is the same as the room number the Mage just exited, // then the Mage should enter this room through this Portal // Alternatively, if firstRoom == true and there was no X in the // room (as a default Mage starting point), move the Mage to this // Portal as a backup measure (if, for instance, you want to just // load room number "5") if (p.toRoom == roomNumber || firstRoom) { // ^ If there's an X in the room, firstRoom will be set to false // by the time the code gets here Mage.S.StopWalking(); // Stop any Mage movement Mage.S.pos = p.pos; // Move _Mage to this Portal location // _Mage maintains her facing from the previous room, so there // is no need to rotate her in order for her to enter this room // facing the right direction. p.justArrived = true; // ^ Tell the Portal that Mage has just arrived. firstRoom = false; // ^ Stops a 2nd Portal in this room from moving the Mage to it } } // Finally assign the roomNumber roomNumber = rNumStr; }
public void BuildRoom(PT_XMLHashtable room) { foreach (Transform t in tileAnchor) { Destroy(t.gameObject); } Mage.S.pos = Vector3.left * 1000; Mage.S.ClearInput(); string rNumStr = room.att("num"); string floorTexStr = room.att("floor"); string wallTexStr = room.att("wall"); string[] roomRows = room.text.Split('\n'); for (int i = 0; i < roomRows.Length; i++) { roomRows[i] = roomRows[i].Trim('\t'); } tiles = new Tile[100, 100]; Tile ti; string type, rawType, tileTexStr; GameObject go; int height; float maxY = roomRows.Length - 1; List <Portal> portals = new List <Portal>(); for (int y = 0; y < roomRows.Length; y++) { for (int x = 0; x < roomRows[y].Length; x++) { height = 0; tileTexStr = floorTexStr; type = rawType = roomRows[y][x].ToString(); switch (rawType) { case " ": case "_": continue; case ".": break; case "|": height = 1; break; default: type = "."; break; } if (type == ".") { tileTexStr = floorTexStr; } else if (type == "|") { tileTexStr = wallTexStr; } go = Instantiate(tilePrefab) as GameObject; ti = go.GetComponent <Tile>(); ti.transform.parent = tileAnchor; ti.pos = new Vector3(x, maxY - y, 0); tiles[x, y] = ti; ti.type = type; ti.height = height; ti.tex = tileTexStr; if (rawType == type) { continue; } switch (rawType) { case "X": if (firstRoom) { Mage.S.pos = ti.pos; roomNumber = rNumStr; firstRoom = false; } break; case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": case "A": case "B": case "C": case "D": case "E": case "F": GameObject pGO = Instantiate(portalPrefab) as GameObject; Portal p = pGO.GetComponent <Portal>(); p.pos = ti.pos; p.transform.parent = tileAnchor; p.toRoom = rawType; portals.Add(p); break; default: Enemy en = EnemyFactory(rawType); if (en == null) { break; } en.pos = ti.pos; en.transform.parent = tileAnchor; en.typeString = rawType; break; } } } foreach (Portal p in portals) { if (p.toRoom == roomNumber || firstRoom) { Mage.S.StopWalking(); Mage.S.pos = p.pos; p.justArrived = true; firstRoom = false; } } roomNumber = rNumStr; }
public void ReadLayout(string xmlText) { xmlr = new PT_XMLReader(); xmlr.Parse(xmlText); xml = xmlr.xml["xml"][0]; multiplier.x = float.Parse(xml["multiplier"][0].att("x"), CultureInfo.InvariantCulture); multiplier.y = float.Parse(xml["multiplier"][0].att("y"), CultureInfo.InvariantCulture); SlotDef tSD; PT_XMLHashList slotsX = xml["slot"]; for (int i = 0; i < slotsX.Count; i++) { tSD = new SlotDef(); if (slotsX[i].HasAtt("type")) { tSD.type = slotsX[i].att("type"); } else { tSD.type = "slot"; } tSD.x = float.Parse(slotsX[i].att("x"), CultureInfo.InvariantCulture); tSD.y = float.Parse(slotsX[i].att("y"), CultureInfo.InvariantCulture); tSD.pos = new Vector3(tSD.x * multiplier.x, tSD.y * multiplier.y, 0); tSD.layerID = int.Parse(slotsX[i].att("layer"), CultureInfo.InvariantCulture); tSD.layerName = tSD.layerID.ToString(); switch (tSD.type) { case "slot": { break; } case "drawpile": { tSD.stagger.x = float.Parse(slotsX[i].att("xstagger"), CultureInfo.InvariantCulture); drawPile = tSD; break; } case "discardpile": { discardPile = tSD; break; } case "target": { target = tSD; break; } case "hand": { tSD.player = int.Parse(slotsX[i].att("player"), CultureInfo.InvariantCulture); tSD.rot = float.Parse(slotsX[i].att("rot"), CultureInfo.InvariantCulture); slotDefs.Add(tSD); break; } } } }
string ParseTag(string eS, PT_XMLHashtable eH) { int ndx = eS.IndexOf("<"); int end, end1, end2, end3; if (ndx == -1) { end3 = eS.IndexOf(">"); if (end3 == -1) { eS = eS.Trim(); eH.text = eS; } return(""); } if (eS[ndx + 1] == '?') { int ndx2 = eS.IndexOf("?>"); string header = eS.Substring(ndx, ndx2 - ndx + 2); eH.header = header; return(eS.Substring(ndx2 + 2)); } if (eS[ndx + 1] == '!') { int ndx2 = eS.IndexOf("-->"); string comment = eS.Substring(ndx, ndx2 - ndx + 3); if (SHOW_COMMENTS) { Debug.Log("XMl Comment: " + comment); } return(eS.Substring(ndx2 + 3)); } end1 = eS.IndexOf(" ", ndx); end2 = eS.IndexOf("/", ndx); end3 = eS.IndexOf(">", ndx); if (end1 == -1) { end1 = int.MaxValue; } if (end2 == -1) { end2 = int.MaxValue; } if (end3 == -1) { end3 = int.MaxValue; } end = Mathf.Min(end1, end2, end3); string tag = eS.Substring(ndx + 1, end - ndx - 1); if (!eH.ContainsKey(tag)) { eH[tag] = new PT_XMLHashList(); } PT_XMLHashList arrL = eH[tag] as PT_XMLHashList; PT_XMLHashtable thisHash = new PT_XMLHashtable(); arrL.Add(thisHash); string atts = ""; if (end1 < end3) { try { atts = eS.Substring(end1, end3 - end1); } catch (System.Exception ex) { Debug.LogException(ex); Debug.Log("break"); } } string att, val; int eqNdx, spNdx; while (atts.Length > 0) { atts = atts.Trim(); eqNdx = atts.IndexOf("="); if (eqNdx == -1) { break; } att = atts.Substring(0, eqNdx); spNdx = atts.IndexOf(" ", eqNdx); if (spNdx == -1) { val = atts.Substring(eqNdx + 1); if (val[val.Length - 1] == '/') { val = val.Substring(0, val.Length - 1); } atts = ""; } else { val = atts.Substring(eqNdx + 1, spNdx - eqNdx - 2); atts = atts.Substring(spNdx); } val = val.Trim('\"'); thisHash.attSet(att, val); } string subs = ""; string leftoverString = ""; bool singleLine = (end2 == end3 - 1); if (!singleLine) { int close = eS.IndexOf("</" + tag + ">"); if (close == -1) { Debug.Log("XMLReader ERROR: XML not well formed. Closing tag </" + tag + "> missing."); return(""); } subs = eS.Substring(end3 + 1, close - end3 - 1); leftoverString = eS.Substring(eS.IndexOf(">", close) + 1); } else { leftoverString = eS.Substring(end3 + 1); } subs = subs.Trim(); if (subs.Length > 0) { Parse(subs, thisHash); } leftoverString = leftoverString.Trim(); return(leftoverString); }
// This function is called to read in the LayoutXML.xml file public void ReadLayout(string xmlText) { xmlr = new PT_XMLReader(); xmlr.Parse(xmlText); // The XML is parsed xml = xmlr.xml["xml"][0]; // And xml is set as a shortcut to the XML // Read in the multiplier, which sets card spacing multiplier.x = float.Parse(xml["multiplier"][0].att("x")); multiplier.y = float.Parse(xml["multiplier"][0].att("y")); // Read in the slots SlotDef tSD; // slotsX is used as a shortcut to all the <slot>s PT_XMLHashList slotsX = xml["slot"]; for (int i = 0; i < slotsX.Count; i++) { tSD = new SlotDef(); // Create a new SlotDef instance if (slotsX[i].HasAtt("type")) { // If this <slot> has a type attribute parse it tSD.type = slotsX[i].att("type"); } else { // If not, set its type to "slot"; it's a card in the rows tSD.type = "slot"; } // Various attributes are parsed into numerical values tSD.x = float.Parse(slotsX[i].att("x")); tSD.y = float.Parse(slotsX[i].att("y")); tSD.layerID = int.Parse(slotsX[i].att("layer")); // This converts the number of the layerID into a text layerName tSD.layerName = sortingLayerNames[tSD.layerID]; switch (tSD.type) { // pull additional attributes based on the type of this <slot> case "slot": tSD.faceUp = (slotsX[i].att("faceup") == "1"); tSD.id = int.Parse(slotsX[i].att("id")); if (slotsX[i].HasAtt("hiddenby")) { string[] hiding = slotsX[i].att("hiddenby").Split(','); foreach (string s in hiding) { tSD.hiddenBy.Add(int.Parse(s)); } } slotDefs.Add(tSD); break; case "drawpile": tSD.stagger.x = float.Parse(slotsX[i].att("xstagger")); drawPile = tSD; break; case "discardpile": discardPile = tSD; break; } } }
public void ReadLayout(string xmlText) { xmlr = new PT_XMLReader(); xmlr.Parse(xmlText); xml = xmlr.xml["xml"][0]; multiplier.x = float.Parse(xml["multiplier"][0].att("x")); multiplier.y = float.Parse(xml["multiplier"][0].att("y")); SlotDef tSD; PT_XMLHashList slotsX = xml["slot"]; for (int i = 0; i < slotsX.Count; i++) { tSD = new SlotDef(); if (slotsX[i].HasAtt("type")) { tSD.type = slotsX[i].att("type"); } else { tSD.type = "slot"; } tSD.x = float.Parse(slotsX[i].att("x")); tSD.y = float.Parse(slotsX[i].att("y")); tSD.layerID = int.Parse(slotsX[i].att("layer")); tSD.layerName = sortingLayerNames[tSD.layerID]; switch (tSD.type) { // pull additional attributes based on the type of this <slot> case "slot": tSD.faceUp = (slotsX[i].att("faceup") == "1"); tSD.id = int.Parse(slotsX[i].att("id")); if (slotsX[i].HasAtt("hiddenby")) { string[] hiding = slotsX[i].att("hiddenby").Split(','); foreach (string s in hiding) { tSD.hiddenBy.Add(int.Parse(s)); } } slotDefs.Add(tSD); break; case "drawpile": tSD.stagger.x = float.Parse(slotsX[i].att("xstagger")); drawPile = tSD; break; case "discardpile": discardPile = tSD; break; } } }
// Bartok calls this method to read in the BartokLayoutXML.xml file public void ReadLayout(string xmlText) { xmlr = new PT_XMLReader(); xmlr.Parse(xmlText); // The XML is parsed xml = xmlr.xml["xml"][0]; // And xml is set as a shortcut to the XML // Read in the multiplier, which sets card spacing multiplier.x = float.Parse(xml["multiplier"][0].att("x")); multiplier.y = float.Parse(xml["multiplier"][0].att("y")); // Read in the slots SlotDef tSD; // slotsX is used as a shortcut to all the <slot>s PT_XMLHashList slotsX = xml["slot"]; for (int i = 0; i < slotsX.Count; i++) { tSD = new SlotDef(); // Create a new SlotDef instance if (slotsX[i].HasAtt("type")) { // If this <slot> has a type attribute parse it tSD.type = slotsX[i].att("type"); } else { // If not, set its type to "slot"; it's a card in the rows tSD.type = "slot"; } // Various attributes are parsed into numerical values tSD.x = float.Parse(slotsX[i].att("x")); tSD.y = float.Parse(slotsX[i].att("y")); tSD.pos = new Vector3(tSD.x * multiplier.x, tSD.y * multiplier.y, 0); // Sorting Layers tSD.layerID = int.Parse(slotsX[i].att("layer")); tSD.layerName = tSD.layerID.ToString(); // pull additional attributes based on the type of each <slot> switch (tSD.type) { case "slot": // ignore slots that are just of the "slot" type break; case "drawpile": tSD.stagger.x = float.Parse(slotsX[i].att("xstagger")); drawPile = tSD; break; case "discardpile": discardPile = tSD; break; case "target": target = tSD; break; case "hand": tSD.player = int.Parse(slotsX[i].att("player")); tSD.rot = float.Parse(slotsX[i].att("rot")); slotDefs.Add(tSD); break; } } }
//从XML<room>入口建立一个room对象 public void BuildRoom(PT_XMLHashtable room) { //销毁旧的Tiles foreach (Transform t in tileAnchor) { Destroy(t.gameObject); } //Mage离开 //Mage.S.pos = Vector3.left * 1000; GameObject.FindWithTag("Mage").transform.position = Vector3.left * 1000; Mage.S.ClearInput(); //---------------------------------------------------------------- string rNumStr = room.att("num"); //从<room>属性获取floors和walls的文本名 string floorTexStr = room.att("floor"); string wallTexStr = room.att("wall"); //基于Rooms.xml文件中返回的carriage值将room分行 string[] roomRows = room.text.Split('\n'); //从每行起始修剪制表符 for (int i = 0; i < roomRows.Length; i++) { roomRows[i] = roomRows[i].Trim('\t'); } //清空tiles数组 tiles = new Tile[100, 100]; //一些局部变量 Tile ti; string type, rawType, tileTexStr; GameObject go; int height; float maxY = roomRows.Length - 1; List <Portal> portals = new List <Portal>(); //循环遍历每个room的每行中的tile for (int y = 0; y < roomRows.Length; y++) { for (int x = 0; x < roomRows[y].Length; x++) { //设置默认值 height = 0; tileTexStr = floorTexStr; //获取代表tile的字符 type = rawType = roomRows[y][x].ToString(); switch (rawType) { case " ": //跳过空格 case "_": continue; case ".": //默认floor break; case "|": //默认wall height = 1; break; default: //其他任何都作为floor type = "."; break; } //基于<room>属性设置floors和walls文本 if (type == ".") { tileTexStr = floorTexStr; } else if (type == "|") { tileTexStr = wallTexStr; } //初始化新的TilePrefab对象 go = Instantiate(tilePrefab) as GameObject; ti = go.GetComponent <Tile>(); //设置父Transform为tileAnchor ti.transform.parent = tileAnchor; //设置tile坐标 ti.pos = new Vector3(x, maxY - y, 0); tiles[x, y] = ti; //设置Tile的类型,高度和文本 ti.type = type; ti.height = height; ti.tex = tileTexStr; //如果类型是rawType,则继续下一个操作 if (rawType == type) { continue; } //检查room中指定的对象实例 switch (rawType) { //Mage的起始位置 case "X": //出错代码:Mage.S.pos = ti.pos; //报错信息:单例化无法设置 //解决措施: //GameObject.FindWithTag("Mage").transform.position = ti.pos; if (firstRoom) { //Mage.S.pos = ti.pos; GameObject.FindWithTag("Mage").transform.position = ti.pos; roomNumber = rNumStr; firstRoom = false; } break; case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": case "A": case "B": case "C": case "D": case "E": case "F": //实例化Portal,设置地点,归于tileAnchor下,赋通向房间的值, GameObject pGo = Instantiate(portalPrefab) as GameObject; //魔法阵的z方向需为负值,否则与地面齐平被覆盖 //产生问题:设置魔法阵后不可单击魔法门位置产生标记 //问题分析:Mage.cs内关于魔法阵识别问题,即便MouseTap()内判断 //解决方案:将魔法阵PortalPrefab_MagicCircle的tag设置为Ground,即可在MouseTap内将其归类于Ground进行识别 Portal p = pGo.GetComponent <Portal>(); p.pos = ti.pos + new Vector3(0, 0, -0.3f); p.transform.parent = tileAnchor; p.toRoom = rawType; portals.Add(p); break; default: //确认是否有Enemy对应的字母 Enemy en = EnemyFactory(rawType); if (en == null) { break; } //设置新的Enemy en.pos = ti.pos; en.transform.parent = tileAnchor; en.typeString = rawType; break; } // } } //定位Mage foreach (Portal p in portals) { //如果p.toRoom与Mage刚离开的房间号相同,则Mage应从该入口交替进入房间 //此外,若firstroom==true且房间内无X坐标,则应该让Mage移动到该入口作为备用手段 if (p.toRoom == roomNumber || firstRoom) { //若房间内没有X坐标,则将firstroom设置为false Mage.S.StopWalking(); Mage.S.pos = p.pos; //Mage保持面向先前的房间 p.justArrived = true; //通知Portal,Mage刚进入 firstRoom = false; // } } //最后分配roomNumber roomNumber = rNumStr; }
// ------------------------------------- // -------------- METODOS -------------- // ------------------------------------- /* * carga el tablero definido en el xml pasado por paramtero */ public void readLayout(string xmlText) { //Antes de hacer nada, reseteamos el tablero this.resetLayout(); xmlr = new PT_XMLReader(); xmlr.Parse(xmlText); xml = xmlr.xml["xml"][0]; //1.- Definiciones de las dimensiones PT_XMLHashtable dimensions = xml["dimensions"][0]; //1.1 - tablero this.size_x = int.Parse(dimensions ["board"][0].att("length_x")); this.size_z = int.Parse(dimensions ["board"][0].att("length_z")); this.scale = float.Parse(dimensions ["board"][0].att("scale")); //1.2 - bloque this.blockSize = float.Parse(dimensions ["block"][0].att("size")); this.blockSeparation = float.Parse(dimensions ["block"][0].att("separation")); //1.3 - cover this.coverSize = float.Parse(dimensions ["cover"][0].att("size")); //1.4 - robot this.robotHeight = float.Parse(dimensions ["robot"][0].att("height")); //2.- Celdas por defecto this.default_height = int.Parse(xml ["board"] [0].att("default_height")); this.initBoard(this.default_height, this.size_x, this.size_z); this.emptyCurrentBoard(); //3.- Definimos de las celdas PT_XMLHashList tileX = xml["board"][0]["tile"]; for (int i = 0; i < tileX.Count; i++) { int x, z; x = int.Parse(tileX[i].att("x")); z = int.Parse(tileX[i].att("z")); this.board_def[x, z].height = int.Parse(tileX[i].att("height")); string attr = (tileX[i].HasAtt("attr")) ? tileX[i].att("attr") : "none"; switch (attr) { case "goal": this.board_def[x, z].type = TileType.goal; Director.S.totalGoals++; break; default: this.board_def[x, z].type = TileType.normal; break; } this.board_def[x, z].isOn = false; //leemos movimientos. string mvto_t = (tileX[i].HasAtt("mvto")) ? tileX[i].att("mvto") : "none"; switch (mvto_t) { case "h": this.board_def[x, z].typeMvto = tipoMovimiento.horizontal; this.board_def[x, z].nSteps = int.Parse(tileX[i].att("nsteps")); this.board_def[x, z].createStates(); break; case "v": this.board_def[x, z].typeMvto = tipoMovimiento.vertical; this.board_def[x, z].nSteps = int.Parse(tileX[i].att("nsteps")); this.board_def[x, z].createStates(); break; case "f": this.board_def[x, z].typeMvto = tipoMovimiento.frente; this.board_def[x, z].nSteps = int.Parse(tileX[i].att("nsteps")); this.board_def[x, z].createStates(); break; case "none": this.board_def[x, z].typeMvto = tipoMovimiento.none; break; } //Cada celda ocupa su posicion original al comenzar el juego this.current_board[x, z] = new PairInt(x, z); } //4.- Posicion inicial del robot. PT_XMLHashtable robot = xml["robot"][0]["position"][0]; this.robotPosition = new Vector3(float.Parse(robot.att("x")), float.Parse(robot.att("y")), float.Parse(robot.att("z"))); robot = xml["robot"][0]["rotation"][0]; this.robotRotation = new Vector3(float.Parse(robot.att("x")), float.Parse(robot.att("y")), float.Parse(robot.att("z"))); //Transformamos la rotacion en el intervalo [0,360) while (this.robotRotation.y < 0) { this.robotRotation.y += 360; } while (this.robotRotation.y >= 360) { this.robotRotation.y -= 360; } }
public void BuildLevel(PT_XMLHashtable level) { // Destroy any old Tiles foreach (Transform t in tileAnchor) { // Clear out old tiles // ^ You can iterate over a Transform to get its children Destroy(t.gameObject); } string lNumStr = level.att("num"); int x_start = int.Parse (level.att ("x_start")); int y_start = int.Parse (level.att ("y_start")); int x_goal = int.Parse (level.att ("x_goal")); int y_goal = int.Parse (level.att ("y_goal")); string[] levelRows = level.text.Split('\n'); for (int i=0; i<levelRows.Length; i++) { levelRows[i] = levelRows[i].Trim('\t'); } // Clear the tiles Array tiles = new Tile[ 100, 100 , 10 ]; // Arbitrary max room size is 100x100x10 // Declare a number of local fields that we'll use later Tile ti; string type; GameObject go; int height; int z_start = -1; int[,] map = new int[100,100]; float maxY = levelRows.Length-1; // These loops scan through each tile of each row of the room for (int y=0; y<levelRows.Length; y++) { for (int x=0; x<levelRows[y].Length; x++) { // Set defaults height = 0; // Get the character representing the tile type = levelRows [y] [x].ToString (); switch (type) { case ".": case " ": case "_": case "0": // cualquiera de estas cosas se interpreta como hueco height = 0; map[x,y] = 0; break; default:// todo lo demas sera un numero que indica la altura height = int.Parse(type); map[x,y] = height; for (int h = 0; h < height; h++) { // pintar un cubo por cada altura if (y == y_goal && x == x_goal && h == height-1){ // coincide con las coordenadas objetivo go = Instantiate (goalPrefab) as GameObject; }else{ // casilla normal go = Instantiate (tilePrefab) as GameObject; } ti = go.GetComponent<Tile> (); // Set the parent Transform to tileAnchor ti.transform.parent = tileAnchor; // Set the position of the tile ti.pos = new Vector3 (x,h,y); tiles [x, h, y] = ti; // Add ti to the tiles 2D Array // Set the type, height, and texture of the Tile ti.type = "baldosa"; } if (y == y_start && x == x_start){ z_start = height; } break; } } } Game.S.setMap (map, x_goal, y_goal, x_start, y_start, z_start ); }
public void BuildRoom(PT_XMLHashtable room) { // Destroy any old Tiles foreach (Transform t in tileAnchor) { // Clear out old tiles // ^ You can iterate over a Transform to get its children Destroy(t.gameObject); } // Move the Mage out of the way Mage.S.pos = Vector3.left * 1000; // ^ This keeps the Mage from accidentally triggering OnTriggerExit() on // a Portal. In my testing, I found that OnTriggerExit was being called // at strange times. Mage.S.ClearInput(); // Cancel any active mouse input and drags string rNumStr = room.att("num"); // Get the texture names for the floors and walls from <room> attributes string floorTexStr = room.att("floor"); string wallTexStr = room.att("wall"); // Split the room into rows of tiles based on carriage returns in the // Rooms.xml file string[] roomRows = room.text.Split('\n'); // Trim tabs from the beginnings of lines. However, we're leaving spaces // and underscores to allow for non-rectangular rooms. for (int i = 0; i < roomRows.Length; i++) { roomRows[i] = roomRows[i].Trim('\t'); } // Clear the tiles Array tiles = new Tile[100, 100]; // Arbitrary max room size is 100x100 // Declare a number of local fields that we'll use later Tile ti; string type, rawType, tileTexStr; GameObject go; int height; float maxY = roomRows.Length - 1; List<Portal> portals = new List<Portal>(); // These loops scan through each tile of each row of the room for (int y = 0; y < roomRows.Length; y++) { for (int x = 0; x < roomRows[y].Length; x++) { // Set defaults height = 0; tileTexStr = floorTexStr; // Get the character representing the tile type = rawType = roomRows[y][x].ToString(); switch (rawType) { case " ": // empty space case "_": // empty space // Just skip over empty space continue; case ".": // default floor // Keep type="." break; case "|": // default wall height = 1; break; default: // Anything else will be interpreted as floor type = "."; break; } // Set the texture for floor or wall based on <room> attributes if (type == ".") { tileTexStr = floorTexStr; } else if (type == "|") { tileTexStr = wallTexStr; } // Instantiate a new TilePrefab go = Instantiate(tilePrefab) as GameObject; ti = go.GetComponent<Tile>(); // Set the parent Transform to tileAnchor ti.transform.parent = tileAnchor; // Set the position of the tile ti.pos = new Vector3(x, maxY - y, 0); tiles[x, y] = ti; // Add ti to the tiles 2D Array // Set the type, height, and texture of the Tile ti.type = type; ti.height = height; ti.tex = tileTexStr; // If the type is still rawType, continue to the next iteration if (rawType == type) continue; // Check for specific entities in the room switch (rawType) { // 1 case "X": // Starting position for the Mage // Mage.S.pos = ti.pos; // Uses the Mage Singleton if (firstRoom) { Mage.S.pos = ti.pos; // Uses the Mage Singleton roomNumber = rNumStr; // ^ Setting roomNumber now keeps any portals from // moving the Mage to them in this first room. firstRoom = false; } break; case "0": // Numbers are room portals (up to F in hexadecimal) case "1": // This allows portals to be placed in the Rooms.xml file case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": case "A": case "B": case "C": case "D": case "E": case "F": // Instantiate a Portal GameObject pGO = Instantiate(portalPrefab) as GameObject; Portal p = pGO.GetComponent<Portal>(); p.pos = ti.pos; p.transform.parent = tileAnchor; // ^ Attaching this to the tileAnchor means that the Portal // will be Destroyed when a new room is built p.toRoom = rawType; portals.Add(p); break; default: // Try to see if there's an Enemy for that letter Enemy en = EnemyFactory(rawType); if (en == null) break; // If there's not one, break out // Set up the new Enemy en.pos = ti.pos; // Make en a child of tileAnchor so it's deleted when the // next room is loaded. en.transform.parent = tileAnchor; en.typeString = rawType; break; } // More to come here... } } // Position the Mage foreach (Portal p in portals) { // If p.toRoom is the same as the room number the Mage just exited, // then the Mage should enter this room through this Portal // Alternatively, if firstRoom == true and there was no X in the // room (as a default Mage starting point), move the Mage to this // Portal as a backup measure (if, for instance, you want to just // load room number "5") if (p.toRoom == roomNumber || firstRoom) { // ^ If there's an X in the room, firstRoom will be set to false // by the time the code gets here Mage.S.StopWalking(); // Stop any Mage movement Mage.S.pos = p.pos; // Move _Mage to this Portal location // _Mage maintains her facing from the previous room, so there // is no need to rotate her in order for her to enter this room // facing the right direction. p.justArrived = true; // ^ Tell the Portal that Mage has just arrived. firstRoom = false; // ^ Stops a 2nd Portal in this room from moving the Mage to it } } // Finally assign the roomNumber roomNumber = rNumStr; }
/* void Awake() { inputTA = Resources.Load("WellFormedSample") as TextAsset; input = inputTA.text; print(input); output = new XMLHashtable(); Parse(input, output); // TODO: Make something which will trace a Hashtable or output it as XML print(output["videocollection"][0]["video"][1]["title"][0].text); } */ // This function creates a new XMLHashtable and calls the real Parse() public void Parse(string eS) { xmlText = eS; xml = new PT_XMLHashtable(); Parse(eS, xml); }
// This function parses a single tag and calls Parse() if it encounters subtags string ParseTag(string eS, PT_XMLHashtable eH) { // search for "<" int ndx = eS.IndexOf("<"); int end, end1, end2, end3; if (ndx == -1) { // It's possible that this is just a string (e.g. <someTagTheStringIsInside>string</someTagTheStringIsInside>) end3 = eS.IndexOf(">"); // This closes a standard tag; look for the closing tag if (end3 == -1) { // In that case, we just need to add an @ key/value to the hashtable eS = eS.Trim(); // I think this is redundant //eH["@"] = eS; eH.text = eS; } return(""); // We're done with this tag } // Ignore this if it is just an XML header (e.g. <?xml version="1.0"?>) if (eS[ndx + 1] == '?') { // search for the closing tag of this header int ndx2 = eS.IndexOf("?>"); string header = eS.Substring(ndx, ndx2 - ndx + 2); //eH["@XML_Header"] = header; eH.header = header; return(eS.Substring(ndx2 + 2)); } // Ignore this if it is an XML comment (e.g. <!-- Comment text -->) if (eS[ndx + 1] == '!') { // search for the closing tag of this header int ndx2 = eS.IndexOf("-->"); string comment = eS.Substring(ndx, ndx2 - ndx + 3); if (SHOW_COMMENTS) { Debug.Log("XMl Comment: " + comment); } //eH["@XML_Header"] = header; return(eS.Substring(ndx2 + 3)); } // Find the end of the tag name // For the next few comments, this is what happens when this character is the first one found after the beginning of the tag end1 = eS.IndexOf(" ", ndx); // This means that we'll have attributes end2 = eS.IndexOf("/", ndx); // Immediately closes the tag, end3 = eS.IndexOf(">", ndx); // This closes a standard tag; look for the closing tag if (end1 == -1) { end1 = int.MaxValue; } if (end2 == -1) { end2 = int.MaxValue; } if (end3 == -1) { end3 = int.MaxValue; } end = Mathf.Min(end1, end2, end3); string tag = eS.Substring(ndx + 1, end - ndx - 1); // search for this tag in eH. If it's not there, make it if (!eH.ContainsKey(tag)) { eH[tag] = new PT_XMLHashList(); } // Create a hashtable to contain this tag's information PT_XMLHashList arrL = eH[tag] as PT_XMLHashList; //int thisHashIndex = arrL.Count; PT_XMLHashtable thisHash = new PT_XMLHashtable(); arrL.Add(thisHash); // Pull the attributes string string atts = ""; if (end1 < end3) { try { atts = eS.Substring(end1, end3 - end1); } catch (System.Exception ex) { Debug.LogException(ex); Debug.Log("break"); } } // Parse the attributes, which are all guaranteed to be strings string att, val; int eqNdx, spNdx; while (atts.Length > 0) { atts = atts.Trim(); eqNdx = atts.IndexOf("="); if (eqNdx == -1) { break; } //att = "@"+atts.Substring(0,eqNdx); att = atts.Substring(0, eqNdx); spNdx = atts.IndexOf(" ", eqNdx); if (spNdx == -1) // This is the last attribute and doesn't have a space after it { val = atts.Substring(eqNdx + 1); if (val[val.Length - 1] == '/') // If the trailing / from /> was caught, remove it { val = val.Substring(0, val.Length - 1); } atts = ""; } else // This attribute has a space after it { val = atts.Substring(eqNdx + 1, spNdx - eqNdx - 2); atts = atts.Substring(spNdx); } val = val.Trim('\"'); //thisHash[att] = val; // All attributes have to be unique, so this should be okay. thisHash.attSet(att, val); } // Pull the subs, which is everything contained by this tag but exclusing the tags on either side (e.g. <tag att="hi">.....subs.....</tag>) string subs = ""; string leftoverString = ""; // singleLine means this doesn't have a separate closing tag (e.g. <tag att="hi" />) bool singleLine = (end2 == end3 - 1); // ? true : false; if (!singleLine) // This is a multiline tag (e.g. <tag> .... </tag>) // find the closing tag { int close = eS.IndexOf("</" + tag + ">"); // TODO: Should this do something more if there is no closing tag? if (close == -1) { Debug.Log("XMLReader ERROR: XML not well formed. Closing tag </" + tag + "> missing."); return(""); } subs = eS.Substring(end3 + 1, close - end3 - 1); leftoverString = eS.Substring(eS.IndexOf(">", close) + 1); } else { leftoverString = eS.Substring(end3 + 1); } subs = subs.Trim(); // Call Parse if this contains subs if (subs.Length > 0) { Parse(subs, thisHash); } // Trim and return the leftover string leftoverString = leftoverString.Trim(); return(leftoverString); }
public void BuildRoom(PT_XMLHashtable room) { string floorTexStr = room.att("floor"); string wallTexStr = room.att("wall"); string[] roomRows = room.text.Split('\n'); for (int i = 0; i < roomRows.Length; i++) { roomRows[i] = roomRows[i].Trim('\t'); } tiles = new Tile[100, 100]; Tile ti; string type, rawType, tileTexStr; GameObject go; int height; float maxY = roomRows.Length - 1; for (int y = 0; y < roomRows.Length; y++) { for (int x = 0; x < roomRows[y].Length; x++) { height = 0; tileTexStr = floorTexStr; type = rawType = roomRows[y][x].ToString(); switch (rawType) { case " ": case "_": continue; case ".": // default floor break; case "|": // default wall height = 1; break; default: type = "."; break; } if (type == ".") { tileTexStr = floorTexStr; } else if (type == "|") { tileTexStr = wallTexStr; } go = Instantiate(tilePrefab) as GameObject; ti = go.GetComponent <Tile>(); ti.transform.parent = tileAnchor; ti.pos = new Vector3(x, maxY - y, 0); tiles[x, y] = ti; ti.type = type; ti.height = height; ti.tex = tileTexStr; if (rawType == type) { continue; } switch (rawType) { case "X": Mage.S.pos = ti.pos; break; } //More here } } }
// This function is called to read in the LayoutXML.xml file public void ReadLayout(string xmlText) { xmlr = new PT_XMLReader(); xmlr.Parse(xmlText); // The XML is parsed xml = xmlr.xml["xml"][0]; // And xml is set as a shortcut to the XML //Read in the multiplier, which sets card spacing multiplier.x = float.Parse(xml["multiplier"][0].att("x")); multiplier.y = float.Parse(xml["multiplier"][0].att("y")); //Read in the slots SlotDef tSD; //slotsX is used as a shortcut to all the <slot>s PT_XMLHashList slotsX = xml["slot"]; for (int i = 0; i < slotsX.Count; i++) { tSD = new SlotDef(); // Create a new SlotDef instance if (slotsX[i].HasAtt("type")) { // If this <slot> has a type attribute parse it tSD.type = slotsX[i].att("type"); } else { // If not, set its type to "slot"; it's a card in the rows tSD.type = "slot"; } // Various attributes are parsed into numerical values tSD.x = float.Parse(slotsX[i].att("x")); tSD.y = float.Parse(slotsX[i].att("y")); tSD.layerID = int.Parse(slotsX[i].att("layer")); //This converts the number of the layerID into a text layerName tSD.layerName = sortingLayerNames[tSD.layerID]; switch (tSD.type) { //pull additional attributes based on the type of this <slot> case "slot": tSD.faceUp = (slotsX[i].att("faceup") == "1"); tSD.id = int.Parse(slotsX[i].att("id")); if (slotsX[i].HasAtt("hiddenby")) { string[] hiding = slotsX[i].att("hiddenby").Split(','); foreach (string s in hiding) { tSD.hiddenBy.Add(int.Parse(s)); } } slotDefs.Add(tSD); break; case "drawpile": tSD.stagger.x = float.Parse(slotsX[i].att("xstagger")); drawPile = tSD; break; case "discardpile": discardPile = tSD; break; } } }
// This function parses a single tag and calls Parse() if it encounters subtags string ParseTag(string eS, PT_XMLHashtable eH) { // search for "<" int ndx = eS.IndexOf("<"); int end, end1, end2, end3; if (ndx == -1) { // It's possible that this is just a string (e.g. <someTagTheStringIsInside>string</someTagTheStringIsInside>) end3 = eS.IndexOf(">"); // This closes a standard tag; look for the closing tag if (end3 == -1) { // In that case, we just need to add an @ key/value to the hashtable eS = eS.Trim(); // I think this is redundant //eH["@"] = eS; eH.text = eS; } return(""); // We're done with this tag } // Ignore this if it is just an XML header (e.g. <?xml version="1.0"?>) if (eS[ndx+1] == '?') { // search for the closing tag of this header int ndx2 = eS.IndexOf("?>"); string header = eS.Substring(ndx, ndx2-ndx+2); //eH["@XML_Header"] = header; eH.header = header; return(eS.Substring(ndx2+2)); } // Ignore this if it is an XML comment (e.g. <!-- Comment text -->) if (eS[ndx+1] == '!') { // search for the closing tag of this header int ndx2 = eS.IndexOf("-->"); string comment = eS.Substring(ndx, ndx2-ndx+3); if (SHOW_COMMENTS) Debug.Log("XMl Comment: "+comment); //eH["@XML_Header"] = header; return(eS.Substring(ndx2+3)); } // Find the end of the tag name // For the next few comments, this is what happens when this character is the first one found after the beginning of the tag end1 = eS.IndexOf(" ", ndx); // This means that we'll have attributes end2 = eS.IndexOf("/", ndx); // Immediately closes the tag, end3 = eS.IndexOf(">", ndx); // This closes a standard tag; look for the closing tag if (end1 == -1) end1 = int.MaxValue; if (end2 == -1) end2 = int.MaxValue; if (end3 == -1) end3 = int.MaxValue; end = Mathf.Min(end1, end2, end3); string tag = eS.Substring(ndx+1, end-ndx-1); // search for this tag in eH. If it's not there, make it if (!eH.ContainsKey(tag)) { eH[tag] = new PT_XMLHashList(); } // Create a hashtable to contain this tag's information PT_XMLHashList arrL = eH[tag] as PT_XMLHashList; //int thisHashIndex = arrL.Count; PT_XMLHashtable thisHash = new PT_XMLHashtable(); arrL.Add(thisHash); // Pull the attributes string string atts = ""; if (end1 < end3) { try { atts = eS.Substring(end1, end3-end1); } catch(System.Exception ex) { Debug.LogException(ex); Debug.Log("break"); } } // Parse the attributes, which are all guaranteed to be strings string att, val; int eqNdx, spNdx; while (atts.Length > 0) { atts = atts.Trim(); eqNdx = atts.IndexOf("="); if (eqNdx == -1) break; //att = "@"+atts.Substring(0,eqNdx); att = atts.Substring(0,eqNdx); spNdx = atts.IndexOf(" ",eqNdx); if (spNdx == -1) { // This is the last attribute and doesn't have a space after it val = atts.Substring(eqNdx+1); if (val[val.Length-1] == '/') { // If the trailing / from /> was caught, remove it val = val.Substring(0,val.Length-1); } atts = ""; } else { // This attribute has a space after it val = atts.Substring(eqNdx+1, spNdx - eqNdx - 2); atts = atts.Substring(spNdx); } val = val.Trim('\"'); //thisHash[att] = val; // All attributes have to be unique, so this should be okay. thisHash.attSet(att, val); } // Pull the subs, which is everything contained by this tag but exclusing the tags on either side (e.g. <tag att="hi">.....subs.....</tag>) string subs = ""; string leftoverString = ""; // singleLine means this doesn't have a separate closing tag (e.g. <tag att="hi" />) bool singleLine = (end2 == end3-1);// ? true : false; if (!singleLine) { // This is a multiline tag (e.g. <tag> .... </tag>) // find the closing tag int close = eS.IndexOf("</"+tag+">"); // TODO: Should this do something more if there is no closing tag? if (close == -1) { Debug.Log("XMLReader ERROR: XML not well formed. Closing tag </"+tag+"> missing."); return(""); } subs = eS.Substring(end3+1, close-end3-1); leftoverString = eS.Substring( eS.IndexOf(">",close)+1 ); } else { leftoverString = eS.Substring(end3+1); } subs = subs.Trim(); // Call Parse if this contains subs if (subs.Length > 0) { Parse(subs, thisHash); } // Trim and return the leftover string leftoverString = leftoverString.Trim(); return(leftoverString); }
//This function is called to read in the LayoutXML.xml file public void ReadLayout(string xmlText) { xmlr = new PT_XMLReader(); xmlr.Parse(xmlText); //The XML is parsed xml = xmlr.xml["xml"][0]; //And xml is set as a shortcut to the XML //Read in the multiplier, which sets card spacing multiplier.x = float.Parse(xml["multiplier"][0].att("x")); multiplier.y = float.Parse(xml["multiplier"][0].att("y")); //Read in the slots SlotDef tSD; //slotsX is used as a shortcut to all the <slot>s PT_XMLHashList slotsX = xml["slot"]; for (int i = 0; i < slotsX.Count; i++) { tSD = new SlotDef(); //Create a new SlotDef instance if (slotsX[i].HasAtt("type")) { //If this <slot> has a type attribute parse it tSD.type = slotsX[i].att("type"); } else { //If not, set its type to "slot" tSD.type = "slot"; } //Various attributes are parsed into numerical values tSD.x = float.Parse(slotsX[i].att("x")); tSD.y = float.Parse(slotsX[i].att("y")); tSD.pos = new Vector3(tSD.x * multiplier.x, tSD.y * multiplier.y, 0); //Sorting Layers tSD.layerID = int.Parse(slotsX[i].att("layer")); //In this game, the Sorting Layers are named 1, 2, 3, ...through 10 //This converts the number of the layerID into a text layerName tSD.layerName = tSD.layerID.ToString(); //The layers are used to make sure that the correct cards are //on top of the others. In Unity 2D, all of our assets are //effectively at the same Z depth, so sorting layers are used //to differentiate betwene them. //pull additional attributes based on the type of each <slot> switch (tSD.type) { case "slot": //ignore slots that are just of the "slot" type break; case "drawpile": //The drawPile xstagger is read but not actually used in Bartok tSD.stagger.x = float.Parse(slotsX[i].att("xstagger")); drawPile = tSD; break; case "discardpile": discardPile = tSD; break; case "target": //The target card has a different layer from discardPile target = tSD; break; case "hand": //Information for each player's hand tSD.player = int.Parse(slotsX[i].att("player")); tSD.rot = float.Parse(slotsX[i].att("rot")); slotDefs.Add(tSD); break; } } }