public NPCObject Copy() { NPCObject copy = new NPCObject(); copy.EngageType = EngageType; copy.SpeedPlus = SpeedPlus; copy.B2b3 = B2b3; copy.B2b4 = B2b4; copy.B2b5 = B2b5; copy.B2b6 = B2b6; copy.B2b7 = B2b7; copy.B3b0 = B3b0; copy.B3b1 = B3b1; copy.B3b2 = B3b2; copy.B3b3 = B3b3; copy.B3b4 = B3b4; copy.B3b5 = B3b5; copy.B3b6 = B3b6; copy.B3b7 = B3b7; copy.B4b0 = B4b0; copy.B4b1 = B4b1; copy.NPCID = NPCID; copy.Action = Action; copy.Event = Event; copy.Pack = Pack; copy.EngageTrigger = EngageTrigger; copy.B7b6 = B7b6; copy.B7b7 = B7b7; copy.AfterBattle = AfterBattle; // copy.X = X; copy.Y = Y; copy.Z = Z; copy.ShowNPC = ShowNPC; copy.ZHalf = ZHalf; copy.F = F; // copy.Mem70A7 = Mem70A7; // return(copy); }
private void AddNew(NPCObject newNPCObject) { // Insert the new object at the current top-left visible bounds of the tilemap PictureBox Point topLeftVisibleBounds = new Point(Math.Abs(picture.Left) / zoom, Math.Abs(picture.Top) / zoom); int x = collision.PixelCoords[topLeftVisibleBounds.Y * 1024 + topLeftVisibleBounds.X].X + 2; int y = collision.PixelCoords[topLeftVisibleBounds.Y * 1024 + topLeftVisibleBounds.X].Y + 4; Point isometricLocation = new Point(x, y); if (Model.FreeNPCSpace() >= 12) { if (npcObjects.Count < 28) { int selectedIndex = -1; if (npcObjects.Count > 0) { npcObjects.Insert(SelectedNPC + 1, newNPCObject); selectedIndex = listBox.SelectedIndex; } else { npcObjects.Insert(0, newNPCObject); } // BuildListBox(selectedIndex); } else { MessageBox.Show("Could not insert any more NPCs. The maximum number of NPCs plus NPC clones allowed is 28.", "LAZY SHELL", MessageBoxButtons.OK, MessageBoxIcon.Information); } } else { MessageBox.Show("Could not insert the NPC. " + Model.MaximumSpaceExceeded("NPCs"), "LAZY SHELL", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
/// <summary> /// Gets the reference information for a set of NPCs which can reference /// a specified index in an NPCObject collection. /// </summary> /// <param name="NPCObjects"></param> /// <param name="index"></param> /// <returns></returns> public ReferenceInfo GetReferenceInfo(List <NPCObject> NPCObjects, int index) { ReferenceInfo referenceInfo = new ReferenceInfo(); // Cancel if specified index at end of collection if (index >= NPCObjects.Count - 1) { return(referenceInfo); } // Determine maximum number of references based on specified index int maxReferenceCount = NPCObjects.Count - (index + 1); if (maxReferenceCount > 15) { maxReferenceCount = 15; } // Declare the specified index and the siblings after the specified index var npcObject = NPCObjects[index]; var nextSiblings = NPCObjects.GetRange(index + 1, maxReferenceCount); #region Compare base variables // First, compare referenced variables and trim sibling list accordingly for (int i = 0; i < nextSiblings.Count; i++) { NPCObject sibling = nextSiblings[i]; // Compare all base variables if (sibling.SpeedPlus != npcObject.SpeedPlus || sibling.EngageTrigger != npcObject.EngageTrigger || sibling.AfterBattle != npcObject.AfterBattle || sibling.B2b3 != npcObject.B2b3 || sibling.B2b4 != npcObject.B2b4 || sibling.B2b5 != npcObject.B2b5 || sibling.B2b6 != npcObject.B2b6 || sibling.B2b7 != npcObject.B2b7 || sibling.B3b0 != npcObject.B3b0 || sibling.B3b1 != npcObject.B3b1 || sibling.B3b2 != npcObject.B3b2 || sibling.B3b3 != npcObject.B3b3 || sibling.B3b4 != npcObject.B3b4 || sibling.B3b5 != npcObject.B3b5 || sibling.B3b6 != npcObject.B3b6 || sibling.B3b7 != npcObject.B3b7 || sibling.B4b0 != npcObject.B4b0 || sibling.B4b1 != npcObject.B4b1 || sibling.B7b6 != npcObject.B7b6 || sibling.B7b7 != npcObject.B7b7) { // If comparison failed, remove current and all subsequent siblings nextSiblings.RemoveRange(i, nextSiblings.Count - i); break; } // Cancel whole operation if no siblings left if (nextSiblings.Count == 0) { return(referenceInfo); } // If treasure, don't need to execute following code if (npcObject.EngageType == EngageType.Treasure) { continue; } // Compare all referenced variables using boundaries // (Treasure engage type does not reference anything) if (npcObject.EngageType == EngageType.Event) { if (sibling.NPCID > npcObject.NPCID + 7 || sibling.NPCID < npcObject.NPCID - 7 || sibling.Action > npcObject.Action + 3 || sibling.Action < npcObject.Action - 3 || sibling.Event > npcObject.Event + 7 || sibling.Event < npcObject.Event - 7) { // If comparison failed, remove current and all subsequent siblings nextSiblings.RemoveRange(i, nextSiblings.Count - i); break; } } else if (npcObject.EngageType == EngageType.Battle) { if (sibling.Action > npcObject.Action + 15 || sibling.Action < npcObject.Action - 15 || sibling.Pack > npcObject.Pack + 15 || sibling.Pack < npcObject.Pack - 15) { // If comparison failed, remove current and all subsequent siblings nextSiblings.RemoveRange(i, nextSiblings.Count - i); break; } } // Cancel whole operation if no siblings left if (nextSiblings.Count == 0) { return(referenceInfo); } } #endregion // Cancel whole operation if no siblings left if (nextSiblings.Count == 0) { return(referenceInfo); } // If treasure, don't need to execute following code if (npcObject.EngageType == EngageType.Treasure) { return(referenceInfo); } #region Calculate lowest values // Declare a floor and ceiling value for the variables int lowestNPCID = npcObject.NPCID; int lowestAction = npcObject.Action; int lowestEvent = npcObject.Event; int lowestPack = npcObject.Pack; int highestNPCID = npcObject.NPCID; int highestAction = npcObject.Action; int highestEvent = npcObject.Event; int highestPack = npcObject.Pack; // Trim siblings based on their variables' extension beyond the floor and ceiling boundaries for (int i = 0; i < nextSiblings.Count; i++) { NPCObject sibling = nextSiblings[i]; // Check if variables too high or low if (npcObject.EngageType == EngageType.Event) { if (sibling.NPCID > lowestNPCID + 7 || sibling.NPCID < highestNPCID - 7 || sibling.Action > lowestAction + 3 || sibling.Action < highestAction - 3 || sibling.Event > lowestEvent + 7 || sibling.Event < highestEvent - 7) { // If comparison failed, remove current and all subsequent siblings nextSiblings.RemoveRange(i, nextSiblings.Count - i); break; } } else if (npcObject.EngageType == EngageType.Battle) { if (sibling.Action > lowestAction + 15 || sibling.Action < highestAction - 15 || sibling.Pack > lowestPack + 15 || sibling.Pack < highestPack - 15) { // If comparison failed, remove current and all subsequent siblings nextSiblings.RemoveRange(i, nextSiblings.Count - i); break; } } // If lower than lowest if (sibling.NPCID < lowestNPCID) { lowestNPCID = sibling.NPCID; } if (sibling.Action < lowestAction) { lowestAction = sibling.Action; } if (sibling.Event < lowestEvent) { lowestEvent = sibling.Event; } if (sibling.Pack < lowestPack) { lowestPack = sibling.Pack; } // If higher than highest if (sibling.NPCID > highestNPCID) { highestNPCID = sibling.NPCID; } if (sibling.Action > highestAction) { highestAction = sibling.Action; } if (sibling.Event > highestEvent) { highestEvent = sibling.Event; } if (sibling.Pack > highestPack) { highestPack = sibling.Pack; } } #endregion // Cancel whole operation if no siblings left if (nextSiblings.Count == 0) { return(referenceInfo); } //if (optimize) //{ // // Check each sibling to see if it can contain more references // for (int i = 0; i < nextSiblings.Count; i++) // { // var siblingReferenceInfo = GetReferenceInfo(NPCObjects, index + 1 + i, false); // // If so, remove following siblings so current sibling can contain them later // if (siblingReferenceInfo.Count > nextSiblings.Count - i) // nextSiblings.RemoveRange(i, nextSiblings.Count - i); // } // // Cancel whole operation if no siblings left // if (nextSiblings.Count == 0) // return referenceInfo; //} referenceInfo.Count = nextSiblings.Count; referenceInfo.BaseEvent = lowestEvent; referenceInfo.BaseNPCID = lowestNPCID; referenceInfo.BaseAction = lowestAction; referenceInfo.BasePack = lowestPack; // We have the full reference count return(referenceInfo); }
// Read/write ROM public void ReadFromROM(List <NPCObject> NPCObjects, ref int offset) { ReferenceInfo referenceInfo = new ReferenceInfo(); byte temp = rom[offset++]; // referenceInfo.Count = temp & 0x0F; // EngageType = (EngageType)((temp & 0x30) >> 4); temp = rom[offset++]; SpeedPlus = (byte)(temp & 0x07); // B2b3 = (temp & 0x08) == 0x08; B2b4 = (temp & 0x10) == 0x10; B2b5 = (temp & 0x20) == 0x20; B2b6 = (temp & 0x40) == 0x40; B2b7 = (temp & 0x80) == 0x80; // temp = rom[offset++]; B3b0 = (temp & 0x01) == 0x01; B3b1 = (temp & 0x02) == 0x02; B3b2 = (temp & 0x04) == 0x04; B3b3 = (temp & 0x08) == 0x08; B3b4 = (temp & 0x10) == 0x10; B3b5 = (temp & 0x20) == 0x20; B3b6 = (temp & 0x40) == 0x40; B3b7 = (temp & 0x80) == 0x80; // B4b0 = (rom[offset] & 0x01) == 0x01; B4b1 = (rom[offset] & 0x02) == 0x02; // referenceInfo.BaseNPCID = (Bits.GetShort(rom, offset++) & 0x0FFF) >> 2; referenceInfo.BaseAction = (Bits.GetShort(rom, offset++) & 0x3FF0) >> 4; // B7b6 = (rom[offset] & 0x40) == 0x40; B7b7 = (rom[offset++] & 0x80) == 0x80; // ushort tempShort = Bits.GetShort(rom, offset++); if (EngageType == EngageType.Battle) { referenceInfo.BasePack = tempShort & 0xFF; } else { referenceInfo.BaseEvent = tempShort & 0xFFF; } // temp = rom[offset++]; if (EngageType == EngageType.Battle) { AfterBattle = (byte)((temp >> 1) & 0x07); } EngageTrigger = (byte)Math.Min((temp & 0xF0) >> 4, 12); // Add references to collection ReadReference(ref offset, referenceInfo); int count = referenceInfo.Count; while (count-- > 0) { NPCObject reference = this.Copy(); reference.ReadReference(ref offset, referenceInfo); NPCObjects.Add(reference); } }