/// <summary> /// </summary> /// <returns> /// </returns> private static List <NanoFormula> ReadNanoFormulas() { var np = new NewParser(); List <NanoFormula> rawNanoList = new List <NanoFormula>(); int counter = 0; foreach (int recnum in extractor.GetRecordInstances(Extractor.RecordType.Nano)) { if (counter == 0) { counter = recnum; } byte[] data = extractor.GetRecordData(Extractor.RecordType.Nano, recnum); NanoFormula nano = np.ParseNano(recnum, data, "temp.sql"); rawNanoList.Add(nano); if ((counter % 2000) == 0) { Console.Write("\rNano ID: " + recnum.ToString().PadLeft(9)); } counter++; } Console.Write("\rNano ID: " + rawNanoList[rawNanoList.Count - 1].ID.ToString().PadLeft(9)); File.Delete("temp.sql"); return(rawNanoList); }
/// <summary> /// </summary> /// <param name="nanoId"> /// </param> /// <param name="target"> /// </param> /// <returns> /// </returns> /// <exception cref="NotImplementedException"> /// </exception> public bool CastNano(int nanoId, Identity target) { // Procedure: // 1. Check if nano can be casted (criteria to Use (3)) // 2. Lock nanocasting ability // 3. Wait for cast attack delay // 4. Check target's restance to the nano // 5. Execute nanos gamefunctions // 6. Wait for nano recharge delay // 7. Unlock nano casting NanoFormula nano = NanoLoader.NanoList[nanoId]; int strain = nano.NanoStrain(); CastNanoSpellMessageHandler.Default.Send(this.Character, nanoId, target); // CharacterAction 107 - Finish nano casting int attackDelay = this.Character.CalculateNanoAttackTime(nano); Console.WriteLine("Attack-Delay: " + attackDelay); if (attackDelay != 1234567890) { Thread.Sleep(attackDelay * 10); } // Check here for nanoresist of the target, maybe the 1 in finishnanocasting is kind of did land/didnt land flag CharacterActionMessageHandler.Default.FinishNanoCasting( this.Character, CharacterActionType.FinishNanoCasting, Identity.None, 1, nanoId); // TODO: Calculate nanocost modifiers etc. this.Character.Stats[StatIds.currentnano].Value -= nano.getItemAttribute(407); // CharacterAction 98 - Set nano duration CharacterActionMessageHandler.Default.SetNanoDuration( this.Character, target, nanoId, nano.getItemAttribute(8)); Thread.Sleep(nano.getItemAttribute(210) * 10); // Recharge Delay return(false); }
/// <summary> /// </summary> /// <param name="nano"> /// </param> /// <returns> /// </returns> public int CalculateNanoAttackTime(NanoFormula nano) { // Calculation in 100's of seconds!! int aggdef = this.Stats[StatIds.aggdef].Value; int aggdefReduction = aggdef - 25; int nanoinit = this.Stats[StatIds.nanoprowessinitiative].Value; if (nanoinit > 1200) { nanoinit = ((nanoinit - 1200) / 3) + 1200; } int nanoInitreduction = nanoinit >> 1; int attackCap = nano.getItemAttribute(523); // AttackDelayCap int attackDelay = nano.getItemAttribute(294); // AttackDelay // The Math.Min is safeguard for calculation errors due to uint->int casting of originally negative values return(Math.Min(Math.Max(attackDelay - aggdefReduction - nanoInitreduction, attackCap), attackDelay)); }
/// <summary> /// The parse nano. /// </summary> /// <param name="rectype"> /// The rectype. /// </param> /// <param name="recnum"> /// The recnum. /// </param> /// <param name="data"> /// The data. /// </param> /// <param name="sqlFile"> /// The sql file. /// </param> /// <returns> /// The <see cref="AONanos"/>. /// </returns> public NanoFormula ParseNano(int rectype, int recnum, byte[] data, string sqlFile) { this.br = new BufferedReader(rectype, recnum, data); NanoFormula aon = new NanoFormula(); aon.ID = recnum; this.br.Skip(16); int numberOfAttributes = this.br.Read3F1() - 1; int counter = 0; while (true) { if (counter > numberOfAttributes) { break; } int attrkey = this.br.ReadInt32(); int attrval = this.br.ReadInt32(); if (attrkey == 54) { aon.Stats.Add(attrkey, attrval); } else { aon.Stats.Add(attrkey, attrval); } counter++; } this.br.Skip(8); short nameLength = this.br.ReadInt16(); short descriptionLength = this.br.ReadInt16(); if (nameLength > 0) { this.br.ReadString(nameLength); } if (descriptionLength > 0) { this.br.ReadString(descriptionLength); // Read and discard Description } bool flag4 = true; checked { while (this.br.Ptr < this.br.Buffer.Length - 8 && flag4) { switch (this.br.ReadInt32()) { case 2: this.ParseFunctionSet(aon.Events); break; case 3: case 5: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 15: case 16: case 17: case 18: case 19: case 21: goto IL_4BF; case 4: this.ParseAtkDefSet(aon.Attack, aon.Defend); break; case 6: { this.br.Skip(4); int count = this.br.Read3F1() * 8; this.br.Skip(count); break; } case 14: this.ParseAnimSoundSet(1, null); break; case 20: this.ParseAnimSoundSet(2, null); break; case 22: this.ParseActionSet(aon.Actions); break; case 23: this.ParseShopHash(aon.Events); break; default: goto IL_4BF; } continue; IL_4BF: flag4 = false; } } return(aon); }