From baf2d8892127cd6da9d2f6f2f8d991d617c87800 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 26 Feb 2014 23:29:14 +0000 Subject: Implemented ballistic missiles (fireworks) + Added fireworks --- MCServer/crafting.txt | 49 +++++- src/CraftingRecipes.cpp | 89 ++++++++++- src/Entities/ProjectileEntity.cpp | 87 ++++++----- src/Entities/ProjectileEntity.h | 12 +- src/Item.cpp | 22 ++- src/Item.h | 16 +- src/Items/ItemThrowable.h | 6 +- src/Protocol/Protocol17x.cpp | 77 ++++++---- src/World.cpp | 4 +- src/World.h | 2 +- src/WorldStorage/FastNBT.h | 2 +- src/WorldStorage/FireworksSerializer.cpp | 250 +++++++++++++++++++++++++++++++ src/WorldStorage/FireworksSerializer.h | 88 +++++++++++ src/WorldStorage/NBTChunkSerializer.cpp | 14 +- src/WorldStorage/WSSAnvil.cpp | 6 + 15 files changed, 637 insertions(+), 87 deletions(-) create mode 100644 src/WorldStorage/FireworksSerializer.cpp create mode 100644 src/WorldStorage/FireworksSerializer.h diff --git a/MCServer/crafting.txt b/MCServer/crafting.txt index 92abe24cb..bce0c5e9e 100644 --- a/MCServer/crafting.txt +++ b/MCServer/crafting.txt @@ -39,6 +39,7 @@ # # Need to list each of the four log types, otherwise all logs would get converted into apple planks (^0) + ApplePlanks, 4 = AppleLog, * ConiferPlanks, 4 = ConiferLog, * BirchPlanks, 4 = BirchLog, * @@ -434,6 +435,48 @@ GoldNugget, 9 = GoldIngot, * EnchantmentTable = Obsidian, 1:3, 2:3, 3:3, 2:2 | Diamond, 1:2, 3:2 | Book, 2:1 - - - +#******************************************************# +# Fireworks & Co. +# (Best not to add non-vanilla items to this as it will cause internal firework data handling code to log warnings) + +# Ballistic firework rockets - plain and with firework star, all with 1 - 3 gunpowder +FireworkRocket = Paper, * | Gunpowder, * +FireworkRocket = Paper, * | Gunpowder, * | Gunpowder, * +FireworkRocket = Paper, * | Gunpowder, * | Gunpowder, * | Gunpowder, * +FireworkRocket = FireworkStar, * | Paper, * | Gunpowder, * +FireworkRocket = FireworkStar, * | Paper, * | Gunpowder, * | Gunpowder, * +FireworkRocket = FireworkStar, * | Paper, * | Gunpowder, * | Gunpowder, * | Gunpowder, * + +# Radioactive firework stars +# Plain powder and dye +FireworkStar = Gunpowder, * | Dye ^-1, * + +# Powder and effect, with effect combining +FireworkStar = Gunpowder, * | Dye ^-1, * | Diamond, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Glowdust, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Glowdust, * | Diamond, * + +# Powder and shape (no shape combining possible) +FireworkStar = Gunpowder, * | Dye ^-1, * | Firecharge, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Goldnugget, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Feather, * +FireworkStar = Gunpowder, * | Dye ^-1, * | SkeletonHead ^-1, * + +# Power and shape (no shape combining possible), combined with effect +FireworkStar = Gunpowder, * | Dye ^-1, * | Firecharge, * | Diamond, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Firecharge, * | Glowdust, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Goldnugget, * | Diamond, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Goldnugget, * | Glowdust, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Feather, * | Diamond, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Feather, * | Glowdust, * +FireworkStar = Gunpowder, * | Dye ^-1, * | SkeletonHead ^-1, * | Diamond, * +FireworkStar = Gunpowder, * | Dye ^-1, * | SkeletonHead ^-1, * | Glowdust, * + +# Power and shape (no shape combining possible), combined with effect (with effect combining) +FireworkStar = Gunpowder, * | Dye ^-1, * | Firecharge, * | Glowdust, * | Diamond, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Goldnugget, * | Glowdust, * | Diamond, * +FireworkStar = Gunpowder, * | Dye ^-1, * | Feather, * | Glowdust, * | Diamond, * +FireworkStar = Gunpowder, * | Dye ^-1, * | SkeletonHead ^-1, * | Glowdust, * | Diamond, * + +# Star colour-change +FireworkStar = FireworkStar, * | Dye ^-1, * diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index fb1a10cca..41de0da8c 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -1,4 +1,4 @@ - + // CraftingRecipes.cpp // Interfaces to the cCraftingRecipes class representing the storage of crafting recipes @@ -762,6 +762,93 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti Recipe->m_Ingredients.push_back(*itrS); } Recipe->m_Ingredients.insert(Recipe->m_Ingredients.end(), MatchedSlots.begin(), MatchedSlots.end()); + + + // Henceforth is code to handle fireworks + // We use Recipe instead of a_Recipe because we want the wildcard ingredients' slot numbers as well, which was just added previously + + if (Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_ROCKET) + { + for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + { + switch (itr->m_Item.m_ItemType) + { + case E_ITEM_FIREWORK_STAR: + { + // Result was a rocket, found a star - copy star data to rocket data + int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); + Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); + break; + } + case E_ITEM_GUNPOWDER: + { + // Gunpowder - increase flight time + Recipe->m_Result.m_FireworkItem.m_FlightTimeInTicks += 20; + break; + } + case E_ITEM_PAPER: break; + default: LOG("Unexpected item in firework rocket recipe, was the crafting file fireworks section changed?"); break; + } + } + } + else if (Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_STAR) + { + for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + { + switch (itr->m_Item.m_ItemType) + { + case E_ITEM_FIREWORK_STAR: + { + // Result was star, found another star - probably adding fade colours, but copy data over anyhow + int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); + Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); + break; + } + case E_ITEM_DYE: + { + // Found a dye in ingredients... + for (cRecipeSlots::const_iterator itrnumerodos = Recipe->m_Ingredients.begin(); itrnumerodos != Recipe->m_Ingredients.end(); ++itrnumerodos) + { + // Loop through ingredients. Can we find a star? + if (itrnumerodos->m_Item.m_ItemType == E_ITEM_FIREWORK_STAR) + { + // Yes, this is definately adding fade colours, unless crafting.txt was changed :/ + for (cRecipeSlots::const_iterator itrnumerotres = Recipe->m_Ingredients.begin(); itrnumerotres != Recipe->m_Ingredients.end(); ++itrnumerotres) + { + // Loop again, can we find dye? + if (itrnumerotres->m_Item.m_ItemType == E_ITEM_DYE) + { + // Yep, push back fade colour and exit the loop + // There is a potential for flexibility here - we can move the goto out of the loop, so we can add multiple dyes (∴ multiple fade colours) + // That will require lots of dye-adding to crafting.txt though - TODO, perchance? + int GridID = (itrnumerotres->x + a_OffsetX) + a_GridStride * (itrnumerotres->y + a_OffsetY); + Recipe->m_Result.m_FireworkItem.m_FadeColours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); + goto next; + } + } + } + } + + // Just normal crafting of star, push back normal colours + int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); + Recipe->m_Result.m_FireworkItem.m_Colours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); + + next: + break; + } + case E_ITEM_GUNPOWDER: break; + case E_ITEM_DIAMOND: Recipe->m_Result.m_FireworkItem.m_HasTrail = true; break; + case E_ITEM_GLOWSTONE_DUST: Recipe->m_Result.m_FireworkItem.m_HasFlicker = true; break; + + case E_ITEM_FIRE_CHARGE: Recipe->m_Result.m_FireworkItem.m_Type = 1; break; + case E_ITEM_GOLD_NUGGET: Recipe->m_Result.m_FireworkItem.m_Type = 2; break; + case E_ITEM_FEATHER: Recipe->m_Result.m_FireworkItem.m_Type = 4; break; + case E_ITEM_HEAD: Recipe->m_Result.m_FireworkItem.m_Type = 3; break; + default: LOG("Unexpected item in firework star recipe, was the crafting file fireworks section changed?"); break; // ermahgerd BARD ardmins + } + } + } + return Recipe.release(); } diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index ef82c6e94..be8e24540 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -214,7 +214,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Ve -cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d * a_Speed) +cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item, const Vector3d * a_Speed) { Vector3d Speed; if (a_Speed != NULL) @@ -231,8 +231,15 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, case pkGhastFireball: return new cGhastFireballEntity (a_Creator, a_X, a_Y, a_Z, Speed); case pkFireCharge: return new cFireChargeEntity (a_Creator, a_X, a_Y, a_Z, Speed); case pkExpBottle: return new cExpBottleEntity (a_Creator, a_X, a_Y, a_Z, Speed); - case pkFirework: return new cFireworkEntity (a_Creator, a_X, a_Y, a_Z ); - // TODO: the rest + case pkFirework: + { + if (a_Item.m_FireworkItem.m_Colours.empty()) + { + return NULL; + } + + return new cFireworkEntity(a_Creator, a_X, a_Y, a_Z, a_Item); + } } LOGWARNING("%s: Unknown projectile kind: %d", __FUNCTION__, a_Kind); @@ -276,6 +283,7 @@ AString cProjectileEntity::GetMCAClassName(void) const case pkExpBottle: return "ThrownExpBottle"; case pkSplashPotion: return "ThrownPotion"; case pkWitherSkull: return "WitherSkull"; + case pkFirework: return "Firework"; case pkFishingFloat: return ""; // Unknown, perhaps MC doesn't save this? } ASSERT(!"Unhandled projectile entity kind!"); @@ -693,8 +701,10 @@ void cExpBottleEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_H /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cFireworkEntity : -cFireworkEntity::cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z) : -super(pkFirework, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25) +cFireworkEntity::cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item) : +super(pkFirework, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25), + m_ExplodeTimer(0), + m_FireworkItem(a_Item) { } @@ -702,30 +712,20 @@ super(pkFirework, a_Creator, a_X, a_Y, a_Z, 0.25, 0.25) -void cFireworkEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) +void cFireworkEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) { - if ((a_HitFace != BLOCK_FACE_BOTTOM) && (a_HitFace != BLOCK_FACE_NONE)) + int RelX = POSX_TOINT - a_Chunk.GetPosX() * cChunkDef::Width; + int RelZ = POSZ_TOINT - a_Chunk.GetPosZ() * cChunkDef::Width; + int PosY = POSY_TOINT; + + if ((PosY < 0) || (PosY >= cChunkDef::Height)) { - return; + goto setspeed; } - SetSpeed(0, 0, 0); - SetPosition(GetPosX(), GetPosY() - 0.5, GetPosZ()); - - m_IsInGround = true; - - BroadcastMovementUpdate(); -} - - - - - -void cFireworkEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) -{ if (m_IsInGround) { - if (a_Chunk.GetBlock((int)GetPosX(), (int)GetPosY() + 1, (int)GetPosZ()) == E_BLOCK_AIR) + if (a_Chunk.GetBlock(RelX, POSY_TOINT + 1, RelZ) == E_BLOCK_AIR) { m_IsInGround = false; } @@ -734,28 +734,35 @@ void cFireworkEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) return; } } + else + { + if (a_Chunk.GetBlock(RelX, POSY_TOINT + 1, RelZ) != E_BLOCK_AIR) + { + OnHitSolidBlock(GetPosition(), BLOCK_FACE_YM); + return; + } + } - Vector3d PerTickSpeed = GetSpeed() / 20; - Vector3d Pos = GetPosition(); +setspeed: + AddSpeedY(1); + AddPosition(GetSpeed() * (a_Dt / 1000)); +} - // Trace the tick's worth of movement as a line: - Vector3d NextPos = Pos + PerTickSpeed; - cProjectileTracerCallback TracerCallback(this); - if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos)) + + + + +void cFireworkEntity::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + + if (m_ExplodeTimer == m_FireworkItem.m_FireworkItem.m_FlightTimeInTicks) { - // Something has been hit, abort all other processing - return; + m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_FIREWORK_EXPLODE); + Destroy(); } - // The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff - - // Update the position: - SetPosition(NextPos); - // Add slowdown and gravity effect to the speed: - Vector3d NewSpeed(GetSpeed()); - NewSpeed.y += 2; - NewSpeed *= TracerCallback.GetSlowdownCoeff(); - SetSpeed(NewSpeed); + m_ExplodeTimer++; } diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index e80592999..fac592d16 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -46,7 +46,7 @@ public: cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, double a_Width, double a_Height); cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height); - static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d * a_Speed = NULL); + static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item, const Vector3d * a_Speed = NULL); /// Called by the physics blocktracer when the entity hits a solid block, the hit position and the face hit (BLOCK_FACE_) is given virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace); @@ -305,13 +305,19 @@ public: CLASS_PROTODEF(cFireworkEntity); - cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z); + cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item); + const cItem & GetItem(void) const { return m_FireworkItem; } protected: // cProjectileEntity overrides: - virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + +private: + + int m_ExplodeTimer; + cItem m_FireworkItem; // tolua_begin diff --git a/src/Item.cpp b/src/Item.cpp index 9170006b6..61d57e763 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -1,4 +1,4 @@ - + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Item.h" @@ -139,6 +139,16 @@ void cItem::GetJson(Json::Value & a_OutValue) const { a_OutValue["Lore"] = m_Lore; } + + if ((m_ItemType == E_ITEM_FIREWORK_ROCKET) || (m_ItemType == E_ITEM_FIREWORK_STAR)) + { + a_OutValue["Flicker"] = m_FireworkItem.m_HasFlicker; + a_OutValue["Trail"] = m_FireworkItem.m_HasTrail; + a_OutValue["Type"] = m_FireworkItem.m_Type; + a_OutValue["FlightTimeInTicks"] = m_FireworkItem.m_FlightTimeInTicks; + a_OutValue["Colours"] = m_FireworkItem.ColoursToString(m_FireworkItem); + a_OutValue["FadeColours"] = m_FireworkItem.FadeColoursToString(m_FireworkItem); + } } } @@ -157,6 +167,16 @@ void cItem::FromJson(const Json::Value & a_Value) m_Enchantments.AddFromString(a_Value.get("ench", "").asString()); m_CustomName = a_Value.get("Name", "").asString(); m_Lore = a_Value.get("Lore", "").asString(); + + if ((m_ItemType == E_ITEM_FIREWORK_ROCKET) || (m_ItemType == E_ITEM_FIREWORK_STAR)) + { + m_FireworkItem.m_HasFlicker = a_Value.get("Flicker", false).asBool(); + m_FireworkItem.m_HasTrail = a_Value.get("Trail", false).asBool(); + m_FireworkItem.m_Type = (NIBBLETYPE)a_Value.get("Type", 0).asInt(); + m_FireworkItem.m_FlightTimeInTicks = (short)a_Value.get("FlightTimeInTicks", 0).asInt(); + m_FireworkItem.ColoursFromString(a_Value.get("Colours", "").asString(), m_FireworkItem); + m_FireworkItem.FadeColoursFromString(a_Value.get("FadeColours", "").asString(), m_FireworkItem); + } } } diff --git a/src/Item.h b/src/Item.h index cc3b3c961..4bdfb12dd 100644 --- a/src/Item.h +++ b/src/Item.h @@ -11,6 +11,7 @@ #include "Defines.h" #include "Enchantments.h" +#include "WorldStorage/FireworksSerializer.h" @@ -38,7 +39,8 @@ public: m_ItemCount(0), m_ItemDamage(0), m_CustomName(""), - m_Lore("") + m_Lore(""), + m_FireworkItem() { } @@ -57,7 +59,8 @@ public: m_ItemDamage (a_ItemDamage), m_Enchantments(a_Enchantments), m_CustomName (a_CustomName), - m_Lore (a_Lore) + m_Lore (a_Lore), + m_FireworkItem() { if (!IsValidItem(m_ItemType)) { @@ -77,7 +80,8 @@ public: m_ItemDamage (a_CopyFrom.m_ItemDamage), m_Enchantments(a_CopyFrom.m_Enchantments), m_CustomName (a_CopyFrom.m_CustomName), - m_Lore (a_CopyFrom.m_Lore) + m_Lore (a_CopyFrom.m_Lore), + m_FireworkItem(a_CopyFrom.m_FireworkItem) { } @@ -90,6 +94,7 @@ public: m_Enchantments.Clear(); m_CustomName = ""; m_Lore = ""; + m_FireworkItem.EmptyData(); } @@ -115,7 +120,8 @@ public: (m_ItemDamage == a_Item.m_ItemDamage) && (m_Enchantments == a_Item.m_Enchantments) && (m_CustomName == a_Item.m_CustomName) && - (m_Lore == a_Item.m_Lore) + (m_Lore == a_Item.m_Lore) && + m_FireworkItem.IsEqualTo(a_Item.m_FireworkItem) ); } @@ -177,6 +183,8 @@ public: cEnchantments m_Enchantments; AString m_CustomName; AString m_Lore; + + cFireworkItem m_FireworkItem; }; // tolua_end diff --git a/src/Items/ItemThrowable.h b/src/Items/ItemThrowable.h index 46049f961..c6a4e714e 100644 --- a/src/Items/ItemThrowable.h +++ b/src/Items/ItemThrowable.h @@ -35,7 +35,7 @@ public: Vector3d Pos = a_Player->GetThrowStartPos(); Vector3d Speed = a_Player->GetLookVector() * m_SpeedCoeff; - a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, &Speed); + a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, m_ProjectileKind, a_Player, a_Player->GetEquippedItem(), &Speed); return true; } @@ -127,13 +127,13 @@ public: return false; } + a_World->CreateProjectile(a_BlockX + 0.5, a_BlockY + 1, a_BlockZ + 0.5, m_ProjectileKind, a_Player, a_Player->GetEquippedItem()); + if (!a_Player->IsGameModeCreative()) { a_Player->GetInventory().RemoveOneEquippedItem(); } - a_World->CreateProjectile(a_BlockX + 0.5, a_BlockY + 1, a_BlockZ + 0.5, m_ProjectileKind, a_Player, 0); - return true; } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 992023464..e0f02930c 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2069,36 +2069,47 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) // Load enchantments and custom display names from the NBT data: for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag)) { - if ( - (NBT.GetType(tag) == TAG_List) && - ( - (NBT.GetName(tag) == "ench") || - (NBT.GetName(tag) == "StoredEnchantments") - ) - ) + AString TagName = NBT.GetName(tag); + switch (NBT.GetType(tag)) { - EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag); - } - else if ((NBT.GetType(tag) == TAG_Compound) && (NBT.GetName(tag) == "display")) // Custom name and lore tag - { - for (int displaytag = NBT.GetFirstChild(tag); displaytag >= 0; displaytag = NBT.GetNextSibling(displaytag)) + case TAG_List: { - if ((NBT.GetType(displaytag) == TAG_String) && (NBT.GetName(displaytag) == "Name")) // Custon name tag + if ((TagName == "ench") || (TagName == "StoredEnchantments")) // Enchantments tags { - a_Item.m_CustomName = NBT.GetString(displaytag); + EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag); } - else if ((NBT.GetType(displaytag) == TAG_List) && (NBT.GetName(displaytag) == "Lore")) // Lore tag + break; + } + case TAG_Compound: + { + if (TagName == "display") // Custom name and lore tag { - AString Lore; - - for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings + for (int displaytag = NBT.GetFirstChild(tag); displaytag >= 0; displaytag = NBT.GetNextSibling(displaytag)) { - AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a newline, used internally by MCS to display a new line in the client; don't forget to c_str ;) + if ((NBT.GetType(displaytag) == TAG_String) && (NBT.GetName(displaytag) == "Name")) // Custon name tag + { + a_Item.m_CustomName = NBT.GetString(displaytag); + } + else if ((NBT.GetType(displaytag) == TAG_List) && (NBT.GetName(displaytag) == "Lore")) // Lore tag + { + AString Lore; + + for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings + { + AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a newline, used internally by MCS to display a new line in the client; don't forget to c_str ;) + } + + a_Item.m_Lore = Lore; + } } - - a_Item.m_Lore = Lore; } + else if ((TagName == "Fireworks") || (TagName == "Explosion")) + { + cFireworkItem::ParseFromNBT(a_Item.m_FireworkItem, NBT, tag, (ENUM_ITEM_ID)a_Item.m_ItemType); + } + break; } + default: LOGD("Unimplemented NBT data when parsing!"); break; } } } @@ -2262,7 +2273,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) WriteByte (a_Item.m_ItemCount); WriteShort(a_Item.m_ItemDamage); - if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty()) + if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR)) { WriteShort(-1); return; @@ -2301,6 +2312,10 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) } Writer.EndCompound(); } + if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) + { + cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, (ENUM_ITEM_ID)a_Item.m_ItemType); + } Writer.Finish(); AString Compressed; CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); @@ -2465,10 +2480,22 @@ void cProtocol172::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity) } case cEntity::etProjectile: { - if (((cProjectileEntity &)a_Entity).GetProjectileKind() == cProjectileEntity::pkArrow) + cProjectileEntity & Projectile = (cProjectileEntity &)a_Entity; + switch (Projectile.GetProjectileKind()) { - WriteByte(0x10); - WriteByte(((const cArrowEntity &)a_Entity).IsCritical() ? 1 : 0); + case cProjectileEntity::pkArrow: + { + WriteByte(0x10); + WriteByte(((const cArrowEntity &)a_Entity).IsCritical() ? 1 : 0); + break; + } + case cProjectileEntity::pkFirework: + { + WriteByte(0xA8); + WriteItem(((const cFireworkEntity &)a_Entity).GetItem()); + break; + } + default: break; } break; } diff --git a/src/World.cpp b/src/World.cpp index ffdae2a37..ffb463169 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2904,9 +2904,9 @@ int cWorld::SpawnMobFinalize(cMonster * a_Monster) -int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const Vector3d * a_Speed) +int cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem a_Item, const Vector3d * a_Speed) { - cProjectileEntity * Projectile = cProjectileEntity::Create(a_Kind, a_Creator, a_PosX, a_PosY, a_PosZ, a_Speed); + cProjectileEntity * Projectile = cProjectileEntity::Create(a_Kind, a_Creator, a_PosX, a_PosY, a_PosZ, a_Item, a_Speed); if (Projectile == NULL) { return -1; diff --git a/src/World.h b/src/World.h index 4b74f7aba..4fdbd8c0d 100644 --- a/src/World.h +++ b/src/World.h @@ -693,7 +693,7 @@ public: int SpawnMobFinalize(cMonster* a_Monster); /** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise */ - int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const Vector3d * a_Speed = NULL); // tolua_export + int CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem a_Item, const Vector3d * a_Speed = NULL); // tolua_export /** Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread! */ int GetTickRandomNumber(unsigned a_Range) { return (int)(m_TickRand.randInt(a_Range)); } diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index a78b610cb..e7e56282f 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -266,7 +266,7 @@ protected: eTagType m_ItemType; // for TAG_List, the element type } ; - static const int MAX_STACK = 50; // Highliy doubtful that an NBT would be constructed this many levels deep + static const int MAX_STACK = 50; // Highly doubtful that an NBT would be constructed this many levels deep // These two fields emulate a stack. A raw array is used due to speed issues - no reallocations are allowed. sParent m_Stack[MAX_STACK]; diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp new file mode 100644 index 000000000..eeb4e39ee --- /dev/null +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -0,0 +1,250 @@ + +#include "Globals.h" +#include "FireworksSerializer.h" +#include "WorldStorage/FastNBT.h" +#include + + + + + +void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFastNBTWriter & a_Writer, const ENUM_ITEM_ID a_Type) +{ + switch (a_Type) + { + case E_ITEM_FIREWORK_ROCKET: + { + a_Writer.BeginCompound("Fireworks"); + a_Writer.AddByte("Flight", a_FireworkItem.m_FlightTimeInTicks / 20); + a_Writer.BeginList("Explosions", TAG_Compound); + a_Writer.BeginCompound(""); + a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker); + a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail); + a_Writer.AddByte("Type", a_FireworkItem.m_Type); + a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size()); + a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size()); + a_Writer.EndCompound(); + a_Writer.EndList(); + a_Writer.EndCompound(); + break; + } + case E_ITEM_FIREWORK_STAR: + { + a_Writer.BeginCompound("Explosion"); + a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker); + a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail); + a_Writer.AddByte("Type", a_FireworkItem.m_Type); + if (!a_FireworkItem.m_Colours.empty()) + { + a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size()); + } + if (!a_FireworkItem.m_FadeColours.empty()) + { + a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size()); + } + a_Writer.EndCompound(); + break; + } + default: ASSERT(!"Unhandled firework item!"); break; + } +} + + + + + +void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNBT & a_NBT, int a_TagIdx, const ENUM_ITEM_ID a_Type) +{ + if (a_TagIdx < 0) + { + return; + } + + switch (a_Type) + { + case E_ITEM_FIREWORK_STAR: + { + for (int explosiontag = a_NBT.GetFirstChild(a_TagIdx); explosiontag >= 0; explosiontag = a_NBT.GetNextSibling(explosiontag)) + { + eTagType TagType = a_NBT.GetType(explosiontag); + if (TagType == TAG_Byte) // Custon name tag + { + AString ExplosionName = a_NBT.GetName(explosiontag); + + if (ExplosionName == "Flicker") + { + a_FireworkItem.m_HasFlicker = (a_NBT.GetByte(explosiontag) == 1); + } + else if (ExplosionName == "Trail") + { + a_FireworkItem.m_HasTrail = (a_NBT.GetByte(explosiontag) == 1); + } + else if (ExplosionName == "Type") + { + a_FireworkItem.m_Type = a_NBT.GetByte(explosiontag); + } + } + else if (TagType == TAG_IntArray) + { + AString ExplosionName = a_NBT.GetName(explosiontag); + + if (ExplosionName == "Colors") + { + if (a_NBT.GetDataLength(explosiontag) == 0) + { + continue; + } + + const int * ColourData = (const int *)(a_NBT.GetData(explosiontag)); + for (int i = 0; i < ARRAYCOUNT(ColourData); i++) + { + a_FireworkItem.m_Colours.push_back(ntohl(ColourData[i])); + } + } + else if (ExplosionName == "FadeColors") + { + if (a_NBT.GetDataLength(explosiontag) == 0) + { + continue; + } + + const int * FadeColourData = (const int *)(a_NBT.GetData(explosiontag)); + for (int i = 0; i < ARRAYCOUNT(FadeColourData); i++) + { + a_FireworkItem.m_FadeColours.push_back(ntohl(FadeColourData[i])); + } + } + } + } + break; + } + case E_ITEM_FIREWORK_ROCKET: + { + for (int fireworkstag = a_NBT.GetFirstChild(a_TagIdx); fireworkstag >= 0; fireworkstag = a_NBT.GetNextSibling(fireworkstag)) + { + eTagType TagType = a_NBT.GetType(fireworkstag); + if (TagType == TAG_Byte) // Custon name tag + { + if (a_NBT.GetName(fireworkstag) == "Flight") + { + a_FireworkItem.m_FlightTimeInTicks = a_NBT.GetByte(fireworkstag) * 20; + } + } + else if ((TagType == TAG_List) && (a_NBT.GetName(fireworkstag) == "Explosions")) + { + int ExplosionsChild = a_NBT.GetFirstChild(fireworkstag); + if ((a_NBT.GetType(ExplosionsChild) == TAG_Compound) && (a_NBT.GetName(ExplosionsChild).empty())) + { + ParseFromNBT(a_FireworkItem, a_NBT, ExplosionsChild, E_ITEM_FIREWORK_STAR); + } + } + } + break; + } + default: ASSERT(!"Unhandled firework item!"); break; + } +} + + + + + +AString cFireworkItem::ColoursToString(const cFireworkItem & a_FireworkItem) +{ + AString Result; + + for (std::vector::const_iterator itr = a_FireworkItem.m_Colours.begin(); itr != a_FireworkItem.m_Colours.end(); ++itr) + { + AppendPrintf(Result, "%i;", *itr); + } + + return Result; +} + + + + + +void cFireworkItem::ColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem) +{ + AStringVector Split = StringSplit(a_String, ";"); + + for (size_t itr = 0; itr < Split.size(); ++itr) + { + if (Split[itr].empty()) + { + continue; + } + + a_FireworkItem.m_Colours.push_back(atoi(Split[itr].c_str())); + } +} + + + + + +AString cFireworkItem::FadeColoursToString(const cFireworkItem & a_FireworkItem) +{ + AString Result; + + for (std::vector::const_iterator itr = a_FireworkItem.m_FadeColours.begin(); itr != a_FireworkItem.m_FadeColours.end(); ++itr) + { + AppendPrintf(Result, "%i;", *itr); + } + + return Result; +} + + + + + +void cFireworkItem::FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem) +{ + AStringVector Split = StringSplit(a_String, ";"); + + for (size_t itr = 0; itr < Split.size(); ++itr) + { + if (Split[itr].empty()) + { + continue; + } + + a_FireworkItem.m_FadeColours.push_back(atoi(Split[itr].c_str())); + } +} + + + + + +int GetVanillaColourCodeFromDye(short a_DyeMeta) +{ + /* + Colours are supposed to be calculated via: R << 16 + G << 8 + B + However, the RGB values fireworks use aren't the same as the ones for dyes (the ones listed in the MC Wiki) + Therefore, here is a list of numbers gotten via the Protocol Proxy + */ + + switch (a_DyeMeta) + { + case E_META_DYE_BLACK: return 1973019; + case E_META_DYE_RED: return 11743532; + case E_META_DYE_GREEN: return 3887386; + case E_META_DYE_BROWN: return 5320730; + case E_META_DYE_BLUE: return 2437522; + case E_META_DYE_PURPLE: return 8073150; + case E_META_DYE_CYAN: return 2651799; + case E_META_DYE_LIGHTGRAY: return 11250603; + case E_META_DYE_GRAY: return 4408131; + case E_META_DYE_PINK: return 14188952; + case E_META_DYE_LIGHTGREEN: return 4312372; + case E_META_DYE_YELLOW: return 14602026; + case E_META_DYE_LIGHTBLUE: return 6719955; + case E_META_DYE_MAGENTA: return 12801229; + case E_META_DYE_ORANGE: return 15435844; + case E_META_DYE_WHITE: return 15790320; + default: ASSERT(!"Unhandled dye meta whilst trying to get colour code for fireworks!"); break; + } +} diff --git a/src/WorldStorage/FireworksSerializer.h b/src/WorldStorage/FireworksSerializer.h new file mode 100644 index 000000000..475d80bda --- /dev/null +++ b/src/WorldStorage/FireworksSerializer.h @@ -0,0 +1,88 @@ + +// FireworksSerializer.h + +// Declares the cFireworkItem class representing a firework or firework star + + + + + +#pragma once + +#include "Defines.h" + +class cFastNBTWriter; +class cParsedNBT; + + + + + +class cFireworkItem +{ +public: + cFireworkItem(void) : + m_HasFlicker(false), + m_HasTrail(false), + m_Type(0), + m_FlightTimeInTicks(0) + { + } + + inline void CopyFrom(const cFireworkItem & a_Item) + { + m_FlightTimeInTicks = a_Item.m_FlightTimeInTicks; + m_HasFlicker = a_Item.m_HasFlicker; + m_HasTrail = a_Item.m_HasTrail; + m_Type = a_Item.m_Type; + m_Colours = a_Item.m_Colours; + m_FadeColours = a_Item.m_FadeColours; + } + + inline void EmptyData(void) + { + m_FlightTimeInTicks = 0; + m_HasFlicker = false; + m_Type = 0; + m_HasTrail = false; + m_Colours.clear(); + m_FadeColours.clear(); + } + + inline bool IsEqualTo(const cFireworkItem & a_Item) const + { + return + ( + (m_FlightTimeInTicks == a_Item.m_FlightTimeInTicks) && + (m_HasFlicker == a_Item.m_HasFlicker) && + (m_HasTrail == a_Item.m_HasTrail) && + (m_Type == a_Item.m_Type) && + (m_Colours == a_Item.m_Colours) && + (m_FadeColours == a_Item.m_FadeColours) + ); + } + + /** Writes firework NBT data to a Writer object */ + static void WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFastNBTWriter & a_Writer, const ENUM_ITEM_ID a_Type); + /** Reads NBT data from a NBT object and populates a FireworkItem with it */ + static void ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNBT & a_NBT, int a_TagIdx, const ENUM_ITEM_ID a_Type); + + /** Converts the firework's vector of colours into a string of values separated by a semicolon */ + static AString ColoursToString(const cFireworkItem & a_FireworkItem); + /** Parses a string containing encoded firework colours and populates a FireworkItem with it */ + static void ColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem); + /** Converts the firework's vector of fade colours into a string of values separated by a semicolon */ + static AString FadeColoursToString(const cFireworkItem & a_FireworkItem); + /** Parses a string containing encoded firework fade colours and populates a FireworkItem with it */ + static void FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem); + + /** Returns a colour code for fireworks used by the network code */ + static const inline int GetVanillaColourCodeFromDye(short a_DyeMeta); + + bool m_HasFlicker; + bool m_HasTrail; + NIBBLETYPE m_Type; + short m_FlightTimeInTicks; + std::vector m_Colours; + std::vector m_FadeColours; +}; \ No newline at end of file diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index c1c659b36..6d82cba86 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -90,11 +90,19 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin } // Write the enchantments: - if (!a_Item.m_Enchantments.IsEmpty()) + if (!a_Item.m_Enchantments.IsEmpty() || ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR))) { - const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; m_Writer.BeginCompound("tag"); - EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, m_Writer, TagName); + if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) + { + cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, m_Writer, (ENUM_ITEM_ID)a_Item.m_ItemType); + } + + if (!a_Item.m_Enchantments.IsEmpty()) + { + const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; + EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, m_Writer, TagName); + } m_Writer.EndCompound(); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 05332d23d..0658d5029 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -658,6 +658,12 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_ { EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, a_NBT, EnchTag); } + + int FireworksTag = a_NBT.FindChildByName(TagTag, ((a_Item.m_ItemType == E_ITEM_FIREWORK_STAR) ? "Fireworks" : "Explosion")); + if (EnchTag > 0) + { + cFireworkItem::ParseFromNBT(a_Item.m_FireworkItem, a_NBT, FireworksTag, (ENUM_ITEM_ID)a_Item.m_ItemType); + } return true; } -- cgit v1.2.3 From a97f28939fb706cbe26bc0de400c7bf2f14f19f4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 26 Feb 2014 23:30:10 +0000 Subject: Fixed sheep ASSERTing sometimes --- src/Mobs/Sheep.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index 4761103e5..c64360153 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -68,17 +68,28 @@ void cSheep::OnRightClicked(cPlayer & a_Player) void cSheep::Tick(float a_Dt, cChunk & a_Chunk) { - // The sheep should not move when he's eating so only handle the physics. + super::Tick(a_Dt, a_Chunk); + int PosX = POSX_TOINT; + int PosY = POSY_TOINT - 1; + int PosZ = POSZ_TOINT; + + if ((PosY <= 0) || (PosY > cChunkDef::Height)) + { + return; + } + if (m_TimeToStopEating > 0) { - HandlePhysics(a_Dt, a_Chunk); + m_bMovingToDestination = false; // The sheep should not move when he's eating m_TimeToStopEating--; + if (m_TimeToStopEating == 0) { - if (m_World->GetBlock((int) GetPosX(), (int) GetPosY() - 1, (int) GetPosZ()) == E_BLOCK_GRASS) + if (m_World->GetBlock(PosX, PosY, PosZ) == E_BLOCK_GRASS) // Make sure grass hasn't been destroyed in the meantime { - // The sheep ate the grass so we change it to dirt. - m_World->SetBlock((int) GetPosX(), (int) GetPosY() - 1, (int) GetPosZ(), E_BLOCK_DIRT, 0); + // The sheep ate the grass so we change it to dirt + m_World->SetBlock(PosX, PosY, PosZ, E_BLOCK_DIRT, 0); + GetWorld()->BroadcastSoundParticleEffect(2001, PosX, PosY, PosX, E_BLOCK_GRASS); m_IsSheared = false; m_World->BroadcastEntityMetadata(*this); } @@ -86,12 +97,11 @@ void cSheep::Tick(float a_Dt, cChunk & a_Chunk) } else { - super::Tick(a_Dt, a_Chunk); if (m_World->GetTickRandomNumber(600) == 1) { - if (m_World->GetBlock((int) GetPosX(), (int) GetPosY() - 1, (int) GetPosZ()) == E_BLOCK_GRASS) + if (m_World->GetBlock(PosX, PosY, PosZ) == E_BLOCK_GRASS) { - m_World->BroadcastEntityStatus(*this, 10); + m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_SHEEP_EATING); m_TimeToStopEating = 40; } } -- cgit v1.2.3 From 84913299f45a28d3bd6146b3decbf14764449030 Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 27 Feb 2014 11:33:35 -0800 Subject: Added some Metadate rotaters using templated Mixin --- src/Blocks/BlockBed.h | 5 +-- src/Blocks/BlockButton.h | 4 +-- src/Blocks/BlockChest.h | 4 +-- src/Blocks/BlockComparator.h | 4 +-- src/Blocks/BlockDoor.cpp | 2 +- src/Blocks/BlockDoor.h | 57 +++++++++++++++++++++++++++++- src/Blocks/BlockDropSpenser.h | 18 ++++++++-- src/Blocks/BlockEnderchest.h | 4 +-- src/Blocks/BlockFenceGate.h | 4 +-- src/Blocks/MetaRotater.h | 82 +++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 168 insertions(+), 16 deletions(-) create mode 100644 src/Blocks/MetaRotater.h diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index caec2b56f..6e8884114 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -4,6 +4,7 @@ #include "BlockHandler.h" #include "ChunkInterface.h" #include "WorldInterface.h" +#include "MetaRotater.h" #include "../Entities/Player.h" @@ -11,11 +12,11 @@ class cBlockBedHandler : - public cBlockHandler + public cMetaRotater { public: cBlockBedHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index ca6850ced..5a4bf7c96 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -7,11 +7,11 @@ class cBlockButtonHandler : - public cBlockHandler + public cMetaRotater { public: cBlockButtonHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 02ecc4346..4ab23bced 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -10,11 +10,11 @@ class cBlockChestHandler : - public cBlockEntityHandler + public cMetaRotater { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index aba390d9d..7e672eece 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -9,11 +9,11 @@ class cBlockComparatorHandler : - public cBlockHandler + public cMetaRotater { public: cBlockComparatorHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 2ff5c1c37..f0d0b4b7f 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -9,7 +9,7 @@ cBlockDoorHandler::cBlockDoorHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : super(a_BlockType) { } diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index ef0dbb787..c3647b203 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -9,8 +9,9 @@ class cBlockDoorHandler : - public cBlockHandler + public cMetaRotater { + typedef super cMetaRotater; public: cBlockDoorHandler(BLOCKTYPE a_BlockType); @@ -167,6 +168,60 @@ public: } + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override + { + if (a_Meta & 0x08) + { + return a_Meta; + } + else + { + return super::MetaRotateCCW(a_Meta); + } + } + + + + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override + { + if (a_Meta & 0x08) + { + return a_Meta; + } + else + { + return super::MetaRotateCW(a_Meta); + } + } + + + + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override + { + if (a_Meta & 0x08) + { + return a_Meta; + } + else + { + return super::MetaMirrorXY(a_Meta); + } + } + + + + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override + { + if (a_Meta & 0x08) + { + return a_Meta; + } + else + { + return super::MetaMirrorYZ(a_Meta); + } + } + } ; diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h index 30d347ec9..2253fcd1b 100644 --- a/src/Blocks/BlockDropSpenser.h +++ b/src/Blocks/BlockDropSpenser.h @@ -12,11 +12,11 @@ class cBlockDropSpenserHandler : - public cBlockEntityHandler + public cMetaRotater { public: cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) : - cBlockEntityHandler(a_BlockType) + cMetaRotater(a_BlockType) { } @@ -34,6 +34,20 @@ public: a_BlockMeta = cPiston::RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch()); return true; } + + virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag. Lowest three bits are position. 0x08 == 1000 + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Mirrors defined by by a table. (Source, mincraft.gamepedia.com) 0x07 == 0111 + switch (a_Meta & 0x07) + { + case 0x00: return 0x01 + OtherMeta; // Down -> Up + case 0x01: return 0x00 + OtherMeta; // Up -> Down + } + // Not Facing Up or Down; No change. + return a_Meta; + } } ; diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h index b4b0b995d..ed3f37013 100644 --- a/src/Blocks/BlockEnderchest.h +++ b/src/Blocks/BlockEnderchest.h @@ -8,11 +8,11 @@ class cBlockEnderchestHandler : - public cBlockEntityHandler + public cMetaRotater { public: cBlockEnderchestHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index fb984f345..035579e8e 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -8,11 +8,11 @@ class cBlockFenceGateHandler : - public cBlockHandler + public cMetaRotater { public: cBlockFenceGateHandler(BLOCKTYPE a_BlockType) : - cBlockHandler(a_BlockType) + cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/MetaRotater.h b/src/Blocks/MetaRotater.h new file mode 100644 index 000000000..f1656f1bd --- /dev/null +++ b/src/Blocks/MetaRotater.h @@ -0,0 +1,82 @@ + +#pragma once + +template +class cMetaRotater : public Base +{ +public: + + cMetaRotater(BLOCKTYPE a_BlockType) : + Base(a_BlockType) + {} + + virtual ~cMetaRotater() {} + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override; +}; + + +template +NIBBLETYPE cMetaRotater::MetaRotateCW(NIBBLETYPE a_Meta) +{ +NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); +switch (a_Meta & BitFilter) +{ +case South: return West | OtherMeta; +case West: return North | OtherMeta; +case North: return East | OtherMeta; +case East: return South | OtherMeta; +} +ASSERT(!"Invalid Meta value"); +return a_Meta; +} + + +template +NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) +{ +NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); +switch (a_Meta & BitFilter) +{ +case South: return East | OtherMeta; +case East: return North | OtherMeta; +case North: return West | OtherMeta; +case West: return South | OtherMeta; +} +ASSERT(!"Invalid Meta value"); +return a_Meta; +} + + + +template +NIBBLETYPE cMetaRotater::MetaMirrorXY(NIBBLETYPE a_Meta) +{ +NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); +switch (a_Meta & BitFilter) +{ +case South: return North | OtherMeta; +case North: return South | OtherMeta; +} +// Not Facing North or South; No change. +return a_Meta; +} + + + + +template +NIBBLETYPE cMetaRotater::MetaMirrorYZ(NIBBLETYPE a_Meta) +{ +NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); +switch (a_Meta & BitFilter) +{ +case West: return East | OtherMeta; +case East: return West | OtherMeta; +} +// Not Facing East or West; No change. +return a_Meta; +} -- cgit v1.2.3 From 528467bc5c514d8ef193c4e9dd06fb5aeb9f0dd9 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 27 Feb 2014 21:48:49 +0000 Subject: Fixed compile --- src/WorldStorage/FireworksSerializer.cpp | 3 +-- src/WorldStorage/FireworksSerializer.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index eeb4e39ee..7f5077912 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -2,7 +2,6 @@ #include "Globals.h" #include "FireworksSerializer.h" #include "WorldStorage/FastNBT.h" -#include @@ -219,7 +218,7 @@ void cFireworkItem::FadeColoursFromString(const AString & a_String, cFireworkIte -int GetVanillaColourCodeFromDye(short a_DyeMeta) +int cFireworkItem::GetVanillaColourCodeFromDye(short a_DyeMeta) { /* Colours are supposed to be calculated via: R << 16 + G << 8 + B diff --git a/src/WorldStorage/FireworksSerializer.h b/src/WorldStorage/FireworksSerializer.h index 475d80bda..37fb6c883 100644 --- a/src/WorldStorage/FireworksSerializer.h +++ b/src/WorldStorage/FireworksSerializer.h @@ -77,7 +77,7 @@ public: static void FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem); /** Returns a colour code for fireworks used by the network code */ - static const inline int GetVanillaColourCodeFromDye(short a_DyeMeta); + static int GetVanillaColourCodeFromDye(short a_DyeMeta); bool m_HasFlicker; bool m_HasTrail; -- cgit v1.2.3 From 9ac9249acaf21d01af41b4cdfc862961b1f9e286 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 27 Feb 2014 21:49:10 +0000 Subject: Removed unneeded includes in Player.cpp --- src/Entities/Player.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 0152bfc5b..f4039e548 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -10,18 +10,11 @@ #include "../BlockEntities/BlockEntity.h" #include "../GroupManager.h" #include "../Group.h" -#include "../ChatColor.h" -#include "../Item.h" -#include "../Tracer.h" #include "../Root.h" #include "../OSSupport/Timer.h" -#include "../MersenneTwister.h" #include "../Chunk.h" #include "../Items/ItemHandler.h" -#include "../Vector3d.h" -#include "../Vector3f.h" - #include "inifile/iniFile.h" #include "json/json.h" -- cgit v1.2.3 From 35def963f06dd46823300aebf09af0009189328b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Feb 2014 15:31:20 +0100 Subject: Moved common cGroupManager code to a separate function. This fixes my concerns in PR #709. --- src/Entities/Player.cpp | 18 +++++++++++------- src/GroupManager.cpp | 21 ++++++++++++++++----- src/GroupManager.h | 3 +++ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index e0f0b9222..f419ee09c 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1529,14 +1529,14 @@ void cPlayer::LoadPermissionsFromDisk() std::string Groups = IniFile.GetValue(m_PlayerName, "Groups", ""); if (!Groups.empty()) { - AStringVector Split = StringSplit( Groups, "," ); - for( unsigned int i = 0; i < Split.size(); i++ ) + AStringVector Split = StringSplitAndTrim(Groups, ","); + for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr) { - if (!cRoot::Get()->GetGroupManager()->ExistsGroup(Split[i])) + if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr)) { - LOGWARNING("The group %s for player %s was not found!", Split[i].c_str(), m_PlayerName.c_str()); + LOGWARNING("The group %s for player %s was not found!", itr->c_str(), m_PlayerName.c_str()); } - AddToGroup(Split[i].c_str()); + AddToGroup(*itr); } } else @@ -1544,11 +1544,15 @@ void cPlayer::LoadPermissionsFromDisk() AddToGroup("Default"); } - m_Color = IniFile.GetValue(m_PlayerName, "Color", "-")[0]; + AString Color = IniFile.GetValue(m_PlayerName, "Color", "-"); + if (!Color.empty()) + { + m_Color = Color[0]; + } } else { - cRoot::Get()->GetGroupManager()->CheckUsers(); + cGroupManager::GenerateDefaultUsersIni(IniFile); AddToGroup("Default"); } ResolvePermissions(); diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp index 5125e7586..33b601e82 100644 --- a/src/GroupManager.cpp +++ b/src/GroupManager.cpp @@ -55,16 +55,27 @@ cGroupManager::cGroupManager() +void cGroupManager::GenerateDefaultUsersIni(cIniFile & a_IniFile) +{ + LOGWARN("Regenerating users.ini, all users will be reset"); + a_IniFile.AddHeaderComment(" This file stores the players' groups."); + a_IniFile.AddHeaderComment(" The format is:"); + a_IniFile.AddHeaderComment(" [PlayerName]"); + a_IniFile.AddHeaderComment(" Groups = GroupName1, GroupName2, ..."); + + a_IniFile.WriteFile("users.ini"); +} + + + + + void cGroupManager::CheckUsers(void) { cIniFile IniFile; if (!IniFile.ReadFile("users.ini")) { - LOGWARN("Regenerating users.ini, all users will be reset"); - IniFile.AddHeaderComment(" This is the file in which the group the player belongs to is stored"); - IniFile.AddHeaderComment(" The format is: [PlayerName] | Groups=GroupName"); - - IniFile.WriteFile("users.ini"); + GenerateDefaultUsersIni(IniFile); return; } diff --git a/src/GroupManager.h b/src/GroupManager.h index 377a54c98..9e1689a76 100644 --- a/src/GroupManager.h +++ b/src/GroupManager.h @@ -19,6 +19,9 @@ public: void LoadGroups(void); void CheckUsers(void); + /** Writes the default header to the specified ini file, and saves it as "users.ini". */ + static void GenerateDefaultUsersIni(cIniFile & a_IniFile); + private: friend class cRoot; cGroupManager(); -- cgit v1.2.3 From d97363a1b39fd94a77bb84a4d9732ab4f46b08b7 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Feb 2014 15:41:46 +0100 Subject: Documented the changes in cJukeboxEntity. --- MCServer/Plugins/APIDump/Classes/BlockEntities.lua | 6 ++++-- src/BlockEntities/JukeboxEntity.h | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/MCServer/Plugins/APIDump/Classes/BlockEntities.lua b/MCServer/Plugins/APIDump/Classes/BlockEntities.lua index cf258160c..61a8e8d22 100644 --- a/MCServer/Plugins/APIDump/Classes/BlockEntities.lua +++ b/MCServer/Plugins/APIDump/Classes/BlockEntities.lua @@ -196,9 +196,11 @@ World:ForEachChestInChunk(Player:GetChunkX(), Player:GetChunkZ(), Inherits = "cBlockEntity", Functions = { - EjectRecord = { Params = "", Return = "", Notes = "Ejects the current record as a {{cPickup|pickup}}. No action if there's no current record. To remove record without generating the pickup, use SetRecord(0)" }, + EjectRecord = { Params = "", Return = "bool", Notes = "Ejects the current record as a {{cPickup|pickup}}. No action if there's no current record. To remove record without generating the pickup, use SetRecord(0). Returns true if pickup ejected." }, GetRecord = { Params = "", Return = "number", Notes = "Returns the record currently present. Zero for no record, E_ITEM_*_DISC for records." }, - PlayRecord = { Params = "", Return = "", Notes = "Plays the currently present record. No action if there's no current record." }, + IsPlayingRecord = { Params = "", Return = "bool", Notes = "Returns true if the jukebox is playing a record." }, + IsRecordItem = { Params = "ItemType", Return = "bool", Notes = "Returns true if the specified item is a record that can be played." }, + PlayRecord = { Params = "RecordItemType", Return = "bool", Notes = "Plays the specified Record. Return false if the parameter isn't a playable Record (E_ITEM_XXX_DISC). If there is a record already playing, ejects it first." }, SetRecord = { Params = "number", Return = "", Notes = "Sets the currently present record. Use zero for no record, or E_ITEM_*_DISC for records." }, }, }, -- cJukeboxEntity diff --git a/src/BlockEntities/JukeboxEntity.h b/src/BlockEntities/JukeboxEntity.h index 01ce52494..3d1d604f7 100644 --- a/src/BlockEntities/JukeboxEntity.h +++ b/src/BlockEntities/JukeboxEntity.h @@ -38,10 +38,11 @@ public: int GetRecord(void); void SetRecord(int a_Record); - /** Play a Record. Return false, when a_Record isn't a Record */ + /** Plays the specified Record. Return false if a_Record isn't a playable Record (E_ITEM_XXX_DISC). + If there is a record already playing, ejects it first. */ bool PlayRecord(int a_Record); - /** Ejects the currently held record as a pickup. Return false when no record inserted. */ + /** Ejects the currently held record as a pickup. Return false when no record had been inserted. */ bool EjectRecord(void); /** Is in the Jukebox a Record? */ -- cgit v1.2.3 From 182646188448f9fd8df0b4c0391a2db04575c49d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Feb 2014 16:26:23 +0100 Subject: Fixed multiple gcc warnings about unused params. --- src/Entities/Painting.cpp | 11 +++++++++++ src/Entities/Painting.h | 2 +- src/HTTPServer/HTTPServer.cpp | 4 ++++ src/Items/ItemHandler.cpp | 26 +++++++++++++++++++++++++- src/OSSupport/BlockingTCPLink.cpp | 4 ++++ src/UI/SlotArea.cpp | 30 ++++++++++++++++++++++++++++++ src/UI/SlotArea.h | 6 +++--- 7 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/Entities/Painting.cpp b/src/Entities/Painting.cpp index b98c1e67a..e217556c7 100644 --- a/src/Entities/Painting.cpp +++ b/src/Entities/Painting.cpp @@ -4,6 +4,7 @@ #include "Painting.h" #include "ClientHandle.h" #include "Player.h" +#include "../Chunk.h" @@ -30,6 +31,16 @@ void cPainting::SpawnOn(cClientHandle & a_Client) +void cPainting::Tick(float a_Dt, cChunk & a_Chunk) +{ + UNUSED(a_Dt); + UNUSED(a_Chunk); +} + + + + + void cPainting::GetDrops(cItems & a_Items, cEntity * a_Killer) { if ((a_Killer != NULL) && a_Killer->IsPlayer() && !((cPlayer *)a_Killer)->IsGameModeCreative()) diff --git a/src/Entities/Painting.h b/src/Entities/Painting.h index 95afbed1e..c1024bd1b 100644 --- a/src/Entities/Painting.h +++ b/src/Entities/Painting.h @@ -24,7 +24,7 @@ public: private: virtual void SpawnOn(cClientHandle & a_Client) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override {}; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void GetDrops(cItems & a_Items, cEntity * a_Killer) override; virtual void KilledBy(cEntity * a_Killer) override { diff --git a/src/HTTPServer/HTTPServer.cpp b/src/HTTPServer/HTTPServer.cpp index f6f5b0f8b..4e9195a00 100644 --- a/src/HTTPServer/HTTPServer.cpp +++ b/src/HTTPServer/HTTPServer.cpp @@ -29,6 +29,8 @@ class cDebugCallbacks : { virtual void OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override { + UNUSED(a_Connection); + if (cHTTPFormParser::HasFormData(a_Request)) { a_Request.SetUserData(new cHTTPFormParser(a_Request, *this)); @@ -38,6 +40,8 @@ class cDebugCallbacks : virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) override { + UNUSED(a_Connection); + cHTTPFormParser * FormParser = (cHTTPFormParser *)(a_Request.GetUserData()); if (FormParser != NULL) { diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index c10d13edc..507f7fa86 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -248,6 +248,14 @@ cItemHandler::cItemHandler(int a_ItemType) bool cItemHandler::OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) { + UNUSED(a_World); + UNUSED(a_Player); + UNUSED(a_Item); + UNUSED(a_BlockX); + UNUSED(a_BlockY); + UNUSED(a_BlockZ); + UNUSED(a_Dir); + return false; } @@ -257,6 +265,14 @@ bool cItemHandler::OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & bool cItemHandler::OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) { + UNUSED(a_World); + UNUSED(a_Player); + UNUSED(a_Item); + UNUSED(a_BlockX); + UNUSED(a_BlockY); + UNUSED(a_BlockZ); + UNUSED(a_Dir); + return false; } @@ -266,6 +282,8 @@ bool cItemHandler::OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cI void cItemHandler::OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ) { + UNUSED(a_Item); + BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); cBlockHandler * Handler = cBlockHandler::GetBlockHandler(Block); @@ -288,7 +306,9 @@ void cItemHandler::OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, const void cItemHandler::OnFoodEaten(cWorld * a_World, cPlayer * a_Player, cItem * a_Item) { - + UNUSED(a_World); + UNUSED(a_Player); + UNUSED(a_Item); } @@ -461,6 +481,8 @@ bool cItemHandler::IsPlaceable(void) bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) { + UNUSED(a_BlockType); + return false; } @@ -499,6 +521,8 @@ bool cItemHandler::GetPlacementBlockTypeMeta( bool cItemHandler::EatItem(cPlayer * a_Player, cItem * a_Item) { + UNUSED(a_Item); + FoodInfo Info = GetFoodInfo(); if ((Info.FoodLevel > 0) || (Info.Saturation > 0.f)) diff --git a/src/OSSupport/BlockingTCPLink.cpp b/src/OSSupport/BlockingTCPLink.cpp index af50eda5d..e9c00d6d4 100644 --- a/src/OSSupport/BlockingTCPLink.cpp +++ b/src/OSSupport/BlockingTCPLink.cpp @@ -89,6 +89,8 @@ bool cBlockingTCPLink::Connect(const char * iAddress, unsigned int iPort) int cBlockingTCPLink::Send(char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) { + UNUSED(a_Flags); + ASSERT(m_Socket.IsValid()); if (!m_Socket.IsValid()) { @@ -104,6 +106,8 @@ int cBlockingTCPLink::Send(char * a_Data, unsigned int a_Size, int a_Flags /* = int cBlockingTCPLink::SendMessage( const char* a_Message, int a_Flags /* = 0 */ ) { + UNUSED(a_Flags); + ASSERT(m_Socket.IsValid()); if (!m_Socket.IsValid()) { diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index bfcad3d92..88977e005 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -224,6 +224,24 @@ void cSlotArea::DblClicked(cPlayer & a_Player, int a_SlotNum) +void cSlotArea::OnPlayerAdded(cPlayer & a_Player) +{ + UNUSED(a_Player); +} + + + + + +void cSlotArea::OnPlayerRemoved(cPlayer & a_Player) +{ + UNUSED(a_Player); +} + + + + + void cSlotArea::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_Apply, bool a_KeepEmptySlots) { for (int i = 0; i < m_NumSlots; i++) @@ -447,6 +465,18 @@ void cSlotAreaCrafting::OnPlayerRemoved(cPlayer & a_Player) + +void cSlotAreaCrafting::DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) +{ + UNUSED(a_ItemStack); + UNUSED(a_Player); + UNUSED(a_ShouldApply); + UNUSED(a_KeepEmptySlots); +} + + + + void cSlotAreaCrafting::ClickedResult(cPlayer & a_Player) { cItem & DraggingItem = a_Player.GetDraggingItem(); diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index d31c87e0c..25b367cff 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -48,10 +48,10 @@ public: virtual void DblClicked(cPlayer & a_Player, int a_SlotNum); /// Called when a new player opens the same parent window. The window already tracks the player. CS-locked. - virtual void OnPlayerAdded(cPlayer & a_Player) {} ; + virtual void OnPlayerAdded(cPlayer & a_Player); /// Called when one of the players closes the parent window. The window already doesn't track the player. CS-locked. - virtual void OnPlayerRemoved(cPlayer & a_Player) {} ; + virtual void OnPlayerRemoved(cPlayer & a_Player); /** Called to store as much of a_ItemStack in the area as possible. a_ItemStack is modified to reflect the change. The default implementation searches each slot for available space and distributes the stack there. @@ -226,7 +226,7 @@ public: virtual void OnPlayerRemoved(cPlayer & a_Player) override; // Distributing items into this area is completely disabled - virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override {} + virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots) override; protected: /// Maps player's EntityID -> current recipe; not a std::map because cCraftingGrid needs proper constructor params -- cgit v1.2.3 From 3991c04d478b0e929faff4ce95fdb53eae67b888 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 1 Mar 2014 02:43:35 +0100 Subject: Improved comments in float size check. --- src/WorldStorage/FastNBT.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index 49f97c458..d68ebd54c 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -175,8 +175,8 @@ public: // Cause a compile-time error if sizeof(float) != 4 // If your platform produces a compiler error here, you'll need to add code that manually decodes 32-bit floats - char Check1[5 - sizeof(float)]; // sizeof(float) <= 4 - char Check2[sizeof(float) - 3]; // sizeof(float) >= 4 + char Check1[5 - sizeof(float)]; // Fails if sizeof(float) > 4 + char Check2[sizeof(float) - 3]; // Fails if sizeof(float) < 4 UNUSED(Check1); UNUSED(Check2); -- cgit v1.2.3 From aecbf772932792d122d191f8a45b75ddb2756d6f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 1 Mar 2014 02:46:50 +0100 Subject: Removed cBlockHandler forward declaration from cChunkInterface. Wasn't needed. Also reformatted the code. --- src/Blocks/ChunkInterface.h | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/Blocks/ChunkInterface.h b/src/Blocks/ChunkInterface.h index b30eff1e4..b58c0c086 100644 --- a/src/Blocks/ChunkInterface.h +++ b/src/Blocks/ChunkInterface.h @@ -5,31 +5,35 @@ #include "../ForEachChunkProvider.h" #include "WorldInterface.h" -class cBlockHandler; -class cChunkInterface : public cForEachChunkProvider + + + +class cChunkInterface: + public cForEachChunkProvider { public: cChunkInterface(cChunkMap * a_ChunkMap) : m_ChunkMap(a_ChunkMap) {} - BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ) + BLOCKTYPE GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->GetBlock(a_BlockX,a_BlockY,a_BlockZ); } - BLOCKTYPE GetBlock (const Vector3i & a_Pos ) + BLOCKTYPE GetBlock(const Vector3i & a_Pos ) { - return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); + return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); } - NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ) + NIBBLETYPE GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); } - bool GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) + bool GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) { return m_ChunkMap->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } + /** Sets the block at the specified coords to the specified value. Full processing, incl. updating neighbors, is performed. */ @@ -37,7 +41,8 @@ public: { m_ChunkMap->SetBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } - void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData) + + void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData) { m_ChunkMap->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_MetaData); } @@ -55,7 +60,11 @@ public: { m_ChunkMap->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } - void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) { FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta ); } + + void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) + { + FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta ); + } void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) { @@ -77,3 +86,7 @@ public: private: cChunkMap * m_ChunkMap; }; + + + + -- cgit v1.2.3 From c18748648d791911e5e2df81ae600859c8522e9a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 1 Mar 2014 02:54:46 +0100 Subject: Forgotten changes to cChunkInterface. --- src/Blocks/ChunkInterface.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Blocks/ChunkInterface.h b/src/Blocks/ChunkInterface.h index b58c0c086..be7c2e0e5 100644 --- a/src/Blocks/ChunkInterface.h +++ b/src/Blocks/ChunkInterface.h @@ -20,9 +20,9 @@ public: { return m_ChunkMap->GetBlock(a_BlockX,a_BlockY,a_BlockZ); } - BLOCKTYPE GetBlock(const Vector3i & a_Pos ) + BLOCKTYPE GetBlock(const Vector3i & a_Pos) { - return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z ); + return GetBlock(a_Pos.x, a_Pos.y, a_Pos.z); } NIBBLETYPE GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) { -- cgit v1.2.3 From ce07a22fe6f210cd6461d54cd7fd8eaaaa47be4f Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 1 Mar 2014 10:44:34 +0100 Subject: APIDump: Documented cRoot:CreateAndInitializeWorld. --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index c6221f30d..241aa05ad 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1773,6 +1773,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); BroadcastChatInfo = { Params = "Message", Return = "", Notes = "Prepends Yellow [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For informational messages, such as command usage." }, BroadcastChatSuccess = { Params = "Message", Return = "", Notes = "Prepends Green [INFO] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For success messages." }, BroadcastChatWarning = { Params = "Message", Return = "", Notes = "Prepends Rose [WARN] / colours entire text (depending on ShouldUseChatPrefixes()) and broadcasts message. For concerning events, such as plugin reload etc." }, + CreateAndInitializeWorld = { Params = "WorldName", Return = "{{cWorld|cWorld}}", Notes = "Creates a new world and initializes it. If there is a world whith the same name it returns nil." }, FindAndDoWithPlayer = { Params = "PlayerName, CallbackFunction", Return = "", Notes = "Calls the given callback function for the given player." }, ForEachPlayer = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each player. The callback function has the following signature:
function Callback({{cPlayer|cPlayer}})
" }, ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature:
function Callback({{cWorld|cWorld}})
" }, -- cgit v1.2.3 From 5c449452871340eeae9df8f34c5e145fda991d92 Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 1 Mar 2014 12:06:19 +0200 Subject: Exported and documented cScoreboard --- MCServer/Plugins/APIDump/APIDesc.lua | 90 ++++++++++++++++++++++++++++++++++++ src/Bindings/AllToLua.pkg | 1 + src/Entities/Player.cpp | 21 ++------- src/Scoreboard.cpp | 30 ++++++++++++ src/Scoreboard.h | 67 ++++++++++++++------------- 5 files changed, 160 insertions(+), 49 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index c6221f30d..c2dd6ba99 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1115,6 +1115,42 @@ local Item5 = cItem(E_ITEM_DIAMOND_CHESTPLATE, 1, 0, "thorns=1;unbreaking=3"); }, }, -- cItem + cObjective = + { + Desc = [[ + This class represents a single scoreboard objective. + ]], + Functions = + { + AddScore = { Params = "string, number", Return = "Score", Notes = "Adds a value to the score of the specified player and returns the new value." }, + GetDisplayName = { Params = "", Return = "string", Notes = "Returns the display name of the objective. This name will be shown to the connected players." }, + GetName = { Params = "", Return = "string", Notes = "Returns the internal name of the objective." }, + GetScore = { Params = "string", Return = "Score", Notes = "Returns the score of the specified player." }, + GetType = { Params = "", Return = "eType", Notes = "Returns the type of the objective. (i.e what is being tracked)" }, + Reset = { Params = "", Return = "", Notes = "Resets the scores of the tracked players." }, + ResetScore = { Params = "string", Return = "", Notes = "Reset the score of the specified player." }, + SetDisplayName = { Params = "string", Return = "", Notes = "Sets the display name of the objective." }, + SetScore = { Params = "string, Score", Return = "", Notes = "Sets the score of the specified player." }, + SubScore = { Params = "string, number", Return = "Score", Notes = "Subtracts a value from the score of the specified player and returns the new value." }, + }, + Constants = + { + E_TYPE_ACHIEVEMENT = { Notes = "" }, + E_TYPE_DEATH_COUNT = { Notes = "" }, + E_TYPE_DUMMY = { Notes = "" }, + E_TYPE_HEALTH = { Notes = "" }, + E_TYPE_PLAYER_KILL_COUNT = { Notes = "" }, + E_TYPE_STAT = { Notes = "" }, + E_TYPE_STAT_BLOCK_MINE = { Notes = "" }, + E_TYPE_STAT_ENTITY_KILL = { Notes = "" }, + E_TYPE_STAT_ENTITY_KILLED_BY = { Notes = "" }, + E_TYPE_STAT_ITEM_BREAK = { Notes = "" }, + E_TYPE_STAT_ITEM_CRAFT = { Notes = "" }, + E_TYPE_STAT_ITEM_USE = { Notes = "" }, + E_TYPE_TOTAL_KILL_COUNT = { Notes = "" }, + }, + }, -- cObjective + cPainting = { Desc = "This class represents a painting in the world. These paintings are special and different from Vanilla in that they can be critical-hit.", @@ -1821,6 +1857,34 @@ end }, }, -- cRoot + cScoreboard = + { + Desc = [[ + This class manages the objectives and teams of a single world. + ]], + Functions = + { + AddPlayerScore = { Params = "Name, Type, Value", Return = "", Notes = "Adds a value to all player scores of the specified objective type." }, + GetNumObjectives = { Params = "", Return = "number", Notes = "Returns the nuber of registered objectives." }, + GetNumTeams = { Params = "", Return = "number", Notes = "Returns the number of registered teams." }, + GetObjective = { Params = "string", Return = "{{cObjective}}", Notes = "Returns the objective with the specified name." }, + GetObjectiveIn = { Params = "DisplaySlot", Return = "{{cObjective}}", Notes = "Returns the objective in the specified display slot. Can be nil." }, + GetTeam = { Params = "string", Return = "{{cTeam}}", Notes = "Returns the team with the specified name." }, + RegisterObjective = { Params = "Name, DisplayName, Type", Return = "{{cObjective}}", Notes = "Registers a new scoreboard objective. Returns the {{cObjective}} instance, nil on error." }, + RegisterTeam = { Params = "Name, DisplayName, Prefix, Suffix", Return = "{{cTeam}}", Notes = "Registers a new team. Returns the {{cTeam}} instance, nil on error." }, + RemoveObjective = { Params = "string", Return = "bool", Notes = "Removes the objective with the specified name. Returns true if operation was successful." }, + RemoveTeam = { Params = "string", Return = "bool", Notes = "Removes the team with the specified name. Returns true if operation was successful." }, + SetDisplay = { Params = "Name, DisplaySlot", Return = "", Notes = "Updates the currently displayed objective." }, + }, + Constants = + { + E_DISPLAY_SLOT_COUNT = { Notes = "" }, + E_DISPLAY_SLOT_LIST = { Notes = "" }, + E_DISPLAY_SLOT_NAME = { Notes = "" }, + E_DISPLAY_SLOT_SIDEBAR = { Notes = "" }, + }, + }, -- cScoreboard + cServer = { Desc = [[ @@ -1841,6 +1905,32 @@ end }, }, -- cServer + cTeam = + { + Desc = [[ + This class manages a single player team. + ]], + Functions = + { + AddPlayer = { Params = "string", Returns = "bool", Notes = "Adds a player to this team. Returns true if the operation was successful." }, + AllowsFriendlyFire = { Params = "", Return = "bool", Notes = "Returns whether team friendly fire is allowed." }, + CanSeeFriendlyInvisible = { Params = "", Return = "bool", Notes = "Returns whether players can see invisible teammates." }, + HasPlayer = { Params = "string", Returns = "bool", Notes = "Returns whether the specified player is a member of this team." }, + GetDisplayName = { Params = "", Return = "string", Notes = "Returns the display name of the team." }, + GetName = { Params = "", Return = "string", Notes = "Returns the internal name of the team." }, + GetNumPlayers = { Params = "", Return = "number", Notes = "Returns the number of registered players." }, + GetPrefix = { Params = "", Return = "string", Notes = "Returns the prefix prepended to the names of the members of this team." }, + RemovePlayer = { Params = "string", Returns = "bool", Notes = "Removes the player with the specified name from this team. Returns true if the operation was successful." }, + Reset = { Params = "", Returns = "", Notes = "Removes all players from this team." }, + GetSuffix = { Params = "", Return = "string", Notes = "Returns the suffix appended to the names of the members of this team." }, + SetCanSeeFriendlyInvisible = { Params = "bool", Return = "", Notes = "Set whether players can see invisible teammates." }, + SetDisplayName = { Params = "string", Return = "", Notes = "Sets the display name of this team. (i.e. what will be shown to the players)" }, + SetFriendlyFire = { Params = "bool", Return = "", Notes = "Sets whether team friendly fire is allowed." }, + SetPrefix = { Params = "string", Return = "", Notes = "Sets the prefix prepended to the names of the members of this team." }, + SetSuffix = { Params = "string", Return = "", Notes = "Sets the suffix appended to the names of the members of this team." }, + }, + }, -- cTeam + cTNTEntity = { Desc = "This class manages a TNT entity.", diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 6537437cd..1a2140771 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -75,6 +75,7 @@ $cfile "../Mobs/Monster.h" $cfile "../CompositeChat.h" $cfile "../Map.h" $cfile "../MapManager.h" +$cfile "../Scoreboard.h" diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index f419ee09c..416bda2ec 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -858,6 +858,8 @@ void cPlayer::KilledBy(cEntity * a_Killer) else if (a_Killer->IsPlayer()) { GetWorld()->BroadcastChatDeath(Printf("%s was killed by %s", GetName().c_str(), ((cPlayer *)a_Killer)->GetName().c_str())); + + m_World->GetScoreBoard().AddPlayerScore(((cPlayer *)a_Killer)->GetName(), cObjective::E_TYPE_PLAYER_KILL_COUNT, 1); } else { @@ -867,24 +869,7 @@ void cPlayer::KilledBy(cEntity * a_Killer) GetWorld()->BroadcastChatDeath(Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str())); } - class cIncrementCounterCB - : public cObjectiveCallback - { - AString m_Name; - public: - cIncrementCounterCB(const AString & a_Name) : m_Name(a_Name) {} - - virtual bool Item(cObjective * a_Objective) override - { - a_Objective->AddScore(m_Name, 1); - return true; - } - } IncrementCounter (GetName()); - - cScoreboard & Scoreboard = m_World->GetScoreBoard(); - - // Update scoreboard objectives - Scoreboard.ForEachObjectiveWith(cObjective::E_TYPE_DEATH_COUNT, IncrementCounter); + m_World->GetScoreBoard().AddPlayerScore(GetName(), cObjective::E_TYPE_DEATH_COUNT, 1); } diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index 61ecac5b7..1c5a22eff 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -246,6 +246,17 @@ void cTeam::Reset(void) +void cTeam::SetDisplayName(const AString & a_Name) +{ + m_DisplayName = a_Name; + + // TODO 2014-03-01 xdot: Update clients +} + + + + + unsigned int cTeam::GetNumPlayers(void) const { return m_Players.size(); @@ -306,6 +317,8 @@ bool cScoreboard::RemoveObjective(const AString & a_Name) ASSERT(m_World != NULL); m_World->BroadcastScoreboardObjective(it->second.GetName(), it->second.GetDisplayName(), 1); + // TODO 2014-03-01 xdot: Remove objective from display slot + return true; } @@ -465,6 +478,23 @@ void cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallb +void cScoreboard::AddPlayerScore(const AString & a_Name, cObjective::eType a_Type, cObjective::Score a_Value) +{ + cCSLock Lock(m_CSObjectives); + + for (cObjectiveMap::iterator it = m_Objectives.begin(); it != m_Objectives.end(); ++it) + { + if (it->second.GetType() == a_Type) + { + it->second.AddScore(a_Name, a_Value); + } + } +} + + + + + void cScoreboard::SendTo(cClientHandle & a_Client) { cCSLock Lock(m_CSObjectives); diff --git a/src/Scoreboard.h b/src/Scoreboard.h index f64ba2bce..f9a8665da 100644 --- a/src/Scoreboard.h +++ b/src/Scoreboard.h @@ -67,29 +67,29 @@ public: const AString & GetName(void) const { return m_Name; } const AString & GetDisplayName(void) const { return m_DisplayName; } - /// Resets the objective + /** Resets the objective */ void Reset(void); - /// Returns the score of the specified player + /** Returns the score of the specified player */ Score GetScore(const AString & a_Name) const; - /// Sets the score of the specified player + /** Sets the score of the specified player */ void SetScore(const AString & a_Name, Score a_Score); - /// Resets the score of the specified player + /** Resets the score of the specified player */ void ResetScore(const AString & a_Name); - /// Adds a_Delta and returns the new score + /** Adds a_Delta and returns the new score */ Score AddScore(const AString & a_Name, Score a_Delta); - /// Subtracts a_Delta and returns the new score + /** Subtracts a_Delta and returns the new score */ Score SubScore(const AString & a_Name, Score a_Delta); void SetDisplayName(const AString & a_Name); // tolua_end - /// Send this objective to the specified client + /** Send this objective to the specified client */ void SendTo(cClientHandle & a_Client); private: @@ -109,7 +109,8 @@ private: friend class cScoreboardSerializer; -}; + +}; // tolua_export @@ -127,21 +128,21 @@ public: const AString & a_Prefix, const AString & a_Suffix ); - /// Adds a new player to the team + // tolua_begin + + /** Adds a new player to the team */ bool AddPlayer(const AString & a_Name); - /// Removes a player from the team + /** Removes a player from the team */ bool RemovePlayer(const AString & a_Name); - /// Returns whether the specified player is in this team + /** Returns whether the specified player is in this team */ bool HasPlayer(const AString & a_Name) const; - /// Removes all registered players + /** Removes all registered players */ void Reset(void); - // tolua_begin - - /// Returns the number of registered players + /** Returns the number of registered players */ unsigned int GetNumPlayers(void) const; bool AllowsFriendlyFire(void) const { return m_AllowsFriendlyFire; } @@ -180,7 +181,8 @@ private: friend class cScoreboardSerializer; -}; + +}; // tolua_export @@ -209,44 +211,46 @@ public: // tolua_begin - /// Registers a new scoreboard objective, returns the cObjective instance, NULL on name collision + /** Registers a new scoreboard objective, returns the cObjective instance, NULL on name collision */ cObjective * RegisterObjective(const AString & a_Name, const AString & a_DisplayName, cObjective::eType a_Type); - /// Removes a registered objective, returns true if operation was successful + /** Removes a registered objective, returns true if operation was successful */ bool RemoveObjective(const AString & a_Name); - /// Retrieves the objective with the specified name, NULL if not found + /** Retrieves the objective with the specified name, NULL if not found */ cObjective * GetObjective(const AString & a_Name); - /// Registers a new team, returns the cTeam instance, NULL on name collision + /** Registers a new team, returns the cTeam instance, NULL on name collision */ cTeam * RegisterTeam(const AString & a_Name, const AString & a_DisplayName, const AString & a_Prefix, const AString & a_Suffix); - /// Removes a registered team, returns true if operation was successful + /** Removes a registered team, returns true if operation was successful */ bool RemoveTeam(const AString & a_Name); - /// Retrieves the team with the specified name, NULL if not found + /** Retrieves the team with the specified name, NULL if not found */ cTeam * GetTeam(const AString & a_Name); - cTeam * QueryPlayerTeam(const AString & a_Name); // WARNING: O(n logn) - void SetDisplay(const AString & a_Objective, eDisplaySlot a_Slot); - void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot); - cObjective * GetObjectiveIn(eDisplaySlot a_Slot); - /// Execute callback for each objective with the specified type - void ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback); - unsigned int GetNumObjectives(void) const; unsigned int GetNumTeams(void) const; + void AddPlayerScore(const AString & a_Name, cObjective::eType a_Type, cObjective::Score a_Value = 1); + // tolua_end - /// Send this scoreboard to the specified client + /** Send this scoreboard to the specified client */ void SendTo(cClientHandle & a_Client); + cTeam * QueryPlayerTeam(const AString & a_Name); // WARNING: O(n logn) + + /** Execute callback for each objective with the specified type */ + void ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback); + + void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot); + private: @@ -269,7 +273,8 @@ private: friend class cScoreboardSerializer; -} ; + +}; // tolua_export -- cgit v1.2.3 From a28e5eca1835e1be868c3bcd22d87e3cfae2f547 Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 1 Mar 2014 14:03:16 +0200 Subject: Exported cScoreboard::ForEachObjective --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + src/Bindings/ManualBindings.cpp | 4 ++++ src/Scoreboard.cpp | 24 ++++++++++++++++++++++-- src/Scoreboard.h | 19 +++++++++++++++++-- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index c2dd6ba99..5bc69eb24 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1865,6 +1865,7 @@ end Functions = { AddPlayerScore = { Params = "Name, Type, Value", Return = "", Notes = "Adds a value to all player scores of the specified objective type." }, + ForEachObjective = { Params = "CallBackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each objective in the scoreboard. Returns true if all objectives have been processed (including when there are zero objectives), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature:
function Callback({{cObjective|Objective}}, [CallbackData])
The callback should return false or no value to continue with the next objective, or true to abort the enumeration." }, GetNumObjectives = { Params = "", Return = "number", Notes = "Returns the nuber of registered objectives." }, GetNumTeams = { Params = "", Return = "number", Notes = "Returns the number of registered teams." }, GetObjective = { Params = "string", Return = "{{cObjective}}", Notes = "Returns the objective with the specified name." }, diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 461186d3b..3c3e78d25 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2583,6 +2583,10 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_beginmodule(tolua_S, "cMapManager"); tolua_function(tolua_S, "DoWithMap", tolua_DoWithID); tolua_endmodule(tolua_S); + + tolua_beginmodule(tolua_S, "cScoreboard"); + tolua_function(tolua_S, "ForEachObjective", tolua_ForEach); + tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cPlugin"); tolua_function(tolua_S, "Call", tolua_cPlugin_Call); diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index 1c5a22eff..43b8ba1ad 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -457,7 +457,7 @@ cObjective * cScoreboard::GetObjectiveIn(eDisplaySlot a_Slot) -void cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback) +bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback) { cCSLock Lock(m_CSObjectives); @@ -468,10 +468,30 @@ void cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallb // Call callback if (a_Callback.Item(&it->second)) { - return; + return false; } } } + return true; +} + + + + + +bool cScoreboard::ForEachObjective(cObjectiveCallback& a_Callback) +{ + cCSLock Lock(m_CSObjectives); + + for (cObjectiveMap::iterator it = m_Objectives.begin(); it != m_Objectives.end(); ++it) + { + // Call callback + if (a_Callback.Item(&it->second)) + { + return false; + } + } + return true; } diff --git a/src/Scoreboard.h b/src/Scoreboard.h index f9a8665da..8e268516d 100644 --- a/src/Scoreboard.h +++ b/src/Scoreboard.h @@ -92,6 +92,12 @@ public: /** Send this objective to the specified client */ void SendTo(cClientHandle & a_Client); + static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates + { + return "cObjective"; + } + + private: typedef std::pair cTrackedPlayer; @@ -246,8 +252,17 @@ public: cTeam * QueryPlayerTeam(const AString & a_Name); // WARNING: O(n logn) - /** Execute callback for each objective with the specified type */ - void ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback); + /** Execute callback for each objective with the specified type + * + * Returns true if all objectives processed, false if the callback aborted by returning true. + */ + bool ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback); + + /** Execute callback for each objective. + * + * Returns true if all objectives processed, false if the callback aborted by returning true. + */ + bool ForEachObjective(cObjectiveCallback& a_Callback); // Exported in ManualBindings.cpp void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot); -- cgit v1.2.3 From 692a84af31889af7a83b780009b1fcc81bfa3d99 Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 1 Mar 2014 14:20:29 +0200 Subject: Shortened enums --- src/Entities/Player.cpp | 4 +- src/Scoreboard.cpp | 62 +++++++++++++++---------------- src/Scoreboard.h | 36 +++++++++--------- src/WorldStorage/ScoreboardSerializer.cpp | 14 +++---- 4 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 416bda2ec..8f94f1feb 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -859,7 +859,7 @@ void cPlayer::KilledBy(cEntity * a_Killer) { GetWorld()->BroadcastChatDeath(Printf("%s was killed by %s", GetName().c_str(), ((cPlayer *)a_Killer)->GetName().c_str())); - m_World->GetScoreBoard().AddPlayerScore(((cPlayer *)a_Killer)->GetName(), cObjective::E_TYPE_PLAYER_KILL_COUNT, 1); + m_World->GetScoreBoard().AddPlayerScore(((cPlayer *)a_Killer)->GetName(), cObjective::otPlayerKillCount, 1); } else { @@ -869,7 +869,7 @@ void cPlayer::KilledBy(cEntity * a_Killer) GetWorld()->BroadcastChatDeath(Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str())); } - m_World->GetScoreBoard().AddPlayerScore(GetName(), cObjective::E_TYPE_DEATH_COUNT, 1); + m_World->GetScoreBoard().AddPlayerScore(GetName(), cObjective::otDeathCount, 1); } diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index 43b8ba1ad..ee56a1145 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -17,19 +17,19 @@ AString cObjective::TypeToString(eType a_Type) { switch (a_Type) { - case E_TYPE_DUMMY: return "dummy"; - case E_TYPE_DEATH_COUNT: return "deathCount"; - case E_TYPE_PLAYER_KILL_COUNT: return "playerKillCount"; - case E_TYPE_TOTAL_KILL_COUNT: return "totalKillCount"; - case E_TYPE_HEALTH: return "health"; - case E_TYPE_ACHIEVEMENT: return "achievement"; - case E_TYPE_STAT: return "stat"; - case E_TYPE_STAT_ITEM_CRAFT: return "stat.craftItem"; - case E_TYPE_STAT_ITEM_USE: return "stat.useItem"; - case E_TYPE_STAT_ITEM_BREAK: return "stat.breakItem"; - case E_TYPE_STAT_BLOCK_MINE: return "stat.mineBlock"; - case E_TYPE_STAT_ENTITY_KILL: return "stat.killEntity"; - case E_TYPE_STAT_ENTITY_KILLED_BY: return "stat.entityKilledBy"; + case otDummy: return "dummy"; + case otDeathCount: return "deathCount"; + case otPlayerKillCount: return "playerKillCount"; + case otTotalKillCount: return "totalKillCount"; + case otHealth: return "health"; + case otAchievement: return "achievement"; + case otStat: return "stat"; + case otStatItemCraft: return "stat.craftItem"; + case otStatItemUse: return "stat.useItem"; + case otStatItemBreak: return "stat.breakItem"; + case otStatBlockMine: return "stat.mineBlock"; + case otStatEntityKill: return "stat.killEntity"; + case otStatEntityKilledBy: return "stat.entityKilledBy"; default: return ""; } @@ -46,19 +46,19 @@ cObjective::eType cObjective::StringToType(const AString & a_Name) const char * m_String; } TypeMap [] = { - {E_TYPE_DUMMY, "dummy"}, - {E_TYPE_DEATH_COUNT, "deathCount"}, - {E_TYPE_PLAYER_KILL_COUNT, "playerKillCount"}, - {E_TYPE_TOTAL_KILL_COUNT, "totalKillCount"}, - {E_TYPE_HEALTH, "health"}, - {E_TYPE_ACHIEVEMENT, "achievement"}, - {E_TYPE_STAT, "stat"}, - {E_TYPE_STAT_ITEM_CRAFT, "stat.craftItem"}, - {E_TYPE_STAT_ITEM_USE, "stat.useItem"}, - {E_TYPE_STAT_ITEM_BREAK, "stat.breakItem"}, - {E_TYPE_STAT_BLOCK_MINE, "stat.mineBlock"}, - {E_TYPE_STAT_ENTITY_KILL, "stat.killEntity"}, - {E_TYPE_STAT_ENTITY_KILLED_BY, "stat.entityKilledBy"} + {otDummy, "dummy" }, + {otDeathCount, "deathCount" }, + {otPlayerKillCount, "playerKillCount" }, + {otTotalKillCount, "totalKillCount" }, + {otHealth, "health" }, + {otAchievement, "achievement" }, + {otStat, "stat" }, + {otStatItemCraft, "stat.craftItem" }, + {otStatItemUse, "stat.useItem" }, + {otStatItemBreak, "stat.breakItem" }, + {otStatBlockMine, "stat.mineBlock" }, + {otStatEntityKill, "stat.killEntity" }, + {otStatEntityKilledBy, "stat.entityKilledBy"} }; for (size_t i = 0; i < ARRAYCOUNT(TypeMap); i++) { @@ -67,7 +67,7 @@ cObjective::eType cObjective::StringToType(const AString & a_Name) return TypeMap[i].m_Type; } } // for i - TypeMap[] - return E_TYPE_DUMMY; + return otDummy; } @@ -268,7 +268,7 @@ unsigned int cTeam::GetNumPlayers(void) const cScoreboard::cScoreboard(cWorld * a_World) : m_World(a_World) { - for (int i = 0; i < (int) E_DISPLAY_SLOT_COUNT; ++i) + for (int i = 0; i < (int) dsCount; ++i) { m_Display[i] = NULL; } @@ -423,7 +423,7 @@ cTeam * cScoreboard::QueryPlayerTeam(const AString & a_Name) void cScoreboard::SetDisplay(const AString & a_Objective, eDisplaySlot a_Slot) { - ASSERT(a_Slot < E_DISPLAY_SLOT_COUNT); + ASSERT(a_Slot < dsCount); cObjective * Objective = GetObjective(a_Objective); @@ -448,7 +448,7 @@ void cScoreboard::SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot) cObjective * cScoreboard::GetObjectiveIn(eDisplaySlot a_Slot) { - ASSERT(a_Slot < E_DISPLAY_SLOT_COUNT); + ASSERT(a_Slot < dsCount); return m_Display[a_Slot]; } @@ -524,7 +524,7 @@ void cScoreboard::SendTo(cClientHandle & a_Client) it->second.SendTo(a_Client); } - for (int i = 0; i < (int) E_DISPLAY_SLOT_COUNT; ++i) + for (int i = 0; i < (int) dsCount; ++i) { // Avoid race conditions cObjective * Objective = m_Display[i]; diff --git a/src/Scoreboard.h b/src/Scoreboard.h index 8e268516d..2abd1564b 100644 --- a/src/Scoreboard.h +++ b/src/Scoreboard.h @@ -31,23 +31,23 @@ public: enum eType { - E_TYPE_DUMMY, + otDummy, - E_TYPE_DEATH_COUNT, - E_TYPE_PLAYER_KILL_COUNT, - E_TYPE_TOTAL_KILL_COUNT, - E_TYPE_HEALTH, + otDeathCount, + otPlayerKillCount, + otTotalKillCount, + otHealth, - E_TYPE_ACHIEVEMENT, + otAchievement, - E_TYPE_STAT, - E_TYPE_STAT_ITEM_CRAFT, - E_TYPE_STAT_ITEM_USE, - E_TYPE_STAT_ITEM_BREAK, + otStat, + otStatItemCraft, + otStatItemUse, + otStatItemBreak, - E_TYPE_STAT_BLOCK_MINE, - E_TYPE_STAT_ENTITY_KILL, - E_TYPE_STAT_ENTITY_KILLED_BY + otStatBlockMine, + otStatEntityKill, + otStatEntityKilledBy }; // tolua_end @@ -201,11 +201,11 @@ public: enum eDisplaySlot { - E_DISPLAY_SLOT_LIST = 0, - E_DISPLAY_SLOT_SIDEBAR, - E_DISPLAY_SLOT_NAME, + dsList = 0, + dsSidebar, + dsName, - E_DISPLAY_SLOT_COUNT + dsCount }; // tolua_end @@ -284,7 +284,7 @@ private: cWorld * m_World; - cObjective* m_Display[E_DISPLAY_SLOT_COUNT]; + cObjective * m_Display[dsCount]; friend class cScoreboardSerializer; diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index 9b8b661c4..6c885bb45 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -173,13 +173,13 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.BeginCompound("DisplaySlots"); - cObjective * Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_LIST); + cObjective * Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsList); a_Writer.AddString("slot_0", (Objective == NULL) ? "" : Objective->GetName()); - Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_SIDEBAR); + Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsSidebar); a_Writer.AddString("slot_1", (Objective == NULL) ? "" : Objective->GetName()); - Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_NAME); + Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsName); a_Writer.AddString("slot_2", (Objective == NULL) ? "" : Objective->GetName()); a_Writer.EndCompound(); // DisplaySlots @@ -280,7 +280,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { AString Name, DisplayName, Prefix, Suffix; - bool AllowsFriendlyFire = false, CanSeeFriendlyInvisible = false; + bool AllowsFriendlyFire = true, CanSeeFriendlyInvisible = false; int CurrLine = a_NBT.FindChildByName(Child, "Name"); if (CurrLine >= 0) @@ -346,7 +346,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { AString Name = a_NBT.GetString(CurrLine); - m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_LIST); + m_ScoreBoard->SetDisplay(Name, cScoreboard::dsList); } CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_1"); @@ -354,7 +354,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { AString Name = a_NBT.GetString(CurrLine); - m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_SIDEBAR); + m_ScoreBoard->SetDisplay(Name, cScoreboard::dsSidebar); } CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_2"); @@ -362,7 +362,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT) { AString Name = a_NBT.GetString(CurrLine); - m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_NAME); + m_ScoreBoard->SetDisplay(Name, cScoreboard::dsName); } return true; -- cgit v1.2.3 From 39c8e68ef030b70f1f50165e74d26100bc1988cc Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 1 Mar 2014 14:27:55 +0200 Subject: Exported cScoreboard::ForEachTeam --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + src/Bindings/ManualBindings.cpp | 1 + src/Scoreboard.cpp | 19 +++++++++++++++++++ src/Scoreboard.h | 15 ++++++++++++++- 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 5bc69eb24..e45c5c475 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1866,6 +1866,7 @@ end { AddPlayerScore = { Params = "Name, Type, Value", Return = "", Notes = "Adds a value to all player scores of the specified objective type." }, ForEachObjective = { Params = "CallBackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each objective in the scoreboard. Returns true if all objectives have been processed (including when there are zero objectives), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature:
function Callback({{cObjective|Objective}}, [CallbackData])
The callback should return false or no value to continue with the next objective, or true to abort the enumeration." }, + ForEachTeam = { Params = "CallBackFunction, [CallbackData]", Return = "bool", Notes = "Calls the specified callback for each team in the scoreboard. Returns true if all teams have been processed (including when there are zero teams), or false if the callback function has aborted the enumeration by returning true. The callback function has the following signature:
function Callback({{cObjective|Objective}}, [CallbackData])
The callback should return false or no value to continue with the next team, or true to abort the enumeration." }, GetNumObjectives = { Params = "", Return = "number", Notes = "Returns the nuber of registered objectives." }, GetNumTeams = { Params = "", Return = "number", Notes = "Returns the number of registered teams." }, GetObjective = { Params = "string", Return = "{{cObjective}}", Notes = "Returns the objective with the specified name." }, diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 3c3e78d25..fcdd728be 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2586,6 +2586,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_beginmodule(tolua_S, "cScoreboard"); tolua_function(tolua_S, "ForEachObjective", tolua_ForEach); + tolua_function(tolua_S, "ForEachTeam", tolua_ForEach); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cPlugin"); diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index ee56a1145..05fd0314d 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -498,6 +498,25 @@ bool cScoreboard::ForEachObjective(cObjectiveCallback& a_Callback) +bool cScoreboard::ForEachTeam(cTeamCallback& a_Callback) +{ + cCSLock Lock(m_CSObjectives); + + for (cTeamMap::iterator it = m_Teams.begin(); it != m_Teams.end(); ++it) + { + // Call callback + if (a_Callback.Item(&it->second)) + { + return false; + } + } + return true; +} + + + + + void cScoreboard::AddPlayerScore(const AString & a_Name, cObjective::eType a_Type, cObjective::Score a_Value) { cCSLock Lock(m_CSObjectives); diff --git a/src/Scoreboard.h b/src/Scoreboard.h index 2abd1564b..e22ecaeb1 100644 --- a/src/Scoreboard.h +++ b/src/Scoreboard.h @@ -14,9 +14,11 @@ class cObjective; +class cTeam; class cWorld; typedef cItemCallback cObjectiveCallback; +typedef cItemCallback cTeamCallback; @@ -170,6 +172,11 @@ public: // tolua_end + static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates + { + return "cTeam"; + } + private: typedef std::set cPlayerNameSet; @@ -260,10 +267,16 @@ public: /** Execute callback for each objective. * - * Returns true if all objectives processed, false if the callback aborted by returning true. + * Returns true if all objectives have been processed, false if the callback aborted by returning true. */ bool ForEachObjective(cObjectiveCallback& a_Callback); // Exported in ManualBindings.cpp + /** Execute callback for each team. + * + * Returns true if all teams have been processed, false if the callback aborted by returning true. + */ + bool ForEachTeam(cTeamCallback& a_Callback); // Exported in ManualBindings.cpp + void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot); -- cgit v1.2.3 From add9955255ffc3dba012d4adfa743b244b240ea5 Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 1 Mar 2014 15:03:27 +0200 Subject: APIDump: Fixed cScoreboard enums --- MCServer/Plugins/APIDump/APIDesc.lua | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index e45c5c475..ea89d04af 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1135,19 +1135,19 @@ local Item5 = cItem(E_ITEM_DIAMOND_CHESTPLATE, 1, 0, "thorns=1;unbreaking=3"); }, Constants = { - E_TYPE_ACHIEVEMENT = { Notes = "" }, - E_TYPE_DEATH_COUNT = { Notes = "" }, - E_TYPE_DUMMY = { Notes = "" }, - E_TYPE_HEALTH = { Notes = "" }, - E_TYPE_PLAYER_KILL_COUNT = { Notes = "" }, - E_TYPE_STAT = { Notes = "" }, - E_TYPE_STAT_BLOCK_MINE = { Notes = "" }, - E_TYPE_STAT_ENTITY_KILL = { Notes = "" }, - E_TYPE_STAT_ENTITY_KILLED_BY = { Notes = "" }, - E_TYPE_STAT_ITEM_BREAK = { Notes = "" }, - E_TYPE_STAT_ITEM_CRAFT = { Notes = "" }, - E_TYPE_STAT_ITEM_USE = { Notes = "" }, - E_TYPE_TOTAL_KILL_COUNT = { Notes = "" }, + otAchievement = { Notes = "" }, + otDeathCount = { Notes = "" }, + otDummy = { Notes = "" }, + otHealth = { Notes = "" }, + otPlayerKillCount = { Notes = "" }, + otStat = { Notes = "" }, + otStatBlockMine = { Notes = "" }, + otStatEntityKill = { Notes = "" }, + otStatEntityKilledBy = { Notes = "" }, + otStatItemBreak = { Notes = "" }, + otStatItemCraft = { Notes = "" }, + otStatItemUse = { Notes = "" }, + otTotalKillCount = { Notes = "" }, }, }, -- cObjective @@ -1880,10 +1880,10 @@ end }, Constants = { - E_DISPLAY_SLOT_COUNT = { Notes = "" }, - E_DISPLAY_SLOT_LIST = { Notes = "" }, - E_DISPLAY_SLOT_NAME = { Notes = "" }, - E_DISPLAY_SLOT_SIDEBAR = { Notes = "" }, + dsCount = { Notes = "" }, + dsList = { Notes = "" }, + dsName = { Notes = "" }, + dsSidebar = { Notes = "" }, }, }, -- cScoreboard -- cgit v1.2.3 From 48288992041eb89eb0d21380b9e1326426c3a61b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 1 Mar 2014 14:23:53 +0100 Subject: DoxyFile: Updated after all the folder renaming. --- Doxyfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Doxyfile b/Doxyfile index 33f15c4b1..d4dae6ec5 100644 --- a/Doxyfile +++ b/Doxyfile @@ -665,9 +665,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = source \ - iniFile \ - WebServer +INPUT = src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -- cgit v1.2.3 From 6129b6edf161c61db91d91145e9b1f23db688529 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 1 Mar 2014 14:29:40 +0100 Subject: If there is a SourceLocation available the InfoDump will note it in the forum version. --- MCServer/Plugins/InfoDump.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua index 8fac09d60..03ce46d99 100644 --- a/MCServer/Plugins/InfoDump.lua +++ b/MCServer/Plugins/InfoDump.lua @@ -578,7 +578,10 @@ local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo) DumpAdditionalInfoForum(a_PluginInfo, f); DumpCommandsForum(a_PluginInfo, f); DumpPermissionsForum(a_PluginInfo, f); - + if (a_PluginInfo.SourceLocation ~= nil) then + f:write("[b][color=blue]Source:[/color] [url=" .. a_PluginInfo.SourceLocation .. "]Link[/url][/b]"); + end + f:close(); end -- cgit v1.2.3 From 854cf9df999691463aa382bc760d3a4322d015a5 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 1 Mar 2014 14:45:38 +0100 Subject: Using comma instead of string concatenation. --- MCServer/Plugins/InfoDump.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua index 03ce46d99..e7ed157e3 100644 --- a/MCServer/Plugins/InfoDump.lua +++ b/MCServer/Plugins/InfoDump.lua @@ -579,7 +579,7 @@ local function DumpPluginInfoForum(a_PluginFolder, a_PluginInfo) DumpCommandsForum(a_PluginInfo, f); DumpPermissionsForum(a_PluginInfo, f); if (a_PluginInfo.SourceLocation ~= nil) then - f:write("[b][color=blue]Source:[/color] [url=" .. a_PluginInfo.SourceLocation .. "]Link[/url][/b]"); + f:write("[b][color=blue]Source:[/color] [url=", a_PluginInfo.SourceLocation, "]Link[/url][/b]"); end f:close(); -- cgit v1.2.3 From 5c5502be9e46a0a5d44b6994e8075e5588598912 Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 1 Mar 2014 17:04:17 +0200 Subject: Refactored global block property arrays --- src/BlockInfo.cpp | 423 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/BlockInfo.h | 54 +++++++ 2 files changed, 477 insertions(+) create mode 100644 src/BlockInfo.cpp create mode 100644 src/BlockInfo.h diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp new file mode 100644 index 000000000..6ae59db53 --- /dev/null +++ b/src/BlockInfo.cpp @@ -0,0 +1,423 @@ + +#include "Globals.h" + +#include "BlockInfo.h" + + + + + +BlockInfo BlockInfo::ms_Info[256]; + + + + + +BlockInfo::BlockInfo() + : m_LightValue(0x00) + , m_SpreadLightFalloff(0x0f) + , m_Transparent(false) + , m_OneHitDig(false) + , m_PistonBreakable(false) + , m_IsSnowable(true) + , m_RequiresSpecialTool(false) + , m_IsSolid(true) + , m_FullyOccupiesVoxel(false) +{} + + + + + +BlockInfo & BlockInfo::GetById(unsigned int a_ID) +{ + ASSERT(a_ID < 256); + + return ms_Info[a_ID]; +} + + + + + +void BlockInfo::Initialize(void) +{ + // Emissive blocks + ms_Info[E_BLOCK_FIRE ].m_LightValue = 15; + ms_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15; + ms_Info[E_BLOCK_JACK_O_LANTERN ].m_LightValue = 15; + ms_Info[E_BLOCK_LAVA ].m_LightValue = 15; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_LightValue = 15; + ms_Info[E_BLOCK_END_PORTAL ].m_LightValue = 15; + ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_LightValue = 15; + ms_Info[E_BLOCK_TORCH ].m_LightValue = 14; + ms_Info[E_BLOCK_BURNING_FURNACE ].m_LightValue = 13; + ms_Info[E_BLOCK_NETHER_PORTAL ].m_LightValue = 11; + ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_LightValue = 9; + ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_LightValue = 9; + ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_LightValue = 7; + ms_Info[E_BLOCK_BREWING_STAND ].m_LightValue = 1; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_LightValue = 1; + ms_Info[E_BLOCK_DRAGON_EGG ].m_LightValue = 1; + + + // Spread blocks + ms_Info[E_BLOCK_AIR ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_CAKE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_CHEST ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_COBWEB ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_CROPS ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_FENCE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_FENCE_GATE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_FIRE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_GLASS ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_GLASS_PANE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_GLOWSTONE ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1; + + // Light in water and lava dissapears faster: + ms_Info[E_BLOCK_LAVA ].m_SpreadLightFalloff = 3; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_SpreadLightFalloff = 3; + ms_Info[E_BLOCK_STATIONARY_WATER ].m_SpreadLightFalloff = 3; + ms_Info[E_BLOCK_WATER ].m_SpreadLightFalloff = 3; + + + // Transparent blocks + ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Transparent = true; + ms_Info[E_BLOCK_AIR ].m_Transparent = true; + ms_Info[E_BLOCK_BIG_FLOWER ].m_Transparent = true; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_Transparent = true; + ms_Info[E_BLOCK_CARROTS ].m_Transparent = true; + ms_Info[E_BLOCK_CHEST ].m_Transparent = true; + ms_Info[E_BLOCK_COBWEB ].m_Transparent = true; + ms_Info[E_BLOCK_CROPS ].m_Transparent = true; + ms_Info[E_BLOCK_DANDELION ].m_Transparent = true; + ms_Info[E_BLOCK_DETECTOR_RAIL ].m_Transparent = true; + ms_Info[E_BLOCK_ENDER_CHEST ].m_Transparent = true; + ms_Info[E_BLOCK_FENCE ].m_Transparent = true; + ms_Info[E_BLOCK_FENCE_GATE ].m_Transparent = true; + ms_Info[E_BLOCK_FIRE ].m_Transparent = true; + ms_Info[E_BLOCK_FLOWER ].m_Transparent = true; + ms_Info[E_BLOCK_FLOWER_POT ].m_Transparent = true; + ms_Info[E_BLOCK_GLASS ].m_Transparent = true; + ms_Info[E_BLOCK_GLASS_PANE ].m_Transparent = true; + ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Transparent = true; + ms_Info[E_BLOCK_ICE ].m_Transparent = true; + ms_Info[E_BLOCK_IRON_DOOR ].m_Transparent = true; + ms_Info[E_BLOCK_LAVA ].m_Transparent = true; + ms_Info[E_BLOCK_LEAVES ].m_Transparent = true; + ms_Info[E_BLOCK_LEVER ].m_Transparent = true; + ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Transparent = true; + ms_Info[E_BLOCK_MELON_STEM ].m_Transparent = true; + ms_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Transparent = true; + ms_Info[E_BLOCK_NEW_LEAVES ].m_Transparent = true; + ms_Info[E_BLOCK_POTATOES ].m_Transparent = true; + ms_Info[E_BLOCK_POWERED_RAIL ].m_Transparent = true; + ms_Info[E_BLOCK_PISTON_EXTENSION ].m_Transparent = true; + ms_Info[E_BLOCK_PUMPKIN_STEM ].m_Transparent = true; + ms_Info[E_BLOCK_RAIL ].m_Transparent = true; + ms_Info[E_BLOCK_RED_MUSHROOM ].m_Transparent = true; + ms_Info[E_BLOCK_SIGN_POST ].m_Transparent = true; + ms_Info[E_BLOCK_SNOW ].m_Transparent = true; + ms_Info[E_BLOCK_STAINED_GLASS ].m_Transparent = true; + ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true; + ms_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true; + ms_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true; + ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true; + ms_Info[E_BLOCK_TALL_GRASS ].m_Transparent = true; + ms_Info[E_BLOCK_TORCH ].m_Transparent = true; + ms_Info[E_BLOCK_VINES ].m_Transparent = true; + ms_Info[E_BLOCK_WALLSIGN ].m_Transparent = true; + ms_Info[E_BLOCK_WATER ].m_Transparent = true; + ms_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true; + ms_Info[E_BLOCK_WOODEN_DOOR ].m_Transparent = true; + ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Transparent = true; + + // TODO: Any other transparent blocks? + + + // One hit break blocks: + ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_OneHitDig = true; + ms_Info[E_BLOCK_BIG_FLOWER ].m_OneHitDig = true; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_OneHitDig = true; + ms_Info[E_BLOCK_CARROTS ].m_OneHitDig = true; + ms_Info[E_BLOCK_CROPS ].m_OneHitDig = true; + ms_Info[E_BLOCK_DANDELION ].m_OneHitDig = true; + ms_Info[E_BLOCK_FIRE ].m_OneHitDig = true; + ms_Info[E_BLOCK_FLOWER ].m_OneHitDig = true; + ms_Info[E_BLOCK_FLOWER_POT ].m_OneHitDig = true; + ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_OneHitDig = true; + ms_Info[E_BLOCK_MELON_STEM ].m_OneHitDig = true; + ms_Info[E_BLOCK_POTATOES ].m_OneHitDig = true; + ms_Info[E_BLOCK_PUMPKIN_STEM ].m_OneHitDig = true; + ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_OneHitDig = true; + ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_OneHitDig = true; + ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_OneHitDig = true; + ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_OneHitDig = true; + ms_Info[E_BLOCK_REDSTONE_WIRE ].m_OneHitDig = true; + ms_Info[E_BLOCK_RED_MUSHROOM ].m_OneHitDig = true; + ms_Info[E_BLOCK_REEDS ].m_OneHitDig = true; + ms_Info[E_BLOCK_SAPLING ].m_OneHitDig = true; + ms_Info[E_BLOCK_TNT ].m_OneHitDig = true; + ms_Info[E_BLOCK_TALL_GRASS ].m_OneHitDig = true; + ms_Info[E_BLOCK_TORCH ].m_OneHitDig = true; + + + // Blocks that break when pushed by piston: + ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_PistonBreakable = true; + ms_Info[E_BLOCK_AIR ].m_PistonBreakable = true; + ms_Info[E_BLOCK_BED ].m_PistonBreakable = true; + ms_Info[E_BLOCK_BIG_FLOWER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_PistonBreakable = true; + ms_Info[E_BLOCK_COBWEB ].m_PistonBreakable = true; + ms_Info[E_BLOCK_CROPS ].m_PistonBreakable = true; + ms_Info[E_BLOCK_DANDELION ].m_PistonBreakable = true; + ms_Info[E_BLOCK_DEAD_BUSH ].m_PistonBreakable = true; + ms_Info[E_BLOCK_FIRE ].m_PistonBreakable = true; + ms_Info[E_BLOCK_FLOWER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; + ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true; + ms_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true; + ms_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true; + ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; + ms_Info[E_BLOCK_LADDER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_LAVA ].m_PistonBreakable = true; + ms_Info[E_BLOCK_LEVER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_MELON ].m_PistonBreakable = true; + ms_Info[E_BLOCK_MELON_STEM ].m_PistonBreakable = true; + ms_Info[E_BLOCK_PUMPKIN ].m_PistonBreakable = true; + ms_Info[E_BLOCK_PUMPKIN_STEM ].m_PistonBreakable = true; + ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_PistonBreakable = true; + ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_PistonBreakable = true; + ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_PistonBreakable = true; + ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_PistonBreakable = true; + ms_Info[E_BLOCK_REDSTONE_WIRE ].m_PistonBreakable = true; + ms_Info[E_BLOCK_RED_MUSHROOM ].m_PistonBreakable = true; + ms_Info[E_BLOCK_REEDS ].m_PistonBreakable = true; + ms_Info[E_BLOCK_SNOW ].m_PistonBreakable = true; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_PistonBreakable = true; + ms_Info[E_BLOCK_STATIONARY_WATER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_STONE_BUTTON ].m_PistonBreakable = true; + ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_PistonBreakable = true; + ms_Info[E_BLOCK_TALL_GRASS ].m_PistonBreakable = true; + ms_Info[E_BLOCK_TORCH ].m_PistonBreakable = true; + ms_Info[E_BLOCK_VINES ].m_PistonBreakable = true; + ms_Info[E_BLOCK_WATER ].m_PistonBreakable = true; + ms_Info[E_BLOCK_WOODEN_BUTTON ].m_PistonBreakable = true; + ms_Info[E_BLOCK_WOODEN_DOOR ].m_PistonBreakable = true; + ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_PistonBreakable = true; + + + // Blocks that cannot be snowed over: + ms_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_IsSnowable = false; + ms_Info[E_BLOCK_AIR ].m_IsSnowable = false; + ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSnowable = false; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSnowable = false; + ms_Info[E_BLOCK_CACTUS ].m_IsSnowable = false; + ms_Info[E_BLOCK_CHEST ].m_IsSnowable = false; + ms_Info[E_BLOCK_CROPS ].m_IsSnowable = false; + ms_Info[E_BLOCK_DANDELION ].m_IsSnowable = false; + ms_Info[E_BLOCK_FIRE ].m_IsSnowable = false; + ms_Info[E_BLOCK_FLOWER ].m_IsSnowable = false; + ms_Info[E_BLOCK_GLASS ].m_IsSnowable = false; + ms_Info[E_BLOCK_ICE ].m_IsSnowable = false; + ms_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_IsSnowable = false; + ms_Info[E_BLOCK_LAVA ].m_IsSnowable = false; + ms_Info[E_BLOCK_LILY_PAD ].m_IsSnowable = false; + ms_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_IsSnowable = false; + ms_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_IsSnowable = false; + ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSnowable = false; + ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSnowable = false; + ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSnowable = false; + ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSnowable = false; + ms_Info[E_BLOCK_REEDS ].m_IsSnowable = false; + ms_Info[E_BLOCK_SAPLING ].m_IsSnowable = false; + ms_Info[E_BLOCK_SIGN_POST ].m_IsSnowable = false; + ms_Info[E_BLOCK_SNOW ].m_IsSnowable = false; + ms_Info[E_BLOCK_STAINED_GLASS ].m_IsSnowable = false; + ms_Info[E_BLOCK_STAINED_GLASS_PANE ].m_IsSnowable = false; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSnowable = false; + ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSnowable = false; + ms_Info[E_BLOCK_TALL_GRASS ].m_IsSnowable = false; + ms_Info[E_BLOCK_TNT ].m_IsSnowable = false; + ms_Info[E_BLOCK_TORCH ].m_IsSnowable = false; + ms_Info[E_BLOCK_VINES ].m_IsSnowable = false; + ms_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false; + ms_Info[E_BLOCK_WATER ].m_IsSnowable = false; + + + // Blocks that don't drop without a special tool: + ms_Info[E_BLOCK_BRICK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_CAULDRON ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_COAL_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_COBBLESTONE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_COBWEB ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_DIAMOND_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_EMERALD_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_END_STONE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_GOLD_BLOCK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_GOLD_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_IRON_BLOCK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_IRON_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_LAPIS_BLOCK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_LAPIS_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_NETHERRACK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_NETHER_BRICK ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_OBSIDIAN ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_REDSTONE_ORE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_SANDSTONE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_SANDSTONE_STAIRS ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_SNOW ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_STONE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_STONE_BRICKS ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true; + + + // Nonsolid blocks: + ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSolid = false; + ms_Info[E_BLOCK_AIR ].m_IsSolid = false; + ms_Info[E_BLOCK_BIG_FLOWER ].m_IsSolid = false; + ms_Info[E_BLOCK_BROWN_MUSHROOM ].m_IsSolid = false; + ms_Info[E_BLOCK_CARROTS ].m_IsSolid = false; + ms_Info[E_BLOCK_COBWEB ].m_IsSolid = false; + ms_Info[E_BLOCK_CROPS ].m_IsSolid = false; + ms_Info[E_BLOCK_DANDELION ].m_IsSolid = false; + ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSolid = false; + ms_Info[E_BLOCK_END_PORTAL ].m_IsSolid = false; + ms_Info[E_BLOCK_FIRE ].m_IsSolid = false; + ms_Info[E_BLOCK_FLOWER ].m_IsSolid = false; + ms_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false; + ms_Info[E_BLOCK_LAVA ].m_IsSolid = false; + ms_Info[E_BLOCK_LEVER ].m_IsSolid = false; + ms_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_IsSolid = false; + ms_Info[E_BLOCK_MELON_STEM ].m_IsSolid = false; + ms_Info[E_BLOCK_NETHER_PORTAL ].m_IsSolid = false; + ms_Info[E_BLOCK_PISTON_EXTENSION ].m_IsSolid = false; + ms_Info[E_BLOCK_POTATOES ].m_IsSolid = false; + ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSolid = false; + ms_Info[E_BLOCK_RAIL ].m_IsSolid = false; + ms_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_IsSolid = false; + ms_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_IsSolid = false; + ms_Info[E_BLOCK_REDSTONE_WIRE ].m_IsSolid = false; + ms_Info[E_BLOCK_RED_MUSHROOM ].m_IsSolid = false; + ms_Info[E_BLOCK_REEDS ].m_IsSolid = false; + ms_Info[E_BLOCK_SAPLING ].m_IsSolid = false; + ms_Info[E_BLOCK_SIGN_POST ].m_IsSolid = false; + ms_Info[E_BLOCK_SNOW ].m_IsSolid = false; + ms_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false; + ms_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false; + ms_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false; + ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false; + ms_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false; + ms_Info[E_BLOCK_TORCH ].m_IsSolid = false; + ms_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false; + ms_Info[E_BLOCK_VINES ].m_IsSolid = false; + ms_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false; + ms_Info[E_BLOCK_WATER ].m_IsSolid = false; + ms_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false; + ms_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_IsSolid = false; + ms_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false; + + + // Torch placeable blocks: + ms_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_BOOKCASE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_BRICK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_CLAY ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_COAL_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_COBBLESTONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_COMMAND_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_CRAFTING_TABLE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DIAMOND_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DIAMOND_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DIRT ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DISPENSER ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_DROPPER ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_EMERALD_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_EMERALD_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_END_STONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_FURNACE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_GLOWSTONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_GOLD_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_GOLD_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_GRASS ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_GRAVEL ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_HARDENED_CLAY ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_JUKEBOX ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_LAPIS_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_LAPIS_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_LOG ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_MELON ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_MYCELIUM ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_NETHERRACK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_NETHER_BRICK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_NOTE_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_OBSIDIAN ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_PACKED_ICE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_PLANKS ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_PUMPKIN ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_QUARTZ_BLOCK ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_REDSTONE_ORE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_SANDSTONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_SAND ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_SILVERFISH_EGG ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_SPONGE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_STAINED_CLAY ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_WOOL ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_STONE ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_STONE_BRICKS ].m_FullyOccupiesVoxel = true; +} + + + + + +// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor: +class cBlockInfoInitializer +{ +public: + cBlockInfoInitializer(void) + { + BlockInfo::Initialize(); + } +} BlockInfoInitializer; + + + + + diff --git a/src/BlockInfo.h b/src/BlockInfo.h new file mode 100644 index 000000000..1e09b0df5 --- /dev/null +++ b/src/BlockInfo.h @@ -0,0 +1,54 @@ + +#pragma once + + + + + + +class BlockInfo +{ +public: + + BlockInfo(); + + /** (Re-)Initializes the internal BlockInfo structures. */ + static void Initialize(void); + + /** Returns the associated BlockInfo structure. */ + static BlockInfo & GetById(unsigned int a_ID); + + NIBBLETYPE m_LightValue; + NIBBLETYPE m_SpreadLightFalloff; + + bool m_Transparent; + bool m_OneHitDig; + bool m_PistonBreakable; + bool m_IsSnowable; + bool m_RequiresSpecialTool; + bool m_IsSolid; + bool m_FullyOccupiesVoxel; + + + inline static NIBBLETYPE GetLightValue (unsigned int a_ID) { return GetById(a_ID).m_LightValue; } + inline static NIBBLETYPE GetSpreadLightFalloff(unsigned int a_ID) { return GetById(a_ID).m_SpreadLightFalloff; } + inline static bool IsTransparent (unsigned int a_ID) { return GetById(a_ID).m_Transparent; } + inline static bool IsOneHitDig (unsigned int a_ID) { return GetById(a_ID).m_OneHitDig; } + inline static bool IsPistoneBreakable (unsigned int a_ID) { return GetById(a_ID).m_PistonBreakable; } + inline static bool IsSnowable (unsigned int a_ID) { return GetById(a_ID).m_IsSnowable; } + inline static bool RequiresSpecialTool (unsigned int a_ID) { return GetById(a_ID).m_RequiresSpecialTool; } + inline static bool IsSolid (unsigned int a_ID) { return GetById(a_ID).m_IsSolid; } + inline static bool FullyOccupiesVoxel (unsigned int a_ID) { return GetById(a_ID).m_FullyOccupiesVoxel; } + + +protected: + + // TODO xdot: Change to std::vector to support dynamic block IDs + static BlockInfo ms_Info[256]; + + +}; + + + + -- cgit v1.2.3 From 0acfbdd91283c96fd0f371f51029a72d6c9cd3de Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 1 Mar 2014 09:47:27 -0800 Subject: Final implementation of MetaRotater --- src/Blocks/MetaRotater.h | 96 +++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/src/Blocks/MetaRotater.h b/src/Blocks/MetaRotater.h index f1656f1bd..b83ed177a 100644 --- a/src/Blocks/MetaRotater.h +++ b/src/Blocks/MetaRotater.h @@ -1,7 +1,7 @@ #pragma once -template +template class cMetaRotater : public Base { public: @@ -19,64 +19,70 @@ public: }; -template -NIBBLETYPE cMetaRotater::MetaRotateCW(NIBBLETYPE a_Meta) +template +NIBBLETYPE cMetaRotater::MetaRotateCW(NIBBLETYPE a_Meta) { -NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); -switch (a_Meta & BitFilter) -{ -case South: return West | OtherMeta; -case West: return North | OtherMeta; -case North: return East | OtherMeta; -case East: return South | OtherMeta; -} -ASSERT(!"Invalid Meta value"); -return a_Meta; + NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); + switch (a_Meta & BitFilter) + { + case South: return West | OtherMeta; + case West: return North | OtherMeta; + case North: return East | OtherMeta; + case East: return South | OtherMeta; + } + if(AssertIfNotMatched) + { + ASSERT(!"Invalid Meta value"); + return a_Meta; + } } -template -NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) +template +NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) { -NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); -switch (a_Meta & BitFilter) -{ -case South: return East | OtherMeta; -case East: return North | OtherMeta; -case North: return West | OtherMeta; -case West: return South | OtherMeta; -} -ASSERT(!"Invalid Meta value"); -return a_Meta; + NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); + switch (a_Meta & BitFilter) + { + case South: return East | OtherMeta; + case East: return North | OtherMeta; + case North: return West | OtherMeta; + case West: return South | OtherMeta; + } + if(AssertIfNotMatched) + { + ASSERT(!"Invalid Meta value"); + return a_Meta; + } } -template -NIBBLETYPE cMetaRotater::MetaMirrorXY(NIBBLETYPE a_Meta) +template +NIBBLETYPE cMetaRotater::MetaMirrorXY(NIBBLETYPE a_Meta) { -NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); -switch (a_Meta & BitFilter) -{ -case South: return North | OtherMeta; -case North: return South | OtherMeta; -} -// Not Facing North or South; No change. -return a_Meta; + NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); + switch (a_Meta & BitFilter) + { + case South: return North | OtherMeta; + case North: return South | OtherMeta; + } + // Not Facing North or South; No change. + return a_Meta; } -template -NIBBLETYPE cMetaRotater::MetaMirrorYZ(NIBBLETYPE a_Meta) +template +NIBBLETYPE cMetaRotater::MetaMirrorYZ(NIBBLETYPE a_Meta) { -NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); -switch (a_Meta & BitFilter) -{ -case West: return East | OtherMeta; -case East: return West | OtherMeta; -} -// Not Facing East or West; No change. -return a_Meta; + NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); + switch (a_Meta & BitFilter) + { + case West: return East | OtherMeta; + case East: return West | OtherMeta; + } + // Not Facing East or West; No change. + return a_Meta; } -- cgit v1.2.3 From 65edffd5b04623dcd4cebbd1afb2575e98eee5db Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 1 Mar 2014 10:04:50 -0800 Subject: Implemented Rotations --- src/Blocks/BlockBed.h | 4 +-- src/Blocks/BlockButton.h | 5 ++-- src/Blocks/BlockChest.h | 5 ++-- src/Blocks/BlockComparator.h | 5 ++-- src/Blocks/BlockDoor.h | 5 ++-- src/Blocks/BlockDropSpenser.h | 1 + src/Blocks/BlockEnderchest.h | 2 +- src/Blocks/BlockFenceGate.h | 6 ++-- src/Blocks/BlockStairs.h | 68 ++----------------------------------------- src/Blocks/BlockTorch.h | 67 ++---------------------------------------- src/Blocks/BlockVine.h | 30 ++----------------- 11 files changed, 28 insertions(+), 170 deletions(-) diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index 6e8884114..d8a796735 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -12,11 +12,11 @@ class cBlockBedHandler : - public cMetaRotater + public cMetaRotater { public: cBlockBedHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index 5a4bf7c96..4daa03005 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -2,16 +2,17 @@ #include "BlockHandler.h" #include "Chunk.h" +#include "MetaRotater.h" class cBlockButtonHandler : - public cMetaRotater + public cMetaRotater { public: cBlockButtonHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 4ab23bced..6a13e826e 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -4,17 +4,18 @@ #include "BlockEntity.h" #include "../BlockArea.h" #include "../Entities/Player.h" +#include "MetaRotater.h" class cBlockChestHandler : - public cMetaRotater + public cMetaRotater { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index 7e672eece..238e687ab 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -3,17 +3,18 @@ #include "BlockHandler.h" #include "BlockRedstoneRepeater.h" +#include "MetaRotater.h" class cBlockComparatorHandler : - public cMetaRotater + public cMetaRotater { public: cBlockComparatorHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index c3647b203..8e3f2d83f 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -4,14 +4,15 @@ #include "BlockHandler.h" #include "../Entities/Player.h" #include "Chunk.h" +#include "MetaRotater.h" class cBlockDoorHandler : - public cMetaRotater + public cMetaRotater { - typedef super cMetaRotater; + typedef super cMetaRotater; public: cBlockDoorHandler(BLOCKTYPE a_BlockType); diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h index 2253fcd1b..73937577a 100644 --- a/src/Blocks/BlockDropSpenser.h +++ b/src/Blocks/BlockDropSpenser.h @@ -6,6 +6,7 @@ #pragma once #include "../Piston.h" +#include "MetaRotater.h" diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h index ed3f37013..6ca83399a 100644 --- a/src/Blocks/BlockEnderchest.h +++ b/src/Blocks/BlockEnderchest.h @@ -2,7 +2,7 @@ #pragma once #include "BlockEntity.h" - +#include "MetaRotater.h" diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index 035579e8e..c33393590 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" - +#include "MetaRotater.h" class cBlockFenceGateHandler : - public cMetaRotater + public cMetaRotater { public: cBlockFenceGateHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index c1887bc46..f07afc9f0 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" - +#include "MetaRotater.h" class cBlockStairsHandler : - public cBlockHandler + public cMetaRotater { public: cBlockStairsHandler(BLOCKTYPE a_BlockType) : - cBlockHandler(a_BlockType) + cMetaRotater(a_BlockType) { } @@ -96,54 +96,6 @@ public: } - virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override - { - // Bits 3 and 4 stay, the rest is swapped around according to a table: - NIBBLETYPE TopBits = (a_Meta & 0x0c); - switch (a_Meta & 0x03) - { - case 0x00: return TopBits | 0x03; // East -> North - case 0x01: return TopBits | 0x02; // West -> South - case 0x02: return TopBits | 0x00; // South -> East - case 0x03: return TopBits | 0x01; // North -> West - } - // Not reachable, but to avoid a compiler warning: - return 0; - } - - - virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override - { - // Bits 3 and 4 stay, the rest is swapped around according to a table: - NIBBLETYPE TopBits = (a_Meta & 0x0c); - switch (a_Meta & 0x03) - { - case 0x00: return TopBits | 0x02; // East -> South - case 0x01: return TopBits | 0x03; // West -> North - case 0x02: return TopBits | 0x01; // South -> West - case 0x03: return TopBits | 0x00; // North -> East - } - // Not reachable, but to avoid a compiler warning: - return 0; - } - - - virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override - { - // Bits 3 and 4 stay, the rest is swapped around according to a table: - NIBBLETYPE TopBits = (a_Meta & 0x0c); - switch (a_Meta & 0x03) - { - case 0x00: return TopBits | 0x00; // East -> East - case 0x01: return TopBits | 0x01; // West -> West - case 0x02: return TopBits | 0x03; // South -> North - case 0x03: return TopBits | 0x02; // North -> South - } - // Not reachable, but to avoid a compiler warning: - return 0; - } - - virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override { // Toggle bit 3: @@ -151,20 +103,6 @@ public: } - virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override - { - // Bits 3 and 4 stay, the rest is swapped around according to a table: - NIBBLETYPE TopBits = (a_Meta & 0x0c); - switch (a_Meta & 0x03) - { - case 0x00: return TopBits | 0x01; // East -> West - case 0x01: return TopBits | 0x00; // West -> East - case 0x02: return TopBits | 0x02; // South -> South - case 0x03: return TopBits | 0x03; // North -> North - } - // Not reachable, but to avoid a compiler warning: - return 0; - } } ; diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index f2a4c8665..59c896857 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -2,17 +2,17 @@ #include "BlockHandler.h" #include "../Chunk.h" - +#include "MetaRotater.h" class cBlockTorchHandler : - public cBlockHandler + public cMetaRotater { public: cBlockTorchHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } @@ -185,67 +185,6 @@ public: { return "step.wood"; } - - - virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override - { - // Bit 4 stays, the rest is swapped around according to a table: - NIBBLETYPE TopBits = (a_Meta & 0x08); - switch (a_Meta & 0x07) - { - case 0x01: return TopBits | 0x04; // East -> North - case 0x02: return TopBits | 0x03; // West -> South - case 0x03: return TopBits | 0x01; // South -> East - case 0x04: return TopBits | 0x02; // North -> West - default: return a_Meta; // Floor -> Floor - } - } - - - virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override - { - // Bit 4 stays, the rest is swapped around according to a table: - NIBBLETYPE TopBits = (a_Meta & 0x08); - switch (a_Meta & 0x07) - { - case 0x01: return TopBits | 0x03; // East -> South - case 0x02: return TopBits | 0x04; // West -> North - case 0x03: return TopBits | 0x02; // South -> West - case 0x04: return TopBits | 0x01; // North -> East - default: return a_Meta; // Floor -> Floor - } - } - - - virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override - { - // Bit 4 stays, the rest is swapped around according to a table: - NIBBLETYPE TopBits = (a_Meta & 0x08); - switch (a_Meta & 0x07) - { - case 0x03: return TopBits | 0x04; // South -> North - case 0x04: return TopBits | 0x03; // North -> South - default: return a_Meta; // Keep the rest - } - } - - - // Mirroring around the XZ plane doesn't make sense for floor torches, - // the others stay the same, so let's keep all the metas the same. - // The base class does tht for us, no need to override MetaMirrorXZ() - - - virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override - { - // Bit 4 stays, the rest is swapped around according to a table: - NIBBLETYPE TopBits = (a_Meta & 0x08); - switch (a_Meta & 0x07) - { - case 0x01: return TopBits | 0x02; // East -> West - case 0x02: return TopBits | 0x01; // West -> East - default: return a_Meta; // Keep the rest - } - } } ; diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index ee7dcee8a..9e2105f67 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" - +#include "MetaRotater.h" class cBlockVineHandler : - public cBlockHandler + public cMetaRotater { public: cBlockVineHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } @@ -169,31 +169,7 @@ public: a_World->SetBlock(X, Y - 1, Z, E_BLOCK_VINES, a_World->GetBlockMeta(X, Y, Z)); } } - - virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override - { - return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right - } - - virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override - { - return ((a_Meta << 1) | (a_Meta >> 3)) & 0x0f; // Rotate bits to the left - } - - - virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override - { - // Bits 2 and 4 stay, bits 1 and 3 swap - return ((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2)); - } - - - virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override - { - // Bits 1 and 3 stay, bits 2 and 4 swap - return ((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2)); - } } ; -- cgit v1.2.3 From 5093b75ef1488b3687e1c54c893ab68b4475e451 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 1 Mar 2014 10:14:24 -0800 Subject: Revesed typedef --- src/Blocks/BlockDoor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 8e3f2d83f..0caeb7dba 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -12,7 +12,7 @@ class cBlockDoorHandler : public cMetaRotater { - typedef super cMetaRotater; + typedef cMetaRotater super; public: cBlockDoorHandler(BLOCKTYPE a_BlockType); -- cgit v1.2.3 From 1e1d89fd2005ee634094fd3d55638965d41acecf Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 1 Mar 2014 10:17:55 -0800 Subject: Fixed errors --- src/Blocks/BlockChest.h | 2 +- src/Blocks/BlockDropSpenser.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 6a13e826e..1646454a7 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -15,7 +15,7 @@ class cBlockChestHandler : { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h index 73937577a..adc819a4c 100644 --- a/src/Blocks/BlockDropSpenser.h +++ b/src/Blocks/BlockDropSpenser.h @@ -17,7 +17,7 @@ class cBlockDropSpenserHandler : { public: cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotater(a_BlockType) { } -- cgit v1.2.3 From d73cdba1f66a92f011ac881b581595c0959139ef Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 1 Mar 2014 21:34:19 +0200 Subject: g_BlockXXX => cBlockInfo::XXX --- src/BlockInfo.cpp | 10 +++++----- src/BlockInfo.h | 27 +++++++++++++++++++++----- src/Blocks/BlockButton.h | 2 +- src/Blocks/BlockCactus.h | 2 +- src/Blocks/BlockDirt.h | 4 ++-- src/Blocks/BlockLadder.h | 2 +- src/Blocks/BlockLever.h | 2 +- src/Blocks/BlockRail.h | 4 ++-- src/Blocks/BlockRedstone.h | 2 +- src/Blocks/BlockSnow.h | 2 +- src/Blocks/BlockTorch.h | 6 +++--- src/Blocks/BlockTrapdoor.h | 2 +- src/Blocks/BlockVine.h | 2 +- src/Chunk.cpp | 10 +++++----- src/ClientHandle.cpp | 2 +- src/Defines.h | 2 +- src/Entities/Entity.cpp | 6 +++--- src/Entities/Minecart.cpp | 16 +++++++-------- src/Entities/Player.cpp | 2 +- src/Entities/ProjectileEntity.cpp | 4 ++-- src/Generating/FinishGen.cpp | 6 +++--- src/Globals.h | 1 + src/Items/ItemRedstoneDust.h | 2 +- src/LightingThread.cpp | 4 ++-- src/LightingThread.h | 4 ++-- src/MobSpawner.cpp | 14 ++++++------- src/Mobs/Monster.cpp | 10 +++++----- src/Mobs/SnowGolem.cpp | 2 +- src/Piston.cpp | 2 +- src/Simulator/FireSimulator.cpp | 2 +- src/Simulator/IncrementalRedstoneSimulator.cpp | 4 ++-- src/Simulator/IncrementalRedstoneSimulator.h | 2 +- src/Tracer.cpp | 2 +- 33 files changed, 91 insertions(+), 73 deletions(-) diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 6ae59db53..5fd6d33c1 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -7,13 +7,13 @@ -BlockInfo BlockInfo::ms_Info[256]; +cBlockInfo cBlockInfo::ms_Info[256]; -BlockInfo::BlockInfo() +cBlockInfo::cBlockInfo() : m_LightValue(0x00) , m_SpreadLightFalloff(0x0f) , m_Transparent(false) @@ -29,7 +29,7 @@ BlockInfo::BlockInfo() -BlockInfo & BlockInfo::GetById(unsigned int a_ID) +cBlockInfo & cBlockInfo::GetById(unsigned int a_ID) { ASSERT(a_ID < 256); @@ -40,7 +40,7 @@ BlockInfo & BlockInfo::GetById(unsigned int a_ID) -void BlockInfo::Initialize(void) +void cBlockInfo::Initialize(void) { // Emissive blocks ms_Info[E_BLOCK_FIRE ].m_LightValue = 15; @@ -413,7 +413,7 @@ class cBlockInfoInitializer public: cBlockInfoInitializer(void) { - BlockInfo::Initialize(); + cBlockInfo::Initialize(); } } BlockInfoInitializer; diff --git a/src/BlockInfo.h b/src/BlockInfo.h index 1e09b0df5..a06c47a47 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -6,27 +6,44 @@ -class BlockInfo +class cBlockInfo { public: - BlockInfo(); + cBlockInfo(); /** (Re-)Initializes the internal BlockInfo structures. */ static void Initialize(void); /** Returns the associated BlockInfo structure. */ - static BlockInfo & GetById(unsigned int a_ID); + static cBlockInfo & GetById(unsigned int a_ID); + + /** How much light do the blocks emit on their own? */ NIBBLETYPE m_LightValue; + + /** How much light do the blocks consume? */ NIBBLETYPE m_SpreadLightFalloff; + /** Is a block completely transparent? (light doesn't get decreased(?)) */ bool m_Transparent; + + /** Is a block destroyed after a single hit? */ bool m_OneHitDig; + + /** Can a piston break this block? */ bool m_PistonBreakable; + + /** Can this block hold snow atop? */ bool m_IsSnowable; + + /** Does this block require a tool to drop? */ bool m_RequiresSpecialTool; + + /** Is this block solid (player cannot walk through)? */ bool m_IsSolid; + + /** Does this block fully occupy it's voxel - is it a 'full' block? */ bool m_FullyOccupiesVoxel; @@ -34,7 +51,7 @@ public: inline static NIBBLETYPE GetSpreadLightFalloff(unsigned int a_ID) { return GetById(a_ID).m_SpreadLightFalloff; } inline static bool IsTransparent (unsigned int a_ID) { return GetById(a_ID).m_Transparent; } inline static bool IsOneHitDig (unsigned int a_ID) { return GetById(a_ID).m_OneHitDig; } - inline static bool IsPistoneBreakable (unsigned int a_ID) { return GetById(a_ID).m_PistonBreakable; } + inline static bool IsPistonBreakable (unsigned int a_ID) { return GetById(a_ID).m_PistonBreakable; } inline static bool IsSnowable (unsigned int a_ID) { return GetById(a_ID).m_IsSnowable; } inline static bool RequiresSpecialTool (unsigned int a_ID) { return GetById(a_ID).m_RequiresSpecialTool; } inline static bool IsSolid (unsigned int a_ID) { return GetById(a_ID).m_IsSolid; } @@ -44,7 +61,7 @@ public: protected: // TODO xdot: Change to std::vector to support dynamic block IDs - static BlockInfo ms_Info[256]; + static cBlockInfo ms_Info[256]; }; diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index ca6850ced..2db9b7ec7 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -101,7 +101,7 @@ public: AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]); + return (a_RelY > 0) && (cBlockInfo::IsSolid(BlockIsOn)); } } ; diff --git a/src/Blocks/BlockCactus.h b/src/Blocks/BlockCactus.h index 83595d2b9..ed441517d 100644 --- a/src/Blocks/BlockCactus.h +++ b/src/Blocks/BlockCactus.h @@ -54,7 +54,7 @@ public: NIBBLETYPE BlockMeta; if ( a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta) && - (g_BlockIsSolid[BlockType]) + cBlockInfo::IsSolid(BlockType) ) { return false; diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 91534c5e5..544424a04 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -36,7 +36,7 @@ public: if (a_RelY < cChunkDef::Height - 1) { BLOCKTYPE Above = a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ); - if ((!g_BlockTransparent[Above] && !g_BlockOneHitDig[Above]) || IsBlockWater(Above)) + if ((!cBlockInfo::IsTransparent(Above) && !cBlockInfo::IsOneHitDig(Above)) || IsBlockWater(Above)) { a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, E_META_DIRT_NORMAL); return; @@ -77,7 +77,7 @@ public: BLOCKTYPE AboveDest; NIBBLETYPE AboveMeta; Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); - if ((g_BlockOneHitDig[AboveDest] || g_BlockTransparent[AboveDest]) && !IsBlockWater(AboveDest)) + if ((cBlockInfo::IsOneHitDig(AboveDest) || cBlockInfo::IsTransparent(AboveDest)) && !IsBlockWater(AboveDest)) { Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); } diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h index 6a105d5c9..a3e9edc6b 100644 --- a/src/Blocks/BlockLadder.h +++ b/src/Blocks/BlockLadder.h @@ -91,7 +91,7 @@ public: AddFaceDirection( a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); - return g_BlockIsSolid[a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)]; + return cBlockInfo::IsSolid(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ)); } diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index 48c7e774b..ef6e102cd 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -102,7 +102,7 @@ public: AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]); + return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn); } } ; diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index 52d6f60b3..07e9814cd 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -98,7 +98,7 @@ public: { return false; } - if (!g_BlockIsSolid[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]) + if (!cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))) { return false; } @@ -130,7 +130,7 @@ public: // Too close to the edge, cannot simulate return true; } - return g_BlockIsSolid[BlockType]; + return cBlockInfo::IsSolid(BlockType); } } return true; diff --git a/src/Blocks/BlockRedstone.h b/src/Blocks/BlockRedstone.h index 10de96197..a898c9acb 100644 --- a/src/Blocks/BlockRedstone.h +++ b/src/Blocks/BlockRedstone.h @@ -20,7 +20,7 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return ((a_RelY > 0) && g_BlockFullyOccupiesVoxel[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]); + return ((a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))); } diff --git a/src/Blocks/BlockSnow.h b/src/Blocks/BlockSnow.h index a3daf0393..b21995d3c 100644 --- a/src/Blocks/BlockSnow.h +++ b/src/Blocks/BlockSnow.h @@ -72,7 +72,7 @@ public: BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ); NIBBLETYPE MetaBelow = a_Chunk.GetMeta(a_RelX, a_RelY - 1, a_RelZ); - if (g_BlockIsSnowable[BlockBelow] || ((BlockBelow == E_BLOCK_SNOW) && (MetaBelow == 7))) + if (cBlockInfo::IsSnowable(BlockBelow) || ((BlockBelow == E_BLOCK_SNOW) && (MetaBelow == 7))) { // If block below is snowable, or it is a thin slow block and has a meta of 7 (full thin snow block), say yay return true; diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index f2a4c8665..84bbb37ec 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -99,7 +99,7 @@ public: static bool CanBePlacedOn(BLOCKTYPE a_BlockType, eBlockFace a_BlockFace) { - if ( !g_BlockFullyOccupiesVoxel[a_BlockType] ) + if ( !cBlockInfo::FullyOccupiesVoxel(a_BlockType) ) { return (a_BlockFace == BLOCK_FACE_TOP); // Allow placement only when torch upright (for glass, etc.); exceptions won't even be sent by client, no need to handle } @@ -129,7 +129,7 @@ public: { return Face; } - else if ((g_BlockFullyOccupiesVoxel[BlockInQuestion]) && (i != BLOCK_FACE_BOTTOM)) + else if (cBlockInfo::FullyOccupiesVoxel(BlockInQuestion) && (i != BLOCK_FACE_BOTTOM)) { // Otherwise, if block in that direction is torch placeable and we haven't gotten to it via the bottom face, return that face return Face; @@ -163,7 +163,7 @@ public: // No need to check for upright orientation, it was done when the torch was placed return true; } - else if ( !g_BlockFullyOccupiesVoxel[BlockInQuestion] ) + else if ( !cBlockInfo::FullyOccupiesVoxel(BlockInQuestion) ) { return false; } diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 08fc28327..70a369e69 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -97,7 +97,7 @@ public: AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && (g_BlockIsSolid[BlockIsOn]); + return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn); } }; diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index ee7dcee8a..d8c114284 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -70,7 +70,7 @@ public: /// Returns true if the specified block type is good for vines to attach to static bool IsBlockAttachable(BLOCKTYPE a_BlockType) { - return (a_BlockType == E_BLOCK_LEAVES) || g_BlockIsSolid[a_BlockType]; + return (a_BlockType == E_BLOCK_LEAVES) || cBlockInfo::IsSolid(a_BlockType); } diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 8dfbbeef5..a75828461 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -883,7 +883,7 @@ void cChunk::ApplyWeatherToTop() FastSetBlock(X, Height, Z, E_BLOCK_SNOW, TopMeta - 1); } } - else if (g_BlockIsSnowable[TopBlock]) + else if (cBlockInfo::IsSnowable(TopBlock)) { SetBlock(X, Height + 1, Z, E_BLOCK_SNOW, 0); } @@ -1540,10 +1540,10 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT SetNibble(m_BlockMeta, index, a_BlockMeta); // ONLY recalculate lighting if it's necessary! - if( - (g_BlockLightValue[OldBlockType ] != g_BlockLightValue[a_BlockType]) || - (g_BlockSpreadLightFalloff[OldBlockType] != g_BlockSpreadLightFalloff[a_BlockType]) || - (g_BlockTransparent[OldBlockType] != g_BlockTransparent[a_BlockType]) + if ( + (cBlockInfo::GetLightValue (OldBlockType) != cBlockInfo::GetLightValue (a_BlockType)) || + (cBlockInfo::GetSpreadLightFalloff(OldBlockType) != cBlockInfo::GetSpreadLightFalloff(a_BlockType)) || + (cBlockInfo::IsTransparent (OldBlockType) != cBlockInfo::IsTransparent (a_BlockType)) ) { m_IsLightValid = false; diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index b08ceb5f6..60f14af54 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -819,7 +819,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc if ( (m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately - g_BlockOneHitDig[a_OldBlock] // One-hit blocks get destroyed immediately, too + cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too ) { HandleBlockDigFinished(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta); diff --git a/src/Defines.h b/src/Defines.h index ba2866f83..31d48860f 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -654,7 +654,7 @@ namespace ItemCategory inline bool BlockRequiresSpecialTool(BLOCKTYPE a_BlockType) { if(!IsValidBlock(a_BlockType)) return false; - return g_BlockRequiresSpecialTool[a_BlockType]; + return cBlockInfo::RequiresSpecialTool(a_BlockType); } diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 8554ab2a5..96e8c15a5 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -582,11 +582,11 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) int RelBlockZ = BlockZ - (NextChunk->GetPosZ() * cChunkDef::Width); BLOCKTYPE BlockIn = NextChunk->GetBlock( RelBlockX, BlockY, RelBlockZ ); BLOCKTYPE BlockBelow = (BlockY > 0) ? NextChunk->GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR; - if (!g_BlockIsSolid[BlockIn]) // Making sure we are not inside a solid block + if (!cBlockInfo::IsSolid(BlockIn)) // Making sure we are not inside a solid block { if (m_bOnGround) // check if it's still on the ground { - if (!g_BlockIsSolid[BlockBelow]) // Check if block below is air or water. + if (!cBlockInfo::IsSolid(BlockBelow)) // Check if block below is air or water. { m_bOnGround = false; } @@ -616,7 +616,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) // The pickup is too close to an unloaded chunk, bail out of any physics handling return; } - if (!g_BlockIsSolid[GotBlock]) + if (!cBlockInfo::IsSolid(GotBlock)) { NextPos.x += gCrossCoords[i].x; NextPos.z += gCrossCoords[i].z; diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index d854906b7..f52a7b6d9 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -720,7 +720,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) if (GetSpeedZ() > 0) { BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)ceil(GetPosZ())); - if (!IsBlockRail(Block) && g_BlockIsSolid[Block]) + if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block)) { // We could try to detect a block in front based purely on coordinates, but xoft made a bounding box system - why not use? :P cBoundingBox bbBlock(Vector3d((int)floor(GetPosX()), (int)floor(GetPosY()), (int)ceil(GetPosZ())), 0.5, 1); @@ -737,7 +737,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) else if (GetSpeedZ() < 0) { BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) - 1); - if (!IsBlockRail(Block) && g_BlockIsSolid[Block]) + if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block)) { cBoundingBox bbBlock(Vector3d((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) - 1), 0.5, 1); cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ() - 1), GetWidth() / 2, GetHeight()); @@ -757,7 +757,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) if (GetSpeedX() > 0) { BLOCKTYPE Block = m_World->GetBlock((int)ceil(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ())); - if (!IsBlockRail(Block) && g_BlockIsSolid[Block]) + if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block)) { cBoundingBox bbBlock(Vector3d((int)ceil(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ())), 0.5, 1); cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight()); @@ -773,7 +773,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) else if (GetSpeedX() < 0) { BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()) - 1, (int)floor(GetPosY()), (int)floor(GetPosZ())); - if (!IsBlockRail(Block) && g_BlockIsSolid[Block]) + if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block)) { cBoundingBox bbBlock(Vector3d((int)floor(GetPosX()) - 1, (int)floor(GetPosY()), (int)floor(GetPosZ())), 0.5, 1); cBoundingBox bbMinecart(Vector3d(GetPosX() - 1, floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight()); @@ -798,10 +798,10 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) BLOCKTYPE BlockZM = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) + 1); BLOCKTYPE BlockZP = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) + 1); if ( - (!IsBlockRail(BlockXM) && g_BlockIsSolid[BlockXM]) || - (!IsBlockRail(BlockXP) && g_BlockIsSolid[BlockXP]) || - (!IsBlockRail(BlockZM) && g_BlockIsSolid[BlockZM]) || - (!IsBlockRail(BlockZP) && g_BlockIsSolid[BlockZP]) + (!IsBlockRail(BlockXM) && cBlockInfo::IsSolid(BlockXM)) || + (!IsBlockRail(BlockXP) && cBlockInfo::IsSolid(BlockXP)) || + (!IsBlockRail(BlockZM) && cBlockInfo::IsSolid(BlockZM)) || + (!IsBlockRail(BlockZP) && cBlockInfo::IsSolid(BlockZP)) ) { SetSpeed(0, 0, 0); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 8f94f1feb..42ee14cf3 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1904,7 +1904,7 @@ void cPlayer::Detach() { for (int z = PosZ - 2; z <= (PosZ + 2); ++z) { - if (!g_BlockIsSolid[m_World->GetBlock(x, y, z)] && g_BlockIsSolid[m_World->GetBlock(x, y - 1, z)]) + if (!cBlockInfo::IsSolid(m_World->GetBlock(x, y, z)) && cBlockInfo::IsSolid(m_World->GetBlock(x, y - 1, z))) { TeleportToCoords(x, y, z); return; diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index ef82c6e94..03bc0c99d 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -50,12 +50,12 @@ protected: LOGD("Hit block %d:%d at {%d, %d, %d} face %d, %s (%s)", a_BlockType, a_BlockMeta, a_BlockX, a_BlockY, a_BlockZ, a_EntryFace, - g_BlockIsSolid[a_BlockType] ? "solid" : "non-solid", + cBlockInfo::IsSolid(a_BlockType) ? "solid" : "non-solid", ItemToString(cItem(a_BlockType, 1, a_BlockMeta)).c_str() ); */ - if (g_BlockIsSolid[a_BlockType]) + if (cBlockInfo::IsSolid(a_BlockType)) { // The projectile hit a solid block // Calculate the exact hit coords: diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 02045f76a..f2d66af70 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -88,7 +88,7 @@ void cFinishGenNetherClumpFoliage::GenFinish(cChunkDesc & a_ChunkDesc) { continue; } - if (!g_BlockIsSolid[a_ChunkDesc.GetBlockType(PosX, y - 1, PosZ)]) // Only place on solid blocks + if (!cBlockInfo::IsSolid(a_ChunkDesc.GetBlockType(PosX, y - 1, PosZ))) // Only place on solid blocks { continue; } @@ -131,7 +131,7 @@ void cFinishGenNetherClumpFoliage::TryPlaceClump(cChunkDesc & a_ChunkDesc, int a } BLOCKTYPE BlockBelow = a_ChunkDesc.GetBlockType(x, y - 1, z); - if (!g_BlockIsSolid[BlockBelow]) // Only place on solid blocks + if (!cBlockInfo::IsSolid(BlockBelow)) // Only place on solid blocks { continue; } @@ -329,7 +329,7 @@ void cFinishGenSnow::GenFinish(cChunkDesc & a_ChunkDesc) case biFrozenOcean: { int Height = a_ChunkDesc.GetHeight(x, z); - if (g_BlockIsSnowable[a_ChunkDesc.GetBlockType(x, Height, z)]) + if (cBlockInfo::IsSnowable(a_ChunkDesc.GetBlockType(x, Height, z))) { a_ChunkDesc.SetBlockType(x, Height + 1, z, E_BLOCK_SNOW); a_ChunkDesc.SetHeight(x, z, Height + 1); diff --git a/src/Globals.h b/src/Globals.h index e4737a98a..28805a83f 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -250,6 +250,7 @@ T Clamp(T a_Value, T a_Min, T a_Max) #include "ChunkDef.h" #include "BiomeDef.h" #include "BlockID.h" +#include "BlockInfo.h" #include "Entities/Effects.h" diff --git a/src/Items/ItemRedstoneDust.h b/src/Items/ItemRedstoneDust.h index 18c6b8615..274d905a5 100644 --- a/src/Items/ItemRedstoneDust.h +++ b/src/Items/ItemRedstoneDust.h @@ -27,7 +27,7 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { - if (!g_BlockFullyOccupiesVoxel[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)]) // Some solid blocks, such as cocoa beans, are not suitable for dust + if (!cBlockInfo::FullyOccupiesVoxel(a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ))) // Some solid blocks, such as cocoa beans, are not suitable for dust { return false; } diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 9c81d004d..44dadb8a9 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -391,7 +391,7 @@ void cLightingThread::PrepareBlockLight(void) int idx = BaseZ + x; for (int y = m_HeightMap[idx], Index = idx + y * BlocksPerYLayer; y >= 0; y--, Index -= BlocksPerYLayer) { - if (g_BlockLightValue[m_BlockTypes[Index]] == 0) + if (cBlockInfo::GetLightValue(m_BlockTypes[Index]) == 0) { continue; } @@ -401,7 +401,7 @@ void cLightingThread::PrepareBlockLight(void) m_SeedIdx1[m_NumSeeds++] = Index; // Light it up: - m_BlockLight[Index] = g_BlockLightValue[m_BlockTypes[Index]]; + m_BlockLight[Index] = cBlockInfo::GetLightValue(m_BlockTypes[Index]); } } } diff --git a/src/LightingThread.h b/src/LightingThread.h index 72d561348..198f27248 100644 --- a/src/LightingThread.h +++ b/src/LightingThread.h @@ -169,13 +169,13 @@ protected: ASSERT(a_DstIdx >= 0); ASSERT(a_DstIdx < (int)ARRAYCOUNT(m_BlockTypes)); - if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]]) + if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + cBlockInfo::GetSpreadLightFalloff(m_BlockTypes[a_DstIdx])) { // We're not offering more light than the dest block already has return; } - a_Light[a_DstIdx] = a_Light[a_SrcIdx] - g_BlockSpreadLightFalloff[m_BlockTypes[a_DstIdx]]; + a_Light[a_DstIdx] = a_Light[a_SrcIdx] - cBlockInfo::GetSpreadLightFalloff(m_BlockTypes[a_DstIdx]); if (!a_IsSeedOut[a_DstIdx]) { a_IsSeedOut[a_DstIdx] = true; diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index c86268e63..7704f6cf3 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -145,7 +145,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R case cMonster::mtBat: { - return (a_RelY <= 63) && (BlockLight <= 4) && (SkyLight <= 4) && (TargetBlock == E_BLOCK_AIR) && (!g_BlockTransparent[BlockAbove]); + return (a_RelY <= 63) && (BlockLight <= 4) && (SkyLight <= 4) && (TargetBlock == E_BLOCK_AIR) && !cBlockInfo::IsTransparent(BlockAbove); } case cMonster::mtChicken: @@ -157,7 +157,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return ( (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && - (!g_BlockTransparent[BlockBelow]) && + (!cBlockInfo::IsTransparent(BlockBelow)) && (BlockBelow == E_BLOCK_GRASS) && (SkyLight >= 9) ); @@ -188,7 +188,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && (BlockTop == E_BLOCK_AIR) && - (!g_BlockTransparent[BlockBelow]) && + (!cBlockInfo::IsTransparent(BlockBelow)) && (SkyLight <= 7) && (BlockLight <= 7) ); @@ -215,7 +215,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R HaveFloor || ( a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1, a_RelZ + z, TargetBlock) && - !g_BlockTransparent[TargetBlock] + !cBlockInfo::IsTransparent(TargetBlock) ) ); } @@ -230,7 +230,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return ( (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && - (!g_BlockTransparent[BlockBelow]) && + (!cBlockInfo::IsTransparent(BlockBelow)) && (SkyLight <= 7) && (BlockLight <= 7) && (m_Random.NextInt(2, a_Biome) == 0) @@ -242,7 +242,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return ( (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && - (!g_BlockTransparent[BlockBelow]) && + (!cBlockInfo::IsTransparent(BlockBelow)) && ( (a_RelY <= 40) || (a_Biome == biSwampland) ) @@ -255,7 +255,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return ( (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && - (!g_BlockTransparent[BlockBelow]) && + (!cBlockInfo::IsTransparent(BlockBelow)) && (m_Random.NextInt(20, a_Biome) == 0) ); } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index ac9137ccd..6e3c91d58 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -148,11 +148,11 @@ void cMonster::TickPathFinding() BLOCKTYPE BlockAtYPP = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY + 2, gCrossCoords[i].z + PosZ); BLOCKTYPE BlockAtYM = m_World->GetBlock(gCrossCoords[i].x + PosX, PosY - 1, gCrossCoords[i].z + PosZ); - if ((!g_BlockIsSolid[BlockAtY]) && (!g_BlockIsSolid[BlockAtYP]) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) + if ((!cBlockInfo::IsSolid(BlockAtY)) && (!cBlockInfo::IsSolid(BlockAtYP)) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY, gCrossCoords[i].z + PosZ)); } - else if ((g_BlockIsSolid[BlockAtY]) && (!g_BlockIsSolid[BlockAtYP]) && (!g_BlockIsSolid[BlockAtYPP]) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) + else if ((cBlockInfo::IsSolid(BlockAtY)) && (!cBlockInfo::IsSolid(BlockAtYP)) && (!cBlockInfo::IsSolid(BlockAtYPP)) && (!IsBlockLava(BlockAtYM)) && (BlockAtY != E_BLOCK_FENCE) && (BlockAtY != E_BLOCK_FENCE_GATE)) { m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ)); } @@ -416,9 +416,9 @@ int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) else if (PosY > cChunkDef::Height) PosY = cChunkDef::Height; - if (!g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))]) + if (!cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ)))) { - while (!g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))] && (PosY > 0)) + while (!cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))) && (PosY > 0)) { PosY--; } @@ -427,7 +427,7 @@ int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) } else { - while (g_BlockIsSolid[m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))] && (PosY < cChunkDef::Height)) + while (cBlockInfo::IsSolid(m_World->GetBlock((int)floor(a_PosX), PosY, (int)floor(a_PosZ))) && (PosY < cChunkDef::Height)) { PosY++; } diff --git a/src/Mobs/SnowGolem.cpp b/src/Mobs/SnowGolem.cpp index 67e3a3bb8..c1979a495 100644 --- a/src/Mobs/SnowGolem.cpp +++ b/src/Mobs/SnowGolem.cpp @@ -38,7 +38,7 @@ void cSnowGolem::Tick(float a_Dt, cChunk & a_Chunk) { BLOCKTYPE BlockBelow = m_World->GetBlock((int) floor(GetPosX()), (int) floor(GetPosY()) - 1, (int) floor(GetPosZ())); BLOCKTYPE Block = m_World->GetBlock((int) floor(GetPosX()), (int) floor(GetPosY()), (int) floor(GetPosZ())); - if (Block == E_BLOCK_AIR && g_BlockIsSolid[BlockBelow]) + if (Block == E_BLOCK_AIR && cBlockInfo::IsSolid(BlockBelow)) { m_World->SetBlock((int) floor(GetPosX()), (int) floor(GetPosY()), (int) floor(GetPosZ()), E_BLOCK_SNOW, 0); } diff --git a/src/Piston.cpp b/src/Piston.cpp index 5eb14451d..b21d576f3 100644 --- a/src/Piston.cpp +++ b/src/Piston.cpp @@ -242,7 +242,7 @@ bool cPiston::CanPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) bool cPiston::CanBreakPush(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { UNUSED(a_BlockMeta); - return g_BlockPistonBreakable[a_BlockType]; + return cBlockInfo::IsPistonBreakable(a_BlockType); } diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index b77fa1658..6aef97079 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -239,7 +239,7 @@ int cFireSimulator::GetBurnStepTime(cChunk * a_Chunk, int a_RelX, int a_RelY, in { return m_BurnStepTimeFuel; } - IsBlockBelowSolid = g_BlockIsSolid[BlockBelow]; + IsBlockBelowSolid = cBlockInfo::IsSolid(BlockBelow); } for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 91de9e0cc..0640227b0 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -566,14 +566,14 @@ void cIncrementalRedstoneSimulator::HandleRedstoneWire(int a_BlockX, int a_Block { if ((i >= 4) && (i <= 7)) // If we are currently checking for wire surrounding ourself one block above... { - if (g_BlockIsSolid[m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ)]) // If there is something solid above us (wire cut off)... + if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))) // If there is something solid above us (wire cut off)... { continue; // We don't receive power from that wire } } else if ((i >= 8) && (i <= 11)) // See above, but this is for wire below us { - if (g_BlockIsSolid[m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y + 1, a_BlockZ + gCrossCoords[i].z)]) + if (cBlockInfo::IsSolid(m_World.GetBlock(a_BlockX + gCrossCoords[i].x, a_BlockY + gCrossCoords[i].y + 1, a_BlockZ + gCrossCoords[i].z))) { continue; } diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index e6bc28621..8b7363366 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -170,7 +170,7 @@ private: /* ====== Misc Functions ====== */ /** Returns if a block is viable to be the MiddleBlock of a SetLinkedPowered operation */ - inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return g_BlockFullyOccupiesVoxel[Block]; } + inline static bool IsViableMiddleBlock(BLOCKTYPE Block) { return cBlockInfo::FullyOccupiesVoxel(Block); } /** Returns if a block is a mechanism (something that accepts power and does something) */ inline static bool IsMechanism(BLOCKTYPE Block) diff --git a/src/Tracer.cpp b/src/Tracer.cpp index ef136302f..968a64439 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -226,7 +226,7 @@ bool cTracer::Trace( const Vector3f & a_Start, const Vector3f & a_Direction, int BLOCKTYPE BlockID = m_World->GetBlock(pos.x, pos.y, pos.z); // Block is counted as a collision if we are not doing a line of sight and it is solid, // or if the block is not air and not water. That way mobs can still see underwater. - if ((!a_LineOfSight && g_BlockIsSolid[BlockID]) || (a_LineOfSight && (BlockID != E_BLOCK_AIR) && !IsBlockWater(BlockID))) + if ((!a_LineOfSight && cBlockInfo::IsSolid(BlockID)) || (a_LineOfSight && (BlockID != E_BLOCK_AIR) && !IsBlockWater(BlockID))) { BlockHitPosition = pos; int Normal = GetHitNormal(a_Start, End, pos ); -- cgit v1.2.3 From 29cc1ed05160955d1a17e63a0e9b26b9203e5d0f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 1 Mar 2014 20:51:58 +0100 Subject: Ignoring all plugin subfolders. Plugins developed directly with MCS have been added explicitly; other plugins are ignored. --- MCServer/Plugins/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/Plugins/.gitignore b/MCServer/Plugins/.gitignore index 89eab800a..8553945b5 100644 --- a/MCServer/Plugins/.gitignore +++ b/MCServer/Plugins/.gitignore @@ -1,2 +1,3 @@ *.txt *.md +*/ -- cgit v1.2.3 From 2f85c9648b3f109bb579611dbb9af45b64c8a2f8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 1 Mar 2014 20:56:09 +0100 Subject: Unified StructureGens and FinisherGens. Now they are all Finishers. Fixes #398. --- src/Generating/Caves.cpp | 6 +- src/Generating/Caves.h | 16 ++-- src/Generating/ComposableGenerator.cpp | 157 +++++++++++++++------------------ src/Generating/ComposableGenerator.h | 56 ++++-------- src/Generating/MineShafts.cpp | 2 +- src/Generating/MineShafts.h | 6 +- src/Generating/Ravines.cpp | 2 +- src/Generating/Ravines.h | 6 +- src/Generating/StructGen.cpp | 10 +-- src/Generating/StructGen.h | 30 +++---- 10 files changed, 128 insertions(+), 163 deletions(-) diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp index 2571e6b77..98b7c8681 100644 --- a/src/Generating/Caves.cpp +++ b/src/Generating/Caves.cpp @@ -762,7 +762,7 @@ void cStructGenWormNestCaves::ClearCache(void) -void cStructGenWormNestCaves::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenWormNestCaves::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); @@ -902,7 +902,7 @@ static float GetMarbleNoise( float x, float y, float z, cNoise & a_Noise ) -void cStructGenMarbleCaves::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenMarbleCaves::GenFinish(cChunkDesc & a_ChunkDesc) { cNoise Noise(m_Seed); for (int z = 0; z < cChunkDef::Width; z++) @@ -938,7 +938,7 @@ void cStructGenMarbleCaves::GenStructures(cChunkDesc & a_ChunkDesc) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cStructGenDualRidgeCaves: -void cStructGenDualRidgeCaves::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenDualRidgeCaves::GenFinish(cChunkDesc & a_ChunkDesc) { for (int z = 0; z < cChunkDef::Width; z++) { diff --git a/src/Generating/Caves.h b/src/Generating/Caves.h index ea7f10bf4..7c45c056b 100644 --- a/src/Generating/Caves.h +++ b/src/Generating/Caves.h @@ -20,7 +20,7 @@ class cStructGenMarbleCaves : - public cStructureGen + public cFinishGen { public: cStructGenMarbleCaves(int a_Seed) : m_Seed(a_Seed) {} @@ -29,8 +29,8 @@ protected: int m_Seed; - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -38,7 +38,7 @@ protected: class cStructGenDualRidgeCaves : - public cStructureGen + public cFinishGen { public: cStructGenDualRidgeCaves(int a_Seed, float a_Threshold) : @@ -55,8 +55,8 @@ protected: int m_Seed; float m_Threshold; - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -64,7 +64,7 @@ protected: class cStructGenWormNestCaves : - public cStructureGen + public cFinishGen { public: cStructGenWormNestCaves(int a_Seed, int a_Size = 64, int a_Grid = 96, int a_MaxOffset = 128) : @@ -94,7 +94,7 @@ protected: void GetCavesForChunk(int a_ChunkX, int a_ChunkZ, cCaveSystems & a_Caves); // cStructGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index cfa7e9c6f..e96e9a645 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -133,11 +133,6 @@ cComposableGenerator::~cComposableGenerator() delete *itr; } m_FinishGens.clear(); - for (cStructureGenList::const_iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) - { - delete *itr; - } - m_StructureGens.clear(); delete m_CompositionGen; m_CompositionGen = NULL; @@ -164,7 +159,6 @@ void cComposableGenerator::Initialize(cIniFile & a_IniFile) InitBiomeGen(a_IniFile); InitHeightGen(a_IniFile); InitCompositionGen(a_IniFile); - InitStructureGens(a_IniFile); InitFinishGens(a_IniFile); } @@ -201,14 +195,6 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a m_CompositionGen->ComposeTerrain(a_ChunkDesc); } - if (a_ChunkDesc.IsUsingDefaultStructures()) - { - for (cStructureGenList::iterator itr = m_StructureGens.begin(); itr != m_StructureGens.end(); ++itr) - { - (*itr)->GenStructures(a_ChunkDesc); - } // for itr - m_StructureGens[] - } - if (a_ChunkDesc.IsUsingDefaultFinish()) { for (cFinishGenList::iterator itr = m_FinishGens.begin(); itr != m_FinishGens.end(); ++itr) @@ -290,35 +276,69 @@ void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile) -void cComposableGenerator::InitStructureGens(cIniFile & a_IniFile) +void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { - AString Structures = a_IniFile.GetValueSet("Generator", "Structures", "Ravines, WormNestCaves, WaterLakes, LavaLakes, OreNests, Trees"); - int Seed = m_ChunkGenerator.GetSeed(); - AStringVector Str = StringSplitAndTrim(Structures, ","); + eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld")); + + // Older configuration used "Structures" in addition to "Finishers"; we don't distinguish between the two anymore (#398) + // Therefore, we load Structures from the ini file for compatibility, but move its contents over to Finishers: + AString Structures = a_IniFile.GetValue("Generator", "Structures", ""); + AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, LavaLakes, OreNests, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator"); + if (!Structures.empty()) + { + LOGINFO("[Generator].Structures is deprecated, moving the contents to [Generator].Finishers."); + // Structures used to generate before Finishers, so place them first: + Structures.append(", "); + Finishers = Structures + Finishers; + a_IniFile.SetValue("Generator", "Finishers", Finishers); + } + a_IniFile.DeleteValue("Generator", "Structures"); + + // Create all requested finishers: + AStringVector Str = StringSplitAndTrim(Finishers, ","); for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) { - if (NoCaseCompare(*itr, "DualRidgeCaves") == 0) + // Finishers, alpha-sorted: + if (NoCaseCompare(*itr, "BottomLava") == 0) { - float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); - m_StructureGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold)); + int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; + int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); + m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel)); + } + else if (NoCaseCompare(*itr, "DeadBushes") == 0) + { + m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, biDesert, 2, E_BLOCK_SAND, E_BLOCK_SAND)); } else if (NoCaseCompare(*itr, "DirectOverhangs") == 0) { - m_StructureGens.push_back(new cStructGenDirectOverhangs(Seed)); + m_FinishGens.push_back(new cStructGenDirectOverhangs(Seed)); } else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0) { - m_StructureGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed)); + m_FinishGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed)); + } + else if (NoCaseCompare(*itr, "DualRidgeCaves") == 0) + { + float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); + m_FinishGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold)); + } + else if (NoCaseCompare(*itr, "Ice") == 0) + { + m_FinishGens.push_back(new cFinishGenIce); } else if (NoCaseCompare(*itr, "LavaLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10); - m_StructureGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen, Probability)); + m_FinishGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen, Probability)); + } + else if (NoCaseCompare(*itr, "LavaSprings") == 0) + { + m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)); } else if (NoCaseCompare(*itr, "MarbleCaves") == 0) { - m_StructureGens.push_back(new cStructGenMarbleCaves(Seed)); + m_FinishGens.push_back(new cStructGenMarbleCaves(Seed)); } else if (NoCaseCompare(*itr, "MineShafts") == 0) { @@ -327,71 +347,11 @@ void cComposableGenerator::InitStructureGens(cIniFile & a_IniFile) int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600); int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); - m_StructureGens.push_back(new cStructGenMineShafts( + m_FinishGens.push_back(new cStructGenMineShafts( Seed, GridSize, MaxSystemSize, ChanceCorridor, ChanceCrossing, ChanceStaircase )); } - else if (NoCaseCompare(*itr, "OreNests") == 0) - { - m_StructureGens.push_back(new cStructGenOreNests(Seed)); - } - else if (NoCaseCompare(*itr, "Ravines") == 0) - { - m_StructureGens.push_back(new cStructGenRavines(Seed, 128)); - } - else if (NoCaseCompare(*itr, "Trees") == 0) - { - m_StructureGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); - } - else if (NoCaseCompare(*itr, "WaterLakes") == 0) - { - int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); - m_StructureGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen, Probability)); - } - else if (NoCaseCompare(*itr, "WormNestCaves") == 0) - { - m_StructureGens.push_back(new cStructGenWormNestCaves(Seed)); - } - else - { - LOGWARNING("Unknown structure generator: \"%s\". Ignoring.", itr->c_str()); - } - } // for itr - Str[] -} - - - - - -void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) -{ - int Seed = m_ChunkGenerator.GetSeed(); - eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld")); - - AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "SprinkleFoliage,Ice,Snow,Lilypads,BottomLava,DeadBushes,PreSimulator"); - AStringVector Str = StringSplitAndTrim(Finishers, ","); - for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) - { - // Finishers, alpha-sorted: - if (NoCaseCompare(*itr, "BottomLava") == 0) - { - int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; - int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); - m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel)); - } - else if (NoCaseCompare(*itr, "DeadBushes") == 0) - { - m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, biDesert, 2, E_BLOCK_SAND, E_BLOCK_SAND)); - } - else if (NoCaseCompare(*itr, "Ice") == 0) - { - m_FinishGens.push_back(new cFinishGenIce); - } - else if (NoCaseCompare(*itr, "LavaSprings") == 0) - { - m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)); - } else if (NoCaseCompare(*itr, "Lilypads") == 0) { m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_LILY_PAD, biSwampland, 4, E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER)); @@ -400,10 +360,18 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed)); } + else if (NoCaseCompare(*itr, "OreNests") == 0) + { + m_FinishGens.push_back(new cStructGenOreNests(Seed)); + } else if (NoCaseCompare(*itr, "PreSimulator") == 0) { m_FinishGens.push_back(new cFinishGenPreSimulator); } + else if (NoCaseCompare(*itr, "Ravines") == 0) + { + m_FinishGens.push_back(new cStructGenRavines(Seed, 128)); + } else if (NoCaseCompare(*itr, "Snow") == 0) { m_FinishGens.push_back(new cFinishGenSnow); @@ -412,10 +380,27 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed)); } + else if (NoCaseCompare(*itr, "Trees") == 0) + { + m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); + } + else if (NoCaseCompare(*itr, "WaterLakes") == 0) + { + int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); + m_FinishGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen, Probability)); + } else if (NoCaseCompare(*itr, "WaterSprings") == 0) { m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension)); } + else if (NoCaseCompare(*itr, "WormNestCaves") == 0) + { + m_FinishGens.push_back(new cStructGenWormNestCaves(Seed)); + } + else + { + LOGWARNING("Unknown Finisher in the [Generator] section: \"%s\". Ignoring.", itr->c_str()); + } } // for itr - Str[] } diff --git a/src/Generating/ComposableGenerator.h b/src/Generating/ComposableGenerator.h index 29add0636..6b7627d2e 100644 --- a/src/Generating/ComposableGenerator.h +++ b/src/Generating/ComposableGenerator.h @@ -43,16 +43,16 @@ class cBiomeGen public: virtual ~cBiomeGen() {} // Force a virtual destructor in descendants - /// Generates biomes for the given chunk + /** Generates biomes for the given chunk */ virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0; - /// Reads parameters from the ini file, prepares generator for use. + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeBiomeGen(cIniFile & a_IniFile) {} - /// Creates the correct BiomeGen descendant based on the ini file settings and the seed provided. - /// a_CacheOffByDefault gets set to whether the cache should be disabled by default - /// Used in BiomeVisualiser, too. - /// Implemented in BioGen.cpp! + /** Creates the correct BiomeGen descendant based on the ini file settings and the seed provided. + a_CacheOffByDefault gets set to whether the cache should be disabled by default. + Used in BiomeVisualiser, too. + Implemented in BioGen.cpp! */ static cBiomeGen * CreateBiomeGen(cIniFile & a_IniFile, int a_Seed, bool & a_CacheOffByDefault); } ; @@ -72,10 +72,10 @@ class cTerrainHeightGen public: virtual ~cTerrainHeightGen() {} // Force a virtual destructor in descendants - /// Generates heightmap for the given chunk + /** Generates heightmap for the given chunk */ virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) = 0; - /// Reads parameters from the ini file, prepares generator for use. + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeHeightGen(cIniFile & a_IniFile) {} /** Creates the correct TerrainHeightGen descendant based on the ini file settings and the seed provided. @@ -102,7 +102,7 @@ public: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc) = 0; - /// Reads parameters from the ini file, prepares generator for use. + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeCompoGen(cIniFile & a_IniFile) {} /** Creates the correct TerrainCompositionGen descendant based on the ini file settings and the seed provided. @@ -116,28 +116,12 @@ public: -/** The interface that a structure generator must implement -Structures are generated after the terrain composition took place. It should modify the blocktype data to account -for whatever structures the generator is generating. -Note that ores are considered structures too, at least from the interface point of view. -Also note that a worldgenerator may contain multiple structure generators, one for each type of structure -*/ -class cStructureGen -{ -public: - virtual ~cStructureGen() {} // Force a virtual destructor in descendants - - virtual void GenStructures(cChunkDesc & a_ChunkDesc) = 0; -} ; - -typedef std::list cStructureGenList; - - - - - /** The interface that a finisher must implement -Finisher implements small additions after all structures have been generated. +Finisher implements changes to the chunk after the rough terrain has been generated. +Examples of finishers are trees, snow, ore, lilypads and others. +Note that a worldgenerator may contain multiple finishers. +Also note that previously we used to distinguish between a structuregen and a finisher; this distinction is +no longer relevant, all structure generators are considered finishers now (#398) */ class cFinishGen { @@ -171,7 +155,6 @@ protected: cBiomeGen * m_BiomeGen; cTerrainHeightGen * m_HeightGen; cTerrainCompositionGen * m_CompositionGen; - cStructureGenList m_StructureGens; cFinishGenList m_FinishGens; // Generators underlying the caches: @@ -180,19 +163,16 @@ protected: cTerrainCompositionGen * m_UnderlyingCompositionGen; - /// Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly + /** Reads the biome gen settings from the ini and initializes m_BiomeGen accordingly */ void InitBiomeGen(cIniFile & a_IniFile); - /// Reads the HeightGen settings from the ini and initializes m_HeightGen accordingly + /** Reads the HeightGen settings from the ini and initializes m_HeightGen accordingly */ void InitHeightGen(cIniFile & a_IniFile); - /// Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly + /** Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly */ void InitCompositionGen(cIniFile & a_IniFile); - /// Reads the structures to generate from the ini and initializes m_StructureGens accordingly - void InitStructureGens(cIniFile & a_IniFile); - - /// Reads the finishers from the ini and initializes m_FinishGens accordingly + /** Reads the finishers from the ini and initializes m_FinishGens accordingly */ void InitFinishGens(cIniFile & a_IniFile); } ; diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index cc39cef7b..d9acc57bb 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -1407,7 +1407,7 @@ void cStructGenMineShafts::GetMineShaftSystemsForChunk( -void cStructGenMineShafts::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenMineShafts::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); diff --git a/src/Generating/MineShafts.h b/src/Generating/MineShafts.h index c53d3bc53..ba32e75ad 100644 --- a/src/Generating/MineShafts.h +++ b/src/Generating/MineShafts.h @@ -17,7 +17,7 @@ class cStructGenMineShafts : - public cStructureGen + public cFinishGen { public: cStructGenMineShafts( @@ -52,8 +52,8 @@ protected: */ void GetMineShaftSystemsForChunk(int a_ChunkX, int a_ChunkZ, cMineShaftSystems & a_MineShaftSystems); - // cStructureGen overrides: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen overrides: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; diff --git a/src/Generating/Ravines.cpp b/src/Generating/Ravines.cpp index cfda47e32..e64f55214 100644 --- a/src/Generating/Ravines.cpp +++ b/src/Generating/Ravines.cpp @@ -117,7 +117,7 @@ void cStructGenRavines::ClearCache(void) -void cStructGenRavines::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenRavines::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); diff --git a/src/Generating/Ravines.h b/src/Generating/Ravines.h index 05164a5b2..c76b9f19f 100644 --- a/src/Generating/Ravines.h +++ b/src/Generating/Ravines.h @@ -17,7 +17,7 @@ class cStructGenRavines : - public cStructureGen + public cFinishGen { public: cStructGenRavines(int a_Seed, int a_Size); @@ -37,8 +37,8 @@ protected: /// Returns all ravines that *may* intersect the given chunk. All the ravines are valid until the next call to this function. void GetRavinesForChunk(int a_ChunkX, int a_ChunkZ, cRavines & a_Ravines); - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index 47945cc2b..3cc8a09c3 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -54,7 +54,7 @@ const int NEST_SIZE_GRAVEL = 32; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cStructGenTrees: -void cStructGenTrees::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); @@ -306,7 +306,7 @@ int cStructGenTrees::GetNumTrees( /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cStructGenOreNests: -void cStructGenOreNests::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenOreNests::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); @@ -413,7 +413,7 @@ void cStructGenOreNests::GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_Ore /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cStructGenLakes: -void cStructGenLakes::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenLakes::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); @@ -545,7 +545,7 @@ cStructGenDirectOverhangs::cStructGenDirectOverhangs(int a_Seed) : -void cStructGenDirectOverhangs::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) { // If there is no column of the wanted biome, bail out: if (!HasWantedBiome(a_ChunkDesc)) @@ -665,7 +665,7 @@ cStructGenDistortedMembraneOverhangs::cStructGenDistortedMembraneOverhangs(int a -void cStructGenDistortedMembraneOverhangs::GenStructures(cChunkDesc & a_ChunkDesc) +void cStructGenDistortedMembraneOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) { const NOISE_DATATYPE Frequency = (NOISE_DATATYPE)16; const NOISE_DATATYPE Amount = (NOISE_DATATYPE)1; diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index 853748bb8..9176bc192 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -21,7 +21,7 @@ class cStructGenTrees : - public cStructureGen + public cFinishGen { public: cStructGenTrees(int a_Seed, cBiomeGen * a_BiomeGen, cTerrainHeightGen * a_HeightGen, cTerrainCompositionGen * a_CompositionGen) : @@ -64,8 +64,8 @@ protected: const cChunkDef::BiomeMap & a_Biomes ); - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -73,7 +73,7 @@ protected: class cStructGenOreNests : - public cStructureGen + public cFinishGen { public: cStructGenOreNests(int a_Seed) : m_Noise(a_Seed), m_Seed(a_Seed) {} @@ -82,8 +82,8 @@ protected: cNoise m_Noise; int m_Seed; - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; void GenerateOre(int a_ChunkX, int a_ChunkZ, BLOCKTYPE a_OreType, int a_MaxHeight, int a_NumNests, int a_NestSize, cChunkDef::BlockTypes & a_BlockTypes, int a_Seq); } ; @@ -93,7 +93,7 @@ protected: class cStructGenLakes : - public cStructureGen + public cFinishGen { public: cStructGenLakes(int a_Seed, BLOCKTYPE a_Fluid, cTerrainHeightGen & a_HeiGen, int a_Probability) : @@ -112,8 +112,8 @@ protected: cTerrainHeightGen & m_HeiGen; int m_Probability; ///< Chance, 0 .. 100, of a chunk having the lake - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; /// Creates a lake image for the specified chunk into a_Lake void CreateLakeImage(int a_ChunkX, int a_ChunkZ, cBlockArea & a_Lake); @@ -125,7 +125,7 @@ protected: class cStructGenDirectOverhangs : - public cStructureGen + public cFinishGen { public: cStructGenDirectOverhangs(int a_Seed); @@ -134,8 +134,8 @@ protected: cNoise m_Noise1; cNoise m_Noise2; - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; bool HasWantedBiome(cChunkDesc & a_ChunkDesc) const; } ; @@ -145,7 +145,7 @@ protected: class cStructGenDistortedMembraneOverhangs : - public cStructureGen + public cFinishGen { public: cStructGenDistortedMembraneOverhangs(int a_Seed); @@ -156,8 +156,8 @@ protected: cNoise m_NoiseZ; cNoise m_NoiseH; - // cStructureGen override: - virtual void GenStructures(cChunkDesc & a_ChunkDesc) override; + // cFinishGen override: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; -- cgit v1.2.3 From 2325a1a162a888e34ed7f80b2e59d3987b034b51 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 1 Mar 2014 20:59:22 +0100 Subject: ChunkDesc warns about StructureGen's deprecation. --- src/Generating/ChunkDesc.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index d9529b4b0..308fbe423 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -209,6 +209,7 @@ bool cChunkDesc::IsUsingDefaultComposition(void) const void cChunkDesc::SetUseDefaultStructures(bool a_bUseDefaultStructures) { + LOGWARNING("%s: Structures are no longer accounted for, use Finishers instead", __FUNCTION__); m_bUseDefaultStructures = a_bUseDefaultStructures; } @@ -218,6 +219,7 @@ void cChunkDesc::SetUseDefaultStructures(bool a_bUseDefaultStructures) bool cChunkDesc::IsUsingDefaultStructures(void) const { + LOGWARNING("%s: Structures are no longer accounted for, use Finishers instead", __FUNCTION__); return m_bUseDefaultStructures; } -- cgit v1.2.3 From 2998228e85bb535ea49f3ef0d7314274a72dd9b9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 2 Mar 2014 08:22:27 +0100 Subject: Added more documentation for FastNBT parser. --- src/WorldStorage/FastNBT.h | 48 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index d68ebd54c..01a9ad274 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -106,6 +106,10 @@ public: /** Parses and contains the parsed data Also implements data accessor functions for tree traversal and value getters The data pointer passed in the constructor is assumed to be valid throughout the object's life. Care must be taken not to initialize from a temporary. +The parser decomposes the input data into a tree of tags that is stored as an array of cFastNBTTag items, +and accessing the tree is done by using the array indices for tags. Each tag stores the indices for its parent, +first child, last child, prev sibling and next sibling, a value of -1 indicates that the indice is not valid. +Each primitive tag also stores the length of the contained data, in bytes. */ class cParsedNBT { @@ -114,13 +118,32 @@ public: bool IsValid(void) const {return m_IsValid; } + /** Returns the root tag of the hierarchy. */ int GetRoot(void) const {return 0; } + + /** Returns the first child of the specified tag, or -1 if none / not applicable. */ int GetFirstChild (int a_Tag) const { return m_Tags[a_Tag].m_FirstChild; } + + /** Returns the last child of the specified tag, or -1 if none / not applicable. */ int GetLastChild (int a_Tag) const { return m_Tags[a_Tag].m_LastChild; } + + /** Returns the next sibling of the specified tag, or -1 if none. */ int GetNextSibling(int a_Tag) const { return m_Tags[a_Tag].m_NextSibling; } + + /** Returns the previous sibling of the specified tag, or -1 if none. */ int GetPrevSibling(int a_Tag) const { return m_Tags[a_Tag].m_PrevSibling; } - int GetDataLength (int a_Tag) const { return m_Tags[a_Tag].m_DataLength; } + + /** Returns the length of the tag's data, in bytes. + Not valid for Compound or List tags! */ + int GetDataLength (int a_Tag) const + { + ASSERT(m_Tags[a_Tag].m_Type != TAG_List); + ASSERT(m_Tags[a_Tag].m_Type != TAG_Compound); + return m_Tags[a_Tag].m_DataLength; + } + /** Returns the data stored in this tag. + Not valid for Compound or List tags! */ const char * GetData(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type != TAG_List); @@ -128,47 +151,56 @@ public: return m_Data + m_Tags[a_Tag].m_DataStart; } + /** Returns the direct child tag of the specified name, or -1 if no such tag. */ int FindChildByName(int a_Tag, const AString & a_Name) const { return FindChildByName(a_Tag, a_Name.c_str(), a_Name.length()); } + /** Returns the direct child tag of the specified name, or -1 if no such tag. */ int FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength = 0) const; - int FindTagByPath (int a_Tag, const AString & a_Path) const; + + /** Returns the child tag of the specified path (Name1\Name2\Name3...), or -1 if no such tag. */ + int FindTagByPath(int a_Tag, const AString & a_Path) const; eTagType GetType(int a_Tag) const { return m_Tags[a_Tag].m_Type; } - /// Returns the children type for a list tag; undefined on other tags. If list empty, returns TAG_End + /** Returns the children type for a List tag; undefined on other tags. If list empty, returns TAG_End. */ eTagType GetChildrenType(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_List); return (m_Tags[a_Tag].m_FirstChild < 0) ? TAG_End : m_Tags[m_Tags[a_Tag].m_FirstChild].m_Type; } + /** Returns the value stored in a Byte tag. Not valid for any other tag type. */ inline unsigned char GetByte(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_Byte); return (unsigned char)(m_Data[m_Tags[a_Tag].m_DataStart]); } + /** Returns the value stored in a Short tag. Not valid for any other tag type. */ inline Int16 GetShort(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_Short); return GetBEShort(m_Data + m_Tags[a_Tag].m_DataStart); } + /** Returns the value stored in an Int tag. Not valid for any other tag type. */ inline Int32 GetInt(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_Int); return GetBEInt(m_Data + m_Tags[a_Tag].m_DataStart); } + /** Returns the value stored in a Long tag. Not valid for any other tag type. */ inline Int64 GetLong(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_Long); return NetworkToHostLong8(m_Data + m_Tags[a_Tag].m_DataStart); } + /** Returns the value stored in a Float tag. Not valid for any other tag type. */ inline float GetFloat(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_Float); @@ -186,12 +218,21 @@ public: return f; } + /** Returns the value stored in a Double tag. Not valid for any other tag type. */ inline double GetDouble(int a_Tag) const { + // Cause a compile-time error if sizeof(double) != 8 + // If your platform produces a compiler error here, you'll need to add code that manually decodes 64-bit doubles + char Check1[9 - sizeof(double)]; // Fails if sizeof(double) > 8 + char Check2[sizeof(double) - 7]; // Fails if sizeof(double) < 8 + UNUSED(Check1); + UNUSED(Check2); + ASSERT(m_Tags[a_Tag].m_Type == TAG_Double); return NetworkToHostDouble8(m_Data + m_Tags[a_Tag].m_DataStart); } + /** Returns the value stored in a String tag. Not valid for any other tag type. */ inline AString GetString(int a_Tag) const { ASSERT(m_Tags[a_Tag].m_Type == TAG_String); @@ -200,6 +241,7 @@ public: return res; } + /** Returns the tag's name. For tags that are not named, returns an empty string. */ inline AString GetName(int a_Tag) const { AString res; -- cgit v1.2.3 From 3ca56b39bce5ad59625d2ffb5ae730858fed8bcd Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 2 Mar 2014 10:50:24 +0200 Subject: Exported cBlockInfo --- MCServer/Plugins/APIDump/APIDesc.lua | 32 ++++++++++++++++++++++++++++++++ src/Bindings/AllToLua.pkg | 1 + src/BlockInfo.h | 11 ++++++++--- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 4d0113223..695d1a853 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -290,6 +290,38 @@ g_APIDesc = }, -- AdditionalInfo }, -- cBlockArea + cBlockInfo = + { + Desc = [[ + This class is used to query and register block properties. + ]], + Functions = + { + FullyOccupiesVoxel = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block fully occupies its voxel." }, + GetById = { Params = "ID", Return = "{{cBlockInfo}}", Notes = "Returns the {{cBlockInfo}} structure for the block with the specified ID." }, + GetLightValue = { Params = "ID", Return = "number", Notes = "Returns how much light the specified block emits on its own." }, + GetSpreadLightFalloff = { Params = "ID", Return = "number", Notes = "Returns how much light the specified block consumes." }, + IsOneHitDig = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block will be destroyed after a single hit." }, + IsPistonBreakable = { Params = "ID", Return = "bool", Notes = "Returns whether a piston can break the specified block." }, + IsSnowable = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block can hold snow atop." }, + IsSolid = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block is solid." }, + IsTransparent = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block is transparent." }, + RequiresSpecialTool = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block requires a special tool to drop." }, + }, + Variables = + { + m_FullyOccupiesVoxel = { Type = "bool", Notes = "Does this block fully occupy its voxel - is it a 'full' block?" }, + m_IsSnowable = { Type = "bool", Notes = "Can this block hold snow atop?" }, + m_IsSolid = { Type = "bool", Notes = "Is this block solid (player cannot walk through)?" }, + m_LightValue = { Type = "number", Notes = "How much light do the blocks emit on their own?" }, + m_OneHitDig = { Type = "bool", Notes = "Is a block destroyed after a single hit?" }, + m_PistonBreakable = { Type = "bool", Notes = "Can a piston break this block?" }, + m_RequiresSpecialTool = { Type = "bool", Notes = "Does this block require a tool to drop?" }, + m_SpreadLightFalloff = { Type = "number", Notes = "How much light do the blocks consume?" }, + m_Transparent = { Type = "bool", Notes = "Is a block completely transparent? (light doesn't get decreased(?))" }, + }, + }, -- cBlockInfo + cChatColor = { Desc = [[ diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 1a2140771..6b067b1e5 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -26,6 +26,7 @@ $cfile "WebPlugin.h" $cfile "LuaWindow.h" $cfile "../BlockID.h" +$cfile "../BlockInfo.h" $cfile "../StringUtils.h" $cfile "../Defines.h" $cfile "../ChatColor.h" diff --git a/src/BlockInfo.h b/src/BlockInfo.h index a06c47a47..57092ca54 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -5,16 +5,19 @@ - +// tolua_begin class cBlockInfo { public: + // tolua_end cBlockInfo(); /** (Re-)Initializes the internal BlockInfo structures. */ static void Initialize(void); + // tolua_begin + /** Returns the associated BlockInfo structure. */ static cBlockInfo & GetById(unsigned int a_ID); @@ -43,7 +46,7 @@ public: /** Is this block solid (player cannot walk through)? */ bool m_IsSolid; - /** Does this block fully occupy it's voxel - is it a 'full' block? */ + /** Does this block fully occupy its voxel - is it a 'full' block? */ bool m_FullyOccupiesVoxel; @@ -57,6 +60,8 @@ public: inline static bool IsSolid (unsigned int a_ID) { return GetById(a_ID).m_IsSolid; } inline static bool FullyOccupiesVoxel (unsigned int a_ID) { return GetById(a_ID).m_FullyOccupiesVoxel; } + // tolua_end + protected: @@ -64,7 +69,7 @@ protected: static cBlockInfo ms_Info[256]; -}; +}; // tolua_export -- cgit v1.2.3 From 68b75f7b7a2ff09b55526c80f4201c029fae7ce7 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 2 Mar 2014 11:12:29 +0200 Subject: Manually exported g_Block tables --- src/Bindings/DeprecatedBindings.cpp | 434 ++++++++++++++++++++++++++++++++++++ src/Bindings/DeprecatedBindings.h | 8 + src/Bindings/LuaState.cpp | 2 + src/CMakeLists.txt | 1 + 4 files changed, 445 insertions(+) create mode 100644 src/Bindings/DeprecatedBindings.cpp create mode 100644 src/Bindings/DeprecatedBindings.h diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp new file mode 100644 index 000000000..08d775f10 --- /dev/null +++ b/src/Bindings/DeprecatedBindings.cpp @@ -0,0 +1,434 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "DeprecatedBindings.h" +#include "tolua++/include/tolua++.h" + +#include "Plugin.h" +#include "PluginLua.h" +#include "PluginManager.h" +#include "LuaWindow.h" +#include "LuaChunkStay.h" + +#include "../BlockInfo.h" + + + + + +/* get function: g_BlockLightValue */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockLightValue +static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetLightValue(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockLightValue */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockLightValue +static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::GetById(tolua_index).m_LightValue = ((unsigned char) tolua_tonumber(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockSpreadLightFalloff */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockSpreadLightFalloff +static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetSpreadLightFalloff(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockSpreadLightFalloff */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockSpreadLightFalloff +static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::GetById(tolua_index).m_SpreadLightFalloff = ((unsigned char) tolua_tonumber(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockTransparent */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockTransparent +static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsTransparent(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockTransparent */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockTransparent +static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::GetById(tolua_index).m_Transparent = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockOneHitDig */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockOneHitDig +static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsOneHitDig(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockOneHitDig */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockOneHitDig +static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::GetById(tolua_index).m_OneHitDig = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockPistonBreakable */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockPistonBreakable +static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsPistonBreakable(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockPistonBreakable */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockPistonBreakable +static int tolua_set_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::GetById(tolua_index).m_PistonBreakable = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockIsSnowable */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockIsSnowable +static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsSnowable(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockIsSnowable */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockIsSnowable +static int tolua_set_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::GetById(tolua_index).m_IsSnowable = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockRequiresSpecialTool */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockRequiresSpecialTool +static int tolua_get_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::RequiresSpecialTool(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockRequiresSpecialTool */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockRequiresSpecialTool +static int tolua_set_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::GetById(tolua_index).m_RequiresSpecialTool = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockIsSolid */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockIsSolid +static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsSolid(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockIsSolid */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockIsSolid +static int tolua_set_AllToLua_g_BlockIsSolid(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::GetById(tolua_index).m_IsSolid = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + +/* get function: g_BlockFullyOccupiesVoxel */ +#ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockFullyOccupiesVoxel +static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + tolua_pushboolean(tolua_S,(bool)cBlockInfo::FullyOccupiesVoxel(tolua_index)); + return 1; +} +#endif //#ifndef TOLUA_DISABLE + +/* set function: g_BlockFullyOccupiesVoxel */ +#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockFullyOccupiesVoxel +static int tolua_set_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) +{ + int tolua_index; + #ifndef TOLUA_RELEASE + { + tolua_Error tolua_err; + if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } + #endif + tolua_index = (int)tolua_tonumber(tolua_S,2,0); + #ifndef TOLUA_RELEASE + if (tolua_index<0 || tolua_index>=256) + tolua_error(tolua_S,"array indexing out of range.",NULL); + #endif + cBlockInfo::GetById(tolua_index).m_FullyOccupiesVoxel = ((bool) tolua_toboolean(tolua_S,3,0)); + return 0; +} +#endif //#ifndef TOLUA_DISABLE + + + + + +void DeprecatedBindings::Bind(lua_State * tolua_S) +{ + tolua_array(tolua_S, "g_BlockLightValue", tolua_get_AllToLua_g_BlockLightValue, tolua_set_AllToLua_g_BlockLightValue); + tolua_array(tolua_S, "g_BlockSpreadLightFalloff", tolua_get_AllToLua_g_BlockSpreadLightFalloff, tolua_set_AllToLua_g_BlockSpreadLightFalloff); + tolua_array(tolua_S, "g_BlockTransparent", tolua_get_AllToLua_g_BlockTransparent, tolua_set_AllToLua_g_BlockTransparent); + tolua_array(tolua_S, "g_BlockOneHitDig", tolua_get_AllToLua_g_BlockOneHitDig, tolua_set_AllToLua_g_BlockOneHitDig); + tolua_array(tolua_S, "g_BlockPistonBreakable", tolua_get_AllToLua_g_BlockPistonBreakable, tolua_set_AllToLua_g_BlockPistonBreakable); + tolua_array(tolua_S, "g_BlockIsSnowable", tolua_get_AllToLua_g_BlockIsSnowable, tolua_set_AllToLua_g_BlockIsSnowable); + tolua_array(tolua_S, "g_BlockRequiresSpecialTool", tolua_get_AllToLua_g_BlockRequiresSpecialTool, tolua_set_AllToLua_g_BlockRequiresSpecialTool); + tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, tolua_set_AllToLua_g_BlockIsSolid); + tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, tolua_set_AllToLua_g_BlockFullyOccupiesVoxel); +} + + + + diff --git a/src/Bindings/DeprecatedBindings.h b/src/Bindings/DeprecatedBindings.h new file mode 100644 index 000000000..5fc3cfa80 --- /dev/null +++ b/src/Bindings/DeprecatedBindings.h @@ -0,0 +1,8 @@ +#pragma once + +struct lua_State; +class DeprecatedBindings +{ +public: + static void Bind( lua_State* tolua_S ); +}; diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 45a066efe..a5540df17 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -14,6 +14,7 @@ extern "C" #include "tolua++/include/tolua++.h" #include "Bindings.h" #include "ManualBindings.h" +#include "DeprecatedBindings.h" // fwd: SQLite/lsqlite3.c extern "C" @@ -95,6 +96,7 @@ void cLuaState::Create(void) luaL_openlibs(m_LuaState); tolua_AllToLua_open(m_LuaState); ManualBindings::Bind(m_LuaState); + DeprecatedBindings::Bind(m_LuaState); luaopen_lsqlite3(m_LuaState); luaopen_lxp(m_LuaState); m_IsOwned = true; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 387556775..5e0731264 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -95,6 +95,7 @@ if (NOT MSVC) #add cpp files here add_library(Bindings Bindings/Bindings + Bindings/DeprecatedBindings Bindings/LuaChunkStay Bindings/LuaState Bindings/LuaWindow -- cgit v1.2.3 From cff4ee11f125efb0b10ffe19d84869b858416584 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 2 Mar 2014 11:30:20 +0200 Subject: Removed g_BlockXXX arrays --- src/Bindings/DeprecatedBindings.cpp | 4 + src/BlockID.cpp | 399 ------------------------------------ src/BlockID.h | 14 -- src/Defines.h | 27 --- 4 files changed, 4 insertions(+), 440 deletions(-) diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 08d775f10..3e4940494 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -418,6 +418,8 @@ static int tolua_set_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) void DeprecatedBindings::Bind(lua_State * tolua_S) { + tolua_beginmodule(tolua_S, NULL); + tolua_array(tolua_S, "g_BlockLightValue", tolua_get_AllToLua_g_BlockLightValue, tolua_set_AllToLua_g_BlockLightValue); tolua_array(tolua_S, "g_BlockSpreadLightFalloff", tolua_get_AllToLua_g_BlockSpreadLightFalloff, tolua_set_AllToLua_g_BlockSpreadLightFalloff); tolua_array(tolua_S, "g_BlockTransparent", tolua_get_AllToLua_g_BlockTransparent, tolua_set_AllToLua_g_BlockTransparent); @@ -427,6 +429,8 @@ void DeprecatedBindings::Bind(lua_State * tolua_S) tolua_array(tolua_S, "g_BlockRequiresSpecialTool", tolua_get_AllToLua_g_BlockRequiresSpecialTool, tolua_set_AllToLua_g_BlockRequiresSpecialTool); tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, tolua_set_AllToLua_g_BlockIsSolid); tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, tolua_set_AllToLua_g_BlockFullyOccupiesVoxel); + + tolua_endmodule(tolua_S); } diff --git a/src/BlockID.cpp b/src/BlockID.cpp index ff1c54e3f..79e122032 100644 --- a/src/BlockID.cpp +++ b/src/BlockID.cpp @@ -12,20 +12,6 @@ -NIBBLETYPE g_BlockLightValue[256]; -NIBBLETYPE g_BlockSpreadLightFalloff[256]; -bool g_BlockTransparent[256]; -bool g_BlockOneHitDig[256]; -bool g_BlockPistonBreakable[256]; -bool g_BlockIsSnowable[256]; -bool g_BlockRequiresSpecialTool[256]; -bool g_BlockIsSolid[256]; -bool g_BlockFullyOccupiesVoxel[256]; - - - - - class cBlockIDMap { // Making the map case-insensitive: @@ -481,389 +467,4 @@ cItem GetIniItemSet(cIniFile & a_IniFile, const char * a_Section, const char * a -// This is actually just some code that needs to run at program startup, so it is wrapped into a global var's constructor: -class cBlockPropertiesInitializer -{ -public: - cBlockPropertiesInitializer(void) - { - memset(g_BlockLightValue, 0x00, sizeof(g_BlockLightValue)); - memset(g_BlockSpreadLightFalloff, 0x0f, sizeof(g_BlockSpreadLightFalloff)); // 0x0f means total falloff - memset(g_BlockTransparent, 0x00, sizeof(g_BlockTransparent)); - memset(g_BlockOneHitDig, 0x00, sizeof(g_BlockOneHitDig)); - memset(g_BlockPistonBreakable, 0x00, sizeof(g_BlockPistonBreakable)); - memset(g_BlockFullyOccupiesVoxel, 0x00, sizeof(g_BlockFullyOccupiesVoxel)); - - // Setting bools to true must be done manually, see http://forum.mc-server.org/showthread.php?tid=629&pid=5415#pid5415 - for (size_t i = 0; i < ARRAYCOUNT(g_BlockIsSnowable); i++) - { - g_BlockIsSnowable[i] = true; - } - memset(g_BlockRequiresSpecialTool, 0x00, sizeof(g_BlockRequiresSpecialTool)); // Set all blocks to false - - // Setting bools to true must be done manually, see http://forum.mc-server.org/showthread.php?tid=629&pid=5415#pid5415 - for (size_t i = 0; i < ARRAYCOUNT(g_BlockIsSolid); i++) - { - g_BlockIsSolid[i] = true; - } - - // Emissive blocks - g_BlockLightValue[E_BLOCK_FIRE] = 15; - g_BlockLightValue[E_BLOCK_GLOWSTONE] = 15; - g_BlockLightValue[E_BLOCK_JACK_O_LANTERN] = 15; - g_BlockLightValue[E_BLOCK_LAVA] = 15; - g_BlockLightValue[E_BLOCK_STATIONARY_LAVA] = 15; - g_BlockLightValue[E_BLOCK_END_PORTAL] = 15; - g_BlockLightValue[E_BLOCK_REDSTONE_LAMP_ON] = 15; - g_BlockLightValue[E_BLOCK_TORCH] = 14; - g_BlockLightValue[E_BLOCK_BURNING_FURNACE] = 13; - g_BlockLightValue[E_BLOCK_NETHER_PORTAL] = 11; - g_BlockLightValue[E_BLOCK_REDSTONE_ORE_GLOWING] = 9; - g_BlockLightValue[E_BLOCK_REDSTONE_REPEATER_ON] = 9; - g_BlockLightValue[E_BLOCK_REDSTONE_TORCH_ON] = 7; - g_BlockLightValue[E_BLOCK_BREWING_STAND] = 1; - g_BlockLightValue[E_BLOCK_BROWN_MUSHROOM] = 1; - g_BlockLightValue[E_BLOCK_DRAGON_EGG] = 1; - - // Spread blocks - g_BlockSpreadLightFalloff[E_BLOCK_AIR] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_CAKE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_CHEST] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_COBWEB] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_CROPS] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_FENCE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_FENCE_GATE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_FIRE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_GLASS] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_GLASS_PANE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_GLOWSTONE] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_IRON_BARS] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_IRON_DOOR] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_LEAVES] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_SIGN_POST] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_TORCH] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_VINES] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_WALLSIGN] = 1; - g_BlockSpreadLightFalloff[E_BLOCK_WOODEN_DOOR] = 1; - - // Light in water and lava dissapears faster: - g_BlockSpreadLightFalloff[E_BLOCK_LAVA] = 3; - g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_LAVA] = 3; - g_BlockSpreadLightFalloff[E_BLOCK_STATIONARY_WATER] = 3; - g_BlockSpreadLightFalloff[E_BLOCK_WATER] = 3; - - // Transparent blocks - g_BlockTransparent[E_BLOCK_ACTIVATOR_RAIL] = true; - g_BlockTransparent[E_BLOCK_AIR] = true; - g_BlockTransparent[E_BLOCK_BIG_FLOWER] = true; - g_BlockTransparent[E_BLOCK_BROWN_MUSHROOM] = true; - g_BlockTransparent[E_BLOCK_CARROTS] = true; - g_BlockTransparent[E_BLOCK_CHEST] = true; - g_BlockTransparent[E_BLOCK_COBWEB] = true; - g_BlockTransparent[E_BLOCK_CROPS] = true; - g_BlockTransparent[E_BLOCK_DANDELION] = true; - g_BlockTransparent[E_BLOCK_DETECTOR_RAIL] = true; - g_BlockTransparent[E_BLOCK_ENDER_CHEST] = true; - g_BlockTransparent[E_BLOCK_FENCE] = true; - g_BlockTransparent[E_BLOCK_FENCE_GATE] = true; - g_BlockTransparent[E_BLOCK_FIRE] = true; - g_BlockTransparent[E_BLOCK_FLOWER] = true; - g_BlockTransparent[E_BLOCK_FLOWER_POT] = true; - g_BlockTransparent[E_BLOCK_GLASS] = true; - g_BlockTransparent[E_BLOCK_GLASS_PANE] = true; - g_BlockTransparent[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockTransparent[E_BLOCK_ICE] = true; - g_BlockTransparent[E_BLOCK_IRON_DOOR] = true; - g_BlockTransparent[E_BLOCK_LAVA] = true; - g_BlockTransparent[E_BLOCK_LEAVES] = true; - g_BlockTransparent[E_BLOCK_LEVER] = true; - g_BlockTransparent[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockTransparent[E_BLOCK_MELON_STEM] = true; - g_BlockTransparent[E_BLOCK_NETHER_BRICK_FENCE] = true; - g_BlockTransparent[E_BLOCK_NEW_LEAVES] = true; - g_BlockTransparent[E_BLOCK_POTATOES] = true; - g_BlockTransparent[E_BLOCK_POWERED_RAIL] = true; - g_BlockTransparent[E_BLOCK_PISTON_EXTENSION] = true; - g_BlockTransparent[E_BLOCK_PUMPKIN_STEM] = true; - g_BlockTransparent[E_BLOCK_RAIL] = true; - g_BlockTransparent[E_BLOCK_RED_MUSHROOM] = true; - g_BlockTransparent[E_BLOCK_SIGN_POST] = true; - g_BlockTransparent[E_BLOCK_SNOW] = true; - g_BlockTransparent[E_BLOCK_STAINED_GLASS] = true; - g_BlockTransparent[E_BLOCK_STAINED_GLASS_PANE] = true; - g_BlockTransparent[E_BLOCK_STATIONARY_LAVA] = true; - g_BlockTransparent[E_BLOCK_STATIONARY_WATER] = true; - g_BlockTransparent[E_BLOCK_STONE_BUTTON] = true; - g_BlockTransparent[E_BLOCK_STONE_PRESSURE_PLATE] = true; - g_BlockTransparent[E_BLOCK_TALL_GRASS] = true; - g_BlockTransparent[E_BLOCK_TORCH] = true; - g_BlockTransparent[E_BLOCK_VINES] = true; - g_BlockTransparent[E_BLOCK_WALLSIGN] = true; - g_BlockTransparent[E_BLOCK_WATER] = true; - g_BlockTransparent[E_BLOCK_WOODEN_BUTTON] = true; - g_BlockTransparent[E_BLOCK_WOODEN_DOOR] = true; - g_BlockTransparent[E_BLOCK_WOODEN_PRESSURE_PLATE] = true; - - // TODO: Any other transparent blocks? - - // One hit break blocks: - g_BlockOneHitDig[E_BLOCK_ACTIVE_COMPARATOR] = true; - g_BlockOneHitDig[E_BLOCK_BIG_FLOWER] = true; - g_BlockOneHitDig[E_BLOCK_BROWN_MUSHROOM] = true; - g_BlockOneHitDig[E_BLOCK_CARROTS] = true; - g_BlockOneHitDig[E_BLOCK_CROPS] = true; - g_BlockOneHitDig[E_BLOCK_DANDELION] = true; - g_BlockOneHitDig[E_BLOCK_FIRE] = true; - g_BlockOneHitDig[E_BLOCK_FLOWER] = true; - g_BlockOneHitDig[E_BLOCK_FLOWER_POT] = true; - g_BlockOneHitDig[E_BLOCK_INACTIVE_COMPARATOR] = true; - g_BlockOneHitDig[E_BLOCK_MELON_STEM] = true; - g_BlockOneHitDig[E_BLOCK_POTATOES] = true; - g_BlockOneHitDig[E_BLOCK_PUMPKIN_STEM] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_OFF] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_REPEATER_ON] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_OFF] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_TORCH_ON] = true; - g_BlockOneHitDig[E_BLOCK_REDSTONE_WIRE] = true; - g_BlockOneHitDig[E_BLOCK_RED_MUSHROOM] = true; - g_BlockOneHitDig[E_BLOCK_REEDS] = true; - g_BlockOneHitDig[E_BLOCK_SAPLING] = true; - g_BlockOneHitDig[E_BLOCK_TNT] = true; - g_BlockOneHitDig[E_BLOCK_TALL_GRASS] = true; - g_BlockOneHitDig[E_BLOCK_TORCH] = true; - - // Blocks that break when pushed by piston: - g_BlockPistonBreakable[E_BLOCK_ACTIVE_COMPARATOR] = true; - g_BlockPistonBreakable[E_BLOCK_AIR] = true; - g_BlockPistonBreakable[E_BLOCK_BED] = true; - g_BlockPistonBreakable[E_BLOCK_BIG_FLOWER] = true; - g_BlockPistonBreakable[E_BLOCK_BROWN_MUSHROOM] = true; - g_BlockPistonBreakable[E_BLOCK_COBWEB] = true; - g_BlockPistonBreakable[E_BLOCK_CROPS] = true; - g_BlockPistonBreakable[E_BLOCK_DANDELION] = true; - g_BlockPistonBreakable[E_BLOCK_DEAD_BUSH] = true; - g_BlockPistonBreakable[E_BLOCK_FIRE] = true; - g_BlockPistonBreakable[E_BLOCK_FLOWER] = true; - g_BlockPistonBreakable[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockPistonBreakable[E_BLOCK_INACTIVE_COMPARATOR] = true; - g_BlockPistonBreakable[E_BLOCK_IRON_DOOR] = true; - g_BlockPistonBreakable[E_BLOCK_JACK_O_LANTERN] = true; - g_BlockPistonBreakable[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockPistonBreakable[E_BLOCK_LADDER] = true; - g_BlockPistonBreakable[E_BLOCK_LAVA] = true; - g_BlockPistonBreakable[E_BLOCK_LEVER] = true; - g_BlockPistonBreakable[E_BLOCK_MELON] = true; - g_BlockPistonBreakable[E_BLOCK_MELON_STEM] = true; - g_BlockPistonBreakable[E_BLOCK_PUMPKIN] = true; - g_BlockPistonBreakable[E_BLOCK_PUMPKIN_STEM] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_REPEATER_OFF] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_REPEATER_ON] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_OFF] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_TORCH_ON] = true; - g_BlockPistonBreakable[E_BLOCK_REDSTONE_WIRE] = true; - g_BlockPistonBreakable[E_BLOCK_RED_MUSHROOM] = true; - g_BlockPistonBreakable[E_BLOCK_REEDS] = true; - g_BlockPistonBreakable[E_BLOCK_SNOW] = true; - g_BlockPistonBreakable[E_BLOCK_STATIONARY_LAVA] = true; - g_BlockPistonBreakable[E_BLOCK_STATIONARY_WATER] = true; - g_BlockPistonBreakable[E_BLOCK_STONE_BUTTON] = true; - g_BlockPistonBreakable[E_BLOCK_STONE_PRESSURE_PLATE] = true; - g_BlockPistonBreakable[E_BLOCK_TALL_GRASS] = true; - g_BlockPistonBreakable[E_BLOCK_TORCH] = true; - g_BlockPistonBreakable[E_BLOCK_VINES] = true; - g_BlockPistonBreakable[E_BLOCK_WATER] = true; - g_BlockPistonBreakable[E_BLOCK_WOODEN_BUTTON] = true; - g_BlockPistonBreakable[E_BLOCK_WOODEN_DOOR] = true; - g_BlockPistonBreakable[E_BLOCK_WOODEN_PRESSURE_PLATE] = true; - - - // Blocks that cannot be snowed over: - g_BlockIsSnowable[E_BLOCK_ACTIVE_COMPARATOR] = false; - g_BlockIsSnowable[E_BLOCK_AIR] = false; - g_BlockIsSnowable[E_BLOCK_BIG_FLOWER] = false; - g_BlockIsSnowable[E_BLOCK_BROWN_MUSHROOM] = false; - g_BlockIsSnowable[E_BLOCK_CACTUS] = false; - g_BlockIsSnowable[E_BLOCK_CHEST] = false; - g_BlockIsSnowable[E_BLOCK_CROPS] = false; - g_BlockIsSnowable[E_BLOCK_DANDELION] = false; - g_BlockIsSnowable[E_BLOCK_FIRE] = false; - g_BlockIsSnowable[E_BLOCK_FLOWER] = false; - g_BlockIsSnowable[E_BLOCK_GLASS] = false; - g_BlockIsSnowable[E_BLOCK_ICE] = false; - g_BlockIsSnowable[E_BLOCK_INACTIVE_COMPARATOR] = false; - g_BlockIsSnowable[E_BLOCK_LAVA] = false; - g_BlockIsSnowable[E_BLOCK_LILY_PAD] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_OFF] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_REPEATER_ON] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_OFF] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_TORCH_ON] = false; - g_BlockIsSnowable[E_BLOCK_REDSTONE_WIRE] = false; - g_BlockIsSnowable[E_BLOCK_RED_MUSHROOM] = false; - g_BlockIsSnowable[E_BLOCK_REEDS] = false; - g_BlockIsSnowable[E_BLOCK_SAPLING] = false; - g_BlockIsSnowable[E_BLOCK_SIGN_POST] = false; - g_BlockIsSnowable[E_BLOCK_SNOW] = false; - g_BlockIsSnowable[E_BLOCK_STAINED_GLASS] = false; - g_BlockIsSnowable[E_BLOCK_STAINED_GLASS_PANE] = false; - g_BlockIsSnowable[E_BLOCK_STATIONARY_LAVA] = false; - g_BlockIsSnowable[E_BLOCK_STATIONARY_WATER] = false; - g_BlockIsSnowable[E_BLOCK_TALL_GRASS] = false; - g_BlockIsSnowable[E_BLOCK_TNT] = false; - g_BlockIsSnowable[E_BLOCK_TORCH] = false; - g_BlockIsSnowable[E_BLOCK_VINES] = false; - g_BlockIsSnowable[E_BLOCK_WALLSIGN] = false; - g_BlockIsSnowable[E_BLOCK_WATER] = false; - - - // Blocks that don't drop without a special tool: - g_BlockRequiresSpecialTool[E_BLOCK_BRICK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_CAULDRON] = true; - g_BlockRequiresSpecialTool[E_BLOCK_COAL_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_COBBLESTONE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_COBBLESTONE_STAIRS] = true; - g_BlockRequiresSpecialTool[E_BLOCK_COBWEB] = true; - g_BlockRequiresSpecialTool[E_BLOCK_DIAMOND_BLOCK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_DIAMOND_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_DOUBLE_STONE_SLAB] = true; - g_BlockRequiresSpecialTool[E_BLOCK_EMERALD_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_END_STONE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_GOLD_BLOCK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_GOLD_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_IRON_BLOCK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_IRON_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_LAPIS_BLOCK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_LAPIS_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_MOSSY_COBBLESTONE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_NETHERRACK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_NETHER_BRICK] = true; - g_BlockRequiresSpecialTool[E_BLOCK_NETHER_BRICK_STAIRS] = true; - g_BlockRequiresSpecialTool[E_BLOCK_OBSIDIAN] = true; - g_BlockRequiresSpecialTool[E_BLOCK_REDSTONE_ORE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_REDSTONE_ORE_GLOWING] = true; - g_BlockRequiresSpecialTool[E_BLOCK_SANDSTONE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_SANDSTONE_STAIRS] = true; - g_BlockRequiresSpecialTool[E_BLOCK_SNOW] = true; - g_BlockRequiresSpecialTool[E_BLOCK_STONE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_STONE_BRICKS] = true; - g_BlockRequiresSpecialTool[E_BLOCK_STONE_BRICK_STAIRS] = true; - g_BlockRequiresSpecialTool[E_BLOCK_STONE_PRESSURE_PLATE] = true; - g_BlockRequiresSpecialTool[E_BLOCK_STONE_SLAB] = true; - g_BlockRequiresSpecialTool[E_BLOCK_VINES] = true; - - // Nonsolid blocks: - g_BlockIsSolid[E_BLOCK_ACTIVATOR_RAIL] = false; - g_BlockIsSolid[E_BLOCK_AIR] = false; - g_BlockIsSolid[E_BLOCK_BIG_FLOWER] = false; - g_BlockIsSolid[E_BLOCK_BROWN_MUSHROOM] = false; - g_BlockIsSolid[E_BLOCK_CARROTS] = false; - g_BlockIsSolid[E_BLOCK_COBWEB] = false; - g_BlockIsSolid[E_BLOCK_CROPS] = false; - g_BlockIsSolid[E_BLOCK_DANDELION] = false; - g_BlockIsSolid[E_BLOCK_DETECTOR_RAIL] = false; - g_BlockIsSolid[E_BLOCK_END_PORTAL] = false; - g_BlockIsSolid[E_BLOCK_FIRE] = false; - g_BlockIsSolid[E_BLOCK_FLOWER] = false; - g_BlockIsSolid[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE] = false; - g_BlockIsSolid[E_BLOCK_LAVA] = false; - g_BlockIsSolid[E_BLOCK_LEVER] = false; - g_BlockIsSolid[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE] = false; - g_BlockIsSolid[E_BLOCK_MELON_STEM] = false; - g_BlockIsSolid[E_BLOCK_NETHER_PORTAL] = false; - g_BlockIsSolid[E_BLOCK_PISTON_EXTENSION] = false; - g_BlockIsSolid[E_BLOCK_POTATOES] = false; - g_BlockIsSolid[E_BLOCK_POWERED_RAIL] = false; - g_BlockIsSolid[E_BLOCK_RAIL] = false; - g_BlockIsSolid[E_BLOCK_REDSTONE_TORCH_OFF] = false; - g_BlockIsSolid[E_BLOCK_REDSTONE_TORCH_ON] = false; - g_BlockIsSolid[E_BLOCK_REDSTONE_WIRE] = false; - g_BlockIsSolid[E_BLOCK_RED_MUSHROOM] = false; - g_BlockIsSolid[E_BLOCK_REEDS] = false; - g_BlockIsSolid[E_BLOCK_SAPLING] = false; - g_BlockIsSolid[E_BLOCK_SIGN_POST] = false; - g_BlockIsSolid[E_BLOCK_SNOW] = false; - g_BlockIsSolid[E_BLOCK_STATIONARY_LAVA] = false; - g_BlockIsSolid[E_BLOCK_STATIONARY_WATER] = false; - g_BlockIsSolid[E_BLOCK_STONE_BUTTON] = false; - g_BlockIsSolid[E_BLOCK_STONE_PRESSURE_PLATE] = false; - g_BlockIsSolid[E_BLOCK_TALL_GRASS] = false; - g_BlockIsSolid[E_BLOCK_TORCH] = false; - g_BlockIsSolid[E_BLOCK_TRIPWIRE] = false; - g_BlockIsSolid[E_BLOCK_VINES] = false; - g_BlockIsSolid[E_BLOCK_WALLSIGN] = false; - g_BlockIsSolid[E_BLOCK_WATER] = false; - g_BlockIsSolid[E_BLOCK_WOODEN_BUTTON] = false; - g_BlockIsSolid[E_BLOCK_WOODEN_PRESSURE_PLATE] = false; - g_BlockIsSolid[E_BLOCK_WOODEN_SLAB] = false; - - // Torch placeable blocks: - g_BlockFullyOccupiesVoxel[E_BLOCK_NEW_LOG] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_BEDROCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_BLOCK_OF_COAL] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_BLOCK_OF_REDSTONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_BOOKCASE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_BRICK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_CLAY] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_COAL_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_COBBLESTONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_COMMAND_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_CRAFTING_TABLE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DIAMOND_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DIAMOND_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DIRT] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DISPENSER] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DOUBLE_STONE_SLAB] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DOUBLE_WOODEN_SLAB] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_DROPPER] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_EMERALD_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_EMERALD_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_END_STONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_FURNACE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_GLOWSTONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_GOLD_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_GOLD_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_GRASS] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_GRAVEL] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_HARDENED_CLAY] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_HAY_BALE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_HUGE_BROWN_MUSHROOM] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_HUGE_RED_MUSHROOM] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_IRON_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_IRON_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_JACK_O_LANTERN] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_JUKEBOX] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_LAPIS_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_LAPIS_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_LOG] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_MELON] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_MOSSY_COBBLESTONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_MYCELIUM] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_NETHERRACK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_NETHER_BRICK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_NETHER_QUARTZ_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_NOTE_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_OBSIDIAN] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_PACKED_ICE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_PLANKS] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_PUMPKIN] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_QUARTZ_BLOCK] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_LAMP_OFF] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_LAMP_ON] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_ORE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_REDSTONE_ORE_GLOWING] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_SANDSTONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_SAND] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_SILVERFISH_EGG] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_SPONGE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_STAINED_CLAY] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_WOOL] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_STONE] = true; - g_BlockFullyOccupiesVoxel[E_BLOCK_STONE_BRICKS] = true; - } -} BlockPropertiesInitializer; - - - - diff --git a/src/BlockID.h b/src/BlockID.h index 861bb8dae..1c454cd23 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -909,17 +909,3 @@ extern cItem GetIniItemSet(cIniFile & a_IniFile, const char * a_Section, const c -// Block properties: -extern NIBBLETYPE g_BlockLightValue[256]; -extern NIBBLETYPE g_BlockSpreadLightFalloff[256]; -extern bool g_BlockTransparent[256]; -extern bool g_BlockOneHitDig[256]; -extern bool g_BlockPistonBreakable[256]; -extern bool g_BlockIsSnowable[256]; -extern bool g_BlockRequiresSpecialTool[256]; -extern bool g_BlockIsSolid[256]; -extern bool g_BlockFullyOccupiesVoxel[256]; - - - - diff --git a/src/Defines.h b/src/Defines.h index 31d48860f..6d3d28c80 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -17,33 +17,6 @@ typedef std::vector cSlotNums; // tolua_begin -/// How much light do the blocks emit on their own? -extern unsigned char g_BlockLightValue[]; - -/// How much light do the block consume? -extern unsigned char g_BlockSpreadLightFalloff[]; - -/// Is a block completely transparent? (light doesn't get decreased(?)) -extern bool g_BlockTransparent[]; - -/// Is a block destroyed after a single hit? -extern bool g_BlockOneHitDig[]; - -/// Can a piston break this block? -extern bool g_BlockPistonBreakable[256]; - -/// Can this block hold snow atop? -extern bool g_BlockIsSnowable[256]; - -/// Does this block require a tool to drop? -extern bool g_BlockRequiresSpecialTool[256]; - -/// Is this block solid (player cannot walk through)? -extern bool g_BlockIsSolid[256]; - -/// Does this block fully occupy it's voxel - is it a 'full' block? -extern bool g_BlockFullyOccupiesVoxel[256]; - /// Experience Orb setup enum { -- cgit v1.2.3 From f40f2ad9283bd5aa587cd0943adc5f8c7a3b41c1 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 2 Mar 2014 12:59:09 +0200 Subject: APIDump: ID -> Type --- MCServer/Plugins/APIDump/APIDesc.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 695d1a853..ed9c32d32 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -297,16 +297,16 @@ g_APIDesc = ]], Functions = { - FullyOccupiesVoxel = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block fully occupies its voxel." }, - GetById = { Params = "ID", Return = "{{cBlockInfo}}", Notes = "Returns the {{cBlockInfo}} structure for the block with the specified ID." }, - GetLightValue = { Params = "ID", Return = "number", Notes = "Returns how much light the specified block emits on its own." }, - GetSpreadLightFalloff = { Params = "ID", Return = "number", Notes = "Returns how much light the specified block consumes." }, - IsOneHitDig = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block will be destroyed after a single hit." }, - IsPistonBreakable = { Params = "ID", Return = "bool", Notes = "Returns whether a piston can break the specified block." }, - IsSnowable = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block can hold snow atop." }, - IsSolid = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block is solid." }, - IsTransparent = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block is transparent." }, - RequiresSpecialTool = { Params = "ID", Return = "bool", Notes = "Returns whether the specified block requires a special tool to drop." }, + FullyOccupiesVoxel = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block fully occupies its voxel." }, + GetById = { Params = "Type", Return = "{{cBlockInfo}}", Notes = "Returns the {{cBlockInfo}} structure for the specified type." }, + GetLightValue = { Params = "Type", Return = "number", Notes = "Returns how much light the specified block emits on its own." }, + GetSpreadLightFalloff = { Params = "Type", Return = "number", Notes = "Returns how much light the specified block consumes." }, + IsOneHitDig = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block will be destroyed after a single hit." }, + IsPistonBreakable = { Params = "Type", Return = "bool", Notes = "Returns whether a piston can break the specified block." }, + IsSnowable = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block can hold snow atop." }, + IsSolid = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block is solid." }, + IsTransparent = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block is transparent." }, + RequiresSpecialTool = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block requires a special tool to drop." }, }, Variables = { -- cgit v1.2.3 From 8990410f18a03ca553cca0103cd167bac06443cc Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 2 Mar 2014 12:02:29 +0000 Subject: Reverted BlockVine --- src/Blocks/BlockVine.h | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 9e2105f67..b8213f29b 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -1,4 +1,3 @@ - #pragma once #include "BlockHandler.h" @@ -8,11 +7,11 @@ class cBlockVineHandler : - public cMetaRotater + public cBlockHandler { public: cBlockVineHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cBlockHandler(a_BlockType) { } @@ -169,6 +168,31 @@ public: a_World->SetBlock(X, Y - 1, Z, E_BLOCK_VINES, a_World->GetBlockMeta(X, Y, Z)); } } + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override + { + return ((a_Meta >> 1) | (a_Meta << 3)) & 0x0f; // Rotate bits to the right + } + + + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override + { + return ((a_Meta << 1) | (a_Meta >> 3)) & 0x0f; // Rotate bits to the left + } + + + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override + { + // Bits 2 and 4 stay, bits 1 and 3 swap + return ((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2)); + } + + + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override + { + // Bits 1 and 3 stay, bits 2 and 4 swap + return ((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2)); + } } ; -- cgit v1.2.3 From 10fdc51b0a9b571b118b257109014e1c29591698 Mon Sep 17 00:00:00 2001 From: tonibm19 Date: Sun, 2 Mar 2014 14:35:03 +0100 Subject: Creeper fixes - Fixed explosion time (1.5s, according to minecraftwiki) - Creeper explodes if right clicked with flint and steel --- src/Mobs/Creeper.cpp | 41 ++++++++++++++++++++++++++++++++--------- src/Mobs/Creeper.h | 3 ++- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index 40ee20e44..3471b4cf1 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -4,6 +4,7 @@ #include "Creeper.h" #include "../World.h" #include "../Entities/ProjectileEntity.h" +#include "../Entities/Player.h" @@ -13,6 +14,7 @@ cCreeper::cCreeper(void) : super("Creeper", mtCreeper, "mob.creeper.say", "mob.creeper.say", 0.6, 1.8), m_bIsBlowing(false), m_bIsCharged(false), + m_BurnedWithFlintAndSteel(false), m_ExplodingTimer(0) { } @@ -25,12 +27,25 @@ void cCreeper::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); - if (!ReachedFinalDestination()) + if (!ReachedFinalDestination() && !m_BurnedWithFlintAndSteel) { m_ExplodingTimer = 0; m_bIsBlowing = false; m_World->BroadcastEntityMetadata(*this); } + else + { + if (m_bIsBlowing) + { + m_ExplodingTimer += 1; + } + + if (m_ExplodingTimer == 30) + { + m_World->DoExplosionAt((m_bIsCharged ? 5 : 3), GetPosX(), GetPosY(), GetPosZ(), false, esMonster, this); + Destroy(); + } + } } @@ -80,22 +95,30 @@ void cCreeper::Attack(float a_Dt) { UNUSED(a_Dt); - m_ExplodingTimer += 1; - if (!m_bIsBlowing) { m_World->BroadcastSoundEffect("game.tnt.primed", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 1.f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); m_bIsBlowing = true; m_World->BroadcastEntityMetadata(*this); } - - if (m_ExplodingTimer == 20) - { - m_World->DoExplosionAt((m_bIsCharged ? 5 : 3), GetPosX(), GetPosY(), GetPosZ(), false, esMonster, this); - Destroy(); - } } + +void cCreeper::OnRightClicked(cPlayer & a_Player) +{ + if ((a_Player.GetEquippedItem().m_ItemType == E_ITEM_FLINT_AND_STEEL)) + { + if (!a_Player.IsGameModeCreative()) + { + a_Player.UseEquippedItem(); + } + m_World->BroadcastSoundEffect("game.tnt.primed", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 1.f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); + m_bIsBlowing = true; + m_World->BroadcastEntityMetadata(*this); + m_BurnedWithFlintAndSteel = true; + } +} + diff --git a/src/Mobs/Creeper.h b/src/Mobs/Creeper.h index 0f71e5ad2..9abca369b 100644 --- a/src/Mobs/Creeper.h +++ b/src/Mobs/Creeper.h @@ -21,13 +21,14 @@ public: virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Attack(float a_Dt) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void OnRightClicked(cPlayer & a_Player) override; bool IsBlowing(void) const {return m_bIsBlowing; } bool IsCharged(void) const {return m_bIsCharged; } private: - bool m_bIsBlowing, m_bIsCharged; + bool m_bIsBlowing, m_bIsCharged, m_BurnedWithFlintAndSteel; int m_ExplodingTimer; } ; -- cgit v1.2.3 From 0c87341631198386c765bc18848fbd93e66c1aab Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 2 Mar 2014 16:24:09 +0200 Subject: GetById => Get --- MCServer/Plugins/APIDump/APIDesc.lua | 20 ++++++++++---------- src/Bindings/DeprecatedBindings.cpp | 18 +++++++++--------- src/BlockInfo.cpp | 6 +++--- src/BlockInfo.h | 20 ++++++++++---------- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index ed9c32d32..0b6f33b37 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -297,16 +297,16 @@ g_APIDesc = ]], Functions = { - FullyOccupiesVoxel = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block fully occupies its voxel." }, - GetById = { Params = "Type", Return = "{{cBlockInfo}}", Notes = "Returns the {{cBlockInfo}} structure for the specified type." }, - GetLightValue = { Params = "Type", Return = "number", Notes = "Returns how much light the specified block emits on its own." }, - GetSpreadLightFalloff = { Params = "Type", Return = "number", Notes = "Returns how much light the specified block consumes." }, - IsOneHitDig = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block will be destroyed after a single hit." }, - IsPistonBreakable = { Params = "Type", Return = "bool", Notes = "Returns whether a piston can break the specified block." }, - IsSnowable = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block can hold snow atop." }, - IsSolid = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block is solid." }, - IsTransparent = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block is transparent." }, - RequiresSpecialTool = { Params = "Type", Return = "bool", Notes = "Returns whether the specified block requires a special tool to drop." }, + FullyOccupiesVoxel = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block fully occupies its voxel." }, + Get = { Params = "Type", Return = "{{cBlockInfo}}", Notes = "(STATIC) Returns the {{cBlockInfo}} structure for the specified type." }, + GetLightValue = { Params = "Type", Return = "number", Notes = "(STATIC) Returns how much light the specified block emits on its own." }, + GetSpreadLightFalloff = { Params = "Type", Return = "number", Notes = "(STATIC) Returns how much light the specified block consumes." }, + IsOneHitDig = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block will be destroyed after a single hit." }, + IsPistonBreakable = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether a piston can break the specified block." }, + IsSnowable = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block can hold snow atop." }, + IsSolid = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block is solid." }, + IsTransparent = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block is transparent." }, + RequiresSpecialTool = { Params = "Type", Return = "bool", Notes = "(STATIC) Returns whether the specified block requires a special tool to drop." }, }, Variables = { diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 3e4940494..7c0d8dca1 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -55,7 +55,7 @@ static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) if (tolua_index<0) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::GetById(tolua_index).m_LightValue = ((unsigned char) tolua_tonumber(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_LightValue = ((unsigned char) tolua_tonumber(tolua_S,3,0)); return 0; } #endif //#ifndef TOLUA_DISABLE @@ -99,7 +99,7 @@ static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) if (tolua_index<0) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::GetById(tolua_index).m_SpreadLightFalloff = ((unsigned char) tolua_tonumber(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_SpreadLightFalloff = ((unsigned char) tolua_tonumber(tolua_S,3,0)); return 0; } #endif //#ifndef TOLUA_DISABLE @@ -143,7 +143,7 @@ static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) if (tolua_index<0) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::GetById(tolua_index).m_Transparent = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_Transparent = ((bool) tolua_toboolean(tolua_S,3,0)); return 0; } #endif //#ifndef TOLUA_DISABLE @@ -187,7 +187,7 @@ static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) if (tolua_index<0) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::GetById(tolua_index).m_OneHitDig = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_OneHitDig = ((bool) tolua_toboolean(tolua_S,3,0)); return 0; } #endif //#ifndef TOLUA_DISABLE @@ -231,7 +231,7 @@ static int tolua_set_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) if (tolua_index<0 || tolua_index>=256) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::GetById(tolua_index).m_PistonBreakable = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_PistonBreakable = ((bool) tolua_toboolean(tolua_S,3,0)); return 0; } #endif //#ifndef TOLUA_DISABLE @@ -275,7 +275,7 @@ static int tolua_set_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) if (tolua_index<0 || tolua_index>=256) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::GetById(tolua_index).m_IsSnowable = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_IsSnowable = ((bool) tolua_toboolean(tolua_S,3,0)); return 0; } #endif //#ifndef TOLUA_DISABLE @@ -319,7 +319,7 @@ static int tolua_set_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) if (tolua_index<0 || tolua_index>=256) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::GetById(tolua_index).m_RequiresSpecialTool = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_RequiresSpecialTool = ((bool) tolua_toboolean(tolua_S,3,0)); return 0; } #endif //#ifndef TOLUA_DISABLE @@ -363,7 +363,7 @@ static int tolua_set_AllToLua_g_BlockIsSolid(lua_State* tolua_S) if (tolua_index<0 || tolua_index>=256) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::GetById(tolua_index).m_IsSolid = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_IsSolid = ((bool) tolua_toboolean(tolua_S,3,0)); return 0; } #endif //#ifndef TOLUA_DISABLE @@ -407,7 +407,7 @@ static int tolua_set_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) if (tolua_index<0 || tolua_index>=256) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::GetById(tolua_index).m_FullyOccupiesVoxel = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_FullyOccupiesVoxel = ((bool) tolua_toboolean(tolua_S,3,0)); return 0; } #endif //#ifndef TOLUA_DISABLE diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 5fd6d33c1..c73ae18b6 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -29,11 +29,11 @@ cBlockInfo::cBlockInfo() -cBlockInfo & cBlockInfo::GetById(unsigned int a_ID) +cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type) { - ASSERT(a_ID < 256); + ASSERT(a_Type < 256); - return ms_Info[a_ID]; + return ms_Info[a_Type]; } diff --git a/src/BlockInfo.h b/src/BlockInfo.h index 57092ca54..34a845b20 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -19,7 +19,7 @@ public: // tolua_begin /** Returns the associated BlockInfo structure. */ - static cBlockInfo & GetById(unsigned int a_ID); + static cBlockInfo & Get(BLOCKTYPE a_Type); /** How much light do the blocks emit on their own? */ @@ -50,15 +50,15 @@ public: bool m_FullyOccupiesVoxel; - inline static NIBBLETYPE GetLightValue (unsigned int a_ID) { return GetById(a_ID).m_LightValue; } - inline static NIBBLETYPE GetSpreadLightFalloff(unsigned int a_ID) { return GetById(a_ID).m_SpreadLightFalloff; } - inline static bool IsTransparent (unsigned int a_ID) { return GetById(a_ID).m_Transparent; } - inline static bool IsOneHitDig (unsigned int a_ID) { return GetById(a_ID).m_OneHitDig; } - inline static bool IsPistonBreakable (unsigned int a_ID) { return GetById(a_ID).m_PistonBreakable; } - inline static bool IsSnowable (unsigned int a_ID) { return GetById(a_ID).m_IsSnowable; } - inline static bool RequiresSpecialTool (unsigned int a_ID) { return GetById(a_ID).m_RequiresSpecialTool; } - inline static bool IsSolid (unsigned int a_ID) { return GetById(a_ID).m_IsSolid; } - inline static bool FullyOccupiesVoxel (unsigned int a_ID) { return GetById(a_ID).m_FullyOccupiesVoxel; } + inline static NIBBLETYPE GetLightValue (BLOCKTYPE a_Type) { return Get(a_Type).m_LightValue; } + inline static NIBBLETYPE GetSpreadLightFalloff(BLOCKTYPE a_Type) { return Get(a_Type).m_SpreadLightFalloff; } + inline static bool IsTransparent (BLOCKTYPE a_Type) { return Get(a_Type).m_Transparent; } + inline static bool IsOneHitDig (BLOCKTYPE a_Type) { return Get(a_Type).m_OneHitDig; } + inline static bool IsPistonBreakable (BLOCKTYPE a_Type) { return Get(a_Type).m_PistonBreakable; } + inline static bool IsSnowable (BLOCKTYPE a_Type) { return Get(a_Type).m_IsSnowable; } + inline static bool RequiresSpecialTool (BLOCKTYPE a_Type) { return Get(a_Type).m_RequiresSpecialTool; } + inline static bool IsSolid (BLOCKTYPE a_Type) { return Get(a_Type).m_IsSolid; } + inline static bool FullyOccupiesVoxel (BLOCKTYPE a_Type) { return Get(a_Type).m_FullyOccupiesVoxel; } // tolua_end -- cgit v1.2.3 From 274d2bcb17791c292a2095af649b1a4c51246d23 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 2 Mar 2014 16:05:39 +0100 Subject: Added blockface mirroring and rotating. --- src/Defines.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/Defines.h b/src/Defines.h index 6d3d28c80..018ecb1d3 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -226,6 +226,56 @@ inline const char * ClickActionToString(eClickAction a_ClickAction) +/** Returns a blockface mirrored around the Y axis (doesn't change up/down). */ +inline eBlockFace MirrorBlockFaceY(eBlockFace a_BlockFace) +{ + switch (a_BlockFace) + { + case BLOCK_FACE_XM: return BLOCK_FACE_XP; + case BLOCK_FACE_XP: return BLOCK_FACE_XM; + case BLOCK_FACE_ZM: return BLOCK_FACE_ZP; + case BLOCK_FACE_ZP: return BLOCK_FACE_ZM; + } + return a_BlockFace; +} + + + + + +/** Returns a blockface rotated around the Y axis counter-clockwise. */ +inline eBlockFace RotateBlockFaceCCW(eBlockFace a_BlockFace) +{ + switch (a_BlockFace) + { + case BLOCK_FACE_XM: return BLOCK_FACE_ZP; + case BLOCK_FACE_XP: return BLOCK_FACE_ZM; + case BLOCK_FACE_ZM: return BLOCK_FACE_XM; + case BLOCK_FACE_ZP: return BLOCK_FACE_XP; + } + return a_BlockFace; +} + + + + + +inline eBlockFace RotateBlockFaceCW(eBlockFace a_BlockFace) +{ + switch (a_BlockFace) + { + case BLOCK_FACE_XM: return BLOCK_FACE_ZM; + case BLOCK_FACE_XP: return BLOCK_FACE_ZP; + case BLOCK_FACE_ZM: return BLOCK_FACE_XP; + case BLOCK_FACE_ZP: return BLOCK_FACE_XM; + } + return a_BlockFace; +} + + + + + inline bool IsValidBlock(int a_BlockType) { if ( -- cgit v1.2.3 From 7fb354e8f09d16832b1261a5dc9b43d6a8d2fd0e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 2 Mar 2014 16:34:16 +0100 Subject: Fixed MSVC warnings in DeprecatedBindings. --- src/Bindings/DeprecatedBindings.cpp | 84 +++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 7c0d8dca1..408b1b84a 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -38,6 +38,10 @@ static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE + + + + /* set function: g_BlockLightValue */ #ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockLightValue static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) @@ -60,6 +64,10 @@ static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE + + + + /* get function: g_BlockSpreadLightFalloff */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockSpreadLightFalloff static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) @@ -82,6 +90,10 @@ static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE + + + + /* set function: g_BlockSpreadLightFalloff */ #ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockSpreadLightFalloff static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) @@ -104,6 +116,10 @@ static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE + + + + /* get function: g_BlockTransparent */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockTransparent static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) @@ -121,11 +137,15 @@ static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) if (tolua_index<0) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsTransparent(tolua_index)); + tolua_pushboolean(tolua_S, cBlockInfo::IsTransparent(tolua_index)); return 1; } #endif //#ifndef TOLUA_DISABLE + + + + /* set function: g_BlockTransparent */ #ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockTransparent static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) @@ -143,11 +163,15 @@ static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) if (tolua_index<0) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::Get(tolua_index).m_Transparent = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_Transparent = (tolua_toboolean(tolua_S,3,0) != 0); return 0; } #endif //#ifndef TOLUA_DISABLE + + + + /* get function: g_BlockOneHitDig */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockOneHitDig static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) @@ -170,6 +194,10 @@ static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE + + + + /* set function: g_BlockOneHitDig */ #ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockOneHitDig static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) @@ -187,11 +215,15 @@ static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) if (tolua_index<0) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::Get(tolua_index).m_OneHitDig = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_OneHitDig = (tolua_toboolean(tolua_S,3,0) != 0); return 0; } #endif //#ifndef TOLUA_DISABLE + + + + /* get function: g_BlockPistonBreakable */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockPistonBreakable static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) @@ -214,6 +246,10 @@ static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE + + + + /* set function: g_BlockPistonBreakable */ #ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockPistonBreakable static int tolua_set_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) @@ -231,11 +267,15 @@ static int tolua_set_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) if (tolua_index<0 || tolua_index>=256) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::Get(tolua_index).m_PistonBreakable = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_PistonBreakable = (tolua_toboolean(tolua_S,3,0) != 0); return 0; } #endif //#ifndef TOLUA_DISABLE + + + + /* get function: g_BlockIsSnowable */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockIsSnowable static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) @@ -258,6 +298,10 @@ static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE + + + + /* set function: g_BlockIsSnowable */ #ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockIsSnowable static int tolua_set_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) @@ -275,11 +319,15 @@ static int tolua_set_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) if (tolua_index<0 || tolua_index>=256) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::Get(tolua_index).m_IsSnowable = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_IsSnowable = (tolua_toboolean(tolua_S,3,0) != 0); return 0; } #endif //#ifndef TOLUA_DISABLE + + + + /* get function: g_BlockRequiresSpecialTool */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockRequiresSpecialTool static int tolua_get_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) @@ -302,6 +350,10 @@ static int tolua_get_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE + + + + /* set function: g_BlockRequiresSpecialTool */ #ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockRequiresSpecialTool static int tolua_set_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) @@ -319,11 +371,15 @@ static int tolua_set_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) if (tolua_index<0 || tolua_index>=256) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::Get(tolua_index).m_RequiresSpecialTool = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_RequiresSpecialTool = (tolua_toboolean(tolua_S,3,0) != 0); return 0; } #endif //#ifndef TOLUA_DISABLE + + + + /* get function: g_BlockIsSolid */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockIsSolid static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) @@ -346,6 +402,10 @@ static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE + + + + /* set function: g_BlockIsSolid */ #ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockIsSolid static int tolua_set_AllToLua_g_BlockIsSolid(lua_State* tolua_S) @@ -363,11 +423,15 @@ static int tolua_set_AllToLua_g_BlockIsSolid(lua_State* tolua_S) if (tolua_index<0 || tolua_index>=256) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::Get(tolua_index).m_IsSolid = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_IsSolid = (tolua_toboolean(tolua_S,3,0) != 0); return 0; } #endif //#ifndef TOLUA_DISABLE + + + + /* get function: g_BlockFullyOccupiesVoxel */ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockFullyOccupiesVoxel static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) @@ -390,6 +454,10 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE + + + + /* set function: g_BlockFullyOccupiesVoxel */ #ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockFullyOccupiesVoxel static int tolua_set_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) @@ -407,7 +475,7 @@ static int tolua_set_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) if (tolua_index<0 || tolua_index>=256) tolua_error(tolua_S,"array indexing out of range.",NULL); #endif - cBlockInfo::Get(tolua_index).m_FullyOccupiesVoxel = ((bool) tolua_toboolean(tolua_S,3,0)); + cBlockInfo::Get(tolua_index).m_FullyOccupiesVoxel = (tolua_toboolean(tolua_S,3,0) != 0); return 0; } #endif //#ifndef TOLUA_DISABLE -- cgit v1.2.3 From 0c8d08cb0962640bb3688f80ff782245daa2747c Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 2 Mar 2014 16:48:55 +0100 Subject: Simplified and more clearer infodump for Github. --- MCServer/Plugins/InfoDump.lua | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua index e7ed157e3..ede4c0e8b 100644 --- a/MCServer/Plugins/InfoDump.lua +++ b/MCServer/Plugins/InfoDump.lua @@ -317,26 +317,19 @@ local function WriteCommandsCategoryGithub(a_Category, f) if (CategoryName == "") then CategoryName = "General"; end - f:write("\n## ", GithubizeString(a_Category.DisplayName or CategoryName), "\n"); + f:write("\n### ", GithubizeString(a_Category.DisplayName or CategoryName), "\n"); -- Write description: if (a_Category.Description ~= "") then - f:write(GithubizeString(a_Category.Description), "\n"); + f:write(GithubizeString(a_Category.Description), "\n\n"); end + f:write("| Command | Permission | Discription | \n") + f:write("| ------- | ---------- | ----------- | \n") + -- Write commands: - f:write("\n"); for idx2, cmd in ipairs(a_Category.Commands) do - f:write("\n### ", cmd.CommandString, "\n", GithubizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "\n\n"); - if (cmd.Info.Permission ~= nil) then - f:write("Permission required: **", cmd.Info.Permission, "**\n\n"); - end - if (cmd.Info.DetailedDescription ~= nil) then - f:write(GithubizeString(cmd.Info.DetailedDescription)); - end - if (cmd.Info.ParameterCombinations ~= nil) then - WriteCommandParameterCombinationsGithub(cmd.CommandString, cmd.Info.ParameterCombinations, f); - end + f:write("|", cmd.CommandString, " | ", cmd.Info.Permission or "", " | ", GithubizeString(cmd.Info.HelpString or "UNDOCUMENTED"), "| \n") end f:write("\n\n") end @@ -601,7 +594,7 @@ local function DumpPluginInfoGithub(a_PluginFolder, a_PluginInfo) f:write(GithubizeString(a_PluginInfo.Description), "\n"); DumpAdditionalInfoGithub(a_PluginInfo, f); DumpCommandsGithub(a_PluginInfo, f); - DumpPermissionsGithub(a_PluginInfo, f); + --DumpPermissionsGithub(a_PluginInfo, f); -- Seems a little overkill since they are already mentioned in the commands. f:close(); end -- cgit v1.2.3 From 20e377ea7b64f60bd5565b8c97ce26750e0eeb5e Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 2 Mar 2014 16:55:04 +0100 Subject: Fixed typo Discription => Description --- MCServer/Plugins/InfoDump.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua index ede4c0e8b..59263d056 100644 --- a/MCServer/Plugins/InfoDump.lua +++ b/MCServer/Plugins/InfoDump.lua @@ -324,7 +324,7 @@ local function WriteCommandsCategoryGithub(a_Category, f) f:write(GithubizeString(a_Category.Description), "\n\n"); end - f:write("| Command | Permission | Discription | \n") + f:write("| Command | Permission | Description | \n") f:write("| ------- | ---------- | ----------- | \n") -- Write commands: -- cgit v1.2.3 From 070d483236279e69c736e740fa8459d3ac627790 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 2 Mar 2014 21:25:05 +0200 Subject: cBlockInfo now manages the respective cBlockHandler --- src/BlockInfo.cpp | 22 +++++++++++++++++++++ src/BlockInfo.h | 27 ++++++++++++++++++++++++++ src/Blocks/BlockHandler.cpp | 45 ++----------------------------------------- src/Blocks/BlockHandler.h | 22 +++------------------ src/Blocks/ChunkInterface.cpp | 2 +- src/ClientHandle.cpp | 6 +++--- src/Items/ItemHandler.cpp | 2 +- src/Mobs/Villager.cpp | 2 +- src/Root.cpp | 1 - src/Scoreboard.cpp | 12 +++++++++--- src/World.cpp | 2 +- 11 files changed, 70 insertions(+), 73 deletions(-) diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index c73ae18b6..195af49c7 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -2,6 +2,7 @@ #include "Globals.h" #include "BlockInfo.h" +#include "Blocks/BlockHandler.h" @@ -23,12 +24,25 @@ cBlockInfo::cBlockInfo() , m_RequiresSpecialTool(false) , m_IsSolid(true) , m_FullyOccupiesVoxel(false) + , m_Handler(NULL) {} +cBlockInfo::~cBlockInfo() +{ + if (m_Handler != NULL) + { + delete m_Handler; + } +} + + + + + cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type) { ASSERT(a_Type < 256); @@ -42,6 +56,14 @@ cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type) void cBlockInfo::Initialize(void) { + for (unsigned int i = 0; i < 256; ++i) + { + if (ms_Info[i].m_Handler == NULL) + { + ms_Info[i].m_Handler = cBlockHandler::CreateBlockHandler((BLOCKTYPE) i); + } + } + // Emissive blocks ms_Info[E_BLOCK_FIRE ].m_LightValue = 15; ms_Info[E_BLOCK_GLOWSTONE ].m_LightValue = 15; diff --git a/src/BlockInfo.h b/src/BlockInfo.h index 34a845b20..40c1db867 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -5,6 +5,13 @@ +// fwd: +class cBlockHandler; + + + + + // tolua_begin class cBlockInfo { @@ -13,6 +20,8 @@ public: cBlockInfo(); + ~cBlockInfo(); + /** (Re-)Initializes the internal BlockInfo structures. */ static void Initialize(void); @@ -49,6 +58,12 @@ public: /** Does this block fully occupy its voxel - is it a 'full' block? */ bool m_FullyOccupiesVoxel; + // tolua_end + + /** Associated block handler. */ + cBlockHandler * m_Handler; + + // tolua_begin inline static NIBBLETYPE GetLightValue (BLOCKTYPE a_Type) { return Get(a_Type).m_LightValue; } inline static NIBBLETYPE GetSpreadLightFalloff(BLOCKTYPE a_Type) { return Get(a_Type).m_SpreadLightFalloff; } @@ -62,6 +77,8 @@ public: // tolua_end + inline static cBlockHandler * GetHandler (BLOCKTYPE a_Type) { return Get(a_Type).m_Handler; } + protected: @@ -74,3 +91,13 @@ protected: + +// Shortcut to get the blockhandler for a specific block +inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType) +{ + return cBlockInfo::Get(a_BlockType).m_Handler; +} + + + + diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 834727c9a..052f88f7a 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -77,33 +77,6 @@ -bool cBlockHandler::m_HandlerInitialized = false; -cBlockHandler * cBlockHandler::m_BlockHandler[256]; - - - - - -cBlockHandler * cBlockHandler::GetBlockHandler(BLOCKTYPE a_BlockType) -{ - if (!m_HandlerInitialized) - { - // We have to initialize - memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); - m_HandlerInitialized = true; - } - if (m_BlockHandler[a_BlockType] != NULL) - { - return m_BlockHandler[a_BlockType]; - } - - return m_BlockHandler[a_BlockType] = CreateBlockHandler(a_BlockType); -} - - - - - cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) { switch(a_BlockType) @@ -192,7 +165,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_REDSTONE_REPEATER_ON: return new cBlockRedstoneRepeaterHandler(a_BlockType); case E_BLOCK_REDSTONE_TORCH_OFF: return new cBlockRedstoneTorchHandler (a_BlockType); case E_BLOCK_REDSTONE_TORCH_ON: return new cBlockRedstoneTorchHandler (a_BlockType); - case E_BLOCK_REDSTONE_WIRE: return new cBlockRedstoneHandler (a_BlockType); + case E_BLOCK_REDSTONE_WIRE: return new cBlockRedstoneHandler (a_BlockType); case E_BLOCK_RED_MUSHROOM: return new cBlockMushroomHandler (a_BlockType); case E_BLOCK_RED_ROSE: return new cBlockFlowerHandler (a_BlockType); case E_BLOCK_SAND: return new cBlockSandHandler (a_BlockType); @@ -231,20 +204,6 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) -void cBlockHandler::Deinit() -{ - for (int i = 0; i < 256; i++) - { - delete m_BlockHandler[i]; - } - memset(m_BlockHandler, 0, sizeof(m_BlockHandler)); // Don't leave any dangling pointers around, just in case - m_HandlerInitialized = false; -} - - - - - cBlockHandler::cBlockHandler(BLOCKTYPE a_BlockType) { m_BlockType = a_BlockType; @@ -329,7 +288,7 @@ void cBlockHandler::NeighborChanged(cChunkInterface & a_ChunkInterface, int a_Bl { if ((a_BlockY >= 0) && (a_BlockY < cChunkDef::Height)) { - GetBlockHandler(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + cBlockInfo::GetHandler(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnNeighborChanged(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); } } diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index a2913d7f8..c46a46045 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -136,30 +136,14 @@ public: /// Block meta following mirroring virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; } - /// Get the blockhandler for a specific block id - static cBlockHandler * GetBlockHandler(BLOCKTYPE a_BlockType); - - /// Deletes all initialised block handlers - static void Deinit(); - protected: BLOCKTYPE m_BlockType; // Creates a new blockhandler for the given block type. For internal use only, use ::GetBlockHandler() instead. - static cBlockHandler *CreateBlockHandler(BLOCKTYPE a_BlockType); - static cBlockHandler *m_BlockHandler[256]; - static bool m_HandlerInitialized; //used to detect if the blockhandlers are initialized -}; - - + static cBlockHandler * CreateBlockHandler(BLOCKTYPE a_BlockType); - - -// Shortcut to get the blockhandler for a specific block -inline cBlockHandler * BlockHandler(BLOCKTYPE a_BlockType) -{ - return cBlockHandler::GetBlockHandler(a_BlockType); -} + friend class cBlockInfo; +}; diff --git a/src/Blocks/ChunkInterface.cpp b/src/Blocks/ChunkInterface.cpp index b2dda19f4..540581ae7 100644 --- a/src/Blocks/ChunkInterface.cpp +++ b/src/Blocks/ChunkInterface.cpp @@ -6,7 +6,7 @@ bool cChunkInterface::DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z) { - cBlockHandler *Handler = cBlockHandler::GetBlockHandler(GetBlock(a_X, a_Y, a_Z)); + cBlockHandler * Handler = cBlockInfo::GetHandler(GetBlock(a_X, a_Y, a_Z)); Handler->OnDestroyed(*this, a_WorldInterface, a_X, a_Y, a_Z); return m_ChunkMap->DigBlock(a_X, a_Y, a_Z); } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 07a8984c5..6982a6227 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -838,7 +838,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc cWorld * World = m_Player->GetWorld(); cChunkInterface ChunkInterface(World->GetChunkMap()); - cBlockHandler * Handler = cBlockHandler::GetBlockHandler(a_OldBlock); + cBlockHandler * Handler = cBlockInfo::GetHandler(a_OldBlock); Handler->OnDigging(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ); cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); @@ -852,7 +852,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc int pZ = a_BlockZ; AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false) - Handler = cBlockHandler::GetBlockHandler(World->GetBlock(pX, pY, pZ)); + Handler = cBlockInfo::GetHandler(World->GetBlock(pX, pY, pZ)); if (Handler->IsClickedThrough()) { @@ -963,7 +963,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); - cBlockHandler * BlockHandler = cBlockHandler::GetBlockHandler(BlockType); + cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); if (BlockHandler->IsUseable() && !m_Player->IsCrouched()) { diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 507f7fa86..1d357fcf1 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -285,7 +285,7 @@ void cItemHandler::OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, const UNUSED(a_Item); BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - cBlockHandler * Handler = cBlockHandler::GetBlockHandler(Block); + cBlockHandler * Handler = cBlockInfo::GetHandler(Block); if (a_Player->IsGameModeSurvival()) { diff --git a/src/Mobs/Villager.cpp b/src/Mobs/Villager.cpp index 09a6e2d09..bbd8d6aaa 100644 --- a/src/Mobs/Villager.cpp +++ b/src/Mobs/Villager.cpp @@ -150,7 +150,7 @@ void cVillager::HandleFarmerTryHarvestCrops() BLOCKTYPE CropBlock = m_World->GetBlock(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); if (IsBlockFarmable(CropBlock) && m_World->GetBlockMeta(m_CropsPos.x, m_CropsPos.y, m_CropsPos.z) == 0x7) { - cBlockHandler * Handler = cBlockHandler::GetBlockHandler(CropBlock); + cBlockHandler * Handler = cBlockInfo::GetHandler(CropBlock); cChunkInterface ChunkInterface(m_World->GetChunkMap()); cBlockInServerPluginInterface PluginInterface(*m_World); Handler->DropBlock(ChunkInterface, *m_World, PluginInterface, this, m_CropsPos.x, m_CropsPos.y, m_CropsPos.z); diff --git a/src/Root.cpp b/src/Root.cpp index af2cb9e4b..78c94888d 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -245,7 +245,6 @@ void cRoot::Start(void) delete m_PluginManager; m_PluginManager = NULL; cItemHandler::Deinit(); - cBlockHandler::Deinit(); LOG("Cleaning up..."); delete m_Server; m_Server = NULL; diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index 05fd0314d..c1da27086 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -312,12 +312,18 @@ bool cScoreboard::RemoveObjective(const AString & a_Name) return false; } - m_Objectives.erase(it); - ASSERT(m_World != NULL); m_World->BroadcastScoreboardObjective(it->second.GetName(), it->second.GetDisplayName(), 1); - // TODO 2014-03-01 xdot: Remove objective from display slot + for (unsigned int i = 0; i < (unsigned int) dsCount; ++i) + { + if (m_Display[i] == &it->second) + { + SetDisplay(NULL, (eDisplaySlot) i); + } + } + + m_Objectives.erase(it); return true; } diff --git a/src/World.cpp b/src/World.cpp index ffdae2a37..2dfa85d64 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1723,7 +1723,7 @@ bool cWorld::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) bool cWorld::DigBlock(int a_X, int a_Y, int a_Z) { - cBlockHandler *Handler = cBlockHandler::GetBlockHandler(GetBlock(a_X, a_Y, a_Z)); + cBlockHandler * Handler = cBlockInfo::GetHandler(GetBlock(a_X, a_Y, a_Z)); cChunkInterface ChunkInterface(GetChunkMap()); Handler->OnDestroyed(ChunkInterface, *this, a_X, a_Y, a_Z); return m_ChunkMap->DigBlock(a_X, a_Y, a_Z); -- cgit v1.2.3 From 6536233f4d0bb9411895ce78d1c57e37a7aac044 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 2 Mar 2014 12:29:20 -0800 Subject: Reformated MetaRotater --- src/Blocks/MetaRotater.h | 49 +++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/Blocks/MetaRotater.h b/src/Blocks/MetaRotater.h index b83ed177a..5493c87e2 100644 --- a/src/Blocks/MetaRotater.h +++ b/src/Blocks/MetaRotater.h @@ -1,7 +1,18 @@ +// MetaRotater.h + +// Provides a mixin for rotations and reflections + #pragma once -template +/* +Provides a mixin for rotations and reflections following the standard pattern of apply mask then use case. + +Usage: +Inherit from this class providing your base class as Base, the BitMask for the direction bits in bitmask and the masked value for the directions in North, East, South, West. There is also an aptional parameter AssertIfNotMatched. Set this if it is invalid for a block to exist in any other state. +*/ + +template class cMetaRotater : public Base { public: @@ -19,18 +30,18 @@ public: }; -template -NIBBLETYPE cMetaRotater::MetaRotateCW(NIBBLETYPE a_Meta) +template +NIBBLETYPE cMetaRotater::MetaRotateCW(NIBBLETYPE a_Meta) { - NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); - switch (a_Meta & BitFilter) + NIBBLETYPE OtherMeta = a_Meta & (~BitMask); + switch (a_Meta & BitMask) { case South: return West | OtherMeta; case West: return North | OtherMeta; case North: return East | OtherMeta; case East: return South | OtherMeta; } - if(AssertIfNotMatched) + if (AssertIfNotMatched) { ASSERT(!"Invalid Meta value"); return a_Meta; @@ -38,18 +49,18 @@ NIBBLETYPE cMetaRotater -NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) +template +NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) { - NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); - switch (a_Meta & BitFilter) + NIBBLETYPE OtherMeta = a_Meta & (~BitMask); + switch (a_Meta & BitMask) { case South: return East | OtherMeta; case East: return North | OtherMeta; case North: return West | OtherMeta; case West: return South | OtherMeta; } - if(AssertIfNotMatched) + if (AssertIfNotMatched) { ASSERT(!"Invalid Meta value"); return a_Meta; @@ -58,11 +69,11 @@ NIBBLETYPE cMetaRotater -NIBBLETYPE cMetaRotater::MetaMirrorXY(NIBBLETYPE a_Meta) +template +NIBBLETYPE cMetaRotater::MetaMirrorXY(NIBBLETYPE a_Meta) { - NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); - switch (a_Meta & BitFilter) + NIBBLETYPE OtherMeta = a_Meta & (~BitMask); + switch (a_Meta & BitMask) { case South: return North | OtherMeta; case North: return South | OtherMeta; @@ -74,11 +85,11 @@ NIBBLETYPE cMetaRotater -NIBBLETYPE cMetaRotater::MetaMirrorYZ(NIBBLETYPE a_Meta) +template +NIBBLETYPE cMetaRotater::MetaMirrorYZ(NIBBLETYPE a_Meta) { - NIBBLETYPE OtherMeta = a_Meta & (~BitFilter); - switch (a_Meta & BitFilter) + NIBBLETYPE OtherMeta = a_Meta & (~BitMask); + switch (a_Meta & BitMask) { case West: return East | OtherMeta; case East: return West | OtherMeta; -- cgit v1.2.3 From a38be148ba980e7d54bf72c9056502850d81c77a Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 2 Mar 2014 12:33:08 -0800 Subject: Reformatted --- src/Blocks/BlockBed.h | 4 ++-- src/Blocks/BlockButton.h | 4 ++-- src/Blocks/BlockChest.h | 4 ++-- src/Blocks/BlockComparator.h | 4 ++-- src/Blocks/BlockDoor.h | 4 ++-- src/Blocks/BlockDropSpenser.h | 4 ++-- src/Blocks/BlockEnderchest.h | 4 ++-- src/Blocks/BlockFenceGate.h | 4 ++-- src/Blocks/BlockStairs.h | 4 ++-- src/Blocks/BlockTorch.h | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index d8a796735..6daa94730 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -12,11 +12,11 @@ class cBlockBedHandler : - public cMetaRotater + public cMetaRotater { public: cBlockBedHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index 4daa03005..e4923c441 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -8,11 +8,11 @@ class cBlockButtonHandler : - public cMetaRotater + public cMetaRotater { public: cBlockButtonHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 1646454a7..30588d8fc 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -11,11 +11,11 @@ class cBlockChestHandler : - public cMetaRotater + public cMetaRotater { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index 238e687ab..a8536b149 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -10,11 +10,11 @@ class cBlockComparatorHandler : - public cMetaRotater + public cMetaRotater { public: cBlockComparatorHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 0caeb7dba..ef73a5d42 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -10,9 +10,9 @@ class cBlockDoorHandler : - public cMetaRotater + public cMetaRotater { - typedef cMetaRotater super; + typedef cMetaRotater super; public: cBlockDoorHandler(BLOCKTYPE a_BlockType); diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h index adc819a4c..7e0ad0e55 100644 --- a/src/Blocks/BlockDropSpenser.h +++ b/src/Blocks/BlockDropSpenser.h @@ -13,11 +13,11 @@ class cBlockDropSpenserHandler : - public cMetaRotater + public cMetaRotater { public: cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h index 6ca83399a..97cf484fb 100644 --- a/src/Blocks/BlockEnderchest.h +++ b/src/Blocks/BlockEnderchest.h @@ -8,11 +8,11 @@ class cBlockEnderchestHandler : - public cMetaRotater + public cMetaRotater { public: cBlockEnderchestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index c33393590..8c94e4875 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -8,11 +8,11 @@ class cBlockFenceGateHandler : - public cMetaRotater + public cMetaRotater { public: cBlockFenceGateHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index f07afc9f0..bbbe0ee84 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -8,11 +8,11 @@ class cBlockStairsHandler : - public cMetaRotater + public cMetaRotater { public: cBlockStairsHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index 59c896857..03a63ac72 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -8,11 +8,11 @@ class cBlockTorchHandler : - public cMetaRotater + public cMetaRotater { public: cBlockTorchHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } -- cgit v1.2.3 From 36fd78af35b49d64b97e93df6428ace787c88c4c Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 2 Mar 2014 22:55:14 +0200 Subject: Removed if condition --- src/BlockInfo.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 195af49c7..399efcd9b 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -33,10 +33,7 @@ cBlockInfo::cBlockInfo() cBlockInfo::~cBlockInfo() { - if (m_Handler != NULL) - { - delete m_Handler; - } + delete m_Handler; } -- cgit v1.2.3 From 442c1d96fc77a91b917c7a7aefb7f8f23c0a7e10 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 3 Mar 2014 20:55:04 +0100 Subject: Fixed previous weather changes. cWorld::GetDefaultWeatherInterval() returns -1 for unknown weather. --- src/World.cpp | 6 +++--- src/World.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index 58d50d3a8..6ee0def91 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -325,8 +325,8 @@ int cWorld::GetDefaultWeatherInterval(eWeather a_Weather) } default: { - LOGWARNING("Missing default weather interval for weather %d.", a_Weather); - return 1200; + LOGWARNING("%s: Missing default weather interval for weather %d.", __FUNCTION__, a_Weather); + return -1; } } // switch (Weather) } @@ -348,7 +348,7 @@ void cWorld::SetWeather(eWeather a_NewWeather) m_WeatherInterval = GetDefaultWeatherInterval(a_NewWeather); // The weather can't be found: - if (m_WeatherInterval == 1200) + if (m_WeatherInterval < 0) { return; } diff --git a/src/World.h b/src/World.h index 27f1482e5..93397c014 100644 --- a/src/World.h +++ b/src/World.h @@ -139,7 +139,8 @@ public: BroadcastTimeUpdate(); } - /** Returns the default weather interval for the specific weather type */ + /** Returns the default weather interval for the specific weather type. + Returns -1 for any unknown weather. */ int GetDefaultWeatherInterval(eWeather a_Weather); /** Returns the current game mode. Partly OBSOLETE, you should use IsGameModeXXX() functions wherever applicable */ -- cgit v1.2.3 From e50ffba1ad1cae0154828ccc210ba4949af088f3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 4 Mar 2014 18:40:55 +0100 Subject: Fixed an assert in map-loading. The maps were loaded too soon, the world wasn't initialized yet. --- src/World.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index 6ee0def91..37c07b398 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -264,8 +264,6 @@ cWorld::cWorld(const AString & a_WorldName) : // Load the scoreboard cScoreboardSerializer Serializer(m_WorldName, &m_Scoreboard); Serializer.Load(); - - m_MapManager.LoadMapData(); } @@ -652,13 +650,13 @@ void cWorld::Start(void) m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfAmbient, 0)); m_LastSpawnMonster.insert(std::map::value_type(cMonster::mfWater, 0)); + m_MapManager.LoadMapData(); // Save any changes that the defaults may have done to the ini file: if (!IniFile.WriteFile(m_IniFileName)) { LOGWARNING("Could not write world config to %s", m_IniFileName.c_str()); } - } -- cgit v1.2.3 From ecfe17b096994649610c03561496d8506648322c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 4 Mar 2014 21:55:24 +0100 Subject: cLuaState: Made public the GetStackValue() functions. --- src/Bindings/LuaState.cpp | 18 ++++++--- src/Bindings/LuaState.h | 97 ++++++++++++++++++++++++----------------------- 2 files changed, 61 insertions(+), 54 deletions(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index a5540df17..1890dcfe5 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -716,7 +716,7 @@ void cLuaState::Push(cBlockEntity * a_BlockEntity) -void cLuaState::GetReturn(int a_StackPos, bool & a_ReturnedVal) +void cLuaState::GetStackValue(int a_StackPos, bool & a_ReturnedVal) { a_ReturnedVal = (tolua_toboolean(m_LuaState, a_StackPos, a_ReturnedVal ? 1 : 0) > 0); } @@ -725,11 +725,17 @@ void cLuaState::GetReturn(int a_StackPos, bool & a_ReturnedVal) -void cLuaState::GetReturn(int a_StackPos, AString & a_ReturnedVal) +void cLuaState::GetStackValue(int a_StackPos, AString & a_Value) { - if (lua_isstring(m_LuaState, a_StackPos)) + size_t len = 0; + const char * data = lua_tolstring(m_LuaState, a_StackPos, &len); + if (data != NULL) + { + a_Value.assign(data, len); + } + else { - a_ReturnedVal = tolua_tocppstring(m_LuaState, a_StackPos, a_ReturnedVal.c_str()); + a_Value.clear(); } } @@ -737,7 +743,7 @@ void cLuaState::GetReturn(int a_StackPos, AString & a_ReturnedVal) -void cLuaState::GetReturn(int a_StackPos, int & a_ReturnedVal) +void cLuaState::GetStackValue(int a_StackPos, int & a_ReturnedVal) { if (lua_isnumber(m_LuaState, a_StackPos)) { @@ -749,7 +755,7 @@ void cLuaState::GetReturn(int a_StackPos, int & a_ReturnedVal) -void cLuaState::GetReturn(int a_StackPos, double & a_ReturnedVal) +void cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal) { if (lua_isnumber(m_LuaState, a_StackPos)) { diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index dcb660c3f..4a7a6fadb 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -197,6 +197,19 @@ public: void Push(void * a_Ptr); void Push(cHopperEntity * a_Hopper); void Push(cBlockEntity * a_BlockEntity); + + /** Retrieve value at a_StackPos, if it is a valid bool. If not, a_Value is unchanged */ + void GetStackValue(int a_StackPos, bool & a_Value); + + /** Retrieve value at a_StackPos, if it is a valid string. If not, a_Value is unchanged */ + void GetStackValue(int a_StackPos, AString & a_Value); + + /** Retrieve value at a_StackPos, if it is a valid number. If not, a_Value is unchanged */ + void GetStackValue(int a_StackPos, int & a_Value); + + /** Retrieve value at a_StackPos, if it is a valid number. If not, a_Value is unchanged */ + void GetStackValue(int a_StackPos, double & a_Value); + /** Call any 0-param 0-return Lua function in a single line: */ template @@ -270,7 +283,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); return true; } @@ -292,7 +305,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); ASSERT(InitialTop == lua_gettop(m_LuaState)); return true; @@ -315,7 +328,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); return true; } @@ -338,7 +351,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); return true; } @@ -362,7 +375,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); return true; } @@ -387,7 +400,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); return true; } @@ -414,7 +427,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); return true; } @@ -442,7 +455,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); return true; } @@ -471,7 +484,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); return true; } @@ -501,7 +514,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); return true; } @@ -532,7 +545,7 @@ public: { return false; } - GetReturn(-1, a_Ret1); + GetStackValue(-1, a_Ret1); lua_pop(m_LuaState, 1); return true; } @@ -553,8 +566,8 @@ public: { return false; } - GetReturn(-2, a_Ret1); - GetReturn(-1, a_Ret2); + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); lua_pop(m_LuaState, 2); return true; } @@ -576,8 +589,8 @@ public: { return false; } - GetReturn(-2, a_Ret1); - GetReturn(-1, a_Ret2); + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); lua_pop(m_LuaState, 2); return true; } @@ -601,8 +614,8 @@ public: { return false; } - GetReturn(-2, a_Ret1); - GetReturn(-1, a_Ret2); + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); lua_pop(m_LuaState, 2); return true; } @@ -627,8 +640,8 @@ public: { return false; } - GetReturn(-2, a_Ret1); - GetReturn(-1, a_Ret2); + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); lua_pop(m_LuaState, 2); return true; } @@ -654,8 +667,8 @@ public: { return false; } - GetReturn(-2, a_Ret1); - GetReturn(-1, a_Ret2); + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); lua_pop(m_LuaState, 2); return true; } @@ -683,8 +696,8 @@ public: { return false; } - GetReturn(-2, a_Ret1); - GetReturn(-1, a_Ret2); + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); lua_pop(m_LuaState, 2); return true; } @@ -713,8 +726,8 @@ public: { return false; } - GetReturn(-2, a_Ret1); - GetReturn(-1, a_Ret2); + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); lua_pop(m_LuaState, 2); return true; } @@ -743,9 +756,9 @@ public: { return false; } - GetReturn(-3, a_Ret1); - GetReturn(-2, a_Ret2); - GetReturn(-1, a_Ret3); + GetStackValue(-3, a_Ret1); + GetStackValue(-2, a_Ret2); + GetStackValue(-1, a_Ret3); lua_pop(m_LuaState, 3); return true; } @@ -775,9 +788,9 @@ public: { return false; } - GetReturn(-3, a_Ret1); - GetReturn(-2, a_Ret2); - GetReturn(-1, a_Ret3); + GetStackValue(-3, a_Ret1); + GetStackValue(-2, a_Ret2); + GetStackValue(-1, a_Ret3); lua_pop(m_LuaState, 3); return true; } @@ -808,11 +821,11 @@ public: { return false; } - GetReturn(-5, a_Ret1); - GetReturn(-4, a_Ret2); - GetReturn(-3, a_Ret3); - GetReturn(-2, a_Ret4); - GetReturn(-1, a_Ret5); + GetStackValue(-5, a_Ret1); + GetStackValue(-4, a_Ret2); + GetStackValue(-3, a_Ret3); + GetStackValue(-2, a_Ret4); + GetStackValue(-1, a_Ret5); lua_pop(m_LuaState, 5); return true; } @@ -918,18 +931,6 @@ protected: /** Pushes a usertype of the specified class type onto the stack */ void PushUserType(void * a_Object, const char * a_Type); - /** Retrieve value returned at a_StackPos, if it is a valid bool. If not, a_ReturnedVal is unchanged */ - void GetReturn(int a_StackPos, bool & a_ReturnedVal); - - /** Retrieve value returned at a_StackPos, if it is a valid string. If not, a_ReturnedVal is unchanged */ - void GetReturn(int a_StackPos, AString & a_ReturnedVal); - - /** Retrieve value returned at a_StackPos, if it is a valid number. If not, a_ReturnedVal is unchanged */ - void GetReturn(int a_StackPos, int & a_ReturnedVal); - - /** Retrieve value returned at a_StackPos, if it is a valid number. If not, a_ReturnedVal is unchanged */ - void GetReturn(int a_StackPos, double & a_ReturnedVal); - /** Calls the function that has been pushed onto the stack by PushFunction(), with arguments pushed by PushXXX(). -- cgit v1.2.3 From 8f782885640a270bfe23843dff82367d28f9fb23 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 4 Mar 2014 22:17:23 +0100 Subject: Manually exported cCompositeChat modifiers. This adds chaining support to them. Fixes #755. --- src/Bindings/ManualBindings.cpp | 258 ++++++++++++++++++++++++++++++++++++++++ src/CompositeChat.h | 17 +-- 2 files changed, 268 insertions(+), 7 deletions(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index fcdd728be..9fbc2e842 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -26,6 +26,7 @@ #include "md5/md5.h" #include "../LineBlockTracer.h" #include "../WorldStorage/SchematicFileSerializer.h" +#include "../CompositeChat.h" @@ -2511,6 +2512,253 @@ static int tolua_cBlockArea_SaveToSchematicFile(lua_State * tolua_S) +static int tolua_cCompositeChat_AddRunCommandPart(lua_State * tolua_S) +{ + // function cCompositeChat:AddRunCommandPart(Message, Command, [Style]) + // Exported manually to support call-chaining (return *this) + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cCompositeChat") || + !L.CheckParamString(2, 3) + ) + { + return 0; + } + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) + { + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddRunCommandPart'", NULL); + return 0; + } + + // Add the part: + AString Text, Command, Style; + L.GetStackValue(2, Text); + L.GetStackValue(3, Command); + L.GetStackValue(4, Style); + self->AddRunCommandPart(Text, Command, Style); + + // Cut away everything from the stack except for the cCompositeChat instance; return that: + lua_settop(L, 1); + return 1; +} + + + + + +static int tolua_cCompositeChat_AddSuggestCommandPart(lua_State * tolua_S) +{ + // function cCompositeChat:AddSuggestCommandPart(Message, Command, [Style]) + // Exported manually to support call-chaining (return *this) + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cCompositeChat") || + !L.CheckParamString(2, 3) + ) + { + return 0; + } + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) + { + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddSuggestCommandPart'", NULL); + return 0; + } + + // Add the part: + AString Text, Command, Style; + L.GetStackValue(2, Text); + L.GetStackValue(3, Command); + L.GetStackValue(4, Style); + self->AddSuggestCommandPart(Text, Command, Style); + + // Cut away everything from the stack except for the cCompositeChat instance; return that: + lua_settop(L, 1); + return 1; +} + + + + + +static int tolua_cCompositeChat_AddTextPart(lua_State * tolua_S) +{ + // function cCompositeChat:AddTextPart(Message, [Style]) + // Exported manually to support call-chaining (return *this) + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cCompositeChat") || + !L.CheckParamString(2) + ) + { + return 0; + } + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) + { + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddTextPart'", NULL); + return 0; + } + + // Add the part: + AString Text, Style; + L.GetStackValue(2, Text); + L.GetStackValue(3, Style); + self->AddTextPart(Text, Style); + + // Cut away everything from the stack except for the cCompositeChat instance; return that: + lua_settop(L, 1); + return 1; +} + + + + + +static int tolua_cCompositeChat_AddUrlPart(lua_State * tolua_S) +{ + // function cCompositeChat:AddTextPart(Message, Url, [Style]) + // Exported manually to support call-chaining (return *this) + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cCompositeChat") || + !L.CheckParamString(2, 3) + ) + { + return 0; + } + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) + { + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddUrlPart'", NULL); + return 0; + } + + // Add the part: + AString Text, Url, Style; + L.GetStackValue(2, Text); + L.GetStackValue(3, Url); + L.GetStackValue(4, Style); + self->AddUrlPart(Text, Url, Style); + + // Cut away everything from the stack except for the cCompositeChat instance; return that: + lua_settop(L, 1); + return 1; +} + + + + + +static int tolua_cCompositeChat_ParseText(lua_State * tolua_S) +{ + // function cCompositeChat:ParseText(TextMessage) + // Exported manually to support call-chaining (return *this) + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cCompositeChat") || + !L.CheckParamString(2) + ) + { + return 0; + } + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) + { + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:ParseText'", NULL); + return 0; + } + + // Parse the text: + AString Text; + L.GetStackValue(2, Text); + self->ParseText(Text); + + // Cut away everything from the stack except for the cCompositeChat instance; return that: + lua_settop(L, 1); + return 1; +} + + + + + +static int tolua_cCompositeChat_SetMessageType(lua_State * tolua_S) +{ + // function cCompositeChat:SetMessageType(MessageType) + // Exported manually to support call-chaining (return *this) + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cCompositeChat") || + !L.CheckParamNumber(2) + ) + { + return 0; + } + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) + { + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:SetMessageType'", NULL); + return 0; + } + + // Set the type: + int MessageType; + L.GetStackValue(1, MessageType); + self->SetMessageType((eMessageType)MessageType); + + // Cut away everything from the stack except for the cCompositeChat instance; return that: + lua_settop(L, 1); + return 1; +} + + + + + +static int tolua_cCompositeChat_UnderlineUrls(lua_State * tolua_S) +{ + // function cCompositeChat:UnderlineUrls() + // Exported manually to support call-chaining (return *this) + + // Check params: + cLuaState L(tolua_S); + if (!L.CheckParamUserType(1, "cCompositeChat")) + { + return 0; + } + cCompositeChat * self = (cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) + { + tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:UnderlineUrls'", NULL); + return 0; + } + + // Call the processing + self->UnderlineUrls(); + + // Cut away everything from the stack except for the cCompositeChat instance; return that: + lua_settop(L, 1); + return 1; +} + + + + + void ManualBindings::Bind(lua_State * tolua_S) { tolua_beginmodule(tolua_S, NULL); @@ -2535,6 +2783,16 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "SaveToSchematicFile", tolua_cBlockArea_SaveToSchematicFile); tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cCompositeChat"); + tolua_function(tolua_S, "AddRunCommandPart", tolua_cCompositeChat_AddRunCommandPart); + tolua_function(tolua_S, "AddSuggestCommandPart", tolua_cCompositeChat_AddSuggestCommandPart); + tolua_function(tolua_S, "AddTextPart", tolua_cCompositeChat_AddTextPart); + tolua_function(tolua_S, "AddUrlPart", tolua_cCompositeChat_AddUrlPart); + tolua_function(tolua_S, "ParseText", tolua_cCompositeChat_ParseText); + tolua_function(tolua_S, "SetMessageType", tolua_cCompositeChat_SetMessageType); + tolua_function(tolua_S, "UnderlineUrls", tolua_cCompositeChat_UnderlineUrls); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cHopperEntity"); tolua_function(tolua_S, "GetOutputBlockPos", tolua_cHopperEntity_GetOutputBlockPos); tolua_endmodule(tolua_S); diff --git a/src/CompositeChat.h b/src/CompositeChat.h index 51600da4f..27319490d 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -124,14 +124,15 @@ public: /** Removes all parts from the object. */ void Clear(void); + // tolua_end + + // The following are exported in ManualBindings in order to support chaining - they return *this in Lua (#755) + /** Adds a plain text part, with optional style. The default style is plain white text. */ void AddTextPart(const AString & a_Message, const AString & a_Style = ""); - // tolua_end - - /** Adds a part that is translated client-side, with the formatting parameters and optional style. - Exported in ManualBindings due to AStringVector usage - Lua uses an array-table of strings. */ + /** Adds a part that is translated client-side, with the formatting parameters and optional style. */ void AddClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style = ""); // tolua_begin @@ -155,12 +156,14 @@ public: /** Sets the message type, which is indicated by prefixes added to the message when serializing. */ void SetMessageType(eMessageType a_MessageType); - /** Returns the message type set previously by SetMessageType(). */ - eMessageType GetMessageType(void) const { return m_MessageType; } - /** Adds the "underline" style to each part that is an URL. */ void UnderlineUrls(void); + // tolua_begin + + /** Returns the message type set previously by SetMessageType(). */ + eMessageType GetMessageType(void) const { return m_MessageType; } + // tolua_end const cParts & GetParts(void) const { return m_Parts; } -- cgit v1.2.3 From ab30d94b2fed330bb487e30960d82c0bedff37b4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 4 Mar 2014 22:17:47 +0100 Subject: Debuggers: Added simple test for cCompositeChat. --- MCServer/Plugins/Debuggers/Debuggers.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 66894d835..329a652cd 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -30,6 +30,7 @@ function Initialize(Plugin) PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated); PM:AddHook(cPluginManager.HOOK_PLUGINS_LOADED, OnPluginsLoaded); PM:AddHook(cPluginManager.HOOK_PLUGIN_MESSAGE, OnPluginMessage); + PM:AddHook(cPluginManager.HOOK_PLAYER_JOINED, OnPlayerJoined) PM:BindCommand("/le", "debuggers", HandleListEntitiesCmd, "- Shows a list of all the loaded entities"); PM:BindCommand("/ke", "debuggers", HandleKillEntitiesCmd, "- Kills all the loaded entities"); @@ -1258,3 +1259,17 @@ end + +function OnPlayerJoined(a_Player) + -- Test composite chat chaining: + a_Player:SendMessage(cCompositeChat() + :AddTextPart("Hello, ") + :AddUrlPart(a_Player:GetName(), "www.mc-server.org", "u@2") + :AddSuggestCommandPart(", and welcome.", "/help", "u") + :AddRunCommandPart(" SetDay", "/time set 0") + ) +end + + + + -- cgit v1.2.3 From a845c051b8df10c6eaf1f68d3c37abe71425e9d6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 4 Mar 2014 22:25:31 +0100 Subject: Fixed some gcc warnings in Defines.h. --- src/Defines.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Defines.h b/src/Defines.h index 018ecb1d3..6ab2274a4 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -235,8 +235,8 @@ inline eBlockFace MirrorBlockFaceY(eBlockFace a_BlockFace) case BLOCK_FACE_XP: return BLOCK_FACE_XM; case BLOCK_FACE_ZM: return BLOCK_FACE_ZP; case BLOCK_FACE_ZP: return BLOCK_FACE_ZM; + default: return a_BlockFace; } - return a_BlockFace; } @@ -252,8 +252,8 @@ inline eBlockFace RotateBlockFaceCCW(eBlockFace a_BlockFace) case BLOCK_FACE_XP: return BLOCK_FACE_ZM; case BLOCK_FACE_ZM: return BLOCK_FACE_XM; case BLOCK_FACE_ZP: return BLOCK_FACE_XP; + default: return a_BlockFace; } - return a_BlockFace; } @@ -268,8 +268,8 @@ inline eBlockFace RotateBlockFaceCW(eBlockFace a_BlockFace) case BLOCK_FACE_XP: return BLOCK_FACE_ZP; case BLOCK_FACE_ZM: return BLOCK_FACE_XP; case BLOCK_FACE_ZP: return BLOCK_FACE_XM; + default: return a_BlockFace; } - return a_BlockFace; } -- cgit v1.2.3 From 1ea17c0a75b84d5f4070c57ad2a7d6cbb4e8b79b Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 5 Mar 2014 15:54:38 +0200 Subject: Implemented vanilla-like fluid simulator --- src/Scoreboard.cpp | 2 +- src/Simulator/FloodyFluidSimulator.cpp | 23 +++-- src/Simulator/FloodyFluidSimulator.h | 12 ++- src/Simulator/VanillaFluidSimulator.cpp | 150 ++++++++++++++++++++++++++++++++ src/Simulator/VanillaFluidSimulator.h | 42 +++++++++ src/World.cpp | 26 ++++-- 6 files changed, 238 insertions(+), 17 deletions(-) create mode 100644 src/Simulator/VanillaFluidSimulator.cpp create mode 100644 src/Simulator/VanillaFluidSimulator.h diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index c1da27086..8088e624b 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -506,7 +506,7 @@ bool cScoreboard::ForEachObjective(cObjectiveCallback& a_Callback) bool cScoreboard::ForEachTeam(cTeamCallback& a_Callback) { - cCSLock Lock(m_CSObjectives); + cCSLock Lock(m_CSTeams); for (cTeamMap::iterator it = m_Teams.begin(); it != m_Teams.end(); ++it) { diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index 95182345c..b1ac734d7 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -86,7 +86,12 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re { // Spread only down, possibly washing away what's there or turning lava to stone / cobble / obsidian: SpreadToNeighbor(a_Chunk, a_RelX, a_RelY - 1, a_RelZ, 8); - SpreadFurther = false; + + // Source blocks spread both downwards and sideways + if (MyMeta != 0) + { + SpreadFurther = false; + } } // If source creation is on, check for it here: else if ( @@ -105,10 +110,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re if (SpreadFurther && (NewMeta < 8)) { // Spread to the neighbors: - SpreadToNeighbor(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, NewMeta); - SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, NewMeta); - SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, NewMeta); - SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, NewMeta); + Spread(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta); } // Mark as processed: @@ -119,6 +121,17 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re +void cFloodyFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) +{ + SpreadToNeighbor(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, a_NewMeta); + SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta); + SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, a_NewMeta); + SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, a_NewMeta); +} + + + + bool cFloodyFluidSimulator::CheckTributaries(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_MyMeta) { // If we have a section above, check if there's fluid above this block that would feed it: diff --git a/src/Simulator/FloodyFluidSimulator.h b/src/Simulator/FloodyFluidSimulator.h index c4af2e246..5fd91b2b1 100644 --- a/src/Simulator/FloodyFluidSimulator.h +++ b/src/Simulator/FloodyFluidSimulator.h @@ -38,14 +38,20 @@ protected: // cDelayedFluidSimulator overrides: virtual void SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override; - /// Checks tributaries, if not fed, decreases the block's level and returns true + /** Checks tributaries, if not fed, decreases the block's level and returns true. */ bool CheckTributaries(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_MyMeta); - /// Spreads into the specified block, if the blocktype there allows. a_Area is for checking. + /** Spreads into the specified block, if the blocktype there allows. a_Area is for checking. */ void SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta); - /// Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns true if so + /** Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns true if so. */ bool CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); + + /** Spread water to neighbors. + * + * May be overridden to provide more sophisticated algorithms. + */ + virtual void Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta); } ; diff --git a/src/Simulator/VanillaFluidSimulator.cpp b/src/Simulator/VanillaFluidSimulator.cpp new file mode 100644 index 000000000..5308d162b --- /dev/null +++ b/src/Simulator/VanillaFluidSimulator.cpp @@ -0,0 +1,150 @@ + +// VanillaFluidSimulator.cpp + +#include "Globals.h" + +#include "VanillaFluidSimulator.h" +#include "../World.h" +#include "../Chunk.h" +#include "../BlockArea.h" +#include "../Blocks/BlockHandler.h" +#include "../BlockInServerPluginInterface.h" + + + + + +static const int InfiniteCost = 100; + + + + + +cVanillaFluidSimulator::cVanillaFluidSimulator( + cWorld & a_World, + BLOCKTYPE a_Fluid, + BLOCKTYPE a_StationaryFluid, + NIBBLETYPE a_Falloff, + int a_TickDelay, + int a_NumNeighborsForSource +) : super(a_World, a_Fluid, a_StationaryFluid, a_Falloff, a_TickDelay, a_NumNeighborsForSource) +{ +} + + + + + +void cVanillaFluidSimulator::Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) +{ + int Cost[4]; + Cost[0] = CalculateFlowCost(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, X_PLUS); + Cost[1] = CalculateFlowCost(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, X_MINUS); + Cost[2] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, Z_PLUS); + Cost[3] = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, Z_MINUS); + + int MinCost = InfiniteCost; + for (unsigned int i = 0; i < ARRAYCOUNT(Cost); ++i) + { + if (Cost[i] < MinCost) + { + MinCost = Cost[i]; + } + } + + if (Cost[0] == MinCost) + { + SpreadToNeighbor(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, a_NewMeta); + } + if (Cost[1] == MinCost) + { + SpreadToNeighbor(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, a_NewMeta); + } + if (Cost[2] == MinCost) + { + SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, a_NewMeta); + } + if (Cost[3] == MinCost) + { + SpreadToNeighbor(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, a_NewMeta); + } +} + + + + + +int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, Direction a_Dir, unsigned a_Iteration) +{ + int Cost = InfiniteCost; + + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + + // Check if block is passable + if (!a_Chunk->UnboundedRelGetBlock(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta)) + { + return Cost; + } + if (!IsPassableForFluid(BlockType)) + { + return Cost; + } + + // Check if block below is passable + if (!a_Chunk->UnboundedRelGetBlock(a_RelX, a_RelY - 1, a_RelZ, BlockType, BlockMeta)) + { + return Cost; + } + if (IsPassableForFluid(BlockType)) + { + // Path found, exit + return a_Iteration; + } + + // 5 blocks away, bail out + if (a_Iteration > 3) + { + return Cost; + } + + // Recurse + if (a_Dir != X_MINUS) + { + int NextCost = CalculateFlowCost(a_Chunk, a_RelX + 1, a_RelY, a_RelZ, X_PLUS, a_Iteration + 1); + if (NextCost < Cost) + { + Cost = NextCost; + } + } + if (a_Dir != X_PLUS) + { + int NextCost = CalculateFlowCost(a_Chunk, a_RelX - 1, a_RelY, a_RelZ, X_MINUS, a_Iteration + 1); + if (NextCost < Cost) + { + Cost = NextCost; + } + } + if (a_Dir != Z_MINUS) + { + int NextCost = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ + 1, Z_PLUS, a_Iteration + 1); + if (NextCost < Cost) + { + Cost = NextCost; + } + } + if (a_Dir != Z_PLUS) + { + int NextCost = CalculateFlowCost(a_Chunk, a_RelX, a_RelY, a_RelZ - 1, Z_MINUS, a_Iteration + 1); + if (NextCost < Cost) + { + Cost = NextCost; + } + } + + return Cost; +} + + + + diff --git a/src/Simulator/VanillaFluidSimulator.h b/src/Simulator/VanillaFluidSimulator.h new file mode 100644 index 000000000..a9ea98b5a --- /dev/null +++ b/src/Simulator/VanillaFluidSimulator.h @@ -0,0 +1,42 @@ + +// VanillaFluidSimulator.h + + + + + +#pragma once + +#include "FloodyFluidSimulator.h" + + + + + +// fwd: +class cBlockArea; + + + + + +class cVanillaFluidSimulator : + public cFloodyFluidSimulator +{ + typedef cFloodyFluidSimulator super; + +public: + cVanillaFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, NIBBLETYPE a_Falloff, int a_TickDelay, int a_NumNeighborsForSource); + +protected: + // cFloodyFluidSimulator overrides: + virtual void Spread(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) override; + + /** Recursively calculates the minimum number of blocks needed to descend a level. */ + int CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, Direction a_Dir, unsigned a_Iteration = 0); + +} ; + + + + diff --git a/src/World.cpp b/src/World.cpp index 2dfa85d64..01ba5e503 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -34,6 +34,7 @@ #include "Simulator/NoopRedstoneSimulator.h" #include "Simulator/SandSimulator.h" #include "Simulator/IncrementalRedstoneSimulator.h" +#include "Simulator/VanillaFluidSimulator.h" #include "Simulator/VaporizeFluidSimulator.h" // Mobs: @@ -2987,8 +2988,8 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c AString SimulatorName = a_IniFile.GetValueSet("Physics", SimulatorNameKey, ""); if (SimulatorName.empty()) { - LOGWARNING("[Physics] %s not present or empty in %s, using the default of \"Floody\".", SimulatorNameKey.c_str(), GetIniFileName().c_str()); - SimulatorName = "Floody"; + LOGWARNING("[Physics] %s not present or empty in %s, using the default of \"Vanilla\".", SimulatorNameKey.c_str(), GetIniFileName().c_str()); + SimulatorName = "Vanilla"; } cFluidSimulator * res = NULL; @@ -3012,15 +3013,24 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c } else { - if (NoCaseCompare(SimulatorName, "floody") != 0) - { - // The simulator name doesn't match anything we have, issue a warning: - LOGWARNING("%s [Physics]:%s specifies an unknown simulator, using the default \"Floody\".", GetIniFileName().c_str(), SimulatorNameKey.c_str()); - } int Falloff = a_IniFile.GetValueSetI(SimulatorSectionName, "Falloff", IsWater ? 1 : 2); int TickDelay = a_IniFile.GetValueSetI(SimulatorSectionName, "TickDelay", IsWater ? 5 : 30); int NumNeighborsForSource = a_IniFile.GetValueSetI(SimulatorSectionName, "NumNeighborsForSource", IsWater ? 2 : -1); - res = new cFloodyFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, Falloff, TickDelay, NumNeighborsForSource); + + if (NoCaseCompare(SimulatorName, "floody") == 0) + { + res = new cFloodyFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, Falloff, TickDelay, NumNeighborsForSource); + } + else if (NoCaseCompare(SimulatorName, "vanilla") == 0) + { + res = new cVanillaFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, Falloff, TickDelay, NumNeighborsForSource); + } + else + { + // The simulator name doesn't match anything we have, issue a warning: + LOGWARNING("%s [Physics]:%s specifies an unknown simulator, using the default \"Vanilla\".", GetIniFileName().c_str(), SimulatorNameKey.c_str()); + res = new cVanillaFluidSimulator(*this, a_SimulateBlock, a_StationaryBlock, Falloff, TickDelay, NumNeighborsForSource); + } } m_SimulatorManager->RegisterSimulator(res, Rate); -- cgit v1.2.3 From d4a5b16c52c41da59d2fe3405570653521e5d36e Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 5 Mar 2014 15:10:20 +0100 Subject: Add data backsending, when the Client interacts a Block and the Interact is cancelled. --- src/Blocks/BlockComparator.h | 6 ++++++ src/Blocks/BlockDoor.cpp | 21 +++++++++++++++++++++ src/Blocks/BlockDoor.h | 1 + src/Blocks/BlockFenceGate.h | 6 ++++++ src/Blocks/BlockHandler.cpp | 10 ++++++++++ src/Blocks/BlockHandler.h | 5 ++++- src/Blocks/BlockRedstoneRepeater.h | 8 +++++++- src/Blocks/BlockTNT.h | 32 ++++++++++++++++++++++++++++++++ src/Blocks/BlockTrapdoor.h | 5 +++++ src/ClientHandle.cpp | 14 ++++++++++---- 10 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 src/Blocks/BlockTNT.h diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index aba390d9d..b0ac75aaf 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -26,6 +26,12 @@ public: } + virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override + { + a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to 0 diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 2ff5c1c37..6c51feab3 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -55,6 +55,27 @@ void cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterfac +void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) +{ + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + a_Player->GetClientHandle()->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta); + + if (Meta & 8) + { + // Current block is top of the door + a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, a_Player); + } + else + { + // Current block is bottom of the door + a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, a_Player); + } +} + + + + + void cBlockDoorHandler::OnPlacedByPlayer( cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index ef0dbb787..68be2c658 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -16,6 +16,7 @@ public: virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; + virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override; virtual const char * GetStepSound(void) override; diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index fb984f345..a14510724 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -48,6 +48,12 @@ public: } + virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override + { + a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + } + + virtual bool IsUseable(void) override { return true; diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 052f88f7a..c5165986c 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -57,6 +57,7 @@ #include "BlockRedstoneLamp.h" #include "BlockRedstoneRepeater.h" #include "BlockRedstoneTorch.h" +#include "BlockTNT.h" #include "BlockSand.h" #include "BlockSapling.h" #include "BlockSideways.h" @@ -185,6 +186,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType); case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType); case E_BLOCK_TRAPDOOR: return new cBlockTrapdoorHandler (a_BlockType); + case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType); case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType); case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType); case E_BLOCK_WATER: return new cBlockFluidHandler (a_BlockType); @@ -320,6 +322,14 @@ void cBlockHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & +void cBlockHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) +{ +} + + + + + void cBlockHandler::ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) { // Setting the meta to a_BlockMeta keeps most textures. The few other blocks have to override this. diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index c46a46045..fbb36d96a 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -69,6 +69,9 @@ public: /// Called if the user right clicks the block and the block is useable virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ); + /** Called when a Right Click to this Block is cancelled */ + virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace); + /// Called when the item is mined to convert it into pickups. Pickups may specify multiple items. Appends items to a_Pickups, preserves its original contents virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta); @@ -80,7 +83,7 @@ public: /// Checks if the block can stay at the specified relative coords in the chunk virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk); - + /** Checks if the block can be placed at this point. Default: CanBeAt(...) NOTE: This call doesn't actually place the block diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index eb0918acf..81e3f2b8f 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -29,7 +29,7 @@ public: a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetYaw()); return true; } - + virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { @@ -37,6 +37,12 @@ public: } + virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override + { + a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to 0 diff --git a/src/Blocks/BlockTNT.h b/src/Blocks/BlockTNT.h new file mode 100644 index 000000000..a9044d65e --- /dev/null +++ b/src/Blocks/BlockTNT.h @@ -0,0 +1,32 @@ + +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockTNTHandler : + public cBlockHandler +{ +public: + cBlockTNTHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual const char * GetStepSound(void) override + { + return "step.wood"; + } + + virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override + { + a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + } +}; + + + + diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index a28861e69..ffeebd647 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -42,6 +42,11 @@ public: World->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle()); } + virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override + { + a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + } + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 6982a6227..870568cdf 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -920,14 +920,22 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, ItemToFullString(a_HeldItem).c_str() ); + cWorld * World = m_Player->GetWorld(); + cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); if (PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ)) { // A plugin doesn't agree with the action, replace the block on the client and quit: + cChunkInterface ChunkInterface(World->GetChunkMap()); + BLOCKTYPE BlockType = World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); + BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + if (a_BlockFace > -1) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); //2 block high things } return; } @@ -953,12 +961,10 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e if (a_BlockFace > -1) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); } return; } - - cWorld * World = m_Player->GetWorld(); BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; -- cgit v1.2.3 From ee1ba3e0b094ce80965eb2f1dd599fca6ff6736c Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 5 Mar 2014 15:14:20 +0100 Subject: Set tnt step sound to step.grass --- src/Blocks/BlockTNT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/BlockTNT.h b/src/Blocks/BlockTNT.h index a9044d65e..f5cdecb9a 100644 --- a/src/Blocks/BlockTNT.h +++ b/src/Blocks/BlockTNT.h @@ -18,7 +18,7 @@ public: virtual const char * GetStepSound(void) override { - return "step.wood"; + return "step.grass"; } virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override -- cgit v1.2.3 From 86615428cd3d967c8bd73628fe8946405060d24c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 5 Mar 2014 18:28:42 +0100 Subject: APIDump: Ignoring classes by exact match. "cCompositeChat" was ignored because it matched "os". --- MCServer/Plugins/APIDump/APIDesc.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 0b6f33b37..1d30ea72d 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2701,16 +2701,16 @@ end IgnoreClasses = { - "coroutine", - "debug", - "io", - "math", - "package", - "os", - "string", - "table", - "g_Stats", - "g_TrackedPages", + "^coroutine$", + "^debug$", + "^io$", + "^math$", + "^package$", + "^os$", + "^string$", + "^table$", + "^g_Stats$", + "^g_TrackedPages$", }, IgnoreFunctions = -- cgit v1.2.3 From 036608c6453857e7faf3b32f05fa5d9f62b93fa0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 5 Mar 2014 18:56:32 +0100 Subject: APIDump: Documented the cCompositeChat class. --- MCServer/Plugins/APIDump/APIDesc.lua | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 1d30ea72d..94cdd0063 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -483,6 +483,58 @@ end }, }, -- cClientHandle + cCompositeChat = + { + Desc = [[ + Encapsulates a chat message that can contain various formatting, URLs, commands executed on click + and commands suggested on click. The chat message can be sent by the regular chat-sending functions, + {{cPlayer}}:SendMessage(), {{cWorld}}:BroadcastChat() and {{cRoot}}:BroadcastChat().

+

+ Note that most of the functions in this class are so-called modifiers - they modify the object and + then return the object itself, so that they can be chained one after another. + ]], + Functions = + { + constructor = + { + { Params = "", Return = "", Notes = "Creates an empty chat message" }, + { Params = "Text", Return = "", Notes = "Creates a chat message containing the specified text, parsed by the ParseText() function. This allows easy migration from old chat messages." }, + }, + AddRunCommandPart = { Params = "Text, Command, [Style]", Return = "self", Notes = "Adds a text which, when clicked, runs the specified command. Chaining." }, + AddSuggestCommandPart = { Params = "Text, Command, [Style]", Return = "self", Notes = "Adds a text which, when clicked, puts the specified command into the player's chat input area. Chaining." }, + AddTextPart = { Params = "Text, [Style]", Return = "self", Notes = "Adds a regular text. Chaining." }, + AddUrlPart = { Params = "Text, Url, [Style]", Return = "self", Notes = "Adds a text which, when clicked, opens up a browser at the specified URL. Chaining." }, + Clear = { Params = "", Return = "", Notes = "Removes all parts from this object" }, + GetMessageType = { Params = "", Return = "MessageType", Notes = "Returns the MessageType (mtXXX constant) that is associated with this message. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.)" }, + ParseText = { Params = "Text", Return = "self", Notes = "Adds text, while recognizing http and https URLs and old-style formatting codes (\"@2\"). Chaining." }, + SetMessageType = { Params = "MessageType", Return = "self", Notes = "Sets the MessageType (mtXXX constant) that is associated with this message. When sent to a player, the message will be formatted according to this message type and the player's settings (adding \"[INFO]\" prefix etc.) Chaining." }, + UnderlineUrls = { Params = "", Return = "self", Notes = "Makes all URL parts contained in the message underlined. Doesn't affect parts added in the future. Chaining." }, + }, + + AdditionalInfo = + { + { + Header = "Chaining example", + Contents = [[ + Sending a chat message that is composed of multiple different parts has been made easy thanks to + chaining. Consider the following example that shows how a message containing all kinds of parts + is sent (adapted from the Debuggers plugin): +

+function OnPlayerJoined(a_Player)
+	-- Send an example composite chat message to the player:
+	a_Player:SendMessage(cCompositeChat()
+		:AddTextPart("Hello, ")
+		:AddUrlPart(a_Player:GetName(), "www.mc-server.org", "u@2")  -- Colored underlined link
+		:AddSuggestCommandPart(", and welcome.", "/help", "u")       -- Underlined suggest-command
+		:AddRunCommandPart(" SetDay", "/time set 0")                 -- Regular text that will execute command when clicked
+		:SetMessageType(mtJoin)                                      -- It is a join-message
+	)
+end
+ ]], + }, + }, -- AdditionalInfo + }, -- cCompositeChat + cCraftingGrid = { Desc = [[ -- cgit v1.2.3 From dc0cbd594c05395b5d71af8a8a1f24b10c2d0d50 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 5 Mar 2014 19:17:59 +0100 Subject: The APIDump generates a list of all the permissions again. --- MCServer/Plugins/InfoDump.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/MCServer/Plugins/InfoDump.lua b/MCServer/Plugins/InfoDump.lua index 59263d056..c61f9c9e6 100644 --- a/MCServer/Plugins/InfoDump.lua +++ b/MCServer/Plugins/InfoDump.lua @@ -530,12 +530,13 @@ local function DumpPermissionsGithub(a_PluginInfo, f) -- Dump the permissions: f:write("\n# Permissions\n"); + f:write("| Permissions | Description | Commands | Recommended groups |\n") + f:write("| ----------- | ----------- | -------- | ------------------ |\n") for idx, perm in ipairs(Permissions) do - f:write("### ", perm.Name, "\n"); - f:write(GithubizeString(perm.Info.Description or "")); + f:write(perm.Name, " | "); + f:write(GithubizeString(perm.Info.Description or ""), " | "); local CommandsAffected = perm.Info.CommandsAffected or {}; if (#CommandsAffected > 0) then - f:write("\n\nCommands affected:\n - "); local Affects = {}; for idx2, cmd in ipairs(CommandsAffected) do if (type(cmd) == "string") then @@ -544,11 +545,10 @@ local function DumpPermissionsGithub(a_PluginInfo, f) table.insert(Affects, GetCommandRefGithub(cmd.Name, cmd)); end end - f:write(table.concat(Affects, "\n - ")); - f:write("\n"); + f:write(table.concat(Affects, ", "), " | "); end if (perm.Info.RecommendedGroups ~= nil) then - f:write("\n\nRecommended groups: ", perm.Info.RecommendedGroups, "\n"); + f:write(perm.Info.RecommendedGroups, " |"); end f:write("\n"); end @@ -594,7 +594,7 @@ local function DumpPluginInfoGithub(a_PluginFolder, a_PluginInfo) f:write(GithubizeString(a_PluginInfo.Description), "\n"); DumpAdditionalInfoGithub(a_PluginInfo, f); DumpCommandsGithub(a_PluginInfo, f); - --DumpPermissionsGithub(a_PluginInfo, f); -- Seems a little overkill since they are already mentioned in the commands. + DumpPermissionsGithub(a_PluginInfo, f); f:close(); end -- cgit v1.2.3 From 594ddd86a04d895fdecb1cd4767031abc5c8dcca Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 5 Mar 2014 19:33:43 +0100 Subject: Add SendBlockTo to cWorldInterface --- src/Blocks/BlockComparator.h | 3 ++- src/Blocks/BlockDoor.cpp | 8 +++++--- src/Blocks/BlockFenceGate.h | 2 +- src/Blocks/BlockHandler.h | 2 +- src/Blocks/BlockRedstoneRepeater.h | 3 ++- src/Blocks/BlockTNT.h | 2 +- src/Blocks/BlockTrapdoor.h | 3 ++- src/Blocks/WorldInterface.h | 3 +++ src/World.h | 2 +- 9 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index b0ac75aaf..cea35a864 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -28,7 +28,8 @@ public: virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override { - a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + UNUSED(a_ChunkInterface); + a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); } diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 6c51feab3..0acf04852 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -57,18 +57,20 @@ void cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterfac void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) { + UNUSED(a_ChunkInterface); + + a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - a_Player->GetClientHandle()->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta); if (Meta & 8) { // Current block is top of the door - a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, a_Player); + a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY - 1, a_BlockZ, a_Player); } else { // Current block is bottom of the door - a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, a_Player); + a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, a_Player); } } diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index a14510724..1abe1eecf 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -50,7 +50,7 @@ public: virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override { - a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); } diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index fbb36d96a..50c2e2ad5 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -83,7 +83,7 @@ public: /// Checks if the block can stay at the specified relative coords in the chunk virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk); - + /** Checks if the block can be placed at this point. Default: CanBeAt(...) NOTE: This call doesn't actually place the block diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index 81e3f2b8f..1e2a86949 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -39,7 +39,8 @@ public: virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override { - a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + UNUSED(a_ChunkInterface); + a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); } diff --git a/src/Blocks/BlockTNT.h b/src/Blocks/BlockTNT.h index f5cdecb9a..283a03730 100644 --- a/src/Blocks/BlockTNT.h +++ b/src/Blocks/BlockTNT.h @@ -23,7 +23,7 @@ public: virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override { - a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); } }; diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index ffeebd647..9bae92c4d 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -44,7 +44,8 @@ public: virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override { - a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); + UNUSED(a_ChunkInterface); + a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); } virtual bool GetPlacementBlockTypeMeta( diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index b6f2f55a7..c38ffc6db 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -27,4 +27,7 @@ public: /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0; + + /** If there is a block entity at the specified coords, sends it to the client specified */ + virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0; }; diff --git a/src/World.h b/src/World.h index 93397c014..69d0d6b41 100644 --- a/src/World.h +++ b/src/World.h @@ -455,7 +455,7 @@ public: // tolua_begin bool DigBlock (int a_X, int a_Y, int a_Z); - void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player ); + virtual void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player); double GetSpawnX(void) const { return m_SpawnX; } double GetSpawnY(void) const { return m_SpawnY; } -- cgit v1.2.3 From 53231bebd650b9398060cee1434ad4c44152d36e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 5 Mar 2014 22:12:48 +0000 Subject: Added extra awesomeness to TNT + TNT now has a chance of flinging FallingBlock entities around * Improved TNT damage * Improved TNT spawning visuals * Possible fix for 'SetSwimState failure' messages in debug --- src/ChunkMap.cpp | 31 +- src/Entities/Entity.cpp | 380 +++++++++++++------------ src/Entities/Entity.h | 1 + src/Entities/FallingBlock.cpp | 19 +- src/Items/ItemLighter.h | 2 +- src/Simulator/IncrementalRedstoneSimulator.cpp | 2 +- src/World.cpp | 6 +- 7 files changed, 232 insertions(+), 209 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index b5795fbaf..b13337b44 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1832,8 +1832,17 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } + else if (m_World->GetTickRandomNumber(100) < 20) // 20% chance of flinging stuff around + { + if (!cBlockInfo::FullyOccupiesVoxel(area.GetBlockType(bx + x, by + y, bz + z))) + { + break; + } + m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, area.GetBlockType(bx + x, by + y, bz + z), area.GetBlockMeta(bx + x, by + y, bz + z)); + } area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); + break; } } // switch (BlockType) } // for z @@ -1846,11 +1855,10 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ public cEntityCallback { public: - cTNTDamageCallback(cBoundingBox & a_bbTNT, Vector3d a_ExplosionPos, int a_ExplosionSize, int a_ExplosionSizeSq) : + cTNTDamageCallback(cBoundingBox & a_bbTNT, Vector3d a_ExplosionPos, int a_ExplosionSize) : m_bbTNT(a_bbTNT), m_ExplosionPos(a_ExplosionPos), - m_ExplosionSize(a_ExplosionSize), - m_ExplosionSizeSq(a_ExplosionSizeSq) + m_ExplosionSize(a_ExplosionSize) { } @@ -1873,14 +1881,16 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ } Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); - Vector3d MaxExplosionBoundary(m_ExplosionSizeSq, m_ExplosionSizeSq, m_ExplosionSizeSq); // Work out how far we are from the edge of the TNT's explosive effect AbsoluteEntityPos -= m_ExplosionPos; - AbsoluteEntityPos = MaxExplosionBoundary - AbsoluteEntityPos; - double FinalDamage = ((AbsoluteEntityPos.x + AbsoluteEntityPos.y + AbsoluteEntityPos.z) / 3) * m_ExplosionSize; - FinalDamage = a_Entity->GetMaxHealth() - abs(FinalDamage); + // All to positive + AbsoluteEntityPos.x = abs(AbsoluteEntityPos.x); + AbsoluteEntityPos.y = abs(AbsoluteEntityPos.y); + AbsoluteEntityPos.z = abs(AbsoluteEntityPos.z); + + double FinalDamage = (((1 / AbsoluteEntityPos.x) + (1 / AbsoluteEntityPos.y) + (1 / AbsoluteEntityPos.z)) * 2) * m_ExplosionSize; // Clip damage values if (FinalDamage > a_Entity->GetMaxHealth()) @@ -1888,7 +1898,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ else if (FinalDamage < 0) FinalDamage = 0; - if (!a_Entity->IsTNT()) // Don't apply damage to other TNT entities, they should be invincible + if (!a_Entity->IsTNT() && !a_Entity->IsFallingBlock()) // Don't apply damage to other TNT entities, they should be invincible { a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); } @@ -1898,7 +1908,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ if (distance_explosion.SqrLength() < 4096.0) { distance_explosion.Normalize(); - distance_explosion *= m_ExplosionSizeSq; + distance_explosion *= m_ExplosionSize * m_ExplosionSize; a_Entity->AddSpeed(distance_explosion); } @@ -1910,14 +1920,13 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ cBoundingBox & m_bbTNT; Vector3d m_ExplosionPos; int m_ExplosionSize; - int m_ExplosionSizeSq; }; cBoundingBox bbTNT(Vector3d(a_BlockX, a_BlockY, a_BlockZ), 0.5, 1); bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2); - cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), ExplosionSizeInt, ExplosionSizeSq); + cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), ExplosionSizeInt); ForEachEntity(TNTDamageCallback); // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 96e8c15a5..3eac0e2e8 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -521,27 +521,35 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk) { if (a_Chunk.IsValid()) { - HandlePhysics(a_Dt, a_Chunk); - } - } - if (a_Chunk.IsValid()) - { - TickBurning(a_Chunk); - } - if ((a_Chunk.IsValid()) && (GetPosY() < -46)) - { - TickInVoid(a_Chunk); - } - else - m_TicksSinceLastVoidDamage = 0; + cChunk * NextChunk = a_Chunk.GetNeighborChunk(POSX_TOINT, POSZ_TOINT); - if (IsMob() || IsPlayer()) - { - // Set swimming state - SetSwimState(a_Chunk); + if ((NextChunk == NULL) || !NextChunk->IsValid()) + { + return; + } + + TickBurning(*NextChunk); - // Handle drowning - HandleAir(); + if (GetPosY() < VOID_BOUNDARY) + { + TickInVoid(*NextChunk); + } + else + { + m_TicksSinceLastVoidDamage = 0; + } + + if (IsMob() || IsPlayer()) + { + // Set swimming state + SetSwimState(*NextChunk); + + // Handle drowning + HandleAir(); + } + + HandlePhysics(a_Dt, *NextChunk); + } } } @@ -562,7 +570,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) if ((BlockY >= cChunkDef::Height) || (BlockY < 0)) { // Outside of the world - + cChunk * NextChunk = a_Chunk.GetNeighborChunk(BlockX, BlockZ); // See if we can commit our changes. If not, we will discard them. if (NextChunk != NULL) @@ -571,210 +579,208 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) NextPos += (NextSpeed * a_Dt); SetPosition(NextPos); } + return; } - // Make sure we got the correct chunk and a valid one. No one ever knows... - cChunk * NextChunk = a_Chunk.GetNeighborChunk(BlockX, BlockZ); - if (NextChunk != NULL) + int RelBlockX = BlockX - (a_Chunk.GetPosX() * cChunkDef::Width); + int RelBlockZ = BlockZ - (a_Chunk.GetPosZ() * cChunkDef::Width); + BLOCKTYPE BlockIn = a_Chunk.GetBlock( RelBlockX, BlockY, RelBlockZ ); + BLOCKTYPE BlockBelow = (BlockY > 0) ? a_Chunk.GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR; + if (!cBlockInfo::IsSolid(BlockIn)) // Making sure we are not inside a solid block { - int RelBlockX = BlockX - (NextChunk->GetPosX() * cChunkDef::Width); - int RelBlockZ = BlockZ - (NextChunk->GetPosZ() * cChunkDef::Width); - BLOCKTYPE BlockIn = NextChunk->GetBlock( RelBlockX, BlockY, RelBlockZ ); - BLOCKTYPE BlockBelow = (BlockY > 0) ? NextChunk->GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR; - if (!cBlockInfo::IsSolid(BlockIn)) // Making sure we are not inside a solid block + if (m_bOnGround) // check if it's still on the ground { - if (m_bOnGround) // check if it's still on the ground + if (!cBlockInfo::IsSolid(BlockBelow)) // Check if block below is air or water. { - if (!cBlockInfo::IsSolid(BlockBelow)) // Check if block below is air or water. - { - m_bOnGround = false; - } + m_bOnGround = false; } } - else - { - // Push out entity. - BLOCKTYPE GotBlock; + } + else + { + // Push out entity. + BLOCKTYPE GotBlock; - static const struct - { - int x, y, z; - } gCrossCoords[] = - { - { 1, 0, 0}, - {-1, 0, 0}, - { 0, 0, 1}, - { 0, 0, -1}, - } ; - - bool IsNoAirSurrounding = true; - for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) + static const struct + { + int x, y, z; + } gCrossCoords[] = + { + { 1, 0, 0}, + {-1, 0, 0}, + { 0, 0, 1}, + { 0, 0, -1}, + } ; + + bool IsNoAirSurrounding = true; + for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) + { + if (!a_Chunk.UnboundedRelGetBlockType(RelBlockX + gCrossCoords[i].x, BlockY, RelBlockZ + gCrossCoords[i].z, GotBlock)) { - if (!NextChunk->UnboundedRelGetBlockType(RelBlockX + gCrossCoords[i].x, BlockY, RelBlockZ + gCrossCoords[i].z, GotBlock)) - { - // The pickup is too close to an unloaded chunk, bail out of any physics handling - return; - } - if (!cBlockInfo::IsSolid(GotBlock)) - { - NextPos.x += gCrossCoords[i].x; - NextPos.z += gCrossCoords[i].z; - IsNoAirSurrounding = false; - break; - } - } // for i - gCrossCoords[] - - if (IsNoAirSurrounding) + // The pickup is too close to an unloaded chunk, bail out of any physics handling + return; + } + if (!cBlockInfo::IsSolid(GotBlock)) { - NextPos.y += 0.5; + NextPos.x += gCrossCoords[i].x; + NextPos.z += gCrossCoords[i].z; + IsNoAirSurrounding = false; + break; } + } // for i - gCrossCoords[] + + if (IsNoAirSurrounding) + { + NextPos.y += 0.5; + } - m_bOnGround = true; + m_bOnGround = true; - /* - // DEBUG: - LOGD("Entity #%d (%s) is inside a block at {%d, %d, %d}", - m_UniqueID, GetClass(), BlockX, BlockY, BlockZ - ); - */ - } + /* + // DEBUG: + LOGD("Entity #%d (%s) is inside a block at {%d, %d, %d}", + m_UniqueID, GetClass(), BlockX, BlockY, BlockZ + ); + */ + } - if (!m_bOnGround) + if (!m_bOnGround) + { + float fallspeed; + if (IsBlockWater(BlockIn)) { - float fallspeed; - if (IsBlockWater(BlockIn)) - { - fallspeed = m_Gravity * a_Dt / 3; // Fall 3x slower in water. - } - else if (BlockIn == E_BLOCK_COBWEB) - { - NextSpeed.y *= 0.05; // Reduce overall falling speed - fallspeed = 0; // No falling. - } - else - { - // Normal gravity - fallspeed = m_Gravity * a_Dt; - } - NextSpeed.y += fallspeed; + fallspeed = m_Gravity * a_Dt / 3; // Fall 3x slower in water. + } + else if (BlockIn == E_BLOCK_COBWEB) + { + NextSpeed.y *= 0.05; // Reduce overall falling speed + fallspeed = 0; // No falling. } else { - // Friction - if (NextSpeed.SqrLength() > 0.0004f) + // Normal gravity + fallspeed = m_Gravity * a_Dt; + } + NextSpeed.y += fallspeed; + } + else + { + // Friction + if (NextSpeed.SqrLength() > 0.0004f) + { + NextSpeed.x *= 0.7f / (1 + a_Dt); + if (fabs(NextSpeed.x) < 0.05) { - NextSpeed.x *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.x) < 0.05) - { - NextSpeed.x = 0; - } - NextSpeed.z *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.z) < 0.05) - { - NextSpeed.z = 0; - } + NextSpeed.x = 0; + } + NextSpeed.z *= 0.7f / (1 + a_Dt); + if (fabs(NextSpeed.z) < 0.05) + { + NextSpeed.z = 0; } } + } - // Adjust X and Z speed for COBWEB temporary. This speed modification should be handled inside block handlers since we - // might have different speed modifiers according to terrain. - if (BlockIn == E_BLOCK_COBWEB) - { - NextSpeed.x *= 0.25; - NextSpeed.z *= 0.25; - } + // Adjust X and Z speed for COBWEB temporary. This speed modification should be handled inside block handlers since we + // might have different speed modifiers according to terrain. + if (BlockIn == E_BLOCK_COBWEB) + { + NextSpeed.x *= 0.25; + NextSpeed.z *= 0.25; + } - //Get water direction - Direction WaterDir = m_World->GetWaterSimulator()->GetFlowingDirection(BlockX, BlockY, BlockZ); + //Get water direction + Direction WaterDir = m_World->GetWaterSimulator()->GetFlowingDirection(BlockX, BlockY, BlockZ); - m_WaterSpeed *= 0.9f; //Reduce speed each tick + m_WaterSpeed *= 0.9f; //Reduce speed each tick - switch(WaterDir) - { - case X_PLUS: - m_WaterSpeed.x = 0.2f; - m_bOnGround = false; - break; - case X_MINUS: - m_WaterSpeed.x = -0.2f; - m_bOnGround = false; - break; - case Z_PLUS: - m_WaterSpeed.z = 0.2f; - m_bOnGround = false; - break; - case Z_MINUS: - m_WaterSpeed.z = -0.2f; - m_bOnGround = false; - break; - - default: + switch(WaterDir) + { + case X_PLUS: + m_WaterSpeed.x = 0.2f; + m_bOnGround = false; break; - } + case X_MINUS: + m_WaterSpeed.x = -0.2f; + m_bOnGround = false; + break; + case Z_PLUS: + m_WaterSpeed.z = 0.2f; + m_bOnGround = false; + break; + case Z_MINUS: + m_WaterSpeed.z = -0.2f; + m_bOnGround = false; + break; + + default: + break; + } - if (fabs(m_WaterSpeed.x) < 0.05) - { - m_WaterSpeed.x = 0; - } + if (fabs(m_WaterSpeed.x) < 0.05) + { + m_WaterSpeed.x = 0; + } - if (fabs(m_WaterSpeed.z) < 0.05) - { - m_WaterSpeed.z = 0; - } + if (fabs(m_WaterSpeed.z) < 0.05) + { + m_WaterSpeed.z = 0; + } - NextSpeed += m_WaterSpeed; + NextSpeed += m_WaterSpeed; - if( NextSpeed.SqrLength() > 0.f ) + if( NextSpeed.SqrLength() > 0.f ) + { + cTracer Tracer( GetWorld() ); + int Ret = Tracer.Trace( NextPos, NextSpeed, 2 ); + if( Ret ) // Oh noez! we hit something { - cTracer Tracer( GetWorld() ); - int Ret = Tracer.Trace( NextPos, NextSpeed, 2 ); - if( Ret ) // Oh noez! we hit something + // Set to hit position + if( (Tracer.RealHit - NextPos).SqrLength() <= ( NextSpeed * a_Dt ).SqrLength() ) { - // Set to hit position - if( (Tracer.RealHit - NextPos).SqrLength() <= ( NextSpeed * a_Dt ).SqrLength() ) + if( Ret == 1 ) { - if( Ret == 1 ) + if( Tracer.HitNormal.x != 0.f ) NextSpeed.x = 0.f; + if( Tracer.HitNormal.y != 0.f ) NextSpeed.y = 0.f; + if( Tracer.HitNormal.z != 0.f ) NextSpeed.z = 0.f; + + if( Tracer.HitNormal.y > 0 ) // means on ground { - if( Tracer.HitNormal.x != 0.f ) NextSpeed.x = 0.f; - if( Tracer.HitNormal.y != 0.f ) NextSpeed.y = 0.f; - if( Tracer.HitNormal.z != 0.f ) NextSpeed.z = 0.f; - - if( Tracer.HitNormal.y > 0 ) // means on ground - { - m_bOnGround = true; - } + m_bOnGround = true; } - NextPos.Set(Tracer.RealHit.x,Tracer.RealHit.y,Tracer.RealHit.z); - NextPos.x += Tracer.HitNormal.x * 0.3f; - NextPos.y += Tracer.HitNormal.y * 0.05f; // Any larger produces entity vibration-upon-the-spot - NextPos.z += Tracer.HitNormal.z * 0.3f; - } - else - { - NextPos += (NextSpeed * a_Dt); } + NextPos.Set(Tracer.RealHit.x,Tracer.RealHit.y,Tracer.RealHit.z); + NextPos.x += Tracer.HitNormal.x * 0.3f; + NextPos.y += Tracer.HitNormal.y * 0.05f; // Any larger produces entity vibration-upon-the-spot + NextPos.z += Tracer.HitNormal.z * 0.3f; } else { - // We didn't hit anything, so move =] NextPos += (NextSpeed * a_Dt); } } - BlockX = (int) floor(NextPos.x); - BlockZ = (int) floor(NextPos.z); - NextChunk = NextChunk->GetNeighborChunk(BlockX,BlockZ); - // See if we can commit our changes. If not, we will discard them. - if (NextChunk != NULL) + else { - if (NextPos.x != GetPosX()) SetPosX(NextPos.x); - if (NextPos.y != GetPosY()) SetPosY(NextPos.y); - if (NextPos.z != GetPosZ()) SetPosZ(NextPos.z); - if (NextSpeed.x != GetSpeedX()) SetSpeedX(NextSpeed.x); - if (NextSpeed.y != GetSpeedY()) SetSpeedY(NextSpeed.y); - if (NextSpeed.z != GetSpeedZ()) SetSpeedZ(NextSpeed.z); + // We didn't hit anything, so move =] + NextPos += (NextSpeed * a_Dt); } } + + BlockX = (int) floor(NextPos.x); + BlockZ = (int) floor(NextPos.z); + + cChunk * NextChunk = a_Chunk.GetNeighborChunk(BlockX, BlockZ); + // See if we can commit our changes. If not, we will discard them. + if (NextChunk != NULL) + { + if (NextPos.x != GetPosX()) SetPosX(NextPos.x); + if (NextPos.y != GetPosY()) SetPosY(NextPos.y); + if (NextPos.z != GetPosZ()) SetPosZ(NextPos.z); + if (NextSpeed.x != GetSpeedX()) SetSpeedX(NextSpeed.x); + if (NextSpeed.y != GetSpeedY()) SetSpeedY(NextSpeed.y); + if (NextSpeed.z != GetSpeedZ()) SetSpeedZ(NextSpeed.z); + } } @@ -815,14 +821,13 @@ void cEntity::TickBurning(cChunk & a_Chunk) { int RelX = x; int RelZ = z; - cChunk * CurChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RelX, RelZ); - if (CurChunk == NULL) - { - continue; - } + for (int y = MinY; y <= MaxY; y++) { - switch (CurChunk->GetBlock(RelX, y, RelZ)) + BLOCKTYPE Block; + a_Chunk.UnboundedRelGetBlockType(RelX, y, RelZ, Block); + + switch (Block) { case E_BLOCK_FIRE: { @@ -922,7 +927,7 @@ void cEntity::TickInVoid(cChunk & a_Chunk) void cEntity::SetSwimState(cChunk & a_Chunk) { - int RelY = (int)floor(m_LastPosY + 0.1); + int RelY = (int)floor(GetPosY() + 0.1); if ((RelY < 0) || (RelY >= cChunkDef::Height - 1)) { m_IsSwimming = false; @@ -931,11 +936,10 @@ void cEntity::SetSwimState(cChunk & a_Chunk) } BLOCKTYPE BlockIn; - int RelX = (int)floor(m_LastPosX) - a_Chunk.GetPosX() * cChunkDef::Width; - int RelZ = (int)floor(m_LastPosZ) - a_Chunk.GetPosZ() * cChunkDef::Width; + int RelX = POSX_TOINT - a_Chunk.GetPosX() * cChunkDef::Width; + int RelZ = POSZ_TOINT - a_Chunk.GetPosZ() * cChunkDef::Width; // Check if the player is swimming: - // Use Unbounded, because we're being called *after* processing super::Tick(), which could have changed our chunk if (!a_Chunk.UnboundedRelGetBlockType(RelX, RelY, RelZ, BlockIn)) { // This sometimes happens on Linux machines diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index b3b1cef83..ee3f25cd8 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -119,6 +119,7 @@ public: BURN_TICKS = 200, ///< How long to keep an entity burning after it has stood in lava / fire MAX_AIR_LEVEL = 300, ///< Maximum air an entity can have DROWNING_TICKS = 20, ///< Number of ticks per heart of damage + VOID_BOUNDARY = -46 ///< At what position Y to begin applying void damage } ; cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height); diff --git a/src/Entities/FallingBlock.cpp b/src/Entities/FallingBlock.cpp index 9fcd9ac80..a66c7e4ae 100644 --- a/src/Entities/FallingBlock.cpp +++ b/src/Entities/FallingBlock.cpp @@ -33,20 +33,16 @@ void cFallingBlock::SpawnOn(cClientHandle & a_ClientHandle) void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk) { - float MilliDt = a_Dt * 0.001f; - AddSpeedY(MilliDt * -9.8f); - AddPosY(GetSpeedY() * MilliDt); - // GetWorld()->BroadcastTeleportEntity(*this); // Test position - int BlockX = m_OriginalPosition.x; + int BlockX = POSX_TOINT; int BlockY = (int)(GetPosY() - 0.5); - int BlockZ = m_OriginalPosition.z; + int BlockZ = POSZ_TOINT; if (BlockY < 0) { // Fallen out of this world, just continue falling until out of sight, then destroy: - if (BlockY < 100) + if (BlockY < VOID_BOUNDARY) { Destroy(true); } @@ -86,6 +82,15 @@ void cFallingBlock::Tick(float a_Dt, cChunk & a_Chunk) Destroy(true); return; } + + float MilliDt = a_Dt * 0.001f; + AddSpeedY(MilliDt * -9.8f); + AddPosition(GetSpeed() * MilliDt); + + if ((GetSpeedX() != 0) || (GetSpeedZ() != 0)) + { + BroadcastMovementUpdate(); + } } diff --git a/src/Items/ItemLighter.h b/src/Items/ItemLighter.h index cc7daeb08..a828cd4fa 100644 --- a/src/Items/ItemLighter.h +++ b/src/Items/ItemLighter.h @@ -34,8 +34,8 @@ public: { // Activate the TNT: a_World->BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); - a_World->SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 4); // 4 seconds to boom a_World->SetBlock(a_BlockX,a_BlockY,a_BlockZ, E_BLOCK_AIR, 0); + a_World->SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 4); // 4 seconds to boom break; } default: diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 0640227b0..c9305b8ff 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -838,8 +838,8 @@ void cIncrementalRedstoneSimulator::HandleTNT(int a_BlockX, int a_BlockY, int a_ if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { m_World.BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); - m_World.SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 4); // 4 seconds to boom m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + m_World.SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 4); // 4 seconds to boom } } diff --git a/src/World.cpp b/src/World.cpp index ffdae2a37..d6b88f187 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1696,7 +1696,11 @@ void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTim UNUSED(a_InitialVelocityCoeff); cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTimeInSec); TNT->Initialize(this); - // TODO: Add a bit of speed in horiz and vert axes, based on the a_InitialVelocityCoeff + TNT->SetSpeed( + a_InitialVelocityCoeff * (GetTickRandomNumber(2) - 1), /** -1, 0, 1 */ + a_InitialVelocityCoeff * 2, + a_InitialVelocityCoeff * (GetTickRandomNumber(2) - 1) + ); } -- cgit v1.2.3 From 99b9e6dce5ee49c1062074ce9f6d0669b2b265cc Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 6 Mar 2014 11:08:47 +0100 Subject: Broadcast the Equipped Item, if the Slot is changed. --- src/Inventory.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Inventory.cpp b/src/Inventory.cpp index 7f434adfd..c7c089d5f 100644 --- a/src/Inventory.cpp +++ b/src/Inventory.cpp @@ -204,6 +204,12 @@ void cInventory::SetSlot(int a_SlotNum, const cItem & a_Item) return; } Grid->SetSlot(GridSlotNum, a_Item); + + // Broadcast the Equipped Item, if the Slot is changed. + if ((Grid == &m_HotbarSlots) && (m_EquippedSlotNum == (a_SlotNum - invHotbarOffset))) + { + m_Owner.GetWorld()->BroadcastEntityEquipment(m_Owner, 0, a_Item, m_Owner.GetClientHandle()); + } } -- cgit v1.2.3 From 1c7a580e520ba6c28936e46d36abba658bd477b1 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 6 Mar 2014 13:35:53 +0100 Subject: Fix comment --- src/Blocks/WorldInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index c38ffc6db..e59b00eff 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -28,6 +28,6 @@ public: /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0; - /** If there is a block entity at the specified coords, sends it to the client specified */ + /** Sends the block on those coords to the player */ virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0; }; -- cgit v1.2.3 From 787a71929cd4095681b37acf81332b7b9c3ddf89 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 7 Mar 2014 01:30:34 +0100 Subject: Add Flower Pots --- src/Bindings/ManualBindings.cpp | 2 + src/BlockEntities/BlockEntity.cpp | 2 + src/BlockEntities/FlowerPotEntity.cpp | 134 ++++++++++++++++++++++++++++++++ src/BlockEntities/FlowerPotEntity.h | 74 ++++++++++++++++++ src/Blocks/BlockFlowerPot.h | 83 +------------------- src/Chunk.cpp | 35 +++++++++ src/Chunk.h | 7 +- src/ChunkMap.cpp | 18 +++++ src/ChunkMap.h | 5 ++ src/Protocol/Protocol17x.cpp | 16 +++- src/World.cpp | 9 +++ src/World.h | 9 ++- src/WorldStorage/NBTChunkSerializer.cpp | 15 ++++ src/WorldStorage/NBTChunkSerializer.h | 2 + src/WorldStorage/WSSAnvil.cpp | 36 +++++++++ src/WorldStorage/WSSAnvil.h | 1 + src/WorldStorage/WSSCompact.cpp | 40 +++++++++- 17 files changed, 401 insertions(+), 87 deletions(-) create mode 100644 src/BlockEntities/FlowerPotEntity.cpp create mode 100644 src/BlockEntities/FlowerPotEntity.h diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 9fbc2e842..3570b2c1e 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -23,6 +23,7 @@ #include "../BlockEntities/HopperEntity.h" #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/MobHeadEntity.h" +#include "../BlockEntities/FlowerPotEntity.h" #include "md5/md5.h" #include "../LineBlockTracer.h" #include "../WorldStorage/SchematicFileSerializer.h" @@ -2820,6 +2821,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "DoWithNoteBlockAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithCommandBlockAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithMobHeadBlockAt", tolua_DoWithXYZ); + tolua_function(tolua_S, "DoWithFlowerPotAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>); tolua_function(tolua_S, "ForEachBlockEntityInChunk", tolua_ForEachInChunk); diff --git a/src/BlockEntities/BlockEntity.cpp b/src/BlockEntities/BlockEntity.cpp index 57ad83de9..b42318c2f 100644 --- a/src/BlockEntities/BlockEntity.cpp +++ b/src/BlockEntities/BlockEntity.cpp @@ -10,6 +10,7 @@ #include "DispenserEntity.h" #include "DropperEntity.h" #include "EnderChestEntity.h" +#include "FlowerPotEntity.h" #include "FurnaceEntity.h" #include "HopperEntity.h" #include "JukeboxEntity.h" @@ -30,6 +31,7 @@ cBlockEntity * cBlockEntity::CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE case E_BLOCK_DISPENSER: return new cDispenserEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_DROPPER: return new cDropperEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_ENDER_CHEST: return new cEnderChestEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); + case E_BLOCK_FLOWER_POT: return new cFlowerPotEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_HEAD: return new cMobHeadEntity (a_BlockX, a_BlockY, a_BlockZ, a_World); case E_BLOCK_LIT_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World); case E_BLOCK_FURNACE: return new cFurnaceEntity (a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_World); diff --git a/src/BlockEntities/FlowerPotEntity.cpp b/src/BlockEntities/FlowerPotEntity.cpp new file mode 100644 index 000000000..87bf8b921 --- /dev/null +++ b/src/BlockEntities/FlowerPotEntity.cpp @@ -0,0 +1,134 @@ + +// FlowerPotEntity.cpp + +// Implements the cFlowerPotEntity class representing a single sign in the world + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules +#include "json/json.h" +#include "FlowerPotEntity.h" +#include "../Entities/Player.h" +#include "../Item.h" + + + + + +cFlowerPotEntity::cFlowerPotEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) : + super(E_BLOCK_FLOWER_POT, a_BlockX, a_BlockY, a_BlockZ, a_World) +{ +} + + + + + +// It don't do anything when 'used' +void cFlowerPotEntity::UsedBy(cPlayer * a_Player) +{ + if (IsItemInPot()) + { + return; + } + + cItem SelectedItem = a_Player->GetInventory().GetEquippedItem(); + if (IsFlower(SelectedItem.m_ItemType, SelectedItem.m_ItemDamage)) + { + m_Item = SelectedItem.CopyOne(); + if (!a_Player->IsGameModeCreative()) + { + a_Player->GetInventory().RemoveOneEquippedItem(); + } + m_World->BroadcastBlockEntity(m_PosX, m_PosY, m_PosZ, a_Player->GetClientHandle()); + } +} + + + + + +void cFlowerPotEntity::SendTo(cClientHandle & a_Client) +{ + a_Client.SendUpdateBlockEntity(*this); +} + + + + + +void cFlowerPotEntity::Destroy(void) +{ + // Drop the contents as pickups: + if (!m_Item.IsEmpty()) + { + ASSERT(m_World != NULL); + cItems Pickups; + Pickups.Add(m_Item); + m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); + + m_Item.Empty(); + } +} + + + + + +bool cFlowerPotEntity::LoadFromJson(const Json::Value & a_Value) +{ + m_PosX = a_Value.get("x", 0).asInt(); + m_PosY = a_Value.get("y", 0).asInt(); + m_PosZ = a_Value.get("z", 0).asInt(); + + m_Item = cItem(); + m_Item.FromJson(a_Value.get("Item", 0)); + + return true; +} + + + + + +void cFlowerPotEntity::SaveToJson(Json::Value & a_Value) +{ + a_Value["x"] = m_PosX; + a_Value["y"] = m_PosY; + a_Value["z"] = m_PosZ; + + Json::Value Item; + m_Item.GetJson(Item); + a_Value["Item"] = Item; +} + + + + + +bool cFlowerPotEntity::IsFlower(short m_ItemType, short m_ItemData) +{ + switch (m_ItemType) + { + case E_BLOCK_DANDELION: + case E_BLOCK_FLOWER: + case E_BLOCK_CACTUS: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_SAPLING: + case E_BLOCK_DEAD_BUSH: + { + return true; + } + case E_BLOCK_TALL_GRASS: + { + return (m_ItemData == (short) 2); + } + default: + { + return false; + } + } +} + + + + diff --git a/src/BlockEntities/FlowerPotEntity.h b/src/BlockEntities/FlowerPotEntity.h new file mode 100644 index 000000000..da3fe9b7e --- /dev/null +++ b/src/BlockEntities/FlowerPotEntity.h @@ -0,0 +1,74 @@ +// FlowerPotEntity.h + +// Declares the cFlowerPotEntity class representing a single sign in the world + + + + + +#pragma once + +#include "BlockEntity.h" + +class cItem; + + + + + +namespace Json +{ + class Value; +} + + + + + +// tolua_begin + +class cFlowerPotEntity : + public cBlockEntity +{ + typedef cBlockEntity super; + +public: + + // tolua_end + + /** Creates a new flowerpot entity at the specified block coords. a_World may be NULL */ + cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World); + + bool LoadFromJson( const Json::Value& a_Value ); + virtual void SaveToJson(Json::Value& a_Value ) override; + + virtual void Destroy(void) override; + + // tolua_begin + + /** Is a flower in the pot? */ + bool IsItemInPot(void) { return !m_Item.IsEmpty(); } + + /** Get the item in the flower pot */ + cItem GetItem(void) const { return m_Item; } + + /** Set the item in the flower pot */ + void SetItem(const cItem a_Item) { m_Item = a_Item; } + + // tolua_end + + virtual void UsedBy(cPlayer * a_Player) override; + virtual void SendTo(cClientHandle & a_Client) override; + + static bool IsFlower(short m_ItemType, short m_ItemData); + + static const char * GetClassStatic(void) { return "cFlowerPotEntity"; } + +private: + + cItem m_Item; +} ; // tolua_export + + + + diff --git a/src/Blocks/BlockFlowerPot.h b/src/Blocks/BlockFlowerPot.h index 4de85f629..fc75ef638 100644 --- a/src/Blocks/BlockFlowerPot.h +++ b/src/Blocks/BlockFlowerPot.h @@ -2,101 +2,24 @@ #pragma once #include "BlockHandler.h" +#include "BlockEntity.h" class cBlockFlowerPotHandler : - public cBlockHandler + public cBlockEntityHandler { public: cBlockFlowerPotHandler(BLOCKTYPE a_BlockType) : - cBlockHandler(a_BlockType) + cBlockEntityHandler(a_BlockType) { } - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_ITEM_FLOWER_POT, 1, 0)); - if (a_BlockMeta == 0) - { - return; - } - cItem Plant; - switch (a_BlockMeta) - { - case 1: Plant = cItem(E_BLOCK_RED_ROSE, 1, 0); break; - case 2: Plant = cItem(E_BLOCK_YELLOW_FLOWER, 1, 0); break; - case 3: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_APPLE); break; - case 4: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_CONIFER); break; - case 5: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_BIRCH); break; - case 6: Plant = cItem(E_BLOCK_SAPLING, 1, E_META_SAPLING_JUNGLE); break; - case 7: Plant = cItem(E_BLOCK_RED_MUSHROOM, 1, 0); break; - case 8: Plant = cItem(E_BLOCK_BROWN_MUSHROOM, 1, 0); break; - case 9: Plant = cItem(E_BLOCK_CACTUS, 1, 0); break; - case 10: Plant = cItem(E_BLOCK_DEAD_BUSH, 1, 0); break; - case 11: Plant = cItem(E_BLOCK_TALL_GRASS, 1, E_META_TALL_GRASS_FERN); break; - default: return; - } - a_Pickups.push_back(Plant); - } - - - void OnUse(cWorld * a_World, cWorldInterface * a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) - { - NIBBLETYPE Meta = a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ ); - if (Meta != 0) - { - // Already filled - return; - } - - switch (a_Player->GetEquippedItem().m_ItemType) - { - case E_BLOCK_RED_ROSE: Meta = 1; break; - case E_BLOCK_YELLOW_FLOWER: Meta = 2; break; - case E_BLOCK_SAPLING: - { - switch (a_Player->GetEquippedItem().m_ItemDamage) - { - case E_META_SAPLING_APPLE: Meta = 3; break; - case E_META_SAPLING_CONIFER: Meta = 4; break; - case E_META_SAPLING_BIRCH: Meta = 5; break; - case E_META_SAPLING_JUNGLE: Meta = 6; break; - } - break; - } - case E_BLOCK_RED_MUSHROOM: Meta = 7; break; - case E_BLOCK_BROWN_MUSHROOM: Meta = 8; break; - case E_BLOCK_CACTUS: Meta = 9; break; - case E_BLOCK_DEAD_BUSH: Meta = 10; break; - case E_BLOCK_TALL_GRASS: - { - if (a_Player->GetEquippedItem().m_ItemDamage == E_META_TALL_GRASS_FERN) - { - Meta = 11; - } - else - { - return; - } - break; - } - } - - if (a_Player->GetGameMode() != gmCreative) - { - a_Player->GetInventory().RemoveOneEquippedItem(); - } - a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); - } - - - virtual bool IsUseable(void) override - { - return true; } } ; diff --git a/src/Chunk.cpp b/src/Chunk.cpp index a75828461..b5b776147 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -20,6 +20,7 @@ #include "BlockEntities/NoteEntity.h" #include "BlockEntities/SignEntity.h" #include "BlockEntities/MobHeadEntity.h" +#include "BlockEntities/FlowerPotEntity.h" #include "Entities/Pickup.h" #include "Item.h" #include "Noise.h" @@ -1311,6 +1312,7 @@ void cChunk::CreateBlockEntities(void) case E_BLOCK_HEAD: case E_BLOCK_NOTE_BLOCK: case E_BLOCK_JUKEBOX: + case E_BLOCK_FLOWER_POT: { if (!HasBlockEntityAt(x + m_PosX * Width, y + m_PosY * Height, z + m_PosZ * Width)) { @@ -1440,6 +1442,7 @@ void cChunk::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, case E_BLOCK_HEAD: case E_BLOCK_NOTE_BLOCK: case E_BLOCK_JUKEBOX: + case E_BLOCK_FLOWER_POT: { AddBlockEntity(cBlockEntity::CreateByBlockType(a_BlockType, a_BlockMeta, WorldPos.x, WorldPos.y, WorldPos.z, m_World)); break; @@ -2369,6 +2372,38 @@ bool cChunk::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMob +bool cChunk::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback) +{ + // The blockentity list is locked by the parent chunkmap's CS + for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2) + { + ++itr2; + if (((*itr)->GetPosX() != a_BlockX) || ((*itr)->GetPosY() != a_BlockY) || ((*itr)->GetPosZ() != a_BlockZ)) + { + continue; + } + if ((*itr)->GetBlockType() != E_BLOCK_FLOWER_POT) + { + // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out + return false; + } + + // The correct block entity is here, + if (a_Callback.Item((cFlowerPotEntity *)*itr)) + { + return false; + } + return true; + } // for itr - m_BlockEntitites[] + + // Not found: + return false; +} + + + + + bool cChunk::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) { // The blockentity list is locked by the parent chunkmap's CS diff --git a/src/Chunk.h b/src/Chunk.h index c9e9697ca..e8b46f631 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -32,6 +32,7 @@ class cDispenserEntity; class cFurnaceEntity; class cNoteEntity; class cMobHeadEntity; +class cFlowerPotEntity; class cBlockArea; class cPawn; class cPickup; @@ -49,6 +50,7 @@ typedef cItemCallback cFurnaceCallback; typedef cItemCallback cNoteBlockCallback; typedef cItemCallback cCommandBlockCallback; typedef cItemCallback cMobHeadBlockCallback; +typedef cItemCallback cFlowerPotCallback; @@ -253,9 +255,12 @@ public: /** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */ bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); - /** Calls the callback for the mob head block at the specified coords; returns false if there's no mob header block at those coords or callback returns true, returns true if found */ + /** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */ bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback); + /** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */ + bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback); + /** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */ bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index b5795fbaf..7f999fd31 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -2200,6 +2200,24 @@ bool cChunkMap::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c +bool cChunkMap::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback) +{ + int ChunkX, ChunkZ; + int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; + cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk == NULL) && !Chunk->IsValid()) + { + return false; + } + return Chunk->DoWithFlowerPotAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); +} + + + + + bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) { int ChunkX, ChunkZ; diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 9df68c403..6d35b2ebf 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -26,6 +26,7 @@ class cFurnaceEntity; class cNoteEntity; class cCommandBlockEntity; class cMobHeadEntity; +class cFlowerPotEntity; class cPawn; class cPickup; class cChunkDataSerializer; @@ -41,6 +42,7 @@ typedef cItemCallback cChestCallback; typedef cItemCallback cDispenserCallback; typedef cItemCallback cDropperCallback; typedef cItemCallback cDropSpenserCallback; +typedef cItemCallback cFlowerPotCallback; typedef cItemCallback cFurnaceCallback; typedef cItemCallback cNoteBlockCallback; typedef cItemCallback cCommandBlockCallback; @@ -259,6 +261,9 @@ public: /** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */ bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback); // Lua-accessible + /** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */ + bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback); // Lua-accessible + /** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */ bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Lua-accessible diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 992023464..18646254f 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -29,6 +29,7 @@ Implements the 1.7.x protocol classes: #include "../UI/Window.h" #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/MobHeadEntity.h" +#include "../BlockEntities/FlowerPotEntity.h" #include "../CompositeChat.h" @@ -1115,6 +1116,7 @@ void cProtocol172::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity + case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break; } Pkt.WriteByte(Action); @@ -2345,7 +2347,7 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt case E_BLOCK_HEAD: { cMobHeadEntity & MobHeadEntity = (cMobHeadEntity &)a_BlockEntity; - + Writer.AddInt("x", MobHeadEntity.GetPosX()); Writer.AddInt("y", MobHeadEntity.GetPosY()); Writer.AddInt("z", MobHeadEntity.GetPosZ()); @@ -2355,6 +2357,18 @@ void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEnt Writer.AddString("id", "Skull"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though break; } + case E_BLOCK_FLOWER_POT: + { + cFlowerPotEntity & FlowerPotEntity = (cFlowerPotEntity &)a_BlockEntity; + + Writer.AddInt("x", FlowerPotEntity.GetPosX()); + Writer.AddInt("y", FlowerPotEntity.GetPosY()); + Writer.AddInt("z", FlowerPotEntity.GetPosZ()); + Writer.AddInt("Item", (Int32) FlowerPotEntity.GetItem().m_ItemType); + Writer.AddInt("Data", (Int32) FlowerPotEntity.GetItem().m_ItemDamage); + Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though + break; + } default: break; } diff --git a/src/World.cpp b/src/World.cpp index 37c07b398..335c6a00d 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1206,6 +1206,15 @@ bool cWorld::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMob +bool cWorld::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback) +{ + return m_ChunkMap->DoWithFlowerPotAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); +} + + + + + bool cWorld::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) { return m_ChunkMap->GetSignLines(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4); diff --git a/src/World.h b/src/World.h index 93397c014..ee74742c4 100644 --- a/src/World.h +++ b/src/World.h @@ -44,6 +44,7 @@ class cWorldGenerator; // The generator that actually generates the chunks for class cChunkGenerator; // The thread responsible for generating chunks class cChestEntity; class cDispenserEntity; +class cFlowerPotEntity; class cFurnaceEntity; class cNoteEntity; class cMobHeadEntity; @@ -61,6 +62,7 @@ typedef cItemCallback cFurnaceCallback; typedef cItemCallback cNoteBlockCallback; typedef cItemCallback cCommandBlockCallback; typedef cItemCallback cMobHeadBlockCallback; +typedef cItemCallback cFlowerPotCallback; @@ -531,10 +533,13 @@ public: /** Calls the callback for the command block at the specified coords; returns false if there's no command block at those coords or callback returns true, returns true if found */ bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Exported in ManualBindings.cpp - + /** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */ bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback); // Exported in ManualBindings.cpp - + + /** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */ + bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback); // Exported in ManualBindings.cpp + /** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */ bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Exported in ManualBindings.cpp diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index c1c659b36..6d0e29958 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -20,6 +20,7 @@ #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/SignEntity.h" #include "../BlockEntities/MobHeadEntity.h" +#include "../BlockEntities/FlowerPotEntity.h" #include "../Entities/Entity.h" #include "../Entities/FallingBlock.h" @@ -275,6 +276,19 @@ void cNBTChunkSerializer::AddMobHeadEntity(cMobHeadEntity * a_MobHead) +void cNBTChunkSerializer::AddFlowerPotEntity(cFlowerPotEntity * a_FlowerPot) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_FlowerPot, "FlowerPot"); + m_Writer.AddInt ("Item", (Int32) a_FlowerPot->GetItem().m_ItemType); + m_Writer.AddInt ("Data", (Int32) a_FlowerPot->GetItem().m_ItemDamage); + m_Writer.EndCompound(); +} + + + + + void cNBTChunkSerializer::AddBasicEntity(cEntity * a_Entity, const AString & a_ClassName) { m_Writer.AddString("id", a_ClassName); @@ -687,6 +701,7 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity) case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break; case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break; case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break; + case E_BLOCK_FLOWER_POT: AddFlowerPotEntity ((cFlowerPotEntity *) a_Entity); break; case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break; case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break; case E_BLOCK_SIGN_POST: diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 5f9e16ed1..8a9e18413 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -30,6 +30,7 @@ class cJukeboxEntity; class cNoteEntity; class cSignEntity; class cMobHeadEntity; +class cFlowerPotEntity; class cFallingBlock; class cMinecart; class cMinecartWithChest; @@ -96,6 +97,7 @@ protected: void AddSignEntity (cSignEntity * a_Sign); void AddMobHeadEntity (cMobHeadEntity * a_MobHead); void AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock); + void AddFlowerPotEntity(cFlowerPotEntity * a_FlowerPot); // Entities: void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 05332d23d..680f2458f 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -25,6 +25,7 @@ #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/SignEntity.h" #include "../BlockEntities/MobHeadEntity.h" +#include "../BlockEntities/FlowerPotEntity.h" #include "../Mobs/Monster.h" @@ -578,6 +579,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con { LoadDropperFromNBT(a_BlockEntities, a_NBT, Child); } + else if (strncmp(a_NBT.GetData(sID), "FlowerPot", a_NBT.GetDataLength(sID)) == 0) + { + LoadFlowerPotFromNBT(a_BlockEntities, a_NBT, Child); + } else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0) { LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child, a_BlockTypes, a_BlockMetas); @@ -760,6 +765,37 @@ void cWSSAnvil::LoadDropperFromNBT(cBlockEntityList & a_BlockEntities, const cPa +void cWSSAnvil::LoadFlowerPotFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); + int x, y, z; + if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + { + return; + } + std::auto_ptr FlowerPot(new cFlowerPotEntity(x, y, z, m_World)); + short ItemType = 0, ItemData = 0; + + int currentLine = a_NBT.FindChildByName(a_TagIdx, "Item"); + if (currentLine >= 0) + { + ItemType = (short) a_NBT.GetInt(currentLine); + } + + currentLine = a_NBT.FindChildByName(a_TagIdx, "Data"); + if (currentLine >= 0) + { + ItemData = (short) a_NBT.GetInt(currentLine); + } + + FlowerPot->SetItem(cItem(ItemType, 1, ItemData)); + a_BlockEntities.push_back(FlowerPot.release()); +} + + + + + void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas) { ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 4acf3f2a1..b26345b13 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -135,6 +135,7 @@ protected: void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadFlowerPotFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadFurnaceFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas); void LoadHopperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadJukeboxFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index 4c0684dd8..5e49e4909 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -12,8 +12,10 @@ #include "../BlockEntities/ChestEntity.h" #include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/DispenserEntity.h" +#include "../BlockEntities/FlowerPotEntity.h" #include "../BlockEntities/FurnaceEntity.h" #include "../BlockEntities/JukeboxEntity.h" +#include "../BlockEntities/MobHeadEntity.h" #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/SignEntity.h" @@ -75,12 +77,14 @@ void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity) case E_BLOCK_CHEST: SaveInto = "Chests"; break; case E_BLOCK_DISPENSER: SaveInto = "Dispensers"; break; case E_BLOCK_DROPPER: SaveInto = "Droppers"; break; + case E_BLOCK_FLOWER_POT: SaveInto = "FlowerPots"; break; case E_BLOCK_FURNACE: SaveInto = "Furnaces"; break; case E_BLOCK_SIGN_POST: SaveInto = "Signs"; break; case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break; case E_BLOCK_NOTE_BLOCK: SaveInto = "Notes"; break; case E_BLOCK_JUKEBOX: SaveInto = "Jukeboxes"; break; case E_BLOCK_COMMAND_BLOCK: SaveInto = "CommandBlocks"; break; + case E_BLOCK_HEAD: SaveInto = "MobHeads"; break; default: { @@ -298,6 +302,21 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En } } // for itr - AllDispensers[] + // Load Flowerpots: + Json::Value AllFlowerPots = a_Value.get("FlowerPots", Json::nullValue); + for (Json::Value::iterator itr = AllFlowerPots.begin(); itr != AllFlowerPots.end(); ++itr) + { + std::auto_ptr FlowerPotEntity(new cFlowerPotEntity(0, 0, 0, a_World)); + if (!FlowerPotEntity->LoadFromJson(*itr)) + { + LOGWARNING("ERROR READING FLOWERPOT FROM JSON!" ); + } + else + { + a_BlockEntities.push_back(FlowerPotEntity.release()); + } + } // for itr - AllFlowerPots[] + // Load furnaces: Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue); for (Json::Value::iterator itr = AllFurnaces.begin(); itr != AllFurnaces.end(); ++itr) @@ -331,7 +350,7 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En // Load note blocks: Json::Value AllNotes = a_Value.get("Notes", Json::nullValue); - for( Json::Value::iterator itr = AllNotes.begin(); itr != AllNotes.end(); ++itr ) + for (Json::Value::iterator itr = AllNotes.begin(); itr != AllNotes.end(); ++itr) { std::auto_ptr NoteEntity(new cNoteEntity(0, 0, 0, a_World)); if (!NoteEntity->LoadFromJson(*itr)) @@ -346,7 +365,7 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En // Load jukeboxes: Json::Value AllJukeboxes = a_Value.get("Jukeboxes", Json::nullValue); - for( Json::Value::iterator itr = AllJukeboxes.begin(); itr != AllJukeboxes.end(); ++itr ) + for (Json::Value::iterator itr = AllJukeboxes.begin(); itr != AllJukeboxes.end(); ++itr) { std::auto_ptr JukeboxEntity(new cJukeboxEntity(0, 0, 0, a_World)); if (!JukeboxEntity->LoadFromJson(*itr)) @@ -361,7 +380,7 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En // Load command blocks: Json::Value AllCommandBlocks = a_Value.get("CommandBlocks", Json::nullValue); - for( Json::Value::iterator itr = AllCommandBlocks.begin(); itr != AllCommandBlocks.end(); ++itr ) + for (Json::Value::iterator itr = AllCommandBlocks.begin(); itr != AllCommandBlocks.end(); ++itr) { std::auto_ptr CommandBlockEntity(new cCommandBlockEntity(0, 0, 0, a_World)); if (!CommandBlockEntity->LoadFromJson(*itr)) @@ -373,6 +392,21 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En a_BlockEntities.push_back(CommandBlockEntity.release()); } } // for itr - AllCommandBlocks[] + + // Load mob heads: + Json::Value AllMobHeads = a_Value.get("MobHeads", Json::nullValue); + for (Json::Value::iterator itr = AllMobHeads.begin(); itr != AllMobHeads.end(); ++itr) + { + std::auto_ptr MobHeadEntity(new cMobHeadEntity(0, 0, 0, a_World)); + if (!MobHeadEntity->LoadFromJson(*itr)) + { + LOGWARNING("ERROR READING MOB HEAD FROM JSON!" ); + } + else + { + a_BlockEntities.push_back(MobHeadEntity.release()); + } + } // for itr - AllMobHeads[] } -- cgit v1.2.3 From 97d803e34f51470774a6bfc2232cae0b041a1aa0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 7 Mar 2014 09:17:13 +0100 Subject: Added cBlockArea serialization to string. Fixes #665. --- src/Bindings/ManualBindings.cpp | 73 +++++++++++++-- src/WorldStorage/SchematicFileSerializer.cpp | 134 +++++++++++++++++++++------ src/WorldStorage/SchematicFileSerializer.h | 33 ++++++- 3 files changed, 202 insertions(+), 38 deletions(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 9fbc2e842..f9d04ce90 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2483,6 +2483,37 @@ static int tolua_cBlockArea_LoadFromSchematicFile(lua_State * tolua_S) +static int tolua_cBlockArea_LoadFromSchematicString(lua_State * tolua_S) +{ + // function cBlockArea::LoadFromSchematicString + // Exported manually because function has been moved to SchematicFileSerilizer.cpp + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cBlockArea") || + !L.CheckParamString (2) || + !L.CheckParamEnd (3) + ) + { + return 0; + } + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) + { + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::LoadFromSchematicFile'", NULL); + return 0; + } + + AString Data; + L.GetStackValue(2, Data); + bool res = cSchematicFileSerializer::LoadFromSchematicString(*self, Data); + tolua_pushboolean(tolua_S, res); + return 1; +} + + + + + static int tolua_cBlockArea_SaveToSchematicFile(lua_State * tolua_S) { // function cBlockArea::SaveToSchematicFile @@ -2512,6 +2543,34 @@ static int tolua_cBlockArea_SaveToSchematicFile(lua_State * tolua_S) +static int tolua_cBlockArea_SaveToSchematicString(lua_State * tolua_S) +{ + // function cBlockArea::SaveToSchematicString + // Exported manually because function has been moved to SchematicFileSerilizer.cpp + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cBlockArea") || + !L.CheckParamEnd (2) + ) + { + return 0; + } + cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL); + if (self == NULL) + { + tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::SaveToSchematicFile'", NULL); + return 0; + } + + AString Data = cSchematicFileSerializer::SaveToSchematicString(*self); + L.Push(Data); + return 1; +} + + + + + static int tolua_cCompositeChat_AddRunCommandPart(lua_State * tolua_S) { // function cCompositeChat:AddRunCommandPart(Message, Command, [Style]) @@ -2775,12 +2834,14 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cBlockArea"); - tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cBlockArea_GetBlockTypeMeta); - tolua_function(tolua_S, "GetOrigin", tolua_cBlockArea_GetOrigin); - tolua_function(tolua_S, "GetRelBlockTypeMeta", tolua_cBlockArea_GetRelBlockTypeMeta); - tolua_function(tolua_S, "GetSize", tolua_cBlockArea_GetSize); - tolua_function(tolua_S, "LoadFromSchematicFile", tolua_cBlockArea_LoadFromSchematicFile); - tolua_function(tolua_S, "SaveToSchematicFile", tolua_cBlockArea_SaveToSchematicFile); + tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cBlockArea_GetBlockTypeMeta); + tolua_function(tolua_S, "GetOrigin", tolua_cBlockArea_GetOrigin); + tolua_function(tolua_S, "GetRelBlockTypeMeta", tolua_cBlockArea_GetRelBlockTypeMeta); + tolua_function(tolua_S, "GetSize", tolua_cBlockArea_GetSize); + tolua_function(tolua_S, "LoadFromSchematicFile", tolua_cBlockArea_LoadFromSchematicFile); + tolua_function(tolua_S, "LoadFromSchematicString", tolua_cBlockArea_LoadFromSchematicString); + tolua_function(tolua_S, "SaveToSchematicFile", tolua_cBlockArea_SaveToSchematicFile); + tolua_function(tolua_S, "SaveToSchematicString", tolua_cBlockArea_SaveToSchematicString); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cCompositeChat"); diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index 45fd967bd..a6ae8d8e0 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -1,10 +1,18 @@ +// SchematicFileSerializer.cpp + +// Implements the cSchematicFileSerializer class representing the interface to load and save cBlockArea to a .schematic file + #include "Globals.h" #include "OSSupport/GZipFile.h" #include "FastNBT.h" - #include "SchematicFileSerializer.h" +#include "../StringCompression.h" + + + + bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName) { @@ -40,48 +48,51 @@ bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, c -bool cSchematicFileSerializer::SaveToSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName) +bool cSchematicFileSerializer::LoadFromSchematicString(cBlockArea & a_BlockArea, const AString & a_SchematicData) { - cFastNBTWriter Writer("Schematic"); - Writer.AddShort("Width", a_BlockArea.m_SizeX); - Writer.AddShort("Height", a_BlockArea.m_SizeY); - Writer.AddShort("Length", a_BlockArea.m_SizeZ); - Writer.AddString("Materials", "Alpha"); - if (a_BlockArea.HasBlockTypes()) + // Uncompress the data: + AString UngzippedData; + if (UncompressStringGZIP(a_SchematicData.data(), a_SchematicData.size(), UngzippedData) != Z_OK) { - Writer.AddByteArray("Blocks", (const char *)a_BlockArea.m_BlockTypes, a_BlockArea.GetBlockCount()); - } - else - { - AString Dummy(a_BlockArea.GetBlockCount(), 0); - Writer.AddByteArray("Blocks", Dummy.data(), Dummy.size()); + LOG("%s: Cannot unGZip the schematic data.", __FUNCTION__); + return false; } - if (a_BlockArea.HasBlockMetas()) + + // Parse the NBT: + cParsedNBT NBT(UngzippedData.data(), UngzippedData.size()); + if (!NBT.IsValid()) { - Writer.AddByteArray("Data", (const char *)a_BlockArea.m_BlockMetas, a_BlockArea.GetBlockCount()); + LOG("%s: Cannot parse the NBT in the schematic data.", __FUNCTION__); + return false; } - else + + return LoadFromSchematicNBT(a_BlockArea, NBT); +} + + + + + +bool cSchematicFileSerializer::SaveToSchematicFile(const cBlockArea & a_BlockArea, const AString & a_FileName) +{ + // Serialize into NBT data: + AString NBT = SaveToSchematicNBT(a_BlockArea); + if (NBT.empty()) { - AString Dummy(a_BlockArea.GetBlockCount(), 0); - Writer.AddByteArray("Data", Dummy.data(), Dummy.size()); + LOG("%s: Cannot serialize the area into an NBT representation for file \"%s\".", __FUNCTION__, a_FileName.c_str()); + return false; } - // TODO: Save entities and block entities - Writer.BeginList("Entities", TAG_Compound); - Writer.EndList(); - Writer.BeginList("TileEntities", TAG_Compound); - Writer.EndList(); - Writer.Finish(); // Save to file cGZipFile File; if (!File.Open(a_FileName, cGZipFile::fmWrite)) { - LOG("Cannot open file \"%s\" for writing.", a_FileName.c_str()); + LOG("%s: Cannot open file \"%s\" for writing.", __FUNCTION__, a_FileName.c_str()); return false; } - if (!File.Write(Writer.GetResult())) + if (!File.Write(NBT)) { - LOG("Cannot write data to file \"%s\".", a_FileName.c_str()); + LOG("%s: Cannot write data to file \"%s\".", __FUNCTION__, a_FileName.c_str()); return false; } return true; @@ -92,6 +103,31 @@ bool cSchematicFileSerializer::SaveToSchematicFile(cBlockArea & a_BlockArea, con +AString cSchematicFileSerializer::SaveToSchematicString(const cBlockArea & a_BlockArea) +{ + // Serialize into NBT data: + AString NBT = SaveToSchematicNBT(a_BlockArea); + if (NBT.empty()) + { + LOG("%s: Cannot serialize the area into an NBT representation.", __FUNCTION__); + return false; + } + + // Gzip the data: + AString Compressed; + int res = CompressStringGZIP(NBT.data(), NBT.size(), Compressed); + if (res != Z_OK) + { + LOG("%s: Cannot Gzip the area data NBT representation: %d", __FUNCTION__, res); + return false; + } + return Compressed; +} + + + + + bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cParsedNBT & a_NBT) { int TMaterials = a_NBT.FindChildByName(a_NBT.GetRoot(), "Materials"); @@ -170,3 +206,45 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP } + + + +AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockArea) +{ + cFastNBTWriter Writer("Schematic"); + Writer.AddShort("Width", a_BlockArea.m_SizeX); + Writer.AddShort("Height", a_BlockArea.m_SizeY); + Writer.AddShort("Length", a_BlockArea.m_SizeZ); + Writer.AddString("Materials", "Alpha"); + if (a_BlockArea.HasBlockTypes()) + { + Writer.AddByteArray("Blocks", (const char *)a_BlockArea.m_BlockTypes, a_BlockArea.GetBlockCount()); + } + else + { + AString Dummy(a_BlockArea.GetBlockCount(), 0); + Writer.AddByteArray("Blocks", Dummy.data(), Dummy.size()); + } + if (a_BlockArea.HasBlockMetas()) + { + Writer.AddByteArray("Data", (const char *)a_BlockArea.m_BlockMetas, a_BlockArea.GetBlockCount()); + } + else + { + AString Dummy(a_BlockArea.GetBlockCount(), 0); + Writer.AddByteArray("Data", Dummy.data(), Dummy.size()); + } + + // TODO: Save entities and block entities + Writer.BeginList("Entities", TAG_Compound); + Writer.EndList(); + Writer.BeginList("TileEntities", TAG_Compound); + Writer.EndList(); + Writer.Finish(); + + return Writer.GetResult(); +} + + + + diff --git a/src/WorldStorage/SchematicFileSerializer.h b/src/WorldStorage/SchematicFileSerializer.h index 9be2e5b57..f6ce1c16c 100644 --- a/src/WorldStorage/SchematicFileSerializer.h +++ b/src/WorldStorage/SchematicFileSerializer.h @@ -1,4 +1,12 @@ +// SchematicFileSerializer.h + +// Declares the cSchematicFileSerializer class representing the interface to load and save cBlockArea to a .schematic file + + + + + #pragma once #include "../BlockArea.h" @@ -13,17 +21,34 @@ class cParsedNBT; + class cSchematicFileSerializer { public: - /// Loads an area from a .schematic file. Returns true if successful + /** Loads an area from a .schematic file. Returns true if successful. */ static bool LoadFromSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName); - /// Saves the area into a .schematic file. Returns true if successful - static bool SaveToSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName); + /** Loads an area from a string containing the .schematic file data. Returns true if successful. */ + static bool LoadFromSchematicString(cBlockArea & a_BlockArea, const AString & a_SchematicData); + + /** Saves the area into a .schematic file. Returns true if successful. */ + static bool SaveToSchematicFile(const cBlockArea & a_BlockArea, const AString & a_FileName); + + /** Saves the area into a string containing the .schematic file data. + Returns the data, or empty string if failed. */ + static AString SaveToSchematicString(const cBlockArea & a_BlockArea); private: - /// Loads the area from a schematic file uncompressed and parsed into a NBT tree. Returns true if successful. + /** Loads the area from a schematic file uncompressed and parsed into a NBT tree. + Returns true if successful. */ static bool LoadFromSchematicNBT(cBlockArea & a_BlockArea, cParsedNBT & a_NBT); + + /** Saves the area into a NBT representation and returns the NBT data as a string. + Returns an empty string if failed. */ + static AString SaveToSchematicNBT(const cBlockArea & a_BlockArea); }; + + + + -- cgit v1.2.3 From 166ab59582d90194a6fcd6849afe8f2e60d64019 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 7 Mar 2014 09:17:42 +0100 Subject: APIDump: Documented cBlockArea string-serialization functions. --- MCServer/Plugins/APIDump/APIDesc.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 94cdd0063..30ce4cc2b 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -134,6 +134,7 @@ g_APIDesc = HasBlockSkyLights = { Params = "", Return = "bool", Notes = "Returns true if current datatypes include skylight" }, HasBlockTypes = { Params = "", Return = "bool", Notes = "Returns true if current datatypes include block types" }, LoadFromSchematicFile = { Params = "FileName", Return = "", Notes = "Clears current content and loads new content from the specified schematic file. Returns true if successful. Returns false and logs error if unsuccessful, old content is preserved in such a case." }, + LoadFromSchematicString = { Params = "SchematicData", Return = "", Notes = "Clears current content and loads new content from the specified string (assumed to contain .schematic data). Returns true if successful. Returns false and logs error if unsuccessful, old content is preserved in such a case." }, Merge = { { Params = "BlockAreaSrc, {{Vector3i|RelMinCoords}}, Strategy", Return = "", Notes = "Merges BlockAreaSrc into this object at the specified relative coords, using the specified strategy" }, @@ -161,6 +162,7 @@ g_APIDesc = RotateCW = { Params = "", Return = "", Notes = "Rotates the block area around the Y axis, clockwise (north -> east). Modifies blocks' metas (if present) to match." }, RotateCWNoMeta = { Params = "", Return = "", Notes = "Rotates the block area around the Y axis, clockwise (north -> east). Doesn't modify blocks' metas." }, SaveToSchematicFile = { Params = "FileName", Return = "", Notes = "Saves the current contents to a schematic file. Returns true if successful." }, + SaveToSchematicString = { Params = "", Return = "string", Notes = "Saves the current contents to a string (in a .schematic file format). Returns the data if successful, empty string if failed." }, SetBlockLight = { Params = "BlockX, BlockY, BlockZ, BlockLight", Return = "", Notes = "Sets the blocklight at the specified absolute coords" }, SetBlockMeta = { Params = "BlockX, BlockY, BlockZ, BlockMeta", Return = "", Notes = "Sets the block meta at the specified absolute coords" }, SetBlockSkyLight = { Params = "BlockX, BlockY, BlockZ, SkyLight", Return = "", Notes = "Sets the skylight at the specified absolute coords" }, -- cgit v1.2.3 From f6aaeb74a9bb50488c2c5b5732f43dae4beef15c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 7 Mar 2014 09:18:10 +0100 Subject: Debuggers: Added a test of the cBlockArea string-serialization. --- MCServer/Plugins/Debuggers/Debuggers.lua | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 329a652cd..f99c48242 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -71,6 +71,8 @@ function Initialize(Plugin) -- TestExpatBindings(); -- TestPluginCalls(); + TestBlockAreasString() + return true end; @@ -202,6 +204,42 @@ end +function TestBlockAreasString() + -- Write one area to string, then to file: + local BA1 = cBlockArea() + BA1:Create(5, 5, 5, cBlockArea.baTypes + cBlockArea.baMetas) + BA1:Fill(cBlockArea.baTypes, E_BLOCK_DIAMOND_BLOCK) + BA1:FillRelCuboid(1, 3, 1, 3, 1, 3, cBlockArea.baTypes, E_BLOCK_GOLD_BLOCK) + local Data = BA1:SaveToSchematicString() + if ((type(Data) ~= "string") or (Data == "")) then + LOG("Cannot save schematic to string") + return + end + cFile:CreateFolder("schematics") + local f = io.open("schematics/StringTest.schematic", "w") + f:write(Data) + f:close() + + -- Load a second area from that file: + local BA2 = cBlockArea() + if not(BA2:LoadFromSchematicFile("schematics/StringTest.schematic")) then + LOG("Cannot read schematic from string test file") + return + end + BA2:Clear() + + -- Load another area from a string in that file: + f = io.open("schematics/StringTest.schematic", "r") + Data = f:read("*all") + if not(BA2:LoadFromSchematicString(Data)) then + LOG("Cannot load schematic from string") + end +end + + + + + function TestSQLiteBindings() LOG("Testing SQLite bindings..."); -- cgit v1.2.3 From 31df0268089b931b36d009bcf843a59107682d02 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 7 Mar 2014 10:25:18 +0100 Subject: Rewound PolarSSL to master branch. The current Devel branch fails to build on RasPi. --- lib/polarssl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/polarssl b/lib/polarssl index 2ceda5798..2cb1a0c40 160000 --- a/lib/polarssl +++ b/lib/polarssl @@ -1 +1 @@ -Subproject commit 2ceda579893ceb23c5eb0d56df47dc235644e0f4 +Subproject commit 2cb1a0c4009ecf368ecc74eb428394e10f9e6d00 -- cgit v1.2.3 From c2090c0d11313bd67b02c482f1ca80d5c4567d27 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 7 Mar 2014 11:44:16 +0100 Subject: Add Lua Bindings for FlowerPotEntity.h and add documentation. --- src/Bindings/AllToLua.pkg | 2 ++ src/Bindings/ManualBindings.cpp | 2 +- src/Blocks/BlockMobHead.h | 5 +++-- src/CMakeLists.txt | 1 + src/Chunk.cpp | 2 +- src/Chunk.h | 4 ++-- src/ChunkMap.cpp | 4 ++-- src/ChunkMap.h | 4 ++-- src/World.cpp | 4 ++-- src/World.h | 4 ++-- 10 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 6b067b1e5..2676281f9 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -58,6 +58,8 @@ $cfile "../BlockEntities/HopperEntity.h" $cfile "../BlockEntities/JukeboxEntity.h" $cfile "../BlockEntities/NoteEntity.h" $cfile "../BlockEntities/SignEntity.h" +$cfile "../BlockEntities/MobHeadEntity.h" +$cfile "../BlockEntities/FlowerPotEntity.h" $cfile "../WebAdmin.h" $cfile "../Root.h" $cfile "../Vector3f.h" diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 3570b2c1e..b094da5fc 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2820,7 +2820,7 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "DoWithFurnaceAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithNoteBlockAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithCommandBlockAt", tolua_DoWithXYZ); - tolua_function(tolua_S, "DoWithMobHeadBlockAt", tolua_DoWithXYZ); + tolua_function(tolua_S, "DoWithMobHeadAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithFlowerPotAt", tolua_DoWithXYZ); tolua_function(tolua_S, "DoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::DoWithPlayer>); tolua_function(tolua_S, "FindAndDoWithPlayer", tolua_DoWith< cWorld, cPlayer, &cWorld::FindAndDoWithPlayer>); diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 6a00c3acd..2b128f13b 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -29,7 +29,7 @@ public: BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ) override { - class cCallback : public cMobHeadBlockCallback + class cCallback : public cMobHeadCallback { cPlayer * m_Player; NIBBLETYPE m_OldBlockMeta; @@ -45,6 +45,7 @@ public: a_MobHeadEntity->SetType(static_cast(m_OldBlockMeta)); a_MobHeadEntity->SetRotation(static_cast(Rotation)); + a_MobHeadEntity->GetWorld()->BroadcastBlockEntity(a_MobHeadEntity->GetPosX(), a_MobHeadEntity->GetPosY(), a_MobHeadEntity->GetPosZ(), m_Player->GetClientHandle()); return false; } @@ -59,7 +60,7 @@ public: a_BlockMeta = a_BlockFace; cWorld * World = (cWorld *) &a_WorldInterface; - World->DoWithMobHeadBlockAt(a_BlockX, a_BlockY, a_BlockZ, Callback); + World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); } } ; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5e0731264..5029906aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,6 +40,7 @@ if (NOT MSVC) BlockEntities/NoteEntity.h BlockEntities/SignEntity.h BlockEntities/MobHeadEntity.h + BlockEntities/FlowerPotEntity.h BlockID.h BoundingBox.h ChatColor.h diff --git a/src/Chunk.cpp b/src/Chunk.cpp index b5b776147..957d7d575 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2340,7 +2340,7 @@ bool cChunk::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCom -bool cChunk::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback) +bool cChunk::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback) { // The blockentity list is locked by the parent chunkmap's CS for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2) diff --git a/src/Chunk.h b/src/Chunk.h index e8b46f631..b3fa563cc 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -49,7 +49,7 @@ typedef cItemCallback cDispenserCallback; typedef cItemCallback cFurnaceCallback; typedef cItemCallback cNoteBlockCallback; typedef cItemCallback cCommandBlockCallback; -typedef cItemCallback cMobHeadBlockCallback; +typedef cItemCallback cMobHeadCallback; typedef cItemCallback cFlowerPotCallback; @@ -256,7 +256,7 @@ public: bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); /** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */ - bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback); + bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback); /** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */ bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 7f999fd31..40964c654 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -2182,7 +2182,7 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c -bool cChunkMap::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback) +bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback) { int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; @@ -2193,7 +2193,7 @@ bool cChunkMap::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c { return false; } - return Chunk->DoWithMobHeadBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); + return Chunk->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); } diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 6d35b2ebf..9d973f2a9 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -46,7 +46,7 @@ typedef cItemCallback cFlowerPotCallback; typedef cItemCallback cFurnaceCallback; typedef cItemCallback cNoteBlockCallback; typedef cItemCallback cCommandBlockCallback; -typedef cItemCallback cMobHeadBlockCallback; +typedef cItemCallback cMobHeadCallback; typedef cItemCallback cChunkCallback; @@ -259,7 +259,7 @@ public: bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Lua-accessible /** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */ - bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback); // Lua-accessible + bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback); // Lua-accessible /** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */ bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback); // Lua-accessible diff --git a/src/World.cpp b/src/World.cpp index 335c6a00d..ecb278e85 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1197,9 +1197,9 @@ bool cWorld::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCom -bool cWorld::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback) +bool cWorld::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback) { - return m_ChunkMap->DoWithMobHeadBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); + return m_ChunkMap->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); } diff --git a/src/World.h b/src/World.h index ee74742c4..e6c665785 100644 --- a/src/World.h +++ b/src/World.h @@ -61,7 +61,7 @@ typedef cItemCallback cDispenserCallback; typedef cItemCallback cFurnaceCallback; typedef cItemCallback cNoteBlockCallback; typedef cItemCallback cCommandBlockCallback; -typedef cItemCallback cMobHeadBlockCallback; +typedef cItemCallback cMobHeadCallback; typedef cItemCallback cFlowerPotCallback; @@ -535,7 +535,7 @@ public: bool DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cCommandBlockCallback & a_Callback); // Exported in ManualBindings.cpp /** Calls the callback for the mob head block at the specified coords; returns false if there's no mob head block at those coords or callback returns true, returns true if found */ - bool DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback); // Exported in ManualBindings.cpp + bool DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback); // Exported in ManualBindings.cpp /** Calls the callback for the flower pot at the specified coords; returns false if there's no flower pot at those coords or callback returns true, returns true if found */ bool DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback); // Exported in ManualBindings.cpp -- cgit v1.2.3 From 880852394275c4cc3c458582fc245f6f22f9d200 Mon Sep 17 00:00:00 2001 From: andrew Date: Fri, 7 Mar 2014 15:42:03 +0200 Subject: Fixed water/lava interaction --- src/Simulator/FloodyFluidSimulator.cpp | 66 ++++++++++++++++++++++++++++++++- src/Simulator/FloodyFluidSimulator.h | 3 ++ src/Simulator/VanillaFluidSimulator.cpp | 4 +- 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index b1ac734d7..48655afb3 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -54,14 +54,21 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re a_Chunk->GetMeta(a_RelX, a_RelY, a_RelZ) ); - NIBBLETYPE MyMeta = a_Chunk->GetMeta(a_RelX, a_RelY, a_RelZ); - if (!IsAnyFluidBlock(a_Chunk->GetBlock(a_RelX, a_RelY, a_RelZ))) + BLOCKTYPE MyBlock; NIBBLETYPE MyMeta; + a_Chunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, MyBlock, MyMeta); + + if (!IsAnyFluidBlock(MyBlock)) { // Can happen - if a block is scheduled for simulating and gets replaced in the meantime. FLOG(" BadBlockType exit"); return; } + if (HardenBlock(a_Chunk, a_RelX, a_RelY, a_RelZ, MyBlock, MyMeta)) + { + return; + } + if (MyMeta != 0) { // Source blocks aren't checked for tributaries, others are. @@ -309,6 +316,8 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i a_NewMeta ); a_NearChunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); + + HardenBlock(a_NearChunk, a_RelX, a_RelY, a_RelZ, m_FluidBlock, a_NewMeta); } @@ -361,3 +370,56 @@ bool cFloodyFluidSimulator::CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX + +bool cFloodyFluidSimulator::HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) +{ + // Only lava blocks can harden + if (!IsBlockLava(a_BlockType)) + { + return false; + } + + bool ShouldHarden = false; + + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + static const Vector3i Coords[] = + { + Vector3i( 1, 0, 0), + Vector3i(-1, 0, 0), + Vector3i( 0, 0, 1), + Vector3i( 0, 0, -1), + }; + for (size_t i = 0; i < ARRAYCOUNT(Coords); i++) + { + if (!a_Chunk->UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta)) + { + continue; + } + if (IsBlockWater(BlockType)) + { + ShouldHarden = true; + } + } // for i - Coords[] + + if (ShouldHarden) + { + if (a_Meta == 0) + { + // Source lava block + a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_OBSIDIAN, 0); + return true; + } + // Ignore last lava level + else if (a_Meta <= 4) + { + a_Chunk->UnboundedRelSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_COBBLESTONE, 0); + return true; + } + } + + return false; +} + + + diff --git a/src/Simulator/FloodyFluidSimulator.h b/src/Simulator/FloodyFluidSimulator.h index 5fd91b2b1..c0ccd422f 100644 --- a/src/Simulator/FloodyFluidSimulator.h +++ b/src/Simulator/FloodyFluidSimulator.h @@ -47,6 +47,9 @@ protected: /** Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns true if so. */ bool CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); + /** Check if block should harden (Water/Lava interaction) */ + bool HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta); + /** Spread water to neighbors. * * May be overridden to provide more sophisticated algorithms. diff --git a/src/Simulator/VanillaFluidSimulator.cpp b/src/Simulator/VanillaFluidSimulator.cpp index 5308d162b..78aff9d68 100644 --- a/src/Simulator/VanillaFluidSimulator.cpp +++ b/src/Simulator/VanillaFluidSimulator.cpp @@ -86,7 +86,7 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int { return Cost; } - if (!IsPassableForFluid(BlockType)) + if (!IsPassableForFluid(BlockType) && !IsBlockLiquid(BlockType)) { return Cost; } @@ -96,7 +96,7 @@ int cVanillaFluidSimulator::CalculateFlowCost(cChunk * a_Chunk, int a_RelX, int { return Cost; } - if (IsPassableForFluid(BlockType)) + if (IsPassableForFluid(BlockType) || IsBlockLiquid(BlockType)) { // Path found, exit return a_Iteration; -- cgit v1.2.3 From 8fdffbb48caa527b83b40baf88e841d1593e79b6 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 7 Mar 2014 16:14:11 +0100 Subject: Add missing documentation files --- MCServer/Plugins/APIDump/APIDesc.lua | 2 ++ MCServer/Plugins/APIDump/Classes/BlockEntities.lua | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 94cdd0063..9df9d0e77 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2150,7 +2150,9 @@ end DoWithDropSpenserAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a dropper or a dispenser at the specified coords, calls the CallbackFunction with the {{cDropSpenserEntity}} parameter representing the dropper or dispenser. The CallbackFunction has the following signature:
function Callback({{cDropSpenserEntity|DropSpenserEntity}}, [CallbackData])
Note that this can be used to access both dispensers and droppers in a similar way. The function returns false if there is neither dispenser nor dropper, or if there is, it returns the bool value that the callback has returned." }, DoWithDropperAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a dropper at the specified coords, calls the CallbackFunction with the {{cDropperEntity}} parameter representing the dropper. The CallbackFunction has the following signature:
function Callback({{cDropperEntity|DropperEntity}}, [CallbackData])
The function returns false if there is no dropper, or if there is, it returns the bool value that the callback has returned." }, DoWithEntityByID = { Params = "EntityID, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If an entity with the specified ID exists, calls the callback with the {{cEntity}} parameter representing the entity. The CallbackFunction has the following signature:
function Callback({{cEntity|Entity}}, [CallbackData])
The function returns false if the entity was not found, and it returns the same bool value that the callback has returned if the entity was found." }, + DoWithFlowerPotAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a flower pot at the specified coords, calls the CallbackFunction with the {{cFlowerPotEntity}} parameter representing the flower pot. The CallbackFunction has the following signature:
function Callback({{cFlowerPotEntity|FlowerPotEntity}}, [CallbackData])
The function returns false if there is no flower pot, or if there is, it returns the bool value that the callback has returned." }, DoWithFurnaceAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a furnace at the specified coords, calls the CallbackFunction with the {{cFurnaceEntity}} parameter representing the furnace. The CallbackFunction has the following signature:
function Callback({{cFurnaceEntity|FurnaceEntity}}, [CallbackData])
The function returns false if there is no furnace, or if there is, it returns the bool value that the callback has returned." }, + DoWithModHeadAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a mob head at the specified coords, calls the CallbackFunction with the {{cMobHeadEntity}} parameter representing the furnace. The CallbackFunction has the following signature:
function Callback({{cMobHeadEntity|MobHeadEntity}}, [CallbackData])
The function returns false if there is no mob head, or if there is, it returns the bool value that the callback has returned." }, DoWithNoteBlockAt = { Params = "BlockX, BlockY, BlockZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a note block at the specified coords, calls the CallbackFunction with the {{cNoteEntity}} parameter representing the note block. The CallbackFunction has the following signature:
function Callback({{cNoteEntity|NoteEntity}}, [CallbackData])
The function returns false if there is no note block, or if there is, it returns the bool value that the callback has returned." }, DoWithPlayer = { Params = "PlayerName, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a player of the specified name (exact match), calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature:
function Callback({{cPlayer|Player}}, [CallbackData])
The function returns false if the player was not found, or whatever bool value the callback returned if the player was found." }, FastSetBlock = diff --git a/MCServer/Plugins/APIDump/Classes/BlockEntities.lua b/MCServer/Plugins/APIDump/Classes/BlockEntities.lua index 61a8e8d22..3deb50ade 100644 --- a/MCServer/Plugins/APIDump/Classes/BlockEntities.lua +++ b/MCServer/Plugins/APIDump/Classes/BlockEntities.lua @@ -238,6 +238,20 @@ World:ForEachChestInChunk(Player:GetChunkX(), Player:GetChunkZ(), }, Inherits = "cBlockEntity"; }, -- cSignEntity + + cFlowerPotEntity = + { + Desc = [[ + This class represents a flower pot entity in the world. + ]], + Functions = + { + IsItemInPot = { Params = "", Return = "bool", Notes = "Is a flower in the pot?" }, + GetItem = { Params = "", Return = "cItem", Notes = "Returns the item in the flower pot." }, + SetItem = { Params = "cItem", Return = "", Notes = "Set the item in the flower pot" }, + }, + Inherits = "cBlockEntity"; + }, -- cFlowerPotEntity } -- cgit v1.2.3 From fd4eda7d248884a48b5d7c67d4c59ee3a9dbb149 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 7 Mar 2014 17:43:06 +0100 Subject: Fixed a typo. --- src/Bindings/ManualBindings.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index f9d04ce90..0dcb336ef 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2456,7 +2456,7 @@ static int tolua_cBlockArea_GetSize(lua_State * tolua_S) static int tolua_cBlockArea_LoadFromSchematicFile(lua_State * tolua_S) { // function cBlockArea::LoadFromSchematicFile - // Exported manually because function has been moved to SchematicFileSerilizer.cpp + // Exported manually because function has been moved to SchematicFileSerializer.cpp cLuaState L(tolua_S); if ( !L.CheckParamUserType(1, "cBlockArea") || @@ -2486,7 +2486,7 @@ static int tolua_cBlockArea_LoadFromSchematicFile(lua_State * tolua_S) static int tolua_cBlockArea_LoadFromSchematicString(lua_State * tolua_S) { // function cBlockArea::LoadFromSchematicString - // Exported manually because function has been moved to SchematicFileSerilizer.cpp + // Exported manually because function has been moved to SchematicFileSerializer.cpp cLuaState L(tolua_S); if ( !L.CheckParamUserType(1, "cBlockArea") || @@ -2517,7 +2517,7 @@ static int tolua_cBlockArea_LoadFromSchematicString(lua_State * tolua_S) static int tolua_cBlockArea_SaveToSchematicFile(lua_State * tolua_S) { // function cBlockArea::SaveToSchematicFile - // Exported manually because function has been moved to SchematicFileSerilizer.cpp + // Exported manually because function has been moved to SchematicFileSerializer.cpp cLuaState L(tolua_S); if ( !L.CheckParamUserType(1, "cBlockArea") || @@ -2546,7 +2546,7 @@ static int tolua_cBlockArea_SaveToSchematicFile(lua_State * tolua_S) static int tolua_cBlockArea_SaveToSchematicString(lua_State * tolua_S) { // function cBlockArea::SaveToSchematicString - // Exported manually because function has been moved to SchematicFileSerilizer.cpp + // Exported manually because function has been moved to SchematicFileSerializer.cpp cLuaState L(tolua_S); if ( !L.CheckParamUserType(1, "cBlockArea") || -- cgit v1.2.3 From eff054027face23320f55a01fe5884fe285204b6 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 7 Mar 2014 17:51:43 +0100 Subject: Link cItem in the documentation --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- MCServer/Plugins/APIDump/Classes/BlockEntities.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 9df9d0e77..39f7cbcd7 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2152,7 +2152,7 @@ end DoWithEntityByID = { Params = "EntityID, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If an entity with the specified ID exists, calls the callback with the {{cEntity}} parameter representing the entity. The CallbackFunction has the following signature:
function Callback({{cEntity|Entity}}, [CallbackData])
The function returns false if the entity was not found, and it returns the same bool value that the callback has returned if the entity was found." }, DoWithFlowerPotAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a flower pot at the specified coords, calls the CallbackFunction with the {{cFlowerPotEntity}} parameter representing the flower pot. The CallbackFunction has the following signature:
function Callback({{cFlowerPotEntity|FlowerPotEntity}}, [CallbackData])
The function returns false if there is no flower pot, or if there is, it returns the bool value that the callback has returned." }, DoWithFurnaceAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a furnace at the specified coords, calls the CallbackFunction with the {{cFurnaceEntity}} parameter representing the furnace. The CallbackFunction has the following signature:
function Callback({{cFurnaceEntity|FurnaceEntity}}, [CallbackData])
The function returns false if there is no furnace, or if there is, it returns the bool value that the callback has returned." }, - DoWithModHeadAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a mob head at the specified coords, calls the CallbackFunction with the {{cMobHeadEntity}} parameter representing the furnace. The CallbackFunction has the following signature:
function Callback({{cMobHeadEntity|MobHeadEntity}}, [CallbackData])
The function returns false if there is no mob head, or if there is, it returns the bool value that the callback has returned." }, + DoWithMobHeadAt = { Params = "X, Y, Z, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a mob head at the specified coords, calls the CallbackFunction with the {{cMobHeadEntity}} parameter representing the furnace. The CallbackFunction has the following signature:
function Callback({{cMobHeadEntity|MobHeadEntity}}, [CallbackData])
The function returns false if there is no mob head, or if there is, it returns the bool value that the callback has returned." }, DoWithNoteBlockAt = { Params = "BlockX, BlockY, BlockZ, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a note block at the specified coords, calls the CallbackFunction with the {{cNoteEntity}} parameter representing the note block. The CallbackFunction has the following signature:
function Callback({{cNoteEntity|NoteEntity}}, [CallbackData])
The function returns false if there is no note block, or if there is, it returns the bool value that the callback has returned." }, DoWithPlayer = { Params = "PlayerName, CallbackFunction, [CallbackData]", Return = "bool", Notes = "If there is a player of the specified name (exact match), calls the CallbackFunction with the {{cPlayer}} parameter representing the player. The CallbackFunction has the following signature:
function Callback({{cPlayer|Player}}, [CallbackData])
The function returns false if the player was not found, or whatever bool value the callback returned if the player was found." }, FastSetBlock = diff --git a/MCServer/Plugins/APIDump/Classes/BlockEntities.lua b/MCServer/Plugins/APIDump/Classes/BlockEntities.lua index 3deb50ade..de42f66df 100644 --- a/MCServer/Plugins/APIDump/Classes/BlockEntities.lua +++ b/MCServer/Plugins/APIDump/Classes/BlockEntities.lua @@ -247,8 +247,8 @@ World:ForEachChestInChunk(Player:GetChunkX(), Player:GetChunkZ(), Functions = { IsItemInPot = { Params = "", Return = "bool", Notes = "Is a flower in the pot?" }, - GetItem = { Params = "", Return = "cItem", Notes = "Returns the item in the flower pot." }, - SetItem = { Params = "cItem", Return = "", Notes = "Set the item in the flower pot" }, + GetItem = { Params = "", Return = "{{cItem|Item}}", Notes = "Returns the item in the flower pot." }, + SetItem = { Params = "{{cItem|Item}}", Return = "", Notes = "Set the item in the flower pot" }, }, Inherits = "cBlockEntity"; }, -- cFlowerPotEntity -- cgit v1.2.3 From fac56bb935de5a808b197ccc4a886f262d94dc99 Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 7 Mar 2014 16:55:45 +0000 Subject: Enabled -ffast-math --- SetFlags.cmake | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index ded57e6d7..6e86ac0aa 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -1,5 +1,4 @@ - macro (add_flags_lnk FLAGS) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}") set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}") @@ -50,6 +49,9 @@ macro(set_flags) else() add_flags_cxx("-pthread") endif() + + #we support non-IEEE 754 fpus so can make no guarentees about error + add_flags_cxx("-ffast-math") else() # Let gcc / clang know that we're compiling a multi-threaded app: @@ -62,6 +64,9 @@ macro(set_flags) # We use a signed char (fixes #640 on RasPi) add_flags_cxx("-fsigned-char") + + #we support non-IEEE 754 fpus so can make no guarentees about error + add_flags_cxx("-ffast-math") endif() -- cgit v1.2.3 From 2a3d8d46ec5d269b220ed1fb711cb4d2bfa9dfeb Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 7 Mar 2014 17:04:38 +0000 Subject: Only use fast-math in exes --- SetFlags.cmake | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 6e86ac0aa..a5bd3a0a2 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -1,4 +1,3 @@ - macro (add_flags_lnk FLAGS) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}") set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}") @@ -49,9 +48,6 @@ macro(set_flags) else() add_flags_cxx("-pthread") endif() - - #we support non-IEEE 754 fpus so can make no guarentees about error - add_flags_cxx("-ffast-math") else() # Let gcc / clang know that we're compiling a multi-threaded app: @@ -65,8 +61,6 @@ macro(set_flags) # We use a signed char (fixes #640 on RasPi) add_flags_cxx("-fsigned-char") - #we support non-IEEE 754 fpus so can make no guarentees about error - add_flags_cxx("-ffast-math") endif() @@ -189,6 +183,9 @@ macro(set_exe_flags) string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") add_flags_cxx("-Wall -Wextra") + + #we support non-IEEE 754 fpus so can make no guarentees about error + add_flags_cxx("-ffast-math") endif() endmacro() -- cgit v1.2.3 From 95ea0ef43dfbcf2240a0ece70d2829ce63ab0dd3 Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 7 Mar 2014 17:22:37 +0000 Subject: Fixed clang compile --- SetFlags.cmake | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index a5bd3a0a2..6a8211fa2 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -184,8 +184,13 @@ macro(set_exe_flags) string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") add_flags_cxx("-Wall -Wextra") - #we support non-IEEE 754 fpus so can make no guarentees about error + # we support non-IEEE 754 fpus so can make no guarentees about error add_flags_cxx("-ffast-math") + + # clang does not provide the __extern_always_inline macro and a part of libm depends on this when using fast-math + if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + add_flags_cxx("-D__extern_always_inline=inline") + endif() endif() endmacro() -- cgit v1.2.3 From b480148116ea7099c9a6afda83f74a3d45815a83 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 7 Mar 2014 10:26:07 -0800 Subject: Fixed warnings --- SetFlags.cmake | 2 +- src/Bindings/LuaState.cpp | 1 + src/Items/ItemHandler.h | 3 +++ src/OSSupport/SocketThreads.h | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 6a8211fa2..35831e7e9 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -182,7 +182,7 @@ macro(set_exe_flags) string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") - add_flags_cxx("-Wall -Wextra") + add_flags_cxx("-Wall -Wextra -Werror -Wno-error=unused-parameter") # we support non-IEEE 754 fpus so can make no guarentees about error add_flags_cxx("-ffast-math") diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 1890dcfe5..aa6ee05b3 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -677,6 +677,7 @@ void cLuaState::Push(Vector3i * a_Vector) void cLuaState::Push(void * a_Ptr) { + UNUSED(a_Ptr); ASSERT(IsValid()); // Investigate the cause of this - what is the callstack? diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h index ef3f37a7a..5b6c239cc 100644 --- a/src/Items/ItemHandler.h +++ b/src/Items/ItemHandler.h @@ -21,6 +21,9 @@ class cItemHandler public: cItemHandler(int a_ItemType); + // Force virtual destructor + virtual ~cItemHandler() {} + /// Called when the player tries to use the item (right mouse button). Return false to make the item unusable. DEFAULT: False virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir); diff --git a/src/OSSupport/SocketThreads.h b/src/OSSupport/SocketThreads.h index fcd2ce11f..b2eb5950f 100644 --- a/src/OSSupport/SocketThreads.h +++ b/src/OSSupport/SocketThreads.h @@ -103,7 +103,7 @@ private: public: cSocketThread(cSocketThreads * a_Parent); - ~cSocketThread(); + virtual ~cSocketThread(); // All these methods assume parent's m_CS is locked bool HasEmptySlot(void) const {return m_NumSlots < MAX_SLOTS; } -- cgit v1.2.3 From 7f389522ef1f40e847a4a7828ad55e50c0151b00 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 7 Mar 2014 10:42:13 -0800 Subject: Fixed warnings --- src/Blocks/BlockStairs.h | 8 ++++++++ src/Blocks/BlockVine.h | 16 +++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index c1887bc46..93035b3b1 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -25,6 +25,14 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { + UNUSED(a_ChunkInterface); + UNUSED(a_BlockX); + UNUSED(a_BlockY); + UNUSED(a_BlockZ); + UNUSED(a_CursorX); + UNUSED(a_CursorY); + UNUSED(a_CursorZ); + UNUSED(a_BlockMeta); a_BlockType = m_BlockType; a_BlockMeta = RotationToMetaData(a_Player->GetYaw()); switch (a_BlockFace) diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index d8c114284..0934a451b 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -24,6 +24,10 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { + UNUSED(a_Player); + UNUSED(a_CursorX); + UNUSED(a_CursorY); + UNUSED(a_CursorZ); // TODO: Disallow placement where the vine doesn't attach to something properly BLOCKTYPE BlockType = 0; NIBBLETYPE BlockMeta; @@ -162,11 +166,17 @@ public: return false; } - virtual void OnUpdate(cWorld * a_World, int X, int Y, int Z) + virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) { - if (a_World->GetBlock(X, Y - 1, Z) == E_BLOCK_AIR) + UNUSED(a_ChunkInterface); + UNUSED(a_WorldInterface); + UNUSED(a_BlockPluginInterface); + + BLOCKTYPE Block; + a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block); + if (Block == E_BLOCK_AIR) { - a_World->SetBlock(X, Y - 1, Z, E_BLOCK_VINES, a_World->GetBlockMeta(X, Y, Z)); + a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); } } -- cgit v1.2.3 From d86fc1af0640675c707330e671d69b23e27d20c1 Mon Sep 17 00:00:00 2001 From: andrew Date: Fri, 7 Mar 2014 20:49:40 +0200 Subject: Added some comments --- src/Simulator/FloodyFluidSimulator.cpp | 2 ++ src/Simulator/FloodyFluidSimulator.h | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index 48655afb3..03e94e791 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -64,8 +64,10 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re return; } + // When in contact with water, lava should harden if (HardenBlock(a_Chunk, a_RelX, a_RelY, a_RelZ, MyBlock, MyMeta)) { + // Block was changed, bail out return; } diff --git a/src/Simulator/FloodyFluidSimulator.h b/src/Simulator/FloodyFluidSimulator.h index c0ccd422f..632de3bb2 100644 --- a/src/Simulator/FloodyFluidSimulator.h +++ b/src/Simulator/FloodyFluidSimulator.h @@ -47,7 +47,10 @@ protected: /** Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns true if so. */ bool CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); - /** Check if block should harden (Water/Lava interaction) */ + /** Checks if the specified block should harden (Water/Lava interaction) and if so, converts it to a suitable block. + * + * Returns whether the block was changed or not. + */ bool HardenBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta); /** Spread water to neighbors. -- cgit v1.2.3 From d33d72f0dc9ef8969c6b57592fbce54165641591 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 7 Mar 2014 11:04:25 -0800 Subject: Warnings --- src/ByteBuffer.cpp | 10 +++++----- src/ByteBuffer.h | 24 ++++++++++++------------ src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.cpp | 2 +- src/Protocol/Protocol125.h | 21 +++++++++++++++++---- src/Protocol/Protocol132.cpp | 2 +- src/Protocol/Protocol132.h | 2 +- src/Protocol/Protocol17x.cpp | 2 +- src/Protocol/Protocol17x.h | 2 +- src/Protocol/ProtocolRecognizer.cpp | 2 +- src/Protocol/ProtocolRecognizer.h | 2 +- 11 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index d2d3beb97..32a367462 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -171,7 +171,7 @@ cByteBuffer::~cByteBuffer() -bool cByteBuffer::Write(const char * a_Bytes, int a_Count) +bool cByteBuffer::Write(const char * a_Bytes, size_t a_Count) { CHECK_THREAD; CheckValid(); @@ -263,7 +263,7 @@ int cByteBuffer::GetReadableSpace(void) const -bool cByteBuffer::CanReadBytes(int a_Count) const +bool cByteBuffer::CanReadBytes(size_t a_Count) const { CHECK_THREAD; CheckValid(); @@ -274,7 +274,7 @@ bool cByteBuffer::CanReadBytes(int a_Count) const -bool cByteBuffer::CanWriteBytes(int a_Count) const +bool cByteBuffer::CanWriteBytes(size_t a_Count) const { CHECK_THREAD; CheckValid(); @@ -767,7 +767,7 @@ bool cByteBuffer::ReadUTF16String(AString & a_String, int a_NumChars) -bool cByteBuffer::SkipRead(int a_Count) +bool cByteBuffer::SkipRead(size_t a_Count) { CHECK_THREAD; CheckValid(); @@ -860,7 +860,7 @@ void cByteBuffer::ReadAgain(AString & a_Out) -void cByteBuffer::AdvanceReadPos(int a_Count) +void cByteBuffer::AdvanceReadPos(size_t a_Count) { CHECK_THREAD; CheckValid(); diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index cbce119b1..5fdf48c28 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -31,7 +31,7 @@ public: ~cByteBuffer(); /// Writes the bytes specified to the ringbuffer. Returns true if successful, false if not - bool Write(const char * a_Bytes, int a_Count); + bool Write(const char * a_Bytes, size_t a_Count); /// Returns the number of bytes that can be successfully written to the ringbuffer int GetFreeSpace(void) const; @@ -46,10 +46,10 @@ public: int GetDataStart(void) const { return m_DataStart; } /// Returns true if the specified amount of bytes are available for reading - bool CanReadBytes(int a_Count) const; + bool CanReadBytes(size_t a_Count) const; /// Returns true if the specified amount of bytes are available for writing - bool CanWriteBytes(int a_Count) const; + bool CanWriteBytes(size_t a_Count) const; // Read the specified datatype and advance the read pointer; return true if successfully read: bool ReadChar (char & a_Value); @@ -92,19 +92,19 @@ public: bool WriteLEInt (int a_Value); /// Reads a_Count bytes into a_Buffer; returns true if successful - bool ReadBuf(void * a_Buffer, int a_Count); + bool ReadBuf(void * a_Buffer, size_t a_Count); /// Writes a_Count bytes into a_Buffer; returns true if successful - bool WriteBuf(const void * a_Buffer, int a_Count); + bool WriteBuf(const void * a_Buffer, size_t a_Count); /// Reads a_Count bytes into a_String; returns true if successful - bool ReadString(AString & a_String, int a_Count); + bool ReadString(AString & a_String, size_t a_Count); /// Reads 2 * a_NumChars bytes and interprets it as a UTF16-BE string, converting it into UTF8 string a_String bool ReadUTF16String(AString & a_String, int a_NumChars); /// Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer - bool SkipRead(int a_Count); + bool SkipRead(size_t a_Count); /// Reads all available data into a_Data void ReadAll(AString & a_Data); @@ -126,18 +126,18 @@ public: protected: char * m_Buffer; - int m_BufferSize; // Total size of the ringbuffer + size_t m_BufferSize; // Total size of the ringbuffer #ifdef _DEBUG volatile unsigned long m_ThreadID; // Thread that is currently accessing the object, checked via cSingleThreadAccessChecker #endif // _DEBUG - int m_DataStart; // Where the data starts in the ringbuffer - int m_WritePos; // Where the data ends in the ringbuffer - int m_ReadPos; // Where the next read will start in the ringbuffer + size_t m_DataStart; // Where the data starts in the ringbuffer + size_t m_WritePos; // Where the data ends in the ringbuffer + size_t m_ReadPos; // Where the next read will start in the ringbuffer /// Advances the m_ReadPos by a_Count bytes - void AdvanceReadPos(int a_Count); + void AdvanceReadPos(size_t a_Count); } ; diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index b5560f7c1..d3383bf0d 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -52,7 +52,7 @@ public: virtual ~cProtocol() {} /// Called when client sends some data - virtual void DataReceived(const char * a_Data, int a_Size) = 0; + virtual void DataReceived(const char * a_Data, size_t a_Size) = 0; // Sending stuff to clients (alphabetically sorted): virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 3980350f5..e032e4050 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1186,7 +1186,7 @@ void cProtocol125::SendData(const char * a_Data, int a_Size) -void cProtocol125::DataReceived(const char * a_Data, int a_Size) +void cProtocol125::DataReceived(const char * a_Data, size_t a_Size) { if (!m_ReceivedData.Write(a_Data, a_Size)) { diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 1d1484a60..66f3227b0 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -24,7 +24,7 @@ public: cProtocol125(cClientHandle * a_Client); /// Called when client sends some data: - virtual void DataReceived(const char * a_Data, int a_Size) override; + virtual void DataReceived(const char * a_Data, size_t a_Size) override; /// Sending stuff to clients (alphabetically sorted): virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; @@ -57,9 +57,17 @@ public: virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override; virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators) override; - virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override {} // This protocol doesn't support such message + virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override + { + // This protocol doesn't support such message + UNUSED(a_ID); + UNUSED(a_Scale); + } virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override; - virtual void SendPaintingSpawn (const cPainting & a_Painting) override {}; + virtual void SendPaintingSpawn (const cPainting & a_Painting) override + { + UNUSED(a_Painting); + }; virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendPlayerAbilities (void) override {} // This protocol doesn't support such message virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override; @@ -73,7 +81,12 @@ public: virtual void SendRespawn (void) override; virtual void SendExperience (void) override; virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; - virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override {} // This protocol doesn't support such message + virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override + { + UNUSED(a_Name); + UNUSED(a_DisplayName); + UNUSED(a_Mode); + } // This protocol doesn't support such message virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override {} // This protocol doesn't support such message virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override {} // This protocol doesn't support such message virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8 diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index 1f9222a69..8df550c7b 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -108,7 +108,7 @@ cProtocol132::~cProtocol132() -void cProtocol132::DataReceived(const char * a_Data, int a_Size) +void cProtocol132::DataReceived(const char * a_Data, size_t a_Size) { if (m_IsEncrypted) { diff --git a/src/Protocol/Protocol132.h b/src/Protocol/Protocol132.h index 89f4636f5..0702fbf5a 100644 --- a/src/Protocol/Protocol132.h +++ b/src/Protocol/Protocol132.h @@ -40,7 +40,7 @@ public: virtual ~cProtocol132(); /// Called when client sends some data: - virtual void DataReceived(const char * a_Data, int a_Size) override; + virtual void DataReceived(const char * a_Data, size_t a_Size) override; // Sending commands (alphabetically sorted): virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 18646254f..cb9e5b9b1 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -98,7 +98,7 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd -void cProtocol172::DataReceived(const char * a_Data, int a_Size) +void cProtocol172::DataReceived(const char * a_Data, size_t a_Size) { if (m_IsEncrypted) { diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 113501568..41163009e 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -56,7 +56,7 @@ public: cProtocol172(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); /** Called when client sends some data: */ - virtual void DataReceived(const char * a_Data, int a_Size) override; + virtual void DataReceived(const char * a_Data, size_t a_Size) override; /** Sending stuff to clients (alphabetically sorted): */ virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 84b052146..3b9003e60 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -68,7 +68,7 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion) -void cProtocolRecognizer::DataReceived(const char * a_Data, int a_Size) +void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size) { if (m_Protocol == NULL) { diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 6aaafedeb..d7fb8fad2 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -59,7 +59,7 @@ public: static AString GetVersionTextFromInt(int a_ProtocolVersion); /// Called when client sends some data: - virtual void DataReceived(const char * a_Data, int a_Size) override; + virtual void DataReceived(const char * a_Data, size_t a_Size) override; /// Sending stuff to clients (alphabetically sorted): virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; -- cgit v1.2.3 From 21e85b07456f12c029ab32c396285ad13063964f Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 7 Mar 2014 11:15:04 -0800 Subject: Warnings --- src/Generating/MineShafts.cpp | 2 ++ src/Generating/Trees.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index d9acc57bb..28dc37567 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -69,6 +69,8 @@ public: m_BoundingBox(a_BoundingBox) { } + + virtual ~cMineShaft() {} /// Returns true if this mineshaft intersects the specified cuboid bool DoesIntersect(const cCuboid & a_Other) diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index a660285d1..4909587b1 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -595,7 +595,7 @@ void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise { break; } - ASSERT(LayerSize < ARRAYCOUNT(BigOs)); + ASSERT((size_t)LayerSize < ARRAYCOUNT(BigOs)); PushCoordBlocks(a_BlockX, h, a_BlockZ, a_OtherBlocks, BigOs[LayerSize].Coords, BigOs[LayerSize].Count, E_BLOCK_LEAVES, E_META_LEAVES_CONIFER); h--; } -- cgit v1.2.3 From d51cab2d3bb579b663c1211dfc1e69039165c06f Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 7 Mar 2014 11:16:16 -0800 Subject: Turned on Werror --- SetFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 35831e7e9..e6ba782fc 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -182,7 +182,7 @@ macro(set_exe_flags) string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") - add_flags_cxx("-Wall -Wextra -Werror -Wno-error=unused-parameter") + add_flags_cxx("-Wall -Wextra -Werror -Wno-error=unused-parameter -Wno-error=switch") # we support non-IEEE 754 fpus so can make no guarentees about error add_flags_cxx("-ffast-math") -- cgit v1.2.3 From 72697cfb4f7cfa8e82cba4960ac9e8c729c3b24d Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 7 Mar 2014 11:23:28 -0800 Subject: Added support to overide CMake build type with env vars --- src/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5029906aa..cafa519c3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,14 @@ include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include") set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating) set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities) +if(DEFINED ENV{MCSERVER_BUILD_TYPE}) + message("Setting build type to $ENV{MCSERVER_BUILD_TYPE}") + set(CMAKE_BUILD_TYPE $ENV{MCSERVER_BUILD_TYPE}) +endif() + +if(DEFINED ENV{MCSERVER_FORCE32}) + set(FORCE32 $ENV{MCSERVER_FORCE32}) +endif() if (NOT MSVC) -- cgit v1.2.3 From 53fe82eaf85dc3bcd2cfdc12ffb2266e10f91e79 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 7 Mar 2014 11:26:36 -0800 Subject: Added travis support for multiple build types --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c6537cf47..a12ca55e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,13 @@ compiler: - gcc - clang # Build MCServer -script: cmake . -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_TOOLS=1 -DSELF_TEST=1 && make -j 2 && cd MCServer/ && (echo stop | ./MCServer) +script: cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1 && make -j 2 && cd MCServer/ && (echo stop | ./MCServer) + +env: + - MCSERVER_BUILD_TYPE=RELEASE + - MCSERVER_BUILD_TYPE=DEBUG + - MCSERVER_BUILD_TYPE=RELEASE MCSERVER_FORCE32=1 + - MCSERVER_BUILD_TYPE=DEBUG MCSERVER_FORCE32=1 # Notification Settings notifications: -- cgit v1.2.3 From 6b153a5014612a998179f4637139061ed11da6db Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 7 Mar 2014 19:59:49 +0000 Subject: Move env code part 1 --- src/CMakeLists.txt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cafa519c3..c2de26664 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,3 @@ - cmake_minimum_required (VERSION 2.8.2) project (MCServer) @@ -9,15 +8,6 @@ include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include") set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating) set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities) -if(DEFINED ENV{MCSERVER_BUILD_TYPE}) - message("Setting build type to $ENV{MCSERVER_BUILD_TYPE}") - set(CMAKE_BUILD_TYPE $ENV{MCSERVER_BUILD_TYPE}) -endif() - -if(DEFINED ENV{MCSERVER_FORCE32}) - set(FORCE32 $ENV{MCSERVER_FORCE32}) -endif() - if (NOT MSVC) -- cgit v1.2.3 From c67e008a4e3c19a79f82af4d430e43e6ea0eabbf Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 7 Mar 2014 20:03:05 +0000 Subject: Fixed wrong path in debug mode --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index a12ca55e0..14dad4df4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,13 +3,13 @@ compiler: - gcc - clang # Build MCServer -script: cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1 && make -j 2 && cd MCServer/ && (echo stop | ./MCServer) +script: cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1 && make -j 2 && cd MCServer/ && (echo stop | $MCSERVER_PATH) env: - - MCSERVER_BUILD_TYPE=RELEASE - - MCSERVER_BUILD_TYPE=DEBUG - - MCSERVER_BUILD_TYPE=RELEASE MCSERVER_FORCE32=1 - - MCSERVER_BUILD_TYPE=DEBUG MCSERVER_FORCE32=1 + - MCSERVER_BUILD_TYPE=RELEASE MCSERVER_PATH=./MCServer + - MCSERVER_BUILD_TYPE=DEBUG MCSERVER_PATH=./MCServer_debug + - MCSERVER_BUILD_TYPE=RELEASE MCSERVER_FORCE32=1 MCSERVER_PATH=./MCServer + - MCSERVER_BUILD_TYPE=DEBUG MCSERVER_FORCE32=1 MCSERVER_PATH=./MCServer_debug # Notification Settings notifications: -- cgit v1.2.3 From 0eea9eb99841ba379475a277af860d22ac156071 Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 7 Mar 2014 20:16:16 +0000 Subject: Move env code part 2 Only just noticed I committed this on the wrong branch. --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 05b6d879b..e7e8daf7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,15 @@ cmake_minimum_required (VERSION 2.6) # Without this, the MSVC variable isn't defined for MSVC builds ( http://www.cmake.org/pipermail/cmake/2011-November/047130.html ) enable_language(CXX C) +if(DEFINED ENV{MCSERVER_BUILD_TYPE}) + message("Setting build type to $ENV{MCSERVER_BUILD_TYPE}") + set(CMAKE_BUILD_TYPE $ENV{MCSERVER_BUILD_TYPE}) +endif() + +if(DEFINED ENV{MCSERVER_FORCE32}) + set(FORCE32 $ENV{MCSERVER_FORCE32}) +endif() + # This has to be done before any flags have been set up. if(${BUILD_TOOLS}) add_subdirectory(Tools/MCADefrag/) -- cgit v1.2.3 From ffdf5f2022cbeb568cb6ff28448aad98876334b1 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 7 Mar 2014 21:28:52 +0100 Subject: Fixed cBlockArea schematic string saving signature. --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- src/Bindings/ManualBindings.cpp | 10 +++++++--- src/WorldStorage/SchematicFileSerializer.cpp | 7 +++---- src/WorldStorage/SchematicFileSerializer.h | 4 ++-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 5f1b11a4c..1e572492b 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -162,7 +162,7 @@ g_APIDesc = RotateCW = { Params = "", Return = "", Notes = "Rotates the block area around the Y axis, clockwise (north -> east). Modifies blocks' metas (if present) to match." }, RotateCWNoMeta = { Params = "", Return = "", Notes = "Rotates the block area around the Y axis, clockwise (north -> east). Doesn't modify blocks' metas." }, SaveToSchematicFile = { Params = "FileName", Return = "", Notes = "Saves the current contents to a schematic file. Returns true if successful." }, - SaveToSchematicString = { Params = "", Return = "string", Notes = "Saves the current contents to a string (in a .schematic file format). Returns the data if successful, empty string if failed." }, + SaveToSchematicString = { Params = "", Return = "string", Notes = "Saves the current contents to a string (in a .schematic file format). Returns the data if successful, nil if failed." }, SetBlockLight = { Params = "BlockX, BlockY, BlockZ, BlockLight", Return = "", Notes = "Sets the blocklight at the specified absolute coords" }, SetBlockMeta = { Params = "BlockX, BlockY, BlockZ, BlockMeta", Return = "", Notes = "Sets the block meta at the specified absolute coords" }, SetBlockSkyLight = { Params = "BlockX, BlockY, BlockZ, SkyLight", Return = "", Notes = "Sets the skylight at the specified absolute coords" }, diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 05dc9717e..a5247bbe6 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2563,9 +2563,13 @@ static int tolua_cBlockArea_SaveToSchematicString(lua_State * tolua_S) return 0; } - AString Data = cSchematicFileSerializer::SaveToSchematicString(*self); - L.Push(Data); - return 1; + AString Data; + if (cSchematicFileSerializer::SaveToSchematicString(*self, Data)) + { + L.Push(Data); + return 1; + } + return 0; } diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index a6ae8d8e0..b021aeb0c 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -103,7 +103,7 @@ bool cSchematicFileSerializer::SaveToSchematicFile(const cBlockArea & a_BlockAre -AString cSchematicFileSerializer::SaveToSchematicString(const cBlockArea & a_BlockArea) +bool cSchematicFileSerializer::SaveToSchematicString(const cBlockArea & a_BlockArea, AString & a_Out) { // Serialize into NBT data: AString NBT = SaveToSchematicNBT(a_BlockArea); @@ -114,14 +114,13 @@ AString cSchematicFileSerializer::SaveToSchematicString(const cBlockArea & a_Blo } // Gzip the data: - AString Compressed; - int res = CompressStringGZIP(NBT.data(), NBT.size(), Compressed); + int res = CompressStringGZIP(NBT.data(), NBT.size(), a_Out); if (res != Z_OK) { LOG("%s: Cannot Gzip the area data NBT representation: %d", __FUNCTION__, res); return false; } - return Compressed; + return true; } diff --git a/src/WorldStorage/SchematicFileSerializer.h b/src/WorldStorage/SchematicFileSerializer.h index f6ce1c16c..05b6c74f4 100644 --- a/src/WorldStorage/SchematicFileSerializer.h +++ b/src/WorldStorage/SchematicFileSerializer.h @@ -36,8 +36,8 @@ public: static bool SaveToSchematicFile(const cBlockArea & a_BlockArea, const AString & a_FileName); /** Saves the area into a string containing the .schematic file data. - Returns the data, or empty string if failed. */ - static AString SaveToSchematicString(const cBlockArea & a_BlockArea); + Returns true if successful, false on failure. The data is stored into a_Out. */ + static bool SaveToSchematicString(const cBlockArea & a_BlockArea, AString & a_Out); private: /** Loads the area from a schematic file uncompressed and parsed into a NBT tree. -- cgit v1.2.3 From f5e374be41ef3bde93e0faaa76208e3e0e15e9ea Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 8 Mar 2014 10:25:46 +0100 Subject: Add TNT Save/Load and add Netbeans projects to .gitignore --- .gitignore | 1 + src/Entities/TNTEntity.cpp | 27 +++++++++++++++++---------- src/Entities/TNTEntity.h | 23 ++++++++++++++++------- src/WorldStorage/NBTChunkSerializer.cpp | 15 ++++++++++++++- src/WorldStorage/NBTChunkSerializer.h | 2 ++ src/WorldStorage/WSSAnvil.cpp | 28 ++++++++++++++++++++++++++++ src/WorldStorage/WSSAnvil.h | 1 + 7 files changed, 79 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index c8ad93a80..c544f394d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build/ +nbproject/ ipch/ Win32/ MCServer/MCServer diff --git a/src/Entities/TNTEntity.cpp b/src/Entities/TNTEntity.cpp index 339107b2e..4f361403c 100644 --- a/src/Entities/TNTEntity.cpp +++ b/src/Entities/TNTEntity.cpp @@ -10,8 +10,7 @@ cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec) : super(etTNT, a_X, a_Y, a_Z, 0.98, 0.98), - m_Counter(0), - m_MaxFuseTime(a_FuseTimeInSec) + m_FuseTicks(a_FuseTimeInSec) { } @@ -21,8 +20,7 @@ cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSe cTNTEntity::cTNTEntity(const Vector3d & a_Pos, double a_FuseTimeInSec) : super(etTNT, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98), - m_Counter(0), - m_MaxFuseTime(a_FuseTimeInSec) + m_FuseTicks(a_FuseTimeInSec) { } @@ -42,18 +40,27 @@ void cTNTEntity::SpawnOn(cClientHandle & a_ClientHandle) +void cTNTEntity::Explode(void) +{ + m_FuseTicks = 0; + Destroy(true); + LOGD("BOOM at {%f,%f,%f}", GetPosX(), GetPosY(), GetPosZ()); + m_World->DoExplosionAt(4.0, GetPosX() + 0.49, GetPosY() + 0.49, GetPosZ() + 0.49, true, esPrimedTNT, this); +} + + + + + void cTNTEntity::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); BroadcastMovementUpdate(); float delta_time = a_Dt / 1000; // Convert miliseconds to seconds - m_Counter += delta_time; - if (m_Counter > m_MaxFuseTime) // Check if we go KABOOOM + m_FuseTicks -= delta_time; + if (m_FuseTicks <= 0) { - Destroy(true); - LOGD("BOOM at {%f,%f,%f}", GetPosX(), GetPosY(), GetPosZ()); - m_World->DoExplosionAt(4.0, GetPosX() + 0.49, GetPosY() + 0.49, GetPosZ() + 0.49, true, esPrimedTNT, this); - return; + Explode(); } } diff --git a/src/Entities/TNTEntity.h b/src/Entities/TNTEntity.h index d1fcae766..8f83f52d9 100644 --- a/src/Entities/TNTEntity.h +++ b/src/Entities/TNTEntity.h @@ -16,19 +16,28 @@ public: // tolua_end CLASS_PROTODEF(cTNTEntity); - cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec); - cTNTEntity(const Vector3d & a_Pos, double a_FuseTimeInSec); + cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec = 4); + cTNTEntity(const Vector3d & a_Pos, double a_FuseTimeInSec = 4); // cEntity overrides: virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; - - double GetCounterTime(void) const { return m_Counter; } // tolua_export - double GetMaxFuseTime(void) const { return m_MaxFuseTime; } // tolua_export + + // tolua_begin + + /** Explode the tnt */ + void Explode(void); + + /** Returns the fuse ticks until the tnt will explode */ + double GetFuseTicks(void) const { return m_FuseTicks; } + + /** Set the fuse ticks until the tnt will explode */ + void SetFuseTicks(double a_FuseTicks) { m_FuseTicks = a_FuseTicks; } + + // tolua_end protected: - double m_Counter; ///< How much time has elapsed since the object was created, in seconds - double m_MaxFuseTime; ///< How long the fuse is, in seconds + double m_FuseTicks; ///< How much time in seconds is left, while the tnt will explode }; // tolua_export diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 6d0e29958..06b815333 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -28,6 +28,7 @@ #include "../Entities/Minecart.h" #include "../Entities/Pickup.h" #include "../Entities/ProjectileEntity.h" +#include "../Entities/TNTEntity.h" #include "../Mobs/Monster.h" #include "../Mobs/Bat.h" @@ -583,6 +584,18 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) +void cNBTChunkSerializer::AddTNTEntity(cTNTEntity * a_TNT) +{ + m_Writer.BeginCompound(""); + AddBasicEntity(a_TNT, "PrimedTnt"); + m_Writer.AddByte("Fuse", ((unsigned char)a_TNT->GetFuseTicks()) * 10); + m_Writer.EndCompound(); +} + + + + + void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart) { m_Writer.BeginList("Items", TAG_Compound); @@ -662,7 +675,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) case cEntity::etMonster: AddMonsterEntity ((cMonster *) a_Entity); break; case cEntity::etPickup: AddPickupEntity ((cPickup *) a_Entity); break; case cEntity::etProjectile: AddProjectileEntity ((cProjectileEntity *)a_Entity); break; - case cEntity::etTNT: /* TODO */ break; + case cEntity::etTNT: AddTNTEntity ((cTNTEntity *) a_Entity); break; case cEntity::etExpOrb: /* TODO */ break; case cEntity::etItemFrame: /* TODO */ break; case cEntity::etPainting: /* TODO */ break; diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 8a9e18413..3b486d2bc 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -41,6 +41,7 @@ class cMonster; class cPickup; class cItemGrid; class cProjectileEntity; +class cTNTEntity; @@ -107,6 +108,7 @@ protected: void AddMonsterEntity (cMonster * a_Monster); void AddPickupEntity (cPickup * a_Pickup); void AddProjectileEntity (cProjectileEntity * a_Projectile); + void AddTNTEntity (cTNTEntity * a_TNT); void AddMinecartChestContents(cMinecartWithChest * a_Minecart); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 680f2458f..fa0c4dbd9 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -36,6 +36,7 @@ #include "../Entities/Minecart.h" #include "../Entities/Pickup.h" #include "../Entities/ProjectileEntity.h" +#include "../Entities/TNTEntity.h" @@ -1231,6 +1232,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadPigZombieFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } + else if (strncmp(a_IDTag, "PrimedTnt", a_IDTagLength) == 0) + { + LoadTNTFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } // TODO: other entities } @@ -2167,6 +2172,29 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT +void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr TNT(new cTNTEntity(0.0, 0.0, 0.0, 0)); + if (!LoadEntityBaseFromNBT(*TNT.get(), a_NBT, a_TagIdx)) + { + return; + } + + // Load Fuse Ticks: + int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse"); + if (FuseTicks > 0) + { + int MojangFuseTicks = (int) a_NBT.GetByte(FuseTicks); + TNT->SetFuseTicks((double) MojangFuseTicks / 10); + } + + a_Entities.push_back(TNT.release()); +} + + + + + bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx) { double Pos[3]; diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index b26345b13..fe93d16c3 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -192,6 +192,7 @@ protected: void LoadWolfFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPigZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); /// Loads entity common data from the NBT compound; returns true if successful bool LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx); -- cgit v1.2.3 From baeff21a5b693a99057aa5a7dc218bf93630b35a Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 8 Mar 2014 10:29:57 +0100 Subject: Add new tnt documentation --- MCServer/Plugins/APIDump/APIDesc.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 39f7cbcd7..5cea49cb1 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2023,8 +2023,9 @@ end Desc = "This class manages a TNT entity.", Functions = { - GetCounterTime = { Return = "number", Notes = "Returns the time until the entity explodes." }, - GetMaxFuseTime = { Return = "number", Notes = "Returns how long the fuse was." }, + Explode = { Return = "", Notes = "Explode the tnt." }, + GetFuseTicks = { Return = "number", Notes = "Returns the fuse ticks (in seconds) until the tnt will explode." }, + SetFuseTicks = { Return = "number", Notes = "Set the fuse ticks (in seconds) until the tnt will explode." }, }, Inherits = "cEntity", }, -- cgit v1.2.3 From 6679641b9e5ddb833b32ab7163cabaa8003e769e Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 8 Mar 2014 12:53:15 +0200 Subject: cBlockInfo-related changes from #723 --- src/BlockInfo.cpp | 9 +++++++++ src/Blocks/BlockHandler.cpp | 1 + src/Items/ItemPickaxe.h | 22 +++++++++++----------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 399efcd9b..20336a07c 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -271,6 +271,11 @@ void cBlockInfo::Initialize(void) ms_Info[E_BLOCK_VINES ].m_IsSnowable = false; ms_Info[E_BLOCK_WALLSIGN ].m_IsSnowable = false; ms_Info[E_BLOCK_WATER ].m_IsSnowable = false; + ms_Info[E_BLOCK_RAIL ].m_IsSnowable = false; + ms_Info[E_BLOCK_ACTIVATOR_RAIL ].m_IsSnowable = false; + ms_Info[E_BLOCK_POWERED_RAIL ].m_IsSnowable = false; + ms_Info[E_BLOCK_DETECTOR_RAIL ].m_IsSnowable = false; + ms_Info[E_BLOCK_COBWEB ].m_IsSnowable = false; // Blocks that don't drop without a special tool: @@ -309,6 +314,10 @@ void cBlockInfo::Initialize(void) ms_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_RequiresSpecialTool = true; ms_Info[E_BLOCK_STONE_SLAB ].m_RequiresSpecialTool = true; ms_Info[E_BLOCK_VINES ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_FURNACE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_LIT_FURNACE ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_ANVIL ].m_RequiresSpecialTool = true; + ms_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_RequiresSpecialTool = true; // Nonsolid blocks: diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index c5165986c..aa97b2ca9 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -146,6 +146,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_NETHER_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType); case E_BLOCK_NETHER_WART: return new cBlockNetherWartHandler (a_BlockType); + case E_BLOCK_NETHER_QUARTZ_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_NEW_LEAVES: return new cBlockNewLeavesHandler (a_BlockType); case E_BLOCK_NEW_LOG: return new cBlockSidewaysHandler (a_BlockType); case E_BLOCK_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType); diff --git a/src/Items/ItemPickaxe.h b/src/Items/ItemPickaxe.h index bde7f0905..2a8e40daa 100644 --- a/src/Items/ItemPickaxe.h +++ b/src/Items/ItemPickaxe.h @@ -19,17 +19,13 @@ public: { switch(m_ItemType) { - case E_ITEM_WOODEN_PICKAXE: - case E_ITEM_GOLD_PICKAXE: - return 1; - case E_ITEM_STONE_PICKAXE: - return 2; - case E_ITEM_IRON_PICKAXE: - return 3; - case E_ITEM_DIAMOND_PICKAXE: - return 4; - default: - return 0; + case E_ITEM_WOODEN_PICKAXE: return 1; + case E_ITEM_GOLD_PICKAXE: return 1; + case E_ITEM_STONE_PICKAXE: return 2; + case E_ITEM_IRON_PICKAXE: return 3; + case E_ITEM_DIAMOND_PICKAXE: return 4; + + default: return 0; } } @@ -61,6 +57,10 @@ public: return PickaxeLevel() >= 2; } + case E_BLOCK_ANVIL: + case E_BLOCK_ENCHANTMENT_TABLE: + case E_BLOCK_FURNACE: + case E_BLOCK_LIT_FURNACE: case E_BLOCK_COAL_ORE: case E_BLOCK_STONE: case E_BLOCK_COBBLESTONE: -- cgit v1.2.3 From b37966fd214fb048a415a33291a85ee8c263691c Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 8 Mar 2014 12:24:33 +0100 Subject: Change TNT Fuse to ticks --- src/BlockEntities/DispenserEntity.cpp | 2 +- src/Entities/TNTEntity.cpp | 12 ++++++------ src/Entities/TNTEntity.h | 10 +++++----- src/Items/ItemLighter.h | 4 ++-- src/Simulator/IncrementalRedstoneSimulator.cpp | 2 +- src/World.cpp | 4 ++-- src/World.h | 2 +- src/WorldStorage/NBTChunkSerializer.cpp | 2 +- src/WorldStorage/WSSAnvil.cpp | 3 +-- 9 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 374f3d6e3..cbfbb1b6a 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -116,7 +116,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) { double TNTX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); double TNTZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - m_World->SpawnPrimedTNT(TNTX, DispY + 0.5, TNTZ, 4, 0); // 4 seconds fuse, no initial velocity + m_World->SpawnPrimedTNT(TNTX, DispY + 0.5, TNTZ, 80, 0); // 80 ticks fuse, no initial velocity m_Contents.ChangeSlotCount(a_SlotNum, -1); } break; diff --git a/src/Entities/TNTEntity.cpp b/src/Entities/TNTEntity.cpp index 4f361403c..02f31f5bb 100644 --- a/src/Entities/TNTEntity.cpp +++ b/src/Entities/TNTEntity.cpp @@ -8,9 +8,9 @@ -cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec) : +cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, int a_FuseTicks) : super(etTNT, a_X, a_Y, a_Z, 0.98, 0.98), - m_FuseTicks(a_FuseTimeInSec) + m_FuseTicks(a_FuseTicks) { } @@ -18,9 +18,9 @@ cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSe -cTNTEntity::cTNTEntity(const Vector3d & a_Pos, double a_FuseTimeInSec) : +cTNTEntity::cTNTEntity(const Vector3d & a_Pos, int a_FuseTicks) : super(etTNT, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98), - m_FuseTicks(a_FuseTimeInSec) + m_FuseTicks(a_FuseTicks) { } @@ -56,8 +56,8 @@ void cTNTEntity::Tick(float a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); BroadcastMovementUpdate(); - float delta_time = a_Dt / 1000; // Convert miliseconds to seconds - m_FuseTicks -= delta_time; + + m_FuseTicks -= 1; if (m_FuseTicks <= 0) { Explode(); diff --git a/src/Entities/TNTEntity.h b/src/Entities/TNTEntity.h index 8f83f52d9..116f5a8cb 100644 --- a/src/Entities/TNTEntity.h +++ b/src/Entities/TNTEntity.h @@ -16,8 +16,8 @@ public: // tolua_end CLASS_PROTODEF(cTNTEntity); - cTNTEntity(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec = 4); - cTNTEntity(const Vector3d & a_Pos, double a_FuseTimeInSec = 4); + cTNTEntity(double a_X, double a_Y, double a_Z, int a_FuseTicks = 80); + cTNTEntity(const Vector3d & a_Pos, int a_FuseTicks = 80); // cEntity overrides: virtual void SpawnOn(cClientHandle & a_ClientHandle) override; @@ -29,15 +29,15 @@ public: void Explode(void); /** Returns the fuse ticks until the tnt will explode */ - double GetFuseTicks(void) const { return m_FuseTicks; } + int GetFuseTicks(void) const { return m_FuseTicks; } /** Set the fuse ticks until the tnt will explode */ - void SetFuseTicks(double a_FuseTicks) { m_FuseTicks = a_FuseTicks; } + void SetFuseTicks(int a_FuseTicks) { m_FuseTicks = a_FuseTicks; } // tolua_end protected: - double m_FuseTicks; ///< How much time in seconds is left, while the tnt will explode + int m_FuseTicks; ///< How much ticks is left, while the tnt will explode }; // tolua_export diff --git a/src/Items/ItemLighter.h b/src/Items/ItemLighter.h index cc7daeb08..18873e911 100644 --- a/src/Items/ItemLighter.h +++ b/src/Items/ItemLighter.h @@ -33,8 +33,8 @@ public: case E_BLOCK_TNT: { // Activate the TNT: - a_World->BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); - a_World->SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 4); // 4 seconds to boom + a_World->BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0f, 1.0f); + a_World->SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); // 80 ticks to boom a_World->SetBlock(a_BlockX,a_BlockY,a_BlockZ, E_BLOCK_AIR, 0); break; } diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index f377b0aa7..ca2ef4b1a 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -838,7 +838,7 @@ void cIncrementalRedstoneSimulator::HandleTNT(int a_BlockX, int a_BlockY, int a_ if (AreCoordsPowered(a_BlockX, a_BlockY, a_BlockZ)) { m_World.BroadcastSoundEffect("game.tnt.primed", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f); - m_World.SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 4); // 4 seconds to boom + m_World.SpawnPrimedTNT(a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5); // 80 ticks to boom m_World.SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); } } diff --git a/src/World.cpp b/src/World.cpp index ecb278e85..ebc37f7b2 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1725,10 +1725,10 @@ int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType -void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec, double a_InitialVelocityCoeff) +void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks, double a_InitialVelocityCoeff) { UNUSED(a_InitialVelocityCoeff); - cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTimeInSec); + cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTicks); TNT->Initialize(this); // TODO: Add a bit of speed in horiz and vert axes, based on the a_InitialVelocityCoeff } diff --git a/src/World.h b/src/World.h index e6c665785..517b6b4fa 100644 --- a/src/World.h +++ b/src/World.h @@ -445,7 +445,7 @@ public: int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward); /** Spawns a new primed TNT entity at the specified block coords and specified fuse duration. Initial velocity is given based on the relative coefficient provided */ - void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec, double a_InitialVelocityCoeff = 1); + void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTimeInSec = 80, double a_InitialVelocityCoeff = 1); // tolua_end diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 06b815333..17cf838c3 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -588,7 +588,7 @@ void cNBTChunkSerializer::AddTNTEntity(cTNTEntity * a_TNT) { m_Writer.BeginCompound(""); AddBasicEntity(a_TNT, "PrimedTnt"); - m_Writer.AddByte("Fuse", ((unsigned char)a_TNT->GetFuseTicks()) * 10); + m_Writer.AddByte("Fuse", (unsigned char)a_TNT->GetFuseTicks()); m_Writer.EndCompound(); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index fa0c4dbd9..b52b74932 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -2184,8 +2184,7 @@ void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse"); if (FuseTicks > 0) { - int MojangFuseTicks = (int) a_NBT.GetByte(FuseTicks); - TNT->SetFuseTicks((double) MojangFuseTicks / 10); + TNT->SetFuseTicks((int) a_NBT.GetByte(FuseTicks)); } a_Entities.push_back(TNT.release()); -- cgit v1.2.3 From 60091bcba3f5e533a5b2a749e40f52556297e867 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 8 Mar 2014 12:31:20 +0100 Subject: Change tnt documentation to ticks --- MCServer/Plugins/APIDump/APIDesc.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 6d8272a95..28dffc1b6 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2026,8 +2026,8 @@ end Functions = { Explode = { Return = "", Notes = "Explode the tnt." }, - GetFuseTicks = { Return = "number", Notes = "Returns the fuse ticks (in seconds) until the tnt will explode." }, - SetFuseTicks = { Return = "number", Notes = "Set the fuse ticks (in seconds) until the tnt will explode." }, + GetFuseTicks = { Return = "number", Notes = "Returns the fuse ticks until the tnt will explode." }, + SetFuseTicks = { Return = "number", Notes = "Set the fuse ticks until the tnt will explode." }, }, Inherits = "cEntity", }, @@ -2262,7 +2262,7 @@ end SpawnMob = { Params = "X, Y, Z, {{cMonster|MonsterType}}", Return = "EntityID", Notes = "Spawns the specified type of mob at the specified coords. Returns the EntityID of the creates entity, or -1 on failure. " }, SpawnFallingBlock = { Params = "X, Y, Z, BlockType, BlockMeta", Return = "EntityID", Notes = "Spawns an {{cFallingBlock|Falling Block}} entity at the specified coords with the given block type/meta" }, SpawnExperienceOrb = { Params = "X, Y, Z, Reward", Return = "EntityID", Notes = "Spawns an {{cExpOrb|experience orb}} at the specified coords, with the given reward" }, - SpawnPrimedTNT = { Params = "X, Y, Z, FuseTimeSecs, InitialVelocityCoeff", Return = "", Notes = "Spawns a {{cTNTEntity|primed TNT entity}} at the specified coords, with the given fuse time. The entity gets a random speed multiplied by the InitialVelocityCoeff, 1 being the default value." }, + SpawnPrimedTNT = { Params = "X, Y, Z, FuseTicks, InitialVelocityCoeff", Return = "", Notes = "Spawns a {{cTNTEntity|primed TNT entity}} at the specified coords, with the given fuse ticks. The entity gets a random speed multiplied by the InitialVelocityCoeff, 1 being the default value." }, TryGetHeight = { Params = "BlockX, BlockZ", Return = "IsValid, Height", Notes = "Returns true and height of the highest non-air block if the chunk is loaded, or false otherwise." }, UpdateSign = { Params = "X, Y, Z, Line1, Line2, Line3, Line4, [{{cPlayer|Player}}]", Return = "", Notes = "Sets the sign text at the specified coords. The sign-updating hooks are called for the change. The Player parameter is used to indicate the player from whom the change has come, it may be nil. Same as SetSignLiens()" }, UseBlockEntity = { Params = "{{cPlayer|Player}}, BlockX, BlockY, BlockZ", Return = "", Notes = "Makes the specified Player use the block entity at the specified coords (open chest UI, etc.) If the cords are in an unloaded chunk or there's no block entity, ignores the call." }, -- cgit v1.2.3 From 16ebbca35b8fc91061f0141625c292a8096e3b6d Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 8 Mar 2014 14:23:00 +0000 Subject: Moved returns --- src/Blocks/MetaRotater.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Blocks/MetaRotater.h b/src/Blocks/MetaRotater.h index 5493c87e2..d3664b6f1 100644 --- a/src/Blocks/MetaRotater.h +++ b/src/Blocks/MetaRotater.h @@ -1,4 +1,3 @@ - // MetaRotater.h // Provides a mixin for rotations and reflections @@ -44,11 +43,12 @@ NIBBLETYPE cMetaRotater NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) { @@ -63,8 +63,8 @@ NIBBLETYPE cMetaRotater Date: Sat, 8 Mar 2014 15:21:09 +0000 Subject: Disable -Werror on this branch --- SetFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 35831e7e9..6a8211fa2 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -182,7 +182,7 @@ macro(set_exe_flags) string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") - add_flags_cxx("-Wall -Wextra -Werror -Wno-error=unused-parameter") + add_flags_cxx("-Wall -Wextra") # we support non-IEEE 754 fpus so can make no guarentees about error add_flags_cxx("-ffast-math") -- cgit v1.2.3 From 9b47366d0323f09c77b607da778191e79b65335b Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 8 Mar 2014 07:36:52 -0800 Subject: Actually Fixed ByteBuffer --- src/ByteBuffer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 32a367462..8080c1bdc 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -650,7 +650,7 @@ bool cByteBuffer::WriteLEInt(int a_Value) -bool cByteBuffer::ReadBuf(void * a_Buffer, int a_Count) +bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count) { CHECK_THREAD; CheckValid(); @@ -684,7 +684,7 @@ bool cByteBuffer::ReadBuf(void * a_Buffer, int a_Count) -bool cByteBuffer::WriteBuf(const void * a_Buffer, int a_Count) +bool cByteBuffer::WriteBuf(const void * a_Buffer, size_t a_Count) { CHECK_THREAD; CheckValid(); @@ -714,7 +714,7 @@ bool cByteBuffer::WriteBuf(const void * a_Buffer, int a_Count) -bool cByteBuffer::ReadString(AString & a_String, int a_Count) +bool cByteBuffer::ReadString(AString & a_String, size_t a_Count) { CHECK_THREAD; CheckValid(); -- cgit v1.2.3 From 307fad0f257c825c8d433a3e82f2989a8fddd3e0 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 8 Mar 2014 08:33:38 -0800 Subject: Fixed issues with int vs size_t and a few other warnings --- src/BlockInfo.cpp | 2 -- src/Blocks/BlockHandler.h | 2 ++ src/ByteBuffer.cpp | 20 ++++++++++---------- src/ByteBuffer.h | 6 +++--- src/ClientHandle.cpp | 4 ++-- src/Entities/Minecart.cpp | 4 ++-- src/Entities/Minecart.h | 4 ++-- src/Protocol/Protocol17x.cpp | 4 ++-- src/Root.cpp | 6 ++---- src/Simulator/DelayedFluidSimulator.cpp | 2 +- 10 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 20336a07c..d1ecfdf7e 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -42,8 +42,6 @@ cBlockInfo::~cBlockInfo() cBlockInfo & cBlockInfo::Get(BLOCKTYPE a_Type) { - ASSERT(a_Type < 256); - return ms_Info[a_Type]; } diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index 50c2e2ad5..3a3efb3cc 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -23,6 +23,8 @@ class cBlockHandler { public: cBlockHandler(BLOCKTYPE a_BlockType); + + virtual ~cBlockHandler() {} /// Called when the block gets ticked either by a random tick or by a queued tick. /// Note that the coords are chunk-relative! diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 8080c1bdc..bda1105f5 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -177,15 +177,15 @@ bool cByteBuffer::Write(const char * a_Bytes, size_t a_Count) CheckValid(); // Store the current free space for a check after writing: - int CurFreeSpace = GetFreeSpace(); - int CurReadableSpace = GetReadableSpace(); - int WrittenBytes = 0; + size_t CurFreeSpace = GetFreeSpace(); + size_t CurReadableSpace = GetReadableSpace(); + size_t WrittenBytes = 0; if (CurFreeSpace < a_Count) { return false; } - int TillEnd = m_BufferSize - m_WritePos; + size_t TillEnd = m_BufferSize - m_WritePos; if (TillEnd <= a_Count) { // Need to wrap around the ringbuffer end @@ -216,7 +216,7 @@ bool cByteBuffer::Write(const char * a_Bytes, size_t a_Count) -int cByteBuffer::GetFreeSpace(void) const +size_t cByteBuffer::GetFreeSpace(void) const { CHECK_THREAD; CheckValid(); @@ -234,7 +234,7 @@ int cByteBuffer::GetFreeSpace(void) const /// Returns the number of bytes that are currently in the ringbuffer. Note GetReadableBytes() -int cByteBuffer::GetUsedSpace(void) const +size_t cByteBuffer::GetUsedSpace(void) const { CHECK_THREAD; CheckValid(); @@ -246,7 +246,7 @@ int cByteBuffer::GetUsedSpace(void) const /// Returns the number of bytes that are currently available for reading (may be less than UsedSpace due to some data having been read already) -int cByteBuffer::GetReadableSpace(void) const +size_t cByteBuffer::GetReadableSpace(void) const { CHECK_THREAD; CheckValid(); @@ -657,7 +657,7 @@ bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count) ASSERT(a_Count >= 0); NEEDBYTES(a_Count); char * Dst = (char *)a_Buffer; // So that we can do byte math - int BytesToEndOfBuffer = m_BufferSize - m_ReadPos; + size_t BytesToEndOfBuffer = m_BufferSize - m_ReadPos; ASSERT(BytesToEndOfBuffer >= 0); // Sanity check if (BytesToEndOfBuffer <= a_Count) { @@ -691,7 +691,7 @@ bool cByteBuffer::WriteBuf(const void * a_Buffer, size_t a_Count) ASSERT(a_Count >= 0); PUTBYTES(a_Count); char * Src = (char *)a_Buffer; // So that we can do byte math - int BytesToEndOfBuffer = m_BufferSize - m_WritePos; + size_t BytesToEndOfBuffer = m_BufferSize - m_WritePos; if (BytesToEndOfBuffer <= a_Count) { // Reading across the ringbuffer end, read the first part and adjust parameters: @@ -722,7 +722,7 @@ bool cByteBuffer::ReadString(AString & a_String, size_t a_Count) NEEDBYTES(a_Count); a_String.clear(); a_String.reserve(a_Count); - int BytesToEndOfBuffer = m_BufferSize - m_ReadPos; + size_t BytesToEndOfBuffer = m_BufferSize - m_ReadPos; ASSERT(BytesToEndOfBuffer >= 0); // Sanity check if (BytesToEndOfBuffer <= a_Count) { diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index 5fdf48c28..ed2e10a55 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -34,13 +34,13 @@ public: bool Write(const char * a_Bytes, size_t a_Count); /// Returns the number of bytes that can be successfully written to the ringbuffer - int GetFreeSpace(void) const; + size_t GetFreeSpace(void) const; /// Returns the number of bytes that are currently in the ringbuffer. Note GetReadableBytes() - int GetUsedSpace(void) const; + size_t GetUsedSpace(void) const; /// Returns the number of bytes that are currently available for reading (may be less than UsedSpace due to some data having been read already) - int GetReadableSpace(void) const; + size_t GetReadableSpace(void) const; /// Returns the current data start index. For debugging purposes. int GetDataStart(void) const { return m_DataStart; } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 870568cdf..53c859721 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -96,8 +96,8 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) : m_ShouldCheckDownloaded(false), m_NumExplosionsThisTick(0), m_UniqueID(0), - m_Locale("en_GB"), - m_HasSentPlayerChunk(false) + m_HasSentPlayerChunk(false), + m_Locale("en_GB") { m_Protocol = new cProtocolRecognizer(this); diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index f52a7b6d9..7f38aa35a 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -1031,9 +1031,9 @@ cMinecartWithChest::cMinecartWithChest(double a_X, double a_Y, double a_Z) : -void cMinecartWithChest::SetSlot(int a_Idx, const cItem & a_Item) +void cMinecartWithChest::SetSlot(size_t a_Idx, const cItem & a_Item) { - ASSERT((a_Idx >= 0) && (a_Idx < ARRAYCOUNT(m_Items))); + ASSERT(a_Idx < ARRAYCOUNT(m_Items)); m_Items[a_Idx] = a_Item; } diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index 073e78953..ebdb576e0 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -122,7 +122,7 @@ public: const cItem & GetSlot(int a_Idx) const { return m_Items[a_Idx]; } cItem & GetSlot(int a_Idx) { return m_Items[a_Idx]; } - void SetSlot(int a_Idx, const cItem & a_Item); + void SetSlot(size_t a_Idx, const cItem & a_Item); protected: @@ -193,4 +193,4 @@ public: CLASS_PROTODEF(cMinecartWithHopper); cMinecartWithHopper(double a_X, double a_Y, double a_Z); -} ; \ No newline at end of file +} ; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index cb9e5b9b1..8e0d33227 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1244,7 +1244,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) if (m_ReceivedData.GetReadableSpace() > 0) { AString AllData; - int OldReadableSpace = m_ReceivedData.GetReadableSpace(); + size_t OldReadableSpace = m_ReceivedData.GetReadableSpace(); m_ReceivedData.ReadAll(AllData); m_ReceivedData.ResetRead(); m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); @@ -1366,7 +1366,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) if (g_ShouldLogCommIn && (m_ReceivedData.GetReadableSpace() > 0)) { AString AllData; - int OldReadableSpace = m_ReceivedData.GetReadableSpace(); + size_t OldReadableSpace = m_ReceivedData.GetReadableSpace(); m_ReceivedData.ReadAll(AllData); m_ReceivedData.ResetRead(); m_ReceivedData.SkipRead(m_ReceivedData.GetReadableSpace() - OldReadableSpace); diff --git a/src/Root.cpp b/src/Root.cpp index 78c94888d..69f18104e 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -593,7 +593,6 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac unsigned m_NameLength; const AString m_PlayerName; - cPlayerListCallback & m_Callback; virtual bool Item (cPlayer * a_pPlayer) { unsigned int Rating = RateCompareString (m_PlayerName, a_pPlayer->GetName()); @@ -615,18 +614,17 @@ bool cRoot::FindAndDoWithPlayer(const AString & a_PlayerName, cPlayerListCallbac } public: - cCallback (const AString & a_PlayerName, cPlayerListCallback & a_Callback) : + cCallback (const AString & a_PlayerName) : m_BestRating(0), m_NameLength(a_PlayerName.length()), m_PlayerName(a_PlayerName), - m_Callback(a_Callback), m_BestMatch(NULL), m_NumMatches(0) {} cPlayer * m_BestMatch; unsigned m_NumMatches; - } Callback (a_PlayerName, a_Callback); + } Callback (a_PlayerName); ForEachPlayer( Callback ); if (Callback.m_NumMatches == 1) diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp index 3d2170e44..bc5158d95 100644 --- a/src/Simulator/DelayedFluidSimulator.cpp +++ b/src/Simulator/DelayedFluidSimulator.cpp @@ -20,7 +20,7 @@ bool cDelayedFluidSimulatorChunkData::cSlot::Add(int a_RelX, int a_RelY, int a_RelZ) { ASSERT(a_RelZ >= 0); - ASSERT(a_RelZ < ARRAYCOUNT(m_Blocks)); + ASSERT(a_RelZ < static_cast(ARRAYCOUNT(m_Blocks))); cCoordWithIntVector & Blocks = m_Blocks[a_RelZ]; int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); -- cgit v1.2.3 From 66970fe943ccc414c2f4fb722852f0461b8ddca2 Mon Sep 17 00:00:00 2001 From: Jan-Fabian Humann Date: Sat, 8 Mar 2014 17:55:53 +0100 Subject: Split cClientHandle::HandleEntityAction() into three seperate functions HandleEntityCrouch, HandleEntityLeaveBed and HandleEntitySprinting. --- src/ClientHandle.cpp | 58 +++++++++++++++++++++++--------------------- src/ClientHandle.h | 4 ++- src/Protocol/Protocol125.cpp | 23 +++++++++++++++++- src/Protocol/Protocol16x.cpp | 23 +++++++++++++++++- src/Protocol/Protocol17x.cpp | 22 ++++++++++++++++- 5 files changed, 98 insertions(+), 32 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 870568cdf..79fdc5e04 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1453,7 +1453,7 @@ bool cClientHandle::HandleHandshake(const AString & a_Username) -void cClientHandle::HandleEntityAction(int a_EntityID, char a_ActionID) +void cClientHandle::HandleEntityCrouch(int a_EntityID, bool a_IsCrouching) { if (a_EntityID != m_Player->GetUniqueID()) { @@ -1461,35 +1461,37 @@ void cClientHandle::HandleEntityAction(int a_EntityID, char a_ActionID) return; } - switch (a_ActionID) + m_Player->SetCrouch(a_IsCrouching); +} + + + + + +void cClientHandle::HandleEntityLeaveBed(int a_EntityID) +{ + if (a_EntityID != m_Player->GetUniqueID()) { - case 1: // Crouch - { - m_Player->SetCrouch(true); - break; - } - case 2: // Uncrouch - { - m_Player->SetCrouch(false); - break; - } - case 3: // Leave bed - { - m_Player->GetWorld()->BroadcastEntityAnimation(*m_Player, 2); - break; - } - case 4: // Start sprinting - { - m_Player->SetSprint(true); - break; - } - case 5: // Stop sprinting - { - m_Player->SetSprint(false); - SendPlayerMaxSpeed(); - break; - } + // We should only receive entity actions from the entity that is performing the action + return; } + + m_Player->GetWorld()->BroadcastEntityAnimation(*m_Player, 2); +} + + + + + +void cClientHandle::HandleEntitySprinting(int a_EntityID, bool a_IsSprinting) +{ + if (a_EntityID != m_Player->GetUniqueID()) + { + // We should only receive entity actions from the entity that is performing the action + return; + } + + m_Player->SetSprint(a_IsSprinting); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 194533402..035fadfe4 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -188,7 +188,9 @@ public: void HandleChat (const AString & a_Message); void HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem); void HandleDisconnect (const AString & a_Reason); - void HandleEntityAction (int a_EntityID, char a_ActionID); + void HandleEntityCrouch (int a_EntityID, bool a_IsCrouching); + void HandleEntityLeaveBed (int a_EntityID); + void HandleEntitySprinting (int a_EntityID, bool a_IsSprinting); /** Called when the protocol handshake has been received (for protocol versions that support it; otherwise the first instant when a username is received). diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 3980350f5..556ed1d08 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1375,7 +1375,28 @@ int cProtocol125::ParseEntityAction(void) { HANDLE_PACKET_READ(ReadBEInt, int, EntityID); HANDLE_PACKET_READ(ReadChar, char, ActionID); - m_Client->HandleEntityAction(EntityID, ActionID); + + if (ActionID == 1) // Crouch + { + m_Client->HandleEntityCrouch(EntityID, true); + } + else if (ActionID == 2) // Uncrouch + { + m_Client->HandleEntityCrouch(EntityID, false); + } + else if (ActionID == 3) // Leave Bed + { + m_Client->HandleEntityLeaveBed(EntityID); + } + else if (ActionID == 4) // Start sprinting + { + m_Client->HandleEntitySprinting(EntityID, true); + } + else if (ActionID == 5) // Stop sprinting + { + m_Client->HandleEntitySprinting(EntityID, false); + } + return PARSE_OK; } diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp index cfa27b3c4..6a41a577f 100644 --- a/src/Protocol/Protocol16x.cpp +++ b/src/Protocol/Protocol16x.cpp @@ -184,7 +184,28 @@ int cProtocol161::ParseEntityAction(void) HANDLE_PACKET_READ(ReadBEInt, int, EntityID); HANDLE_PACKET_READ(ReadChar, char, ActionID); HANDLE_PACKET_READ(ReadBEInt, int, UnknownHorseVal); - m_Client->HandleEntityAction(EntityID, ActionID); + + if (ActionID == 1) // Crouch + { + m_Client->HandleEntityCrouch(EntityID, true); + } + else if (ActionID == 2) // Uncrouch + { + m_Client->HandleEntityCrouch(EntityID, false); + } + else if (ActionID == 3) // Leave Bed + { + m_Client->HandleEntityLeaveBed(EntityID); + } + else if (ActionID == 4) // Start sprinting + { + m_Client->HandleEntitySprinting(EntityID, true); + } + else if (ActionID == 5) // Stop sprinting + { + m_Client->HandleEntitySprinting(EntityID, false); + } + return PARSE_OK; } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 18646254f..19998a483 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1732,7 +1732,27 @@ void cProtocol172::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadBEInt, int, PlayerID); HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Action); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, JumpBoost); - m_Client->HandleEntityAction(PlayerID, Action); + + if (Action == 1) // Crouch + { + m_Client->HandleEntityCrouch(PlayerID, true); + } + else if (Action == 2) // Uncrouch + { + m_Client->HandleEntityCrouch(PlayerID, false); + } + else if (Action == 3) // Leave Bed + { + m_Client->HandleEntityLeaveBed(PlayerID); + } + else if (Action == 4) // Start sprinting + { + m_Client->HandleEntitySprinting(PlayerID, true); + } + else if (Action == 5) // Stop sprinting + { + m_Client->HandleEntitySprinting(PlayerID, false); + } } -- cgit v1.2.3 From 72f9c8b06970cb351121ad1e02cccc268db8c56d Mon Sep 17 00:00:00 2001 From: Jan-Fabian Humann Date: Sat, 8 Mar 2014 19:26:32 +0100 Subject: Changed if-else to switch-case --- src/Protocol/Protocol125.cpp | 24 +++++++++++------------- src/Protocol/Protocol16x.cpp | 24 +++++++++++------------- src/Protocol/Protocol17x.cpp | 24 +++++++++++------------- 3 files changed, 33 insertions(+), 39 deletions(-) diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 556ed1d08..169ab0c85 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1376,25 +1376,23 @@ int cProtocol125::ParseEntityAction(void) HANDLE_PACKET_READ(ReadBEInt, int, EntityID); HANDLE_PACKET_READ(ReadChar, char, ActionID); - if (ActionID == 1) // Crouch + switch (ActionID) { + case 1: // Crouch m_Client->HandleEntityCrouch(EntityID, true); - } - else if (ActionID == 2) // Uncrouch - { + break; + case 2: // Uncrouch m_Client->HandleEntityCrouch(EntityID, false); - } - else if (ActionID == 3) // Leave Bed - { + break; + case 3: // Leave Bed m_Client->HandleEntityLeaveBed(EntityID); - } - else if (ActionID == 4) // Start sprinting - { + break; + case 4: // Start sprinting m_Client->HandleEntitySprinting(EntityID, true); - } - else if (ActionID == 5) // Stop sprinting - { + break; + case 5: // Stop sprinting m_Client->HandleEntitySprinting(EntityID, false); + break; } return PARSE_OK; diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp index 6a41a577f..4b1b4f408 100644 --- a/src/Protocol/Protocol16x.cpp +++ b/src/Protocol/Protocol16x.cpp @@ -185,25 +185,23 @@ int cProtocol161::ParseEntityAction(void) HANDLE_PACKET_READ(ReadChar, char, ActionID); HANDLE_PACKET_READ(ReadBEInt, int, UnknownHorseVal); - if (ActionID == 1) // Crouch + switch (ActionID) { + case 1: // Crouch m_Client->HandleEntityCrouch(EntityID, true); - } - else if (ActionID == 2) // Uncrouch - { + break; + case 2: // Uncrouch m_Client->HandleEntityCrouch(EntityID, false); - } - else if (ActionID == 3) // Leave Bed - { + break; + case 3: // Leave Bed m_Client->HandleEntityLeaveBed(EntityID); - } - else if (ActionID == 4) // Start sprinting - { + break; + case 4: // Start sprinting m_Client->HandleEntitySprinting(EntityID, true); - } - else if (ActionID == 5) // Stop sprinting - { + break; + case 5: // Stop sprinting m_Client->HandleEntitySprinting(EntityID, false); + break; } return PARSE_OK; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 19998a483..b0ec72a7d 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1733,25 +1733,23 @@ void cProtocol172::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Action); HANDLE_READ(a_ByteBuffer, ReadBEInt, int, JumpBoost); - if (Action == 1) // Crouch + switch (Action) { + case 1: // Crouch m_Client->HandleEntityCrouch(PlayerID, true); - } - else if (Action == 2) // Uncrouch - { + break; + case 2: // Unchrouch m_Client->HandleEntityCrouch(PlayerID, false); - } - else if (Action == 3) // Leave Bed - { + break; + case 3: // Leave Bed m_Client->HandleEntityLeaveBed(PlayerID); - } - else if (Action == 4) // Start sprinting - { + break; + case 4: // Start sprinting m_Client->HandleEntitySprinting(PlayerID, true); - } - else if (Action == 5) // Stop sprinting - { + break; + case 5: // Stop sprinting m_Client->HandleEntitySprinting(PlayerID, false); + break; } } -- cgit v1.2.3 From 27fa2b72ba629e8175d33dace463bd7b7035a6e0 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 8 Mar 2014 11:05:37 -0800 Subject: Enabled self test of bytebuffer --- src/ByteBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index bda1105f5..adb8e9294 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -44,7 +44,7 @@ -#if 0 +#ifdef SELF_TEST /// Self-test of the VarInt-reading and writing code class cByteBufferSelfTest -- cgit v1.2.3 From a6ed75c1fbd7d3a38336e8649b59950837529b14 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 8 Mar 2014 11:18:51 -0800 Subject: Added tons more asserts to bytebuffer --- src/ByteBuffer.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index adb8e9294..67fe1012c 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -185,6 +185,7 @@ bool cByteBuffer::Write(const char * a_Bytes, size_t a_Count) { return false; } + ASSERT(m_BufferSize >= m_WritePos); size_t TillEnd = m_BufferSize - m_WritePos; if (TillEnd <= a_Count) { @@ -223,9 +224,13 @@ size_t cByteBuffer::GetFreeSpace(void) const if (m_WritePos >= m_DataStart) { // Wrap around the buffer end: + ASSERT(m_BufferSize >= m_WritePos); + ASSERT((m_BufferSize - m_WritePos + m_DataStart) >= 1); return m_BufferSize - m_WritePos + m_DataStart - 1; } // Single free space partition: + ASSERT(m_BufferSize >= m_WritePos); + ASSERT(m_BufferSize - m_WritePos >= 1); return m_DataStart - m_WritePos - 1; } @@ -238,6 +243,8 @@ size_t cByteBuffer::GetUsedSpace(void) const { CHECK_THREAD; CheckValid(); + ASSERT(m_BufferSize >= GetFreeSpace()); + ASSERT((m_BufferSize - GetFreeSpace()) >= 1); return m_BufferSize - GetFreeSpace() - 1; } @@ -253,9 +260,11 @@ size_t cByteBuffer::GetReadableSpace(void) const if (m_ReadPos > m_WritePos) { // Wrap around the buffer end: + ASSERT(m_BufferSize >= m_ReadPos); return m_BufferSize - m_ReadPos + m_WritePos; } // Single readable space partition: + ASSERT(m_WritePos >= m_ReadPos); return m_WritePos - m_ReadPos ; } @@ -654,11 +663,10 @@ bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count) { CHECK_THREAD; CheckValid(); - ASSERT(a_Count >= 0); NEEDBYTES(a_Count); char * Dst = (char *)a_Buffer; // So that we can do byte math + ASSERT(m_BufferSize >= m_ReadPos); size_t BytesToEndOfBuffer = m_BufferSize - m_ReadPos; - ASSERT(BytesToEndOfBuffer >= 0); // Sanity check if (BytesToEndOfBuffer <= a_Count) { // Reading across the ringbuffer end, read the first part and adjust parameters: @@ -688,9 +696,9 @@ bool cByteBuffer::WriteBuf(const void * a_Buffer, size_t a_Count) { CHECK_THREAD; CheckValid(); - ASSERT(a_Count >= 0); PUTBYTES(a_Count); char * Src = (char *)a_Buffer; // So that we can do byte math + ASSERT(m_BufferSize >= m_ReadPos); size_t BytesToEndOfBuffer = m_BufferSize - m_WritePos; if (BytesToEndOfBuffer <= a_Count) { @@ -718,18 +726,18 @@ bool cByteBuffer::ReadString(AString & a_String, size_t a_Count) { CHECK_THREAD; CheckValid(); - ASSERT(a_Count >= 0); NEEDBYTES(a_Count); a_String.clear(); a_String.reserve(a_Count); + ASSERT(m_BufferSize >= m_ReadPos); size_t BytesToEndOfBuffer = m_BufferSize - m_ReadPos; - ASSERT(BytesToEndOfBuffer >= 0); // Sanity check if (BytesToEndOfBuffer <= a_Count) { // Reading across the ringbuffer end, read the first part and adjust parameters: if (BytesToEndOfBuffer > 0) { a_String.assign(m_Buffer + m_ReadPos, BytesToEndOfBuffer); + ASSERT(a_Count >= BytesToEndOfBuffer); a_Count -= BytesToEndOfBuffer; } m_ReadPos = 0; @@ -771,7 +779,6 @@ bool cByteBuffer::SkipRead(size_t a_Count) { CHECK_THREAD; CheckValid(); - ASSERT(a_Count >= 0); if (!CanReadBytes(a_Count)) { return false; @@ -809,6 +816,7 @@ bool cByteBuffer::ReadToByteBuffer(cByteBuffer & a_Dst, size_t a_NumBytes) size_t num = (a_NumBytes > sizeof(buf)) ? sizeof(buf) : a_NumBytes; VERIFY(ReadBuf(buf, num)); VERIFY(a_Dst.Write(buf, num)); + ASSERT(a_NumBytes >= num); a_NumBytes -= num; } return true; @@ -846,13 +854,15 @@ void cByteBuffer::ReadAgain(AString & a_Out) // Used by ProtoProxy to repeat communication twice, once for parsing and the other time for the remote party CHECK_THREAD; CheckValid(); - int DataStart = m_DataStart; + size_t DataStart = m_DataStart; if (m_ReadPos < m_DataStart) { // Across the ringbuffer end, read the first part and adjust next part's start: + ASSERT(m_BufferSize >= m_DataStart); a_Out.append(m_Buffer + m_DataStart, m_BufferSize - m_DataStart); DataStart = 0; } + ASSERT(m_ReadPos >= DataStart); a_Out.append(m_Buffer + DataStart, m_ReadPos - DataStart); } -- cgit v1.2.3 From 6b530bde75b33be5f88444cc583548a2e7292a97 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 8 Mar 2014 11:53:37 -0800 Subject: Added static --- src/ByteBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 67fe1012c..a3b40e5ef 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -47,7 +47,7 @@ #ifdef SELF_TEST /// Self-test of the VarInt-reading and writing code -class cByteBufferSelfTest +static class cByteBufferSelfTest { public: cByteBufferSelfTest(void) -- cgit v1.2.3 From 17f27d1750083dc0a3eb958d554184839d7f92f2 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 8 Mar 2014 21:14:59 +0100 Subject: Added switch case indent notice --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a0a332f30..7ec7058ae 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,8 +22,10 @@ Code Stuff - This helps prevent mistakes such as `if (a & 1 == 0)` * White space is free, so use it freely - "freely" as in "plentifully", not "arbitrarily" + * All `case` statements inside a `switch` need an extra indent. * Each and every control statement deserves its braces. This helps maintainability later on when the file is edited, lines added or removed - the control logic doesn't break so easily. - The only exception: a `switch` statement with all `case` statements being a single short statement is allowed to use the short brace-less form. + - These two rules really mean that indent is governed by braces * Add an empty last line in all source files (GCC and GIT can complain otherwise) * Use doxy-comments for functions in the header file, format as `/** Description */` * Use spaces after the comment markers: `// Comment` instead of `//Comment` -- cgit v1.2.3 From 8d2ebf8e19e1556d256f75678d2272bb6739030f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 6 Mar 2014 20:06:53 +0000 Subject: Slight plugin messaging changes - Clients are not allowed to register duplicate channels - Clients are not allowed to use channels that were not registered --- src/ClientHandle.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 870568cdf..c677862eb 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -555,12 +555,25 @@ void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString } else if (a_Channel == "REGISTER") { + if (HasPluginChannel(a_Channel)) + { + SendPluginMessage("UNREGISTER", a_Channel); + return; // Can't register again if already taken - kinda defeats the point of plugin messaging! + } + RegisterPluginChannels(BreakApartPluginChannels(a_Message)); } else if (a_Channel == "UNREGISTER") { UnregisterPluginChannels(BreakApartPluginChannels(a_Message)); } + else if (!HasPluginChannel(a_Channel)) + { + // Ignore if client sent something but didn't register the channel first + LOGD("Player %s sent a plugin message on channel \"%s\", but didn't REGISTER it first", GetUsername().c_str(), a_Channel.c_str()); + SendPluginMessage("UNREGISTER", a_Channel); + return; + } cPluginManager::Get()->CallHookPluginMessage(*this, a_Channel, a_Message); } -- cgit v1.2.3 From ff186f9735bd08727d6d010e6815c103b2e181e8 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 9 Mar 2014 01:23:55 +0000 Subject: TNT explodes when consumed by fire Fixed FS#406 --- src/Simulator/FireSimulator.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 4967c83f9..6079ea740 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -335,20 +335,33 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_Rel { BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; - if (!a_Chunk->UnboundedRelGetBlock(a_RelX + gNeighborCoords[i].x, a_RelY + gNeighborCoords[i].y, a_RelZ + gNeighborCoords[i].z, BlockType, BlockMeta)) + int X = a_RelX + gNeighborCoords[i].x; + int Z = a_RelZ + gNeighborCoords[i].z; + + cChunkPtr Neighbour = a_Chunk->GetRelNeighborChunkAdjustCoords(X, Z); + if (Neighbour == NULL) { - // Neighbor not accessible, ignore it continue; } + Neighbour->GetBlockTypeMeta(X, a_RelY + gCrossCoords[i].y, Z, BlockType, BlockMeta); + if (!IsFuel(BlockType)) { continue; } + + if (BlockType == E_BLOCK_TNT) + { + int AbsX = X + Neighbour->GetPosX() * cChunkDef::Width; + int AbsZ = Z + Neighbour->GetPosZ() * cChunkDef::Width; + + m_World.SpawnPrimedTNT(AbsX, a_RelY + gNeighborCoords[i].y, AbsZ, 0); + Neighbour->SetBlock(X, a_RelY + gNeighborCoords[i].y, Z, E_BLOCK_AIR, 0); + return; + } + bool ShouldReplaceFuel = (m_World.GetTickRandomNumber(MAX_CHANCE_REPLACE_FUEL) < m_ReplaceFuelChance); - a_Chunk->UnboundedRelSetBlock( - a_RelX + gNeighborCoords[i].x, a_RelY + gNeighborCoords[i].y, a_RelZ + gNeighborCoords[i].z, - ShouldReplaceFuel ? E_BLOCK_FIRE : E_BLOCK_AIR, 0 - ); + Neighbour->SetBlock(X, a_RelY + gNeighborCoords[i].y, Z, ShouldReplaceFuel ? E_BLOCK_FIRE : E_BLOCK_AIR, 0); } // for i - Coords[] } -- cgit v1.2.3 From d872f2e41dfe141e1b04cdfb73c915b9bcdb55ea Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 9 Mar 2014 01:49:32 +0000 Subject: Updated Core --- MCServer/Plugins/Core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 3b416b07a..013a32a7f 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 3b416b07a339b3abcbc127070d56eea05b05373d +Subproject commit 013a32a7fb3c8a6cfe0aef892d4c7394d4e1be59 -- cgit v1.2.3 From f74ee8fb51c015f678438cc1dccf23d1d3c2cf6a Mon Sep 17 00:00:00 2001 From: Jan-Fabian Humann Date: Sun, 9 Mar 2014 10:55:06 +0100 Subject: Adjusted style of switch/case --- src/Protocol/Protocol125.cpp | 20 +++++--------------- src/Protocol/Protocol16x.cpp | 20 +++++--------------- src/Protocol/Protocol17x.cpp | 20 +++++--------------- 3 files changed, 15 insertions(+), 45 deletions(-) diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 169ab0c85..ca286bafb 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1378,21 +1378,11 @@ int cProtocol125::ParseEntityAction(void) switch (ActionID) { - case 1: // Crouch - m_Client->HandleEntityCrouch(EntityID, true); - break; - case 2: // Uncrouch - m_Client->HandleEntityCrouch(EntityID, false); - break; - case 3: // Leave Bed - m_Client->HandleEntityLeaveBed(EntityID); - break; - case 4: // Start sprinting - m_Client->HandleEntitySprinting(EntityID, true); - break; - case 5: // Stop sprinting - m_Client->HandleEntitySprinting(EntityID, false); - break; + case 1: m_Client->HandleEntityCrouch(EntityID, true); break; // Crouch + case 2: m_Client->HandleEntityCrouch(EntityID, false); break; // Uncrouch + case 3: m_Client->HandleEntityLeaveBed(EntityID); break; // Leave Bed + case 4: m_Client->HandleEntitySprinting(EntityID, true); break; // Start sprinting + case 5: m_Client->HandleEntitySprinting(EntityID, false); break; // Stop sprinting } return PARSE_OK; diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp index 4b1b4f408..f6ec0a199 100644 --- a/src/Protocol/Protocol16x.cpp +++ b/src/Protocol/Protocol16x.cpp @@ -187,21 +187,11 @@ int cProtocol161::ParseEntityAction(void) switch (ActionID) { - case 1: // Crouch - m_Client->HandleEntityCrouch(EntityID, true); - break; - case 2: // Uncrouch - m_Client->HandleEntityCrouch(EntityID, false); - break; - case 3: // Leave Bed - m_Client->HandleEntityLeaveBed(EntityID); - break; - case 4: // Start sprinting - m_Client->HandleEntitySprinting(EntityID, true); - break; - case 5: // Stop sprinting - m_Client->HandleEntitySprinting(EntityID, false); - break; + case 1: m_Client->HandleEntityCrouch(EntityID, true); break; // Crouch + case 2: m_Client->HandleEntityCrouch(EntityID, false); break; // Uncrouch + case 3: m_Client->HandleEntityLeaveBed(EntityID); break; // Leave Bed + case 4: m_Client->HandleEntitySprinting(EntityID, true); break; // Start sprinting + case 5: m_Client->HandleEntitySprinting(EntityID, false); break; // Stop sprinting } return PARSE_OK; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index b0ec72a7d..0bb9a1204 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1735,21 +1735,11 @@ void cProtocol172::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) switch (Action) { - case 1: // Crouch - m_Client->HandleEntityCrouch(PlayerID, true); - break; - case 2: // Unchrouch - m_Client->HandleEntityCrouch(PlayerID, false); - break; - case 3: // Leave Bed - m_Client->HandleEntityLeaveBed(PlayerID); - break; - case 4: // Start sprinting - m_Client->HandleEntitySprinting(PlayerID, true); - break; - case 5: // Stop sprinting - m_Client->HandleEntitySprinting(PlayerID, false); - break; + case 1: m_Client->HandleEntityCrouch(PlayerID, true); break; // Crouch + case 2: m_Client->HandleEntityCrouch(PlayerID, false); break; // Uncrouch + case 3: m_Client->HandleEntityLeaveBed(PlayerID); break; // Leave Bed + case 4: m_Client->HandleEntitySprinting(PlayerID, true); break; // Start sprinting + case 5: m_Client->HandleEntitySprinting(PlayerID, false); break; // Stop sprinting } } -- cgit v1.2.3 From b4e3d0aa4e573200d1fffc3073e791c54d9eb20c Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 04:37:36 -0700 Subject: Turned off Wunused-parameter --- SetFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index e6ba782fc..4e20c84ab 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -182,7 +182,7 @@ macro(set_exe_flags) string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") - add_flags_cxx("-Wall -Wextra -Werror -Wno-error=unused-parameter -Wno-error=switch") + add_flags_cxx("-Wall -Wextra -Werror -Wno-unused-parameter -Wno-error=switch") # we support non-IEEE 754 fpus so can make no guarentees about error add_flags_cxx("-ffast-math") -- cgit v1.2.3 From 14c2f620d181614cd87270f8811b162858b53a49 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 04:43:22 -0700 Subject: FIxed int in test --- src/ByteBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index a3b40e5ef..96a135562 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -86,7 +86,7 @@ public: cByteBuffer buf(3); for (int i = 0; i < 1000; i++) { - int FreeSpace = buf.GetFreeSpace(); + size_t FreeSpace = buf.GetFreeSpace(); assert(buf.GetReadableSpace() == 0); assert(FreeSpace > 0); assert(buf.Write("a", 1)); -- cgit v1.2.3 From 59d42ec5b2c666f1f50c9763dad13e97e2c6040f Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 04:58:08 -0700 Subject: Enabled loads of clang warnings --- SetFlags.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SetFlags.cmake b/SetFlags.cmake index 4e20c84ab..56d32b8fe 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -190,6 +190,8 @@ macro(set_exe_flags) # clang does not provide the __extern_always_inline macro and a part of libm depends on this when using fast-math if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_flags_cxx("-D__extern_always_inline=inline") + add_flags_cxx("-Weverything -Wno-c++98-compat-pedantic -Wno-string-conversion") + add_flags_cxx("-Wno-extra-semi -Wno-error=switch-enum -Wno-documentation") endif() endif() -- cgit v1.2.3 From 4cb0b82d1df560ad32c92eede91f466c75a87c87 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 05:05:37 -0700 Subject: Fixed some warnings --- src/ChunkDef.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 7be2fa2df..63431f211 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -65,8 +65,8 @@ public: enum { // Chunk dimensions: - Width = 16, - Height = 256, + Width = 16U, + Height = 256U, NumBlocks = Width * Height * Width, /// If the data is collected into a single buffer, how large it needs to be: @@ -132,7 +132,7 @@ public: } - inline static unsigned int MakeIndexNoCheck(int x, int y, int z) + inline static unsigned int MakeIndexNoCheck(unsigned int x, unsigned int y, unsigned int z) { #if AXIS_ORDER == AXIS_ORDER_XZY // For some reason, NOT using the Horner schema is faster. Weird. @@ -240,7 +240,7 @@ public: { if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1)) { - int Index = MakeIndexNoCheck(x, y, z); + unsigned int Index = MakeIndexNoCheck(x, y, z); return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f; } ASSERT(!"cChunkDef::GetNibble(): coords out of chunk range!"); @@ -256,7 +256,7 @@ public: return; } a_Buffer[a_BlockIdx / 2] = ( - (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble + (a_Buffer[a_BlockIdx / 2] & (0xf0 >> (static_cast(a_BlockIdx & 1) * 4))) | // The untouched nibble ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set ); } @@ -282,13 +282,13 @@ public: } - inline static char GetNibble(const NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos ) + inline static NIBBLETYPE GetNibble(const NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos ) { return GetNibble(a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); } - inline static void SetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos, char a_Value ) + inline static void SetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos, NIBBLETYPE a_Value ) { SetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Value ); } @@ -306,6 +306,9 @@ The virtual methods are called in the same order as they're declared here. class cChunkDataCallback abstract { public: + + virtual ~cChunkDataCallback() {} + /** Called before any other callbacks to inform of the current coords (only in processes where multiple chunks can be processed, such as cWorld::ForEachChunkInRect()). If false is returned, the chunk is skipped. -- cgit v1.2.3 From e2cbebe522c8d52dc68e513d7896c1f0d21d5b71 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 27 Feb 2014 23:33:46 +0000 Subject: Fix Linux compile --- src/CraftingRecipes.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 41de0da8c..5d9992fd3 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -806,6 +806,8 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti } case E_ITEM_DYE: { + int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); + // Found a dye in ingredients... for (cRecipeSlots::const_iterator itrnumerodos = Recipe->m_Ingredients.begin(); itrnumerodos != Recipe->m_Ingredients.end(); ++itrnumerodos) { @@ -821,7 +823,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti // Yep, push back fade colour and exit the loop // There is a potential for flexibility here - we can move the goto out of the loop, so we can add multiple dyes (∴ multiple fade colours) // That will require lots of dye-adding to crafting.txt though - TODO, perchance? - int GridID = (itrnumerotres->x + a_OffsetX) + a_GridStride * (itrnumerotres->y + a_OffsetY); + GridID = (itrnumerotres->x + a_OffsetX) + a_GridStride * (itrnumerotres->y + a_OffsetY); Recipe->m_Result.m_FireworkItem.m_FadeColours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); goto next; } @@ -830,7 +832,6 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti } // Just normal crafting of star, push back normal colours - int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); Recipe->m_Result.m_FireworkItem.m_Colours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); next: -- cgit v1.2.3 From c05a1db88d2a81b5aa93881c9791bcaadaad6304 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Mar 2014 21:24:36 +0000 Subject: CheckBlockInteractionsRate() fixed & enabled --- src/ClientHandle.cpp | 48 +++++++++++++++++++----------------------------- src/ClientHandle.h | 4 +++- src/Entities/Player.cpp | 25 ------------------------- src/Entities/Player.h | 11 +---------- 4 files changed, 23 insertions(+), 65 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index b08ceb5f6..ef33a313d 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -52,6 +52,9 @@ /** Maximum number of explosions to send this tick, server will start dropping if exceeded */ #define MAX_EXPLOSIONS_PER_TICK 20 +/** Maximum number of block change interactions a player can perform per tick - exceeding this causes a kick */ +#define MAX_BLOCK_CHANGE_INTERACTIONS 20 + /** How many ticks before the socket is closed after the client is destroyed (#31) */ static const int TICKS_BEFORE_CLOSE = 20; @@ -687,6 +690,14 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status ); + m_NumBlockChangeInteractionsThisTick++; + + if (!CheckBlockInteractionsRate()) + { + Kick("Too many blocks were destroyed per unit time - hacked client?"); + return; + } + cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); if (PlgMgr->CallHookPlayerLeftClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status)) { @@ -694,12 +705,6 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); return; } - - if (!CheckBlockInteractionsRate()) - { - // Too many interactions per second, simply ignore. Probably a hacked client, so don't even send bak the block - return; - } switch (a_Status) { @@ -924,7 +929,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e if (PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ)) { // A plugin doesn't agree with the action, replace the block on the client and quit: - if (a_BlockFace > -1) + if (a_BlockFace > BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); @@ -934,7 +939,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e if (!CheckBlockInteractionsRate()) { - LOGD("Too many block interactions, aborting placement"); + Kick("Too many blocks were destroyed per unit time - hacked client?"); return; } @@ -1613,28 +1618,12 @@ bool cClientHandle::CheckBlockInteractionsRate(void) { ASSERT(m_Player != NULL); ASSERT(m_Player->GetWorld() != NULL); - /* - // TODO: _X 2012_11_01: This needs a total re-thinking and rewriting - int LastActionCnt = m_Player->GetLastBlockActionCnt(); - if ((m_Player->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime()) < 0.1) - { - // Limit the number of block interactions per tick - m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time. - m_Player->SetLastBlockActionCnt(LastActionCnt + 1); - if (m_Player->GetLastBlockActionCnt() > MAXBLOCKCHANGEINTERACTIONS) - { - // Kick if more than MAXBLOCKCHANGEINTERACTIONS per tick - LOGWARN("Player %s tried to interact with a block too quickly! (could indicate bot) Was Kicked.", m_Username.c_str()); - Kick("You're a baaaaaad boy!"); - return false; - } - } - else + + if (m_NumBlockChangeInteractionsThisTick > MAX_BLOCK_CHANGE_INTERACTIONS) { - m_Player->SetLastBlockActionCnt(0); // Reset count - m_Player->SetLastBlockActionTime(); // Player tried to interact with a block. Reset last block interation time. + return false; } - */ + return true; } @@ -1707,8 +1696,9 @@ void cClientHandle::Tick(float a_Dt) } } - // Reset explosion counter: + // Reset explosion & block change counters: m_NumExplosionsThisTick = 0; + m_NumBlockChangeInteractionsThisTick = 0; } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 194533402..2382e81cf 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -46,7 +46,6 @@ class cClientHandle : // tolua_export public cSocketThreads::cCallback { // tolua_export public: - static const int MAXBLOCKCHANGEINTERACTIONS = 20; // 5 didn't help, 10 still doesn't work in Creative, 20 seems to have done the trick #if defined(ANDROID_NDK) static const int DEFAULT_VIEW_DISTANCE = 4; // The default ViewDistance (used when no value is set in Settings.ini) @@ -319,6 +318,9 @@ private: /** Number of explosions sent this tick */ int m_NumExplosionsThisTick; + + /** Number of place or break interactions this tick */ + int m_NumBlockChangeInteractionsThisTick; static int s_ClientCount; int m_UniqueID; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index f4039e548..2a62931ab 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -38,10 +38,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) , m_Inventory(*this) , m_CurrentWindow(NULL) , m_InventoryWindow(NULL) - , m_TimeLastPickupCheck(0.f) , m_Color('-') - , m_LastBlockActionTime(0) - , m_LastBlockActionCnt(0) , m_GameMode(eGameMode_NotSet) , m_IP("") , m_ClientHandle(a_Client) @@ -79,7 +76,6 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) m_LastPlayerListTime = t1.GetNowTime(); m_TimeLastTeleportPacket = 0; - m_TimeLastPickupCheck = 0; m_PlayerName = a_PlayerName; m_bDirtyPosition = true; // So chunks are streamed to player at spawn @@ -1055,27 +1051,6 @@ void cPlayer::CloseWindowIfID(char a_WindowID, bool a_CanRefuse) -void cPlayer::SetLastBlockActionTime() -{ - if (m_World != NULL) - { - m_LastBlockActionTime = m_World->GetWorldAge() / 20.0f; - } -} - - - - - -void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt ) -{ - m_LastBlockActionCnt = a_LastBlockActionCnt; -} - - - - - void cPlayer::SetGameMode(eGameMode a_GameMode) { if ((a_GameMode < gmMin) || (a_GameMode >= gmMax)) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index a795bb9eb..f9404dfaf 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -50,7 +50,7 @@ public: /// Returns the curently equipped weapon; empty item if none virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); } - /// Returns the currently equipped helmet; empty item if nonte + /// Returns the currently equipped helmet; empty item if none virtual cItem GetEquippedHelmet(void) const override { return m_Inventory.GetEquippedHelmet(); } /// Returns the currently equipped chestplate; empty item if none @@ -165,11 +165,6 @@ public: // tolua_end void SetIP(const AString & a_IP); - - float GetLastBlockActionTime() { return m_LastBlockActionTime; } - int GetLastBlockActionCnt() { return m_LastBlockActionCnt; } - void SetLastBlockActionCnt( int ); - void SetLastBlockActionTime(); // Sets the current gamemode, doesn't check validity, doesn't send update packets to client void LoginSetGameMode(eGameMode a_GameMode); @@ -416,12 +411,8 @@ protected: cWindow * m_CurrentWindow; cWindow * m_InventoryWindow; - float m_TimeLastPickupCheck; - char m_Color; - float m_LastBlockActionTime; - int m_LastBlockActionCnt; eGameMode m_GameMode; AString m_IP; -- cgit v1.2.3 From 217aaca699cf1fa85740da4d1f0b71d4b8d806d7 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Mar 2014 21:25:01 +0000 Subject: Moved firework handler to separate function * Also simplified and improved readability of code --- src/CraftingRecipes.cpp | 93 ++++++++++++++++++++++++------------------------- src/CraftingRecipes.h | 3 ++ 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 5d9992fd3..868182394 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -763,13 +763,24 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti } Recipe->m_Ingredients.insert(Recipe->m_Ingredients.end(), MatchedSlots.begin(), MatchedSlots.end()); - - // Henceforth is code to handle fireworks // We use Recipe instead of a_Recipe because we want the wildcard ingredients' slot numbers as well, which was just added previously + HandleFireworks(a_CraftingGrid, Recipe.get(), a_GridStride, a_OffsetX, a_OffsetY); + + return Recipe.release(); +} + + + + + +void cCraftingRecipes::HandleFireworks(const cItem * a_CraftingGrid, cCraftingRecipes::cRecipe * a_Recipe, int a_GridStride, int a_OffsetX, int a_OffsetY) +{ + // TODO: add support for more than one dye in the recipe + // A manual and temporary solution (listing everything) is in crafting.txt for fade colours, but a programmatic solutions needs to be done for everything else - if (Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_ROCKET) + if (a_Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_ROCKET) { - for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + for (cRecipeSlots::const_iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr) { switch (itr->m_Item.m_ItemType) { @@ -777,80 +788,66 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti { // Result was a rocket, found a star - copy star data to rocket data int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); - Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); + a_Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); break; } case E_ITEM_GUNPOWDER: { // Gunpowder - increase flight time - Recipe->m_Result.m_FireworkItem.m_FlightTimeInTicks += 20; + a_Recipe->m_Result.m_FireworkItem.m_FlightTimeInTicks += 20; break; } case E_ITEM_PAPER: break; - default: LOG("Unexpected item in firework rocket recipe, was the crafting file fireworks section changed?"); break; + default: LOG("Unexpected item in firework rocket a_Recipe, was the crafting file fireworks section changed?"); break; } } } - else if (Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_STAR) + else if (a_Recipe->m_Result.m_ItemType == E_ITEM_FIREWORK_STAR) { - for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + std::vector DyeColours; + bool FoundStar = false; + + for (cRecipeSlots::const_iterator itr = a_Recipe->m_Ingredients.begin(); itr != a_Recipe->m_Ingredients.end(); ++itr) { switch (itr->m_Item.m_ItemType) { case E_ITEM_FIREWORK_STAR: { // Result was star, found another star - probably adding fade colours, but copy data over anyhow + FoundStar = true; int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); - Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); + a_Recipe->m_Result.m_FireworkItem.CopyFrom(a_CraftingGrid[GridID].m_FireworkItem); break; } case E_ITEM_DYE: { int GridID = (itr->x + a_OffsetX) + a_GridStride * (itr->y + a_OffsetY); - - // Found a dye in ingredients... - for (cRecipeSlots::const_iterator itrnumerodos = Recipe->m_Ingredients.begin(); itrnumerodos != Recipe->m_Ingredients.end(); ++itrnumerodos) - { - // Loop through ingredients. Can we find a star? - if (itrnumerodos->m_Item.m_ItemType == E_ITEM_FIREWORK_STAR) - { - // Yes, this is definately adding fade colours, unless crafting.txt was changed :/ - for (cRecipeSlots::const_iterator itrnumerotres = Recipe->m_Ingredients.begin(); itrnumerotres != Recipe->m_Ingredients.end(); ++itrnumerotres) - { - // Loop again, can we find dye? - if (itrnumerotres->m_Item.m_ItemType == E_ITEM_DYE) - { - // Yep, push back fade colour and exit the loop - // There is a potential for flexibility here - we can move the goto out of the loop, so we can add multiple dyes (∴ multiple fade colours) - // That will require lots of dye-adding to crafting.txt though - TODO, perchance? - GridID = (itrnumerotres->x + a_OffsetX) + a_GridStride * (itrnumerotres->y + a_OffsetY); - Recipe->m_Result.m_FireworkItem.m_FadeColours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); - goto next; - } - } - } - } - - // Just normal crafting of star, push back normal colours - Recipe->m_Result.m_FireworkItem.m_Colours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); - - next: + DyeColours.push_back(cFireworkItem::GetVanillaColourCodeFromDye(a_CraftingGrid[GridID].m_ItemDamage)); break; } case E_ITEM_GUNPOWDER: break; - case E_ITEM_DIAMOND: Recipe->m_Result.m_FireworkItem.m_HasTrail = true; break; - case E_ITEM_GLOWSTONE_DUST: Recipe->m_Result.m_FireworkItem.m_HasFlicker = true; break; - - case E_ITEM_FIRE_CHARGE: Recipe->m_Result.m_FireworkItem.m_Type = 1; break; - case E_ITEM_GOLD_NUGGET: Recipe->m_Result.m_FireworkItem.m_Type = 2; break; - case E_ITEM_FEATHER: Recipe->m_Result.m_FireworkItem.m_Type = 4; break; - case E_ITEM_HEAD: Recipe->m_Result.m_FireworkItem.m_Type = 3; break; - default: LOG("Unexpected item in firework star recipe, was the crafting file fireworks section changed?"); break; // ermahgerd BARD ardmins + case E_ITEM_DIAMOND: a_Recipe->m_Result.m_FireworkItem.m_HasTrail = true; break; + case E_ITEM_GLOWSTONE_DUST: a_Recipe->m_Result.m_FireworkItem.m_HasFlicker = true; break; + + case E_ITEM_FIRE_CHARGE: a_Recipe->m_Result.m_FireworkItem.m_Type = 1; break; + case E_ITEM_GOLD_NUGGET: a_Recipe->m_Result.m_FireworkItem.m_Type = 2; break; + case E_ITEM_FEATHER: a_Recipe->m_Result.m_FireworkItem.m_Type = 4; break; + case E_ITEM_HEAD: a_Recipe->m_Result.m_FireworkItem.m_Type = 3; break; + default: LOG("Unexpected item in firework star a_Recipe, was the crafting file fireworks section changed?"); break; // ermahgerd BARD ardmins } } - } - return Recipe.release(); + if (FoundStar && (!DyeColours.empty())) + { + // Found a star and a dye? Fade colours. + a_Recipe->m_Result.m_FireworkItem.m_FadeColours = DyeColours; + } + else if (!DyeColours.empty()) + { + // Only dye? Normal colours. + a_Recipe->m_Result.m_FireworkItem.m_Colours = DyeColours; + } + } } diff --git a/src/CraftingRecipes.h b/src/CraftingRecipes.h index 9d92cbfab..90e41eddc 100644 --- a/src/CraftingRecipes.h +++ b/src/CraftingRecipes.h @@ -165,6 +165,9 @@ protected: /// Checks if the grid matches the specified recipe, offset by the specified offsets. Returns a matched cRecipe * if so, or NULL if not matching. Caller must delete the return value! cRecipe * MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY); + + /** Searches for anything firework related, and does the data setting if appropriate */ + void HandleFireworks(const cItem * a_CraftingGrid, cCraftingRecipes::cRecipe * a_Recipe, int a_GridStride, int a_OffsetX, int a_OffsetY); } ; -- cgit v1.2.3 From 8f134adb6dab3ad171f34a2e08a314e591380def Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Mar 2014 21:25:27 +0000 Subject: Improved formatting of username tabcomplete --- src/World.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index ffb463169..8b791fa48 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2929,18 +2929,18 @@ void cWorld::TabCompleteUserName(const AString & a_Text, AStringVector & a_Resul cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = m_Players.begin(), end = m_Players.end(); itr != end; ++itr) { - size_t LastSpace = a_Text.find_last_of(" "); //Find the position of the last space + size_t LastSpace = a_Text.find_last_of(" "); // Find the position of the last space - std::string LastWord = a_Text.substr(LastSpace + 1, a_Text.length()); //Find the last word - std::string PlayerName ((*itr)->GetName()); - std::size_t Found = PlayerName.find(LastWord); //Try to find last word in playername + AString LastWord = a_Text.substr(LastSpace + 1, a_Text.length()); // Find the last word + AString PlayerName ((*itr)->GetName()); + size_t Found = PlayerName.find(LastWord); // Try to find last word in playername - if (Found!=0) + if (Found == AString::npos) { - continue; //No match + continue; // No match } - a_Results.push_back((*itr)->GetName()); //Match! + a_Results.push_back(PlayerName); // Match! } } -- cgit v1.2.3 From d5180ef2308f0de6c9a7a828e5914e8424b9b16f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Mar 2014 21:25:46 +0000 Subject: Added extra dye rules to crafting.txt --- MCServer/crafting.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/MCServer/crafting.txt b/MCServer/crafting.txt index bce0c5e9e..60cda0673 100644 --- a/MCServer/crafting.txt +++ b/MCServer/crafting.txt @@ -478,5 +478,12 @@ FireworkStar = Gunpowder, * | Dye ^-1, * | Goldnugget, * | Glowdust, * | Dia FireworkStar = Gunpowder, * | Dye ^-1, * | Feather, * | Glowdust, * | Diamond, * FireworkStar = Gunpowder, * | Dye ^-1, * | SkeletonHead ^-1, * | Glowdust, * | Diamond, * -# Star colour-change +# Star fade colour-change FireworkStar = FireworkStar, * | Dye ^-1, * +FireworkStar = FireworkStar, * | Dye ^-1, * | Dye ^-1, * +FireworkStar = FireworkStar, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * +FireworkStar = FireworkStar, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * +FireworkStar = FireworkStar, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * +FireworkStar = FireworkStar, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * +FireworkStar = FireworkStar, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * +FireworkStar = FireworkStar, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * | Dye ^-1, * -- cgit v1.2.3 From 124fc8bc664f96158b4db28372da62896d1db211 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 1 Mar 2014 21:26:43 +0000 Subject: Demonstrated issues with GetDataLength() --- src/WorldStorage/FireworksSerializer.cpp | 12 +++++++----- src/WorldStorage/FireworksSerializer.h | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 7f5077912..34204ae8a 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -89,26 +89,28 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB if (ExplosionName == "Colors") { - if (a_NBT.GetDataLength(explosiontag) == 0) + int DataLength = a_NBT.GetDataLength(explosiontag); + if (DataLength == 0) { continue; } const int * ColourData = (const int *)(a_NBT.GetData(explosiontag)); - for (int i = 0; i < ARRAYCOUNT(ColourData); i++) + for (int i = 0; i < DataLength; i++) { a_FireworkItem.m_Colours.push_back(ntohl(ColourData[i])); } } else if (ExplosionName == "FadeColors") { - if (a_NBT.GetDataLength(explosiontag) == 0) + int DataLength = a_NBT.GetDataLength(explosiontag); + if (DataLength == 0) { continue; } const int * FadeColourData = (const int *)(a_NBT.GetData(explosiontag)); - for (int i = 0; i < ARRAYCOUNT(FadeColourData); i++) + for (int i = 0; i < DataLength; i++) { a_FireworkItem.m_FadeColours.push_back(ntohl(FadeColourData[i])); } @@ -244,6 +246,6 @@ int cFireworkItem::GetVanillaColourCodeFromDye(short a_DyeMeta) case E_META_DYE_MAGENTA: return 12801229; case E_META_DYE_ORANGE: return 15435844; case E_META_DYE_WHITE: return 15790320; - default: ASSERT(!"Unhandled dye meta whilst trying to get colour code for fireworks!"); break; + default: ASSERT(!"Unhandled dye meta whilst trying to get colour code for fireworks!"); return 0; } } diff --git a/src/WorldStorage/FireworksSerializer.h b/src/WorldStorage/FireworksSerializer.h index 37fb6c883..5b87bafdb 100644 --- a/src/WorldStorage/FireworksSerializer.h +++ b/src/WorldStorage/FireworksSerializer.h @@ -64,15 +64,19 @@ public: /** Writes firework NBT data to a Writer object */ static void WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFastNBTWriter & a_Writer, const ENUM_ITEM_ID a_Type); + /** Reads NBT data from a NBT object and populates a FireworkItem with it */ static void ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNBT & a_NBT, int a_TagIdx, const ENUM_ITEM_ID a_Type); /** Converts the firework's vector of colours into a string of values separated by a semicolon */ static AString ColoursToString(const cFireworkItem & a_FireworkItem); + /** Parses a string containing encoded firework colours and populates a FireworkItem with it */ static void ColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem); + /** Converts the firework's vector of fade colours into a string of values separated by a semicolon */ static AString FadeColoursToString(const cFireworkItem & a_FireworkItem); + /** Parses a string containing encoded firework fade colours and populates a FireworkItem with it */ static void FadeColoursFromString(const AString & a_String, cFireworkItem & a_FireworkItem); -- cgit v1.2.3 From a2fb28dd082b85d714970f119a82cdba3583037a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Mar 2014 16:28:51 +0000 Subject: Fixed data length issues --- src/ClientHandle.cpp | 2 +- src/WorldStorage/FireworksSerializer.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index ef33a313d..9f08b43a5 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -939,7 +939,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e if (!CheckBlockInteractionsRate()) { - Kick("Too many blocks were destroyed per unit time - hacked client?"); + Kick("Too many blocks were placed/interacted with per unit time - hacked client?"); return; } diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 34204ae8a..464bf225d 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -89,7 +89,8 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB if (ExplosionName == "Colors") { - int DataLength = a_NBT.GetDataLength(explosiontag); + // Divide by four as data length returned in bytes + int DataLength = a_NBT.GetDataLength(explosiontag) / 4; if (DataLength == 0) { continue; @@ -103,7 +104,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB } else if (ExplosionName == "FadeColors") { - int DataLength = a_NBT.GetDataLength(explosiontag); + int DataLength = a_NBT.GetDataLength(explosiontag) / 4; if (DataLength == 0) { continue; -- cgit v1.2.3 From 76bf7ad8132f2d36cf974d7a376ca7b911343eac Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Mar 2014 17:41:34 +0000 Subject: Hexified colours --- src/WorldStorage/FireworksSerializer.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 464bf225d..0e0094e76 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -231,22 +231,22 @@ int cFireworkItem::GetVanillaColourCodeFromDye(short a_DyeMeta) switch (a_DyeMeta) { - case E_META_DYE_BLACK: return 1973019; - case E_META_DYE_RED: return 11743532; - case E_META_DYE_GREEN: return 3887386; - case E_META_DYE_BROWN: return 5320730; - case E_META_DYE_BLUE: return 2437522; - case E_META_DYE_PURPLE: return 8073150; - case E_META_DYE_CYAN: return 2651799; - case E_META_DYE_LIGHTGRAY: return 11250603; - case E_META_DYE_GRAY: return 4408131; - case E_META_DYE_PINK: return 14188952; - case E_META_DYE_LIGHTGREEN: return 4312372; - case E_META_DYE_YELLOW: return 14602026; - case E_META_DYE_LIGHTBLUE: return 6719955; - case E_META_DYE_MAGENTA: return 12801229; - case E_META_DYE_ORANGE: return 15435844; - case E_META_DYE_WHITE: return 15790320; + case E_META_DYE_BLACK: return 0x1E1B1B; + case E_META_DYE_RED: return 0xB3312C; + case E_META_DYE_GREEN: return 0x3B511A; + case E_META_DYE_BROWN: return 0x51301A; + case E_META_DYE_BLUE: return 0x253192; + case E_META_DYE_PURPLE: return 0x7B2FBE; + case E_META_DYE_CYAN: return 0x287697; + case E_META_DYE_LIGHTGRAY: return 0xABABAB; + case E_META_DYE_GRAY: return 0x434343; + case E_META_DYE_PINK: return 0xD88198; + case E_META_DYE_LIGHTGREEN: return 0x41CD34; + case E_META_DYE_YELLOW: return 0xDECF2A; + case E_META_DYE_LIGHTBLUE: return 0x6689D3; + case E_META_DYE_MAGENTA: return 0xC354CD; + case E_META_DYE_ORANGE: return 0xEB8844; + case E_META_DYE_WHITE: return 0xF0F0F0; default: ASSERT(!"Unhandled dye meta whilst trying to get colour code for fireworks!"); return 0; } } -- cgit v1.2.3 From e6305d29a53c9a0c5e607629d30fec70e01cccab Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 7 Mar 2014 18:37:18 +0100 Subject: Added the first skeleton code for PieceGenerator. This is a WIP and won't work / isn't used at all. --- src/Generating/PieceGenerator.cpp | 332 ++++++++++++++++++++++++++++++++++++++ src/Generating/PieceGenerator.h | 213 ++++++++++++++++++++++++ 2 files changed, 545 insertions(+) create mode 100644 src/Generating/PieceGenerator.cpp create mode 100644 src/Generating/PieceGenerator.h diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp new file mode 100644 index 000000000..04513666d --- /dev/null +++ b/src/Generating/PieceGenerator.cpp @@ -0,0 +1,332 @@ + +// PieceGenerator.cpp + +// Implements the cBFSPieceGenerator class and cDFSPieceGenerator class +// representing base classes for generating structures composed of individual "pieces" + +#include "Globals.h" +#include "PieceGenerator.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPiece: + +cPiece::cConnector cPiece::RotateMoveConnector(const cConnector & a_Connector, int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const +{ + cPiece::cConnector res(a_Connector); + + // Rotate the res connector: + Vector3i Size = GetSize(); + switch (a_NumCCWRotations) + { + case 0: + { + // No rotation needed + break; + } + case 1: + { + // 1 CCW rotation: + int NewX = Size.z - res.m_X; + int NewZ = res.m_Z; + res.m_X = NewX; + res.m_Z = NewZ; + res.m_Direction = RotateBlockFaceCCW(res.m_Direction); + break; + } + case 2: + { + // 2 rotations ( = axis flip): + res.m_X = Size.x - res.m_X; + res.m_Z = Size.z - res.m_Z; + res.m_Direction = MirrorBlockFaceY(res.m_Direction); + break; + } + case 3: + { + // 1 CW rotation: + int NewX = res.m_Z; + int NewZ = Size.x - res.m_X; + res.m_X = NewX; + res.m_Z = NewZ; + res.m_Direction = RotateBlockFaceCW(res.m_Direction); + break; + } + } + + // Move the res connector: + res.m_X += a_MoveX; + res.m_Y += a_MoveY; + res.m_Z += a_MoveZ; + + return res; +} + + + + + +cCuboid cPiece::RotateHitBoxToConnector( + const cPiece::cConnector & a_MyConnector, + const cPiece::cConnector & a_ToConnector, + int a_NumCCWRotations +) const +{ + cCuboid res = GetHitBox(); + switch (a_NumCCWRotations) + { + case 0: + { + // No rotation, return the hitbox as-is + break; + } + case 1: + { + // 1 CCW rotation: + // TODO: res.p1.x = + break; + } + } + return res; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPlacedPiece: + +cPlacedPiece::cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece, const Vector3i & a_Coords, int a_NumCCWRotations) : + m_Parent(a_Parent), + m_Piece(&a_Piece), + m_Coords(a_Coords), + m_NumCCWRotations(a_NumCCWRotations) +{ + m_Depth = (m_Parent == NULL) ? 0 : (m_Parent->GetDepth() + 1); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPieceGenerator: + +cPieceGenerator::cPieceGenerator(cPiecePool & a_PiecePool, int a_Seed) : + m_PiecePool(a_PiecePool), + m_Noise(a_Seed), + m_Seed(a_Seed) +{ +} + + + + + +cPlacedPiece cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, int a_BlockZ, cFreeConnectors & a_OutConnectors) +{ + m_PiecePool.Reset(); + int rnd = m_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) / 7; + + // Choose a random one of the starting pieces: + cPieces StartingPieces = m_PiecePool.GetStartingPieces(); + cPiece * StartingPiece = StartingPieces[rnd % StartingPieces.size()]; + rnd = rnd >> 16; + + // Choose a random supported rotation: + int Rotations[4] = {0}; + int NumRotations = 1; + for (int i = 1; i < ARRAYCOUNT(Rotations); i++) + { + if (StartingPiece->CanRotateCCW(i)) + { + Rotations[NumRotations] = i; + NumRotations += 1; + } + } + int Rotation = Rotations[rnd % NumRotations]; + + cPlacedPiece res(NULL, *StartingPiece, Vector3i(a_BlockX, a_BlockY, a_BlockZ), Rotation); + + // Place the piece's connectors into a_OutConnectors: + const cPiece::cConnectors & Conn = StartingPiece->GetConnectors(); + for (cPiece::cConnectors::const_iterator itr = Conn.begin(), end = Conn.end(); itr != end; ++itr) + { + a_OutConnectors.push_back( + cFreeConnector(res, StartingPiece->RotateMoveConnector(*itr, Rotation, a_BlockX, a_BlockY, a_BlockZ)) + ); + } + + return res; +} + + + + + +bool cPieceGenerator::TryPlacePieceAtConnector(const cPlacedPiece & a_ParentPiece, const cPiece::cConnector & a_Connector, cPlacedPieces & a_OutPieces) +{ + // Translation of direction - direction -> number of CCW rotations needed: + // You need DirectionRotationTable[rot1][rot2] CCW turns to get from rot1 to rot2 + static const int DirectionRotationTable[6][6] = + { + /* YM, YP, ZM, ZP, XM, XP + /* YM */ { 0, 0, 0, 0, 0, 0}, + /* YP */ { 0, 0, 0, 0, 0, 0}, + /* ZM */ { 0, 0, 0, 2, 1, 3}, + /* ZP */ { 0, 0, 2, 0, 3, 1}, + /* XM */ { 0, 0, 3, 1, 0, 2}, + /* XP */ { 0, 0, 1, 3, 2, 0}, + }; + + // Get a list of available connections: + const int * RotTable = DirectionRotationTable[a_Connector.m_Direction]; + cConnections Connections; + cPieces AvailablePieces = m_PiecePool.GetPiecesWithConnector(a_Connector.m_Type); + Connections.reserve(AvailablePieces.size()); + for (cPieces::iterator itrP = AvailablePieces.begin(), endP = AvailablePieces.end(); itrP != endP; ++itrP) + { + cPiece::cConnectors Connectors = (*itrP)->GetConnectors(); + for (cPiece::cConnectors::iterator itrC = Connectors.begin(), endC = Connectors.end(); itrC != endC; ++itrC) + { + if (itrC->m_Type != a_Connector.m_Type) + { + continue; + } + // This is a same-type connector, find out how to rotate to it: + int NumCCWRotations = RotTable[itrC->m_Direction]; + if (!(*itrP)->CanRotateCCW(NumCCWRotations)) + { + // Doesn't support this rotation + continue; + } + if (!CheckConnection(a_Connector, **itrP, *itrC, NumCCWRotations, a_OutPieces)) + { + // Doesn't fit in this rotation + continue; + } + Connections.push_back(cConnection(**itrP, *itrC, NumCCWRotations)); + } // for itrC - Connectors[] + } // for itrP - AvailablePieces[] + if (Connections.empty()) + { + // No available connections, bail out + return false; + } + + // Choose a random connection from the list: + int rnd = m_Noise.IntNoise3DInt(a_Connector.m_X, a_Connector.m_Y, a_Connector.m_Z) / 7; + cConnection & Conn = Connections[rnd % Connections.size()]; + + // Place the piece: + cPiece::cConnector NewConnector = Conn.m_Piece->RotateMoveConnector(*(Conn.m_Connector), Conn.m_NumCCWRotations, 0, 0, 0); + Vector3i Coords = a_ParentPiece.GetCoords(); + Coords.x -= NewConnector.m_X; + Coords.y -= NewConnector.m_Y; + Coords.z -= NewConnector.m_Z; + a_OutPieces.push_back(cPlacedPiece(&a_ParentPiece, *(Conn.m_Piece), Coords, Conn.m_NumCCWRotations)); + return false; +} + + + + + +bool cPieceGenerator::CheckConnection( + const cPiece::cConnector & a_ExistingConnector, + const cPiece & a_Piece, + const cPiece::cConnector & a_NewConnector, + int a_NumCCWRotations, + const cPlacedPieces & a_OutPieces +) +{ + // For each placed piece, test the hitbox against the new piece: + cCuboid RotatedHitBox = a_Piece.RotateHitBoxToConnector(a_NewConnector, a_ExistingConnector, a_NumCCWRotations); + for (cPlacedPieces::const_iterator itr = a_OutPieces.begin(), end = a_OutPieces.end(); itr != end; ++itr) + { + if (itr->GetHitBox().DoesIntersect(RotatedHitBox)) + { + return false; + } + } + return true; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPieceGenerator::cConnection: + +cPieceGenerator::cConnection::cConnection(cPiece & a_Piece, cPiece::cConnector & a_Connector, int a_NumCCWRotations) : + m_Piece(&a_Piece), + m_Connector(&a_Connector), + m_NumCCWRotations(a_NumCCWRotations) +{ +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPieceGenerator::cFreeConnector: + +cPieceGenerator::cFreeConnector::cFreeConnector(cPlacedPiece & a_Piece, const cPiece::cConnector & a_Connector) : + m_Piece(&a_Piece), + m_Connector(a_Connector) +{ +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cBFSPieceGenerator: + +cBFSPieceGenerator::cBFSPieceGenerator(cPiecePool & a_PiecePool, int a_Seed) : + super(a_PiecePool, a_Seed) +{ +} + + + + + +void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, cPlacedPieces & a_OutPieces) +{ + a_OutPieces.clear(); + cFreeConnectors ConnectorPool; + + // Place the starting piece: + a_OutPieces.push_back(PlaceStartingPiece(a_BlockX, a_BlockY, a_BlockZ, ConnectorPool)); + + // Place pieces at the available connectors: + /* + Instead of removing them one by one from the pool, we process them sequentially and take note of the last + processed one. To save on memory, once the number of processed connectors reaches a big number, a chunk + of the connectors is removed. + */ + size_t NumProcessed = 0; + while (ConnectorPool.size() > NumProcessed) + { + cFreeConnector & Conn = ConnectorPool[NumProcessed]; + TryPlacePieceAtConnector(*Conn.m_Piece, Conn.m_Connector, a_OutPieces); + NumProcessed++; + if (NumProcessed > 1000) + { + ConnectorPool.erase(ConnectorPool.begin(), ConnectorPool.begin() + NumProcessed); + NumProcessed = 0; + } + } +} + + + + diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h new file mode 100644 index 000000000..3bc71a0ab --- /dev/null +++ b/src/Generating/PieceGenerator.h @@ -0,0 +1,213 @@ + +// PieceGenerator.h + +// Declares the cBFSPieceGenerator class and cDFSPieceGenerator class +// representing base classes for generating structures composed of individual "pieces" + +/* +Each uses a slightly different approach to generating: + - DFS extends pieces one by one until it hits the configured depth (or can't connect another piece anymore), + then starts looking at adjacent connectors (like depth-first search). + - BFS keeps a pool of currently-open connectors, chooses one at random and tries to place a piece on it, + thus possibly extending the pool of open connectors (like breadth-first search). +*/ + + + + + +#pragma once + +#include "../Defines.h" +#include "../Cuboid.h" +#include "../Noise.h" + + + + + +/** Represents a single piece. Can have multiple connectors of different types where other pieces can connect. */ +class cPiece +{ +public: + struct cConnector + { + int m_X; + int m_Y; + int m_Z; + int m_Type; + eBlockFace m_Direction; + + cConnector(int a_X, int a_Y, int a_Z, int a_Type, eBlockFace m_Direction); + }; + + typedef std::vector cConnectors; + + /** Returns all of the available connectors that the piece has. + Each connector has a (relative) position in the piece, and a type associated with it. */ + virtual cConnectors GetConnectors(void) const = 0; + + /** Returns the dimensions of this piece. + The dimensions cover the entire piece, there is no block that the piece generates outside of this size. */ + virtual Vector3i GetSize(void) const = 0; + + /** Returns the "hitbox" of this piece. + A hitbox is what is compared and must not intersect other pieces' hitboxes when generating. */ + virtual cCuboid GetHitBox(void) const = 0; + + /** Returns true if the piece can be rotated CCW the specific number of 90-degree turns. */ + virtual bool CanRotateCCW(int a_NumRotations) const = 0; + + /** Returns a copy of the connector that is rotated and then moved by the specified amounts. */ + cConnector RotateMoveConnector(const cConnector & a_Connector, int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const; + + /** Returns the hitbox after the specified number of rotations and moved so that a_MyConnector is placed at a_ToConnector*/ + cCuboid RotateHitBoxToConnector(const cConnector & a_MyConnector, const cConnector & a_ToConnector, int a_NumCCWRotations) const; +}; + +typedef std::vector cPieces; + + + + + +class cPiecePool +{ +public: + /** Returns a list of pieces that contain the specified connector type. + The cPiece pointers returned are managed by the pool and the caller doesn't free them. */ + virtual cPieces GetPiecesWithConnector(int a_ConnectorType) = 0; + + /** Returns the pieces that should be used as the starting point. + Multiple starting points are supported, one of the returned piece will be chosen. */ + virtual cPieces GetStartingPieces(void) = 0; + + /** Called after a piece is placed, to notify the pool that it has been used. + The pool may adjust the pieces it will return the next time. */ + virtual void PiecePlaced(const cPiece & a_Piece) = 0; + + /** Called when the pool has finished the current structure and should reset any piece-counters it has + for a new structure. */ + virtual void Reset(void) = 0; +}; + + + + + +/** Represents a single piece that has been placed to specific coords in the world. */ +class cPlacedPiece +{ +public: + cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece, const Vector3i & a_Coords, int a_NumCCWRotations); + + const cPiece & GetPiece (void) const { return *m_Piece; } + const Vector3i & GetCoords (void) const { return m_Coords; } + const int GetNumCCWRotations(void) const { return m_NumCCWRotations; } + const cCuboid & GetHitBox (void) const { return m_HitBox; } + const int GetDepth (void) const { return m_Depth; } + +protected: + const cPlacedPiece * m_Parent; + const cPiece * m_Piece; + Vector3i m_Coords; + int m_NumCCWRotations; + cCuboid m_HitBox; + int m_Depth; +}; + +typedef std::vector cPlacedPieces; + + + + + +class cPieceGenerator +{ +public: + cPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); + +protected: + /** The type used for storing a connection from one piece to another, while building the piece tree. */ + struct cConnection + { + cPiece * m_Piece; // The piece being connected + cPiece::cConnector * m_Connector; // The piece's connector being used + int m_NumCCWRotations; // Number of rotations necessary to match the two connectors + + cConnection(cPiece & a_Piece, cPiece::cConnector & a_Connector, int a_NumCCWRotations); + }; + typedef std::vector cConnections; + + /** The type used for storing a pool of connectors that will be attempted to expand by another piece. */ + struct cFreeConnector + { + cPlacedPiece * m_Piece; + cPiece::cConnector m_Connector; + + cFreeConnector(cPlacedPiece & a_Piece, const cPiece::cConnector & a_Connector); + }; + typedef std::vector cFreeConnectors; + + + cPiecePool & m_PiecePool; + cNoise m_Noise; + int m_Seed; + + + /** Selects a starting piece and places it, including the rotations. + Also puts the piece's connectors in a_OutConnectors. */ + cPlacedPiece PlaceStartingPiece(int a_BlockX, int a_BlockY, int a_BlockZ, cFreeConnectors & a_OutConnectors); + + /** Tries to place a new piece at the specified (placed) connector. Returns true if successful. */ + bool TryPlacePieceAtConnector( + const cPlacedPiece & a_ParentPiece, + const cPiece::cConnector & a_Connector, + cPlacedPieces & a_OutPieces + ); + + /** Checks if the specified piece would fit with the already-placed pieces, using the specified connector + and number of CCW rotations. + Returns true if the piece fits, false if not. */ + bool CheckConnection( + const cPiece::cConnector & a_ExistingConnector, // The existing connector + const cPiece & a_Piece, // The new piece + const cPiece::cConnector & a_NewConnector, // The connector of the new piece + int a_NumCCWRotations, // Number of rotations for the new piece to align the connector + const cPlacedPieces & a_OutPieces // All the already-placed pieces to check + ); +} ; + + + + + +class cBFSPieceGenerator : + public cPieceGenerator +{ + typedef cPieceGenerator super; + +public: + cBFSPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); + + /** Generates a placement for pieces at the specified coords. */ + void PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, cPlacedPieces & a_OutPieces); +}; + + + + + +class cDFSPieceGenerator : + public cPieceGenerator +{ +public: + cDFSPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); + + /** Generates a placement for pieces at the specified coords. */ + void PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, cPlacedPieces & a_OutPieces); +}; + + + + -- cgit v1.2.3 From 93f0de521a0e2abb9c35dfb06bd3d306c548bf1b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 7 Mar 2014 21:43:15 +0100 Subject: Added Vector3i::Move(). --- src/Vector3i.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- src/Vector3i.h | 47 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 82 insertions(+), 17 deletions(-) diff --git a/src/Vector3i.cpp b/src/Vector3i.cpp index 4ce1e2cf3..2106aea6d 100644 --- a/src/Vector3i.cpp +++ b/src/Vector3i.cpp @@ -1,6 +1,11 @@ +// Vector3i.cpp + +// Implements the Vector3i class representing an int-based 3D vector + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules +#include "math.h" #include "Vector3i.h" #include "Vector3d.h" @@ -8,9 +13,46 @@ -Vector3i::Vector3i( const Vector3d & v ) - : x( (int)v.x ) - , y( (int)v.y ) - , z( (int)v.z ) +Vector3i::Vector3i(const Vector3d & v) : + x((int)v.x), + y((int)v.y), + z((int)v.z) +{ +} + + + + + +Vector3i::Vector3i(void) : + x(0), + y(0), + z(0) +{ +} + + + + + +Vector3i::Vector3i(int a_x, int a_y, int a_z) : + x(a_x), + y(a_y), + z(a_z) +{ +} + + + + + +void Vector3i::Move(int a_MoveX, int a_MoveY, int a_MoveZ) { -} \ No newline at end of file + x += a_MoveX; + y += a_MoveY; + z += a_MoveZ; +} + + + + diff --git a/src/Vector3i.h b/src/Vector3i.h index 7d726a7b3..39e138683 100644 --- a/src/Vector3i.h +++ b/src/Vector3i.h @@ -1,22 +1,45 @@ + +// Vector3i.h + +// Declares the Vector3i class representing an int-based 3D vector + + + + + #pragma once -#include + + + +// fwd: class Vector3d; -class Vector3i // tolua_export -{ // tolua_export -public: // tolua_export - Vector3i( const Vector3d & v ); // tolua_export - Vector3i() : x(0), y(0), z(0) {} // tolua_export - Vector3i(int a_x, int a_y, int a_z) : x(a_x), y(a_y), z(a_z) {} // tolua_export - inline void Set(int a_x, int a_y, int a_z) { x = a_x, y = a_y, z = a_z; } // tolua_export - inline float Length() const { return sqrtf( (float)( x * x + y * y + z * z) ); } // tolua_export - inline int SqrLength() const { return x * x + y * y + z * z; } // tolua_export - inline bool Equals( const Vector3i & v ) const { return (x == v.x && y == v.y && z == v.z ); } // tolua_export - inline bool Equals( const Vector3i * v ) const { return (x == v->x && y == v->y && z == v->z ); } // tolua_export + + +// tolua_begin +class Vector3i +{ +public: + /** Creates an int vector based on the floor()-ed coords of a double vector. */ + Vector3i(const Vector3d & v); + + Vector3i(void); + Vector3i(int a_x, int a_y, int a_z); + + inline void Set(int a_x, int a_y, int a_z) { x = a_x, y = a_y, z = a_z; } + inline float Length() const { return sqrtf( (float)( x * x + y * y + z * z) ); } + inline int SqrLength() const { return x * x + y * y + z * z; } + + inline bool Equals( const Vector3i & v ) const { return (x == v.x && y == v.y && z == v.z ); } + inline bool Equals( const Vector3i * v ) const { return (x == v->x && y == v->y && z == v->z ); } + + void Move(int a_MoveX, int a_MoveY, int a_MoveZ); + + // tolua_end void operator += ( const Vector3i& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } void operator += ( Vector3i* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } -- cgit v1.2.3 From 5be983e7752091adbf7262f3074b3062ea44ae73 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 9 Mar 2014 10:05:30 +0100 Subject: Added BlockFaceToString() translation function. --- src/Defines.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Defines.h b/src/Defines.h index 6ab2274a4..d2fcce576 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -276,6 +276,26 @@ inline eBlockFace RotateBlockFaceCW(eBlockFace a_BlockFace) +/** Returns the textual representation of the BlockFace constant. */ +inline AString BlockFaceToString(eBlockFace a_BlockFace) +{ + switch (a_BlockFace) + { + case BLOCK_FACE_XM: return "BLOCK_FACE_XM"; + case BLOCK_FACE_XP: return "BLOCK_FACE_XP"; + case BLOCK_FACE_YM: return "BLOCK_FACE_YM"; + case BLOCK_FACE_YP: return "BLOCK_FACE_YP"; + case BLOCK_FACE_ZM: return "BLOCK_FACE_ZM"; + case BLOCK_FACE_ZP: return "BLOCK_FACE_ZP"; + case BLOCK_FACE_NONE: return "BLOCK_FACE_NONE"; + } + return Printf("Unknown BLOCK_FACE: %d", a_BlockFace); +} + + + + + inline bool IsValidBlock(int a_BlockType) { if ( -- cgit v1.2.3 From b9190fc04e1463371cec773d069315a6743a56d5 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 9 Mar 2014 10:11:33 +0100 Subject: PieceGenerator can connect two connectors of the same type. Also added extensive debugging output and a test. --- src/Generating/PieceGenerator.cpp | 347 ++++++++++++++++++++++++++++++++------ src/Generating/PieceGenerator.h | 51 ++++-- 2 files changed, 338 insertions(+), 60 deletions(-) diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index 04513666d..58ccaf2c2 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -11,9 +11,169 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Self-test: + +static class cPieceGeneratorSelfTest : + public cPiecePool +{ +public: + cPieceGeneratorSelfTest(void) + { + // Prepare the internal state: + InitializePieces(); + + // Generate: + cBFSPieceGenerator Gen(*this, 0); + cPlacedPieces OutPieces; + Gen.PlacePieces(500, 50, 500, 3, OutPieces); + + // Print out the pieces: + printf("OutPieces.size() = %u\n", OutPieces.size()); + size_t idx = 0; + for (cPlacedPieces::const_iterator itr = OutPieces.begin(), end = OutPieces.end(); itr != end; ++itr, ++idx) + { + const Vector3i & Coords = (*itr)->GetCoords(); + cCuboid Hitbox = (*itr)->GetHitBox(); + Hitbox.Sort(); + printf("%u: {%d, %d, %d}, rot %d, hitbox {%d, %d, %d} - {%d, %d, %d} (%d * %d * %d)\n", idx, + Coords.x, Coords.y, Coords.z, + (*itr)->GetNumCCWRotations(), + Hitbox.p1.x, Hitbox.p1.y, Hitbox.p1.z, + Hitbox.p2.x, Hitbox.p2.y, Hitbox.p2.z, + Hitbox.DifX() + 1, Hitbox.DifY() + 1, Hitbox.DifZ() + 1 + ); + } // itr - OutPieces[] + printf("Done.\n"); + + // Free the placed pieces properly: + Gen.FreePieces(OutPieces); + } + + ~cPieceGeneratorSelfTest() + { + // Dealloc all the pieces: + for (cPieces::iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr) + { + delete *itr; + } + m_Pieces.clear(); + } + +protected: + class cTestPiece : + public cPiece + { + int m_Size; + public: + cTestPiece(int a_Size) : + m_Size(a_Size) + { + } + + virtual cConnectors GetConnectors(void) const override + { + // Each piece has 4 connectors, one of each type, plus one extra, at the center of its walls: + cConnectors res; + res.push_back(cConnector(m_Size / 2, 1, 0, 0, BLOCK_FACE_ZM)); + res.push_back(cConnector(m_Size / 2, 1, m_Size - 1, 1, BLOCK_FACE_ZP)); + res.push_back(cConnector(0, 1, m_Size / 2, 2, BLOCK_FACE_XM)); + res.push_back(cConnector(m_Size - 1, 1, m_Size / 2, m_Size % 3, BLOCK_FACE_XP)); + return res; + } + + virtual Vector3i GetSize(void) const override + { + return Vector3i(m_Size, 5, m_Size); + } + + virtual cCuboid GetHitBox(void) const override + { + return cCuboid(0, 0, 0, m_Size - 1, 4, m_Size - 1); + } + + virtual bool CanRotateCCW(int a_NumCCWRotations) const override + { + return true; + } + }; + + cPieces m_Pieces; + + virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override + { + // Each piece contains each connector + return m_Pieces; + } + + + virtual cPieces GetStartingPieces(void) override + { + return m_Pieces; + } + + + virtual void PiecePlaced(const cPiece & a_Piece) override + { + UNUSED(a_Piece); + } + + + virtual void Reset(void) override + { + } + + + void InitializePieces(void) + { + m_Pieces.push_back(new cTestPiece(5)); + m_Pieces.push_back(new cTestPiece(7)); + m_Pieces.push_back(new cTestPiece(9)); + } +} g_Test; + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPiece: + +Vector3i cPiece::RotatePos(const Vector3i & a_Pos, int a_NumCCWRotations) const +{ + Vector3i Size = GetSize(); + switch (a_NumCCWRotations) + { + case 0: + { + // No rotation needed + return a_Pos; + } + case 1: + { + // 1 CCW rotation: + return Vector3i(a_Pos.z, a_Pos.y, Size.x - a_Pos.x - 1); + } + case 2: + { + // 2 rotations ( = axis flip): + return Vector3i(Size.x - a_Pos.x - 1, a_Pos.y, Size.z - a_Pos.z - 1); + } + case 3: + { + // 1 CW rotation: + return Vector3i(Size.z - a_Pos.z - 1, a_Pos.y, a_Pos.x); + } + } + ASSERT(!"Unhandled rotation"); + return a_Pos; +} + + + + + cPiece::cConnector cPiece::RotateMoveConnector(const cConnector & a_Connector, int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const { cPiece::cConnector res(a_Connector); @@ -30,37 +190,28 @@ cPiece::cConnector cPiece::RotateMoveConnector(const cConnector & a_Connector, i case 1: { // 1 CCW rotation: - int NewX = Size.z - res.m_X; - int NewZ = res.m_Z; - res.m_X = NewX; - res.m_Z = NewZ; res.m_Direction = RotateBlockFaceCCW(res.m_Direction); break; } case 2: { // 2 rotations ( = axis flip): - res.m_X = Size.x - res.m_X; - res.m_Z = Size.z - res.m_Z; res.m_Direction = MirrorBlockFaceY(res.m_Direction); break; } case 3: { // 1 CW rotation: - int NewX = res.m_Z; - int NewZ = Size.x - res.m_X; - res.m_X = NewX; - res.m_Z = NewZ; res.m_Direction = RotateBlockFaceCW(res.m_Direction); break; } } + res.m_Pos = RotatePos(a_Connector.m_Pos, a_NumCCWRotations); // Move the res connector: - res.m_X += a_MoveX; - res.m_Y += a_MoveY; - res.m_Z += a_MoveZ; + res.m_Pos.x += a_MoveX; + res.m_Pos.y += a_MoveY; + res.m_Pos.z += a_MoveZ; return res; } @@ -71,25 +222,28 @@ cPiece::cConnector cPiece::RotateMoveConnector(const cConnector & a_Connector, i cCuboid cPiece::RotateHitBoxToConnector( const cPiece::cConnector & a_MyConnector, - const cPiece::cConnector & a_ToConnector, + const Vector3i & a_ToConnectorPos, int a_NumCCWRotations ) const { + ASSERT(a_NumCCWRotations == (a_NumCCWRotations % 4)); + Vector3i ConnPos = RotatePos(a_MyConnector.m_Pos, a_NumCCWRotations); + ConnPos = a_ToConnectorPos - ConnPos; + return RotateMoveHitBox(a_NumCCWRotations, ConnPos.x, ConnPos.y, ConnPos.z); +} + + + + + +cCuboid cPiece::RotateMoveHitBox(int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const +{ + ASSERT(a_NumCCWRotations == (a_NumCCWRotations % 4)); cCuboid res = GetHitBox(); - switch (a_NumCCWRotations) - { - case 0: - { - // No rotation, return the hitbox as-is - break; - } - case 1: - { - // 1 CCW rotation: - // TODO: res.p1.x = - break; - } - } + res.p1 = RotatePos(res.p1, a_NumCCWRotations); + res.p2 = RotatePos(res.p2, a_NumCCWRotations); + res.p1.Move(a_MoveX, a_MoveY, a_MoveZ); + res.p2.Move(a_MoveX, a_MoveY, a_MoveZ); return res; } @@ -97,6 +251,31 @@ cCuboid cPiece::RotateHitBoxToConnector( +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPiece::cConnector: + +cPiece::cConnector::cConnector(int a_X, int a_Y, int a_Z, int a_Type, eBlockFace a_Direction) : + m_Pos(a_X, a_Y, a_Z), + m_Type(a_Type), + m_Direction(a_Direction) +{ +} + + + + + +cPiece::cConnector::cConnector(const Vector3i & a_Pos, int a_Type, eBlockFace a_Direction) : + m_Pos(a_Pos), + m_Type(a_Type), + m_Direction(a_Direction) +{ +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPlacedPiece: @@ -107,6 +286,7 @@ cPlacedPiece::cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece m_NumCCWRotations(a_NumCCWRotations) { m_Depth = (m_Parent == NULL) ? 0 : (m_Parent->GetDepth() + 1); + m_HitBox = a_Piece.RotateMoveHitBox(a_NumCCWRotations, a_Coords.x, a_Coords.y, a_Coords.z); } @@ -127,7 +307,20 @@ cPieceGenerator::cPieceGenerator(cPiecePool & a_PiecePool, int a_Seed) : -cPlacedPiece cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, int a_BlockZ, cFreeConnectors & a_OutConnectors) +void cPieceGenerator::FreePieces(cPlacedPieces & a_PlacedPieces) +{ + for (cPlacedPieces::iterator itr = a_PlacedPieces.begin(), end = a_PlacedPieces.end(); itr != end; ++itr) + { + delete *itr; + } // for itr - a_PlacedPieces[] + a_PlacedPieces.clear(); +} + + + + + +cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, int a_BlockZ, cFreeConnectors & a_OutConnectors) { m_PiecePool.Reset(); int rnd = m_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) / 7; @@ -150,7 +343,7 @@ cPlacedPiece cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, int } int Rotation = Rotations[rnd % NumRotations]; - cPlacedPiece res(NULL, *StartingPiece, Vector3i(a_BlockX, a_BlockY, a_BlockZ), Rotation); + cPlacedPiece * res = new cPlacedPiece(NULL, *StartingPiece, Vector3i(a_BlockX, a_BlockY, a_BlockZ), Rotation); // Place the piece's connectors into a_OutConnectors: const cPiece::cConnectors & Conn = StartingPiece->GetConnectors(); @@ -171,7 +364,7 @@ cPlacedPiece cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, int bool cPieceGenerator::TryPlacePieceAtConnector(const cPlacedPiece & a_ParentPiece, const cPiece::cConnector & a_Connector, cPlacedPieces & a_OutPieces) { // Translation of direction - direction -> number of CCW rotations needed: - // You need DirectionRotationTable[rot1][rot2] CCW turns to get from rot1 to rot2 + // You need DirectionRotationTable[rot1][rot2] CCW turns to connect rot1 to rot2 (they are opposite) static const int DirectionRotationTable[6][6] = { /* YM, YP, ZM, ZP, XM, XP @@ -188,6 +381,12 @@ bool cPieceGenerator::TryPlacePieceAtConnector(const cPlacedPiece & a_ParentPiec cConnections Connections; cPieces AvailablePieces = m_PiecePool.GetPiecesWithConnector(a_Connector.m_Type); Connections.reserve(AvailablePieces.size()); + Vector3i ConnPos = a_Connector.m_Pos; // The position at which the new connector should be placed - 1 block away from the connector + AddFaceDirection(ConnPos.x, ConnPos.y, ConnPos.z, a_Connector.m_Direction); + + // DEBUG: + printf("Placing piece at pos {%d, %d, %d}, direction %s\n", ConnPos.x, ConnPos.y, ConnPos.z, BlockFaceToString(a_Connector.m_Direction).c_str()); + for (cPieces::iterator itrP = AvailablePieces.begin(), endP = AvailablePieces.end(); itrP != endP; ++itrP) { cPiece::cConnectors Connectors = (*itrP)->GetConnectors(); @@ -204,7 +403,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector(const cPlacedPiece & a_ParentPiec // Doesn't support this rotation continue; } - if (!CheckConnection(a_Connector, **itrP, *itrC, NumCCWRotations, a_OutPieces)) + if (!CheckConnection(a_Connector, ConnPos, **itrP, *itrC, NumCCWRotations, a_OutPieces)) { // Doesn't fit in this rotation continue; @@ -219,17 +418,23 @@ bool cPieceGenerator::TryPlacePieceAtConnector(const cPlacedPiece & a_ParentPiec } // Choose a random connection from the list: - int rnd = m_Noise.IntNoise3DInt(a_Connector.m_X, a_Connector.m_Y, a_Connector.m_Z) / 7; + int rnd = m_Noise.IntNoise3DInt(a_Connector.m_Pos.x, a_Connector.m_Pos.y, a_Connector.m_Pos.z) / 7; cConnection & Conn = Connections[rnd % Connections.size()]; // Place the piece: - cPiece::cConnector NewConnector = Conn.m_Piece->RotateMoveConnector(*(Conn.m_Connector), Conn.m_NumCCWRotations, 0, 0, 0); - Vector3i Coords = a_ParentPiece.GetCoords(); - Coords.x -= NewConnector.m_X; - Coords.y -= NewConnector.m_Y; - Coords.z -= NewConnector.m_Z; - a_OutPieces.push_back(cPlacedPiece(&a_ParentPiece, *(Conn.m_Piece), Coords, Conn.m_NumCCWRotations)); - return false; + printf("Chosen connector at {%d, %d, %d}, direction %s, needs %d rotations\n", + Conn.m_Connector.m_Pos.x, Conn.m_Connector.m_Pos.y, Conn.m_Connector.m_Pos.z, + BlockFaceToString(Conn.m_Connector.m_Direction).c_str(), + Conn.m_NumCCWRotations + ); + Vector3i NewPos = Conn.m_Piece->RotatePos(Conn.m_Connector.m_Pos, Conn.m_NumCCWRotations); + ConnPos -= NewPos; + a_OutPieces.push_back(new cPlacedPiece(&a_ParentPiece, *(Conn.m_Piece), ConnPos, Conn.m_NumCCWRotations)); + + // Add the new piece's connectors to the list of free connectors: + // TODO + + return true; } @@ -238,6 +443,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector(const cPlacedPiece & a_ParentPiec bool cPieceGenerator::CheckConnection( const cPiece::cConnector & a_ExistingConnector, + const Vector3i & a_ToPos, const cPiece & a_Piece, const cPiece::cConnector & a_NewConnector, int a_NumCCWRotations, @@ -245,10 +451,10 @@ bool cPieceGenerator::CheckConnection( ) { // For each placed piece, test the hitbox against the new piece: - cCuboid RotatedHitBox = a_Piece.RotateHitBoxToConnector(a_NewConnector, a_ExistingConnector, a_NumCCWRotations); + cCuboid RotatedHitBox = a_Piece.RotateHitBoxToConnector(a_NewConnector, a_ToPos, a_NumCCWRotations); for (cPlacedPieces::const_iterator itr = a_OutPieces.begin(), end = a_OutPieces.end(); itr != end; ++itr) { - if (itr->GetHitBox().DoesIntersect(RotatedHitBox)) + if ((*itr)->GetHitBox().DoesIntersect(RotatedHitBox)) { return false; } @@ -260,12 +466,32 @@ bool cPieceGenerator::CheckConnection( +// DEBUG: +void cPieceGenerator::DebugConnectorPool(const cPieceGenerator::cFreeConnectors & a_ConnectorPool, size_t a_NumProcessed) +{ + printf(" Connector pool: %u items\n", a_ConnectorPool.size() - a_NumProcessed); + size_t idx = 0; + for (cPieceGenerator::cFreeConnectors::const_iterator itr = a_ConnectorPool.begin() + a_NumProcessed, end = a_ConnectorPool.end(); itr != end; ++itr, ++idx) + { + printf(" %u: {%d, %d, %d}, type %d, direction %s\n", + idx, + itr->m_Connector.m_Pos.x, itr->m_Connector.m_Pos.y, itr->m_Connector.m_Pos.z, + itr->m_Connector.m_Type, + BlockFaceToString(itr->m_Connector.m_Direction).c_str() + ); + } // for itr - a_ConnectorPool[] +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPieceGenerator::cConnection: cPieceGenerator::cConnection::cConnection(cPiece & a_Piece, cPiece::cConnector & a_Connector, int a_NumCCWRotations) : m_Piece(&a_Piece), - m_Connector(&a_Connector), + m_Connector(a_Connector), m_NumCCWRotations(a_NumCCWRotations) { } @@ -277,8 +503,8 @@ cPieceGenerator::cConnection::cConnection(cPiece & a_Piece, cPiece::cConnector & /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPieceGenerator::cFreeConnector: -cPieceGenerator::cFreeConnector::cFreeConnector(cPlacedPiece & a_Piece, const cPiece::cConnector & a_Connector) : - m_Piece(&a_Piece), +cPieceGenerator::cFreeConnector::cFreeConnector(cPlacedPiece * a_Piece, const cPiece::cConnector & a_Connector) : + m_Piece(a_Piece), m_Connector(a_Connector) { } @@ -299,7 +525,7 @@ cBFSPieceGenerator::cBFSPieceGenerator(cPiecePool & a_PiecePool, int a_Seed) : -void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, cPlacedPieces & a_OutPieces) +void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MaxDepth, cPlacedPieces & a_OutPieces) { a_OutPieces.clear(); cFreeConnectors ConnectorPool; @@ -307,6 +533,17 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, c // Place the starting piece: a_OutPieces.push_back(PlaceStartingPiece(a_BlockX, a_BlockY, a_BlockZ, ConnectorPool)); + // DEBUG: + printf("Placed the starting piece at {%d, %d, %d}\n", a_BlockX, a_BlockY, a_BlockZ); + cCuboid Hitbox = a_OutPieces[0]->GetHitBox(); + Hitbox.Sort(); + printf(" Hitbox: {%d, %d, %d} - {%d, %d, %d} (%d * %d * %d)\n", + Hitbox.p1.x, Hitbox.p1.y, Hitbox.p1.z, + Hitbox.p2.x, Hitbox.p2.y, Hitbox.p2.z, + Hitbox.DifX() + 1, Hitbox.DifY() + 1, Hitbox.DifZ() + 1 + ); + DebugConnectorPool(ConnectorPool, 0); + // Place pieces at the available connectors: /* Instead of removing them one by one from the pool, we process them sequentially and take note of the last @@ -317,7 +554,23 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, c while (ConnectorPool.size() > NumProcessed) { cFreeConnector & Conn = ConnectorPool[NumProcessed]; - TryPlacePieceAtConnector(*Conn.m_Piece, Conn.m_Connector, a_OutPieces); + if (Conn.m_Piece->GetDepth() < a_MaxDepth) + { + if (TryPlacePieceAtConnector(*Conn.m_Piece, Conn.m_Connector, a_OutPieces)) + { + const cPlacedPiece * NewPiece = a_OutPieces.back(); + const Vector3i & Coords = NewPiece->GetCoords(); + printf("Placed a new piece at {%d, %d, %d}, rotation %d\n", Coords.x, Coords.y, Coords.z, NewPiece->GetNumCCWRotations()); + cCuboid Hitbox = NewPiece->GetHitBox(); + Hitbox.Sort(); + printf(" Hitbox: {%d, %d, %d} - {%d, %d, %d} (%d * %d * %d)\n", + Hitbox.p1.x, Hitbox.p1.y, Hitbox.p1.z, + Hitbox.p2.x, Hitbox.p2.y, Hitbox.p2.z, + Hitbox.DifX() + 1, Hitbox.DifY() + 1, Hitbox.DifZ() + 1 + ); + DebugConnectorPool(ConnectorPool, NumProcessed + 1); + } + } NumProcessed++; if (NumProcessed > 1000) { diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 3bc71a0ab..0e24510ae 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -32,13 +32,18 @@ class cPiece public: struct cConnector { - int m_X; - int m_Y; - int m_Z; + /** Position relative to the piece */ + Vector3i m_Pos; + + /** Type of the connector. Any arbitrary number; the generator connects only connectors of the same type. */ int m_Type; + + /** Direction in which the connector is facing. + Will be matched by the opposite direction for the connecting connector. */ eBlockFace m_Direction; - cConnector(int a_X, int a_Y, int a_Z, int a_Type, eBlockFace m_Direction); + cConnector(int a_X, int a_Y, int a_Z, int a_Type, eBlockFace a_Direction); + cConnector(const Vector3i & a_Pos, int a_Type, eBlockFace a_Direction); }; typedef std::vector cConnectors; @@ -58,11 +63,17 @@ public: /** Returns true if the piece can be rotated CCW the specific number of 90-degree turns. */ virtual bool CanRotateCCW(int a_NumRotations) const = 0; + /** Returns a copy of the a_Pos after rotating the piece the specified number of CCW rotations. */ + Vector3i RotatePos(const Vector3i & a_Pos, int a_NumCCWRotations) const; + /** Returns a copy of the connector that is rotated and then moved by the specified amounts. */ cConnector RotateMoveConnector(const cConnector & a_Connector, int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const; - /** Returns the hitbox after the specified number of rotations and moved so that a_MyConnector is placed at a_ToConnector*/ - cCuboid RotateHitBoxToConnector(const cConnector & a_MyConnector, const cConnector & a_ToConnector, int a_NumCCWRotations) const; + /** Returns the hitbox after the specified number of rotations and moved so that a_MyConnector is placed at a_ToConnectorPos. */ + cCuboid RotateHitBoxToConnector(const cConnector & a_MyConnector, const Vector3i & a_ToConnectorPos, int a_NumCCWRotations) const; + + /** Returns the hitbox after the specified number of CCW rotations and moved by the specified amounts. */ + cCuboid RotateMoveHitBox(int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const; }; typedef std::vector cPieces; @@ -116,7 +127,7 @@ protected: int m_Depth; }; -typedef std::vector cPlacedPieces; +typedef std::vector cPlacedPieces; @@ -127,12 +138,16 @@ class cPieceGenerator public: cPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); + /** Cleans up all the memory used by the placed pieces. + Call this utility function instead of freeing the items on your own. */ + void FreePieces(cPlacedPieces & a_PlacedPieces); + protected: /** The type used for storing a connection from one piece to another, while building the piece tree. */ struct cConnection { cPiece * m_Piece; // The piece being connected - cPiece::cConnector * m_Connector; // The piece's connector being used + cPiece::cConnector m_Connector; // The piece's connector being used (relative non-rotated coords) int m_NumCCWRotations; // Number of rotations necessary to match the two connectors cConnection(cPiece & a_Piece, cPiece::cConnector & a_Connector, int a_NumCCWRotations); @@ -145,7 +160,7 @@ protected: cPlacedPiece * m_Piece; cPiece::cConnector m_Connector; - cFreeConnector(cPlacedPiece & a_Piece, const cPiece::cConnector & a_Connector); + cFreeConnector(cPlacedPiece * a_Piece, const cPiece::cConnector & a_Connector); }; typedef std::vector cFreeConnectors; @@ -157,7 +172,7 @@ protected: /** Selects a starting piece and places it, including the rotations. Also puts the piece's connectors in a_OutConnectors. */ - cPlacedPiece PlaceStartingPiece(int a_BlockX, int a_BlockY, int a_BlockZ, cFreeConnectors & a_OutConnectors); + cPlacedPiece * PlaceStartingPiece(int a_BlockX, int a_BlockY, int a_BlockZ, cFreeConnectors & a_OutConnectors); /** Tries to place a new piece at the specified (placed) connector. Returns true if successful. */ bool TryPlacePieceAtConnector( @@ -168,14 +183,22 @@ protected: /** Checks if the specified piece would fit with the already-placed pieces, using the specified connector and number of CCW rotations. + a_ExistingConnector is in world-coords and is already rotated properly + a_ToPos is the world-coords position on which the new connector should be placed (1 block away from a_ExistingConnector, in its Direction) + a_NewConnector is in the original (non-rotated) coords. Returns true if the piece fits, false if not. */ bool CheckConnection( const cPiece::cConnector & a_ExistingConnector, // The existing connector + const Vector3i & a_ToPos, // The position on which the new connector should be placed const cPiece & a_Piece, // The new piece const cPiece::cConnector & a_NewConnector, // The connector of the new piece int a_NumCCWRotations, // Number of rotations for the new piece to align the connector const cPlacedPieces & a_OutPieces // All the already-placed pieces to check ); + + /** DEBUG: Outputs all the connectors in the pool into stdout. + a_NumProcessed signals the number of connectors from the pool that should be considered processed (not listed). */ + void DebugConnectorPool(const cPieceGenerator::cFreeConnectors & a_ConnectorPool, size_t a_NumProcessed); } ; @@ -190,8 +213,9 @@ class cBFSPieceGenerator : public: cBFSPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); - /** Generates a placement for pieces at the specified coords. */ - void PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, cPlacedPieces & a_OutPieces); + /** Generates a placement for pieces at the specified coords. + Caller must free each individual cPlacedPiece in a_OutPieces. */ + void PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, int a_MaxDepth, cPlacedPieces & a_OutPieces); }; @@ -204,7 +228,8 @@ class cDFSPieceGenerator : public: cDFSPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); - /** Generates a placement for pieces at the specified coords. */ + /** Generates a placement for pieces at the specified coords. + Caller must free each individual cPlacedPiece in a_OutPieces. */ void PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, cPlacedPieces & a_OutPieces); }; -- cgit v1.2.3 From 77787fb719bf6437d4101f091b5b9acedea83dd3 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 9 Mar 2014 14:55:47 +0000 Subject: != FACE_NONE --- src/ClientHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d268a4122..1bd55a461 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -949,7 +949,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - if (a_BlockFace > BLOCK_FACE_NONE) + if (a_BlockFace != BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); -- cgit v1.2.3 From b64e9fb7f52e4a2b75b49413fdc2194132885370 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 9 Mar 2014 00:17:23 +0000 Subject: Beds now work properly fixes #707 Also fixes FS392 Conflicts: src/Blocks/WorldInterface.h src/ClientHandle.cpp --- src/Blocks/BlockBed.cpp | 73 +++++++++++++++++++++++++++++++++++++---- src/Blocks/BroadcastInterface.h | 5 +-- src/Blocks/WorldInterface.h | 8 ++++- src/Entities/Player.h | 17 ++++++++-- src/World.h | 8 ++--- 5 files changed, 94 insertions(+), 17 deletions(-) diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index 3dad4feba..ca3927827 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -51,6 +51,49 @@ void cBlockBedHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInt +class cTimeFastForwardTester : + public cPlayerListCallback +{ + virtual bool Item(cPlayer * a_Player) override + { + if (!a_Player->IsInBed()) + { + return true; + } + + return false; + } +}; + + + + + +class cPlayerBedStateUnsetter : + public cPlayerListCallback +{ +public: + cPlayerBedStateUnsetter(Vector3i a_Position, cWorldInterface & a_WorldInterface) : + m_Position(a_Position), m_WorldInterface(a_WorldInterface) + { + } + + virtual bool Item(cPlayer * a_Player) override + { + a_Player->SetIsInBed(false); + m_WorldInterface.GetBroadcastManager().BroadcastEntityAnimation(*a_Player, 2); + return false; + } + +private: + Vector3i m_Position; + cWorldInterface & m_WorldInterface; +}; + + + + + void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { if (a_WorldInterface.GetDimension() != dimOverworld) @@ -69,6 +112,8 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface } else { + Vector3i PillowDirection(0, 0, 0); + if (Meta & 0x8) { // Is pillow @@ -77,16 +122,30 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface else { // Is foot end - Vector3i Direction = MetaDataToDirection( Meta & 0x7 ); - if (a_ChunkInterface.GetBlock(a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z) == E_BLOCK_BED) // Must always use pillow location for sleeping + VERIFY((Meta & 0x4) != 1); // Occupied flag should never be set, else our compilator (intended) is broken + + PillowDirection = MetaDataToDirection(Meta & 0x7); + if (a_ChunkInterface.GetBlock(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z) == E_BLOCK_BED) // Must always use pillow location for sleeping { - a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX + Direction.x, a_BlockY, a_BlockZ + Direction.z); + a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z); } } - a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, (Meta | (1 << 2))); - } - - } else { + + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x4); // Where 0x4 = occupied bit + a_Player->SetIsInBed(true); + + cTimeFastForwardTester Tester; + if (a_WorldInterface.ForEachPlayer(Tester)) + { + cPlayerBedStateUnsetter Unsetter(Vector3i(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z), a_WorldInterface); + a_WorldInterface.ForEachPlayer(Unsetter); + a_WorldInterface.SetTimeOfDay(0); + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0xB); // Where 0xB = 1011, and zero is to make sure 'occupied' bit is always unset + } + } + } + else + { a_Player->SendMessageFailure("You can only sleep at night"); } } diff --git a/src/Blocks/BroadcastInterface.h b/src/Blocks/BroadcastInterface.h index f6ccd580b..01966ffbd 100644 --- a/src/Blocks/BroadcastInterface.h +++ b/src/Blocks/BroadcastInterface.h @@ -5,6 +5,7 @@ class cBroadcastInterface { public: - virtual void BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; - virtual void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0; + virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; + virtual void BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0; + virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) = 0; }; diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index e59b00eff..580339d32 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -27,7 +27,13 @@ public: /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType) = 0; - + /** Sends the block on those coords to the player */ virtual void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player) = 0; + + /** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */ + virtual bool ForEachPlayer(cItemCallback & a_Callback) = 0; + + virtual void SetTimeOfDay(Int64 a_TimeOfDay) = 0; + }; diff --git a/src/Entities/Player.h b/src/Entities/Player.h index a795bb9eb..83a553821 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -275,6 +275,9 @@ public: /// Returns true if the player is currently flying. bool IsFlying(void) const { return m_IsFlying; } + /** Returns if a player is sleeping in a bed */ + bool IsInBed(void) const { return m_bIsInBed; } + /// returns true if the player has thrown out a floater. bool IsFishing(void) const { return m_IsFishing; } @@ -283,6 +286,9 @@ public: int GetFloaterID(void) const { return m_FloaterID; } // tolua_end + + /** Sets a player's in-bed state; we can't be sure plugins will keep this value updated, so no exporting */ + void SetIsInBed(bool a_Flag) { m_bIsInBed = a_Flag; } /// Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet void StartEating(void); @@ -376,8 +382,8 @@ protected: GroupList m_ResolvedGroups; GroupList m_Groups; - std::string m_PlayerName; - std::string m_LoadedWorldName; + AString m_PlayerName; + AString m_LoadedWorldName; /// Xp Level stuff enum @@ -465,7 +471,7 @@ protected: int m_FloaterID; - cTeam* m_Team; + cTeam * m_Team; @@ -488,6 +494,11 @@ protected: /// Adds food exhaustion based on the difference between Pos and LastPos, sprinting status and swimming (in water block) void ApplyFoodExhaustionFromMovement(); + + /** Flag representing whether the player is currently in a bed + Set by a right click on unoccupied bed, unset by a time fast forward or teleport */ + bool m_bIsInBed; + } ; // tolua_export diff --git a/src/World.h b/src/World.h index 0a0939dd1..738697c94 100644 --- a/src/World.h +++ b/src/World.h @@ -134,7 +134,7 @@ public: m_WeatherInterval = a_WeatherInterval; } - void SetTimeOfDay(Int64 a_TimeOfDay) + virtual void SetTimeOfDay(Int64 a_TimeOfDay) { m_TimeOfDay = a_TimeOfDay; m_TimeOfDaySecs = (double)a_TimeOfDay / 20.0; @@ -204,7 +204,7 @@ public: void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityAnimation (const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL); + virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL); void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); // tolua_export void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); @@ -217,7 +217,7 @@ public: void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); void BroadcastTimeUpdate (const cClientHandle * a_Exclude = NULL); - virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ); + virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ); void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = NULL); virtual cBroadcastInterface & GetBroadcastManager() @@ -274,7 +274,7 @@ public: void RemovePlayer( cPlayer* a_Player ); /** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */ - bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + virtual bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << /** Calls the callback for the player of the given name; returns true if the player was found and the callback called, false if player not found. Callback return ignored */ bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << -- cgit v1.2.3 From 888c3f1af7b817ab770703ce0638e0eef07d2d31 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 9 Mar 2014 15:53:03 +0000 Subject: Fixed VERIFY --- src/Blocks/BlockBed.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index ca3927827..6a3c6a55b 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -122,7 +122,7 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface else { // Is foot end - VERIFY((Meta & 0x4) != 1); // Occupied flag should never be set, else our compilator (intended) is broken + VERIFY((Meta & 0x4) != 0x4); // Occupied flag should never be set, else our compilator (intended) is broken PillowDirection = MetaDataToDirection(Meta & 0x7); if (a_ChunkInterface.GetBlock(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z) == E_BLOCK_BED) // Must always use pillow location for sleeping -- cgit v1.2.3 From c5436e1ae75928f08a411d29a0b28241c3f2b062 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 09:16:15 -0700 Subject: Lots more warnings --- SetFlags.cmake | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/SetFlags.cmake b/SetFlags.cmake index 56d32b8fe..ec2f6c556 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -192,6 +192,15 @@ macro(set_exe_flags) add_flags_cxx("-D__extern_always_inline=inline") add_flags_cxx("-Weverything -Wno-c++98-compat-pedantic -Wno-string-conversion") add_flags_cxx("-Wno-extra-semi -Wno-error=switch-enum -Wno-documentation") + add_flags_cxx("-Wno-error=sign-conversion -Wno-error=conversion -Wno-error=padded") + add_flags_cxx("-Wno-error=deprecated -Wno-error=weak-vtables -Wno-error=float-equal") + add_flags_cxx("-Wno-error=missing-prototypes -Wno-error=non-virtual-dtor") + add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") + add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") + add_flags_cxx("-Wno-error=cast-align -Wno-error=unused-macros") + add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") + add_flags_cxx("-Wno-missing-noreturn -Wno-error=unreachable-code -Wno-error=undef") + add_flags_cxx("-Wno-error=format-nonliteral") endif() endif() -- cgit v1.2.3 From f4201e0b825479c6ae8ff3165fc0b7fa949c0006 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 09:25:16 -0700 Subject: Fixed gcc error --- src/WorldStorage/WSSCompact.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index 5e49e4909..4301e1733 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -39,7 +39,7 @@ struct cWSSCompact::sChunkHeader /// The maximum number of PAK files that are cached -const int MAX_PAK_FILES = 16; +const int MAX_PAK_FILES = 16U; /// The maximum number of unsaved chunks before the cPAKFile saves them to disk const int MAX_DIRTY_CHUNKS = 16; -- cgit v1.2.3 From e73caf30f09248a7e428a937226e0383e69ff6ce Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 09:33:40 -0700 Subject: Fix gcc error attempt 2 --- src/WorldStorage/WSSCompact.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index 4301e1733..885099713 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -39,7 +39,7 @@ struct cWSSCompact::sChunkHeader /// The maximum number of PAK files that are cached -const int MAX_PAK_FILES = 16U; +const int MAX_PAK_FILES = static_cast(16); /// The maximum number of unsaved chunks before the cPAKFile saves them to disk const int MAX_DIRTY_CHUNKS = 16; -- cgit v1.2.3 From ebf163b77a030553c616d19179a9cd0f6de787a6 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 09:45:59 -0700 Subject: Unsigned types take 3 --- src/WorldStorage/WSSCompact.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index 885099713..663260aaa 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -39,7 +39,7 @@ struct cWSSCompact::sChunkHeader /// The maximum number of PAK files that are cached -const int MAX_PAK_FILES = static_cast(16); +const int MAX_PAK_FILES = static_cast(16); /// The maximum number of unsaved chunks before the cPAKFile saves them to disk const int MAX_DIRTY_CHUNKS = 16; -- cgit v1.2.3 From b8cd0b0897f42f0d294203cec68729f43ecb711d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 9 Mar 2014 17:48:17 +0100 Subject: Hotfix for MSVC compilation. --- src/Protocol/Protocol125.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 66f3227b0..aca24c03a 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -11,6 +11,7 @@ #include "Protocol.h" #include "../ByteBuffer.h" +#include "../Entities/Painting.h" -- cgit v1.2.3 From 167ef3b7a1a1ec23330552decfc7d005ccfc8caa Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 09:52:49 -0700 Subject: Take 4 --- src/WorldStorage/WSSCompact.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index 663260aaa..6e39b44cc 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -39,7 +39,7 @@ struct cWSSCompact::sChunkHeader /// The maximum number of PAK files that are cached -const int MAX_PAK_FILES = static_cast(16); +const int MAX_PAK_FILES = static_cast(16); /// The maximum number of unsaved chunks before the cPAKFile saves them to disk const int MAX_DIRTY_CHUNKS = 16; -- cgit v1.2.3 From 5c4c147e487e9dc08cfacd156b1f60a485460b75 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 9 Mar 2014 17:58:01 +0100 Subject: Silenced useless MSVC warnings in cMetaRotater. --- src/Blocks/MetaRotater.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Blocks/MetaRotater.h b/src/Blocks/MetaRotater.h index d3664b6f1..dde88e6db 100644 --- a/src/Blocks/MetaRotater.h +++ b/src/Blocks/MetaRotater.h @@ -4,6 +4,15 @@ #pragma once +// MSVC generates warnings for the templated AssertIfNotMatched parameter conditions, so disable it: +#ifdef _MSC_VER + #pragma warning(disable: 4127) // Conditional expression is constant +#endif + + + + + /* Provides a mixin for rotations and reflections following the standard pattern of apply mask then use case. @@ -29,6 +38,9 @@ public: }; + + + template NIBBLETYPE cMetaRotater::MetaRotateCW(NIBBLETYPE a_Meta) { @@ -49,6 +61,8 @@ NIBBLETYPE cMetaRotater NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) { @@ -69,6 +83,8 @@ NIBBLETYPE cMetaRotater NIBBLETYPE cMetaRotater::MetaMirrorXY(NIBBLETYPE a_Meta) { @@ -85,6 +101,7 @@ NIBBLETYPE cMetaRotater NIBBLETYPE cMetaRotater::MetaMirrorYZ(NIBBLETYPE a_Meta) { @@ -97,3 +114,7 @@ NIBBLETYPE cMetaRotater Date: Sun, 9 Mar 2014 10:04:07 -0700 Subject: Take 5 --- src/WorldStorage/WSSCompact.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index 6e39b44cc..18d4452d9 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -39,7 +39,7 @@ struct cWSSCompact::sChunkHeader /// The maximum number of PAK files that are cached -const int MAX_PAK_FILES = static_cast(16); +const int MAX_PAK_FILES = static_cast(16); /// The maximum number of unsaved chunks before the cPAKFile saves them to disk const int MAX_DIRTY_CHUNKS = 16; -- cgit v1.2.3 From 430aba9f1dc5db8c3d1ec9f9552bb41f8a0b21b0 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 10:10:36 -0700 Subject: Its a const not a macro --- src/WorldStorage/WSSCompact.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index 18d4452d9..95477838e 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -39,7 +39,7 @@ struct cWSSCompact::sChunkHeader /// The maximum number of PAK files that are cached -const int MAX_PAK_FILES = static_cast(16); +const size_t MAX_PAK_FILES = 16; /// The maximum number of unsaved chunks before the cPAKFile saves them to disk const int MAX_DIRTY_CHUNKS = 16; -- cgit v1.2.3 From 676dcfd1c74a36882b5b9bb75749e3bd86b75d9e Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 10:32:56 -0700 Subject: Globals.h is now warnings free again. Also turned off Wpadded as it is indicates potental performance issues rather than potential bugs --- SetFlags.cmake | 2 +- src/ChunkDef.h | 32 ++++++++++++++++++++++++-------- src/Globals.h | 2 -- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index ec2f6c556..82472f333 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -192,7 +192,7 @@ macro(set_exe_flags) add_flags_cxx("-D__extern_always_inline=inline") add_flags_cxx("-Weverything -Wno-c++98-compat-pedantic -Wno-string-conversion") add_flags_cxx("-Wno-extra-semi -Wno-error=switch-enum -Wno-documentation") - add_flags_cxx("-Wno-error=sign-conversion -Wno-error=conversion -Wno-error=padded") + add_flags_cxx("-Wno-error=sign-conversion -Wno-error=conversion -Wno-padded") add_flags_cxx("-Wno-error=deprecated -Wno-error=weak-vtables -Wno-error=float-equal") add_flags_cxx("-Wno-error=missing-prototypes -Wno-error=non-virtual-dtor") add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 63431f211..a5059348c 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -124,7 +124,9 @@ public: (z < Width) && (z > -1) ) { - return MakeIndexNoCheck(x, y, z); + return MakeIndexNoCheck(static_cast(x), + static_cast(y), + static_cast(z)); } LOGERROR("cChunkDef::MakeIndex(): coords out of range: {%d, %d, %d}; returning fake index 0", x, y, z); ASSERT(!"cChunkDef::MakeIndex(): coords out of chunk range!"); @@ -166,7 +168,9 @@ public: ASSERT((a_X >= 0) && (a_X < Width)); ASSERT((a_Y >= 0) && (a_Y < Height)); ASSERT((a_Z >= 0) && (a_Z < Width)); - a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)] = a_Type; + a_BlockTypes[MakeIndexNoCheck(static_cast(a_X), + static_cast(a_Y), + static_cast(a_Z))] = a_Type; } @@ -182,7 +186,9 @@ public: ASSERT((a_X >= 0) && (a_X < Width)); ASSERT((a_Y >= 0) && (a_Y < Height)); ASSERT((a_Z >= 0) && (a_Z < Width)); - return a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)]; + return a_BlockTypes[MakeIndexNoCheck(static_cast(a_X), + static_cast(a_Y), + static_cast(a_Z))]; } @@ -240,7 +246,9 @@ public: { if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1)) { - unsigned int Index = MakeIndexNoCheck(x, y, z); + unsigned int Index = MakeIndexNoCheck(static_cast(x), + static_cast(y), + static_cast(z)); return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f; } ASSERT(!"cChunkDef::GetNibble(): coords out of chunk range!"); @@ -255,8 +263,8 @@ public: ASSERT(!"cChunkDef::SetNibble(): index out of range!"); return; } - a_Buffer[a_BlockIdx / 2] = ( - (a_Buffer[a_BlockIdx / 2] & (0xf0 >> (static_cast(a_BlockIdx & 1) * 4))) | // The untouched nibble + a_Buffer[a_BlockIdx / 2] = static_cast( + (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set ); } @@ -274,8 +282,10 @@ public: return; } - int Index = MakeIndexNoCheck(x, y, z); - a_Buffer[Index / 2] = ( + unsigned int Index = MakeIndexNoCheck(static_cast(x), + static_cast(y), + static_cast(z)); + a_Buffer[Index / 2] = static_cast( (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set ); @@ -435,6 +445,9 @@ Used primarily for entity moving while both chunks are locked. class cClientDiffCallback { public: + + virtual ~cClientDiffCallback() {} + /// Called for clients that are in Chunk1 and not in Chunk2, virtual void Removed(cClientHandle * a_Client) = 0; @@ -495,6 +508,9 @@ typedef std::vector cChunkCoordsVector; class cChunkCoordCallback { public: + + virtual ~cChunkCoordCallback() {} + virtual void Call(int a_ChunkX, int a_ChunkZ) = 0; } ; diff --git a/src/Globals.h b/src/Globals.h index 28805a83f..98611fc55 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -254,5 +254,3 @@ T Clamp(T a_Value, T a_Min, T a_Max) #include "Entities/Effects.h" - - -- cgit v1.2.3 From 713c59b60b6a096554eda7fabc7696b33a6fcb59 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 10:41:53 -0700 Subject: Treat enum missmatches as warnings for now as there is such a large number of them. --- SetFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 82472f333..e71bf315d 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -182,7 +182,7 @@ macro(set_exe_flags) string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") - add_flags_cxx("-Wall -Wextra -Werror -Wno-unused-parameter -Wno-error=switch") + add_flags_cxx("-Wall -Wextra -Werror -Wno-unused-parameter -Wno-error=switch -Wno-error=enum-compare") # we support non-IEEE 754 fpus so can make no guarentees about error add_flags_cxx("-ffast-math") -- cgit v1.2.3 From 617ad0b5f8e8d469ec017a0e83754f7401f64d00 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 10:46:39 -0700 Subject: Only enable -Werror in gcc because gcc doesn't let you suppress enum missmatch warnings --- SetFlags.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index e71bf315d..a9657fff1 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -182,7 +182,7 @@ macro(set_exe_flags) string(REPLACE "-w" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") string(REPLACE "-w" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") string(REPLACE "-w" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") - add_flags_cxx("-Wall -Wextra -Werror -Wno-unused-parameter -Wno-error=switch -Wno-error=enum-compare") + add_flags_cxx("-Wall -Wextra -Wno-unused-parameter -Wno-error=switch") # we support non-IEEE 754 fpus so can make no guarentees about error add_flags_cxx("-ffast-math") @@ -190,7 +190,7 @@ macro(set_exe_flags) # clang does not provide the __extern_always_inline macro and a part of libm depends on this when using fast-math if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_flags_cxx("-D__extern_always_inline=inline") - add_flags_cxx("-Weverything -Wno-c++98-compat-pedantic -Wno-string-conversion") + add_flags_cxx("-Werror -Weverything -Wno-c++98-compat-pedantic -Wno-string-conversion") add_flags_cxx("-Wno-extra-semi -Wno-error=switch-enum -Wno-documentation") add_flags_cxx("-Wno-error=sign-conversion -Wno-error=conversion -Wno-padded") add_flags_cxx("-Wno-error=deprecated -Wno-error=weak-vtables -Wno-error=float-equal") -- cgit v1.2.3 From 3aff0b44bcb751606339de6498713b3ef2ce0e33 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 9 Mar 2014 17:51:02 +0000 Subject: Fixed #778 - stack overflow.com --- src/Entities/Floater.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/Floater.h b/src/Entities/Floater.h index 865d6dc50..f3b51d77b 100644 --- a/src/Entities/Floater.h +++ b/src/Entities/Floater.h @@ -11,7 +11,7 @@ class cFloater : public cEntity { - typedef cFloater super; + typedef cEntity super; public: //tolua_end -- cgit v1.2.3 From e5fc3c63f2ab4bcc8d225f746afd07d01ad9d08c Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 10:52:12 -0700 Subject: Fix IsThread destructor --- src/OSSupport/IsThread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h index b8784ea33..42b8bfdda 100644 --- a/src/OSSupport/IsThread.h +++ b/src/OSSupport/IsThread.h @@ -34,7 +34,7 @@ protected: public: cIsThread(const AString & iThreadName); - ~cIsThread(); + virtual ~cIsThread(); /// Starts the thread; returns without waiting for the actual start bool Start(void); -- cgit v1.2.3 From 9825dbfd34c65580d795065d1a82e7697b9c5cbd Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 11:21:42 -0700 Subject: Fixed Mesannine twister to use UInt32 --- MCServer/Plugins/Core | 2 +- src/ByteBuffer.h | 2 +- src/Defines.h | 2 +- src/Map.h | 2 +- src/MersenneTwister.h | 4 +++- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 013a32a7f..3b416b07a 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 013a32a7fb3c8a6cfe0aef892d4c7394d4e1be59 +Subproject commit 3b416b07a339b3abcbc127070d56eea05b05373d diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index ed2e10a55..1915467f3 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -43,7 +43,7 @@ public: size_t GetReadableSpace(void) const; /// Returns the current data start index. For debugging purposes. - int GetDataStart(void) const { return m_DataStart; } + size_t GetDataStart(void) const { return m_DataStart; } /// Returns true if the specified amount of bytes are available for reading bool CanReadBytes(size_t a_Count) const; diff --git a/src/Defines.h b/src/Defines.h index 6ab2274a4..fd240c91a 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -469,7 +469,7 @@ inline void EulerToVector(double a_Pan, double a_Pitch, double & a_X, double & a inline void VectorToEuler(double a_X, double a_Y, double a_Z, double & a_Pan, double & a_Pitch) { - if (a_X != 0) + if (fabs(a_X) < std::numeric_limits::epsilon() ) { a_Pan = atan2(a_Z, a_X) * 180 / PI - 90; } diff --git a/src/Map.h b/src/Map.h index a313d5431..ee7c537b1 100644 --- a/src/Map.h +++ b/src/Map.h @@ -64,7 +64,7 @@ public: unsigned int GetPixelX(void) const { return m_PixelX; } unsigned int GetPixelZ(void) const { return m_PixelZ; } - int GetRot(void) const { return m_Rot; } + unsigned int GetRot(void) const { return m_Rot; } eType GetType(void) const { return m_Type; } diff --git a/src/MersenneTwister.h b/src/MersenneTwister.h index f4c7b0699..07b6b1e5c 100644 --- a/src/MersenneTwister.h +++ b/src/MersenneTwister.h @@ -59,10 +59,12 @@ #include #include +#include "Globals.h" + class MTRand { // Data public: - typedef long uint32; // unsigned integer type, at least 32 bits + typedef UInt32 uint32; // unsigned integer type, at least 32 bits enum { N = 624 }; // length of state vector enum { SAVE = N + 1 }; // length of array for save() -- cgit v1.2.3 From 1fdeabcf78394d197a7ab5e0f9edca07abdedd0e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 9 Mar 2014 19:30:38 +0100 Subject: cPieceGenerator: New connectors are added to the free pool. --- src/Generating/PieceGenerator.cpp | 32 ++++++++++++++++++++++++++------ src/Generating/PieceGenerator.h | 7 ++++--- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index 58ccaf2c2..c8e4ec71b 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -361,7 +361,12 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, i -bool cPieceGenerator::TryPlacePieceAtConnector(const cPlacedPiece & a_ParentPiece, const cPiece::cConnector & a_Connector, cPlacedPieces & a_OutPieces) +bool cPieceGenerator::TryPlacePieceAtConnector( + const cPlacedPiece & a_ParentPiece, + const cPiece::cConnector & a_Connector, + cPlacedPieces & a_OutPieces, + cPieceGenerator::cFreeConnectors & a_OutConnectors +) { // Translation of direction - direction -> number of CCW rotations needed: // You need DirectionRotationTable[rot1][rot2] CCW turns to connect rot1 to rot2 (they are opposite) @@ -429,10 +434,24 @@ bool cPieceGenerator::TryPlacePieceAtConnector(const cPlacedPiece & a_ParentPiec ); Vector3i NewPos = Conn.m_Piece->RotatePos(Conn.m_Connector.m_Pos, Conn.m_NumCCWRotations); ConnPos -= NewPos; - a_OutPieces.push_back(new cPlacedPiece(&a_ParentPiece, *(Conn.m_Piece), ConnPos, Conn.m_NumCCWRotations)); + cPlacedPiece * PlacedPiece = new cPlacedPiece(&a_ParentPiece, *(Conn.m_Piece), ConnPos, Conn.m_NumCCWRotations); + a_OutPieces.push_back(PlacedPiece); // Add the new piece's connectors to the list of free connectors: - // TODO + cPiece::cConnectors Connectors = Conn.m_Piece->GetConnectors(); + + // DEBUG: + printf("Adding %u connectors to the pool\n", Connectors.size() - 1); + + for (cPiece::cConnectors::const_iterator itr = Connectors.begin(), end = Connectors.end(); itr != end; ++itr) + { + if (itr->m_Pos.Equals(Conn.m_Connector.m_Pos)) + { + // This is the connector through which we have been connected to the parent, don't add + continue; + } + a_OutConnectors.push_back(cFreeConnector(PlacedPiece, Conn.m_Piece->RotateMoveConnector(*itr, Conn.m_NumCCWRotations, ConnPos.x, ConnPos.y, ConnPos.z))); + } return true; } @@ -473,11 +492,12 @@ void cPieceGenerator::DebugConnectorPool(const cPieceGenerator::cFreeConnectors size_t idx = 0; for (cPieceGenerator::cFreeConnectors::const_iterator itr = a_ConnectorPool.begin() + a_NumProcessed, end = a_ConnectorPool.end(); itr != end; ++itr, ++idx) { - printf(" %u: {%d, %d, %d}, type %d, direction %s\n", + printf(" %u: {%d, %d, %d}, type %d, direction %s, depth %d\n", idx, itr->m_Connector.m_Pos.x, itr->m_Connector.m_Pos.y, itr->m_Connector.m_Pos.z, itr->m_Connector.m_Type, - BlockFaceToString(itr->m_Connector.m_Direction).c_str() + BlockFaceToString(itr->m_Connector.m_Direction).c_str(), + itr->m_Piece->GetDepth() ); } // for itr - a_ConnectorPool[] } @@ -556,7 +576,7 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, i cFreeConnector & Conn = ConnectorPool[NumProcessed]; if (Conn.m_Piece->GetDepth() < a_MaxDepth) { - if (TryPlacePieceAtConnector(*Conn.m_Piece, Conn.m_Connector, a_OutPieces)) + if (TryPlacePieceAtConnector(*Conn.m_Piece, Conn.m_Connector, a_OutPieces, ConnectorPool)) { const cPlacedPiece * NewPiece = a_OutPieces.back(); const Vector3i & Coords = NewPiece->GetCoords(); diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 0e24510ae..310c21fdd 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -176,9 +176,10 @@ protected: /** Tries to place a new piece at the specified (placed) connector. Returns true if successful. */ bool TryPlacePieceAtConnector( - const cPlacedPiece & a_ParentPiece, - const cPiece::cConnector & a_Connector, - cPlacedPieces & a_OutPieces + const cPlacedPiece & a_ParentPiece, // The existing piece to a new piece should be placed + const cPiece::cConnector & a_Connector, // The existing connector (world-coords) to which a new piece should be placed + cPlacedPieces & a_OutPieces, // Already placed pieces, to be checked for intersections + cFreeConnectors & a_OutConnectors // List of free connectors to which the new connectors will be placed ); /** Checks if the specified piece would fit with the already-placed pieces, using the specified connector -- cgit v1.2.3 From 1bf99b5fd26d142106d7a097900ebfe8a6279ad4 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 11:47:22 -0700 Subject: Be more parinoid about int sizes --- src/Defines.h | 3 ++- src/Globals.h | 18 ++++++++++++++++-- src/MersenneTwister.h | 2 -- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Defines.h b/src/Defines.h index fd240c91a..592b9434a 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -2,6 +2,7 @@ #pragma once #include "ChatColor.h" +#include @@ -469,7 +470,7 @@ inline void EulerToVector(double a_Pan, double a_Pitch, double & a_X, double & a inline void VectorToEuler(double a_X, double a_Y, double a_Z, double & a_Pan, double & a_Pitch) { - if (fabs(a_X) < std::numeric_limits::epsilon() ) + if (fabs(a_X) < std::numeric_limits::epsilon()) { a_Pan = atan2(a_Z, a_X) * 180 / PI - 90; } diff --git a/src/Globals.h b/src/Globals.h index 98611fc55..b046e6db0 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -81,7 +81,7 @@ #endif - +#include // Integral types with predefined sizes: @@ -96,8 +96,22 @@ typedef unsigned short UInt16; typedef unsigned char Byte; +// If you get an error about specialization check the size of integral types +template +class SizeChecker; + +template +class SizeChecker { + T v; +}; +template class SizeChecker; +template class SizeChecker; +template class SizeChecker; +template class SizeChecker; +template class SizeChecker; +template class SizeChecker; // A macro to disallow the copy constructor and operator= functions // This should be used in the private: declarations for any class that shouldn't allow copying itself @@ -179,7 +193,7 @@ typedef unsigned char Byte; #include #include #include - +#include diff --git a/src/MersenneTwister.h b/src/MersenneTwister.h index 07b6b1e5c..2c5440f17 100644 --- a/src/MersenneTwister.h +++ b/src/MersenneTwister.h @@ -59,8 +59,6 @@ #include #include -#include "Globals.h" - class MTRand { // Data public: -- cgit v1.2.3 From 8889d3b73347a7cc094a0e233479e96f2bc25a49 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 9 Mar 2014 19:54:27 +0100 Subject: Added cCuboid::Engulf(). --- src/Cuboid.cpp | 34 ++++++++++++++++++++++++++++++++++ src/Cuboid.h | 3 +++ 2 files changed, 37 insertions(+) diff --git a/src/Cuboid.cpp b/src/Cuboid.cpp index 782837b23..dc8df8500 100644 --- a/src/Cuboid.cpp +++ b/src/Cuboid.cpp @@ -197,3 +197,37 @@ bool cCuboid::IsSorted(void) const + +void cCuboid::Engulf(const Vector3i & a_Point) +{ + if (a_Point.x < p1.x) + { + p1.x = a_Point.x; + } + else if (a_Point.x > p2.x) + { + p2.x = a_Point.x; + } + + if (a_Point.y < p1.y) + { + p1.y = a_Point.y; + } + else if (a_Point.y > p2.y) + { + p2.y = a_Point.y; + } + + if (a_Point.z < p1.z) + { + p1.z = a_Point.z; + } + else if (a_Point.z > p2.z) + { + p2.z = a_Point.z; + } +} + + + + diff --git a/src/Cuboid.h b/src/Cuboid.h index 51ccf799b..50a69b853 100644 --- a/src/Cuboid.h +++ b/src/Cuboid.h @@ -86,6 +86,9 @@ public: /** Returns true if the coords are properly sorted (lesser in p1, greater in p2) */ bool IsSorted(void) const; + + /** If needed, expands the cuboid so that it contains the specified point. Assumes sorted. Doesn't contract. */ + void Engulf(const Vector3i & a_Point); } ; // tolua_end -- cgit v1.2.3 From 2eaae82a2a6f22b684ea153267c8f06f18145753 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 9 Mar 2014 18:57:43 +0000 Subject: Mentiod that we use some c++11 exstensions Eg override, abstract, va_copy, long long. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7ec7058ae..0c36be8b7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ Code Stuff ---------- - * We use C++03 + * We use C++03 with some C++11 extensions (ask if you think that something would be useful) * Use the provided wrappers for OS stuff: - Threading is done by inheriting from `cIsThread`, thread synchronization through `cCriticalSection`, `cSemaphore` and `cEvent`, file access and filesystem operations through the `cFile` class, high-precision timers through `cTimer`, high-precision sleep through `cSleep` * No magic numbers, use named constants: -- cgit v1.2.3 From 81bf846e648bf757a67699c57f2a9e66f6850416 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 9 Mar 2014 21:58:12 +0100 Subject: ChunkDef: Replaced enums with static const ints. This makes them easier to use in std::min et al. --- src/ChunkDef.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 7be2fa2df..7876c58e7 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -62,16 +62,12 @@ typedef unsigned char HEIGHTTYPE; class cChunkDef { public: - enum - { - // Chunk dimensions: - Width = 16, - Height = 256, - NumBlocks = Width * Height * Width, - - /// If the data is collected into a single buffer, how large it needs to be: - BlockDataSize = cChunkDef::NumBlocks * 2 + (cChunkDef::NumBlocks / 2), // 2.5 * numblocks - } ; + // Chunk dimensions: + static const int Width = 16; + static const int Height = 256; + static const int NumBlocks = Width * Height * Width; + /// If the data is collected into a single buffer, how large it needs to be: + static const int BlockDataSize = cChunkDef::NumBlocks * 2 + (cChunkDef::NumBlocks / 2); // 2.5 * numblocks /// The type used for any heightmap operations and storage; idx = x + Width * z; Height points to the highest non-air block in the column typedef HEIGHTTYPE HeightMap[Width * Width]; -- cgit v1.2.3 From dacb6cef1d6d2942f01d15186d8a12b30d39a385 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 9 Mar 2014 22:02:08 +0100 Subject: Hardened cCuboid with asserts for its assumptions. --- src/Cuboid.cpp | 6 ++++++ src/Cuboid.h | 8 +++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Cuboid.cpp b/src/Cuboid.cpp index dc8df8500..2400c64f3 100644 --- a/src/Cuboid.cpp +++ b/src/Cuboid.cpp @@ -72,6 +72,9 @@ int cCuboid::GetVolume(void) const bool cCuboid::DoesIntersect(const cCuboid & a_Other) const { + ASSERT(IsSorted()); + ASSERT(a_Other.IsSorted()); + // In order for cuboids to intersect, each of their coord intervals need to intersect return ( DoIntervalsIntersect(p1.x, p2.x, a_Other.p1.x, a_Other.p2.x) && @@ -86,6 +89,9 @@ bool cCuboid::DoesIntersect(const cCuboid & a_Other) const bool cCuboid::IsCompletelyInside(const cCuboid & a_Outer) const { + ASSERT(IsSorted()); + ASSERT(a_Outer.IsSorted()); + return ( (p1.x >= a_Outer.p1.x) && (p2.x <= a_Outer.p2.x) && diff --git a/src/Cuboid.h b/src/Cuboid.h index 50a69b853..b95517f69 100644 --- a/src/Cuboid.h +++ b/src/Cuboid.h @@ -34,7 +34,8 @@ public: Works on unsorted cuboids, too. */ int GetVolume(void) const; - /** Returns true if the cuboids have at least one voxel in common. Both coords are considered inclusive. */ + /** Returns true if the cuboids have at least one voxel in common. Both coords are considered inclusive. + Assumes both cuboids are sorted. */ bool DoesIntersect(const cCuboid & a_Other) const; bool IsInside(const Vector3i & v) const @@ -64,7 +65,8 @@ public: ); } - /** Returns true if this cuboid is completely inside the specifie cuboid (in all 6 coords) */ + /** Returns true if this cuboid is completely inside the specifie cuboid (in all 6 coords). + Assumes both cuboids are sorted. */ bool IsCompletelyInside(const cCuboid & a_Outer) const; /** Moves the cuboid by the specified offsets in each direction */ @@ -72,7 +74,7 @@ public: /** Expands the cuboid by the specified amount in each direction. Works on unsorted cuboids as well. - Note that this function doesn't check for underflows. */ + Note that this function doesn't check for underflows when using negative amounts. */ void Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ); /** Clamps both X coords to the specified range. Works on unsorted cuboids, too. */ -- cgit v1.2.3 From 0e985293b50ec89a163f40222825b3c147135b9a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 9 Mar 2014 22:04:29 +0100 Subject: A working POCPiece generator. --- src/Generating/ComposableGenerator.cpp | 5 + src/Generating/POCPieceGenerator.cpp | 265 +++++++++++++++++++++++++++++++++ src/Generating/POCPieceGenerator.h | 54 +++++++ src/Generating/PieceGenerator.cpp | 31 +++- src/Generating/PieceGenerator.h | 10 +- 5 files changed, 359 insertions(+), 6 deletions(-) create mode 100644 src/Generating/POCPieceGenerator.cpp create mode 100644 src/Generating/POCPieceGenerator.h diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index e96e9a645..6c00b5905 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -22,6 +22,7 @@ #include "EndGen.h" #include "MineShafts.h" #include "Noise3DGenerator.h" +#include "POCPieceGenerator.h" #include "Ravines.h" @@ -364,6 +365,10 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { m_FinishGens.push_back(new cStructGenOreNests(Seed)); } + else if (NoCaseCompare(*itr, "POCPieces") == 0) + { + m_FinishGens.push_back(new cPOCPieceGenerator(Seed)); + } else if (NoCaseCompare(*itr, "PreSimulator") == 0) { m_FinishGens.push_back(new cFinishGenPreSimulator); diff --git a/src/Generating/POCPieceGenerator.cpp b/src/Generating/POCPieceGenerator.cpp new file mode 100644 index 000000000..9edfcc64f --- /dev/null +++ b/src/Generating/POCPieceGenerator.cpp @@ -0,0 +1,265 @@ + +// POCPieceGenerator.cpp + +// Implements the cPOCPieceGenerator class representing a Proof-Of_Concept structure generator using the cPieceGenerator technique +// The generator generates a maze of rooms at {0, 100, 0} + +#include "Globals.h" +#include "POCPieceGenerator.h" +#include "ChunkDesc.h" + + + + + +/** POC pieces are simple boxes that have connectors in the middle of their walls. +Each wall has one connector, there are 3 connector types that get assigned semi-randomly. +The piece also knows how to imprint itself in a cChunkDesc, each piece has a different color glass +and each connector is uses a different color wool frame. */ +class cPOCPiece : + public cPiece +{ +public: + cPOCPiece(int a_Size) : + m_Size(a_Size) + { + m_Connectors.push_back(cConnector(m_Size / 2, 1, 0, 0, BLOCK_FACE_ZM)); + m_Connectors.push_back(cConnector(m_Size / 2, 1, m_Size - 1, 1, BLOCK_FACE_ZP)); + m_Connectors.push_back(cConnector(0, 1, m_Size / 2, 2, BLOCK_FACE_XM)); + m_Connectors.push_back(cConnector(m_Size - 1, 1, m_Size / 2, m_Size % 3, BLOCK_FACE_XP)); + } + + + /** Imprints the piece in the specified chunk. Assumes they intersect. */ + void ImprintInChunk(cChunkDesc & a_ChunkDesc, const Vector3i & a_Pos, int a_NumCCWRotations) + { + int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; + int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; + Vector3i Min = a_Pos; + Min.Move(-BlockX, 0, -BlockZ); + Vector3i Max = Min; + Max.Move(m_Size - 1, 2, m_Size - 1); + ASSERT(Min.x < cChunkDef::Width); + ASSERT(Min.z < cChunkDef::Width); + ASSERT(Max.x >= 0); + ASSERT(Max.z >= 0); + if (Min.x >= 0) + { + // Draw the XM wall: + a_ChunkDesc.FillRelCuboid(Min.x, Min.x, Min.y, Max.y, Min.z, Max.z, E_BLOCK_STAINED_GLASS, m_Size % 16); + } + if (Min.z >= 0) + { + // Draw the ZM wall: + a_ChunkDesc.FillRelCuboid(Min.x, Max.x, Min.y, Max.y, Min.z, Min.z, E_BLOCK_STAINED_GLASS, m_Size % 16); + } + if (Max.x < cChunkDef::Width) + { + // Draw the XP wall: + a_ChunkDesc.FillRelCuboid(Max.x, Max.x, Min.y, Max.y, Min.z, Max.z, E_BLOCK_STAINED_GLASS, m_Size % 16); + } + if (Max.z < cChunkDef::Width) + { + // Draw the ZP wall: + a_ChunkDesc.FillRelCuboid(Min.x, Max.x, Min.y, Max.y, Max.z, Max.z, E_BLOCK_STAINED_GLASS, m_Size % 16); + } + + // Draw all the connectors: + for (cConnectors::const_iterator itr = m_Connectors.begin(), end = m_Connectors.end(); itr != end; ++itr) + { + cConnector Conn = cPiece::RotateMoveConnector(*itr, a_NumCCWRotations, a_Pos.x, a_Pos.y, a_Pos.z); + Conn.m_Pos.Move(-BlockX, 0, -BlockZ); + if ( + (Conn.m_Pos.x >= 0) && (Conn.m_Pos.x < cChunkDef::Width) && + (Conn.m_Pos.z >= 0) && (Conn.m_Pos.z < cChunkDef::Width) + ) + { + a_ChunkDesc.SetBlockTypeMeta(Conn.m_Pos.x, Conn.m_Pos.y, Conn.m_Pos.z, E_BLOCK_WOOL, itr->m_Type % 16); + } + + /* + // TODO: Frame the connectors + switch (itr->m_Direction) + { + case BLOCK_FACE_XM: + case BLOCK_FACE_XP: + { + // TODO + break; + } + + case BLOCK_FACE_ZM: + case BLOCK_FACE_ZP: + { + // TODO + break; + } + } + */ + } // for itr - m_Connectors[] + } + +protected: + int m_Size; + cConnectors m_Connectors; + + // cPiece overrides: + virtual cConnectors GetConnectors(void) const override + { + return m_Connectors; + } + + virtual Vector3i GetSize(void) const override + { + return Vector3i(m_Size, 3, m_Size); + } + + virtual cCuboid GetHitBox(void) const override + { + return cCuboid(0, 0, 0, m_Size - 1, 2, m_Size - 1); + } + + virtual bool CanRotateCCW(int a_NumRotations) const override + { + return true; + } +}; + + + + + +static void DebugPieces(const cPlacedPieces & a_Pieces) +{ + size_t idx = 0; + for (cPlacedPieces::const_iterator itr = a_Pieces.begin(), end = a_Pieces.end(); itr != end; ++itr, ++idx) + { + const cCuboid & HitBox = (*itr)->GetHitBox(); + printf(" %u: %d rotations, {%d - %d, %d - %d}\n", + idx, (*itr)->GetNumCCWRotations(), + HitBox.p1.x, HitBox.p2.x, HitBox.p1.z, HitBox.p2.z + ); + } // for itr - a_Pieces[] +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cPOCPieceGenerator: + +cPOCPieceGenerator::cPOCPieceGenerator(int a_Seed) : + m_Seed(a_Seed) +{ + // Prepare a vector of available pieces: + m_AvailPieces.push_back(new cPOCPiece(5)); + m_AvailPieces.push_back(new cPOCPiece(7)); + m_AvailPieces.push_back(new cPOCPiece(9)); + + // Generate the structure: + cBFSPieceGenerator Gen(*this, a_Seed); + Gen.PlacePieces(0, 50, 0, 6, m_Pieces); + + // DebugPieces(m_Pieces); + + // Get the smallest cuboid encompassing the entire generated structure: + cCuboid Bounds(0, 50, 0, 0, 50, 0); + for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr) + { + Vector3i MinCoords = (*itr)->GetCoords(); + Bounds.Engulf(MinCoords); + Bounds.Engulf(MinCoords + (*itr)->GetPiece().GetSize()); + } // for itr - m_Pieces[] + m_Bounds = Bounds; +} + + + + + +cPOCPieceGenerator::~cPOCPieceGenerator() +{ + cPieceGenerator::FreePieces(m_Pieces); +} + + + + + +void cPOCPieceGenerator::GenFinish(cChunkDesc & a_ChunkDesc) +{ + int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; + int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; + if ( + (BlockX + 16 < m_Bounds.p1.x) || (BlockX > m_Bounds.p2.x) || // X coords out of bounds of the generated structure + (BlockZ + 16 < m_Bounds.p1.z) || (BlockZ > m_Bounds.p2.z) // Z coords out of bounds of the generated structure + ) + { + return; + } + + // Imprint each piece in the chunk: + for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr) + { + const Vector3i & Pos = (*itr)->GetCoords(); + Vector3i Size = (*itr)->GetPiece().GetSize(); + if (((*itr)->GetNumCCWRotations() % 2) == 1) + { + std::swap(Size.x, Size.z); + } + if ( + (Pos.x >= BlockX + 16) || (Pos.x + Size.x - 1 < BlockX) || + (Pos.z >= BlockZ + 16) || (Pos.z + Size.z - 1 < BlockZ) + ) + { + // This piece doesn't intersect the chunk + continue; + } + + ((cPOCPiece &)(*itr)->GetPiece()).ImprintInChunk(a_ChunkDesc, Pos, (*itr)->GetNumCCWRotations()); + } // for itr - m_Pieces[] + a_ChunkDesc.UpdateHeightmap(); +} + + + + + +cPieces cPOCPieceGenerator::GetPiecesWithConnector(int a_ConnectorType) +{ + // Each piece has each connector + return m_AvailPieces; +} + + + + + +cPieces cPOCPieceGenerator::GetStartingPieces(void) +{ + // Any piece can be a starting piece + return m_AvailPieces; +} + + + + + +void cPOCPieceGenerator::PiecePlaced(const cPiece & a_Piece) +{ + UNUSED(a_Piece); +} + + + + + +void cPOCPieceGenerator::Reset(void) +{ + // Nothing needed +} + + + + diff --git a/src/Generating/POCPieceGenerator.h b/src/Generating/POCPieceGenerator.h new file mode 100644 index 000000000..de3114ce0 --- /dev/null +++ b/src/Generating/POCPieceGenerator.h @@ -0,0 +1,54 @@ + +// POCPieceGenerator.h + +// Declares the cPOCPieceGenerator class representing a Proof-Of_Concept structure generator using the cPieceGenerator technique +// The generator generates a maze of rooms at {0, 100, 0} + + + + + +#pragma once + +#include "PieceGenerator.h" +#include "ComposableGenerator.h" + + + + + +class cPOCPieceGenerator : + public cFinishGen, + protected cPiecePool +{ +public: + cPOCPieceGenerator(int a_Seed); + ~cPOCPieceGenerator(); + +protected: + int m_Seed; + + /** The pieces from which the generated structure is built. */ + cPieces m_AvailPieces; + + /** The placed pieces of the generated structure. */ + cPlacedPieces m_Pieces; + + /** Bounds of the complete structure, to save on processing outside chunks. */ + cCuboid m_Bounds; + + + // cFinishGen overrides: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; + + // cPiecePool overrides: + virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override; + virtual cPieces GetStartingPieces(void) override; + virtual void PiecePlaced(const cPiece & a_Piece) override; + virtual void Reset(void) override; +} ; + + + + + diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index c8e4ec71b..e3de5b951 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -11,6 +11,8 @@ +#ifdef SELF_TEST + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Self-test: @@ -132,6 +134,8 @@ protected: } } g_Test; +#endif // SELF_TEST + @@ -287,6 +291,7 @@ cPlacedPiece::cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece { m_Depth = (m_Parent == NULL) ? 0 : (m_Parent->GetDepth() + 1); m_HitBox = a_Piece.RotateMoveHitBox(a_NumCCWRotations, a_Coords.x, a_Coords.y, a_Coords.z); + m_HitBox.Sort(); } @@ -375,10 +380,10 @@ bool cPieceGenerator::TryPlacePieceAtConnector( /* YM, YP, ZM, ZP, XM, XP /* YM */ { 0, 0, 0, 0, 0, 0}, /* YP */ { 0, 0, 0, 0, 0, 0}, - /* ZM */ { 0, 0, 0, 2, 1, 3}, - /* ZP */ { 0, 0, 2, 0, 3, 1}, - /* XM */ { 0, 0, 3, 1, 0, 2}, - /* XP */ { 0, 0, 1, 3, 2, 0}, + /* ZM */ { 0, 0, 2, 0, 1, 3}, + /* ZP */ { 0, 0, 0, 2, 3, 1}, + /* XM */ { 0, 0, 3, 1, 2, 0}, + /* XP */ { 0, 0, 1, 3, 0, 2}, }; // Get a list of available connections: @@ -389,8 +394,10 @@ bool cPieceGenerator::TryPlacePieceAtConnector( Vector3i ConnPos = a_Connector.m_Pos; // The position at which the new connector should be placed - 1 block away from the connector AddFaceDirection(ConnPos.x, ConnPos.y, ConnPos.z, a_Connector.m_Direction); + /* // DEBUG: - printf("Placing piece at pos {%d, %d, %d}, direction %s\n", ConnPos.x, ConnPos.y, ConnPos.z, BlockFaceToString(a_Connector.m_Direction).c_str()); + printf("Placing piece at connector pos {%d, %d, %d}, direction %s\n", ConnPos.x, ConnPos.y, ConnPos.z, BlockFaceToString(a_Connector.m_Direction).c_str()); + //*/ for (cPieces::iterator itrP = AvailablePieces.begin(), endP = AvailablePieces.end(); itrP != endP; ++itrP) { @@ -427,11 +434,15 @@ bool cPieceGenerator::TryPlacePieceAtConnector( cConnection & Conn = Connections[rnd % Connections.size()]; // Place the piece: + /* + // DEBUG printf("Chosen connector at {%d, %d, %d}, direction %s, needs %d rotations\n", Conn.m_Connector.m_Pos.x, Conn.m_Connector.m_Pos.y, Conn.m_Connector.m_Pos.z, BlockFaceToString(Conn.m_Connector.m_Direction).c_str(), Conn.m_NumCCWRotations ); + //*/ + Vector3i NewPos = Conn.m_Piece->RotatePos(Conn.m_Connector.m_Pos, Conn.m_NumCCWRotations); ConnPos -= NewPos; cPlacedPiece * PlacedPiece = new cPlacedPiece(&a_ParentPiece, *(Conn.m_Piece), ConnPos, Conn.m_NumCCWRotations); @@ -440,8 +451,10 @@ bool cPieceGenerator::TryPlacePieceAtConnector( // Add the new piece's connectors to the list of free connectors: cPiece::cConnectors Connectors = Conn.m_Piece->GetConnectors(); + /* // DEBUG: printf("Adding %u connectors to the pool\n", Connectors.size() - 1); + //*/ for (cPiece::cConnectors::const_iterator itr = Connectors.begin(), end = Connectors.end(); itr != end; ++itr) { @@ -471,6 +484,7 @@ bool cPieceGenerator::CheckConnection( { // For each placed piece, test the hitbox against the new piece: cCuboid RotatedHitBox = a_Piece.RotateHitBoxToConnector(a_NewConnector, a_ToPos, a_NumCCWRotations); + RotatedHitBox.Sort(); for (cPlacedPieces::const_iterator itr = a_OutPieces.begin(), end = a_OutPieces.end(); itr != end; ++itr) { if ((*itr)->GetHitBox().DoesIntersect(RotatedHitBox)) @@ -485,6 +499,7 @@ bool cPieceGenerator::CheckConnection( +//* // DEBUG: void cPieceGenerator::DebugConnectorPool(const cPieceGenerator::cFreeConnectors & a_ConnectorPool, size_t a_NumProcessed) { @@ -501,6 +516,7 @@ void cPieceGenerator::DebugConnectorPool(const cPieceGenerator::cFreeConnectors ); } // for itr - a_ConnectorPool[] } +//*/ @@ -553,6 +569,7 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, i // Place the starting piece: a_OutPieces.push_back(PlaceStartingPiece(a_BlockX, a_BlockY, a_BlockZ, ConnectorPool)); + /* // DEBUG: printf("Placed the starting piece at {%d, %d, %d}\n", a_BlockX, a_BlockY, a_BlockZ); cCuboid Hitbox = a_OutPieces[0]->GetHitBox(); @@ -563,6 +580,7 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, i Hitbox.DifX() + 1, Hitbox.DifY() + 1, Hitbox.DifZ() + 1 ); DebugConnectorPool(ConnectorPool, 0); + //*/ // Place pieces at the available connectors: /* @@ -578,6 +596,8 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, i { if (TryPlacePieceAtConnector(*Conn.m_Piece, Conn.m_Connector, a_OutPieces, ConnectorPool)) { + /* + // DEBUG: const cPlacedPiece * NewPiece = a_OutPieces.back(); const Vector3i & Coords = NewPiece->GetCoords(); printf("Placed a new piece at {%d, %d, %d}, rotation %d\n", Coords.x, Coords.y, Coords.z, NewPiece->GetNumCCWRotations()); @@ -589,6 +609,7 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockY, int a_BlockZ, i Hitbox.DifX() + 1, Hitbox.DifY() + 1, Hitbox.DifZ() + 1 ); DebugConnectorPool(ConnectorPool, NumProcessed + 1); + //*/ } } NumProcessed++; diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 310c21fdd..9dd5bcfba 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -30,6 +30,9 @@ Each uses a slightly different approach to generating: class cPiece { public: + // Force a virtual destructor in all descendants + virtual ~cPiece() {} + struct cConnector { /** Position relative to the piece */ @@ -82,9 +85,14 @@ typedef std::vector cPieces; +/** This class is an interface that provides pieces for the generator. It can keep track of what pieces were +placed and adjust the returned piece vectors. */ class cPiecePool { public: + // Force a virtual destructor in all descendants: + virtual ~cPiecePool() {} + /** Returns a list of pieces that contain the specified connector type. The cPiece pointers returned are managed by the pool and the caller doesn't free them. */ virtual cPieces GetPiecesWithConnector(int a_ConnectorType) = 0; @@ -140,7 +148,7 @@ public: /** Cleans up all the memory used by the placed pieces. Call this utility function instead of freeing the items on your own. */ - void FreePieces(cPlacedPieces & a_PlacedPieces); + static void FreePieces(cPlacedPieces & a_PlacedPieces); protected: /** The type used for storing a connection from one piece to another, while building the piece tree. */ -- cgit v1.2.3 From 0f412a0a022b75823561c2f78e5f0c9469b0d1b4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 9 Mar 2014 21:48:18 +0000 Subject: Removed uneeded meta obtain --- src/Simulator/FireSimulator.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 6079ea740..31cc0b670 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -1,4 +1,3 @@ - #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "FireSimulator.h" @@ -334,7 +333,6 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_Rel for (size_t i = 0; i < ARRAYCOUNT(gNeighborCoords); i++) { BLOCKTYPE BlockType; - NIBBLETYPE BlockMeta; int X = a_RelX + gNeighborCoords[i].x; int Z = a_RelZ + gNeighborCoords[i].z; @@ -343,7 +341,7 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_Rel { continue; } - Neighbour->GetBlockTypeMeta(X, a_RelY + gCrossCoords[i].y, Z, BlockType, BlockMeta); + BlockType = Neighbour->GetBlockTypeMeta(X, a_RelY + gCrossCoords[i].y, Z); if (!IsFuel(BlockType)) { -- cgit v1.2.3 From 0b9763fc5a84ac171338484f653fdae2a2bc999a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 10 Mar 2014 07:55:47 +0100 Subject: Fixed MSVC2008 compilation. --- src/WorldStorage/FireworksSerializer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 0e0094e76..1f05b470d 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -20,8 +20,8 @@ void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFa a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker); a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail); a_Writer.AddByte("Type", a_FireworkItem.m_Type); - a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size()); - a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size()); + a_Writer.AddIntArray("Colors", &(a_FireworkItem.m_Colours[0]), a_FireworkItem.m_Colours.size()); + a_Writer.AddIntArray("FadeColors", &(a_FireworkItem.m_FadeColours[0]), a_FireworkItem.m_FadeColours.size()); a_Writer.EndCompound(); a_Writer.EndList(); a_Writer.EndCompound(); @@ -35,11 +35,11 @@ void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFa a_Writer.AddByte("Type", a_FireworkItem.m_Type); if (!a_FireworkItem.m_Colours.empty()) { - a_Writer.AddIntArray("Colors", a_FireworkItem.m_Colours.data(), a_FireworkItem.m_Colours.size()); + a_Writer.AddIntArray("Colors", &(a_FireworkItem.m_Colours[0]), a_FireworkItem.m_Colours.size()); } if (!a_FireworkItem.m_FadeColours.empty()) { - a_Writer.AddIntArray("FadeColors", a_FireworkItem.m_FadeColours.data(), a_FireworkItem.m_FadeColours.size()); + a_Writer.AddIntArray("FadeColors", &(a_FireworkItem.m_FadeColours[0]), a_FireworkItem.m_FadeColours.size()); } a_Writer.EndCompound(); break; -- cgit v1.2.3 From 6c4807556141f49a3fa5ff63474e6b95e5fd5cbf Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 10 Mar 2014 08:38:40 +0100 Subject: POCPieces: Added height. Now the pieces connect in different heights, too, creating a true 3D maze. --- src/Generating/POCPieceGenerator.cpp | 37 +++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/Generating/POCPieceGenerator.cpp b/src/Generating/POCPieceGenerator.cpp index 9edfcc64f..d7619b8ff 100644 --- a/src/Generating/POCPieceGenerator.cpp +++ b/src/Generating/POCPieceGenerator.cpp @@ -20,13 +20,14 @@ class cPOCPiece : public cPiece { public: - cPOCPiece(int a_Size) : - m_Size(a_Size) + cPOCPiece(int a_SizeXZ, int a_Height) : + m_SizeXZ(a_SizeXZ), + m_Height(a_Height) { - m_Connectors.push_back(cConnector(m_Size / 2, 1, 0, 0, BLOCK_FACE_ZM)); - m_Connectors.push_back(cConnector(m_Size / 2, 1, m_Size - 1, 1, BLOCK_FACE_ZP)); - m_Connectors.push_back(cConnector(0, 1, m_Size / 2, 2, BLOCK_FACE_XM)); - m_Connectors.push_back(cConnector(m_Size - 1, 1, m_Size / 2, m_Size % 3, BLOCK_FACE_XP)); + m_Connectors.push_back(cConnector(m_SizeXZ / 2, a_Height / 2, 0, 0, BLOCK_FACE_ZM)); + m_Connectors.push_back(cConnector(m_SizeXZ / 2, a_Height / 2, m_SizeXZ - 1, 1, BLOCK_FACE_ZP)); + m_Connectors.push_back(cConnector(0, a_Height / 2, m_SizeXZ / 2, 2, BLOCK_FACE_XM)); + m_Connectors.push_back(cConnector(m_SizeXZ - 1, a_Height - 1, m_SizeXZ / 2, m_SizeXZ % 3, BLOCK_FACE_XP)); } @@ -38,7 +39,7 @@ public: Vector3i Min = a_Pos; Min.Move(-BlockX, 0, -BlockZ); Vector3i Max = Min; - Max.Move(m_Size - 1, 2, m_Size - 1); + Max.Move(m_SizeXZ - 1, m_Height - 1, m_SizeXZ - 1); ASSERT(Min.x < cChunkDef::Width); ASSERT(Min.z < cChunkDef::Width); ASSERT(Max.x >= 0); @@ -46,22 +47,22 @@ public: if (Min.x >= 0) { // Draw the XM wall: - a_ChunkDesc.FillRelCuboid(Min.x, Min.x, Min.y, Max.y, Min.z, Max.z, E_BLOCK_STAINED_GLASS, m_Size % 16); + a_ChunkDesc.FillRelCuboid(Min.x, Min.x, Min.y, Max.y, Min.z, Max.z, E_BLOCK_STAINED_GLASS, m_SizeXZ % 16); } if (Min.z >= 0) { // Draw the ZM wall: - a_ChunkDesc.FillRelCuboid(Min.x, Max.x, Min.y, Max.y, Min.z, Min.z, E_BLOCK_STAINED_GLASS, m_Size % 16); + a_ChunkDesc.FillRelCuboid(Min.x, Max.x, Min.y, Max.y, Min.z, Min.z, E_BLOCK_STAINED_GLASS, m_SizeXZ % 16); } if (Max.x < cChunkDef::Width) { // Draw the XP wall: - a_ChunkDesc.FillRelCuboid(Max.x, Max.x, Min.y, Max.y, Min.z, Max.z, E_BLOCK_STAINED_GLASS, m_Size % 16); + a_ChunkDesc.FillRelCuboid(Max.x, Max.x, Min.y, Max.y, Min.z, Max.z, E_BLOCK_STAINED_GLASS, m_SizeXZ % 16); } if (Max.z < cChunkDef::Width) { // Draw the ZP wall: - a_ChunkDesc.FillRelCuboid(Min.x, Max.x, Min.y, Max.y, Max.z, Max.z, E_BLOCK_STAINED_GLASS, m_Size % 16); + a_ChunkDesc.FillRelCuboid(Min.x, Max.x, Min.y, Max.y, Max.z, Max.z, E_BLOCK_STAINED_GLASS, m_SizeXZ % 16); } // Draw all the connectors: @@ -100,7 +101,8 @@ public: } protected: - int m_Size; + int m_SizeXZ; + int m_Height; cConnectors m_Connectors; // cPiece overrides: @@ -111,12 +113,12 @@ protected: virtual Vector3i GetSize(void) const override { - return Vector3i(m_Size, 3, m_Size); + return Vector3i(m_SizeXZ, m_Height, m_SizeXZ); } virtual cCuboid GetHitBox(void) const override { - return cCuboid(0, 0, 0, m_Size - 1, 2, m_Size - 1); + return cCuboid(0, 0, 0, m_SizeXZ - 1, m_Height - 1, m_SizeXZ - 1); } virtual bool CanRotateCCW(int a_NumRotations) const override @@ -153,9 +155,10 @@ cPOCPieceGenerator::cPOCPieceGenerator(int a_Seed) : m_Seed(a_Seed) { // Prepare a vector of available pieces: - m_AvailPieces.push_back(new cPOCPiece(5)); - m_AvailPieces.push_back(new cPOCPiece(7)); - m_AvailPieces.push_back(new cPOCPiece(9)); + m_AvailPieces.push_back(new cPOCPiece(5, 3)); + m_AvailPieces.push_back(new cPOCPiece(7, 5)); + m_AvailPieces.push_back(new cPOCPiece(9, 5)); + m_AvailPieces.push_back(new cPOCPiece(5, 7)); // Generate the structure: cBFSPieceGenerator Gen(*this, a_Seed); -- cgit v1.2.3 From 0cce0478d846114f49c4b8fe201aee7a1bb06b22 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 10 Mar 2014 17:07:46 +0100 Subject: This allows a blockarea to have an Offset. --- src/BlockArea.cpp | 19 +++++++++++++++++++ src/BlockArea.h | 5 +++++ src/WorldStorage/SchematicFileSerializer.cpp | 23 +++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index d07ef747a..986b2ee25 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -168,6 +168,7 @@ cBlockArea::cBlockArea(void) : m_SizeX(0), m_SizeY(0), m_SizeZ(0), + m_Offset(0,0,0), m_BlockTypes(NULL), m_BlockMetas(NULL), m_BlockLight(NULL), @@ -254,6 +255,24 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) +void cBlockArea::SetOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ) +{ + m_Offset.Set(a_OffsetX, a_OffsetY, a_OffsetZ); +} + + + + + +void cBlockArea::SetOffset(Vector3i a_Offset) +{ + m_Offset.Set(a_Offset.x, a_Offset.y, a_Offset.z); +} + + + + + void cBlockArea::SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ) { m_OriginX = a_OriginX; diff --git a/src/BlockArea.h b/src/BlockArea.h index 0703f195e..d89c9b372 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -209,6 +209,8 @@ public: void SetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockLight); void SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight); void SetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight); + void SetOffset (int a_OffsetX, int a_OffsetY, int a_OffsetZ); + void SetOffset (Vector3i a_Offset); // Getters: BLOCKTYPE GetRelBlockType (int a_RelX, int a_RelY, int a_RelZ) const; @@ -219,6 +221,7 @@ public: NIBBLETYPE GetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ) const; NIBBLETYPE GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ) const; + Vector3i GetOffset (void) const {return m_Offset;} void SetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); @@ -299,6 +302,8 @@ protected: int m_SizeY; int m_SizeZ; + Vector3i m_Offset; + BLOCKTYPE * m_BlockTypes; NIBBLETYPE * m_BlockMetas; // Each meta is stored as a separate byte for faster access NIBBLETYPE * m_BlockLight; // Each light value is stored as a separate byte for faster access diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index b021aeb0c..0aea931eb 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -177,6 +177,25 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP a_BlockArea.Clear(); a_BlockArea.SetSize(SizeX, SizeY, SizeZ, AreMetasPresent ? (cBlockArea::baTypes | cBlockArea::baMetas) : cBlockArea::baTypes); + int TOffsetX = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetX"); + int TOffsetY = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetY"); + int TOffsetZ = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetZ"); + + if ( + (TOffsetX < 0) || (TOffsetY < 0) || (TOffsetZ < 0) || + (a_NBT.GetType(TOffsetX) != TAG_Int) || + (a_NBT.GetType(TOffsetY) != TAG_Int) || + (a_NBT.GetType(TOffsetZ) != TAG_Int) + ) + { + // Not every schematic file has an offset, so we shoudn't give a warn message. + a_BlockArea.SetOffset(0, 0, 0); + } + else + { + a_BlockArea.SetOffset(a_NBT.GetInt(TOffsetX), a_NBT.GetInt(TOffsetY), a_NBT.GetInt(TOffsetZ)); + } + // Copy the block types and metas: int NumBytes = a_BlockArea.m_SizeX * a_BlockArea.m_SizeY * a_BlockArea.m_SizeZ; if (a_NBT.GetDataLength(TBlockTypes) < NumBytes) @@ -234,6 +253,10 @@ AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockA Writer.AddByteArray("Data", Dummy.data(), Dummy.size()); } + Writer.AddInt("WEOffsetX", a_BlockArea.m_Offset.x); + Writer.AddInt("WEOffsetY", a_BlockArea.m_Offset.y); + Writer.AddInt("WEOffsetZ", a_BlockArea.m_Offset.z); + // TODO: Save entities and block entities Writer.BeginList("Entities", TAG_Compound); Writer.EndList(); -- cgit v1.2.3 From 30353cd2285d8d2e9ec38c1015c7d45dbdb82b39 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 10:24:44 -0700 Subject: Fixed MTRand warnings --- src/MersenneTwister.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MersenneTwister.h b/src/MersenneTwister.h index 2c5440f17..759b8a1ae 100644 --- a/src/MersenneTwister.h +++ b/src/MersenneTwister.h @@ -72,7 +72,7 @@ protected: uint32 state[N]; // internal state uint32 *pNext; // next value to get from state - int left; // number of values left before reload needed + uint32 left; // number of values left before reload needed // Methods public: @@ -164,7 +164,7 @@ inline void MTRand::initialize( const uint32 seed ) // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. uint32 *s = state; uint32 *r = state; - int i = 1; + uint32 i = 1; *s++ = seed & 0xffffffffUL; for( ; i < N; ++i ) { @@ -205,9 +205,9 @@ inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) // in each element are discarded. // Just call seed() if you want to get array from /dev/urandom initialize(19650218UL); - int i = 1; + uint32 i = 1; uint32 j = 0; - int k = ( (uint32)N > seedLength ? (uint32)N : seedLength ); + uint32 k = ( (uint32)N > seedLength ? (uint32)N : seedLength ); for( ; k; --k ) { state[i] = -- cgit v1.2.3 From 8665233522da3454a77c4c40ace03d3a61150023 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 10:32:51 -0700 Subject: Fixed cast between types of different alignment in cSocket --- src/OSSupport/Socket.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OSSupport/Socket.cpp b/src/OSSupport/Socket.cpp index 6afaceedf..c29e495c3 100644 --- a/src/OSSupport/Socket.cpp +++ b/src/OSSupport/Socket.cpp @@ -307,7 +307,8 @@ bool cSocket::ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Por CloseSocket(); return false; } - addr = *((unsigned long*)hp->h_addr); + // Should be optimised to a single word copy + memcpy(&addr, hp->h_addr, hp->h_length); } sockaddr_in server; -- cgit v1.2.3 From e2e7f2184f09562753be1a474c2d7e8273b1e83b Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 10:38:21 -0700 Subject: Fixed cast to type with different alignment in BlockingTCPLink --- src/OSSupport/BlockingTCPLink.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OSSupport/BlockingTCPLink.cpp b/src/OSSupport/BlockingTCPLink.cpp index e9c00d6d4..07f48b955 100644 --- a/src/OSSupport/BlockingTCPLink.cpp +++ b/src/OSSupport/BlockingTCPLink.cpp @@ -70,7 +70,7 @@ bool cBlockingTCPLink::Connect(const char * iAddress, unsigned int iPort) } } - server.sin_addr.s_addr = *((unsigned long *)hp->h_addr); + memcpy(&server.sin_addr.s_addr,hp->h_addr, hp->h_length); server.sin_family = AF_INET; server.sin_port = htons( (unsigned short)iPort); if (connect(m_Socket, (struct sockaddr *)&server, sizeof(server))) -- cgit v1.2.3 From 7c974b27b1c334da3cd83769398fa9104a2e3253 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 10:42:52 -0700 Subject: Removed unused macro --- src/Protocol/Protocol125.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 50ebb6d43..69f4934d8 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1269,19 +1269,6 @@ int cProtocol125::ParsePacket(unsigned char a_PacketType) -#define HANDLE_PACKET_PARSE(Packet) \ - { \ - int res = Packet.Parse(m_ReceivedData); \ - if (res < 0) \ - { \ - return res; \ - } \ - } - - - - - int cProtocol125::ParseArmAnim(void) { HANDLE_PACKET_READ(ReadBEInt, int, EntityID); -- cgit v1.2.3 From 8864e7d8ca63c972793234d3c65aa534fdec06ad Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 11:13:07 -0700 Subject: Fixed alignment issues in Fireworks Serializer --- src/WorldStorage/FireworksSerializer.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 1f05b470d..bdd5952ad 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -90,16 +90,16 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB if (ExplosionName == "Colors") { // Divide by four as data length returned in bytes - int DataLength = a_NBT.GetDataLength(explosiontag) / 4; + int DataLength = a_NBT.GetDataLength(explosiontag); if (DataLength == 0) { continue; } - const int * ColourData = (const int *)(a_NBT.GetData(explosiontag)); - for (int i = 0; i < DataLength; i++) + const char * ColourData = (a_NBT.GetData(explosiontag)); + for (int i = 0; i < DataLength; i += 4 /* Size of network int*/) { - a_FireworkItem.m_Colours.push_back(ntohl(ColourData[i])); + a_FireworkItem.m_Colours.push_back(GetBEInt(ColourData + i)); } } else if (ExplosionName == "FadeColors") @@ -110,10 +110,10 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB continue; } - const int * FadeColourData = (const int *)(a_NBT.GetData(explosiontag)); - for (int i = 0; i < DataLength; i++) + const char * FadeColourData = (a_NBT.GetData(explosiontag)); + for (int i = 0; i < DataLength; i += 4 /* Size of network int*/) { - a_FireworkItem.m_FadeColours.push_back(ntohl(FadeColourData[i])); + a_FireworkItem.m_FadeColours.push_back(GetBEInt(FadeColourData + i)); } } } -- cgit v1.2.3 From cff66315137e90db1292fa01640aae2e2d23b862 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 11:14:34 -0700 Subject: Removed unused macro from WSSCompact --- src/WorldStorage/WSSCompact.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index 95477838e..1e84fb4ad 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -764,7 +764,6 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3() // Cannot use cChunk::MakeIndex because it might change again????????? // For compatibility, use what we know is current - #define MAKE_2_INDEX( x, y, z ) ( y + (z * 256) + (x * 256 * 16) ) #define MAKE_3_INDEX( x, y, z ) ( x + (z * 16) + (y * 16 * 16) ) unsigned int InChunkOffset = 0; -- cgit v1.2.3 From b2733fad220243a631f9625cc84a50b70b6f43de Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 10 Mar 2014 18:23:12 +0000 Subject: Fixed compile --- src/Simulator/FireSimulator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 31cc0b670..26712e6e6 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -1,3 +1,4 @@ + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "FireSimulator.h" @@ -341,7 +342,7 @@ void cFireSimulator::RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_Rel { continue; } - BlockType = Neighbour->GetBlockTypeMeta(X, a_RelY + gCrossCoords[i].y, Z); + BlockType = Neighbour->GetBlock(X, a_RelY + gCrossCoords[i].y, Z); if (!IsFuel(BlockType)) { -- cgit v1.2.3 From 8947f802940213d371863710e1c3ac873b2dc4b9 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 11:24:12 -0700 Subject: Use string.reserve to avoid the need to do inplace byteswap --- src/WorldStorage/FastNBT.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp index 8f80c3f75..f1f092e0b 100644 --- a/src/WorldStorage/FastNBT.cpp +++ b/src/WorldStorage/FastNBT.cpp @@ -506,22 +506,18 @@ void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, si { TagCommon(a_Name, TAG_IntArray); Int32 len = htonl(a_NumElements); + size_t cap = m_Result.capacity(); + size_t size = m_Result.length(); + if ((cap - size) < (4 + a_NumElements * 4)) + { + m_Result.reserve(size +4 + a_NumElements * 4); + } m_Result.append((const char *)&len, 4); -#if defined(ANDROID_NDK) - // Android has alignment issues - cannot byteswap (htonl) an int that is not 32-bit-aligned, which happens in the regular version for (size_t i = 0; i < a_NumElements; i++) { int Element = htonl(a_Value[i]); m_Result.append((const char *)&Element, 4); } -#else - int * Elements = (int *)(m_Result.data() + m_Result.size()); - m_Result.append(a_NumElements * 4, (char)0); - for (size_t i = 0; i < a_NumElements; i++) - { - Elements[i] = htonl(a_Value[i]); - } -#endif } -- cgit v1.2.3 From 2eca30aebc9a4f7307c31a75ca23e19fa3f1a4a7 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 11:34:20 -0700 Subject: Removed Some unnessicary macros --- src/ClientHandle.cpp | 13 ------------- src/LightingThread.cpp | 6 ------ src/WorldStorage/WSSAnvil.cpp | 4 ++-- 3 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 94c9f5f71..df728e83b 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -36,19 +36,6 @@ - - -#define AddPistonDir(x, y, z, dir, amount) switch (dir) { case 0: (y)-=(amount); break; case 1: (y)+=(amount); break;\ - case 2: (z)-=(amount); break; case 3: (z)+=(amount); break;\ - case 4: (x)-=(amount); break; case 5: (x)+=(amount); break; } - - - - - -/** If the number of queued outgoing packets reaches this, the client will be kicked */ -#define MAX_OUTGOING_PACKETS 2000 - /** Maximum number of explosions to send this tick, server will start dropping if exceeded */ #define MAX_EXPLOSIONS_PER_TICK 20 diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 44dadb8a9..302473d71 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -13,12 +13,6 @@ -/// If more than this many chunks are in the queue, a warning is printed to the log -#define WARN_ON_QUEUE_SIZE 800 - - - - /// Chunk data callback that takes the chunk data and puts them into cLightingThread's m_BlockTypes[] / m_HeightMap[]: class cReader : diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index eb159f28d..070738164 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -507,10 +507,10 @@ cChunkDef::BiomeMap * cWSSAnvil::LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_Bio // The biomes stored don't match in size return NULL; } - const int * BiomeData = (const int *)(a_NBT.GetData(a_TagIdx)); + const char * BiomeData = (a_NBT.GetData(a_TagIdx)); for (size_t i = 0; i < ARRAYCOUNT(*a_BiomeMap); i++) { - (*a_BiomeMap)[i] = (EMCSBiome)(ntohl(BiomeData[i])); + (*a_BiomeMap)[i] = (EMCSBiome)(GetBEInt(&BiomeData[i * 4])); if ((*a_BiomeMap)[i] == 0xff) { // Unassigned biomes -- cgit v1.2.3 From 462829e23d8d3404e58ffc64fd19cf39e9be218f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 10 Mar 2014 18:35:02 +0000 Subject: Shrapnel now configurable --- src/ChunkMap.cpp | 2 +- src/World.cpp | 3 +-- src/World.h | 6 ++++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index b13337b44..e750ad731 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1832,7 +1832,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } - else if (m_World->GetTickRandomNumber(100) < 20) // 20% chance of flinging stuff around + else if (m_World->IsTNTShrapnelEnabled() && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around { if (!cBlockInfo::FullyOccupiesVoxel(area.GetBlockType(bx + x, by + y, bz + z))) { diff --git a/src/World.cpp b/src/World.cpp index d6b88f187..89d0cf454 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -250,8 +250,6 @@ cWorld::cWorld(const AString & a_WorldName) : m_SkyDarkness(0), m_Weather(eWeather_Sunny), m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) - m_bCommandBlocksEnabled(false), - m_bUseChatPrefixes(true), m_Scoreboard(this), m_MapManager(this), m_GeneratorCallbacks(*this), @@ -554,6 +552,7 @@ void cWorld::Start(void) m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", true); m_ShouldLavaSpawnFire = IniFile.GetValueSetB("Physics", "ShouldLavaSpawnFire", true); + m_bTNTSpawnsShrapnel = IniFile.GetValueSetB("Physics", "IsTNTShrapnelEnabled", true); m_bCommandBlocksEnabled = IniFile.GetValueSetB("Mechanics", "CommandBlocksEnabled", false); m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true); m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); diff --git a/src/World.h b/src/World.h index 4b74f7aba..d7d5b5059 100644 --- a/src/World.h +++ b/src/World.h @@ -590,6 +590,9 @@ public: bool AreCommandBlocksEnabled(void) const { return m_bCommandBlocksEnabled; } void SetCommandBlocksEnabled(bool a_Flag) { m_bCommandBlocksEnabled = a_Flag; } + bool IsTNTShrapnelEnabled(void) const { return m_bTNTSpawnsShrapnel; } + void SetTNTShrapnelEnabled(bool a_Flag) { m_bTNTSpawnsShrapnel = a_Flag; } + bool ShouldUseChatPrefixes(void) const { return m_bUseChatPrefixes; } void SetShouldUseChatPrefixes(bool a_Flag) { m_bUseChatPrefixes = a_Flag; } @@ -847,6 +850,9 @@ private: /** Whether prefixes such as [INFO] are prepended to SendMessageXXX() / BroadcastChatXXX() functions */ bool m_bUseChatPrefixes; + + /** Whether TNT explosions, done via cWorld::DoExplosionAt(), should project random affected blocks as FallingBlock entities */ + bool m_bTNTSpawnsShrapnel; cChunkGenerator m_Generator; -- cgit v1.2.3 From b78c729880705c1bf28f266b087046c4eaed8317 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 11:56:23 -0700 Subject: Fixed Alignment issue in ByteBuffer --- src/ByteBuffer.cpp | 2 +- src/StringUtils.cpp | 7 ++----- src/StringUtils.h | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 96a135562..a7553786e 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -767,7 +767,7 @@ bool cByteBuffer::ReadUTF16String(AString & a_String, int a_NumChars) { return false; } - RawBEToUTF8((short *)(RawData.data()), a_NumChars, a_String); + RawBEToUTF8((RawData.data()), a_NumChars, a_String); return true; } diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 3fe75d611..3e047fb5c 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -288,13 +288,13 @@ void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & // Converts a stream of BE shorts into UTF-8 string; returns a ref to a_UTF8 -AString & RawBEToUTF8(short * a_RawData, int a_NumShorts, AString & a_UTF8) +AString & RawBEToUTF8(const char * a_RawData, int a_NumShorts, AString & a_UTF8) { a_UTF8.clear(); a_UTF8.reserve(3 * a_NumShorts / 2); // a quick guess of the resulting size for (int i = 0; i < a_NumShorts; i++) { - int c = ntohs(*(a_RawData + i)); + int c = GetBEShort(a_RawData + i*2); if (c < 0x80) { a_UTF8.push_back((char)c); @@ -364,10 +364,7 @@ Notice from the original file: #define UNI_MAX_BMP 0x0000FFFF #define UNI_MAX_UTF16 0x0010FFFF -#define UNI_MAX_UTF32 0x7FFFFFFF -#define UNI_MAX_LEGAL_UTF32 0x0010FFFF #define UNI_SUR_HIGH_START 0xD800 -#define UNI_SUR_HIGH_END 0xDBFF #define UNI_SUR_LOW_START 0xDC00 #define UNI_SUR_LOW_END 0xDFFF diff --git a/src/StringUtils.h b/src/StringUtils.h index dfbfc2a75..b64108409 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -58,7 +58,7 @@ extern unsigned int RateCompareString(const AString & s1, const AString & s2 ); extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AString & iReplaceWith); // tolua_export /// Converts a stream of BE shorts into UTF-8 string; returns a ref to a_UTF8 -extern AString & RawBEToUTF8(short * a_RawData, int a_NumShorts, AString & a_UTF8); +extern AString & RawBEToUTF8(const char * a_RawData, int a_NumShorts, AString & a_UTF8); /// Converts a UTF-8 string into a UTF-16 BE string, packing that back into AString; return a ref to a_UTF16 extern AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a_UTF16); -- cgit v1.2.3 From 693734bd8307f3089368cb3aca662641f92f2e71 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 11:57:04 -0700 Subject: Enable error on cast-align and unused macros --- SetFlags.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index a9657fff1..d9308f603 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -197,7 +197,6 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=missing-prototypes -Wno-error=non-virtual-dtor") add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") - add_flags_cxx("-Wno-error=cast-align -Wno-error=unused-macros") add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") add_flags_cxx("-Wno-missing-noreturn -Wno-error=unreachable-code -Wno-error=undef") add_flags_cxx("-Wno-error=format-nonliteral") -- cgit v1.2.3 From bc556e7f00ee28198b5ba3e46c1c06caab8fc37b Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 12:21:18 -0700 Subject: Fixed Issues in ProtoProxy --- Tools/ProtoProxy/Connection.cpp | 16 ++++++++-------- Tools/ProtoProxy/Connection.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index 91d2fc42f..be908f303 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -131,8 +131,6 @@ } \ } - -#define MAX_ENC_LEN 1024 @@ -473,14 +471,14 @@ bool cConnection::SendData(SOCKET a_Socket, cByteBuffer & a_Data, const char * a -bool cConnection::SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, const char * a_Data, int a_Size, const char * a_Peer) +bool cConnection::SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, const char * a_Data, size_t a_Size, const char * a_Peer) { DataLog(a_Data, a_Size, "Encrypting %d bytes to %s", a_Size, a_Peer); const Byte * Data = (const Byte *)a_Data; while (a_Size > 0) { Byte Buffer[64 KiB]; - int NumBytes = (a_Size > sizeof(Buffer)) ? sizeof(Buffer) : a_Size; + size_t NumBytes = (a_Size > sizeof(Buffer)) ? sizeof(Buffer) : a_Size; a_Encryptor.ProcessData(Buffer, Data, NumBytes); bool res = SendData(a_Socket, (const char *)Buffer, NumBytes, a_Peer); if (!res) @@ -2263,7 +2261,9 @@ bool cConnection::HandleServerSpawnObjectVehicle(void) HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw); HANDLE_SERVER_PACKET_READ(ReadBEInt, int, DataIndicator); AString ExtraData; - short VelocityX, VelocityY, VelocityZ; + short VelocityX = 0; + short VelocityY = 0; + short VelocityZ = 0; if (DataIndicator != 0) { HANDLE_SERVER_PACKET_READ(ReadBEShort, short, SpeedX); @@ -2697,7 +2697,7 @@ bool cConnection::ParseMetadata(cByteBuffer & a_Buffer, AString & a_Metadata) a_Metadata.push_back(x); while (x != 0x7f) { - int Index = ((unsigned)((unsigned char)x)) & 0x1f; // Lower 5 bits = index + //int Index = ((unsigned)((unsigned char)x)) & 0x1f; // Lower 5 bits = index int Type = ((unsigned)((unsigned char)x)) >> 5; // Upper 3 bits = type int Length = 0; switch (Type) @@ -2772,7 +2772,7 @@ void cConnection::LogMetadata(const AString & a_Metadata, size_t a_IndentCount) { int Index = ((unsigned)((unsigned char)a_Metadata[pos])) & 0x1f; // Lower 5 bits = index int Type = ((unsigned)((unsigned char)a_Metadata[pos])) >> 5; // Upper 3 bits = type - int Length = 0; + //int Length = 0; switch (Type) { case 0: @@ -2827,7 +2827,7 @@ void cConnection::LogMetadata(const AString & a_Metadata, size_t a_IndentCount) ASSERT(!"Cannot parse item description from metadata"); return; } - int After = bb.GetReadableSpace(); + //int After = bb.GetReadableSpace(); int BytesConsumed = BytesLeft - bb.GetReadableSpace(); Log("%sslot[%d] = %s (%d bytes)", Indent.c_str(), Index, ItemDesc.c_str(), BytesConsumed); diff --git a/Tools/ProtoProxy/Connection.h b/Tools/ProtoProxy/Connection.h index 5e4f8cd7b..70b759d0f 100644 --- a/Tools/ProtoProxy/Connection.h +++ b/Tools/ProtoProxy/Connection.h @@ -109,7 +109,7 @@ protected: bool SendData(SOCKET a_Socket, cByteBuffer & a_Data, const char * a_Peer); /// Sends data to the specfied socket, after encrypting it using a_Encryptor. If sending fails, prints a fail message using a_Peer and returns false - bool SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, const char * a_Data, int a_Size, const char * a_Peer); + bool SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, const char * a_Data, size_t a_Size, const char * a_Peer); /// Sends data to the specfied socket, after encrypting it using a_Encryptor. If sending fails, prints a fail message using a_Peer and returns false bool SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, cByteBuffer & a_Data, const char * a_Peer); -- cgit v1.2.3 From bb28f0d1e3fa685791433220d0bf96bda6d4937e Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 12:36:01 -0700 Subject: Fixed assert --- src/ByteBuffer.cpp | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index a7553786e..ae4e72737 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -46,6 +46,9 @@ #ifdef SELF_TEST +#define assert_test(x) ( !!(x) || \ + LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), abort(1)) + /// Self-test of the VarInt-reading and writing code static class cByteBufferSelfTest { @@ -62,11 +65,11 @@ public: cByteBuffer buf(50); buf.Write("\x05\xac\x02\x00", 4); UInt32 v1; - assert(buf.ReadVarInt(v1) && (v1 == 5)); + assert_test(buf.ReadVarInt(v1) && (v1 == 5)); UInt32 v2; - assert(buf.ReadVarInt(v2) && (v2 == 300)); + assert_test(buf.ReadVarInt(v2) && (v2 == 300)); UInt32 v3; - assert(buf.ReadVarInt(v3) && (v3 == 0)); + assert_test(buf.ReadVarInt(v3) && (v3 == 0)); } void TestWrite(void) @@ -77,8 +80,8 @@ public: buf.WriteVarInt(0); AString All; buf.ReadAll(All); - assert(All.size() == 4); - assert(memcmp(All.data(), "\x05\xac\x02\x00", All.size()) == 0); + assert_test(All.size() == 4); + assert_test(memcmp(All.data(), "\x05\xac\x02\x00", All.size()) == 0); } void TestWrap(void) @@ -87,17 +90,17 @@ public: for (int i = 0; i < 1000; i++) { size_t FreeSpace = buf.GetFreeSpace(); - assert(buf.GetReadableSpace() == 0); - assert(FreeSpace > 0); - assert(buf.Write("a", 1)); - assert(buf.CanReadBytes(1)); - assert(buf.GetReadableSpace() == 1); + assert_test(buf.GetReadableSpace() == 0); + assert_test(FreeSpace > 0); + assert_test(buf.Write("a", 1)); + assert_test(buf.CanReadBytes(1)); + assert_test(buf.GetReadableSpace() == 1); unsigned char v = 0; - assert(buf.ReadByte(v)); - assert(v == 'a'); - assert(buf.GetReadableSpace() == 0); + assert_test(buf.ReadByte(v)); + assert_test(v == 'a'); + assert_test(buf.GetReadableSpace() == 0); buf.CommitRead(); - assert(buf.GetFreeSpace() == FreeSpace); // We're back to normal + assert_test(buf.GetFreeSpace() == FreeSpace); // We're back to normal } } -- cgit v1.2.3 From 4ed68916d8c0ac4b5384bbaf83088b52ca2d47d9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 10 Mar 2014 20:52:53 +0100 Subject: Revert "Fixed some warnings" This reverts commit 4cb0b82d1df560ad32c92eede91f466c75a87c87. --- src/ChunkDef.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 63431f211..7be2fa2df 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -65,8 +65,8 @@ public: enum { // Chunk dimensions: - Width = 16U, - Height = 256U, + Width = 16, + Height = 256, NumBlocks = Width * Height * Width, /// If the data is collected into a single buffer, how large it needs to be: @@ -132,7 +132,7 @@ public: } - inline static unsigned int MakeIndexNoCheck(unsigned int x, unsigned int y, unsigned int z) + inline static unsigned int MakeIndexNoCheck(int x, int y, int z) { #if AXIS_ORDER == AXIS_ORDER_XZY // For some reason, NOT using the Horner schema is faster. Weird. @@ -240,7 +240,7 @@ public: { if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1)) { - unsigned int Index = MakeIndexNoCheck(x, y, z); + int Index = MakeIndexNoCheck(x, y, z); return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f; } ASSERT(!"cChunkDef::GetNibble(): coords out of chunk range!"); @@ -256,7 +256,7 @@ public: return; } a_Buffer[a_BlockIdx / 2] = ( - (a_Buffer[a_BlockIdx / 2] & (0xf0 >> (static_cast(a_BlockIdx & 1) * 4))) | // The untouched nibble + (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set ); } @@ -282,13 +282,13 @@ public: } - inline static NIBBLETYPE GetNibble(const NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos ) + inline static char GetNibble(const NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos ) { return GetNibble(a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z ); } - inline static void SetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos, NIBBLETYPE a_Value ) + inline static void SetNibble(NIBBLETYPE * a_Buffer, const Vector3i & a_BlockPos, char a_Value ) { SetNibble( a_Buffer, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, a_Value ); } @@ -306,9 +306,6 @@ The virtual methods are called in the same order as they're declared here. class cChunkDataCallback abstract { public: - - virtual ~cChunkDataCallback() {} - /** Called before any other callbacks to inform of the current coords (only in processes where multiple chunks can be processed, such as cWorld::ForEachChunkInRect()). If false is returned, the chunk is skipped. -- cgit v1.2.3 From e9e2852ce1d7b3cdbbcc115d63f1d4d0ab25457f Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 13:12:43 -0700 Subject: Fixed test asserts --- src/ByteBuffer.cpp | 3 --- src/CompositeChat.cpp | 62 ++++++++++++++++++++++++------------------------- src/CraftingRecipes.cpp | 2 ++ src/Globals.h | 7 +++--- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index ae4e72737..9d97d8614 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -46,9 +46,6 @@ #ifdef SELF_TEST -#define assert_test(x) ( !!(x) || \ - LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), abort(1)) - /// Self-test of the VarInt-reading and writing code static class cByteBufferSelfTest { diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index 3eec35657..19ed30d78 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -32,15 +32,15 @@ public: cCompositeChat Msg; Msg.ParseText("Testing @2color codes and http://links parser"); const cCompositeChat::cParts & Parts = Msg.GetParts(); - assert(Parts.size() == 4); - assert(Parts[0]->m_PartType == cCompositeChat::ptText); - assert(Parts[1]->m_PartType == cCompositeChat::ptText); - assert(Parts[2]->m_PartType == cCompositeChat::ptUrl); - assert(Parts[3]->m_PartType == cCompositeChat::ptText); - assert(Parts[0]->m_Style == ""); - assert(Parts[1]->m_Style == "@2"); - assert(Parts[2]->m_Style == "@2"); - assert(Parts[3]->m_Style == "@2"); + assert_test(Parts.size() == 4); + assert_test(Parts[0]->m_PartType == cCompositeChat::ptText); + assert_test(Parts[1]->m_PartType == cCompositeChat::ptText); + assert_test(Parts[2]->m_PartType == cCompositeChat::ptUrl); + assert_test(Parts[3]->m_PartType == cCompositeChat::ptText); + assert_test(Parts[0]->m_Style == ""); + assert_test(Parts[1]->m_Style == "@2"); + assert_test(Parts[2]->m_Style == "@2"); + assert_test(Parts[3]->m_Style == "@2"); } void TestParser2(void) @@ -48,15 +48,15 @@ public: cCompositeChat Msg; Msg.ParseText("@3Advanced stuff: @5overriding color codes and http://links.with/@4color-in-them handling"); const cCompositeChat::cParts & Parts = Msg.GetParts(); - assert(Parts.size() == 4); - assert(Parts[0]->m_PartType == cCompositeChat::ptText); - assert(Parts[1]->m_PartType == cCompositeChat::ptText); - assert(Parts[2]->m_PartType == cCompositeChat::ptUrl); - assert(Parts[3]->m_PartType == cCompositeChat::ptText); - assert(Parts[0]->m_Style == "@3"); - assert(Parts[1]->m_Style == "@5"); - assert(Parts[2]->m_Style == "@5"); - assert(Parts[3]->m_Style == "@5"); + assert_test(Parts.size() == 4); + assert_test(Parts[0]->m_PartType == cCompositeChat::ptText); + assert_test(Parts[1]->m_PartType == cCompositeChat::ptText); + assert_test(Parts[2]->m_PartType == cCompositeChat::ptUrl); + assert_test(Parts[3]->m_PartType == cCompositeChat::ptText); + assert_test(Parts[0]->m_Style == "@3"); + assert_test(Parts[1]->m_Style == "@5"); + assert_test(Parts[2]->m_Style == "@5"); + assert_test(Parts[3]->m_Style == "@5"); } void TestParser3(void) @@ -64,11 +64,11 @@ public: cCompositeChat Msg; Msg.ParseText("http://links.starting the text"); const cCompositeChat::cParts & Parts = Msg.GetParts(); - assert(Parts.size() == 2); - assert(Parts[0]->m_PartType == cCompositeChat::ptUrl); - assert(Parts[1]->m_PartType == cCompositeChat::ptText); - assert(Parts[0]->m_Style == ""); - assert(Parts[1]->m_Style == ""); + assert_test(Parts.size() == 2); + assert_test(Parts[0]->m_PartType == cCompositeChat::ptUrl); + assert_test(Parts[1]->m_PartType == cCompositeChat::ptText); + assert_test(Parts[0]->m_Style == ""); + assert_test(Parts[1]->m_Style == ""); } void TestParser4(void) @@ -76,11 +76,11 @@ public: cCompositeChat Msg; Msg.ParseText("links finishing the text: http://some.server"); const cCompositeChat::cParts & Parts = Msg.GetParts(); - assert(Parts.size() == 2); - assert(Parts[0]->m_PartType == cCompositeChat::ptText); - assert(Parts[1]->m_PartType == cCompositeChat::ptUrl); - assert(Parts[0]->m_Style == ""); - assert(Parts[1]->m_Style == ""); + assert_test(Parts.size() == 2); + assert_test(Parts[0]->m_PartType == cCompositeChat::ptText); + assert_test(Parts[1]->m_PartType == cCompositeChat::ptUrl); + assert_test(Parts[0]->m_Style == ""); + assert_test(Parts[1]->m_Style == ""); } void TestParser5(void) @@ -88,9 +88,9 @@ public: cCompositeChat Msg; Msg.ParseText("http://only.links"); const cCompositeChat::cParts & Parts = Msg.GetParts(); - assert(Parts.size() == 1); - assert(Parts[0]->m_PartType == cCompositeChat::ptUrl); - assert(Parts[0]->m_Style == ""); + assert_test(Parts.size() == 1); + assert_test(Parts[0]->m_PartType == cCompositeChat::ptUrl); + assert_test(Parts[0]->m_Style == ""); } } gTest; diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 868182394..be9f45caa 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -192,7 +192,9 @@ void cCraftingGrid::Dump(void) { for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++) { + #ifdef _DEBUG int idx = x + m_Width * y; + #endif LOGD("Slot (%d, %d): Type %d, health %d, count %d", x, y, m_Items[idx].m_ItemType, m_Items[idx].m_ItemDamage, m_Items[idx].m_ItemCount ); diff --git a/src/Globals.h b/src/Globals.h index b046e6db0..2cd160677 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -234,9 +234,10 @@ template class SizeChecker; // Pretty much the same as ASSERT() but stays in Release builds #define VERIFY( x ) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__ ), exit(1), 0 ) ) - - - +// Same as assert but in all Self test builds +#ifdef SELF_TEST +#define assert_test(x) ( !!(x) || (assert(0), exit(1), 0)) +#endif /// A generic interface used mainly in ForEach() functions template class cItemCallback -- cgit v1.2.3 From 26d7ed661225ed092bd79c55e16134aef770ee3b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 10 Mar 2014 21:16:13 +0100 Subject: Removed debugging output. Kept it commented-out for later revisions, if needed. --- src/Generating/POCPieceGenerator.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Generating/POCPieceGenerator.cpp b/src/Generating/POCPieceGenerator.cpp index d7619b8ff..9ed4b565e 100644 --- a/src/Generating/POCPieceGenerator.cpp +++ b/src/Generating/POCPieceGenerator.cpp @@ -2,7 +2,7 @@ // POCPieceGenerator.cpp // Implements the cPOCPieceGenerator class representing a Proof-Of_Concept structure generator using the cPieceGenerator technique -// The generator generates a maze of rooms at {0, 100, 0} +// The generator generates a maze of rooms at {0, 50, 0} #include "Globals.h" #include "POCPieceGenerator.h" @@ -131,6 +131,7 @@ protected: +/* static void DebugPieces(const cPlacedPieces & a_Pieces) { size_t idx = 0; @@ -143,6 +144,7 @@ static void DebugPieces(const cPlacedPieces & a_Pieces) ); } // for itr - a_Pieces[] } +//*/ -- cgit v1.2.3 From 98e15a34a416c31d4689836f4f38161f1270513c Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 13:18:53 -0700 Subject: Fixed xofts issues --- Tools/ProtoProxy/Connection.cpp | 2 +- src/ChunkDef.h | 26 ++++++++------------------ src/StringUtils.cpp | 2 +- src/WorldStorage/FastNBT.cpp | 2 +- src/WorldStorage/FireworksSerializer.cpp | 4 ++++ 5 files changed, 15 insertions(+), 21 deletions(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index be908f303..73688d310 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -2697,7 +2697,7 @@ bool cConnection::ParseMetadata(cByteBuffer & a_Buffer, AString & a_Metadata) a_Metadata.push_back(x); while (x != 0x7f) { - //int Index = ((unsigned)((unsigned char)x)) & 0x1f; // Lower 5 bits = index + // int Index = ((unsigned)((unsigned char)x)) & 0x1f; // Lower 5 bits = index int Type = ((unsigned)((unsigned char)x)) >> 5; // Upper 3 bits = type int Length = 0; switch (Type) diff --git a/src/ChunkDef.h b/src/ChunkDef.h index a5059348c..fcda64f5c 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -124,9 +124,7 @@ public: (z < Width) && (z > -1) ) { - return MakeIndexNoCheck(static_cast(x), - static_cast(y), - static_cast(z)); + return MakeIndexNoCheck(x, y, z); } LOGERROR("cChunkDef::MakeIndex(): coords out of range: {%d, %d, %d}; returning fake index 0", x, y, z); ASSERT(!"cChunkDef::MakeIndex(): coords out of chunk range!"); @@ -134,13 +132,13 @@ public: } - inline static unsigned int MakeIndexNoCheck(unsigned int x, unsigned int y, unsigned int z) + inline static unsigned int MakeIndexNoCheck(int x, int y, int z) { #if AXIS_ORDER == AXIS_ORDER_XZY // For some reason, NOT using the Horner schema is faster. Weird. - return x + (z * cChunkDef::Width) + (y * cChunkDef::Width * cChunkDef::Width); // 1.2 is XZY + return static_cast(x + (z * cChunkDef::Width) + (y * cChunkDef::Width * cChunkDef::Width)); // 1.2 is XZY #elif AXIS_ORDER == AXIS_ORDER_YZX - return y + (z * cChunkDef::Width) + (x * cChunkDef::Height * cChunkDef::Width); // 1.1 is YZX + return static_cast(y + (z * cChunkDef::Width) + (x * cChunkDef::Height * cChunkDef::Width)); // 1.1 is YZX #endif } @@ -168,9 +166,7 @@ public: ASSERT((a_X >= 0) && (a_X < Width)); ASSERT((a_Y >= 0) && (a_Y < Height)); ASSERT((a_Z >= 0) && (a_Z < Width)); - a_BlockTypes[MakeIndexNoCheck(static_cast(a_X), - static_cast(a_Y), - static_cast(a_Z))] = a_Type; + a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)] = a_Type; } @@ -186,9 +182,7 @@ public: ASSERT((a_X >= 0) && (a_X < Width)); ASSERT((a_Y >= 0) && (a_Y < Height)); ASSERT((a_Z >= 0) && (a_Z < Width)); - return a_BlockTypes[MakeIndexNoCheck(static_cast(a_X), - static_cast(a_Y), - static_cast(a_Z))]; + return a_BlockTypes[MakeIndexNoCheck(a_X, a_Y, a_Z)]; } @@ -246,9 +240,7 @@ public: { if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1)) { - unsigned int Index = MakeIndexNoCheck(static_cast(x), - static_cast(y), - static_cast(z)); + unsigned int Index = MakeIndexNoCheck(x, y, z); return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f; } ASSERT(!"cChunkDef::GetNibble(): coords out of chunk range!"); @@ -282,9 +274,7 @@ public: return; } - unsigned int Index = MakeIndexNoCheck(static_cast(x), - static_cast(y), - static_cast(z)); + unsigned int Index = MakeIndexNoCheck(x, y, z); a_Buffer[Index / 2] = static_cast( (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 3e047fb5c..3f9275798 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -294,7 +294,7 @@ AString & RawBEToUTF8(const char * a_RawData, int a_NumShorts, AString & a_UTF8) a_UTF8.reserve(3 * a_NumShorts / 2); // a quick guess of the resulting size for (int i = 0; i < a_NumShorts; i++) { - int c = GetBEShort(a_RawData + i*2); + int c = GetBEShort(&a_RawData[i * 2]); if (c < 0x80) { a_UTF8.push_back((char)c); diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp index f1f092e0b..be25fd1a4 100644 --- a/src/WorldStorage/FastNBT.cpp +++ b/src/WorldStorage/FastNBT.cpp @@ -510,7 +510,7 @@ void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, si size_t size = m_Result.length(); if ((cap - size) < (4 + a_NumElements * 4)) { - m_Result.reserve(size +4 + a_NumElements * 4); + m_Result.reserve(size + 4 + (a_NumElements * 4)); } m_Result.append((const char *)&len, 4); for (size_t i = 0; i < a_NumElements; i++) diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index bdd5952ad..3c97ae0a2 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -91,6 +91,8 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB { // Divide by four as data length returned in bytes int DataLength = a_NBT.GetDataLength(explosiontag); + // round to the next highest multiple of four + DataLength -= DataLength % 4; if (DataLength == 0) { continue; @@ -105,6 +107,8 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB else if (ExplosionName == "FadeColors") { int DataLength = a_NBT.GetDataLength(explosiontag) / 4; + // round to the next highest multiple of four + DataLength -= DataLength % 4; if (DataLength == 0) { continue; -- cgit v1.2.3 From e4c7aac1cce39822a39da6bde28ac2066c9c0026 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 13:52:13 -0700 Subject: Prepended Travis to env vars --- .travis.yml | 8 ++++---- CMakeLists.txt | 12 +++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 14dad4df4..0ab25ae3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,10 @@ compiler: script: cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1 && make -j 2 && cd MCServer/ && (echo stop | $MCSERVER_PATH) env: - - MCSERVER_BUILD_TYPE=RELEASE MCSERVER_PATH=./MCServer - - MCSERVER_BUILD_TYPE=DEBUG MCSERVER_PATH=./MCServer_debug - - MCSERVER_BUILD_TYPE=RELEASE MCSERVER_FORCE32=1 MCSERVER_PATH=./MCServer - - MCSERVER_BUILD_TYPE=DEBUG MCSERVER_FORCE32=1 MCSERVER_PATH=./MCServer_debug + - TRAVIS_MCSERVER_BUILD_TYPE=RELEASE MCSERVER_PATH=./MCServer + - TRAVIS_MCSERVER_BUILD_TYPE=DEBUG MCSERVER_PATH=./MCServer_debug + - TRAVIS_MCSERVER_BUILD_TYPE=RELEASE TRAVIS_MCSERVER_FORCE32=1 MCSERVER_PATH=./MCServer + - TRAVIS_MCSERVER_BUILD_TYPE=DEBUG TRAVIS_MCSERVER_FORCE32=1 MCSERVER_PATH=./MCServer_debug # Notification Settings notifications: diff --git a/CMakeLists.txt b/CMakeLists.txt index e7e8daf7d..9a860920c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,13 +3,15 @@ cmake_minimum_required (VERSION 2.6) # Without this, the MSVC variable isn't defined for MSVC builds ( http://www.cmake.org/pipermail/cmake/2011-November/047130.html ) enable_language(CXX C) -if(DEFINED ENV{MCSERVER_BUILD_TYPE}) - message("Setting build type to $ENV{MCSERVER_BUILD_TYPE}") - set(CMAKE_BUILD_TYPE $ENV{MCSERVER_BUILD_TYPE}) +# These env variables are used for configuring Travis CI builds. +# See https://github.com/mc-server/MCServer/pull/767 +if(DEFINED ENV{TRAVIS_MCSERVER_BUILD_TYPE}) + message("Setting build type to $ENV{TRAVIS_MCSERVER_BUILD_TYPE}") + set(CMAKE_BUILD_TYPE $ENV{TRAVIS_MCSERVER_BUILD_TYPE}) endif() -if(DEFINED ENV{MCSERVER_FORCE32}) - set(FORCE32 $ENV{MCSERVER_FORCE32}) +if(DEFINED ENV{TRAVIS_MCSERVER_FORCE32}) + set(FORCE32 $ENV{TRAVIS_MCSERVER_FORCE32}) endif() # This has to be done before any flags have been set up. -- cgit v1.2.3 From e213e5f9fcb3681a5f383546e17b9800d4a4804a Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 11 Mar 2014 18:23:21 +0100 Subject: Renamed m_Offset to m_WEOffset --- src/BlockArea.cpp | 6 +++--- src/BlockArea.h | 5 +++-- src/WorldStorage/SchematicFileSerializer.cpp | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index dfdf998df..983dbe46b 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -168,7 +168,7 @@ cBlockArea::cBlockArea(void) : m_SizeX(0), m_SizeY(0), m_SizeZ(0), - m_Offset(0,0,0), + m_WEOffset(0, 0, 0), m_BlockTypes(NULL), m_BlockMetas(NULL), m_BlockLight(NULL), @@ -257,7 +257,7 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) void cBlockArea::SetOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ) { - m_Offset.Set(a_OffsetX, a_OffsetY, a_OffsetZ); + m_WEOffset.Set(a_OffsetX, a_OffsetY, a_OffsetZ); } @@ -266,7 +266,7 @@ void cBlockArea::SetOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ) void cBlockArea::SetOffset(const Vector3i & a_Offset) { - m_Offset.Set(a_Offset.x, a_Offset.y, a_Offset.z); + m_WEOffset.Set(a_Offset.x, a_Offset.y, a_Offset.z); } diff --git a/src/BlockArea.h b/src/BlockArea.h index 75b8db3a6..76424d02f 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -221,7 +221,7 @@ public: NIBBLETYPE GetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ) const; NIBBLETYPE GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ) const; - const Vector3i & GetOffset (void) const {return m_Offset;} + const Vector3i & GetOffset (void) const {return m_WEOffset;} void SetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); @@ -302,7 +302,8 @@ protected: int m_SizeY; int m_SizeZ; - Vector3i m_Offset; + // Used for schematics that are created by the WorldEdit plugin. The offset is used for player-relative pasting. + Vector3i m_WEOffset; BLOCKTYPE * m_BlockTypes; NIBBLETYPE * m_BlockMetas; // Each meta is stored as a separate byte for faster access diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index 0aea931eb..b899540df 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -253,9 +253,9 @@ AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockA Writer.AddByteArray("Data", Dummy.data(), Dummy.size()); } - Writer.AddInt("WEOffsetX", a_BlockArea.m_Offset.x); - Writer.AddInt("WEOffsetY", a_BlockArea.m_Offset.y); - Writer.AddInt("WEOffsetZ", a_BlockArea.m_Offset.z); + Writer.AddInt("WEOffsetX", a_BlockArea.m_WEOffset.x); + Writer.AddInt("WEOffsetY", a_BlockArea.m_WEOffset.y); + Writer.AddInt("WEOffsetZ", a_BlockArea.m_WEOffset.z); // TODO: Save entities and block entities Writer.BeginList("Entities", TAG_Compound); -- cgit v1.2.3 From fa4ff28bc04f73a2af98a0f00e536e2b5293cbf1 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 11 Mar 2014 19:38:56 +0100 Subject: Documented the functions. --- MCServer/Plugins/APIDump/APIDesc.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 1e572492b..54b2372f8 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -115,6 +115,7 @@ g_APIDesc = GetBlockType = { Params = "BlockX, BlockY, BlockZ", Return = "BLOCKTYPE", Notes = "Returns the block type at the specified absolute coords" }, GetBlockTypeMeta = { Params = "BlockX, BlockY, BlockZ", Return = "BLOCKTYPE, NIBBLETYPE", Notes = "Returns the block type and meta at the specified absolute coords" }, GetDataTypes = { Params = "", Return = "number", Notes = "Returns the mask of datatypes that the objectis currently holding" }, + GetOffset = { Params = "", Returns = "Vector3i", Notes = "Returns the offset wich are sometimes saved in schematic files if created by WorldEdit (Bukkit) for player-relative pasting. The default is 0, 0, 0"}, GetOrigin = { Params = "", Return = "OriginX, OriginY, OriginZ", Notes = "Returns the origin coords of where the area was read from." }, GetOriginX = { Params = "", Return = "number", Notes = "Returns the origin x-coord" }, GetOriginY = { Params = "", Return = "number", Notes = "Returns the origin y-coord" }, @@ -168,6 +169,11 @@ g_APIDesc = SetBlockSkyLight = { Params = "BlockX, BlockY, BlockZ, SkyLight", Return = "", Notes = "Sets the skylight at the specified absolute coords" }, SetBlockType = { Params = "BlockX, BlockY, BlockZ, BlockType", Return = "", Notes = "Sets the block type at the specified absolute coords" }, SetBlockTypeMeta = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta", Return = "", Notes = "Sets the block type and meta at the specified absolute coords" }, + SetOffset = + { + { Params = "{{Vector3i|Offset}}", Return = "", Notes = "Sets the offset of the cBlockArea. Mostly used for WorldEdit." }, + { Params = "OffsetX, OffsetY, OffsetZ", Return = "", Notes = "Sets the offset of the cBlockArea. Mostly used for WorldEdit." }, + } SetOrigin = { { Params = "{{Vector3i|Origin}}", Return = "", Notes = "Resets the origin for the absolute coords. Only affects how absolute coords are translated into relative coords." }, -- cgit v1.2.3 From 7d1e32a28b167faa6b17235283822da0cc7b2c13 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 11 Mar 2014 19:45:16 +0100 Subject: Fixed APIDump --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 54b2372f8..5d4b89425 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -173,7 +173,7 @@ g_APIDesc = { { Params = "{{Vector3i|Offset}}", Return = "", Notes = "Sets the offset of the cBlockArea. Mostly used for WorldEdit." }, { Params = "OffsetX, OffsetY, OffsetZ", Return = "", Notes = "Sets the offset of the cBlockArea. Mostly used for WorldEdit." }, - } + }, SetOrigin = { { Params = "{{Vector3i|Origin}}", Return = "", Notes = "Resets the origin for the absolute coords. Only affects how absolute coords are translated into relative coords." }, -- cgit v1.2.3 From 950614da7e700b8847f0dcc0bac9d76367801a3f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 12 Mar 2014 07:46:14 +0100 Subject: Renamed cBlockArea Offset to WEOffset. Even in getters / setters. --- src/BlockArea.cpp | 4 ++-- src/BlockArea.h | 9 +++++---- src/WorldStorage/SchematicFileSerializer.cpp | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 983dbe46b..406e18a3b 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -255,7 +255,7 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) -void cBlockArea::SetOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ) +void cBlockArea::SetWEOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ) { m_WEOffset.Set(a_OffsetX, a_OffsetY, a_OffsetZ); } @@ -264,7 +264,7 @@ void cBlockArea::SetOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ) -void cBlockArea::SetOffset(const Vector3i & a_Offset) +void cBlockArea::SetWEOffset(const Vector3i & a_Offset) { m_WEOffset.Set(a_Offset.x, a_Offset.y, a_Offset.z); } diff --git a/src/BlockArea.h b/src/BlockArea.h index 76424d02f..31918ce8c 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -209,8 +209,8 @@ public: void SetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockLight); void SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight); void SetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight); - void SetOffset (int a_OffsetX, int a_OffsetY, int a_OffsetZ); - void SetOffset (const Vector3i & a_Offset); + void SetWEOffset (int a_OffsetX, int a_OffsetY, int a_OffsetZ); + void SetWEOffset (const Vector3i & a_Offset); // Getters: BLOCKTYPE GetRelBlockType (int a_RelX, int a_RelY, int a_RelZ) const; @@ -221,7 +221,7 @@ public: NIBBLETYPE GetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ) const; NIBBLETYPE GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ) const; - const Vector3i & GetOffset (void) const {return m_WEOffset;} + const Vector3i & GetWEOffset (void) const {return m_WEOffset;} void SetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); @@ -302,7 +302,8 @@ protected: int m_SizeY; int m_SizeZ; - // Used for schematics that are created by the WorldEdit plugin. The offset is used for player-relative pasting. + /** An extra data value sometimes stored in the .schematic file. Used mainly by the WorldEdit plugin. + cBlockArea doesn't use this value in any way. */ Vector3i m_WEOffset; BLOCKTYPE * m_BlockTypes; diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index b899540df..ef67fdb13 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -189,11 +189,11 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP ) { // Not every schematic file has an offset, so we shoudn't give a warn message. - a_BlockArea.SetOffset(0, 0, 0); + a_BlockArea.SetWEOffset(0, 0, 0); } else { - a_BlockArea.SetOffset(a_NBT.GetInt(TOffsetX), a_NBT.GetInt(TOffsetY), a_NBT.GetInt(TOffsetZ)); + a_BlockArea.SetWEOffset(a_NBT.GetInt(TOffsetX), a_NBT.GetInt(TOffsetY), a_NBT.GetInt(TOffsetZ)); } // Copy the block types and metas: -- cgit v1.2.3 From 15c70a1f68ac176993b647cb0860cd190b7631d0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 12 Mar 2014 07:53:25 +0100 Subject: APIDump: Updated WEOffset-related docs. --- MCServer/Plugins/APIDump/APIDesc.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 086791006..18b90adbf 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -114,8 +114,7 @@ g_APIDesc = GetBlockSkyLight = { Params = "BlockX, BlockY, BlockZ", Return = "NIBBLETYPE", Notes = "Returns the skylight at the specified absolute coords" }, GetBlockType = { Params = "BlockX, BlockY, BlockZ", Return = "BLOCKTYPE", Notes = "Returns the block type at the specified absolute coords" }, GetBlockTypeMeta = { Params = "BlockX, BlockY, BlockZ", Return = "BLOCKTYPE, NIBBLETYPE", Notes = "Returns the block type and meta at the specified absolute coords" }, - GetDataTypes = { Params = "", Return = "number", Notes = "Returns the mask of datatypes that the objectis currently holding" }, - GetOffset = { Params = "", Returns = "Vector3i", Notes = "Returns the offset wich are sometimes saved in schematic files if created by WorldEdit (Bukkit) for player-relative pasting. The default is 0, 0, 0"}, + GetDataTypes = { Params = "", Return = "number", Notes = "Returns the mask of datatypes that the object is currently holding" }, GetOrigin = { Params = "", Return = "OriginX, OriginY, OriginZ", Notes = "Returns the origin coords of where the area was read from." }, GetOriginX = { Params = "", Return = "number", Notes = "Returns the origin x-coord" }, GetOriginY = { Params = "", Return = "number", Notes = "Returns the origin y-coord" }, @@ -130,6 +129,7 @@ g_APIDesc = GetSizeY = { Params = "", Return = "number", Notes = "Returns the size of the held data in the y-axis" }, GetSizeZ = { Params = "", Return = "number", Notes = "Returns the size of the held data in the z-axis" }, GetVolume = { Params = "", Return = "number", Notes = "Returns the volume of the area - the total number of blocks stored within." }, + GetWEOffset = { Params = "", Return = "{{Vector3i}}", Notes = "Returns the WE offset, a data value sometimes stored in the schematic files. MCServer doesn't use this value, but provides access to it using this method. The default is {0, 0, 0}."}, HasBlockLights = { Params = "", Return = "bool", Notes = "Returns true if current datatypes include blocklight" }, HasBlockMetas = { Params = "", Return = "bool", Notes = "Returns true if current datatypes include block metas" }, HasBlockSkyLights = { Params = "", Return = "bool", Notes = "Returns true if current datatypes include skylight" }, @@ -169,11 +169,6 @@ g_APIDesc = SetBlockSkyLight = { Params = "BlockX, BlockY, BlockZ, SkyLight", Return = "", Notes = "Sets the skylight at the specified absolute coords" }, SetBlockType = { Params = "BlockX, BlockY, BlockZ, BlockType", Return = "", Notes = "Sets the block type at the specified absolute coords" }, SetBlockTypeMeta = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta", Return = "", Notes = "Sets the block type and meta at the specified absolute coords" }, - SetOffset = - { - { Params = "{{Vector3i|Offset}}", Return = "", Notes = "Sets the offset of the cBlockArea. Mostly used for WorldEdit." }, - { Params = "OffsetX, OffsetY, OffsetZ", Return = "", Notes = "Sets the offset of the cBlockArea. Mostly used for WorldEdit." }, - }, SetOrigin = { { Params = "{{Vector3i|Origin}}", Return = "", Notes = "Resets the origin for the absolute coords. Only affects how absolute coords are translated into relative coords." }, @@ -184,6 +179,11 @@ g_APIDesc = SetRelBlockSkyLight = { Params = "RelBlockX, RelBlockY, RelBlockZ, SkyLight", Return = "", Notes = "Sets the skylight at the specified relative coords" }, SetRelBlockType = { Params = "RelBlockX, RelBlockY, RelBlockZ, BlockType", Return = "", Notes = "Sets the block type at the specified relative coords" }, SetRelBlockTypeMeta = { Params = "RelBlockX, RelBlockY, RelBlockZ, BlockType, BlockMeta", Return = "", Notes = "Sets the block type and meta at the specified relative coords" }, + SetWEOffset = + { + { Params = "{{Vector3i|Offset}}", Return = "", Notes = "Sets the WE offset, a data value sometimes stored in the schematic files. Mostly used for WorldEdit. MCServer doesn't use this value, but provides access to it using this method." }, + { Params = "OffsetX, OffsetY, OffsetZ", Return = "", Notes = "Sets the WE offset, a data value sometimes stored in the schematic files. Mostly used for WorldEdit. MCServer doesn't use this value, but provides access to it using this method." }, + }, Write = { { Params = "World, {{Vector3i|MinPoint}}, DataTypes", Return = "bool", Notes = "Writes the area into World at the specified coords, returns true if successful" }, -- cgit v1.2.3 From 04dcd850d6c5609bd5ecea2c60b0be0148571d61 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 11 Mar 2014 08:30:01 +0100 Subject: APIDump: Removed old documentation, documented some new functions. --- MCServer/Plugins/APIDump/APIDesc.lua | 21 +++++++++++++++------ MCServer/Plugins/APIDump/Classes/Geometry.lua | 2 ++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 18b90adbf..3c99b82de 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -423,6 +423,7 @@ g_APIDesc = SetUseDefaultFinish = { Params = "bool", Return = "", Notes = "Sets the chunk to use default finishers or not" }, SetUseDefaultHeight = { Params = "bool", Return = "", Notes = "Sets the chunk to use default height generator or not" }, SetUseDefaultStructures = { Params = "bool", Return = "", Notes = "Sets the chunk to use default structures or not" }, + UpdateHeightmap = { Params = "", Return = "", Notes = "Updates the heightmap to match current contents. The plugins should do that if they modify the contents and don't modify the heightmap accordingly; MCServer expects (and checks in Debug mode) that the heightmap matches the contents when the cChunkDesc is returned from a plugin." }, WriteBlockArea = { Params = "{{cBlockArea|BlockArea}}, MinRelX, MinRelY, MinRelZ", Return = "", Notes = "Writes data from the block area into the chunk" }, }, AdditionalInfo = @@ -472,6 +473,7 @@ end Functions = { + GetLocale = { Params = "", Return = "Locale", Notes = "Returns the locale string that the client sends as part of the protocol handshake. Can be used to provide localized strings." }, GetPing = { Params = "", Return = "number", Notes = "Returns the ping time, in ms" }, GetPlayer = { Params = "", Return = "{{cPlayer|cPlayer}}", Notes = "Returns the player object connected to this client. Note that this may be nil, for example if the player object is not yet spawned." }, GetUniqueID = { Params = "", Return = "number", Notes = "Returns the UniqueID of the client used to identify the client in the server" }, @@ -480,6 +482,7 @@ end HasPluginChannel = { Params = "ChannelName", Return = "bool", Notes = "Returns true if the client has registered to receive messages on the specified plugin channel." }, Kick = { Params = "Reason", Return = "", Notes = "Kicks the user with the specified reason" }, SendPluginMessage = { Params = "Channel, Message", Return = "", Notes = "Sends the plugin message on the specified channel." }, + SetLocale = { Params = "Locale", Return = "", Notes = "Sets the locale that MCServer keeps on record. Initially the locale is initialized in protocol handshake, this function allows plugins to override the stored value (but only server-side and only until the user disconnects)." }, SetUsername = { Params = "Name", Return = "", Notes = "Sets the username" }, SetViewDistance = { Params = "ViewDistance", Return = "", Notes = "Sets the viewdistance (number of chunks loaded for the player in each direction)" }, SendBlockChange = { Params = "BlockX, BlockY, BlockZ, BlockType, BlockMeta", Return = "", Notes = "Sends a BlockChange packet to the client. This can be used to create fake blocks only for that player." }, @@ -883,7 +886,6 @@ cFile:Delete("/usr/bin/virus.exe"); SetColor = { Return = "" }, GetColor = { Return = "string" }, AddCommand = { Return = "" }, - HasCommand = { Return = "bool" }, AddPermission = { Return = "" }, InheritFrom = { Return = "" }, }, @@ -1150,7 +1152,6 @@ These ItemGrids are available in the API and can be manipulated by the plugins, IsEnchantable = { Params = "", Return = "bool", Notes = "Returns true if the item is enchantable" }, IsFullStack = { Params = "", Return = "bool", Notes = "Returns true if the item is stacked up to its maximum stacking" }, IsSameType = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is of the same ItemType as the one stored in the object. This is true even if the two items have different enchantments" }, - IsStackableWith = { Params = "cItem", Return = "bool", Notes = "Returns true if the item in the parameter is stackable with the one stored in the object. Two items with different enchantments cannot be stacked" }, IsBothNameAndLoreEmpty = { Params = "", Return = "bool", Notes = "Returns if both the custom name and lore are not set." }, IsCustomNameEmpty = { Params = "", Return = "bool", Notes = "Returns if the custom name of the cItem is empty." }, IsLoreEmpty = { Params = "", Return = "", Notes = "Returns if the lore of the cItem is empty." }, @@ -1656,7 +1657,6 @@ a_Player:OpenWindow(Window); AddToGroup = { Params = "GroupName", Return = "", Notes = "Temporarily adds the player to the specified group. The assignment is lost when the player disconnects." }, CalcLevelFromXp = { Params = "XPAmount", Return = "number", Notes = "(STATIC) Returns the level which is reached with the specified amount of XP. Inverse of XpForLevel()." }, CanFly = { Return = "bool", Notes = "Returns if the player is able to fly." }, - CanUseCommand = { Params = "Command", Return = "bool", Notes = "Returns true if the player is allowed to use the specified command." }, CloseWindow = { Params = "[CanRefuse]", Return = "", Notes = "Closes the currently open UI window. If CanRefuse is true (default), the window may refuse the closing." }, CloseWindowIfID = { Params = "WindowID, [CanRefuse]", Return = "", Notes = "Closes the currently open UI window if its ID matches the given ID. If CanRefuse is true (default), the window may refuse the closing." }, DeltaExperience = { Params = "DeltaXP", Return = "", Notes = "Adds or removes XP from the current XP amount. Won't allow XP to go negative. Returns the new experience, -1 on error (XP overflow)." }, @@ -1733,7 +1733,6 @@ a_Player:OpenWindow(Window); SetSprint = { Params = "IsSprinting", Return = "", Notes = "Sets whether the player is sprinting or not." }, SetSprintingMaxSpeed = { Params = "SprintingMaxSpeed", Return = "", Notes = "Sets the sprinting maximum speed (as reported by the 1.6.1+ protocols)" }, SetVisible = { Params = "IsVisible", Return = "", Notes = "Sets the player visibility to other players" }, - TossItem = { Params = "DraggedItem, [Amount], [CreateType], [CreateDamage]", Return = "", Notes = "FIXME: This function will be rewritten, avoid it. It tosses an item, either from the inventory, dragged in hand (while in UI window) or a newly created one." }, XpForLevel = { Params = "XPLevel", Return = "number", Notes = "(STATIC) Returns the total amount of XP needed for the specified XP level. Inverse of CalcLevelFromXp()." }, }, Constants = @@ -2630,7 +2629,8 @@ end ]], Functions = { - AddFaceDirection = {Params = "BlockX, BlockY, BlockZ, BlockFace, [IsInverse]", Return = "BlockX, BlockY, BlockZ", Notes = "Returns the coords of a block adjacent to the specified block through the specified {{Globals#BlockFace|face}}"}, + AddFaceDirection = {Params = "BlockX, BlockY, BlockZ, BlockFace, [IsInverse]", Return = "BlockX, BlockY, BlockZ", Notes = "Returns the coords of a block adjacent to the specified block through the specified {{Globals#BlockFaces|face}}"}, + BlockFaceToString = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "string", Notes = "Returns the string representation of the {{Globals#BlockFaces|eBlockFace}} constant. Uses the axis-direction-based names, such as BLOCK_FACE_XP." }, BlockStringToType = {Params = "BlockTypeString", Return = "BLOCKTYPE", Notes = "Returns the block type parsed from the given string"}, ClickActionToString = {Params = "{{Globals#ClickAction|ClickAction}}", Return = "string", Notes = "Returns a string description of the ClickAction enumerated value"}, DamageTypeToString = {Params = "{{Globals#DamageType|DamageType}}", Return = "string", Notes = "Converts the {{Globals#DamageType|DamageType}} enumerated value to a string representation "}, @@ -2649,9 +2649,12 @@ end LOGINFO = {Params = "string", Notes = "Logs a text into the server console using 'info' severity (yellow text)"}, LOGWARN = {Params = "string", Notes = "Logs a text into the server console using 'warning' severity (red text); OBSOLETE, use LOGWARNING() instead"}, LOGWARNING = {Params = "string", Notes = "Logs a text into the server console using 'warning' severity (red text)"}, + MirrorBlockFaceY = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "{{Globals#BlockFaces|eBlockFace}}", Notes = "Returns the {{Globals#BlockFaces|eBlockFace}} that corresponds to the given {{Globals#BlockFaces|eBlockFace}} after mirroring it around the Y axis (or rotating 180 degrees around it)." }, NoCaseCompare = {Params = "string, string", Return = "number", Notes = "Case-insensitive string comparison; returns 0 if the strings are the same"}, NormalizeAngleDegrees = { Params = "AngleDegrees", Return = "AngleDegrees", Notes = "Returns the angle, wrapped into the [-180, +180) range." }, ReplaceString = {Params = "full-string, to-be-replaced-string, to-replace-string", Notes = "Replaces *each* occurence of to-be-replaced-string in full-string with to-replace-string"}, + RotateBlockFaceCCW = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "{{Globals#BlockFaces|eBlockFace}}", Notes = "Returns the {{Globals#BlockFaces|eBlockFace}} that corresponds to the given {{Globals#BlockFaces|eBlockFace}} after rotating it around the Y axis 90 degrees counter-clockwise." }, + RotateBlockFaceCW = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "{{Globals#BlockFaces|eBlockFace}}", Notes = "Returns the {{Globals#BlockFaces|eBlockFace}} that corresponds to the given {{Globals#BlockFaces|eBlockFace}} after rotating it around the Y axis 90 degrees clockwise." }, StringSplit = {Params = "string, SeperatorsString", Return = "array table of strings", Notes = "Seperates string into multiple by splitting every time any of the characters in SeperatorsString is encountered."}, StringSplitAndTrim = {Params = "string, SeperatorsString", Return = "array table of strings", Notes = "Seperates string into multiple by splitting every time any of the characters in SeperatorsString is encountered. Each of the separate strings is trimmed (whitespace removed from the beginning and end of the string)"}, StringToBiome = {Params = "string", Return = "{{Globals#BiomeTypes|BiomeType}}", Notes = "Converts a string representation to a {{Globals#BiomeTypes|BiomeType}} enumerated value"}, @@ -2698,7 +2701,13 @@ end Include = "^BLOCK_FACE_.*", TextBefore = [[ These constants are used to describe individual faces of the block. They are used when the - client is interacting with a block, or when the {{cLineBlockTracer}} hits a block, etc. + client is interacting with a block in the {{OnPlayerBreakingBlock|HOOK_PLAYER_BREAKING_BLOCK}}, + {{OnPlayerBrokenBlock|HOOK_PLAYER_BROKEN_BLOCK}}, {{OnPlayerLeftClick|HOOK_PLAYER_LEFT_CLICK}}, + {{OnPlayerPlacedBlock|HOOK_PLAYER_PLACED_BLOCK}}, {{OnPlayerPlacingBlock|HOOK_PLAYER_PLACING_BLOCK}}, + {{OnPlayerRightClick|HOOK_PLAYER_RIGHT_CLICK}}, {{OnPlayerUsedBlock|HOOK_PLAYER_USED_BLOCK}}, + {{OnPlayerUsedItem|HOOK_PLAYER_USED_ITEM}}, {{OnPlayerUsingBlock|HOOK_PLAYER_USING_BLOCK}}, + and {{OnPlayerUsingItem|HOOK_PLAYER_USING_ITEM}} hooks, or when the {{cLineBlockTracer}} hits a + block, etc. ]], }, ClickAction = diff --git a/MCServer/Plugins/APIDump/Classes/Geometry.lua b/MCServer/Plugins/APIDump/Classes/Geometry.lua index e83d6e4b1..6f95c4cbf 100644 --- a/MCServer/Plugins/APIDump/Classes/Geometry.lua +++ b/MCServer/Plugins/APIDump/Classes/Geometry.lua @@ -76,6 +76,7 @@ return DifY = { Params = "", Return = "number", Notes = "Returns the difference between the two Y coords (Y-size minus 1). Assumes sorted." }, DifZ = { Params = "", Return = "number", Notes = "Returns the difference between the two Z coords (Z-size minus 1). Assumes sorted." }, DoesIntersect = { Params = "OtherCuboid", Return = "bool", Notes = "Returns true if this cuboid has at least one voxel in common with OtherCuboid. Note that edges are considered inclusive. Assumes both sorted." }, + Engulf = { Params = "{{Vector3i|Point}}", Return = "", Notes = "If needed, expands the cuboid to include the specified point. Doesn't shrink. Assumes sorted. " }, Expand = { Params = "SubMinX, AddMaxX, SubMinY, AddMaxY, SubMinZ, AddMaxZ", Return = "", Notes = "Expands the cuboid by the specified amount in each direction. Works on unsorted cuboids as well. NOTE: this function doesn't check for underflows." }, GetVolume = { Params = "", Return = "number", Notes = "Returns the volume of the cuboid, in blocks. Note that the volume considers both coords inclusive. Works on unsorted cuboids, too." }, IsCompletelyInside = { Params = "OuterCuboid", Return = "bool", Notes = "Returns true if this cuboid is completely inside (in all directions) in OuterCuboid. Assumes both sorted." }, @@ -308,6 +309,7 @@ end }, Equals = { Params = "Vector3i", Return = "bool", Notes = "Returns true if this vector is exactly the same as the specified vector." }, Length = { Params = "", Return = "number", Notes = "Returns the (euclidean) length of this vector." }, + Move = { Params = "X, Y, Z", Return = "", Notes = "Moves the vector by the specified amount in each axis direction." }, Set = { Params = "x, y, z", Return = "", Notes = "Sets all the coords of the vector at once" }, SqrLength = { Params = "", Return = "number", Notes = "Returns the (euclidean) length of this vector, squared. This operation is slightly less computationally expensive than Length(), while it conserves some properties of Length(), such as comparison." }, }, -- cgit v1.2.3 From 541175d8a08515568d75a8d6b57bc4841e273c4a Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 11 Mar 2014 14:44:21 +0100 Subject: Using ```const Vector3i &``` --- src/BlockArea.cpp | 2 +- src/BlockArea.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 986b2ee25..dfdf998df 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -264,7 +264,7 @@ void cBlockArea::SetOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ) -void cBlockArea::SetOffset(Vector3i a_Offset) +void cBlockArea::SetOffset(const Vector3i & a_Offset) { m_Offset.Set(a_Offset.x, a_Offset.y, a_Offset.z); } diff --git a/src/BlockArea.h b/src/BlockArea.h index d89c9b372..75b8db3a6 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -210,7 +210,7 @@ public: void SetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockSkyLight); void SetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_BlockSkyLight); void SetOffset (int a_OffsetX, int a_OffsetY, int a_OffsetZ); - void SetOffset (Vector3i a_Offset); + void SetOffset (const Vector3i & a_Offset); // Getters: BLOCKTYPE GetRelBlockType (int a_RelX, int a_RelY, int a_RelZ) const; @@ -221,7 +221,7 @@ public: NIBBLETYPE GetBlockLight (int a_BlockX, int a_BlockY, int a_BlockZ) const; NIBBLETYPE GetRelBlockSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ) const; - Vector3i GetOffset (void) const {return m_Offset;} + const Vector3i & GetOffset (void) const {return m_Offset;} void SetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); -- cgit v1.2.3 From b4bf13aa4f004a7819e262679a295d8ca886557b Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 11 Mar 2014 16:01:17 +0200 Subject: Unified Vector classes --- src/Bindings/AllToLua.pkg | 10 +- src/Bindings/LuaState.h | 3 +- src/BlockArea.h | 2 +- src/BoundingBox.h | 2 +- src/CMakeLists.txt | 4 +- src/ChunkDef.h | 2 +- src/ClientHandle.cpp | 3 - src/ClientHandle.h | 2 +- src/Cuboid.h | 3 +- src/Entities/Entity.h | 4 +- src/Entities/Player.cpp | 1 + src/Globals.h | 8 ++ src/LineBlockTracer.cpp | 2 +- src/Matrix4f.h | 2 +- src/Mobs/Bat.cpp | 2 +- src/Mobs/Squid.cpp | 2 +- src/Scoreboard.h | 2 + src/Server.cpp | 2 +- src/Simulator/Simulator.cpp | 1 - src/Simulator/Simulator.h | 2 +- src/Tracer.cpp | 4 - src/Tracer.h | 3 +- src/Vector3.h | 264 ++++++++++++++++++++++++++++++++++++++++++ src/Vector3d.cpp | 77 ------------ src/Vector3d.h | 81 ------------- src/Vector3f.cpp | 34 ------ src/Vector3f.h | 47 -------- src/Vector3i.cpp | 58 ---------- src/Vector3i.h | 68 ----------- src/World.cpp | 1 - src/World.h | 3 +- src/WorldStorage/WSSCompact.h | 2 +- 32 files changed, 300 insertions(+), 401 deletions(-) create mode 100644 src/Vector3.h delete mode 100644 src/Vector3d.cpp delete mode 100644 src/Vector3d.h delete mode 100644 src/Vector3f.cpp delete mode 100644 src/Vector3f.h delete mode 100644 src/Vector3i.cpp delete mode 100644 src/Vector3i.h diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 2676281f9..302714318 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -11,6 +11,7 @@ typedef unsigned int UInt32; typedef unsigned short UInt16; +$cfile "../Vector3.h" $cfile "../ChunkDef.h" $cfile "../BiomeDef.h" @@ -62,9 +63,6 @@ $cfile "../BlockEntities/MobHeadEntity.h" $cfile "../BlockEntities/FlowerPotEntity.h" $cfile "../WebAdmin.h" $cfile "../Root.h" -$cfile "../Vector3f.h" -$cfile "../Vector3d.h" -$cfile "../Vector3i.h" $cfile "../Matrix4f.h" $cfile "../Cuboid.h" $cfile "../BoundingBox.h" @@ -97,4 +95,10 @@ typedef unsigned char Byte; +// Aliases +$renaming Vector3 @ Vector3d +$renaming Vector3 @ Vector3f +$renaming Vector3 @ Vector3i + + diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 4a7a6fadb..1156f5363 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -29,6 +29,8 @@ extern "C" #include "lua/src/lauxlib.h" } +#include "../Vector3.h" + @@ -52,7 +54,6 @@ class cWebAdmin; struct HTTPTemplateRequest; class cTNTEntity; class cCreeper; -class Vector3i; class cHopperEntity; class cBlockEntity; diff --git a/src/BlockArea.h b/src/BlockArea.h index 0703f195e..0e52a5de0 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -13,13 +13,13 @@ #pragma once #include "ForEachChunkProvider.h" +#include "Vector3.h" // fwd: class cCuboid; -class Vector3i; diff --git a/src/BoundingBox.h b/src/BoundingBox.h index 9ac5f11b8..a7c6c3eea 100644 --- a/src/BoundingBox.h +++ b/src/BoundingBox.h @@ -8,7 +8,7 @@ #pragma once -#include "Vector3d.h" +#include "Vector3.h" #include "Defines.h" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c2de26664..04736c2d7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,9 +70,7 @@ if (NOT MSVC) StringUtils.h Tracer.h UI/Window.h - Vector3d.h - Vector3f.h - Vector3i.h + Vector3.h WebAdmin.h World.h ) diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 7876c58e7..04a7f5af2 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -9,7 +9,7 @@ #pragma once -#include "Vector3i.h" +#include "Vector3.h" #include "BiomeDef.h" diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 94c9f5f71..9083d7ae0 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -22,9 +22,6 @@ #include "Blocks/BlockSlab.h" #include "Blocks/ChunkInterface.h" -#include "Vector3f.h" -#include "Vector3d.h" - #include "Root.h" #include "Authenticator.h" diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 72b1c7d09..8366caa16 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -12,7 +12,7 @@ #define CCLIENTHANDLE_H_INCLUDED #include "Defines.h" -#include "Vector3d.h" +#include "Vector3.h" #include "OSSupport/SocketThreads.h" #include "ChunkDef.h" #include "ByteBuffer.h" diff --git a/src/Cuboid.h b/src/Cuboid.h index b95517f69..b90a09e05 100644 --- a/src/Cuboid.h +++ b/src/Cuboid.h @@ -1,8 +1,7 @@ #pragma once -#include "Vector3i.h" -#include "Vector3d.h" +#include "Vector3.h" diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index b3b1cef83..a73565de7 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -2,9 +2,7 @@ #pragma once #include "../Item.h" -#include "../Vector3d.h" -#include "../Vector3f.h" -#include "../Vector3i.h" +#include "../Vector3.h" diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index ccdd151f3..440d30595 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -14,6 +14,7 @@ #include "../OSSupport/Timer.h" #include "../Chunk.h" #include "../Items/ItemHandler.h" +#include "../Vector3.h" #include "inifile/iniFile.h" #include "json/json.h" diff --git a/src/Globals.h b/src/Globals.h index 28805a83f..b8acfca64 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -246,6 +246,14 @@ T Clamp(T a_Value, T a_Min, T a_Max) +#ifndef TOLUA_TEMPLATE_BIND +#define TOLUA_TEMPLATE_BIND(x) +#endif + + + + + // Common headers (part 2, with macros): #include "ChunkDef.h" #include "BiomeDef.h" diff --git a/src/LineBlockTracer.cpp b/src/LineBlockTracer.cpp index da1c7f2fd..f4f29e833 100644 --- a/src/LineBlockTracer.cpp +++ b/src/LineBlockTracer.cpp @@ -5,7 +5,7 @@ #include "Globals.h" #include "LineBlockTracer.h" -#include "Vector3d.h" +#include "Vector3.h" #include "World.h" #include "Chunk.h" diff --git a/src/Matrix4f.h b/src/Matrix4f.h index 249c92f5f..0e36974ad 100644 --- a/src/Matrix4f.h +++ b/src/Matrix4f.h @@ -2,7 +2,7 @@ #define _USE_MATH_DEFINES #include -#include "Vector3f.h" +#include "Vector3.h" class Matrix4f { diff --git a/src/Mobs/Bat.cpp b/src/Mobs/Bat.cpp index b9c82996b..1417ddd9e 100644 --- a/src/Mobs/Bat.cpp +++ b/src/Mobs/Bat.cpp @@ -2,7 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Bat.h" -#include "../Vector3d.h" +#include "../Vector3.h" #include "../Chunk.h" diff --git a/src/Mobs/Squid.cpp b/src/Mobs/Squid.cpp index ba9171b39..bd0e141a0 100644 --- a/src/Mobs/Squid.cpp +++ b/src/Mobs/Squid.cpp @@ -2,7 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Squid.h" -#include "../Vector3d.h" +#include "../Vector3.h" #include "../Chunk.h" diff --git a/src/Scoreboard.h b/src/Scoreboard.h index e22ecaeb1..2fae5e499 100644 --- a/src/Scoreboard.h +++ b/src/Scoreboard.h @@ -150,6 +150,8 @@ public: /** Removes all registered players */ void Reset(void); + // tolua_begin + /** Returns the number of registered players */ unsigned int GetNumPlayers(void) const; diff --git a/src/Server.cpp b/src/Server.cpp index fcbcaa919..1b168ff20 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -24,7 +24,7 @@ #include "MersenneTwister.h" #include "inifile/iniFile.h" -#include "Vector3f.h" +#include "Vector3.h" #include #include diff --git a/src/Simulator/Simulator.cpp b/src/Simulator/Simulator.cpp index 06fd0f858..0739f0187 100644 --- a/src/Simulator/Simulator.cpp +++ b/src/Simulator/Simulator.cpp @@ -3,7 +3,6 @@ #include "Simulator.h" #include "../World.h" -#include "../Vector3i.h" #include "../BlockID.h" #include "../Defines.h" #include "../Chunk.h" diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h index a25b7f1b6..a2e2a5742 100644 --- a/src/Simulator/Simulator.h +++ b/src/Simulator/Simulator.h @@ -1,7 +1,7 @@ #pragma once -#include "../Vector3i.h" +#include "../Vector3.h" #include "inifile/iniFile.h" diff --git a/src/Tracer.cpp b/src/Tracer.cpp index 968a64439..6da6b2ad7 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -4,10 +4,6 @@ #include "Tracer.h" #include "World.h" -#include "Vector3f.h" -#include "Vector3i.h" -#include "Vector3d.h" - #include "Entities/Entity.h" #ifndef _WIN32 diff --git a/src/Tracer.h b/src/Tracer.h index 6c2ab6792..bdb080f0d 100644 --- a/src/Tracer.h +++ b/src/Tracer.h @@ -1,8 +1,7 @@ #pragma once -#include "Vector3i.h" -#include "Vector3f.h" +#include "Vector3.h" diff --git a/src/Vector3.h b/src/Vector3.h new file mode 100644 index 000000000..0be52248d --- /dev/null +++ b/src/Vector3.h @@ -0,0 +1,264 @@ + +#pragma once + + + + +#include + + + + + + + + + +template +// tolua_begin +class Vector3 +{ + + TOLUA_TEMPLATE_BIND((T, int, float, double)) + +public: + + T x, y, z; + + + inline Vector3() : x(0), y(0), z(0) {} + inline Vector3(T a_x, T a_y, T a_z) : x(a_x), y(a_y), z(a_z) {} + + + // tolua_end + template + Vector3(const Vector3<_T> & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {} + + template + Vector3(const Vector3<_T> * a_Rhs) : x(a_Rhs->x), y(a_Rhs->y), z(a_Rhs->z) {} + // tolua_begin + + + inline void Set(T a_x, T a_y, T a_z) + { + x = a_x; + y = a_y; + z = a_z; + } + + inline void Normalize(void) + { + T Len = 1.0 / Length(); + + x *= Len; + y *= Len; + z *= Len; + } + + inline Vector3 NormalizeCopy(void) const + { + T Len = 1.0 / Length(); + + return Vector3( + x * Len, + y * Len, + z * Len + ); + } + + inline void NormalizeCopy(Vector3 & a_Rhs) const + { + T Len = 1.0 / Length(); + + a_Rhs.Set( + x * Len, + y * Len, + z * Len + ); + } + + inline T Length(void) const + { + return sqrt(x * x + y * y + z * z); + } + + inline T SqrLength(void) const + { + return x * x + y * y + z * z; + } + + inline T Dot(const Vector3 & a_Rhs) const + { + return x * a_Rhs.x + y * a_Rhs.y + z * a_Rhs.z; + } + + inline Vector3 Cross(const Vector3 & a_Rhs) const + { + return Vector3( + y * a_Rhs.z - z * a_Rhs.y, + z * a_Rhs.x - x * a_Rhs.z, + x * a_Rhs.y - y * a_Rhs.x + ); + } + + inline bool Equals(const Vector3 & a_Rhs) const + { + return x == a_Rhs.x && y == a_Rhs.y && z == a_Rhs.z; + } + + inline bool operator < (const Vector3 & a_Rhs) + { + // return (x < a_Rhs.x) && (y < a_Rhs.y) && (z < a_Rhs.z); ? + return (x < a_Rhs.x) || (x == a_Rhs.x && y < a_Rhs.y) || (x == a_Rhs.x && y == a_Rhs.y && z < a_Rhs.z); + } + + inline void Move(T a_X, T a_Y, T a_Z) + { + x += a_X; + y += a_Y; + z += a_Z; + } + + // tolua_end + + inline void operator += (const Vector3 & a_Rhs) + { + x += a_Rhs.x; + y += a_Rhs.y; + z += a_Rhs.z; + } + + inline void operator -= (const Vector3 & a_Rhs) + { + x -= a_Rhs.x; + y -= a_Rhs.y; + z -= a_Rhs.z; + } + + inline void operator *= (const Vector3 & a_Rhs) + { + x *= a_Rhs.x; + y *= a_Rhs.y; + z *= a_Rhs.z; + } + + inline void operator *= (T a_v) + { + x *= a_v; + y *= a_v; + z *= a_v; + } + + // tolua_begin + + inline Vector3 operator + (const Vector3& a_Rhs) const + { + return Vector3( + x + a_Rhs.x, + y + a_Rhs.y, + z + a_Rhs.z + ); + } + + inline Vector3 operator - (const Vector3& a_Rhs) const + { + return Vector3( + x - a_Rhs.x, + y - a_Rhs.y, + z - a_Rhs.z + ); + } + + inline Vector3 operator * (const Vector3& a_Rhs) const + { + return Vector3( + x * a_Rhs.x, + y * a_Rhs.y, + z * a_Rhs.z + ); + } + + inline Vector3 operator * (T a_v) const + { + return Vector3( + x * a_v, + y * a_v, + z * a_v + ); + } + + inline Vector3 operator / (T a_v) const + { + return Vector3( + x / a_v, + y / a_v, + z / a_v + ); + } + + inline double LineCoeffToXYPlane(const Vector3 & a_OtherEnd, T a_Z) const + { + if (abs(z - a_OtherEnd.z) < EPS) + { + return NO_INTERSECTION; + } + + return (a_Z - z) / (a_OtherEnd.z - z); + } + + inline double LineCoeffToXZPlane(const Vector3 & a_OtherEnd, T a_Y) const + { + if (abs(y - a_OtherEnd.y) < EPS) + { + return NO_INTERSECTION; + } + + return (a_Y - y) / (a_OtherEnd.y - y); + } + + inline double LineCoeffToYZPlane(const Vector3 & a_OtherEnd, T a_X) const + { + if (abs(x - a_OtherEnd.x) < EPS) + { + return NO_INTERSECTION; + } + + return (a_X - x) / (a_OtherEnd.x - x); + } + + /** The max difference between two coords for which the coords are assumed equal. */ + static const double EPS; + + /** Return value of LineCoeffToPlane() if the line is parallel to the plane. */ + static const double NO_INTERSECTION; +}; +// tolua_end + +template +const double Vector3::EPS = 0.000001; + +template +const double Vector3::NO_INTERSECTION = 1e70; + + + + + +// tolua_begin +typedef Vector3 Vector3d; +typedef Vector3 Vector3f; +typedef Vector3 Vector3i; +// tolua_end + + + + + +typedef std::list cVector3iList; +typedef std::vector cVector3iArray; + + + + + + diff --git a/src/Vector3d.cpp b/src/Vector3d.cpp deleted file mode 100644 index 96ebebab5..000000000 --- a/src/Vector3d.cpp +++ /dev/null @@ -1,77 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Vector3d.h" -#include "Vector3f.h" - - - - - -const double Vector3d::EPS = 0.000001; ///< The max difference between two coords for which the coords are assumed equal -const double Vector3d::NO_INTERSECTION = 1e70; ///< Return value of LineCoeffToPlane() if the line is parallel to the plane - - - - - -Vector3d::Vector3d(const Vector3f & v) : - x(v.x), - y(v.y), - z(v.z) -{ -} - - - - - -Vector3d::Vector3d(const Vector3f * v) : - x(v->x), - y(v->y), - z(v->z) -{ -} - - - - - -double Vector3d::LineCoeffToXYPlane(const Vector3d & a_OtherEnd, double a_Z) const -{ - if (abs(z - a_OtherEnd.z) < EPS) - { - return NO_INTERSECTION; - } - return (a_Z - z) / (a_OtherEnd.z - z); -} - - - - - -double Vector3d::LineCoeffToXZPlane(const Vector3d & a_OtherEnd, double a_Y) const -{ - if (abs(y - a_OtherEnd.y) < EPS) - { - return NO_INTERSECTION; - } - return (a_Y - y) / (a_OtherEnd.y - y); -} - - - - - -double Vector3d::LineCoeffToYZPlane(const Vector3d & a_OtherEnd, double a_X) const -{ - if (abs(x - a_OtherEnd.x) < EPS) - { - return NO_INTERSECTION; - } - return (a_X - x) / (a_OtherEnd.x - x); -} - - - - diff --git a/src/Vector3d.h b/src/Vector3d.h deleted file mode 100644 index a06a17c09..000000000 --- a/src/Vector3d.h +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include - -class Vector3f; - - - -// tolua_begin - -class Vector3d -{ -public: - // convert from float - Vector3d(const Vector3f & v); - Vector3d(const Vector3f * v); - - Vector3d() : x(0), y(0), z(0) {} - Vector3d(double a_x, double a_y, double a_z) : x(a_x), y(a_y), z(a_z) {} - - inline void Set(double a_x, double a_y, double a_z) { x = a_x, y = a_y, z = a_z; } - inline void Normalize() { double l = 1.0f / Length(); x *= l; y *= l; z *= l; } - inline Vector3d NormalizeCopy() { double l = 1.0f / Length(); return Vector3d( x * l, y * l, z * l ); } - inline void NormalizeCopy(Vector3d & a_V) { double l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } - inline double Length() const { return (double)sqrt( x * x + y * y + z * z ); } - inline double SqrLength() const { return x * x + y * y + z * z; } - inline double Dot( const Vector3d & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } - inline Vector3d Cross( const Vector3d & v ) const { return Vector3d( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } - - /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Z coord - The result satisfies the following equation: - (*this + Result * (a_OtherEnd - *this)).z = a_Z - If the line is too close to being parallel, this function returns NO_INTERSECTION - */ - double LineCoeffToXYPlane(const Vector3d & a_OtherEnd, double a_Z) const; - - /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Y coord - The result satisfies the following equation: - (*this + Result * (a_OtherEnd - *this)).y = a_Y - If the line is too close to being parallel, this function returns NO_INTERSECTION - */ - double LineCoeffToXZPlane(const Vector3d & a_OtherEnd, double a_Y) const; - - /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified X coord - The result satisfies the following equation: - (*this + Result * (a_OtherEnd - *this)).x = a_X - If the line is too close to being parallel, this function returns NO_INTERSECTION - */ - double LineCoeffToYZPlane(const Vector3d & a_OtherEnd, double a_X) const; - - inline bool Equals(const Vector3d & v) const { return ((x == v.x) && (y == v.y) && (z == v.z)); } - - // tolua_end - - void operator += ( const Vector3d& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } - void operator += ( Vector3d* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } - void operator -= ( const Vector3d& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } - void operator -= ( Vector3d* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } - void operator *= ( double a_f ) { x *= a_f; y *= a_f; z *= a_f; } - - // tolua_begin - - Vector3d operator + (const Vector3d & v2) const { return Vector3d(x + v2.x, y + v2.y, z + v2.z ); } - Vector3d operator + (const Vector3d * v2) const { return Vector3d(x + v2->x, y + v2->y, z + v2->z ); } - Vector3d operator - (const Vector3d & v2) const { return Vector3d(x - v2.x, y - v2.y, z - v2.z ); } - Vector3d operator - (const Vector3d * v2) const { return Vector3d(x - v2->x, y - v2->y, z - v2->z ); } - Vector3d operator * (const double f) const { return Vector3d(x * f, y * f, z * f ); } - Vector3d operator * (const Vector3d & v2) const { return Vector3d(x * v2.x, y * v2.y, z * v2.z ); } - Vector3d operator / (const double f) const { return Vector3d(x / f, y / f, z / f ); } - - double x, y, z; - - static const double EPS; ///< The max difference between two coords for which the coords are assumed equal - static const double NO_INTERSECTION; ///< Return value of LineCoeffToPlane() if the line is parallel to the plane -} ; - -// tolua_end - - - - diff --git a/src/Vector3f.cpp b/src/Vector3f.cpp deleted file mode 100644 index 59d71d371..000000000 --- a/src/Vector3f.cpp +++ /dev/null @@ -1,34 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Vector3f.h" -#include "Vector3d.h" -#include "Vector3i.h" - -Vector3f::Vector3f( const Vector3d & v ) - : x( (float)v.x ) - , y( (float)v.y ) - , z( (float)v.z ) -{ -} - -Vector3f::Vector3f( const Vector3d * v ) - : x( (float)v->x ) - , y( (float)v->y ) - , z( (float)v->z ) -{ -} - -Vector3f::Vector3f( const Vector3i & v ) - : x( (float)v.x ) - , y( (float)v.y ) - , z( (float)v.z ) -{ -} - -Vector3f::Vector3f( const Vector3i * v ) - : x( (float)v->x ) - , y( (float)v->y ) - , z( (float)v->z ) -{ -} \ No newline at end of file diff --git a/src/Vector3f.h b/src/Vector3f.h deleted file mode 100644 index adb154ad7..000000000 --- a/src/Vector3f.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include - -class Vector3i; -class Vector3d; -class Vector3f // tolua_export -{ // tolua_export -public: // tolua_export - Vector3f( const Vector3d & v ); // tolua_export - Vector3f( const Vector3d * v ); // tolua_export - Vector3f( const Vector3i & v ); // tolua_export - Vector3f( const Vector3i * v ); // tolua_export - - - Vector3f() : x(0), y(0), z(0) {} // tolua_export - Vector3f(float a_x, float a_y, float a_z) : x(a_x), y(a_y), z(a_z) {} // tolua_export - - inline void Set(float a_x, float a_y, float a_z) { x = a_x, y = a_y, z = a_z; } // tolua_export - inline void Normalize() { float l = 1.0f / Length(); x *= l; y *= l; z *= l; } // tolua_export - inline Vector3f NormalizeCopy() const { float l = 1.0f / Length(); return Vector3f( x * l, y * l, z * l ); }// tolua_export - inline void NormalizeCopy(Vector3f & a_V) const { float l = 1.0f / Length(); a_V.Set(x*l, y*l, z*l ); } // tolua_export - inline float Length() const { return (float)sqrtf( x * x + y * y + z * z ); } // tolua_export - inline float SqrLength() const { return x * x + y * y + z * z; } // tolua_export - inline float Dot( const Vector3f & a_V ) const { return x * a_V.x + y * a_V.y + z * a_V.z; } // tolua_export - inline Vector3f Cross( const Vector3f & v ) const { return Vector3f( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } // tolua_export - - inline bool Equals( const Vector3f & v ) const { return (x == v.x && y == v.y && z == v.z ); } // tolua_export - - void operator += ( const Vector3f& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } - void operator += ( Vector3f* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } - void operator -= ( const Vector3f& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } - void operator -= ( Vector3f* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } - void operator *= ( float a_f ) { x *= a_f; y *= a_f; z *= a_f; } - void operator *= ( Vector3f* a_V ) { x *= a_V->x; y *= a_V->y; z *= a_V->z; } - void operator *= ( const Vector3f& a_V ) { x *= a_V.x; y *= a_V.y; z *= a_V.z; } - - Vector3f operator + ( const Vector3f& v2 ) const { return Vector3f( x + v2.x, y + v2.y, z + v2.z ); } // tolua_export - Vector3f operator + ( const Vector3f* v2 ) const { return Vector3f( x + v2->x, y + v2->y, z + v2->z ); } // tolua_export - Vector3f operator - ( const Vector3f& v2 ) const { return Vector3f( x - v2.x, y - v2.y, z - v2.z ); } // tolua_export - Vector3f operator - ( const Vector3f* v2 ) const { return Vector3f( x - v2->x, y - v2->y, z - v2->z ); } // tolua_export - Vector3f operator * ( const float f ) const { return Vector3f( x * f, y * f, z * f ); } // tolua_export - Vector3f operator * ( const Vector3f& v2 ) const { return Vector3f( x * v2.x, y * v2.y, z * v2.z ); } // tolua_export - - float x, y, z; // tolua_export - -};// tolua_export diff --git a/src/Vector3i.cpp b/src/Vector3i.cpp deleted file mode 100644 index 2106aea6d..000000000 --- a/src/Vector3i.cpp +++ /dev/null @@ -1,58 +0,0 @@ - -// Vector3i.cpp - -// Implements the Vector3i class representing an int-based 3D vector - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "math.h" -#include "Vector3i.h" -#include "Vector3d.h" - - - - - -Vector3i::Vector3i(const Vector3d & v) : - x((int)v.x), - y((int)v.y), - z((int)v.z) -{ -} - - - - - -Vector3i::Vector3i(void) : - x(0), - y(0), - z(0) -{ -} - - - - - -Vector3i::Vector3i(int a_x, int a_y, int a_z) : - x(a_x), - y(a_y), - z(a_z) -{ -} - - - - - -void Vector3i::Move(int a_MoveX, int a_MoveY, int a_MoveZ) -{ - x += a_MoveX; - y += a_MoveY; - z += a_MoveZ; -} - - - - diff --git a/src/Vector3i.h b/src/Vector3i.h deleted file mode 100644 index 39e138683..000000000 --- a/src/Vector3i.h +++ /dev/null @@ -1,68 +0,0 @@ - -// Vector3i.h - -// Declares the Vector3i class representing an int-based 3D vector - - - - - -#pragma once - - - - - -// fwd: -class Vector3d; - - - - - -// tolua_begin -class Vector3i -{ -public: - /** Creates an int vector based on the floor()-ed coords of a double vector. */ - Vector3i(const Vector3d & v); - - Vector3i(void); - Vector3i(int a_x, int a_y, int a_z); - - inline void Set(int a_x, int a_y, int a_z) { x = a_x, y = a_y, z = a_z; } - inline float Length() const { return sqrtf( (float)( x * x + y * y + z * z) ); } - inline int SqrLength() const { return x * x + y * y + z * z; } - - inline bool Equals( const Vector3i & v ) const { return (x == v.x && y == v.y && z == v.z ); } - inline bool Equals( const Vector3i * v ) const { return (x == v->x && y == v->y && z == v->z ); } - - void Move(int a_MoveX, int a_MoveY, int a_MoveZ); - - // tolua_end - - void operator += ( const Vector3i& a_V ) { x += a_V.x; y += a_V.y; z += a_V.z; } - void operator += ( Vector3i* a_V ) { x += a_V->x; y += a_V->y; z += a_V->z; } - void operator -= ( const Vector3i& a_V ) { x -= a_V.x; y -= a_V.y; z -= a_V.z; } - void operator -= ( Vector3i* a_V ) { x -= a_V->x; y -= a_V->y; z -= a_V->z; } - void operator *= ( int a_f ) { x *= a_f; y *= a_f; z *= a_f; } - - friend Vector3i operator + ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z ); } - friend Vector3i operator + ( const Vector3i& v1, Vector3i* v2 ) { return Vector3i( v1.x + v2->x, v1.y + v2->y, v1.z + v2->z ); } - friend Vector3i operator - ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z ); } - friend Vector3i operator - ( const Vector3i& v1, Vector3i* v2 ) { return Vector3i( v1.x - v2->x, v1.y - v2->y, v1.z - v2->z ); } - friend Vector3i operator - ( const Vector3i* v1, Vector3i& v2 ) { return Vector3i( v1->x - v2.x, v1->y - v2.y, v1->z - v2.z ); } - friend Vector3i operator * ( const Vector3i& v, const int f ) { return Vector3i( v.x * f, v.y * f, v.z * f ); } - friend Vector3i operator * ( const Vector3i& v1, const Vector3i& v2 ) { return Vector3i( v1.x * v2.x, v1.y * v2.y, v1.z * v2.z ); } - friend Vector3i operator * ( const int f, const Vector3i& v ) { return Vector3i( v.x * f, v.y * f, v.z * f ); } - friend bool operator < ( const Vector3i& v1, const Vector3i& v2 ) { return (v1.x cVector3iList; -typedef std::vector cVector3iArray; - - - - diff --git a/src/World.cpp b/src/World.cpp index a9db6bf00..3d01dc40f 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -46,7 +46,6 @@ #include "Generating/Trees.h" #include "Bindings/PluginManager.h" #include "Blocks/BlockHandler.h" -#include "Vector3d.h" #include "Tracer.h" diff --git a/src/World.h b/src/World.h index d48db5911..a772710ab 100644 --- a/src/World.h +++ b/src/World.h @@ -14,8 +14,7 @@ #include "ChunkMap.h" #include "WorldStorage/WorldStorage.h" #include "Generating/ChunkGenerator.h" -#include "Vector3i.h" -#include "Vector3f.h" +#include "Vector3.h" #include "ChunkSender.h" #include "Defines.h" #include "LightingThread.h" diff --git a/src/WorldStorage/WSSCompact.h b/src/WorldStorage/WSSCompact.h index 64b8d7f31..4df146ec3 100644 --- a/src/WorldStorage/WSSCompact.h +++ b/src/WorldStorage/WSSCompact.h @@ -12,7 +12,7 @@ #define WSSCOMPACT_H_INCLUDED #include "WorldStorage.h" -#include "../Vector3i.h" +#include "../Vector3.h" #include "json/json.h" -- cgit v1.2.3 From deafec874d87b5b1ef0dd7fb094fd7b38634a0db Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 11 Mar 2014 15:14:47 +0100 Subject: Snowballs now actualy hurt other entities. 3 damage for blazes and 1 for the ender dragon. Otherwise 0 --- src/Entities/ProjectileEntity.cpp | 26 ++++++++++++++++++++++++-- src/Entities/ProjectileEntity.h | 1 + 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 03bc0c99d..92890919c 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -655,8 +655,6 @@ cThrownSnowballEntity::cThrownSnowballEntity(cEntity * a_Creator, double a_X, do void cThrownSnowballEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) { - // TODO: Apply damage to certain mobs (blaze etc.) and anger all mobs - Destroy(); } @@ -664,6 +662,30 @@ void cThrownSnowballEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFac +void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) +{ + int TotalDamage = 0; + if (a_EntityHit.IsMob()) + { + cMonster::eType MobType = ((cMonster &) a_EntityHit).GetMobType(); + if (MobType == cMonster::mtBlaze) + { + TotalDamage = 3; + } + else if (MobType == cMonster::mtEnderDragon) + { + TotalDamage = 1; + } + } + a_EntityHit.TakeDamage(dtRangedAttack, m_Creator, TotalDamage, 1); + + Destroy(true); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cBottleOEnchantingEntity : diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index e80592999..840dac871 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -259,6 +259,7 @@ protected: // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; + virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override; // tolua_begin -- cgit v1.2.3 From ef3c5a97a46212a0f8cd1a05125f4b75e3f32b74 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 11 Mar 2014 16:24:05 +0100 Subject: TakeDamage now has the cThrownSnowballEntity instead of the creator's object. --- src/Entities/ProjectileEntity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 92890919c..37238a0c0 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -677,7 +677,7 @@ void cThrownSnowballEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & TotalDamage = 1; } } - a_EntityHit.TakeDamage(dtRangedAttack, m_Creator, TotalDamage, 1); + a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1); Destroy(true); } -- cgit v1.2.3 From d64db443c2d0f094c4ee098fa1ffacb2c92e5d88 Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 11 Mar 2014 18:10:15 +0200 Subject: LineCoeff Doc --- src/Vector3.h | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Vector3.h b/src/Vector3.h index 0be52248d..8ee7a87b0 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -10,10 +10,6 @@ - - - - template // tolua_begin class Vector3 @@ -196,6 +192,11 @@ public: ); } + /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Z coord. + The result satisfies the following equation: + (*this + Result * (a_OtherEnd - *this)).z = a_Z + If the line is too close to being parallel, this function returns NO_INTERSECTION + */ inline double LineCoeffToXYPlane(const Vector3 & a_OtherEnd, T a_Z) const { if (abs(z - a_OtherEnd.z) < EPS) @@ -206,6 +207,11 @@ public: return (a_Z - z) / (a_OtherEnd.z - z); } + /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Y coord. + The result satisfies the following equation: + (*this + Result * (a_OtherEnd - *this)).y = a_Y + If the line is too close to being parallel, this function returns NO_INTERSECTION + */ inline double LineCoeffToXZPlane(const Vector3 & a_OtherEnd, T a_Y) const { if (abs(y - a_OtherEnd.y) < EPS) @@ -216,6 +222,11 @@ public: return (a_Y - y) / (a_OtherEnd.y - y); } + /** Returns the coefficient for the (a_OtherEnd - this) line to reach the specified X coord. + The result satisfies the following equation: + (*this + Result * (a_OtherEnd - *this)).x = a_X + If the line is too close to being parallel, this function returns NO_INTERSECTION + */ inline double LineCoeffToYZPlane(const Vector3 & a_OtherEnd, T a_X) const { if (abs(x - a_OtherEnd.x) < EPS) @@ -231,9 +242,14 @@ public: /** Return value of LineCoeffToPlane() if the line is parallel to the plane. */ static const double NO_INTERSECTION; + }; // tolua_end + + + + template const double Vector3::EPS = 0.000001; -- cgit v1.2.3 From 9810d57a394b2bb56fbcfddb05d34dcd504a7b35 Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 11 Mar 2014 18:32:33 +0200 Subject: Unified Matrix4 code --- src/Bindings/AllToLua.pkg | 1 - src/CMakeLists.txt | 1 - src/Entities/Entity.cpp | 2 +- src/Matrix4.h | 228 ++++++++++++++++++++++++++++++++++++++++++++++ src/Matrix4f.cpp | 4 - src/Matrix4f.h | 225 --------------------------------------------- src/Vector3.h | 2 +- 7 files changed, 230 insertions(+), 233 deletions(-) create mode 100644 src/Matrix4.h delete mode 100644 src/Matrix4f.cpp delete mode 100644 src/Matrix4f.h diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 302714318..1cd7c74f8 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -63,7 +63,6 @@ $cfile "../BlockEntities/MobHeadEntity.h" $cfile "../BlockEntities/FlowerPotEntity.h" $cfile "../WebAdmin.h" $cfile "../Root.h" -$cfile "../Matrix4f.h" $cfile "../Cuboid.h" $cfile "../BoundingBox.h" $cfile "../Tracer.h" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 04736c2d7..0f8700692 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -62,7 +62,6 @@ if (NOT MSVC) Inventory.h Item.h ItemGrid.h - Matrix4f.h Mobs/Monster.h OSSupport/File.h Root.h diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 96e8c15a5..0750ae05e 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -4,7 +4,7 @@ #include "../World.h" #include "../Server.h" #include "../Root.h" -#include "../Matrix4f.h" +#include "../Matrix4.h" #include "../ClientHandle.h" #include "../Chunk.h" #include "../Simulator/FluidSimulator.h" diff --git a/src/Matrix4.h b/src/Matrix4.h new file mode 100644 index 000000000..14ccb94fd --- /dev/null +++ b/src/Matrix4.h @@ -0,0 +1,228 @@ + +#pragma once + + + + +#include + + + + + +template +// tolua_begin +class Matrix4 +{ + + TOLUA_TEMPLATE_BIND((T, float, double)) + + // tolua_end + +public: + + T cell[16]; + + enum + { + TX=3, TY=7, TZ=11, + D0=0, D1=5, D2=10, D3=15, + SX=D0, SY=D1, SZ=D2, + W=D3 + }; + + // tolua_begin + + inline Matrix4(void) + { + Identity(); + } + + inline Matrix4(const Matrix4 & a_Rhs) + { + *this = a_Rhs; + } + + inline Matrix4 & operator = (const Matrix4 & a_Rhs) + { + for (unsigned int i = 0; i < 16; ++i) + { + cell[i] = a_Rhs.cell[i]; + } + return *this; + } + + inline T & operator [] (int a_N) + { + ASSERT(a_N < 16); + return cell[a_N]; + } + + inline void Identity() + { + cell[1] = cell[2] = cell[TX] = cell[4] = cell[6] = cell[TY] = + cell[8] = cell[9] = cell[TZ] = cell[12] = cell[13] = cell[14] = 0; + cell[D0] = cell[D1] = cell[D2] = cell[W] = 1; + } + + inline void Init(const Vector3 & a_Pos, T a_RX, T a_RY, T a_RZ) + { + Matrix4 t; + t.RotateX(a_RZ); + RotateY(a_RY); + Concatenate(t); + t.RotateZ(a_RX); + Concatenate(t); + Translate(a_Pos); + } + + inline void RotateX(T a_RX) + { + T sx = (T) sin(a_RX * M_PI / 180); + T cx = (T) cos(a_RX * M_PI / 180); + + Identity(); + + cell[5] = cx, cell[6] = sx, cell[9] = -sx, cell[10] = cx; + } + + inline void RotateY(T a_RY) + { + T sy = (T) sin(a_RY * M_PI / 180); + T cy = (T) cos(a_RY * M_PI / 180); + + Identity(); + + cell[0] = cy, cell[2] = -sy, cell[8] = sy, cell[10] = cy; + } + + inline void RotateZ(T a_RZ) + { + T sz = (T) sin(a_RZ * M_PI / 180); + T cz = (T) cos(a_RZ * M_PI / 180); + + Identity(); + + cell[0] = cz; cell[1] = sz; + cell[4] = -sz; cell[5] = cz; + } + + inline void Translate(const Vector3 & a_Pos) + { + cell[TX] += a_Pos.x; + cell[TY] += a_Pos.y; + cell[TZ] += a_Pos.z; + } + + inline void SetTranslation(const Vector3 & a_Pos) + { + cell[TX] = a_Pos.x; + cell[TY] = a_Pos.y; + cell[TZ] = a_Pos.z; + } + + inline void Concatenate(const Matrix4 & m2) + { + Matrix4 res; + + for (unsigned int c = 0; c < 4; ++c) + { + for (unsigned int r = 0; r < 4; ++r) + { + res.cell[r * 4 + c] = ( + cell[r * 4] * m2.cell[c] + + cell[r * 4 + 1] * m2.cell[c + 4] + + cell[r * 4 + 2] * m2.cell[c + 8] + + cell[r * 4 + 3] * m2.cell[c + 12] + ); + } + } + + *this = res; + } + + inline Vector3 Transform(const Vector3 & v) const + { + T x = cell[0] * v.x + cell[1] * v.y + cell[2] * v.z + cell[3]; + T y = cell[4] * v.x + cell[5] * v.y + cell[6] * v.z + cell[7]; + T z = cell[8] * v.x + cell[9] * v.y + cell[10] * v.z + cell[11]; + + return Vector3(x, y, z); + } + + inline void Invert(void) + { + Matrix4 t; + + T tx = -cell[3]; + T ty = -cell[7]; + T tz = -cell[11]; + + for (unsigned int h = 0; h < 3; ++h) + { + for (unsigned int v = 0; v < 3; ++v) + { + t.cell[h + v * 4] = cell[v + h * 4]; + } + } + + for (unsigned int i = 0; i < 11; ++i) + { + cell[i] = t.cell[i]; + } + + cell[3] = tx * cell[0] + ty * cell[1] + tz * cell[2]; + cell[7] = tx * cell[4] + ty * cell[5] + tz * cell[6]; + cell[11] = tx * cell[8] + ty * cell[9] + tz * cell[10]; + } + + inline Vector3 GetXColumn(void) const + { + return Vector3(cell[0], cell[1], cell[2]); + } + + inline Vector3 GetYColumn(void) const + { + return Vector3(cell[4], cell[5], cell[6]); + } + + inline Vector3 GetZColumn(void) const + { + return Vector3(cell[8], cell[9], cell[10]); + } + + inline void SetXColumn(const Vector3 & a_X) + { + cell[0] = a_X.x; + cell[1] = a_X.y; + cell[2] = a_X.z; + } + + inline void SetYColumn(const Vector3 & a_Y) + { + cell[4] = a_Y.x; + cell[5] = a_Y.y; + cell[6] = a_Y.z; + } + + inline void SetZColumn(const Vector3 & a_Z) + { + cell[8] = a_Z.x; + cell[9] = a_Z.y; + cell[10] = a_Z.z; + } +}; +// tolua_end + + + + +// tolua_begin +typedef Matrix4 Matrix4d; +typedef Matrix4 Matrix4f; +// tolua_end + + + + + diff --git a/src/Matrix4f.cpp b/src/Matrix4f.cpp deleted file mode 100644 index d0a407a99..000000000 --- a/src/Matrix4f.cpp +++ /dev/null @@ -1,4 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -// _X: empty file?? diff --git a/src/Matrix4f.h b/src/Matrix4f.h deleted file mode 100644 index 0e36974ad..000000000 --- a/src/Matrix4f.h +++ /dev/null @@ -1,225 +0,0 @@ -#pragma once - -#define _USE_MATH_DEFINES -#include -#include "Vector3.h" - -class Matrix4f -{ -public: - enum - { - TX=3, - TY=7, - TZ=11, - D0=0, D1=5, D2=10, D3=15, - SX=D0, SY=D1, SZ=D2, - W=D3 - }; - Matrix4f() { Identity(); } - float& operator [] ( int a_N ) { return cell[a_N]; } - void Identity() - { - cell[1] = cell[2] = cell[TX] = cell[4] = cell[6] = cell[TY] = - cell[8] = cell[9] = cell[TZ] = cell[12] = cell[13] = cell[14] = 0; - cell[D0] = cell[D1] = cell[D2] = cell[W] = 1; - } - void Init( Vector3f a_Pos, float a_RX, float a_RY, float a_RZ ) - { - Matrix4f t; - t.RotateX( a_RZ ); - RotateY( a_RY ); - Concatenate( t ); - t.RotateZ( a_RX ); - Concatenate( t ); - Translate( a_Pos ); - } - void RotateX( float a_RX ) - { - float sx = (float)sin( a_RX * M_PI / 180 ); - float cx = (float)cos( a_RX * M_PI / 180 ); - Identity(); - cell[5] = cx, cell[6] = sx, cell[9] = -sx, cell[10] = cx; - } - void RotateY( float a_RY ) - { - float sy = (float)sin( a_RY * M_PI / 180 ); - float cy = (float)cos( a_RY * M_PI / 180 ); - Identity (); - cell[0] = cy, cell[2] = -sy, cell[8] = sy, cell[10] = cy; - } - void RotateZ( float a_RZ ) - { - float sz = (float)sin( a_RZ * M_PI / 180 ); - float cz = (float)cos( a_RZ * M_PI / 180 ); - Identity (); - cell[0] = cz, cell[1] = sz, cell[4] = -sz, cell[5] = cz; - } - void Translate( Vector3f a_Pos ) { cell[TX] += a_Pos.x; cell[TY] += a_Pos.y; cell[TZ] += a_Pos.z; } - void SetTranslation( Vector3f a_Pos ) { cell[TX] = a_Pos.x; cell[TY] = a_Pos.y; cell[TZ] = a_Pos.z; } - void Concatenate( const Matrix4f& m2 ) - { - Matrix4f res; - int c; - for ( c = 0; c < 4; c++ ) for ( int r = 0; r < 4; r++ ) - res.cell[r * 4 + c] = cell[r * 4] * m2.cell[c] + - cell[r * 4 + 1] * m2.cell[c + 4] + - cell[r * 4 + 2] * m2.cell[c + 8] + - cell[r * 4 + 3] * m2.cell[c + 12]; - for ( c = 0; c < 16; c++ ) cell[c] = res.cell[c]; - } - Vector3f Transform( const Vector3f& v ) const - { - float x = cell[0] * v.x + cell[1] * v.y + cell[2] * v.z + cell[3]; - float y = cell[4] * v.x + cell[5] * v.y + cell[6] * v.z + cell[7]; - float z = cell[8] * v.x + cell[9] * v.y + cell[10] * v.z + cell[11]; - return Vector3f( x, y, z ); - } - void Invert() - { - Matrix4f t; - int h, i; - float tx = -cell[3], ty = -cell[7], tz = -cell[11]; - for ( h = 0; h < 3; h++ ) for ( int v = 0; v < 3; v++ ) t.cell[h + v * 4] = cell[v + h * 4]; - for ( i = 0; i < 11; i++ ) cell[i] = t.cell[i]; - cell[3] = tx * cell[0] + ty * cell[1] + tz * cell[2]; - cell[7] = tx * cell[4] + ty * cell[5] + tz * cell[6]; - cell[11] = tx * cell[8] + ty * cell[9] + tz * cell[10]; - } - Vector3f GetXColumn() { return Vector3f( cell[0], cell[1], cell[2] ); } - Vector3f GetYColumn() { return Vector3f( cell[4], cell[5], cell[6] ); } - Vector3f GetZColumn() { return Vector3f( cell[8], cell[9], cell[10] ); } - void SetXColumn( const Vector3f & a_X ) - { - cell[0] = a_X.x; - cell[1] = a_X.y; - cell[2] = a_X.z; - } - void SetYColumn( const Vector3f & a_Y ) - { - cell[4] = a_Y.x; - cell[5] = a_Y.y; - cell[6] = a_Y.z; - } - void SetZColumn( const Vector3f & a_Z ) - { - cell[8] = a_Z.x; - cell[9] = a_Z.y; - cell[10] = a_Z.z; - } - float cell[16]; -}; - - - - - -class Matrix4d -{ -public: - enum - { - TX=3, - TY=7, - TZ=11, - D0=0, D1=5, D2=10, D3=15, - SX=D0, SY=D1, SZ=D2, - W=D3 - }; - Matrix4d() { Identity(); } - double& operator [] ( int a_N ) { return cell[a_N]; } - void Identity() - { - cell[1] = cell[2] = cell[TX] = cell[4] = cell[6] = cell[TY] = - cell[8] = cell[9] = cell[TZ] = cell[12] = cell[13] = cell[14] = 0; - cell[D0] = cell[D1] = cell[D2] = cell[W] = 1; - } - void Init( Vector3f a_Pos, double a_RX, double a_RY, double a_RZ ) - { - Matrix4d t; - t.RotateX( a_RZ ); - RotateY( a_RY ); - Concatenate( t ); - t.RotateZ( a_RX ); - Concatenate( t ); - Translate( a_Pos ); - } - void RotateX( double a_RX ) - { - double sx = (double)sin( a_RX * M_PI / 180 ); - double cx = (double)cos( a_RX * M_PI / 180 ); - Identity(); - cell[5] = cx, cell[6] = sx, cell[9] = -sx, cell[10] = cx; - } - void RotateY( double a_RY ) - { - double sy = (double)sin( a_RY * M_PI / 180 ); - double cy = (double)cos( a_RY * M_PI / 180 ); - Identity (); - cell[0] = cy, cell[2] = -sy, cell[8] = sy, cell[10] = cy; - } - void RotateZ( double a_RZ ) - { - double sz = (double)sin( a_RZ * M_PI / 180 ); - double cz = (double)cos( a_RZ * M_PI / 180 ); - Identity (); - cell[0] = cz, cell[1] = sz, cell[4] = -sz, cell[5] = cz; - } - void Translate( Vector3d a_Pos ) { cell[TX] += a_Pos.x; cell[TY] += a_Pos.y; cell[TZ] += a_Pos.z; } - void SetTranslation( Vector3d a_Pos ) { cell[TX] = a_Pos.x; cell[TY] = a_Pos.y; cell[TZ] = a_Pos.z; } - void Concatenate( const Matrix4d & m2 ) - { - Matrix4d res; - int c; - for ( c = 0; c < 4; c++ ) for ( int r = 0; r < 4; r++ ) - res.cell[r * 4 + c] = cell[r * 4] * m2.cell[c] + - cell[r * 4 + 1] * m2.cell[c + 4] + - cell[r * 4 + 2] * m2.cell[c + 8] + - cell[r * 4 + 3] * m2.cell[c + 12]; - for ( c = 0; c < 16; c++ ) cell[c] = res.cell[c]; - } - Vector3d Transform( const Vector3d & v ) const - { - double x = cell[0] * v.x + cell[1] * v.y + cell[2] * v.z + cell[3]; - double y = cell[4] * v.x + cell[5] * v.y + cell[6] * v.z + cell[7]; - double z = cell[8] * v.x + cell[9] * v.y + cell[10] * v.z + cell[11]; - return Vector3d( x, y, z ); - } - void Invert() - { - Matrix4d t; - int h, i; - double tx = -cell[3], ty = -cell[7], tz = -cell[11]; - for ( h = 0; h < 3; h++ ) for ( int v = 0; v < 3; v++ ) t.cell[h + v * 4] = cell[v + h * 4]; - for ( i = 0; i < 11; i++ ) cell[i] = t.cell[i]; - cell[3] = tx * cell[0] + ty * cell[1] + tz * cell[2]; - cell[7] = tx * cell[4] + ty * cell[5] + tz * cell[6]; - cell[11] = tx * cell[8] + ty * cell[9] + tz * cell[10]; - } - Vector3d GetXColumn() { return Vector3d( cell[0], cell[1], cell[2] ); } - Vector3d GetYColumn() { return Vector3d( cell[4], cell[5], cell[6] ); } - Vector3d GetZColumn() { return Vector3d( cell[8], cell[9], cell[10] ); } - void SetXColumn( const Vector3d & a_X ) - { - cell[0] = a_X.x; - cell[1] = a_X.y; - cell[2] = a_X.z; - } - void SetYColumn( const Vector3d & a_Y ) - { - cell[4] = a_Y.x; - cell[5] = a_Y.y; - cell[6] = a_Y.z; - } - void SetZColumn( const Vector3d & a_Z ) - { - cell[8] = a_Z.x; - cell[9] = a_Z.y; - cell[10] = a_Z.z; - } - double cell[16]; -} ; - - - - diff --git a/src/Vector3.h b/src/Vector3.h index 8ee7a87b0..841c3e7d1 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -22,7 +22,7 @@ public: T x, y, z; - inline Vector3() : x(0), y(0), z(0) {} + inline Vector3(void) : x(0), y(0), z(0) {} inline Vector3(T a_x, T a_y, T a_z) : x(a_x), y(a_y), z(a_z) {} -- cgit v1.2.3 From 728870ed9dd8231fe493863d6cb51766c5b244ca Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 12:35:44 -0700 Subject: Fixed Warnings in PieceGenerator --- src/Generating/PieceGenerator.cpp | 14 +++++++------- src/Generating/PieceGenerator.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index e3de5b951..8fcc14389 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -31,14 +31,14 @@ public: Gen.PlacePieces(500, 50, 500, 3, OutPieces); // Print out the pieces: - printf("OutPieces.size() = %u\n", OutPieces.size()); + printf("OutPieces.size() = %zu\n", OutPieces.size()); size_t idx = 0; for (cPlacedPieces::const_iterator itr = OutPieces.begin(), end = OutPieces.end(); itr != end; ++itr, ++idx) { const Vector3i & Coords = (*itr)->GetCoords(); cCuboid Hitbox = (*itr)->GetHitBox(); Hitbox.Sort(); - printf("%u: {%d, %d, %d}, rot %d, hitbox {%d, %d, %d} - {%d, %d, %d} (%d * %d * %d)\n", idx, + printf("%zu: {%d, %d, %d}, rot %d, hitbox {%d, %d, %d} - {%d, %d, %d} (%d * %d * %d)\n", idx, Coords.x, Coords.y, Coords.z, (*itr)->GetNumCCWRotations(), Hitbox.p1.x, Hitbox.p1.y, Hitbox.p1.z, @@ -183,7 +183,6 @@ cPiece::cConnector cPiece::RotateMoveConnector(const cConnector & a_Connector, i cPiece::cConnector res(a_Connector); // Rotate the res connector: - Vector3i Size = GetSize(); switch (a_NumCCWRotations) { case 0: @@ -338,7 +337,7 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockY, i // Choose a random supported rotation: int Rotations[4] = {0}; int NumRotations = 1; - for (int i = 1; i < ARRAYCOUNT(Rotations); i++) + for (size_t i = 1; i < ARRAYCOUNT(Rotations); i++) { if (StartingPiece->CanRotateCCW(i)) { @@ -378,7 +377,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector( static const int DirectionRotationTable[6][6] = { /* YM, YP, ZM, ZP, XM, XP - /* YM */ { 0, 0, 0, 0, 0, 0}, + YM */ { 0, 0, 0, 0, 0, 0}, /* YP */ { 0, 0, 0, 0, 0, 0}, /* ZM */ { 0, 0, 2, 0, 1, 3}, /* ZP */ { 0, 0, 0, 2, 3, 1}, @@ -503,11 +502,12 @@ bool cPieceGenerator::CheckConnection( // DEBUG: void cPieceGenerator::DebugConnectorPool(const cPieceGenerator::cFreeConnectors & a_ConnectorPool, size_t a_NumProcessed) { - printf(" Connector pool: %u items\n", a_ConnectorPool.size() - a_NumProcessed); + printf(" Connector pool: %zu items\n", a_ConnectorPool.size() - a_NumProcessed); size_t idx = 0; for (cPieceGenerator::cFreeConnectors::const_iterator itr = a_ConnectorPool.begin() + a_NumProcessed, end = a_ConnectorPool.end(); itr != end; ++itr, ++idx) { - printf(" %u: {%d, %d, %d}, type %d, direction %s, depth %d\n", + // Format specifier for size_t is zu + printf(" %zu: {%d, %d, %d}, type %d, direction %s, depth %d\n", idx, itr->m_Connector.m_Pos.x, itr->m_Connector.m_Pos.y, itr->m_Connector.m_Pos.z, itr->m_Connector.m_Type, diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 9dd5bcfba..3386d7a94 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -122,9 +122,9 @@ public: const cPiece & GetPiece (void) const { return *m_Piece; } const Vector3i & GetCoords (void) const { return m_Coords; } - const int GetNumCCWRotations(void) const { return m_NumCCWRotations; } + int GetNumCCWRotations(void) const { return m_NumCCWRotations; } const cCuboid & GetHitBox (void) const { return m_HitBox; } - const int GetDepth (void) const { return m_Depth; } + int GetDepth (void) const { return m_Depth; } protected: const cPlacedPiece * m_Parent; -- cgit v1.2.3 From 0fc4a1ee06199db80edd4a9f79a4ba1c4369f656 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 12:36:51 -0700 Subject: Move comment --- SetFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index d9308f603..25310c368 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -187,8 +187,8 @@ macro(set_exe_flags) # we support non-IEEE 754 fpus so can make no guarentees about error add_flags_cxx("-ffast-math") - # clang does not provide the __extern_always_inline macro and a part of libm depends on this when using fast-math if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + # clang does not provide the __extern_always_inline macro and a part of libm depends on this when using fast-math add_flags_cxx("-D__extern_always_inline=inline") add_flags_cxx("-Werror -Weverything -Wno-c++98-compat-pedantic -Wno-string-conversion") add_flags_cxx("-Wno-extra-semi -Wno-error=switch-enum -Wno-documentation") -- cgit v1.2.3 From 80cc824c0cf8634439dfb3913cf17af714b03d99 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 12:41:18 -0700 Subject: Fixed Chunkdef warnings --- src/ChunkDef.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 5dd64e1b5..61ad49ad0 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -112,7 +112,7 @@ public: } - inline static unsigned int MakeIndex(int x, int y, int z ) + inline static int MakeIndex(int x, int y, int z ) { if ( (x < Width) && (x > -1) && @@ -271,7 +271,7 @@ public: } int Index = MakeIndexNoCheck(x, y, z); - a_Buffer[Index / 2] = ( + a_Buffer[Index / 2] = static_cast( (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set ); -- cgit v1.2.3 From bb4b35e438a77ff45cded8938e1e3e2724a1587e Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 12:54:46 -0700 Subject: Rollback submodule change --- MCServer/Plugins/Core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 3b416b07a..013a32a7f 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 3b416b07a339b3abcbc127070d56eea05b05373d +Subproject commit 013a32a7fb3c8a6cfe0aef892d4c7394d4e1be59 -- cgit v1.2.3 From abf4effaaf0eff1a98e005512f805211c2fad9a7 Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 11 Mar 2014 21:58:50 +0200 Subject: Matrix4: Removed enum --- src/Matrix4.h | 40 ++++++++++++++++++---------------------- src/Vector3.h | 6 ++++++ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/Matrix4.h b/src/Matrix4.h index 14ccb94fd..a20c019e9 100644 --- a/src/Matrix4.h +++ b/src/Matrix4.h @@ -23,14 +23,6 @@ public: T cell[16]; - enum - { - TX=3, TY=7, TZ=11, - D0=0, D1=5, D2=10, D3=15, - SX=D0, SY=D1, SZ=D2, - W=D3 - }; - // tolua_begin inline Matrix4(void) @@ -60,9 +52,11 @@ public: inline void Identity() { - cell[1] = cell[2] = cell[TX] = cell[4] = cell[6] = cell[TY] = - cell[8] = cell[9] = cell[TZ] = cell[12] = cell[13] = cell[14] = 0; - cell[D0] = cell[D1] = cell[D2] = cell[W] = 1; + cell[1] = cell[2] = cell[3] = cell[4] = 0; + cell[6] = cell[7] = cell[8] = cell[9] = 0; + cell[11] = cell[12] = cell[13] = cell[14] = 0; + + cell[0] = cell[5] = cell[10] = cell[15] = 1; } inline void Init(const Vector3 & a_Pos, T a_RX, T a_RY, T a_RZ) @@ -83,7 +77,8 @@ public: Identity(); - cell[5] = cx, cell[6] = sx, cell[9] = -sx, cell[10] = cx; + cell[5] = cx; cell[6] = sx; + cell[9] = -sx; cell[10] = cx; } inline void RotateY(T a_RY) @@ -93,7 +88,8 @@ public: Identity(); - cell[0] = cy, cell[2] = -sy, cell[8] = sy, cell[10] = cy; + cell[0] = cy; cell[2] = -sy; + cell[8] = sy; cell[10] = cy; } inline void RotateZ(T a_RZ) @@ -109,16 +105,16 @@ public: inline void Translate(const Vector3 & a_Pos) { - cell[TX] += a_Pos.x; - cell[TY] += a_Pos.y; - cell[TZ] += a_Pos.z; + cell[3] += a_Pos.x; + cell[7] += a_Pos.y; + cell[11] += a_Pos.z; } inline void SetTranslation(const Vector3 & a_Pos) { - cell[TX] = a_Pos.x; - cell[TY] = a_Pos.y; - cell[TZ] = a_Pos.z; + cell[3] = a_Pos.x; + cell[7] = a_Pos.y; + cell[11] = a_Pos.z; } inline void Concatenate(const Matrix4 & m2) @@ -130,7 +126,7 @@ public: for (unsigned int r = 0; r < 4; ++r) { res.cell[r * 4 + c] = ( - cell[r * 4] * m2.cell[c] + + cell[r * 4 + 0] * m2.cell[c + 0] + cell[r * 4 + 1] * m2.cell[c + 4] + cell[r * 4 + 2] * m2.cell[c + 8] + cell[r * 4 + 3] * m2.cell[c + 12] @@ -207,8 +203,8 @@ public: inline void SetZColumn(const Vector3 & a_Z) { - cell[8] = a_Z.x; - cell[9] = a_Z.y; + cell[8] = a_Z.x; + cell[9] = a_Z.y; cell[10] = a_Z.z; } }; diff --git a/src/Vector3.h b/src/Vector3.h index 841c3e7d1..79c47ae77 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -26,6 +26,12 @@ public: inline Vector3(T a_x, T a_y, T a_z) : x(a_x), y(a_y), z(a_z) {} + // Hardcoded copy constructors (tolua++ does not support function templates .. yet) + Vector3(const Vector3 & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {} + Vector3(const Vector3 & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {} + Vector3(const Vector3 & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {} + + // tolua_end template Vector3(const Vector3<_T> & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {} -- cgit v1.2.3 From 53faac10c50ba88ce540e0464123f388bd7db069 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 13:41:15 -0700 Subject: Added macros to follow format string checking through wrappers --- src/Globals.h | 4 ++++ src/OSSupport/File.h | 2 +- src/StringUtils.h | 6 +++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Globals.h b/src/Globals.h index 2cd160677..e907614d7 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -38,6 +38,8 @@ // No alignment needed in MSVC #define ALIGN_8 #define ALIGN_16 + + #define FORMATSTRING(formatIndex,va_argsIndex) #elif defined(__GNUC__) @@ -56,6 +58,8 @@ // Some portability macros :) #define stricmp strcasecmp + + #define FORMATSTRING(formatIndex,va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) #else diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index 07fce6661..e229035b7 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -131,7 +131,7 @@ public: /** Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there). */ static AStringVector GetFolderContents(const AString & a_Folder); // Exported in ManualBindings.cpp - int Printf(const char * a_Fmt, ...); + int Printf(const char * a_Fmt, ...) FORMATSTRING(2,3); /** Flushes all the bufferef output into the file (only when writing) */ void Flush(void); diff --git a/src/StringUtils.h b/src/StringUtils.h index b64108409..a7f22b100 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -22,13 +22,13 @@ typedef std::list AStringList; /** Add the formated string to the existing data in the string */ -extern AString & AppendVPrintf(AString & str, const char * format, va_list args); +extern AString & AppendVPrintf(AString & str, const char * format, va_list args) FORMATSTRING(2,0); /// Output the formatted text into the string -extern AString & Printf (AString & str, const char * format, ...); +extern AString & Printf (AString & str, const char * format, ...) FORMATSTRING(2,3); /// Output the formatted text into string, return string by value -extern AString Printf(const char * format, ...); +extern AString Printf(const char * format, ...) FORMATSTRING(1,2); /// Add the formatted string to the existing data in the string extern AString & AppendPrintf (AString & str, const char * format, ...); -- cgit v1.2.3 From f64f8790274c4ee63b4eb904110bd35f93652d78 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 13:46:32 -0700 Subject: Fixed format errors in protocol --- src/Protocol/Protocol17x.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 8c800036e..e76c0fe49 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1251,7 +1251,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); AString Hex; CreateHexDump(Hex, AllData.data(), AllData.size(), 16); - m_CommLogFile.Printf("Incoming data, %d (0x%x) unparsed bytes already present in buffer:\n%s\n", + m_CommLogFile.Printf("Incoming data, %zu (0x%zx) unparsed bytes already present in buffer:\n%s\n", AllData.size(), AllData.size(), Hex.c_str() ); } @@ -1351,7 +1351,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) // Put a message in the comm log: if (g_ShouldLogCommIn) { - m_CommLogFile.Printf("^^^^^^ Wrong number of bytes read for this packet (exp %d left, got %d left) ^^^^^^\n\n\n", + m_CommLogFile.Printf("^^^^^^ Wrong number of bytes read for this packet (exp %d left, got %zu left) ^^^^^^\n\n\n", 1, bb.GetReadableSpace() ); m_CommLogFile.Flush(); @@ -1373,7 +1373,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); AString Hex; CreateHexDump(Hex, AllData.data(), AllData.size(), 16); - m_CommLogFile.Printf("There are %d (0x%x) bytes of non-parse-able data left in the buffer:\n%s", + m_CommLogFile.Printf("There are %zu (0x%zx) bytes of non-parse-able data left in the buffer:\n%s", m_ReceivedData.GetReadableSpace(), m_ReceivedData.GetReadableSpace(), Hex.c_str() ); m_CommLogFile.Flush(); -- cgit v1.2.3 From a19f5fc484648d226899667410aeb82de354c714 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 13:51:56 -0700 Subject: Move Format issues --- src/CommandOutput.h | 2 +- src/Log.cpp | 2 +- src/Log.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/CommandOutput.h b/src/CommandOutput.h index 3763d625f..81d9ddb84 100644 --- a/src/CommandOutput.h +++ b/src/CommandOutput.h @@ -17,7 +17,7 @@ public: virtual ~cCommandOutputCallback() {}; // Force a virtual destructor in subclasses /// Syntax sugar function, calls Out() with Printf()-ed parameters; appends a "\n" - void Out(const char * a_Fmt, ...); + void Out(const char * a_Fmt, ...) FORMATSTRING(2,3); /// Called when the command wants to output anything; may be called multiple times virtual void Out(const AString & a_Text) = 0; diff --git a/src/Log.cpp b/src/Log.cpp index 1ea327d5d..54e2b7812 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -118,7 +118,7 @@ void cLog::Log(const char * a_Format, va_list argList) AString Line; #ifdef _DEBUG - Printf(Line, "[%04x|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); + Printf(Line, "[%04zu|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); #else Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); #endif diff --git a/src/Log.h b/src/Log.h index cba248dae..340fa23bc 100644 --- a/src/Log.h +++ b/src/Log.h @@ -14,8 +14,8 @@ private: public: cLog(const AString & a_FileName); ~cLog(); - void Log(const char * a_Format, va_list argList); - void Log(const char * a_Format, ...); + void Log(const char * a_Format, va_list argList) FORMATSTRING(2,0); + void Log(const char * a_Format, ...) FORMATSTRING(2,3); // tolua_begin void SimpleLog(const char * a_String); void OpenLog(const char * a_FileName); -- cgit v1.2.3 From 16b27c4b7ae2ccb03355148fa7fc7116190cc5fb Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 14:16:08 -0700 Subject: Fixed a load of format string errors --- src/Bindings/LuaState.cpp | 4 +++- src/ClientHandle.cpp | 2 +- src/CommandOutput.cpp | 4 ++-- src/CraftingRecipes.cpp | 2 +- src/FurnaceRecipe.cpp | 2 +- src/Generating/ChunkGenerator.cpp | 4 ++-- src/Item.cpp | 8 ++++---- src/MCLogger.h | 8 ++++---- src/OSSupport/SocketThreads.cpp | 2 +- src/Protocol/Protocol132.cpp | 2 +- src/Protocol/Protocol17x.cpp | 6 +++--- src/UI/Window.cpp | 2 +- src/WorldStorage/WSSCompact.cpp | 10 +++++----- 13 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index aa6ee05b3..2351f0c24 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -1281,7 +1281,9 @@ void cLuaState::LogStack(lua_State * a_LuaState, const char * a_Header) { UNUSED(a_Header); // The param seems unused when compiling for release, so the compiler warns - LOGD((a_Header != NULL) ? a_Header : "Lua C API Stack contents:"); + + // Format string consisting only of %s is used to appease the compiler + LOGD("%s",(a_Header != NULL) ? a_Header : "Lua C API Stack contents:"); for (int i = lua_gettop(a_LuaState); i > 0; i--) { AString Value; diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index df728e83b..02b2e1c47 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -882,7 +882,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo LOGD("Prevented a dig/aim bug in the client (finish {%d, %d, %d} vs start {%d, %d, %d}, HSD: %s)", a_BlockX, a_BlockY, a_BlockZ, m_LastDigBlockX, m_LastDigBlockY, m_LastDigBlockZ, - m_HasStartedDigging + (m_HasStartedDigging ? "True" : "False") ); return; } diff --git a/src/CommandOutput.cpp b/src/CommandOutput.cpp index c221682a1..74f857284 100644 --- a/src/CommandOutput.cpp +++ b/src/CommandOutput.cpp @@ -51,7 +51,7 @@ void cLogCommandOutputCallback::Finished(void) { case '\n': { - LOG(m_Buffer.substr(last, i - last).c_str()); + LOG("%s",m_Buffer.substr(last, i - last).c_str()); last = i + 1; break; } @@ -59,7 +59,7 @@ void cLogCommandOutputCallback::Finished(void) } // for i - m_Buffer[] if (last < len) { - LOG(m_Buffer.substr(last).c_str()); + LOG("%s",m_Buffer.substr(last).c_str()); } // Clear the buffer for the next command output: diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index be9f45caa..30f21686c 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -340,7 +340,7 @@ void cCraftingRecipes::LoadRecipes(void) } AddRecipeLine(LineNum, Recipe); } // for itr - Split[] - LOG("Loaded %d crafting recipes", m_Recipes.size()); + LOG("Loaded %zu crafting recipes", m_Recipes.size()); } diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index 2e2276981..dd2f259f3 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -175,7 +175,7 @@ void cFurnaceRecipe::ReloadRecipes(void) { LOGERROR("ERROR: FurnaceRecipe, syntax error" ); } - LOG("Loaded %u furnace recipes and %u fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); + LOG("Loaded %zu furnace recipes and %zu fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); } diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index ef38f1399..92f6009ac 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -116,7 +116,7 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_Chunk // Add to queue, issue a warning if too many: if (m_Queue.size() >= QUEUE_WARNING_LIMIT) { - LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%i)", a_ChunkX, a_ChunkZ, m_Queue.size()); + LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%zu)", a_ChunkX, a_ChunkZ, m_Queue.size()); } m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); } @@ -180,7 +180,7 @@ BLOCKTYPE cChunkGenerator::GetIniBlock(cIniFile & a_IniFile, const AString & a_S BLOCKTYPE Block = BlockStringToType(BlockType); if (Block < 0) { - LOGWARN("[&s].%s Could not parse block value \"%s\". Using default: \"%s\".", a_SectionName.c_str(), a_ValueName.c_str(), BlockType.c_str(),a_Default.c_str()); + LOGWARN("[%s].%s Could not parse block value \"%s\". Using default: \"%s\".", a_SectionName.c_str(), a_ValueName.c_str(), BlockType.c_str(),a_Default.c_str()); return BlockStringToType(a_Default); } return Block; diff --git a/src/Item.cpp b/src/Item.cpp index 61d57e763..c8dda209c 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -216,7 +216,7 @@ cItem * cItems::Get(int a_Idx) { if ((a_Idx < 0) || (a_Idx >= (int)size())) { - LOGWARNING("cItems: Attempt to get an out-of-bounds item at index %d; there are currently %d items. Returning a nil.", a_Idx, size()); + LOGWARNING("cItems: Attempt to get an out-of-bounds item at index %d; there are currently %zu items. Returning a nil.", a_Idx, size()); return NULL; } return &at(a_Idx); @@ -230,7 +230,7 @@ void cItems::Set(int a_Idx, const cItem & a_Item) { if ((a_Idx < 0) || (a_Idx >= (int)size())) { - LOGWARNING("cItems: Attempt to set an item at an out-of-bounds index %d; there are currently %d items. Not setting.", a_Idx, size()); + LOGWARNING("cItems: Attempt to set an item at an out-of-bounds index %d; there are currently %zu items. Not setting.", a_Idx, size()); return; } at(a_Idx) = a_Item; @@ -244,7 +244,7 @@ void cItems::Delete(int a_Idx) { if ((a_Idx < 0) || (a_Idx >= (int)size())) { - LOGWARNING("cItems: Attempt to delete an item at an out-of-bounds index %d; there are currently %d items. Ignoring.", a_Idx, size()); + LOGWARNING("cItems: Attempt to delete an item at an out-of-bounds index %d; there are currently %zu items. Ignoring.", a_Idx, size()); return; } erase(begin() + a_Idx); @@ -258,7 +258,7 @@ void cItems::Set(int a_Idx, short a_ItemType, char a_ItemCount, short a_ItemDama { if ((a_Idx < 0) || (a_Idx >= (int)size())) { - LOGWARNING("cItems: Attempt to set an item at an out-of-bounds index %d; there are currently %d items. Not setting.", a_Idx, size()); + LOGWARNING("cItems: Attempt to set an item at an out-of-bounds index %d; there are currently %zu items. Not setting.", a_Idx, size()); return; } at(a_Idx) = cItem(a_ItemType, a_ItemCount, a_ItemDamage); diff --git a/src/MCLogger.h b/src/MCLogger.h index c949a4cdf..348b51242 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -57,10 +57,10 @@ private: -extern void LOG(const char* a_Format, ...); -extern void LOGINFO(const char* a_Format, ...); -extern void LOGWARN(const char* a_Format, ...); -extern void LOGERROR(const char* a_Format, ...); +extern void LOG(const char* a_Format, ...) FORMATSTRING(1,2); +extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1,2); +extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1,2); +extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1,2); diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index a02661d2c..f37b00202 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -54,7 +54,7 @@ bool cSocketThreads::AddClient(const cSocket & a_Socket, cCallback * a_Client) } // No thread has free space, create a new one: - LOGD("Creating a new cSocketThread (currently have %d)", m_Threads.size()); + LOGD("Creating a new cSocketThread (currently have %zu)", m_Threads.size()); cSocketThread * Thread = new cSocketThread(this); if (!Thread->Start()) { diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index 8df550c7b..43fe90616 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -100,7 +100,7 @@ cProtocol132::~cProtocol132() { if (!m_DataToSend.empty()) { - LOGD("There are %d unsent bytes while deleting cProtocol132", m_DataToSend.size()); + LOGD("There are %zu unsent bytes while deleting cProtocol132", m_DataToSend.size()); } } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index e76c0fe49..9e5fe53fb 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1344,7 +1344,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) if (bb.GetReadableSpace() != 1) { // Read more or less than packet length, report as error - LOGWARNING("Protocol 1.7: Wrong number of bytes read for packet 0x%x, state %d. Read %u bytes, packet contained %u bytes", + LOGWARNING("Protocol 1.7: Wrong number of bytes read for packet 0x%x, state %d. Read %zu bytes, packet contained %u bytes", PacketType, m_State, bb.GetUsedSpace() - bb.GetReadableSpace(), PacketLen ); @@ -2062,7 +2062,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) { AString HexDump; CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16); - LOGWARNING("Cannot unGZIP item metadata (%u bytes):\n%s", a_Metadata.size(), HexDump.c_str()); + LOGWARNING("Cannot unGZIP item metadata (%zu bytes):\n%s", a_Metadata.size(), HexDump.c_str()); return; } @@ -2072,7 +2072,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) { AString HexDump; CreateHexDump(HexDump, Uncompressed.data(), Uncompressed.size(), 16); - LOGWARNING("Cannot parse NBT item metadata: (%u bytes)\n%s", Uncompressed.size(), HexDump.c_str()); + LOGWARNING("Cannot parse NBT item metadata: (%zu bytes)\n%s", Uncompressed.size(), HexDump.c_str()); return; } diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 1a8456f70..5249a4bca 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -637,7 +637,7 @@ int cWindow::DistributeItemToSlots(cPlayer & a_Player, const cItem & a_Item, int { if ((size_t)(a_Item.m_ItemCount) < a_SlotNums.size()) { - LOGWARNING("%s: Distributing less items (%d) than slots (%u)", __FUNCTION__, (int)a_Item.m_ItemCount, a_SlotNums.size()); + LOGWARNING("%s: Distributing less items (%d) than slots (%zu)", __FUNCTION__, (int)a_Item.m_ItemCount, a_SlotNums.size()); // This doesn't seem to happen with the 1.5.1 client, so we don't worry about it for now return 0; } diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index 1e84fb4ad..b1e8d12b7 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -569,7 +569,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() if( ChunksConverted % 32 == 0 ) { - LOGINFO("Updating \"%s\" version 1 to version 2: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); + LOGINFO("Updating \"%s\" version 1 to version 2: %zu %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); } ChunksConverted++; @@ -607,7 +607,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() if (UncompressedSize != (int)UncompressedData.size()) { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", + LOGWARNING("Uncompressed data size differs (exp %d bytes, got %zu) for chunk [%d, %d]", UncompressedSize, UncompressedData.size(), Header->m_ChunkX, Header->m_ChunkZ ); @@ -713,7 +713,7 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3() if( ChunksConverted % 32 == 0 ) { - LOGINFO("Updating \"%s\" version 2 to version 3: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); + LOGINFO("Updating \"%s\" version 2 to version 3: %zu %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); } ChunksConverted++; @@ -751,7 +751,7 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3() if (UncompressedSize != (int)UncompressedData.size()) { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", + LOGWARNING("Uncompressed data size differs (exp %d bytes, got %zu) for chunk [%d, %d]", UncompressedSize, UncompressedData.size(), Header->m_ChunkX, Header->m_ChunkZ ); @@ -866,7 +866,7 @@ bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_Uncomp if (a_UncompressedSize != (int)UncompressedData.size()) { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]", + LOGWARNING("Uncompressed data size differs (exp %d bytes, got %zu) for chunk [%d, %d]", a_UncompressedSize, UncompressedData.size(), a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ ); -- cgit v1.2.3 From 7e6ee7ef8158a037c11405986513aa344ce68f42 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 14:43:14 -0700 Subject: Fixed more Format issues --- src/ByteBuffer.cpp | 2 +- src/MCLogger.h | 14 +++++++------- src/Root.cpp | 10 +++++----- src/Server.cpp | 2 +- src/StringUtils.h | 2 +- src/World.cpp | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 9d97d8614..d3bcfe866 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -459,7 +459,7 @@ bool cByteBuffer::ReadVarUTF8String(AString & a_Value) } if (Size > MAX_STRING_SIZE) { - LOGWARNING("%s: String too large: %llu (%llu KiB)", __FUNCTION__, Size, Size / 1024); + LOGWARNING("%s: String too large: %u (%u KiB)", __FUNCTION__, Size, Size / 1024); } return ReadString(a_Value, (int)Size); } diff --git a/src/MCLogger.h b/src/MCLogger.h index 348b51242..ba9e4827f 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -21,10 +21,10 @@ public: // tolua_export ~cMCLogger(); // tolua_export - void Log(const char* a_Format, va_list a_ArgList); - void Info(const char* a_Format, va_list a_ArgList); - void Warn(const char* a_Format, va_list a_ArgList); - void Error(const char* a_Format, va_list a_ArgList); + void Log(const char* a_Format, va_list a_ArgList) FORMATSTRING(2,0); + void Info(const char* a_Format, va_list a_ArgList) FORMATSTRING(2,0); + void Warn(const char* a_Format, va_list a_ArgList) FORMATSTRING(2,0); + void Error(const char* a_Format, va_list a_ArgList) FORMATSTRING(2,0); void LogSimple(const char* a_Text, int a_LogType = 0 ); // tolua_export @@ -57,9 +57,9 @@ private: -extern void LOG(const char* a_Format, ...) FORMATSTRING(1,2); -extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1,2); -extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1,2); +extern void LOG(const char* a_Format, ...) FORMATSTRING(1,2); +extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1,2); +extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1,2); extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1,2); diff --git a/src/Root.cpp b/src/Root.cpp index 69f18104e..9a5dcac71 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -778,11 +778,11 @@ void cRoot::LogChunkStats(cCommandOutputCallback & a_Output) int Mem = NumValid * sizeof(cChunk); a_Output.Out(" Memory used by chunks: %d KiB (%d MiB)", (Mem + 1023) / 1024, (Mem + 1024 * 1024 - 1) / (1024 * 1024)); a_Output.Out(" Per-chunk memory size breakdown:"); - a_Output.Out(" block types: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockTypes), (sizeof(cChunkDef::BlockTypes) + 1023) / 1024); - a_Output.Out(" block metadata: %6d bytes (%3d KiB)", sizeof(cChunkDef::BlockNibbles), (sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); - a_Output.Out(" block lighting: %6d bytes (%3d KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); - a_Output.Out(" heightmap: %6d bytes (%3d KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024); - a_Output.Out(" biomemap: %6d bytes (%3d KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024); + a_Output.Out(" block types: %6zu bytes (%3zu KiB)", sizeof(cChunkDef::BlockTypes), (sizeof(cChunkDef::BlockTypes) + 1023) / 1024); + a_Output.Out(" block metadata: %6zu bytes (%3zu KiB)", sizeof(cChunkDef::BlockNibbles), (sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); + a_Output.Out(" block lighting: %6zu bytes (%3zu KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); + a_Output.Out(" heightmap: %6zu bytes (%3zu KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024); + a_Output.Out(" biomemap: %6zu bytes (%3zu KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024); int Rest = sizeof(cChunk) - sizeof(cChunkDef::BlockTypes) - 3 * sizeof(cChunkDef::BlockNibbles) - sizeof(cChunkDef::HeightMap) - sizeof(cChunkDef::BiomeMap); a_Output.Out(" other: %6d bytes (%3d KiB)", Rest, (Rest + 1023) / 1024); SumNumValid += NumValid; diff --git a/src/Server.cpp b/src/Server.cpp index fcbcaa919..194195136 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -550,7 +550,7 @@ void cServer::PrintHelp(const AStringVector & a_Split, cCommandOutputCallback & for (AStringPairs::const_iterator itr = Callback.m_Commands.begin(), end = Callback.m_Commands.end(); itr != end; ++itr) { const AStringPair & cmd = *itr; - a_Output.Out(Printf("%-*s%s\n", Callback.m_MaxLen, cmd.first.c_str(), cmd.second.c_str())); + a_Output.Out(Printf("%-*s%s\n", static_cast(Callback.m_MaxLen), cmd.first.c_str(), cmd.second.c_str())); } // for itr - Callback.m_Commands[] a_Output.Finished(); } diff --git a/src/StringUtils.h b/src/StringUtils.h index a7f22b100..728ce31e6 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -31,7 +31,7 @@ extern AString & Printf (AString & str, const char * format, ...) FORMATST extern AString Printf(const char * format, ...) FORMATSTRING(1,2); /// Add the formatted string to the existing data in the string -extern AString & AppendPrintf (AString & str, const char * format, ...); +extern AString & AppendPrintf (AString & str, const char * format, ...) FORMATSTRING(2,3); /// Split the string at any of the listed delimiters, return as a stringvector extern AStringVector StringSplit(const AString & str, const AString & delim); diff --git a/src/World.cpp b/src/World.cpp index a9db6bf00..520ed9ae7 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -103,7 +103,7 @@ protected: { for (;;) { - LOG("%d chunks to load, %d chunks to generate", + LOG("%zu chunks to load, %d chunks to generate", m_World->GetStorage().GetLoadQueueLength(), m_World->GetGenerator().GetQueueLength() ); @@ -155,7 +155,7 @@ protected: { for (;;) { - LOG("%d chunks remaining to light", m_Lighting->GetQueueLength() + LOG("%zu chunks remaining to light", m_Lighting->GetQueueLength() ); // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish -- cgit v1.2.3 From 9c6ca5a3edcfbcd1e9a18eec463ce7702770ceb2 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 14:43:56 -0700 Subject: made format-nonliteral an error --- SetFlags.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 25310c368..42cfa6769 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -199,7 +199,6 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") add_flags_cxx("-Wno-missing-noreturn -Wno-error=unreachable-code -Wno-error=undef") - add_flags_cxx("-Wno-error=format-nonliteral") endif() endif() -- cgit v1.2.3 From 3d15319e3c125507e48a66b3cdbb30feeaa652c1 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 15:55:37 -0700 Subject: Added macros support to tools --- Tools/MCADefrag/Globals.h | 5 ++++- Tools/ProtoProxy/Globals.h | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Tools/MCADefrag/Globals.h b/Tools/MCADefrag/Globals.h index 6f4bbdc76..0f31de7e3 100644 --- a/Tools/MCADefrag/Globals.h +++ b/Tools/MCADefrag/Globals.h @@ -37,7 +37,8 @@ // Some portability macros :) #define stricmp strcasecmp - + + #define FORMATSTRING(formatIndex,va_argsIndex) #else #error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler" @@ -58,6 +59,8 @@ #define ALIGN_8 #define ALIGN_16 */ + + #define FORMATSTRING(formatIndex,va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) #endif diff --git a/Tools/ProtoProxy/Globals.h b/Tools/ProtoProxy/Globals.h index 547903e7a..0724d3a52 100644 --- a/Tools/ProtoProxy/Globals.h +++ b/Tools/ProtoProxy/Globals.h @@ -37,6 +37,8 @@ // Some portability macros :) #define stricmp strcasecmp + + #define FORMATSTRING(formatIndex,va_argsIndex) #else @@ -59,6 +61,9 @@ #define ALIGN_16 */ + #define FORMATSTRING(formatIndex,va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) + + #endif @@ -233,4 +238,4 @@ public: #define LOGERROR printf #define LOGINFO printf -#define LOGWARNING printf \ No newline at end of file +#define LOGWARNING printf -- cgit v1.2.3 From 0c15fdf7b05ee6ad0705b2a789f6b709bbde2733 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 12 Mar 2014 13:05:28 +0100 Subject: Moved Lua API registering into a separate function. This will allow us to use Lua as lite-config files as well, should we want to. --- src/Bindings/LuaState.cpp | 10 +++++++++- src/Bindings/LuaState.h | 7 ++++++- src/Bindings/PluginLua.cpp | 1 + src/WebAdmin.cpp | 1 + 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index aa6ee05b3..1f0549a59 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -94,12 +94,20 @@ void cLuaState::Create(void) } m_LuaState = lua_open(); luaL_openlibs(m_LuaState); + m_IsOwned = true; +} + + + + + +void cLuaState::RegisterAPILibs(void) +{ tolua_AllToLua_open(m_LuaState); ManualBindings::Bind(m_LuaState); DeprecatedBindings::Bind(m_LuaState); luaopen_lsqlite3(m_LuaState); luaopen_lxp(m_LuaState); - m_IsOwned = true; } diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 4a7a6fadb..1495c72f0 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -139,9 +139,14 @@ public: /** Allows this object to be used in the same way as a lua_State *, for example in the LuaLib functions */ operator lua_State * (void) { return m_LuaState; } - /** Creates the m_LuaState, if not closed already. This state will be automatically closed in the destructor */ + /** Creates the m_LuaState, if not closed already. This state will be automatically closed in the destructor. + The regular Lua libs are registered, but the MCS API is not registered (so that Lua can be used as + lite-config as well), use RegisterAPILibs() to do that. */ void Create(void); + /** Registers all the API libraries that MCS provides into m_LuaState. */ + void RegisterAPILibs(void); + /** Closes the m_LuaState, if not closed already */ void Close(void); diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 45c8216be..cccbc3c93 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -75,6 +75,7 @@ bool cPluginLua::Initialize(void) if (!m_LuaState.IsValid()) { m_LuaState.Create(); + m_LuaState.RegisterAPILibs(); // Inject the identification global variables into the state: lua_pushlightuserdata(m_LuaState, this); diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index e88de5947..402cd3035 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -127,6 +127,7 @@ bool cWebAdmin::Start(void) // Initialize the WebAdmin template script and load the file m_TemplateScript.Create(); + m_TemplateScript.RegisterAPILibs(); if (!m_TemplateScript.LoadFile(FILE_IO_PREFIX "webadmin/template.lua")) { LOGWARN("Could not load WebAdmin template \"%s\", using default template.", FILE_IO_PREFIX "webadmin/template.lua"); -- cgit v1.2.3 From a7f9df24d4537a0c7567fa5bbc9e62bb4ef16e56 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 12 Mar 2014 13:11:34 +0100 Subject: The entire unknown command is echoed back to the user on error. --- src/Bindings/PluginManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index c7df6357e..b9cf160c4 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -248,7 +248,7 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) { AStringVector Split(StringSplit(a_Message, " ")); ASSERT(!Split.empty()); // This should not happen - we know there's at least one char in the message so the split needs to be at least one item long - a_Player->SendMessageInfo(Printf("Unknown command: \"%s\"", Split[0].c_str())); + a_Player->SendMessageInfo(Printf("Unknown command: \"%s\"", a_Message.c_str())); LOGINFO("Player %s issued an unknown command: \"%s\"", a_Player->GetName().c_str(), a_Message.c_str()); return true; // Cancel sending } -- cgit v1.2.3 From 5d7df54e35e99d41f69a44c5ea9c78a98fb557d0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 12 Mar 2014 14:11:28 +0100 Subject: Fixed Lua string return values. Fixes #773. --- src/Bindings/LuaState.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 1f0549a59..dfc428bbc 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -742,10 +742,6 @@ void cLuaState::GetStackValue(int a_StackPos, AString & a_Value) { a_Value.assign(data, len); } - else - { - a_Value.clear(); - } } -- cgit v1.2.3 From a3a94436dcc1cc95c1476c8a88400b16ac279e71 Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 12 Mar 2014 15:13:19 +0200 Subject: Vector3: Length() should always return a float --- src/Vector3.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Vector3.h b/src/Vector3.h index 79c47ae77..80583879a 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -27,9 +27,9 @@ public: // Hardcoded copy constructors (tolua++ does not support function templates .. yet) - Vector3(const Vector3 & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {} - Vector3(const Vector3 & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {} - Vector3(const Vector3 & a_Rhs) : x(a_Rhs.x), y(a_Rhs.y), z(a_Rhs.z) {} + Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} + Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} + Vector3(const Vector3 & a_Rhs) : x((T) a_Rhs.x), y((T) a_Rhs.y), z((T) a_Rhs.z) {} // tolua_end @@ -50,7 +50,7 @@ public: inline void Normalize(void) { - T Len = 1.0 / Length(); + double Len = 1.0 / Length(); x *= Len; y *= Len; @@ -59,7 +59,7 @@ public: inline Vector3 NormalizeCopy(void) const { - T Len = 1.0 / Length(); + double Len = 1.0 / Length(); return Vector3( x * Len, @@ -70,7 +70,7 @@ public: inline void NormalizeCopy(Vector3 & a_Rhs) const { - T Len = 1.0 / Length(); + double Len = 1.0 / Length(); a_Rhs.Set( x * Len, @@ -79,12 +79,12 @@ public: ); } - inline T Length(void) const + inline double Length(void) const { - return sqrt(x * x + y * y + z * z); + return sqrt((double)(x * x + y * y + z * z)); } - inline T SqrLength(void) const + inline double SqrLength(void) const { return x * x + y * y + z * z; } -- cgit v1.2.3 From 6f2bb0ad44592ac42334dc627afd3ad734b7a4ab Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 12 Mar 2014 16:13:03 +0200 Subject: M_PI MSVC Fix --- src/Matrix4.h | 2 +- src/Vector3.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Matrix4.h b/src/Matrix4.h index a20c019e9..456677f0f 100644 --- a/src/Matrix4.h +++ b/src/Matrix4.h @@ -3,7 +3,7 @@ - +#define _USE_MATH_DEFINES // Enable non-standard math defines (MSVC) #include diff --git a/src/Vector3.h b/src/Vector3.h index 80583879a..b7a810fc5 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -3,7 +3,7 @@ - +#define _USE_MATH_DEFINES // Enable non-standard math defines (MSVC) #include -- cgit v1.2.3 From 4a883be428ef1d8b22887eeb52736529658c7fd2 Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 12 Mar 2014 16:30:57 +0200 Subject: Vector3: More casts --- src/Vector3.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Vector3.h b/src/Vector3.h index b7a810fc5..ba4abe3eb 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -52,9 +52,9 @@ public: { double Len = 1.0 / Length(); - x *= Len; - y *= Len; - z *= Len; + x = (T)(x * Len); + y = (T)(y * Len); + z = (T)(z * Len); } inline Vector3 NormalizeCopy(void) const @@ -62,9 +62,9 @@ public: double Len = 1.0 / Length(); return Vector3( - x * Len, - y * Len, - z * Len + (T)(x * Len), + (T)(y * Len), + (T)(z * Len) ); } @@ -73,9 +73,9 @@ public: double Len = 1.0 / Length(); a_Rhs.Set( - x * Len, - y * Len, - z * Len + (T)(x * Len), + (T)(y * Len), + (T)(z * Len) ); } -- cgit v1.2.3 From d545be9614e9d6717d19794ea8a49b6d4a0da52f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 12 Mar 2014 15:33:28 +0100 Subject: Fixed missing comment terminator. --- src/Generating/PieceGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index e3de5b951..cf5ab6226 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -377,7 +377,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector( // You need DirectionRotationTable[rot1][rot2] CCW turns to connect rot1 to rot2 (they are opposite) static const int DirectionRotationTable[6][6] = { - /* YM, YP, ZM, ZP, XM, XP + /* YM, YP, ZM, ZP, XM, XP */ /* YM */ { 0, 0, 0, 0, 0, 0}, /* YP */ { 0, 0, 0, 0, 0, 0}, /* ZM */ { 0, 0, 2, 0, 1, 3}, -- cgit v1.2.3 From ef58b0eb54c700800597031c37c3e76fef87cdfb Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 12 Mar 2014 09:49:37 -0700 Subject: Fixed comments an assert --- Tools/ProtoProxy/Connection.cpp | 4 ++-- src/Globals.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index 73688d310..46119ff42 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -2772,7 +2772,7 @@ void cConnection::LogMetadata(const AString & a_Metadata, size_t a_IndentCount) { int Index = ((unsigned)((unsigned char)a_Metadata[pos])) & 0x1f; // Lower 5 bits = index int Type = ((unsigned)((unsigned char)a_Metadata[pos])) >> 5; // Upper 3 bits = type - //int Length = 0; + // int Length = 0; switch (Type) { case 0: @@ -2827,7 +2827,7 @@ void cConnection::LogMetadata(const AString & a_Metadata, size_t a_IndentCount) ASSERT(!"Cannot parse item description from metadata"); return; } - //int After = bb.GetReadableSpace(); + // int After = bb.GetReadableSpace(); int BytesConsumed = BytesLeft - bb.GetReadableSpace(); Log("%sslot[%d] = %s (%d bytes)", Indent.c_str(), Index, ItemDesc.c_str(), BytesConsumed); diff --git a/src/Globals.h b/src/Globals.h index 2cd160677..6661aa476 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -236,7 +236,7 @@ template class SizeChecker; // Same as assert but in all Self test builds #ifdef SELF_TEST -#define assert_test(x) ( !!(x) || (assert(0), exit(1), 0)) +#define assert_test(x) ( !!(x) || (assert(!#x), exit(1), 0)) #endif /// A generic interface used mainly in ForEach() functions -- cgit v1.2.3 From a584b7b3bc95783025d9861964bd987f324ba981 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 12 Mar 2014 10:09:08 -0700 Subject: Fixed printf format compatabilty --- src/Generating/PieceGenerator.cpp | 9 ++++----- src/Globals.h | 5 +++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index 50bfe65fe..8999a5ff7 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -31,14 +31,14 @@ public: Gen.PlacePieces(500, 50, 500, 3, OutPieces); // Print out the pieces: - printf("OutPieces.size() = %zu\n", OutPieces.size()); + printf("OutPieces.size() = " SIZE_T_FMT "\n", OutPieces.size()); size_t idx = 0; for (cPlacedPieces::const_iterator itr = OutPieces.begin(), end = OutPieces.end(); itr != end; ++itr, ++idx) { const Vector3i & Coords = (*itr)->GetCoords(); cCuboid Hitbox = (*itr)->GetHitBox(); Hitbox.Sort(); - printf("%zu: {%d, %d, %d}, rot %d, hitbox {%d, %d, %d} - {%d, %d, %d} (%d * %d * %d)\n", idx, + printf(SIZE_T_FMT ": {%d, %d, %d}, rot %d, hitbox {%d, %d, %d} - {%d, %d, %d} (%d * %d * %d)\n", idx, Coords.x, Coords.y, Coords.z, (*itr)->GetNumCCWRotations(), Hitbox.p1.x, Hitbox.p1.y, Hitbox.p1.z, @@ -502,12 +502,11 @@ bool cPieceGenerator::CheckConnection( // DEBUG: void cPieceGenerator::DebugConnectorPool(const cPieceGenerator::cFreeConnectors & a_ConnectorPool, size_t a_NumProcessed) { - printf(" Connector pool: %zu items\n", a_ConnectorPool.size() - a_NumProcessed); + printf(" Connector pool: " SIZE_T_FMT " items\n", a_ConnectorPool.size() - a_NumProcessed); size_t idx = 0; for (cPieceGenerator::cFreeConnectors::const_iterator itr = a_ConnectorPool.begin() + a_NumProcessed, end = a_ConnectorPool.end(); itr != end; ++itr, ++idx) { - // Format specifier for size_t is zu - printf(" %zu: {%d, %d, %d}, type %d, direction %s, depth %d\n", + printf(" " SIZE_T_FMT ": {%d, %d, %d}, type %d, direction %s, depth %d\n", idx, itr->m_Connector.m_Pos.x, itr->m_Connector.m_Pos.y, itr->m_Connector.m_Pos.z, itr->m_Connector.m_Type, diff --git a/src/Globals.h b/src/Globals.h index 5ced0cc39..b42a06970 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -38,6 +38,9 @@ // No alignment needed in MSVC #define ALIGN_8 #define ALIGN_16 + + // MSVC has its own custom version of zu format + #define SIZE_T_FMT "%Iu" #elif defined(__GNUC__) @@ -56,6 +59,8 @@ // Some portability macros :) #define stricmp strcasecmp + + #define SIZE_T_FMT "%zu" #else -- cgit v1.2.3 From 862e2194433b5d47aaf88261091b35a1ee663482 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 12 Mar 2014 10:34:50 -0700 Subject: Added additional macros to support the MSVC size_t format and changed all formats to use the macros --- src/CraftingRecipes.cpp | 2 +- src/FurnaceRecipe.cpp | 2 +- src/Generating/ChunkGenerator.cpp | 2 +- src/Globals.h | 4 ++++ src/Item.cpp | 8 ++++---- src/Log.cpp | 2 +- src/OSSupport/SocketThreads.cpp | 2 +- src/Protocol/Protocol132.cpp | 2 +- src/Protocol/Protocol17x.cpp | 12 ++++++------ src/Root.cpp | 10 +++++----- src/UI/Window.cpp | 2 +- src/World.cpp | 4 ++-- src/WorldStorage/WSSCompact.cpp | 10 +++++----- 13 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index 30f21686c..30e7a8733 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -340,7 +340,7 @@ void cCraftingRecipes::LoadRecipes(void) } AddRecipeLine(LineNum, Recipe); } // for itr - Split[] - LOG("Loaded %zu crafting recipes", m_Recipes.size()); + LOG("Loaded " SIZE_T_FMT " crafting recipes", m_Recipes.size()); } diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index dd2f259f3..1810d7c49 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -175,7 +175,7 @@ void cFurnaceRecipe::ReloadRecipes(void) { LOGERROR("ERROR: FurnaceRecipe, syntax error" ); } - LOG("Loaded %zu furnace recipes and %zu fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); + LOG("Loaded " SIZE_T_FMT " furnace recipes and " SIZE_T_FMT " fuels", m_pState->Recipes.size(), m_pState->Fuel.size()); } diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index 92f6009ac..73f0223e8 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -116,7 +116,7 @@ void cChunkGenerator::QueueGenerateChunk(int a_ChunkX, int a_ChunkY, int a_Chunk // Add to queue, issue a warning if too many: if (m_Queue.size() >= QUEUE_WARNING_LIMIT) { - LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (%zu)", a_ChunkX, a_ChunkZ, m_Queue.size()); + LOGWARN("WARNING: Adding chunk [%i, %i] to generation queue; Queue is too big! (" SIZE_T_FMT ")", a_ChunkX, a_ChunkZ, m_Queue.size()); } m_Queue.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); } diff --git a/src/Globals.h b/src/Globals.h index faa168c59..08d9e971a 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -43,6 +43,8 @@ // MSVC has its own custom version of zu format #define SIZE_T_FMT "%Iu" + #define SIZE_T_FMT_PRECISION(x) "%" #x "Iu" + #define SIZE_T_FMT_HEX "%Ix" #elif defined(__GNUC__) @@ -65,6 +67,8 @@ #define FORMATSTRING(formatIndex,va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) #define SIZE_T_FMT "%zu" + #define SIZE_T_FMT_PRECISION(x) "%" #x "zu" + #define SIZE_T_FMT_HEX "%zx" #else diff --git a/src/Item.cpp b/src/Item.cpp index c8dda209c..856b68be6 100644 --- a/src/Item.cpp +++ b/src/Item.cpp @@ -216,7 +216,7 @@ cItem * cItems::Get(int a_Idx) { if ((a_Idx < 0) || (a_Idx >= (int)size())) { - LOGWARNING("cItems: Attempt to get an out-of-bounds item at index %d; there are currently %zu items. Returning a nil.", a_Idx, size()); + LOGWARNING("cItems: Attempt to get an out-of-bounds item at index %d; there are currently " SIZE_T_FMT " items. Returning a nil.", a_Idx, size()); return NULL; } return &at(a_Idx); @@ -230,7 +230,7 @@ void cItems::Set(int a_Idx, const cItem & a_Item) { if ((a_Idx < 0) || (a_Idx >= (int)size())) { - LOGWARNING("cItems: Attempt to set an item at an out-of-bounds index %d; there are currently %zu items. Not setting.", a_Idx, size()); + LOGWARNING("cItems: Attempt to set an item at an out-of-bounds index %d; there are currently " SIZE_T_FMT " items. Not setting.", a_Idx, size()); return; } at(a_Idx) = a_Item; @@ -244,7 +244,7 @@ void cItems::Delete(int a_Idx) { if ((a_Idx < 0) || (a_Idx >= (int)size())) { - LOGWARNING("cItems: Attempt to delete an item at an out-of-bounds index %d; there are currently %zu items. Ignoring.", a_Idx, size()); + LOGWARNING("cItems: Attempt to delete an item at an out-of-bounds index %d; there are currently " SIZE_T_FMT " items. Ignoring.", a_Idx, size()); return; } erase(begin() + a_Idx); @@ -258,7 +258,7 @@ void cItems::Set(int a_Idx, short a_ItemType, char a_ItemCount, short a_ItemDama { if ((a_Idx < 0) || (a_Idx >= (int)size())) { - LOGWARNING("cItems: Attempt to set an item at an out-of-bounds index %d; there are currently %zu items. Not setting.", a_Idx, size()); + LOGWARNING("cItems: Attempt to set an item at an out-of-bounds index %d; there are currently " SIZE_T_FMT " items. Not setting.", a_Idx, size()); return; } at(a_Idx) = cItem(a_ItemType, a_ItemCount, a_ItemDamage); diff --git a/src/Log.cpp b/src/Log.cpp index 54e2b7812..395326398 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -118,7 +118,7 @@ void cLog::Log(const char * a_Format, va_list argList) AString Line; #ifdef _DEBUG - Printf(Line, "[%04zu|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); + Printf(Line, "[" SIZE_T_FMT_PRECISION(04) "|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); #else Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); #endif diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index f37b00202..0bc1d6b55 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -54,7 +54,7 @@ bool cSocketThreads::AddClient(const cSocket & a_Socket, cCallback * a_Client) } // No thread has free space, create a new one: - LOGD("Creating a new cSocketThread (currently have %zu)", m_Threads.size()); + LOGD("Creating a new cSocketThread (currently have " SIZE_T_FMT ")", m_Threads.size()); cSocketThread * Thread = new cSocketThread(this); if (!Thread->Start()) { diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp index 43fe90616..be9c503ed 100644 --- a/src/Protocol/Protocol132.cpp +++ b/src/Protocol/Protocol132.cpp @@ -100,7 +100,7 @@ cProtocol132::~cProtocol132() { if (!m_DataToSend.empty()) { - LOGD("There are %zu unsent bytes while deleting cProtocol132", m_DataToSend.size()); + LOGD("There are " SIZE_T_FMT " unsent bytes while deleting cProtocol132", m_DataToSend.size()); } } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 9e5fe53fb..6fc344eaf 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1251,7 +1251,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); AString Hex; CreateHexDump(Hex, AllData.data(), AllData.size(), 16); - m_CommLogFile.Printf("Incoming data, %zu (0x%zx) unparsed bytes already present in buffer:\n%s\n", + m_CommLogFile.Printf("Incoming data, " SIZE_T_FMT " (0x" SIZE_T_FMT_HEX ") unparsed bytes already present in buffer:\n%s\n", AllData.size(), AllData.size(), Hex.c_str() ); } @@ -1344,14 +1344,14 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) if (bb.GetReadableSpace() != 1) { // Read more or less than packet length, report as error - LOGWARNING("Protocol 1.7: Wrong number of bytes read for packet 0x%x, state %d. Read %zu bytes, packet contained %u bytes", + LOGWARNING("Protocol 1.7: Wrong number of bytes read for packet 0x%x, state %d. Read " SIZE_T_FMT " bytes, packet contained %u bytes", PacketType, m_State, bb.GetUsedSpace() - bb.GetReadableSpace(), PacketLen ); // Put a message in the comm log: if (g_ShouldLogCommIn) { - m_CommLogFile.Printf("^^^^^^ Wrong number of bytes read for this packet (exp %d left, got %zu left) ^^^^^^\n\n\n", + m_CommLogFile.Printf("^^^^^^ Wrong number of bytes read for this packet (exp %d left, got " SIZE_T_FMT " left) ^^^^^^\n\n\n", 1, bb.GetReadableSpace() ); m_CommLogFile.Flush(); @@ -1373,7 +1373,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, int a_Size) ASSERT(m_ReceivedData.GetReadableSpace() == OldReadableSpace); AString Hex; CreateHexDump(Hex, AllData.data(), AllData.size(), 16); - m_CommLogFile.Printf("There are %zu (0x%zx) bytes of non-parse-able data left in the buffer:\n%s", + m_CommLogFile.Printf("There are " SIZE_T_FMT " (0x" SIZE_T_FMT_HEX ") bytes of non-parse-able data left in the buffer:\n%s", m_ReceivedData.GetReadableSpace(), m_ReceivedData.GetReadableSpace(), Hex.c_str() ); m_CommLogFile.Flush(); @@ -2062,7 +2062,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) { AString HexDump; CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16); - LOGWARNING("Cannot unGZIP item metadata (%zu bytes):\n%s", a_Metadata.size(), HexDump.c_str()); + LOGWARNING("Cannot unGZIP item metadata (" SIZE_T_FMT " bytes):\n%s", a_Metadata.size(), HexDump.c_str()); return; } @@ -2072,7 +2072,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) { AString HexDump; CreateHexDump(HexDump, Uncompressed.data(), Uncompressed.size(), 16); - LOGWARNING("Cannot parse NBT item metadata: (%zu bytes)\n%s", Uncompressed.size(), HexDump.c_str()); + LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", Uncompressed.size(), HexDump.c_str()); return; } diff --git a/src/Root.cpp b/src/Root.cpp index 9a5dcac71..3555afb45 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -778,11 +778,11 @@ void cRoot::LogChunkStats(cCommandOutputCallback & a_Output) int Mem = NumValid * sizeof(cChunk); a_Output.Out(" Memory used by chunks: %d KiB (%d MiB)", (Mem + 1023) / 1024, (Mem + 1024 * 1024 - 1) / (1024 * 1024)); a_Output.Out(" Per-chunk memory size breakdown:"); - a_Output.Out(" block types: %6zu bytes (%3zu KiB)", sizeof(cChunkDef::BlockTypes), (sizeof(cChunkDef::BlockTypes) + 1023) / 1024); - a_Output.Out(" block metadata: %6zu bytes (%3zu KiB)", sizeof(cChunkDef::BlockNibbles), (sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); - a_Output.Out(" block lighting: %6zu bytes (%3zu KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); - a_Output.Out(" heightmap: %6zu bytes (%3zu KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024); - a_Output.Out(" biomemap: %6zu bytes (%3zu KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024); + a_Output.Out(" block types: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", sizeof(cChunkDef::BlockTypes), (sizeof(cChunkDef::BlockTypes) + 1023) / 1024); + a_Output.Out(" block metadata: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", sizeof(cChunkDef::BlockNibbles), (sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); + a_Output.Out(" block lighting: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", 2 * sizeof(cChunkDef::BlockNibbles), (2 * sizeof(cChunkDef::BlockNibbles) + 1023) / 1024); + a_Output.Out(" heightmap: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", sizeof(cChunkDef::HeightMap), (sizeof(cChunkDef::HeightMap) + 1023) / 1024); + a_Output.Out(" biomemap: " SIZE_T_FMT_PRECISION(6) " bytes (" SIZE_T_FMT_PRECISION(3) " KiB)", sizeof(cChunkDef::BiomeMap), (sizeof(cChunkDef::BiomeMap) + 1023) / 1024); int Rest = sizeof(cChunk) - sizeof(cChunkDef::BlockTypes) - 3 * sizeof(cChunkDef::BlockNibbles) - sizeof(cChunkDef::HeightMap) - sizeof(cChunkDef::BiomeMap); a_Output.Out(" other: %6d bytes (%3d KiB)", Rest, (Rest + 1023) / 1024); SumNumValid += NumValid; diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 5249a4bca..aae7b99a3 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -637,7 +637,7 @@ int cWindow::DistributeItemToSlots(cPlayer & a_Player, const cItem & a_Item, int { if ((size_t)(a_Item.m_ItemCount) < a_SlotNums.size()) { - LOGWARNING("%s: Distributing less items (%d) than slots (%zu)", __FUNCTION__, (int)a_Item.m_ItemCount, a_SlotNums.size()); + LOGWARNING("%s: Distributing less items (%d) than slots (" SIZE_T_FMT ")", __FUNCTION__, (int)a_Item.m_ItemCount, a_SlotNums.size()); // This doesn't seem to happen with the 1.5.1 client, so we don't worry about it for now return 0; } diff --git a/src/World.cpp b/src/World.cpp index 3a6e63e57..8c3a1ff8a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -102,7 +102,7 @@ protected: { for (;;) { - LOG("%zu chunks to load, %d chunks to generate", + LOG("" SIZE_T_FMT " chunks to load, %d chunks to generate", m_World->GetStorage().GetLoadQueueLength(), m_World->GetGenerator().GetQueueLength() ); @@ -154,7 +154,7 @@ protected: { for (;;) { - LOG("%zu chunks remaining to light", m_Lighting->GetQueueLength() + LOG("" SIZE_T_FMT " chunks remaining to light", m_Lighting->GetQueueLength() ); // Wait for 2 sec, but be "reasonably wakeable" when the thread is to finish diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index b1e8d12b7..bb9d4b9e6 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -569,7 +569,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() if( ChunksConverted % 32 == 0 ) { - LOGINFO("Updating \"%s\" version 1 to version 2: %zu %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); + LOGINFO("Updating \"%s\" version 1 to version 2: " SIZE_T_FMT " %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); } ChunksConverted++; @@ -607,7 +607,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() if (UncompressedSize != (int)UncompressedData.size()) { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got %zu) for chunk [%d, %d]", + LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]", UncompressedSize, UncompressedData.size(), Header->m_ChunkX, Header->m_ChunkZ ); @@ -713,7 +713,7 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3() if( ChunksConverted % 32 == 0 ) { - LOGINFO("Updating \"%s\" version 2 to version 3: %zu %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); + LOGINFO("Updating \"%s\" version 2 to version 3: " SIZE_T_FMT " %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() ); } ChunksConverted++; @@ -751,7 +751,7 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3() if (UncompressedSize != (int)UncompressedData.size()) { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got %zu) for chunk [%d, %d]", + LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]", UncompressedSize, UncompressedData.size(), Header->m_ChunkX, Header->m_ChunkZ ); @@ -866,7 +866,7 @@ bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_Uncomp if (a_UncompressedSize != (int)UncompressedData.size()) { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got %zu) for chunk [%d, %d]", + LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]", a_UncompressedSize, UncompressedData.size(), a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ ); -- cgit v1.2.3 From 9a28d1bbe1fc85981ded03e1d190612e6a688b5e Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 12 Mar 2014 11:56:24 -0700 Subject: Fixed comma --- src/Globals.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Globals.h b/src/Globals.h index 08d9e971a..45d403f27 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -39,7 +39,7 @@ #define ALIGN_8 #define ALIGN_16 - #define FORMATSTRING(formatIndex,va_argsIndex) + #define FORMATSTRING(formatIndex, va_argsIndex) // MSVC has its own custom version of zu format #define SIZE_T_FMT "%Iu" @@ -64,7 +64,7 @@ // Some portability macros :) #define stricmp strcasecmp - #define FORMATSTRING(formatIndex,va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) + #define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) #define SIZE_T_FMT "%zu" #define SIZE_T_FMT_PRECISION(x) "%" #x "zu" -- cgit v1.2.3 From bba090ebddd4662f30dc86d3ce20073ef0fc2f6c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 14 Mar 2014 11:18:14 +0100 Subject: cPluginManager:Bind[Console]Command returns true on success. Fixes #801. --- MCServer/Plugins/APIDump/APIDesc.lua | 8 ++++---- src/Bindings/ManualBindings.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 3c99b82de..c5599b212 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1794,13 +1794,13 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); }, BindCommand = { - { Params = "Command, Permission, Callback, HelpString", Return = "", Notes = "(STATIC) Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display." }, - { Params = "Command, Permission, Callback, HelpString", Return = "", Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display." }, + { Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error." }, + { Params = "Command, Permission, Callback, HelpString", Return = "[bool]", Notes = "Binds an in-game command with the specified callback function, permission and help string. By common convention, providing an empty string for HelpString will hide the command from the /help display. Returns true if successful, logs to console and returns no value on error." }, }, BindConsoleCommand = { - { Params = "Command, Callback, HelpString", Return = "", Notes = "(STATIC) Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command." }, - { Params = "Command, Callback, HelpString", Return = "", Notes = "Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command." }, + { Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "(STATIC) Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error." }, + { Params = "Command, Callback, HelpString", Return = "[bool]", Notes = "Binds a console command with the specified callback function and help string. By common convention, providing an empty string for HelpString will hide the command from the \"help\" console command. Returns true if successful, logs to console and returns no value on error." }, }, CallPlugin = { Params = "PluginName, FunctionName, [FunctionArgs...]", Return = "[FunctionRets]", Notes = "(STATIC) Calls the specified function in the specified plugin, passing all the given arguments to it. If it succeeds, it returns all the values returned by that function. If it fails, returns no value at all. Note that only strings, numbers, bools, nils and classes can be used for parameters and return values; tables and functions cannot be copied across plugins." }, DisablePlugin = { Params = "PluginName", Return = "bool", Notes = "Disables a plugin specified by its name. Returns true if the plugin was disabled, false if it wasn't found or wasn't active." }, diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index a5247bbe6..462ef3682 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1497,7 +1497,8 @@ static int tolua_cPluginManager_BindCommand(lua_State * L) } Plugin->BindCommand(Command, FnRef); - return 0; + lua_pushboolean(L, true); + return 1; } @@ -1561,7 +1562,8 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L) } Plugin->BindConsoleCommand(Command, FnRef); - return 0; + lua_pushboolean(L, true); + return 1; } -- cgit v1.2.3 From cd6ab5617cd7b26b13cfe26a950ca17fecefd550 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 06:11:49 -0700 Subject: Fixed xofts issues --- src/ByteBuffer.cpp | 2 +- src/CommandOutput.cpp | 4 ++-- src/CommandOutput.h | 2 +- src/Generating/PieceGenerator.h | 4 ++-- src/Globals.h | 3 ++- src/Log.cpp | 2 +- src/Log.h | 4 ++-- src/MCLogger.h | 16 ++++++++-------- src/OSSupport/File.h | 2 +- src/StringUtils.h | 8 ++++---- 10 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index d3bcfe866..1893d89a8 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -767,7 +767,7 @@ bool cByteBuffer::ReadUTF16String(AString & a_String, int a_NumChars) { return false; } - RawBEToUTF8((RawData.data()), a_NumChars, a_String); + RawBEToUTF8(RawData.data(), a_NumChars, a_String); return true; } diff --git a/src/CommandOutput.cpp b/src/CommandOutput.cpp index 74f857284..2c116b3d6 100644 --- a/src/CommandOutput.cpp +++ b/src/CommandOutput.cpp @@ -51,7 +51,7 @@ void cLogCommandOutputCallback::Finished(void) { case '\n': { - LOG("%s",m_Buffer.substr(last, i - last).c_str()); + LOG("%s", m_Buffer.substr(last, i - last).c_str()); last = i + 1; break; } @@ -59,7 +59,7 @@ void cLogCommandOutputCallback::Finished(void) } // for i - m_Buffer[] if (last < len) { - LOG("%s",m_Buffer.substr(last).c_str()); + LOG("%s", m_Buffer.substr(last).c_str()); } // Clear the buffer for the next command output: diff --git a/src/CommandOutput.h b/src/CommandOutput.h index 81d9ddb84..5682b4fd8 100644 --- a/src/CommandOutput.h +++ b/src/CommandOutput.h @@ -17,7 +17,7 @@ public: virtual ~cCommandOutputCallback() {}; // Force a virtual destructor in subclasses /// Syntax sugar function, calls Out() with Printf()-ed parameters; appends a "\n" - void Out(const char * a_Fmt, ...) FORMATSTRING(2,3); + void Out(const char * a_Fmt, ...) FORMATSTRING(2, 3); /// Called when the command wants to output anything; may be called multiple times virtual void Out(const AString & a_Text) = 0; diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 3386d7a94..bef9d3463 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -122,9 +122,9 @@ public: const cPiece & GetPiece (void) const { return *m_Piece; } const Vector3i & GetCoords (void) const { return m_Coords; } - int GetNumCCWRotations(void) const { return m_NumCCWRotations; } + int GetNumCCWRotations(void) const { return m_NumCCWRotations; } const cCuboid & GetHitBox (void) const { return m_HitBox; } - int GetDepth (void) const { return m_Depth; } + int GetDepth (void) const { return m_Depth; } protected: const cPlacedPiece * m_Parent; diff --git a/src/Globals.h b/src/Globals.h index 45d403f27..c2542f0d8 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -114,7 +114,8 @@ template class SizeChecker; template -class SizeChecker { +class SizeChecker +{ T v; }; diff --git a/src/Log.cpp b/src/Log.cpp index 395326398..a7be04b1a 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -118,7 +118,7 @@ void cLog::Log(const char * a_Format, va_list argList) AString Line; #ifdef _DEBUG - Printf(Line, "[" SIZE_T_FMT_PRECISION(04) "|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); + Printf(Line, "[%04lx|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); #else Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); #endif diff --git a/src/Log.h b/src/Log.h index 340fa23bc..d6a406154 100644 --- a/src/Log.h +++ b/src/Log.h @@ -14,8 +14,8 @@ private: public: cLog(const AString & a_FileName); ~cLog(); - void Log(const char * a_Format, va_list argList) FORMATSTRING(2,0); - void Log(const char * a_Format, ...) FORMATSTRING(2,3); + void Log(const char * a_Format, va_list argList) FORMATSTRING(2, 0); + void Log(const char * a_Format, ...) FORMATSTRING(2, 3); // tolua_begin void SimpleLog(const char * a_String); void OpenLog(const char * a_FileName); diff --git a/src/MCLogger.h b/src/MCLogger.h index ba9e4827f..996e60329 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -21,10 +21,10 @@ public: // tolua_export ~cMCLogger(); // tolua_export - void Log(const char* a_Format, va_list a_ArgList) FORMATSTRING(2,0); - void Info(const char* a_Format, va_list a_ArgList) FORMATSTRING(2,0); - void Warn(const char* a_Format, va_list a_ArgList) FORMATSTRING(2,0); - void Error(const char* a_Format, va_list a_ArgList) FORMATSTRING(2,0); + void Log(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Info(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Warn(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Error(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); void LogSimple(const char* a_Text, int a_LogType = 0 ); // tolua_export @@ -57,10 +57,10 @@ private: -extern void LOG(const char* a_Format, ...) FORMATSTRING(1,2); -extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1,2); -extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1,2); -extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1,2); +extern void LOG(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index e229035b7..b394c5cb9 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -131,7 +131,7 @@ public: /** Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there). */ static AStringVector GetFolderContents(const AString & a_Folder); // Exported in ManualBindings.cpp - int Printf(const char * a_Fmt, ...) FORMATSTRING(2,3); + int Printf(const char * a_Fmt, ...) FORMATSTRING(2, 3); /** Flushes all the bufferef output into the file (only when writing) */ void Flush(void); diff --git a/src/StringUtils.h b/src/StringUtils.h index 728ce31e6..4feff7553 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -22,16 +22,16 @@ typedef std::list AStringList; /** Add the formated string to the existing data in the string */ -extern AString & AppendVPrintf(AString & str, const char * format, va_list args) FORMATSTRING(2,0); +extern AString & AppendVPrintf(AString & str, const char * format, va_list args) FORMATSTRING(2, 0); /// Output the formatted text into the string -extern AString & Printf (AString & str, const char * format, ...) FORMATSTRING(2,3); +extern AString & Printf (AString & str, const char * format, ...) FORMATSTRING(2, 3); /// Output the formatted text into string, return string by value -extern AString Printf(const char * format, ...) FORMATSTRING(1,2); +extern AString Printf(const char * format, ...) FORMATSTRING(1, 2); /// Add the formatted string to the existing data in the string -extern AString & AppendPrintf (AString & str, const char * format, ...) FORMATSTRING(2,3); +extern AString & AppendPrintf (AString & str, const char * format, ...) FORMATSTRING(2, 3); /// Split the string at any of the listed delimiters, return as a stringvector extern AStringVector StringSplit(const AString & str, const AString & delim); -- cgit v1.2.3 From 35fe96b07d2bccb98eca4681b7fbf45b18009b9c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 14 Mar 2014 14:36:44 +0100 Subject: Fixed a warning. --- src/World.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/World.cpp b/src/World.cpp index 3d01dc40f..c314a36da 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2453,14 +2453,14 @@ cPlayer * cWorld::FindClosestPlayer(const Vector3d & a_Pos, float a_SightLimit, { cTracer LineOfSight(this); - float ClosestDistance = a_SightLimit; - cPlayer* ClosestPlayer = NULL; + double ClosestDistance = a_SightLimit; + cPlayer * ClosestPlayer = NULL; cCSLock Lock(m_CSPlayers); for (cPlayerList::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Vector3f Pos = (*itr)->GetPosition(); - float Distance = (Pos - a_Pos).Length(); + double Distance = (Pos - a_Pos).Length(); if (Distance < ClosestDistance) { -- cgit v1.2.3 From 9b63156447882c57698aba48da37c82cc0f0b428 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 14 Mar 2014 14:37:39 +0100 Subject: cPlugin:BindConsoleCommand can be called statically. This has been documented before it was written. --- src/Bindings/ManualBindings.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 462ef3682..20bbc48f2 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1522,7 +1522,10 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L) // Read the arguments to this API call: tolua_Error tolua_err; int idx = 1; - if (tolua_isusertype(L, 1, "cPluginManager", 0, &tolua_err)) + if ( + tolua_isusertype(L, 1, "cPluginManager", 0, &tolua_err) || + tolua_isusertable(L, 1, "cPluginManager", 0, &tolua_err) + ) { idx++; } -- cgit v1.2.3 From 22cdbe99b434a4442502c292bd541093a80cc9b7 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 06:44:04 -0700 Subject: Fixed a couple of missing defs --- SetFlags.cmake | 2 +- src/BoundingBox.cpp | 2 +- src/CompositeChat.cpp | 2 +- src/Noise.cpp | 8 -------- 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 42cfa6769..cdafcaa83 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -198,7 +198,7 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") - add_flags_cxx("-Wno-missing-noreturn -Wno-error=unreachable-code -Wno-error=undef") + add_flags_cxx("-Wno-missing-noreturn -Wno-error=unreachable-code") endif() endif() diff --git a/src/BoundingBox.cpp b/src/BoundingBox.cpp index aab51c539..482f9923f 100644 --- a/src/BoundingBox.cpp +++ b/src/BoundingBox.cpp @@ -10,7 +10,7 @@ -#if SELF_TEST +#ifdef SELF_TEST /** A simple self-test that is executed on program start, used to verify bbox functionality */ static class SelfTest_BoundingBox diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index 19ed30d78..a917ee70f 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -10,7 +10,7 @@ -#if SELF_TEST +#ifdef SELF_TEST /** A simple self-test that verifies that the composite chat parser is working properly. */ class SelfTest_CompositeChat diff --git a/src/Noise.cpp b/src/Noise.cpp index 5f23a47f9..a97ea70c6 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -3,14 +3,6 @@ #include "Noise.h" - - - - -#if NOISE_USE_SSE - #include //_mm_mul_epi32 -#endif - #define FAST_FLOOR(x) (((x) < 0) ? (((int)x) - 1) : ((int)x)) -- cgit v1.2.3 From e61810e1bf67dc43861d4741b16e65b30fe8d23c Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 06:52:49 -0700 Subject: Removed invalid block face handling code The code for handling invalid block faces is removed by gcc and clang as it is undefined behavior for a enum to contain a value that is not part of the enum. Since the only way that the line can be executed is through undefined behavior clang and gcc remove it so the function fits in the caches better. --- src/Defines.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Defines.h b/src/Defines.h index 3b7654265..2e412209d 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -290,7 +290,6 @@ inline AString BlockFaceToString(eBlockFace a_BlockFace) case BLOCK_FACE_ZP: return "BLOCK_FACE_ZP"; case BLOCK_FACE_NONE: return "BLOCK_FACE_NONE"; } - return Printf("Unknown BLOCK_FACE: %d", a_BlockFace); } -- cgit v1.2.3 From 58fa8b40bf5700327d99d96d656994dab619b670 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 07:02:57 -0700 Subject: Removed missiterperatable malfunctioning error handling code --- src/Scoreboard.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index 8088e624b..cfeb1d619 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -30,8 +30,6 @@ AString cObjective::TypeToString(eType a_Type) case otStatBlockMine: return "stat.mineBlock"; case otStatEntityKill: return "stat.killEntity"; case otStatEntityKilledBy: return "stat.entityKilledBy"; - - default: return ""; } } -- cgit v1.2.3 From b829c9b14e95f37a3a5ba70fc42cb8cfe9066522 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 07:12:00 -0700 Subject: Fixed a few unneeded breaks --- src/Map.cpp | 4 +++- src/StringUtils.cpp | 1 - src/main.cpp | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Map.cpp b/src/Map.cpp index 2d8f57168..79370b097 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -243,7 +243,7 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z) { for (unsigned int Z = m_RelZ; Z < m_RelZ + PixelWidth; ++Z) { - unsigned int WaterDepth = 0; + // unsigned int WaterDepth = 0; BLOCKTYPE TargetBlock = E_BLOCK_AIR; NIBBLETYPE TargetMeta = 0; @@ -261,12 +261,14 @@ bool cMap::UpdatePixel(unsigned int a_X, unsigned int a_Z) continue; } // TODO 2014-02-22 xdot: Check if block is liquid + /* else if (false) { --Height; ++WaterDepth; continue; } + */ break; } diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp index 3f9275798..ad622d707 100644 --- a/src/StringUtils.cpp +++ b/src/StringUtils.cpp @@ -454,7 +454,6 @@ AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a if (!isLegalUTF8(source, extraBytesToRead + 1)) { return a_UTF16; - break; } // The cases all fall through. See "Note A" below. diff --git a/src/main.cpp b/src/main.cpp index 2ae8a413b..68eea7f4d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -72,7 +72,6 @@ void NonCtrlHandler(int a_Signal) LOGERROR(" D: | MCServer has encountered an error and needs to close"); LOGERROR("Details | SIGABRT: Server self-terminated due to an internal fault"); exit(EXIT_FAILURE); - break; } case SIGINT: case SIGTERM: -- cgit v1.2.3 From fed461bf2a6bf4e6dc2b6d0cc66b8e806806a859 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 07:12:18 -0700 Subject: Made unreachable code an error --- SetFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 42cfa6769..b22449142 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -198,7 +198,7 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") - add_flags_cxx("-Wno-missing-noreturn -Wno-error=unreachable-code -Wno-error=undef") + add_flags_cxx("-Wno-missing-noreturn -Wno-error=undef") endif() endif() -- cgit v1.2.3 From cd7ef264be438a7c1b19eb6a0478ed5748e551bd Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 07:16:55 -0700 Subject: Disable global constructors and exit-time destructors warnings --- SetFlags.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 42cfa6769..05f2b90c0 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -196,8 +196,8 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=deprecated -Wno-error=weak-vtables -Wno-error=float-equal") add_flags_cxx("-Wno-error=missing-prototypes -Wno-error=non-virtual-dtor") add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") - add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") - add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") + add_flags_cxx("-Wno-exit-time-destructors -Wno-error=missing-variable-declarations") + add_flags_cxx("-Wno-global-constructors -Wno-implicit-fallthrough") add_flags_cxx("-Wno-missing-noreturn -Wno-error=unreachable-code -Wno-error=undef") endif() endif() -- cgit v1.2.3 From 2f81c1d7fbe7932da055581aa815edc9f6ff8191 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 07:33:47 -0700 Subject: Added NORETURN macro --- src/Globals.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Globals.h b/src/Globals.h index c2542f0d8..a5b9d391a 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -45,6 +45,8 @@ #define SIZE_T_FMT "%Iu" #define SIZE_T_FMT_PRECISION(x) "%" #x "Iu" #define SIZE_T_FMT_HEX "%Ix" + + #define NORETURN __declspec(noreturn) #elif defined(__GNUC__) @@ -69,6 +71,8 @@ #define SIZE_T_FMT "%zu" #define SIZE_T_FMT_PRECISION(x) "%" #x "zu" #define SIZE_T_FMT_HEX "%zx" + + #define NORETURN __attribute((__noreturn__)) #else -- cgit v1.2.3 From 8e11c270fc786a8b8b72aed71cf8feee659c4876 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 07:59:25 -0700 Subject: Added Noreturn attribtes to a couple of functions and made a missing noreturn an error --- SetFlags.cmake | 2 +- src/Bindings/LuaState.h | 2 +- src/DeadlockDetect.h | 2 +- src/Globals.h | 11 +++++++++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 42cfa6769..e636c5c95 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -198,7 +198,7 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") - add_flags_cxx("-Wno-missing-noreturn -Wno-error=unreachable-code -Wno-error=undef") + add_flags_cxx("-Wno-error=unreachable-code -Wno-error=undef") endif() endif() diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 73f9629cb..f5cb8379d 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -200,7 +200,7 @@ public: void Push(const HTTPTemplateRequest * a_Request); void Push(cTNTEntity * a_TNTEntity); void Push(Vector3i * a_Vector); - void Push(void * a_Ptr); + NORETURNDEBUG void Push(void * a_Ptr); void Push(cHopperEntity * a_Hopper); void Push(cBlockEntity * a_BlockEntity); diff --git a/src/DeadlockDetect.h b/src/DeadlockDetect.h index cb2309169..6aa98acbb 100644 --- a/src/DeadlockDetect.h +++ b/src/DeadlockDetect.h @@ -60,7 +60,7 @@ protected: void CheckWorldAge(const AString & a_WorldName, Int64 a_Age); /// Called when a deadlock is detected. Aborts the server. - void DeadlockDetected(void); + NORETURN void DeadlockDetected(void); } ; diff --git a/src/Globals.h b/src/Globals.h index a5b9d391a..3e62832b7 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -46,7 +46,7 @@ #define SIZE_T_FMT_PRECISION(x) "%" #x "Iu" #define SIZE_T_FMT_HEX "%Ix" - #define NORETURN __declspec(noreturn) + #define NORETURN __declspec(noreturn) #elif defined(__GNUC__) @@ -72,7 +72,7 @@ #define SIZE_T_FMT_PRECISION(x) "%" #x "zu" #define SIZE_T_FMT_HEX "%zx" - #define NORETURN __attribute((__noreturn__)) + #define NORETURN __attribute((__noreturn__)) #else @@ -98,6 +98,13 @@ #endif +#ifdef _DEBUG + #define NORETURNDEBUG NORETURN +#else + #define NORETURNDEBUG +#endif + + #include -- cgit v1.2.3 From e3646fc877f52c848cfb8a383fdbe89140663199 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 08:05:35 -0700 Subject: Fixed a couple of unneeded returns in ProtoProxy --- Tools/ProtoProxy/Connection.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index 46119ff42..f02b503f1 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -387,8 +387,6 @@ bool cConnection::RelayFromServer(void) return CLIENTSEND(Buffer, res); } } - - return true; } @@ -425,8 +423,6 @@ bool cConnection::RelayFromClient(void) return SERVERSEND(Buffer, res); } } - - return true; } -- cgit v1.2.3 From a982b9b5ace6baab7dda4d7d905907009919dfea Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 14 Mar 2014 16:07:22 +0100 Subject: APIDump: Trigger the dump manually. Fixes #715. The dump can be triggerred by issuing an "api" console command, or in the webadmin. --- MCServer/Plugins/APIDump/main_APIDump.lua | 90 ++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 26 deletions(-) diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua index bd509dcb6..40b37f62c 100644 --- a/MCServer/Plugins/APIDump/main_APIDump.lua +++ b/MCServer/Plugins/APIDump/main_APIDump.lua @@ -9,22 +9,6 @@ -- Global variables: g_Plugin = nil; g_PluginFolder = ""; -g_TrackedPages = {}; -- List of tracked pages, to be checked later whether they exist. Each item is an array of referring pagenames. -g_Stats = -- Statistics about the documentation -{ - NumTotalClasses = 0, - NumUndocumentedClasses = 0, - NumTotalFunctions = 0, - NumUndocumentedFunctions = 0, - NumTotalConstants = 0, - NumUndocumentedConstants = 0, - NumTotalVariables = 0, - NumUndocumentedVariables = 0, - NumTotalHooks = 0, - NumUndocumentedHooks = 0, - NumTrackedLinks = 0, - NumInvalidLinks = 0, -} @@ -33,15 +17,34 @@ g_Stats = -- Statistics about the documentation function Initialize(Plugin) g_Plugin = Plugin; - - Plugin:SetName("APIDump"); - Plugin:SetVersion(1); + g_PluginFolder = Plugin:GetLocalFolder(); LOG("Initialising " .. Plugin:GetName() .. " v." .. Plugin:GetVersion()) - g_PluginFolder = Plugin:GetLocalFolder(); + cPluginManager:BindConsoleCommand("api", HandleCmdApi, "Dumps the Lua API docs into the API/ subfolder") + g_Plugin:AddWebTab("APIDump", HandleWebAdminDump) + -- TODO: Add a WebAdmin tab that has a Dump button + return true +end + + + + + +function HandleCmdApi(a_Split) + DumpApi() +end + + + + + +function DumpApi() + LOG("Dumping the API...") -- Load the API descriptions from the Classes and Hooks subfolders: + -- This needs to be done each time the command is invoked because the export modifies the tables' contents + dofile(g_PluginFolder .. "/APIDesc.lua") if (g_APIDesc.Classes == nil) then g_APIDesc.Classes = {}; end @@ -51,6 +54,24 @@ function Initialize(Plugin) LoadAPIFiles("/Classes/", g_APIDesc.Classes); LoadAPIFiles("/Hooks/", g_APIDesc.Hooks); + -- Reset the stats: + g_TrackedPages = {}; -- List of tracked pages, to be checked later whether they exist. Each item is an array of referring pagenames. + g_Stats = -- Statistics about the documentation + { + NumTotalClasses = 0, + NumUndocumentedClasses = 0, + NumTotalFunctions = 0, + NumUndocumentedFunctions = 0, + NumTotalConstants = 0, + NumUndocumentedConstants = 0, + NumTotalVariables = 0, + NumUndocumentedVariables = 0, + NumTotalHooks = 0, + NumUndocumentedHooks = 0, + NumTrackedLinks = 0, + NumInvalidLinks = 0, + } + -- dump all available API functions and objects: -- DumpAPITxt(); @@ -58,7 +79,6 @@ function Initialize(Plugin) DumpAPIHtml(); LOG("APIDump finished"); - return true end @@ -67,6 +87,9 @@ end function LoadAPIFiles(a_Folder, a_DstTable) + assert(type(a_Folder) == "string") + assert(type(a_DstTable) == "table") + local Folder = g_PluginFolder .. a_Folder; for idx, fnam in ipairs(cFile:GetFolderContents(Folder)) do local FileName = Folder .. fnam; @@ -317,6 +340,11 @@ end function DumpAPIHtml() LOG("Dumping all available functions and constants to API subfolder..."); + -- Create the output folder + if not(cFile:IsFolder("API")) then + cFile:CreateFolder("API"); + end + LOG("Copying static files.."); cFile:CreateFolder("API/Static"); local localFolder = g_Plugin:GetLocalFolder(); @@ -366,11 +394,6 @@ function DumpAPIHtml() ReadDescriptions(API); ReadHooks(Hooks); - -- Create the output folder - if not(cFile:IsFolder("API")) then - cFile:CreateFolder("API"); - end - -- Create a "class index" file, write each class as a link to that file, -- then dump class contents into class-specific file LOG("Writing HTML files..."); @@ -1428,3 +1451,18 @@ end + +function HandleWebAdminDump(a_Request) + if (a_Request.PostParams["Dump"] ~= nil) then + DumpApi() + end + return + [[ +

Pressing the button will generate the API dump on the server. Note that this can take some time.

+
+ ]] +end + + + + -- cgit v1.2.3 From dc1049da3cd8dbf77ba96caf75550711ca0fba86 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 14 Mar 2014 16:08:25 +0100 Subject: Ignoring all config and SQLite files in the output folder. --- MCServer/.gitignore | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/MCServer/.gitignore b/MCServer/.gitignore index 0fd04ef59..64f062ef7 100644 --- a/MCServer/.gitignore +++ b/MCServer/.gitignore @@ -19,10 +19,8 @@ schematics *.pdb memdump* *.grab -Galleries.cfg -Galleries.example.cfg -Galleries.sqlite -ProtectionAreas.sqlite +*.cfg +*.sqlite helgrind.log valgrind.log motd.txt -- cgit v1.2.3 From ccc29c7c6c344b00e5b6c9236cf615b253b9a1b5 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 14 Mar 2014 23:52:51 +0100 Subject: Add fireball interact --- src/BlockEntities/DispenserEntity.cpp | 6 ++++++ src/Items/ItemHandler.cpp | 1 + src/Items/ItemItemFrame.h | 6 +++++- src/Items/ItemLighter.h | 22 +++++++++++++++++++++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index cbfbb1b6a..e03bf776d 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -138,6 +138,12 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) break; } + case E_ITEM_FIRE_CHARGE: + { + // TODO: Spawn fireball entity + break; + } + default: { DropFromSlot(a_Chunk, a_SlotNum); diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 1d357fcf1..232791f99 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -107,6 +107,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_EGG: return new cItemEggHandler(); case E_ITEM_EMPTY_MAP: return new cItemEmptyMapHandler(); case E_ITEM_ENDER_PEARL: return new cItemEnderPearlHandler(); + case E_ITEM_FIRE_CHARGE: return new cItemLighterHandler(a_ItemType); case E_ITEM_FIREWORK_ROCKET: return new cItemFireworkHandler(); case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType); case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType); diff --git a/src/Items/ItemItemFrame.h b/src/Items/ItemItemFrame.h index 74e987445..27e7dba35 100644 --- a/src/Items/ItemItemFrame.h +++ b/src/Items/ItemItemFrame.h @@ -34,7 +34,11 @@ public: if (Block == E_BLOCK_AIR) { cItemFrame * ItemFrame = new cItemFrame(a_Dir, a_BlockX, a_BlockY, a_BlockZ); - ItemFrame->Initialize(a_World); + if (!ItemFrame->Initialize(a_World)) + { + delete ItemFrame; + return false; + } if (!a_Player->IsGameModeCreative()) { diff --git a/src/Items/ItemLighter.h b/src/Items/ItemLighter.h index 18873e911..2db6c829a 100644 --- a/src/Items/ItemLighter.h +++ b/src/Items/ItemLighter.h @@ -26,7 +26,26 @@ public: return false; } - a_Player->UseEquippedItem(); + if (!a_Player->IsGameModeCreative()) + { + switch (m_ItemType) + { + case E_ITEM_FLINT_AND_STEEL: + { + a_Player->UseEquippedItem(); + break; + } + case E_ITEM_FIRE_CHARGE: + { + a_Player->GetInventory().RemoveOneEquippedItem(); + break; + } + default: + { + ASSERT(!"Unknown Lighter Item!"); + } + } + } switch (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ)) { @@ -49,6 +68,7 @@ public: if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_AIR) { a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FIRE, 0); + a_World->BroadcastSoundEffect("fire.ignite", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0F, 1.04F); break; } } -- cgit v1.2.3 From 28898f710b191abb610f31085d6ae076511cc89c Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Mar 2014 00:32:49 +0100 Subject: Add ExpOrb saving. --- src/Entities/ExpOrb.cpp | 26 ++++++--- src/Entities/ExpOrb.h | 16 +++++- src/Entities/Pickup.cpp | 2 +- src/WorldStorage/NBTChunkSerializer.cpp | 17 +++++- src/WorldStorage/NBTChunkSerializer.h | 2 + src/WorldStorage/WSSAnvil.cpp | 96 ++++++++++++++++++++++++--------- src/WorldStorage/WSSAnvil.h | 3 +- 7 files changed, 124 insertions(+), 38 deletions(-) diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp index 3398f1c7b..3623c869a 100644 --- a/src/Entities/ExpOrb.cpp +++ b/src/Entities/ExpOrb.cpp @@ -5,20 +5,26 @@ #include "../ClientHandle.h" -cExpOrb::cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward) : - cEntity(etExpOrb, a_X, a_Y, a_Z, 0.98, 0.98), - m_Reward(a_Reward) +cExpOrb::cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward) + : cEntity(etExpOrb, a_X, a_Y, a_Z, 0.98, 0.98) + , m_Reward(a_Reward) + , m_Timer(0.f) { + SetMaxHealth(5); + SetHealth(5); } -cExpOrb::cExpOrb(const Vector3d & a_Pos, int a_Reward) : - cEntity(etExpOrb, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98), - m_Reward(a_Reward) +cExpOrb::cExpOrb(const Vector3d & a_Pos, int a_Reward) + : cEntity(etExpOrb, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98) + , m_Reward(a_Reward) + , m_Timer(0.f) { + SetMaxHealth(5); + SetHealth(5); } @@ -52,7 +58,7 @@ void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk) LOGD("Player %s picked up an ExpOrb. His reward is %i", a_ClosestPlayer->GetName().c_str(), m_Reward); a_ClosestPlayer->DeltaExperience(m_Reward); - m_World->BroadcastSoundEffect("random.orb", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); + m_World->BroadcastSoundEffect("random.orb", (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 0.5f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); Destroy(); } @@ -64,4 +70,10 @@ void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk) BroadcastMovementUpdate(); } HandlePhysics(a_Dt, a_Chunk); + + m_Timer += a_Dt; + if (m_Timer >= 1000 * 60 * 5) // 5 minutes + { + Destroy(true); + } } diff --git a/src/Entities/ExpOrb.h b/src/Entities/ExpOrb.h index 47d86922c..b75859e4c 100644 --- a/src/Entities/ExpOrb.h +++ b/src/Entities/ExpOrb.h @@ -21,10 +21,22 @@ public: // Override functions virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void SpawnOn(cClientHandle & a_Client) override; + + /** Returns the number of ticks that this entity has existed */ + int GetAge(void) const { return (int)(m_Timer / 50); } // tolua_export + + /** Set the number of ticks that this entity has existed */ + void SetAge(int a_Age) { m_Timer = (float)(a_Age * 50); } // tolua_export - // cExpOrb functions - int GetReward(void) const { return m_Reward; } + /** Get the exp amount */ + int GetReward(void) const { return m_Reward; } // tolua_export + + /** Set the exp amount */ + void SetReward(int a_Reward) { m_Reward = a_Reward; } // tolua_export protected: int m_Reward; + + /** The number of ticks that the entity has existed / timer between collect and destroy; in msec */ + float m_Timer; } ; \ No newline at end of file diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index c5503c16a..7fc89b62b 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -82,7 +82,7 @@ cPickup::cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_It void cPickup::SpawnOn(cClientHandle & a_Client) { - a_Client.SendPickupSpawn(*this); + a_Client.SendPickupSpawn(*this); } diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 17cf838c3..fa5547f46 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -29,6 +29,7 @@ #include "../Entities/Pickup.h" #include "../Entities/ProjectileEntity.h" #include "../Entities/TNTEntity.h" +#include "../Entities/ExpOrb.h" #include "../Mobs/Monster.h" #include "../Mobs/Bat.h" @@ -596,6 +597,20 @@ void cNBTChunkSerializer::AddTNTEntity(cTNTEntity * a_TNT) +void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb* a_ExpOrb) +{ + m_Writer.BeginCompound(""); + AddBasicEntity(a_ExpOrb, "XPOrb"); + m_Writer.AddShort("Health", (short)(unsigned char)a_ExpOrb->GetHealth()); + m_Writer.AddShort("Age", (short)a_ExpOrb->GetAge()); + m_Writer.AddShort("Value", (short)a_ExpOrb->GetReward()); + m_Writer.EndCompound(); +} + + + + + void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart) { m_Writer.BeginList("Items", TAG_Compound); @@ -676,7 +691,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) case cEntity::etPickup: AddPickupEntity ((cPickup *) a_Entity); break; case cEntity::etProjectile: AddProjectileEntity ((cProjectileEntity *)a_Entity); break; case cEntity::etTNT: AddTNTEntity ((cTNTEntity *) a_Entity); break; - case cEntity::etExpOrb: /* TODO */ break; + case cEntity::etExpOrb: AddExpOrbEntity ((cExpOrb *) a_Entity); break; case cEntity::etItemFrame: /* TODO */ break; case cEntity::etPainting: /* TODO */ break; case cEntity::etPlayer: return; // Players aren't saved into the world diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 3b486d2bc..22c309067 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -42,6 +42,7 @@ class cPickup; class cItemGrid; class cProjectileEntity; class cTNTEntity; +class cExpOrb; @@ -109,6 +110,7 @@ protected: void AddPickupEntity (cPickup * a_Pickup); void AddProjectileEntity (cProjectileEntity * a_Projectile); void AddTNTEntity (cTNTEntity * a_TNT); + void AddExpOrbEntity (cExpOrb * a_ExpOrb); void AddMinecartChestContents(cMinecartWithChest * a_Minecart); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index b52b74932..c180f715f 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -37,6 +37,7 @@ #include "../Entities/Pickup.h" #include "../Entities/ProjectileEntity.h" #include "../Entities/TNTEntity.h" +#include "../Entities/ExpOrb.h" @@ -1092,6 +1093,14 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadPickupFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } + else if (strncmp(a_IDTag, "PrimedTnt", a_IDTagLength) == 0) + { + LoadTNTFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } + else if (strncmp(a_IDTag, "XPOrb", a_IDTagLength) == 0) + { + LoadExpOrbFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } else if (strncmp(a_IDTag, "Arrow", a_IDTagLength) == 0) { LoadArrowFromNBT(a_Entities, a_NBT, a_EntityTagIdx); @@ -1232,10 +1241,6 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadPigZombieFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } - else if (strncmp(a_IDTag, "PrimedTnt", a_IDTagLength) == 0) - { - LoadTNTFromNBT(a_Entities, a_NBT, a_EntityTagIdx); - } // TODO: other entities } @@ -1393,6 +1398,9 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } + + // TODO: Add health and age + a_Entities.push_back(Pickup.release()); } @@ -1400,6 +1408,64 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a +void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr TNT(new cTNTEntity(0.0, 0.0, 0.0, 0)); + if (!LoadEntityBaseFromNBT(*TNT.get(), a_NBT, a_TagIdx)) + { + return; + } + + // Load Fuse Ticks: + int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse"); + if (FuseTicks > 0) + { + TNT->SetFuseTicks((int) a_NBT.GetByte(FuseTicks)); + } + + a_Entities.push_back(TNT.release()); +} + + + + + +void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr ExpOrb(new cExpOrb(0.0, 0.0, 0.0, 0)); + if (!LoadEntityBaseFromNBT(*ExpOrb.get(), a_NBT, a_TagIdx)) + { + return; + } + + // Load Health: + int Health = a_NBT.FindChildByName(a_TagIdx, "Health"); + if (Health > 0) + { + ExpOrb->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF)); + } + + // Load Age: + int Age = a_NBT.FindChildByName(a_TagIdx, "Age"); + if (Age > 0) + { + ExpOrb->SetAge(a_NBT.GetShort(Age)); + } + + // Load Reward (Value): + int Reward = a_NBT.FindChildByName(a_TagIdx, "Value"); + if (Reward > 0) + { + ExpOrb->SetReward(a_NBT.GetShort(Reward)); + } + + a_Entities.push_back(ExpOrb.release()); +} + + + + + void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { std::auto_ptr Arrow(new cArrowEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); @@ -2172,28 +2238,6 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT -void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) -{ - std::auto_ptr TNT(new cTNTEntity(0.0, 0.0, 0.0, 0)); - if (!LoadEntityBaseFromNBT(*TNT.get(), a_NBT, a_TagIdx)) - { - return; - } - - // Load Fuse Ticks: - int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse"); - if (FuseTicks > 0) - { - TNT->SetFuseTicks((int) a_NBT.GetByte(FuseTicks)); - } - - a_Entities.push_back(TNT.release()); -} - - - - - bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx) { double Pos[3]; diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index fe93d16c3..75b630d71 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -149,6 +149,8 @@ protected: void LoadBoatFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadFallingBlockFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPickupFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadExpOrbFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadMinecartRFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadMinecartCFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); @@ -192,7 +194,6 @@ protected: void LoadWolfFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPigZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); /// Loads entity common data from the NBT compound; returns true if successful bool LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx); -- cgit v1.2.3 From cf137392885479d4e3f057c64cb078a6025f4b25 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Mar 2014 00:43:38 +0100 Subject: Add health and age load to pickup's. --- src/CMakeLists.txt | 1 + src/Entities/ExpOrb.h | 15 +++++++++------ src/Entities/Pickup.h | 23 +++++++++++++---------- src/WorldStorage/NBTChunkSerializer.cpp | 10 +++++----- src/WorldStorage/WSSAnvil.cpp | 16 +++++++++++++++- 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5029906aa..52a792ba7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -59,6 +59,7 @@ if (NOT MSVC) Entities/Player.h Entities/ProjectileEntity.h Entities/TNTEntity.h + Entities/ExpOrb.h Generating/ChunkDesc.h Group.h Inventory.h diff --git a/src/Entities/ExpOrb.h b/src/Entities/ExpOrb.h index b75859e4c..c1150bd03 100644 --- a/src/Entities/ExpOrb.h +++ b/src/Entities/ExpOrb.h @@ -7,30 +7,33 @@ +// tolua_begin class cExpOrb : public cEntity { typedef cExpOrb super; public: + // tolua_end + CLASS_PROTODEF(cExpOrb); - + cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward); cExpOrb(const Vector3d & a_Pos, int a_Reward); // Override functions virtual void Tick(float a_Dt, cChunk & a_Chunk) override; virtual void SpawnOn(cClientHandle & a_Client) override; - + /** Returns the number of ticks that this entity has existed */ - int GetAge(void) const { return (int)(m_Timer / 50); } // tolua_export - + int GetAge(void) const { return (int)(m_Timer / 50); } // tolua_export + /** Set the number of ticks that this entity has existed */ void SetAge(int a_Age) { m_Timer = (float)(a_Age * 50); } // tolua_export /** Get the exp amount */ int GetReward(void) const { return m_Reward; } // tolua_export - + /** Set the exp amount */ void SetReward(int a_Reward) { m_Reward = a_Reward; } // tolua_export @@ -39,4 +42,4 @@ protected: /** The number of ticks that the entity has existed / timer between collect and destroy; in msec */ float m_Timer; -} ; \ No newline at end of file +} ; // tolua_export \ No newline at end of file diff --git a/src/Entities/Pickup.h b/src/Entities/Pickup.h index c273567d1..74b917bce 100644 --- a/src/Entities/Pickup.h +++ b/src/Entities/Pickup.h @@ -26,31 +26,34 @@ public: CLASS_PROTODEF(cPickup); cPickup(double a_PosX, double a_PosY, double a_PosZ, const cItem & a_Item, bool IsPlayerCreated, float a_SpeedX = 0.f, float a_SpeedY = 0.f, float a_SpeedZ = 0.f); - + cItem & GetItem(void) {return m_Item; } // tolua_export const cItem & GetItem(void) const {return m_Item; } virtual void SpawnOn(cClientHandle & a_ClientHandle) override; - + bool CollectedBy(cPlayer * a_Dest); // tolua_export virtual void Tick(float a_Dt, cChunk & a_Chunk) override; - - /// Returns the number of ticks that this entity has existed - int GetAge(void) const { return (int)(m_Timer / 50); } // tolua_export - - /// Returns true if the pickup has already been collected + + /** Returns the number of ticks that this entity has existed */ + int GetAge(void) const { return (int)(m_Timer / 50); } // tolua_export + + /** Set the number of ticks that this entity has existed */ + void SetAge(int a_Age) { m_Timer = (float)(a_Age * 50); } // tolua_export + + /** Returns true if the pickup has already been collected */ bool IsCollected(void) const { return m_bCollected; } // tolua_export - /// Returns true if created by player (i.e. vomiting), used for determining picking-up delay time + /** Returns true if created by player (i.e. vomiting), used for determining picking-up delay time */ bool IsPlayerCreated(void) const { return m_bIsPlayerCreated; } // tolua_export - + private: Vector3d m_ResultingSpeed; //Can be used to modify the resulting speed for the current tick ;) Vector3d m_WaterSpeed; - /// The number of ticks that the entity has existed / timer between collect and destroy; in msec + /** The number of ticks that the entity has existed / timer between collect and destroy; in msec */ float m_Timer; cItem m_Item; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index fa5547f46..37ebf0610 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -519,8 +519,8 @@ void cNBTChunkSerializer::AddPickupEntity(cPickup * a_Pickup) m_Writer.BeginCompound(""); AddBasicEntity(a_Pickup, "Item"); AddItem(a_Pickup->GetItem(), -1, "Item"); - m_Writer.AddShort("Health", a_Pickup->GetHealth()); - m_Writer.AddShort("Age", a_Pickup->GetAge()); + m_Writer.AddShort("Health", (Int16)(unsigned char)a_Pickup->GetHealth()); + m_Writer.AddShort("Age", (Int16)a_Pickup->GetAge()); m_Writer.EndCompound(); } @@ -601,9 +601,9 @@ void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb* a_ExpOrb) { m_Writer.BeginCompound(""); AddBasicEntity(a_ExpOrb, "XPOrb"); - m_Writer.AddShort("Health", (short)(unsigned char)a_ExpOrb->GetHealth()); - m_Writer.AddShort("Age", (short)a_ExpOrb->GetAge()); - m_Writer.AddShort("Value", (short)a_ExpOrb->GetReward()); + m_Writer.AddShort("Health", (Int16)(unsigned char)a_ExpOrb->GetHealth()); + m_Writer.AddShort("Age", (Int16)a_ExpOrb->GetAge()); + m_Writer.AddShort("Value", (Int16)a_ExpOrb->GetReward()); m_Writer.EndCompound(); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index c180f715f..bb0a831b3 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1383,6 +1383,7 @@ void cWSSAnvil::LoadMinecartHFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { + // Load item: int ItemTag = a_NBT.FindChildByName(a_TagIdx, "Item"); if ((ItemTag < 0) || (a_NBT.GetType(ItemTag) != TAG_Compound)) { @@ -1393,13 +1394,26 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } + std::auto_ptr Pickup(new cPickup(0, 0, 0, Item, false)); // Pickup delay doesn't matter, just say false if (!LoadEntityBaseFromNBT(*Pickup.get(), a_NBT, a_TagIdx)) { return; } - // TODO: Add health and age + // Load health: + int Health = a_NBT.FindChildByName(a_TagIdx, "Health"); + if (Health > 0) + { + Pickup->SetHealth((int) (a_NBT.GetShort(Health) & 0xFF)); + } + + // Load age: + int Age = a_NBT.FindChildByName(a_TagIdx, "Age"); + if (Age > 0) + { + Pickup->SetAge(a_NBT.GetShort(Age)); + } a_Entities.push_back(Pickup.release()); } -- cgit v1.2.3 From 7ac7304c913f9cf82a906589904068a3e7f09d43 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Mar 2014 02:45:25 +0100 Subject: Add item frame saving. --- src/CMakeLists.txt | 2 + src/Entities/HangingEntity.cpp | 53 ++++++++++++++++++++ src/Entities/HangingEntity.h | 49 +++++++++++++++++++ src/Entities/ItemFrame.cpp | 39 ++------------- src/Entities/ItemFrame.h | 22 +++++---- src/WorldStorage/NBTChunkSerializer.cpp | 40 +++++++++++++++- src/WorldStorage/NBTChunkSerializer.h | 4 ++ src/WorldStorage/WSSAnvil.cpp | 85 +++++++++++++++++++++++++++++++++ src/WorldStorage/WSSAnvil.h | 3 ++ 9 files changed, 251 insertions(+), 46 deletions(-) create mode 100644 src/Entities/HangingEntity.cpp create mode 100644 src/Entities/HangingEntity.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 52a792ba7..4ea5c69e9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,6 +60,8 @@ if (NOT MSVC) Entities/ProjectileEntity.h Entities/TNTEntity.h Entities/ExpOrb.h + Entities/HangingEntity.h + Entities/ItemFrame.h Generating/ChunkDesc.h Group.h Inventory.h diff --git a/src/Entities/HangingEntity.cpp b/src/Entities/HangingEntity.cpp new file mode 100644 index 000000000..41ac86268 --- /dev/null +++ b/src/Entities/HangingEntity.cpp @@ -0,0 +1,53 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "HangingEntity.h" +#include "ClientHandle.h" +#include "Player.h" + + + + + +cHangingEntity::cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z) + : cEntity(a_EntityType, a_X, a_Y, a_Z, 0.8, 0.8) + , m_BlockFace(a_BlockFace) +{ + SetMaxHealth(1); + SetHealth(1); +} + + + + + +void cHangingEntity::SpawnOn(cClientHandle & a_ClientHandle) +{ + int Dir = 0; + + // The client uses different values for item frame directions and block faces. Our constants are for the block faces, so we convert them here to item frame faces + switch (m_BlockFace) + { + case BLOCK_FACE_ZP: break; // Initialised to zero + case BLOCK_FACE_ZM: Dir = 2; break; + case BLOCK_FACE_XM: Dir = 1; break; + case BLOCK_FACE_XP: Dir = 3; break; + default: ASSERT(!"Unhandled block face when trying to spawn item frame!"); return; + } + + if ((Dir == 0) || (Dir == 2)) // Probably a client bug, but two directions are flipped and contrary to the norm, so we do -180 + { + SetYaw((Dir * 90) - 180); + } + else + { + SetYaw(Dir * 90); + } + + a_ClientHandle.SendSpawnObject(*this, 71, Dir, (Byte)GetYaw(), (Byte)GetPitch()); + a_ClientHandle.SendEntityMetadata(*this); +} + + + + diff --git a/src/Entities/HangingEntity.h b/src/Entities/HangingEntity.h new file mode 100644 index 000000000..6498e4b5b --- /dev/null +++ b/src/Entities/HangingEntity.h @@ -0,0 +1,49 @@ + +#pragma once + +#include "Entity.h" + + + + + +// tolua_begin +class cHangingEntity : + public cEntity +{ + // tolua_end + typedef cEntity super; + +public: + + CLASS_PROTODEF(cHangingEntity); + + cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z); + + /** Returns the orientation from the hanging entity */ + eBlockFace GetDirection() const { return m_BlockFace; } // tolua_export + + /** Set the orientation from the hanging entity */ + void SetDirection(eBlockFace a_BlockFace) { m_BlockFace = a_BlockFace; } // tolua_export + + /** Returns the X coord. */ + int GetTileX() const { return POSX_TOINT; } // tolua_export + + /** Returns the Y coord. */ + int GetTileY() const { return POSY_TOINT; } // tolua_export + + /** Returns the Z coord. */ + int GetTileZ() const { return POSZ_TOINT; } // tolua_export + +private: + + virtual void SpawnOn(cClientHandle & a_ClientHandle) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override {}; + + eBlockFace m_BlockFace; + +}; // tolua_export + + + + diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp index 8cfa5e18d..9dd909880 100644 --- a/src/Entities/ItemFrame.cpp +++ b/src/Entities/ItemFrame.cpp @@ -10,43 +10,10 @@ cItemFrame::cItemFrame(eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z) - : cEntity(etItemFrame, a_X, a_Y, a_Z, 0.8, 0.8), - m_BlockFace(a_BlockFace), - m_Item(E_BLOCK_AIR), - m_Rotation(0) + : cHangingEntity(etItemFrame, a_BlockFace, a_X, a_Y, a_Z) + , m_Item(E_BLOCK_AIR) + , m_Rotation(0) { - SetMaxHealth(1); - SetHealth(1); -} - - - - - -void cItemFrame::SpawnOn(cClientHandle & a_ClientHandle) -{ - int Dir = 0; - - // The client uses different values for item frame directions and block faces. Our constants are for the block faces, so we convert them here to item frame faces - switch (m_BlockFace) - { - case BLOCK_FACE_ZP: break; // Initialised to zero - case BLOCK_FACE_ZM: Dir = 2; break; - case BLOCK_FACE_XM: Dir = 1; break; - case BLOCK_FACE_XP: Dir = 3; break; - default: ASSERT(!"Unhandled block face when trying to spawn item frame!"); return; - } - - if ((Dir == 0) || (Dir == 2)) // Probably a client bug, but two directions are flipped and contrary to the norm, so we do -180 - { - SetYaw((Dir * 90) - 180); - } - else - { - SetYaw(Dir * 90); - } - - a_ClientHandle.SendSpawnObject(*this, 71, Dir, (Byte)GetYaw(), (Byte)GetPitch()); } diff --git a/src/Entities/ItemFrame.h b/src/Entities/ItemFrame.h index 43915e3f9..6577e7d94 100644 --- a/src/Entities/ItemFrame.h +++ b/src/Entities/ItemFrame.h @@ -1,7 +1,7 @@ #pragma once -#include "Entity.h" +#include "HangingEntity.h" @@ -9,10 +9,10 @@ // tolua_begin class cItemFrame : - public cEntity + public cHangingEntity { // tolua_end - typedef cEntity super; + typedef cHangingEntity super; public: @@ -20,18 +20,24 @@ public: cItemFrame(eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z); - const cItem & GetItem(void) { return m_Item; } - Byte GetRotation(void) const { return m_Rotation; } + /** Returns the item in the frame */ + const cItem & GetItem(void) { return m_Item; } // tolua_export + + /** Set the item in the frame */ + void SetItem(cItem & a_Item) { m_Item = a_Item; }; // tolua_export + + /** Returns the rotation from the item in the frame */ + Byte GetRotation(void) const { return m_Rotation; } // tolua_export + + /** Set the rotation from the item in the frame */ + void SetRotation(Byte a_Rotation) { m_Rotation = a_Rotation; } // tolua_export private: - virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void OnRightClicked(cPlayer & a_Player) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override {}; virtual void KilledBy(cEntity * a_Killer) override; virtual void GetDrops(cItems & a_Items, cEntity * a_Killer) override; - eBlockFace m_BlockFace; cItem m_Item; Byte m_Rotation; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 37ebf0610..6672d289e 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -30,6 +30,8 @@ #include "../Entities/ProjectileEntity.h" #include "../Entities/TNTEntity.h" #include "../Entities/ExpOrb.h" +#include "../Entities/HangingEntity.h" +#include "../Entities/ItemFrame.h" #include "../Mobs/Monster.h" #include "../Mobs/Bat.h" @@ -585,6 +587,25 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) +void cNBTChunkSerializer::AddHangingEntity(cHangingEntity * a_Hanging) +{ + m_Writer.AddByte("Direction", (unsigned char)a_Hanging->GetDirection()); + m_Writer.AddInt("TileX", a_Hanging->GetTileX()); + m_Writer.AddInt("TileY", a_Hanging->GetTileY()); + m_Writer.AddInt("TileZ", a_Hanging->GetTileZ()); + switch (a_Hanging->GetDirection()) + { + case 0: m_Writer.AddByte("Dir", (unsigned char)2); break; + case 1: m_Writer.AddByte("Dir", (unsigned char)1); break; + case 2: m_Writer.AddByte("Dir", (unsigned char)0); break; + case 3: m_Writer.AddByte("Dir", (unsigned char)3); break; + } +} + + + + + void cNBTChunkSerializer::AddTNTEntity(cTNTEntity * a_TNT) { m_Writer.BeginCompound(""); @@ -597,7 +618,7 @@ void cNBTChunkSerializer::AddTNTEntity(cTNTEntity * a_TNT) -void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb* a_ExpOrb) +void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb * a_ExpOrb) { m_Writer.BeginCompound(""); AddBasicEntity(a_ExpOrb, "XPOrb"); @@ -611,6 +632,21 @@ void cNBTChunkSerializer::AddExpOrbEntity(cExpOrb* a_ExpOrb) +void cNBTChunkSerializer::AddItemFrameEntity(cItemFrame * a_ItemFrame) +{ + m_Writer.BeginCompound(""); + AddBasicEntity(a_ItemFrame, "ItemFrame"); + AddHangingEntity(a_ItemFrame); + AddItem(a_ItemFrame->GetItem(), -1, "Item"); + m_Writer.AddByte("ItemRotation", (unsigned char)a_ItemFrame->GetRotation()); + m_Writer.AddFloat("ItemDropChance", 1.0F); + m_Writer.EndCompound(); +} + + + + + void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart) { m_Writer.BeginList("Items", TAG_Compound); @@ -692,7 +728,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) case cEntity::etProjectile: AddProjectileEntity ((cProjectileEntity *)a_Entity); break; case cEntity::etTNT: AddTNTEntity ((cTNTEntity *) a_Entity); break; case cEntity::etExpOrb: AddExpOrbEntity ((cExpOrb *) a_Entity); break; - case cEntity::etItemFrame: /* TODO */ break; + case cEntity::etItemFrame: AddItemFrameEntity ((cItemFrame *) a_Entity); break; case cEntity::etPainting: /* TODO */ break; case cEntity::etPlayer: return; // Players aren't saved into the world default: diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 22c309067..c1134cd00 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -43,6 +43,8 @@ class cItemGrid; class cProjectileEntity; class cTNTEntity; class cExpOrb; +class cHangingEntity; +class cItemFrame; @@ -109,8 +111,10 @@ protected: void AddMonsterEntity (cMonster * a_Monster); void AddPickupEntity (cPickup * a_Pickup); void AddProjectileEntity (cProjectileEntity * a_Projectile); + void AddHangingEntity (cHangingEntity * a_Hanging); void AddTNTEntity (cTNTEntity * a_TNT); void AddExpOrbEntity (cExpOrb * a_ExpOrb); + void AddItemFrameEntity (cItemFrame * a_ItemFrame); void AddMinecartChestContents(cMinecartWithChest * a_Minecart); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index bb0a831b3..6ac26c348 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -38,6 +38,8 @@ #include "../Entities/ProjectileEntity.h" #include "../Entities/TNTEntity.h" #include "../Entities/ExpOrb.h" +#include "../Entities/HangingEntity.h" +#include "../Entities/ItemFrame.h" @@ -1101,6 +1103,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadExpOrbFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } + else if (strncmp(a_IDTag, "ItemFrame", a_IDTagLength) == 0) + { + LoadItemFrameFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } else if (strncmp(a_IDTag, "Arrow", a_IDTagLength) == 0) { LoadArrowFromNBT(a_Entities, a_NBT, a_EntityTagIdx); @@ -1480,6 +1486,85 @@ void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a +void cWSSAnvil::LoadHangingFromNBT(cHangingEntity & a_Hanging, const cParsedNBT & a_NBT, int a_TagIdx) +{ + int Direction = a_NBT.FindChildByName(a_TagIdx, "Direction"); + if (Direction > 0) + { + a_Hanging.SetDirection(static_cast((int)a_NBT.GetByte(Direction))); + } + else + { + Direction = a_NBT.FindChildByName(a_TagIdx, "Dir"); + if (Direction > 0) + { + switch ((int)a_NBT.GetByte(Direction)) + { + case 0: a_Hanging.SetDirection(BLOCK_FACE_NORTH); break; + case 1: a_Hanging.SetDirection(BLOCK_FACE_TOP); break; + case 2: a_Hanging.SetDirection(BLOCK_FACE_BOTTOM); break; + case 3: a_Hanging.SetDirection(BLOCK_FACE_SOUTH); break; + } + } + } + + LOG("LALALAL."); + int TileX = a_NBT.FindChildByName(a_TagIdx, "TileX"); + int TileY = a_NBT.FindChildByName(a_TagIdx, "TileY"); + int TileZ = a_NBT.FindChildByName(a_TagIdx, "TileZ"); + if ((TileX > 0) && (TileY > 0) && (TileZ > 0)) + { + LOG("YO!"); + a_Hanging.SetPosition( + (double)a_NBT.GetInt(TileX), + (double)a_NBT.GetInt(TileY), + (double)a_NBT.GetInt(TileZ) + ); + } +} + + + + + +void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + // Load item: + int ItemTag = a_NBT.FindChildByName(a_TagIdx, "Item"); + if ((ItemTag < 0) || (a_NBT.GetType(ItemTag) != TAG_Compound)) + { + return; + } + cItem Item; + if (!LoadItemFromNBT(Item, a_NBT, ItemTag)) + { + return; + } + + std::auto_ptr ItemFrame(new cItemFrame(BLOCK_FACE_NONE, 0.0, 0.0, 0.0)); + if (!LoadEntityBaseFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx)) + { + return; + } + ItemFrame->SetItem(Item); + + LOG("BAUM! %d", Item.m_ItemType); + LoadHangingFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx); + + // Load Rotation: + int Rotation = a_NBT.FindChildByName(a_TagIdx, "ItemRotation"); + if (Rotation > 0) + { + ItemFrame->SetRotation((Byte)a_NBT.GetByte(Rotation)); + } + + a_Entities.push_back(ItemFrame.release()); +} + + + + + void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { std::auto_ptr Arrow(new cArrowEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0))); diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 75b630d71..50d0e555e 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -20,6 +20,7 @@ class cItemGrid; class cProjectileEntity; +class cHangingEntity; @@ -151,6 +152,8 @@ protected: void LoadPickupFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadExpOrbFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadHangingFromNBT (cHangingEntity & a_Hanging,const cParsedNBT & a_NBT, int a_TagIdx); + void LoadItemFrameFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadMinecartRFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadMinecartCFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); -- cgit v1.2.3 From 0442c41c872badfcc1a7a22c293161cc752623b8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 15 Mar 2014 07:50:39 +0100 Subject: Added cCuboid:Assign(OtherCuboid) API function. --- MCServer/Plugins/APIDump/Classes/Geometry.lua | 8 ++++++-- src/Cuboid.cpp | 14 ++++++++++++++ src/Cuboid.h | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/APIDump/Classes/Geometry.lua b/MCServer/Plugins/APIDump/Classes/Geometry.lua index 6f95c4cbf..78cd94f0c 100644 --- a/MCServer/Plugins/APIDump/Classes/Geometry.lua +++ b/MCServer/Plugins/APIDump/Classes/Geometry.lua @@ -63,12 +63,16 @@ return { constructor = { - { Params = "OtheCuboid", Return = "cCuboid", Notes = "Creates a new Cuboid object as a copy of OtherCuboid" }, + { Params = "OtherCuboid", Return = "cCuboid", Notes = "Creates a new Cuboid object as a copy of OtherCuboid" }, { Params = "{{Vector3i|Point1}}, {{Vector3i|Point2}}", Return = "cCuboid", Notes = "Creates a new Cuboid object with the specified points as its corners." }, { Params = "X, Y, Z", Return = "cCuboid", Notes = "Creates a new Cuboid object with the specified point as both its corners (the cuboid has a size of 1 in each direction)." }, { Params = "X1, Y1, Z1, X2, Y2, Z2", Return = "cCuboid", Notes = "Creates a new Cuboid object with the specified points as its corners." }, }, - Assign = { Params = "X1, Y1, Z1, X2, Y2, Z2", Return = "", Notes = "Assigns all the coords stored in the cuboid. Sort-state is ignored." }, + Assign = + { + { Params = "SrcCuboid", Return = "", Notes = "Copies all the coords from the src cuboid to this cuboid. Sort-state is ignored." }, + { Params = "X1, Y1, Z1, X2, Y2, Z2", Return = "", Notes = "Assigns all the coords to the specified values. Sort-state is ignored." }, + }, ClampX = { Params = "MinX, MaxX", Return = "", Notes = "Clamps both X coords into the range provided. Sortedness-agnostic." }, ClampY = { Params = "MinY, MaxY", Return = "", Notes = "Clamps both Y coords into the range provided. Sortedness-agnostic." }, ClampZ = { Params = "MinZ, MaxZ", Return = "", Notes = "Clamps both Z coords into the range provided. Sortedness-agnostic." }, diff --git a/src/Cuboid.cpp b/src/Cuboid.cpp index 2400c64f3..3e5240248 100644 --- a/src/Cuboid.cpp +++ b/src/Cuboid.cpp @@ -38,6 +38,20 @@ void cCuboid::Assign(int a_X1, int a_Y1, int a_Z1, int a_X2, int a_Y2, int a_Z2) +void cCuboid::Assign(const cCuboid & a_SrcCuboid) +{ + p1.x = a_SrcCuboid.p1.x; + p1.y = a_SrcCuboid.p1.y; + p1.z = a_SrcCuboid.p1.z; + p2.x = a_SrcCuboid.p2.x; + p2.y = a_SrcCuboid.p2.y; + p2.z = a_SrcCuboid.p2.z; +} + + + + + void cCuboid::Sort(void) { if (p1.x > p2.x) diff --git a/src/Cuboid.h b/src/Cuboid.h index b90a09e05..3239c54fc 100644 --- a/src/Cuboid.h +++ b/src/Cuboid.h @@ -21,6 +21,7 @@ public: cCuboid(int a_X1, int a_Y1, int a_Z1, int a_X2, int a_Y2, int a_Z2) : p1(a_X1, a_Y1, a_Z1), p2(a_X2, a_Y2, a_Z2) {} void Assign(int a_X1, int a_Y1, int a_Z1, int a_X2, int a_Y2, int a_Z2); + void Assign(const cCuboid & a_SrcCuboid); void Sort(void); -- cgit v1.2.3 From 62ed305f0760039e645d305a56b41d0ec5080ee0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 15 Mar 2014 07:51:33 +0100 Subject: APIDump: Fixed missing return statement. --- MCServer/Plugins/APIDump/main_APIDump.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua index 40b37f62c..4ed692b52 100644 --- a/MCServer/Plugins/APIDump/main_APIDump.lua +++ b/MCServer/Plugins/APIDump/main_APIDump.lua @@ -33,6 +33,7 @@ end function HandleCmdApi(a_Split) DumpApi() + return true end -- cgit v1.2.3 From d364c7befce884cac2347459512376937d2b8e69 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 15 Mar 2014 08:23:06 +0100 Subject: APIDump: Documented a forgotten cCuboid constructor. --- MCServer/Plugins/APIDump/Classes/Geometry.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/Classes/Geometry.lua b/MCServer/Plugins/APIDump/Classes/Geometry.lua index 78cd94f0c..9887bfb89 100644 --- a/MCServer/Plugins/APIDump/Classes/Geometry.lua +++ b/MCServer/Plugins/APIDump/Classes/Geometry.lua @@ -53,7 +53,7 @@ return { Desc = [[ cCuboid offers some native support for integral-boundary cuboids. A cuboid internally consists of - two {{Vector3i}}s. By default the cuboid doesn't make any assumptions about the defining points, + two {{Vector3i}}-s. By default the cuboid doesn't make any assumptions about the defining points, but for most of the operations in the cCuboid class, the p1 member variable is expected to be the minima and the p2 variable the maxima. The Sort() function guarantees this condition.

@@ -63,6 +63,7 @@ return { constructor = { + { Params = "", Return = "cCuboid", Notes = "Creates a new Cuboid object with all-zero coords" }, { Params = "OtherCuboid", Return = "cCuboid", Notes = "Creates a new Cuboid object as a copy of OtherCuboid" }, { Params = "{{Vector3i|Point1}}, {{Vector3i|Point2}}", Return = "cCuboid", Notes = "Creates a new Cuboid object with the specified points as its corners." }, { Params = "X, Y, Z", Return = "cCuboid", Notes = "Creates a new Cuboid object with the specified point as both its corners (the cuboid has a size of 1 in each direction)." }, -- cgit v1.2.3 From 4a5bea159f13b0f72ac16513a8f5b4b90e5b0ca8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 15 Mar 2014 08:36:49 +0100 Subject: Debuggers: Added a test for WE selection API. This tests mc-server/WorldEdit#34. --- MCServer/Plugins/Debuggers/Debuggers.lua | 40 +++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index f99c48242..d2c9a2a49 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -56,7 +56,8 @@ function Initialize(Plugin) PM:BindCommand("/sched", "debuggers", HandleSched, "- Schedules a simple countdown using cWorld:ScheduleTask()"); PM:BindCommand("/cs", "debuggers", HandleChunkStay, "- Tests the ChunkStay Lua integration for the specified chunk coords"); PM:BindCommand("/compo", "debuggers", HandleCompo, "- Tests the cCompositeChat bindings") - PM:BindCommand("/sb", "debuggers", HandleSetBiome, "- Sets the biome around you to the specified one"); + PM:BindCommand("/sb", "debuggers", HandleSetBiome, "- Sets the biome around you to the specified one") + PM:BindCommand("/wesel", "debuggers", HandleWESel, "- Expands the current WE selection by 1 block in X/Z") Plugin:AddWebTab("Debuggers", HandleRequest_Debuggers) Plugin:AddWebTab("StressTest", HandleRequest_StressTest) @@ -1298,6 +1299,43 @@ end +function HandleWESel(a_Split, a_Player) + -- Check if the selection is a cuboid: + local IsCuboid = cPluginManager:CallPlugin("WorldEdit", "IsPlayerSelectionCuboid") + if (IsCuboid == nil) then + a_Player:SendMessage(cCompositeChat():SetMessageType(mtFailure):AddTextPart("Cannot adjust selection, WorldEdit is not loaded")) + return true + elseif (IsCuboid == false) then + a_Player:SendMessage(cCompositeChat():SetMessageType(mtFailure):AddTextPart("Cannot adjust selection, the selection is not a cuboid")) + return true + end + + -- Get the selection: + local SelCuboid = cCuboid() + local IsSuccess = cPluginManager:CallPlugin("WorldEdit", "GetPlayerCuboidSelection", a_Player, SelCuboid) + if not(IsSuccess) then + a_Player:SendMessage(cCompositeChat():SetMessageType(mtFailure):AddTextPart("Cannot adjust selection, WorldEdit reported failure while getting current selection")) + return true + end + + -- Adjust the selection: + local NumBlocks = tonumber(a_Split[2] or "1") or 1 + SelCuboid:Expand(NumBlocks, NumBlocks, 0, 0, NumBlocks, NumBlocks) + + -- Set the selection: + local IsSuccess = cPluginManager:CallPlugin("WorldEdit", "SetPlayerCuboidSelection", a_Player, SelCuboid) + if not(IsSuccess) then + a_Player:SendMessage(cCompositeChat():SetMessageType(mtFailure):AddTextPart("Cannot adjust selection, WorldEdit reported failure while setting new selection")) + return true + end + a_Player:SendMessage(cCompositeChat():SetMessageType(mtInformation):AddTextPart("Successfully adjusted the selection by " .. NumBlocks .. " block(s)")) + return true +end + + + + + function OnPlayerJoined(a_Player) -- Test composite chat chaining: a_Player:SendMessage(cCompositeChat() -- cgit v1.2.3 From d6edd5f24e2717278093ef5a1e8376cd3c797478 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 15 Mar 2014 11:53:55 +0100 Subject: Remove old debug messages. --- src/WorldStorage/WSSAnvil.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 4f465e479..4dd4c755d 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1514,13 +1514,11 @@ void cWSSAnvil::LoadHangingFromNBT(cHangingEntity & a_Hanging, const cParsedNBT } } - LOG("LALALAL."); int TileX = a_NBT.FindChildByName(a_TagIdx, "TileX"); int TileY = a_NBT.FindChildByName(a_TagIdx, "TileY"); int TileZ = a_NBT.FindChildByName(a_TagIdx, "TileZ"); if ((TileX > 0) && (TileY > 0) && (TileZ > 0)) { - LOG("YO!"); a_Hanging.SetPosition( (double)a_NBT.GetInt(TileX), (double)a_NBT.GetInt(TileY), @@ -1554,7 +1552,6 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT } ItemFrame->SetItem(Item); - LOG("BAUM! %d", Item.m_ItemType); LoadHangingFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx); // Load Rotation: -- cgit v1.2.3 From 2e9fe777e425e65d733110247e73c1d9fb25ab1c Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 15 Mar 2014 06:45:26 -0700 Subject: Patched tolua to emit range checks for enums --- lib/tolua++/CMakeLists.txt | 21 + lib/tolua++/src/bin/basic_lua.h | 746 ++++++++++++++ lib/tolua++/src/bin/enumerate_lua.h | 281 ++++++ lib/tolua++/src/bin/function_lua.h | 1192 +++++++++++++++++++++++ lib/tolua++/src/bin/lua/enumerate.lua | 78 +- lib/tolua++/src/bin/lua/function.lua | 1 - lib/tolua++/src/bin/toluabind.c | 1730 +-------------------------------- src/CMakeLists.txt | 1 + 8 files changed, 2303 insertions(+), 1747 deletions(-) create mode 100644 lib/tolua++/src/bin/basic_lua.h create mode 100644 lib/tolua++/src/bin/enumerate_lua.h create mode 100644 lib/tolua++/src/bin/function_lua.h diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 5ec8ee822..9c8943aac 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -5,6 +5,25 @@ project (tolua++) include_directories ("${PROJECT_SOURCE_DIR}/../../src/") include_directories ("${PROJECT_SOURCE_DIR}/include/") include_directories ("${PROJECT_SOURCE_DIR}/../") +include_directories ("${PROJECT_SOURCE_DIR}") + +if(UNIX) + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h + COMMAND xxd -i lua/basic.lua >basic_lua.h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ + DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/basic.lua) + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h + COMMAND xxd -i lua/enumerate.lua >enumerate_lua.h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ + DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/enumerate.lua) + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h + COMMAND xxd -i lua/function.lua >function_lua.h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ + DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/function.lua) + set_property(SOURCE src/bin/toluabind.c APPEND PROPERTY OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h) + message(hello) +endif() + file(GLOB LIB_SOURCE "src/lib/*.c" @@ -14,6 +33,8 @@ file(GLOB BIN_SOURCE "src/bin/*.c" ) + + add_executable(tolua ${BIN_SOURCE}) add_library(tolualib ${LIB_SOURCE}) diff --git a/lib/tolua++/src/bin/basic_lua.h b/lib/tolua++/src/bin/basic_lua.h new file mode 100644 index 000000000..9f3b114b4 --- /dev/null +++ b/lib/tolua++/src/bin/basic_lua.h @@ -0,0 +1,746 @@ +unsigned char lua_basic_lua[] = { + 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x20, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, + 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, + 0x57, 0x61, 0x6c, 0x64, 0x65, 0x6d, 0x61, 0x72, 0x20, 0x43, 0x65, 0x6c, + 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x65, 0x43, 0x47, 0x72, 0x61, + 0x66, 0x2f, 0x50, 0x55, 0x43, 0x2d, 0x52, 0x69, 0x6f, 0x0a, 0x2d, 0x2d, + 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x31, 0x39, 0x39, 0x38, 0x0a, 0x2d, 0x2d, + 0x20, 0x4c, 0x61, 0x73, 0x74, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x3a, 0x20, 0x41, 0x70, 0x72, 0x20, 0x32, 0x30, 0x30, 0x33, 0x0a, 0x2d, + 0x2d, 0x20, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x24, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x69, + 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, + 0x61, 0x72, 0x65, 0x3b, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, 0x61, 0x6e, + 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, 0x72, 0x20, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, 0x69, 0x74, 0x2e, 0x0a, 0x2d, + 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, + 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x69, 0x73, + 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x61, 0x73, 0x20, 0x69, + 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, 0x73, 0x2c, 0x20, 0x61, 0x6e, + 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x6f, + 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, + 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x69, + 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x2c, 0x20, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x65, 0x6e, 0x68, 0x61, 0x6e, + 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x6f, 0x72, 0x20, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x42, 0x61, 0x73, 0x69, + 0x63, 0x20, 0x43, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x63, 0x6f, 0x72, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x4c, 0x75, + 0x61, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x41, + 0x6c, 0x6c, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x22, 0x63, 0x68, 0x61, 0x72, 0x2a, + 0x22, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x22, 0x5f, + 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x0a, 0x2d, 0x2d, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x63, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, + 0x22, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x22, 0x20, 0x77, 0x69, 0x6c, 0x6c, + 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x22, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, + 0x74, 0x61, 0x22, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x3d, + 0x20, 0x7b, 0x0a, 0x20, 0x5b, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x5d, + 0x20, 0x3d, 0x20, 0x27, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x63, 0x68, + 0x61, 0x72, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x69, 0x6e, 0x74, 0x27, + 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, + 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x27, 0x5d, + 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, + 0x0a, 0x20, 0x5b, 0x27, 0x6c, 0x6f, 0x6e, 0x67, 0x27, 0x5d, 0x20, 0x3d, + 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, 0x20, + 0x5b, 0x27, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x27, 0x5d, + 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, + 0x0a, 0x20, 0x5b, 0x27, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, + 0x20, 0x5b, 0x27, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, + 0x20, 0x5b, 0x27, 0x5f, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, + 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, + 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, + 0x74, 0x61, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x75, 0x73, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x63, 0x68, + 0x61, 0x72, 0x2a, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x76, 0x6f, 0x69, + 0x64, 0x2a, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x75, 0x73, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x62, 0x6f, + 0x6f, 0x6c, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x62, 0x6f, 0x6f, 0x6c, + 0x65, 0x61, 0x6e, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x6c, 0x75, 0x61, + 0x5f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x27, 0x5d, 0x20, 0x3d, 0x20, + 0x27, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, + 0x4c, 0x55, 0x41, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x27, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x2c, 0x20, 0x20, + 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x20, 0x34, 0x2e, + 0x30, 0x0a, 0x20, 0x5b, 0x27, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x2a, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x5f, 0x6c, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x6c, 0x75, 0x61, 0x5f, + 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x5d, 0x20, 0x3d, + 0x20, 0x27, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x2c, 0x0a, 0x7d, 0x0a, + 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x63, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x3d, 0x20, 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x20, 0x3d, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x2a, 0x22, 0x2c, 0x0a, 0x20, 0x75, 0x73, 0x65, 0x72, + 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x22, 0x76, 0x6f, 0x69, 0x64, + 0x2a, 0x22, 0x2c, 0x0a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, + 0x20, 0x3d, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x2c, 0x0a, 0x20, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x69, 0x6e, 0x74, + 0x22, 0x2c, 0x0a, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, + 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x22, + 0x2c, 0x0a, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, + 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x6f, + 0x20, 0x61, 0x20, 0x27, 0x72, 0x61, 0x77, 0x20, 0x70, 0x75, 0x73, 0x68, + 0x27, 0x20, 0x6f, 0x66, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, + 0x72, 0x61, 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, + 0x66, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, + 0x45, 0x61, 0x63, 0x68, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x63, 0x6f, + 0x72, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x64, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x61, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, 0x61, 0x67, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x0a, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, + 0x76, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x63, 0x6f, 0x6c, + 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x0a, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x0a, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, + 0x0a, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x20, 0x3d, 0x20, 0x7b, 0x7d, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x0a, 0x5f, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, + 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x4c, 0x69, + 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x73, 0x0a, 0x5f, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, + 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x4c, 0x69, 0x73, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x6e, + 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x0a, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, + 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, + 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x73, 0x29, + 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, + 0x6f, 0x6c, 0x64, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x25, 0x73, 0x2a, + 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x40, 0x25, 0x73, 0x2a, 0x28, + 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x29, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, 0x49, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x65, 0x6e, 0x61, 0x6d, + 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x3b, 0x20, + 0x69, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, + 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, + 0x3a, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x40, 0x70, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x74, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x5f, 0x72, + 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x2c, 0x7b, 0x6f, 0x6c, 0x64, + 0x3d, 0x6f, 0x6c, 0x64, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x3d, 0x6e, 0x65, + 0x77, 0x7d, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x72, + 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x73, 0x29, 0x0a, + 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, 0x67, 0x65, 0x74, + 0x6e, 0x28, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x29, + 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6d, 0x2c, 0x6e, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x2c, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x5b, 0x69, + 0x5d, 0x2e, 0x6f, 0x6c, 0x64, 0x2c, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, + 0x69, 0x6e, 0x67, 0x5b, 0x69, 0x5d, 0x2e, 0x6e, 0x65, 0x77, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, 0x30, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x28, + 0x73, 0x2c, 0x66, 0x29, 0x0a, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x75, 0x72, + 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x2a, 0x2a, 0x2a, 0x63, + 0x75, 0x72, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, + 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x5f, 0x63, + 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x29, 0x0a, 0x09, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x29, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, + 0x54, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x20, 0x3d, + 0x20, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x31, 0x2c, + 0x31, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x23, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x22, + 0x5c, 0x6e, 0x2a, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, + 0x22, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, + 0x32, 0x29, 0x2e, 0x2e, 0x22, 0x2e, 0x5c, 0x6e, 0x5c, 0x6e, 0x22, 0x29, + 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, + 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x73, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x5f, + 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2d, 0x5c, 0x6e, 0x29, 0x22, 0x29, 0x20, + 0x2d, 0x2d, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x20, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x63, 0x75, 0x72, + 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x2c, 0x22, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x2c, 0x22, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x22, 0x29, 0x20, 0x2d, 0x2d, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x20, + 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, + 0x5f, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x22, 0x63, + 0x68, 0x61, 0x72, 0x2a, 0x22, 0x29, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x27, + 0x63, 0x68, 0x61, 0x72, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x20, + 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x5f, 0x6c, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x22, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x22, 0x29, 0x20, 0x20, 0x2d, 0x2d, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x27, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, + 0x27, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x22, + 0x43, 0x6f, 0x64, 0x65, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x3a, 0x5c, 0x6e, 0x22, + 0x2e, 0x2e, 0x73, 0x2e, 0x2e, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x22, 0x28, 0x66, 0x20, 0x69, 0x73, + 0x20, 0x6e, 0x69, 0x6c, 0x29, 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x2a, 0x2a, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, 0x22, + 0x2e, 0x2e, 0x66, 0x2e, 0x2e, 0x73, 0x2e, 0x2e, 0x22, 0x2e, 0x5c, 0x6e, + 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, + 0x50, 0x55, 0x54, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x6d, 0x73, 0x67, + 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, + 0x71, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, + 0x55, 0x54, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x20, + 0x3d, 0x20, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x0a, 0x20, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x28, 0x22, 0x5c, 0x6e, 0x2a, 0x2a, 0x20, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x6d, 0x73, 0x67, 0x2e, 0x2e, 0x22, 0x2e, + 0x5c, 0x6e, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, + 0x50, 0x55, 0x54, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x20, 0x61, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x66, 0x75, 0x6c, + 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x67, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x28, 0x74, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x69, 0x73, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, + 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x29, 0x0a, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x5f, 0x75, 0x73, 0x65, 0x72, + 0x74, 0x79, 0x70, 0x65, 0x5b, 0x66, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, + 0x65, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x74, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x76, 0x61, 0x72, 0x28, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x74, + 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x74, 0x0a, 0x09, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x09, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, + 0x65, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, + 0x69, 0x66, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, + 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, + 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x2c, 0x74, 0x20, 0x3d, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, + 0x66, 0x28, 0x27, 0x27, 0x2c, 0x20, 0x74, 0x29, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x5f, 0x62, 0x61, 0x73, + 0x69, 0x63, 0x5b, 0x74, 0x5d, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x62, 0x2c, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x63, + 0x74, 0x79, 0x70, 0x65, 0x5b, 0x62, 0x5d, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, 0x6c, + 0x69, 0x74, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, + 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x6c, + 0x69, 0x74, 0x20, 0x28, 0x73, 0x2c, 0x74, 0x29, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, + 0x7d, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x73, + 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x2e, + 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, + 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x22, + 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x22, 0x2e, + 0x2e, 0x74, 0x2e, 0x2e, 0x22, 0x25, 0x73, 0x2a, 0x22, 0x0a, 0x20, 0x73, + 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x5e, + 0x25, 0x73, 0x2b, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, + 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x25, 0x73, + 0x2b, 0x24, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, 0x3d, + 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x70, 0x2c, 0x66, 0x29, + 0x0a, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x2e, 0x6e, 0x20, + 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, 0x6e, 0x5d, 0x20, + 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x28, 0x25, + 0x73, 0x25, 0x73, 0x2a, 0x29, 0x24, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x73, + 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, + 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x6e, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, + 0x61, 0x6c, 0x20, 0x63, 0x61, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, + 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x28, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x29, 0x0a, 0x2d, 0x2d, 0x20, + 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x27, + 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x27, 0x5e, 0x27, 0x20, 0x28, 0x61, 0x73, 0x20, 0x75, 0x73, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, + 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6c, 0x73, 0x6f, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x77, 0x68, 0x69, 0x74, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x20, 0x70, 0x61, + 0x74, 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, + 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, + 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, + 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x62, 0x65, + 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x65, 0x6e, 0x64, + 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, + 0x30, 0x7d, 0x0a, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x61, 0x64, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, + 0x6f, 0x66, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x2c, 0x20, 0x6f, 0x66, 0x73, + 0x29, 0x0a, 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, + 0x5e, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, + 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, + 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x20, + 0x2b, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x5b, 0x72, 0x65, + 0x74, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x6f, 0x66, + 0x73, 0x20, 0x3c, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x6c, 0x65, 0x6e, 0x28, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x0a, 0x09, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x75, 0x62, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x2c, 0x20, 0x2d, 0x31, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x73, 0x75, 0x62, 0x2c, 0x20, 0x22, 0x5e, 0x22, 0x2e, 0x2e, + 0x70, 0x61, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, 0x2d, 0x31, 0x29, + 0x0a, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, + 0x73, 0x2b, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, + 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, + 0x3d, 0x20, 0x22, 0x28, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x3c, 0x22, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, + 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x28, + 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x20, 0x3d, 0x20, 0x22, 0x5e, 0x25, 0x62, 0x28, 0x29, 0x22, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x68, + 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x3c, 0x22, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x22, + 0x5e, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x62, 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x75, + 0x62, 0x2c, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x29, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2d, 0x2d, 0x20, + 0x75, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3f, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, 0x31, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, + 0x20, 0x2b, 0x20, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, + 0x31, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x61, 0x64, + 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, 0x29, + 0x0a, 0x09, 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x6e, + 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, + 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x3d, 0x31, 0x0a, + 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x5b, 0x31, 0x5d, 0x20, 0x3d, + 0x20, 0x22, 0x22, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, + 0x63, 0x61, 0x74, 0x65, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x20, 0x28, 0x74, 0x2c, 0x66, + 0x2c, 0x6c, 0x2c, 0x6a, 0x73, 0x74, 0x72, 0x29, 0x0a, 0x09, 0x6a, 0x73, + 0x74, 0x72, 0x20, 0x3d, 0x20, 0x6a, 0x73, 0x74, 0x72, 0x20, 0x6f, 0x72, + 0x20, 0x22, 0x20, 0x22, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x73, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x69, 0x3d, 0x66, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, + 0x20, 0x69, 0x3c, 0x3d, 0x6c, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x73, + 0x20, 0x3d, 0x20, 0x73, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x20, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x69, 0x20, 0x3c, 0x3d, 0x20, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x2e, 0x2e, 0x6a, 0x73, 0x74, + 0x72, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x65, + 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x66, 0x6f, 0x6c, + 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x20, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x20, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x20, + 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, + 0x3c, 0x3d, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x2c, 0x27, 0x5b, 0x25, 0x28, + 0x2c, 0x22, 0x5d, 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, + 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x5e, 0x5b, 0x25, 0x61, 0x5f, + 0x7e, 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x27, 0x20, 0x27, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x61, 0x72, 0x67, + 0x5b, 0x69, 0x5d, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x72, 0x67, + 0x5b, 0x69, 0x5d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x72, 0x67, + 0x5b, 0x69, 0x5d, 0x2c, 0x2d, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, + 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, + 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, + 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x5d, 0x2c, 0x22, 0x5b, 0x25, 0x2f, 0x25, + 0x29, 0x25, 0x3b, 0x25, 0x7b, 0x25, 0x7d, 0x5d, 0x24, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x27, 0x5c, 0x6e, 0x27, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x6c, 0x69, + 0x6e, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x28, 0x2e, 0x2e, 0x2e, 0x29, + 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, + 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x61, 0x72, + 0x67, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x2c, 0x27, 0x5b, 0x25, 0x28, 0x2c, 0x22, 0x5d, 0x27, + 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, + 0x5d, 0x2c, 0x22, 0x5e, 0x5b, 0x25, 0x61, 0x5f, 0x7e, 0x5d, 0x22, 0x29, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, + 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x20, 0x7e, 0x3d, 0x20, 0x27, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, + 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x2d, 0x31, 0x2c, 0x2d, + 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x61, 0x72, 0x67, 0x5b, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x5d, 0x2c, 0x22, + 0x5b, 0x25, 0x2f, 0x25, 0x29, 0x25, 0x3b, 0x25, 0x7b, 0x25, 0x7d, 0x5d, + 0x24, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, + 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, + 0x6f, 0x6b, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x6e, 0x61, 0x6d, + 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x3d, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x22, 0x67, 0x65, 0x74, 0x5f, 0x22, 0x2e, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x20, 0x22, 0x73, 0x65, 0x74, 0x5f, 0x22, 0x2e, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, + 0x71, 0x74, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x73, 0x65, 0x74, 0x22, 0x2e, 0x2e, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x75, 0x70, 0x70, 0x65, 0x72, + 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x29, 0x29, + 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, + 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x2d, 0x31, + 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, + 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x76, + 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x2d, 0x2d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x24, 0x5b, 0x69, 0x63, 0x68, 0x6c, 0x5d, 0x66, 0x69, 0x6c, 0x65, 0x20, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2c, 0x0a, + 0x2d, 0x2d, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, + 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, + 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x68, 0x6f, + 0x6f, 0x6b, 0x28, 0x70, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x70, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x63, + 0x6f, 0x64, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x6b, 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x24, 0x69, 0x66, 0x69, 0x6c, + 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x0a, + 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x64, 0x20, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x27, 0x20, 0x69, 0x6e, 0x73, + 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, + 0x6e, 0x79, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x61, + 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x24, 0x69, 0x66, 0x69, + 0x6c, 0x65, 0x2e, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, + 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x74, + 0x2c, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, + 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, + 0x67, 0x20, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, + 0x64, 0x65, 0x20, 0x28, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x27, 0x24, 0x72, + 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x27, 0x2c, 0x20, 0x63, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x29, + 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x74, + 0x75, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x0a, 0x2d, 0x2d, + 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x50, + 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x27, 0x20, 0x6b, 0x65, + 0x79, 0x2e, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, + 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, + 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x20, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, + 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, + 0x6f, 0x6d, 0x20, 0x27, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, + 0x27, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, + 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x20, 0x61, 0x20, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x0a, 0x2d, 0x2d, 0x20, 0x61, + 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, + 0x69, 0x74, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, + 0x6d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x64, 0x6f, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x20, 0x6f, 0x72, 0x20, + 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x29, 0x0a, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, + 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, + 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, + 0x72, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, + 0x28, 0x66, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, + 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, + 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x66, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, + 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, + 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x5f, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x6f, + 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x2e, 0x2e, 0x2e, + 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, + 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x70, 0x75, 0x73, 0x68, + 0x65, 0x72, 0x73, 0x0a, 0x0a, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x0a, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, 0x6f, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, + 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, + 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, + 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, + 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x65, 0x73, 0x5b, 0x74, 0x5d, 0x0a, 0x0a, 0x09, 0x77, 0x68, + 0x69, 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x64, 0x6f, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, + 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x65, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x62, + 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, + 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, + 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x75, 0x73, 0x65, 0x72, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, + 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x74, + 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, + 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, + 0x73, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x69, 0x73, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, + 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, + 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, + 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x0a, 0x65, 0x6e, 0x64, 0x0a +}; +unsigned int lua_basic_lua_len = 8909; diff --git a/lib/tolua++/src/bin/enumerate_lua.h b/lib/tolua++/src/bin/enumerate_lua.h new file mode 100644 index 000000000..271cf2a23 --- /dev/null +++ b/lib/tolua++/src/bin/enumerate_lua.h @@ -0,0 +1,281 @@ +unsigned char lua_enumerate_lua[] = { + 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x65, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, + 0x20, 0x62, 0x79, 0x20, 0x57, 0x61, 0x6c, 0x64, 0x65, 0x6d, 0x61, 0x72, + 0x20, 0x43, 0x65, 0x6c, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x65, + 0x43, 0x47, 0x72, 0x61, 0x66, 0x2f, 0x50, 0x55, 0x43, 0x2d, 0x52, 0x69, + 0x6f, 0x0a, 0x2d, 0x2d, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x31, 0x39, 0x39, + 0x38, 0x0a, 0x2d, 0x2d, 0x20, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x65, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2e, 0x6c, 0x75, 0x61, 0x2c, + 0x76, 0x20, 0x31, 0x2e, 0x33, 0x20, 0x32, 0x30, 0x30, 0x30, 0x2f, 0x30, + 0x31, 0x2f, 0x32, 0x34, 0x20, 0x32, 0x30, 0x3a, 0x34, 0x31, 0x3a, 0x31, + 0x35, 0x20, 0x63, 0x65, 0x6c, 0x65, 0x73, 0x20, 0x45, 0x78, 0x70, 0x20, + 0x24, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, + 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, + 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x3b, 0x20, 0x79, 0x6f, + 0x75, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, + 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, + 0x69, 0x74, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, + 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6e, 0x64, + 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, + 0x22, 0x61, 0x73, 0x20, 0x69, 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, + 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, + 0x20, 0x6e, 0x6f, 0x20, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x2c, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2c, 0x20, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, + 0x65, 0x6e, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x70, 0x72, + 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, + 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x64, 0x3a, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x20, + 0x20, 0x7b, 0x69, 0x7d, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, + 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x7b, + 0x0a, 0x7d, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, 0x6d, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x2e, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x0a, 0x73, 0x65, 0x74, 0x6d, 0x65, + 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2c, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x29, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x3a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x28, + 0x70, 0x72, 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x70, 0x72, 0x65, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x65, 0x20, 0x6f, 0x72, + 0x20, 0x27, 0x27, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, + 0x63, 0x75, 0x72, 0x72, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, + 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, + 0x5d, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e, + 0x2e, 0x27, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x2e, 0x2e, + 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x50, 0x72, + 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x3a, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2c, + 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x45, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x7b, 0x22, 0x29, 0x0a, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, + 0x2e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x2e, + 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, + 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x27, 0x22, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x5b, 0x69, 0x5d, 0x2e, 0x2e, 0x22, + 0x27, 0x28, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x2e, 0x22, 0x29, 0x2c, + 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x7d, 0x22, 0x2e, + 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, 0x20, + 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x63, 0x6f, 0x64, + 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x28, 0x29, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, + 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, + 0x20, 0x7e, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, 0x3d, + 0x20, 0x31, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x22, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, + 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, 0x28, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x4c, 0x2c, 0x20, + 0x69, 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, + 0x64, 0x65, 0x66, 0x2c, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x20, 0x65, 0x72, 0x72, 0x29, 0x22, 0x29, + 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7b, + 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x22, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x69, 0x73, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x4c, 0x2c, 0x6c, + 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x65, 0x72, 0x72, 0x29, 0x29, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3b, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x69, 0x6e, + 0x74, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x4c, + 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x29, 0x3b, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3e, 0x3d, 0x20, + 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x69, + 0x6e, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, 0x26, 0x26, 0x20, 0x76, 0x61, + 0x6c, 0x20, 0x3c, 0x3d, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x3b, 0x22, + 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, + 0x7d, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, + 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, + 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x28, 0x74, + 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x73, + 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, + 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x29, 0x0a, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, + 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x20, 0x69, 0x66, + 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, + 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x22, + 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, + 0x3d, 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x09, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x28, 0x22, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x73, 0x2e, + 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, + 0x6f, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3c, 0x61, 0x6e, 0x6f, + 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x3e, + 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x64, + 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, + 0x79, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x56, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x28, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, + 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x74, 0x20, + 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x0a, + 0x09, 0x20, 0x69, 0x66, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x74, 0x2e, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x2e, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x0a, 0x09, 0x09, 0x74, 0x2e, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x20, 0x3d, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x28, 0x29, 0x0a, 0x09, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, 0x65, 0x63, + 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x20, 0x28, 0x6e, 0x2c, 0x62, 0x2c, 0x76, 0x61, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x62, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x62, 0x2c, + 0x20, 0x22, 0x2c, 0x5b, 0x25, 0x73, 0x5c, 0x6e, 0x5d, 0x2a, 0x7d, 0x22, + 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x7d, 0x22, 0x29, 0x20, 0x2d, 0x2d, 0x20, + 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x6c, 0x61, + 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, + 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x62, 0x2c, 0x32, 0x2c, 0x2d, + 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x65, + 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x62, 0x72, 0x61, + 0x63, 0x65, 0x73, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, + 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x69, + 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x77, 0x68, + 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, + 0x27, 0x3d, 0x27, 0x29, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x69, 0x73, + 0x63, 0x61, 0x72, 0x64, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x2e, 0x6e, + 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, + 0x09, 0x65, 0x5b, 0x65, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x74, + 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, + 0x3d, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x74, + 0x74, 0x5b, 0x32, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, + 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x74, 0x5b, 0x32, + 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x20, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x2b, + 0x20, 0x31, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x69, + 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3e, 0x20, 0x6d, 0x61, + 0x78, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x61, + 0x78, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x0a, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, + 0x32, 0x5d, 0x20, 0x3c, 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x74, + 0x74, 0x5b, 0x32, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6c, 0x75, + 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x0a, 0x09, 0x69, 0x20, 0x20, + 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x65, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, + 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, + 0x29, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x65, 0x5b, 0x69, + 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x65, + 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x40, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x65, + 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, + 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x5b, 0x32, 0x5d, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x5b, 0x32, + 0x5d, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x72, 0x65, 0x6e, + 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x2e, 0x6c, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x5b, + 0x32, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, + 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x5b, 0x20, 0x6e, 0x73, 0x2e, 0x2e, 0x65, 0x5b, 0x69, 0x5d, + 0x20, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x6e, 0x73, 0x2e, 0x2e, 0x65, 0x5b, + 0x69, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, + 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x0a, 0x09, 0x65, 0x2e, 0x6d, 0x69, + 0x6e, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x0a, 0x09, 0x65, 0x2e, 0x6d, + 0x61, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x0a, 0x09, 0x69, 0x66, + 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x54, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, + 0x22, 0x69, 0x6e, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x29, 0x0a, 0x09, + 0x09, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x5b, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x6e, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, + 0x65, 0x2c, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a +}; +unsigned int lua_enumerate_lua_len = 3329; diff --git a/lib/tolua++/src/bin/function_lua.h b/lib/tolua++/src/bin/function_lua.h new file mode 100644 index 000000000..c1317b9fe --- /dev/null +++ b/lib/tolua++/src/bin/function_lua.h @@ -0,0 +1,1192 @@ +unsigned char lua_function_lua[] = { + 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, + 0x62, 0x79, 0x20, 0x57, 0x61, 0x6c, 0x64, 0x65, 0x6d, 0x61, 0x72, 0x20, + 0x43, 0x65, 0x6c, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x65, 0x43, + 0x47, 0x72, 0x61, 0x66, 0x2f, 0x50, 0x55, 0x43, 0x2d, 0x52, 0x69, 0x6f, + 0x0a, 0x2d, 0x2d, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x31, 0x39, 0x39, 0x38, + 0x0a, 0x2d, 0x2d, 0x20, 0x24, 0x49, 0x64, 0x3a, 0x20, 0x24, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x64, 0x65, + 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x73, 0x6f, 0x66, + 0x74, 0x77, 0x61, 0x72, 0x65, 0x3b, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x63, + 0x61, 0x6e, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x2f, 0x6f, + 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, 0x69, 0x74, 0x2e, + 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x66, 0x74, + 0x77, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, + 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x61, 0x73, + 0x20, 0x69, 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, 0x73, 0x2c, 0x20, + 0x61, 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, + 0x20, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x6d, + 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x2c, 0x20, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2c, 0x20, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x65, 0x6e, 0x68, + 0x61, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x6f, + 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x2e, 0x0a, 0x2d, 0x2d, + 0x20, 0x54, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, + 0x6e, 0x67, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x61, 0x72, + 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x3a, 0x0a, 0x2d, 0x2d, + 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x0a, + 0x2d, 0x2d, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, + 0x20, 0x3d, 0x20, 0x22, 0x2a, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x26, + 0x22, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, + 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, + 0x2d, 0x2d, 0x20, 0x20, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x6c, 0x75, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x2d, 0x2d, 0x20, + 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x73, + 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x20, 0x3d, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x20, 0x22, 0x74, 0x68, 0x69, 0x73, 0x22, 0x2e, 0x0a, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, + 0x27, 0x27, 0x2c, 0x0a, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, + 0x27, 0x27, 0x2c, 0x0a, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x2c, 0x0a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x2c, 0x0a, 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x6e, 0x3d, 0x30, 0x7d, 0x2c, 0x0a, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x20, 0x3d, 0x20, 0x27, 0x27, 0x2c, 0x0a, 0x7d, 0x0a, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x5f, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x73, + 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x29, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x65, 0x20, 0x74, 0x61, 0x67, 0x73, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x64, 0x65, 0x63, 0x6c, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x29, 0x0a, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x76, 0x61, 0x72, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x66, + 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, + 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x20, + 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6d, 0x6f, 0x64, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x2c, + 0x27, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x64, 0x65, + 0x63, 0x6c, 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x72, 0x69, + 0x74, 0x65, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x2d, 0x2d, 0x20, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x20, 0x43, 0x2f, 0x43, 0x2b, 0x2b, + 0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, + 0x65, 0x20, 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x29, 0x0a, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, + 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x2d, 0x32, + 0x2c, 0x2d, 0x31, 0x29, 0x20, 0x2d, 0x20, 0x31, 0x20, 0x20, 0x2d, 0x2d, + 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x6f, 0x76, + 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x72, 0x65, + 0x74, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2d, + 0x2d, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x3a, + 0x69, 0x6e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x29, 0x0a, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, + 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x29, + 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x66, + 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x69, + 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x70, 0x75, 0x72, 0x65, 0x20, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, + 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x0a, 0x20, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x22, + 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, + 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x20, 0x22, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2c, 0x22, + 0x20, 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, + 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, + 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, + 0x4c, 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, + 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x69, + 0x6e, 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, + 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, + 0x2c, 0x22, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x22, 0x29, + 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, + 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, + 0x4c, 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, + 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x20, 0x69, 0x6e, 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x29, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7b, 0x22, 0x29, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, + 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, + 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, 0x27, + 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, + 0x72, 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x69, 0x66, 0x20, 0x28, 0x5c, 0x6e, 0x27, 0x29, + 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, + 0x61, 0x72, 0x67, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, + 0x32, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, + 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, + 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, + 0x65, 0x77, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x7e, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x27, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x27, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x22, + 0x2e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x21, 0x27, 0x2e, 0x2e, 0x66, 0x75, 0x6e, 0x63, + 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x31, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, + 0x27, 0x22, 0x2c, 0x30, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x65, 0x72, 0x72, 0x29, 0x20, 0x7c, 0x7c, 0x5c, 0x6e, 0x27, 0x29, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x61, 0x72, 0x67, 0x73, 0x0a, 0x20, 0x69, 0x66, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, + 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, + 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, + 0x69, 0x5d, 0x3a, 0x6f, 0x75, 0x74, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x2e, 0x2e, 0x27, + 0x20, 0x7c, 0x7c, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x6e, + 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, + 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x6c, + 0x69, 0x73, 0x74, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x69, 0x73, 0x6e, 0x6f, 0x6f, 0x62, 0x6a, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, + 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, + 0x72, 0x72, 0x29, 0x5c, 0x6e, 0x20, 0x29, 0x27, 0x29, 0x0a, 0x09, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x67, 0x6f, 0x74, + 0x6f, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, + 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, + 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, + 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x7b, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x69, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 0x0a, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x7e, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x2a, + 0x27, 0x2c, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x3d, 0x20, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x28, + 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x2a, 0x29, 0x20, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, + 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x31, 0x2c, 0x30, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, + 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, 0x5e, + 0x25, 0x73, 0x2a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x25, 0x73, 0x25, + 0x73, 0x2a, 0x28, 0x2e, 0x2a, 0x29, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, + 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, + 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x65, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, + 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, + 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x7e, + 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, + 0x4c, 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x73, 0x65, 0x6c, + 0x66, 0x29, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, + 0x27, 0x2e, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x22, 0x69, 0x6e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x5c, 0x27, 0x73, 0x65, 0x6c, 0x66, + 0x5c, 0x27, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, 0x5c, 0x27, 0x22, 0x2c, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x2e, 0x2e, + 0x27, 0x22, 0x2c, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x29, 0x3b, 0x27, 0x29, + 0x3b, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, + 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, + 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, + 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, + 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, + 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x67, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, + 0x79, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x6e, + 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, + 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x70, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, + 0x6f, 0x6b, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x0a, 0x0a, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, 0x22, + 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x69, 0x66, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x4d, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x26, 0x5b, 0x5d, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, + 0x31, 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x35, 0x20, 0x3f, 0x0a, 0x09, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, + 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x28, + 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, + 0x31, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x2d, 0x31, 0x29, + 0x20, 0x3d, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x27, 0x29, 0x20, 0x3d, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x2c, 0x27, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, + 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x29, 0x20, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, 0x77, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x6e, 0x65, 0x77, 0x28, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, 0x28, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, + 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x2e, 0x27, 0x3a, 0x3a, 0x27, 0x2e, 0x2e, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, + 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x75, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x61, + 0x73, 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x09, 0x2d, 0x2d, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x5f, 0x63, 0x61, 0x73, 0x74, 0x3c, 0x27, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, + 0x2c, 0x27, 0x20, 0x3e, 0x28, 0x2a, 0x73, 0x65, 0x6c, 0x66, 0x27, 0x29, + 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, + 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, + 0x28, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, + 0x6c, 0x66, 0x2d, 0x3e, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x27, 0x29, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, + 0x73, 0x5b, 0x31, 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x2c, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, + 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, + 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, + 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x61, 0x72, + 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, + 0x31, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, + 0x31, 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x2d, 0x31, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, + 0x77, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x20, + 0x2d, 0x2d, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, 0x28, 0x0a, 0x09, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x3d, + 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x63, 0x74, 0x20, + 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x6e, + 0x65, 0x77, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x61, 0x73, + 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x72, 0x61, + 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5b, 0x74, 0x5d, + 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, + 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x27, 0x2e, 0x2e, 0x74, + 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x74, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, + 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, + 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x74, + 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x75, 0x73, 0x68, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, + 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x5f, + 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, + 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, + 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, + 0x28, 0x28, 0x27, 0x2c, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x2c, 0x27, 0x29, + 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x29, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, + 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, + 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x5f, 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, + 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x2c, 0x73, + 0x69, 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x29, + 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x27, 0x2c, + 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, + 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x5f, 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, + 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, + 0x2a, 0x29, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, + 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, + 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, + 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, + 0x69, 0x64, 0x2a, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, + 0x74, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, + 0x29, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x64, + 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, + 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x6c, + 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, + 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, + 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, + 0x6e, 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x74, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, + 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x7d, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x65, + 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, + 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, + 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x73, + 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6e, 0x61, 0x72, 0x67, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, + 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, + 0x2d, 0x2d, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x64, 0x79, 0x6e, 0x61, + 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, + 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x66, 0x72, 0x65, + 0x65, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x29, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x2e, + 0x2e, 0x6e, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x27, 0x3b, 0x27, 0x29, 0x0a, + 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x76, + 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, + 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, + 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x52, + 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, + 0x2e, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x22, 0x23, 0x66, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, 0x5c, 0x27, 0x2e, + 0x22, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, + 0x65, 0x29, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, + 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, + 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x0a, 0x09, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x3a, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x31, 0x2c, + 0x2d, 0x33, 0x29, 0x2e, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, + 0x22, 0x25, 0x30, 0x32, 0x64, 0x22, 0x2c, 0x6f, 0x76, 0x65, 0x72, 0x6c, + 0x6f, 0x61, 0x64, 0x29, 0x2e, 0x2e, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, + 0x66, 0x20, 0x2f, 0x2f, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, + 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, + 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, + 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x63, + 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, 0x77, + 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, + 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, + 0x28, 0x31, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x28, 0x70, 0x72, + 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, + 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, + 0x65, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x20, 0x70, 0x75, 0x72, 0x65, 0x20, 0x76, 0x69, + 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x73, 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, + 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, 0x2e, 0x2e, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, + 0x27, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, + 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x6e, 0x65, 0x77, + 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, + 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, + 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x2c, 0x22, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x22, 0x2c, 0x27, 0x2e, + 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, + 0x2e, 0x27, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x09, 0x20, 0x20, 0x2d, 0x2d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x73, 0x65, 0x74, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, + 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2c, 0x20, 0x22, 0x27, 0x2e, 0x2e, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x2c, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, + 0x2e, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x22, + 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x20, 0x3d, + 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, + 0x64, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, + 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x70, 0x74, 0x72, + 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x74, 0x72, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x2e, 0x2e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, + 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, + 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, + 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2e, 0x2e, 0x22, 0x27, + 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x63, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, + 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, + 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x2e, 0x2e, 0x22, 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x22, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, + 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, + 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x69, 0x5d, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x20, 0x22, 0x2c, 0x22, 0x2c, + 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x22, + 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x7d, 0x22, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, + 0x73, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x62, 0x79, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x63, 0x6f, 0x6c, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x62, + 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x74, 0x72, 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, 0x25, 0x73, 0x2a, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, 0x2c, 0x22, 0x22, + 0x29, 0x0a, 0x09, 0x20, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, + 0x3d, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x63, 0x6f, 0x6c, + 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x63, 0x6c, + 0x65, 0x61, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x20, 0x72, 0x20, 0x3d, + 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x09, 0x77, + 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x72, + 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x63, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x20, 0x6f, 0x72, 0x20, 0x72, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, + 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, + 0x20, 0x6c, 0x75, 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, + 0x6f, 0x61, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, + 0x28, 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3a, 0x6f, + 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, + 0x70, 0x61, 0x72, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x73, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x69, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, + 0x72, 0x2c, 0x20, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x20, + 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x64, 0x65, 0x66, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, + 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x3d, 0x28, 0x2e, + 0x2a, 0x29, 0x24, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, + 0x61, 0x72, 0x2c, 0x20, 0x22, 0x7c, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, + 0x6f, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x0a, 0x0a, 0x09, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, + 0x72, 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x61, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, + 0x61, 0x72, 0x2c, 0x20, 0x27, 0x3d, 0x25, 0x73, 0x2a, 0x6e, 0x65, 0x77, + 0x27, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, + 0x25, 0x28, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, + 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x61, 0x73, 0x20, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x2e, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x3f, 0x0a, 0x09, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x20, 0x2d, + 0x2d, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x4e, 0x55, 0x4c, 0x4c, + 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, + 0x6e, 0x67, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x5b, 0x25, 0x28, 0x26, + 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, + 0x72, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x28, 0x6d, 0x6f, 0x73, 0x74, + 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x65, 0x6e, 0x63, 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x69, + 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x26, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x69, 0x66, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, + 0x28, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x3a, 0x22, 0x29, 0x20, 0x6f, + 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, + 0x6e, 0x65, 0x77, 0x25, 0x73, 0x2b, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x69, + 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x6f, 0x6d, 0x65, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x3a, 0x3a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x20, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x27, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x2d, + 0x2d, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x3f, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, + 0x67, 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x2c, 0x20, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x29, 0x20, 0x2d, 0x2d, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, + 0x61, 0x73, 0x74, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, + 0x2c, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x6c, 0x61, 0x73, + 0x74, 0x5f, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x22, 0x5e, 0x28, 0x5b, 0x5e, + 0x3d, 0x5d, 0x2b, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x61, 0x72, 0x67, 0x2c, 0x20, 0x22, 0x28, 0x5b, 0x25, 0x25, 0x25, 0x28, + 0x25, 0x29, 0x5d, 0x29, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x25, 0x25, 0x31, + 0x22, 0x29, 0x3b, 0x0a, 0x09, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, + 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, + 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x2c, 0x25, 0x73, 0x2a, 0x22, 0x2e, + 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x22, + 0x25, 0x73, 0x2a, 0x25, 0x29, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, + 0x22, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x2c, 0x20, 0x73, + 0x5f, 0x61, 0x72, 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x46, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, + 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x28, 0x22, 0x23, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x27, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, + 0x28, 0x74, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x3a, 0x69, 0x6e, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x20, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x27, + 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x2e, + 0x2e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x2c, 0x20, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x69, 0x73, 0x20, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, + 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x3d, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x72, + 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x62, 0x3c, 0x3e, 0x22, + 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, + 0x6e, 0x65, 0x77, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6c, 0x6e, + 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x0a, + 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, + 0x5f, 0x6e, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, + 0x20, 0x20, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, + 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, + 0x20, 0x27, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, + 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, + 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x7e, 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, + 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, + 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x0a, 0x20, + 0x20, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x5f, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x74, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x74, 0x3a, 0x63, 0x66, 0x75, 0x6e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x28, + 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x22, 0x29, 0x2e, 0x2e, 0x74, 0x3a, + 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x74, 0x29, 0x0a, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, + 0x65, 0x63, 0x74, 0x73, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x3a, 0x20, 0x6f, 0x6e, 0x65, 0x20, + 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64, 0x20, + 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, + 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x61, 0x2c, 0x63, 0x29, 0x0a, 0x20, + 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, + 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, + 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x65, 0x20, 0x62, 0x72, 0x61, 0x63, 0x65, 0x73, 0x0a, 0x20, 0x2d, + 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, + 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x28, + 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, + 0x32, 0x29, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, 0x57, 0x27, 0x5d, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, + 0x69, 0x6e, 0x64, 0x28, 0x61, 0x2c, 0x20, 0x22, 0x25, 0x2e, 0x25, 0x2e, + 0x25, 0x2e, 0x25, 0x73, 0x2a, 0x25, 0x29, 0x22, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x28, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x20, 0x28, 0x60, 0x2e, 0x2e, 0x2e, 0x27, 0x29, 0x20, 0x61, 0x72, 0x65, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x2e, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x69, 0x6e, 0x67, + 0x20, 0x22, 0x2e, 0x2e, 0x64, 0x2e, 0x2e, 0x61, 0x2e, 0x2e, 0x63, 0x29, + 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, + 0x6c, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, + 0x0a, 0x0a, 0x20, 0x09, 0x61, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x20, 0x22, + 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x25, 0x28, 0x25, 0x29, 0x5d, 0x29, 0x25, + 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x31, 0x22, 0x29, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x73, 0x74, 0x72, 0x69, + 0x70, 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x70, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x28, 0x73, 0x74, 0x72, 0x73, + 0x75, 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x29, 0x3b, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, + 0x28, 0x61, 0x2c, 0x31, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x20, 0x31, 0x2c, + 0x20, 0x2d, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x6c, 0x65, + 0x6e, 0x28, 0x6c, 0x61, 0x73, 0x74, 0x29, 0x2b, 0x31, 0x29, 0x29, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, + 0x20, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x2c, 0x22, + 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x31, 0x29, + 0x0a, 0x0a, 0x09, 0x09, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x22, 0x28, 0x22, + 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x6e, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x2c, 0x25, + 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x2e, 0x2e, 0x27, + 0x29, 0x27, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6e, 0x73, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x73, 0x28, 0x6e, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x46, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x6e, 0x73, 0x2c, 0x20, + 0x63, 0x29, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, + 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x09, + 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, + 0x20, 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, 0x69, 0x5d, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, + 0x6c, 0x2e, 0x6e, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, + 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x76, + 0x61, 0x72, 0x27, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x0a, 0x20, 0x20, + 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x64, 0x2c, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x29, 0x0a, 0x20, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x0a, 0x20, 0x66, + 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x0a, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x46, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x66, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6a, 0x6f, + 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x70, 0x2c, 0x20, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x29, 0x0a, + 0x0a, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, + 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x61, + 0x73, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x72, + 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x6e, 0x28, + 0x74, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x73, + 0x65, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x20, + 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x66, 0x6f, 0x72, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2c, 0x6c, + 0x61, 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x0a, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x6c, 0x73, 0x65, + 0x70, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x09, 0x09, 0x6c, 0x73, + 0x65, 0x70, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x70, 0x0a, 0x09, 0x09, 0x6c, + 0x6f, 0x6f, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x72, 0x65, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, + 0x70, 0x61, 0x72, 0x73, 0x28, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, + 0x2c, 0x20, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, + 0x61, 0x73, 0x74, 0x0a, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, + 0x74, 0x2e, 0x6e, 0x2c, 0x31, 0x2c, 0x2d, 0x31, 0x20, 0x64, 0x6f, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x74, 0x5b, 0x69, + 0x5d, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6c, + 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x0a, 0x09, 0x09, 0x09, 0x73, + 0x74, 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x69, 0x66, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x2d, 0x2d, 0x09, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, + 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2c, 0x73, 0x74, 0x72, 0x69, 0x70, 0x2c, + 0x6c, 0x61, 0x73, 0x74, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x70, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x28, 0x73, + 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, + 0x5e, 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x73, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x29, 0x24, 0x22, 0x2c, + 0x20, 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x20, 0x22, + 0x2c, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, + 0x65, 0x70, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x22, 0x22, + 0x2c, 0x22, 0x22, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, + 0x2c, 0x74, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x74, 0x5b, + 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x22, + 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x2e, + 0x73, 0x65, 0x70, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x09, 0x09, + 0x73, 0x65, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x2c, 0x22, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x22, 0x28, 0x22, 0x2e, 0x2e, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x22, 0x29, + 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a +}; +unsigned int lua_function_lua_len = 14264; diff --git a/lib/tolua++/src/bin/lua/enumerate.lua b/lib/tolua++/src/bin/lua/enumerate.lua index 99fe74629..5f0dedfe1 100644 --- a/lib/tolua++/src/bin/lua/enumerate.lua +++ b/lib/tolua++/src/bin/lua/enumerate.lua @@ -48,6 +48,21 @@ function classEnumerate:print (ident,close) print(ident.."}"..close) end +_global_output_enums = {} + +-- write support code +function classEnumerate:supcode () + if _global_output_enums[self.name] ~= nil then + _global_output_enums[self.name] = 1 + output("int tolua_is" .. self.name .. " (lua_State* L, int lo, int def, tolua_Error* err)") + output("{") + output("if (!tolua_isnumber(L,lo,def,err)) return 0;") + output("int val = tolua_tonumber(L,lo,def);") + output("return val >= " .. self.min .. " && val <= " ..self.max .. ";") + output("}") + end +end + -- Internal constructor function _Enumerate (t,varname) setmetatable(t,classEnumerate) @@ -67,40 +82,57 @@ function _Enumerate (t,varname) t.access = parent.curr_member_access t.global_access = t:check_public_access() end -return t + return t end -- Constructor -- Expects a string representing the enumerate body function Enumerate (n,b,varname) b = string.gsub(b, ",[%s\n]*}", "\n}") -- eliminate last ',' - local t = split(strsub(b,2,-2),',') -- eliminate braces - local i = 1 - local e = {n=0} - while t[i] do - local tt = split(t[i],'=') -- discard initial value - e.n = e.n + 1 - e[e.n] = tt[1] - i = i+1 - end - -- set lua names - i = 1 - e.lnames = {} - local ns = getcurrnamespace() - while e[i] do - local t = split(e[i],'@') - e[i] = t[1] + local t = split(strsub(b,2,-2),',') -- eliminate braces + local i = 1 + local e = {n=0} + local value = 0 + local min = 0 + local max = 0 + while t[i] do + local tt = split(t[i],'=') -- discard initial value + e.n = e.n + 1 + e[e.n] = tt[1] + tt[2] = tonumber(tt[2]) + if tt[2] == nil then + tt[2] = value + end + value = tt[2] + 1 -- advance the selected value + if tt[2] > max then + max = tt[2] + end + if tt[2] < min then + min = tt[2] + end + i = i+1 + end + -- set lua names + i = 1 + e.lnames = {} + local ns = getcurrnamespace() + while e[i] do + local t = split(e[i],'@') + e[i] = t[1] if not t[2] then - t[2] = applyrenaming(t[1]) + t[2] = applyrenaming(t[1]) end - e.lnames[i] = t[2] or t[1] - _global_enums[ ns..e[i] ] = (ns..e[i]) - i = i+1 - end + e.lnames[i] = t[2] or t[1] + _global_enums[ ns..e[i] ] = (ns..e[i]) + i = i+1 + end e.name = n + e.min = min + e.max = max if n ~= "" then Typedef("int "..n) + _is_functions[n] = "tolua_is" .. n end - return _Enumerate(e, varname) + return _Enumerate(e, varname) end diff --git a/lib/tolua++/src/bin/lua/function.lua b/lib/tolua++/src/bin/lua/function.lua index 2358e9ff7..7120fb063 100644 --- a/lib/tolua++/src/bin/lua/function.lua +++ b/lib/tolua++/src/bin/lua/function.lua @@ -50,7 +50,6 @@ end -- Write binding function -- Outputs C/C++ binding function. function classFunction:supcode (local_constructor) - local overload = strsub(self.cname,-2,-1) - 1 -- indicate overloaded func local nret = 0 -- number of returned values local class = self:inclass() diff --git a/lib/tolua++/src/bin/toluabind.c b/lib/tolua++/src/bin/toluabind.c index bf71cf158..6be141580 100644 --- a/lib/tolua++/src/bin/toluabind.c +++ b/lib/tolua++/src/bin/toluabind.c @@ -384,603 +384,8 @@ TOLUA_API int tolua_tolua_open (lua_State* tolua_S) { /* begin embedded lua code */ int top = lua_gettop(tolua_S); - static unsigned char B[] = { - 45, 45, 32,116,111,108,117, 97, 58, 32, 98, 97,115,105, 99, - 32,117,116,105,108,105,116,121, 32,102,117,110, 99,116,105, - 111,110,115, 10, 45, 45, 32, 87,114,105,116,116,101,110, 32, - 98,121, 32, 87, 97,108,100,101,109, 97,114, 32, 67,101,108, - 101,115, 10, 45, 45, 32, 84,101, 67, 71,114, 97,102, 47, 80, - 85, 67, 45, 82,105,111, 10, 45, 45, 32, 74,117,108, 32, 49, - 57, 57, 56, 10, 45, 45, 32, 76, 97,115,116, 32,117,112,100, - 97,116,101, 58, 32, 65,112,114, 32, 50, 48, 48, 51, 10, 45, - 45, 32, 36, 73,100, 58, 32, 36, 10, 10, 45, 45, 32, 84,104, - 105,115, 32, 99,111,100,101, 32,105,115, 32,102,114,101,101, - 32,115,111,102,116,119, 97,114,101, 59, 32,121,111,117, 32, - 99, 97,110, 32,114,101,100,105,115,116,114,105, 98,117,116, - 101, 32,105,116, 32, 97,110,100, 47,111,114, 32,109,111,100, - 105,102,121, 32,105,116, 46, 10, 45, 45, 32, 84,104,101, 32, - 115,111,102,116,119, 97,114,101, 32,112,114,111,118,105,100, - 101,100, 32,104,101,114,101,117,110,100,101,114, 32,105,115, - 32,111,110, 32, 97,110, 32, 34, 97,115, 32,105,115, 34, 32, - 98, 97,115,105,115, 44, 32, 97,110,100, 10, 45, 45, 32,116, - 104,101, 32, 97,117,116,104,111,114, 32,104, 97,115, 32,110, - 111, 32,111, 98,108,105,103, 97,116,105,111,110, 32,116,111, - 32,112,114,111,118,105,100,101, 32,109, 97,105,110,116,101, - 110, 97,110, 99,101, 44, 32,115,117,112,112,111,114,116, 44, - 32,117,112,100, 97,116,101,115, 44, 10, 45, 45, 32,101,110, - 104, 97,110, 99,101,109,101,110,116,115, 44, 32,111,114, 32, - 109,111,100,105,102,105, 99, 97,116,105,111,110,115, 46, 10, - 10, 10, 45, 45, 32, 66, 97,115,105, 99, 32, 67, 32,116,121, - 112,101,115, 32, 97,110,100, 32,116,104,101,105,114, 32, 99, - 111,114,114,101,115,112,111,110,100,105,110,103, 32, 76,117, - 97, 32,116,121,112,101,115, 10, 45, 45, 32, 65,108,108, 32, - 111, 99, 99,117,114,114,101,110, 99,101,115, 32,111,102, 32, - 34, 99,104, 97,114, 42, 34, 32,119,105,108,108, 32, 98,101, - 32,114,101,112,108, 97, 99,101,100, 32, 98,121, 32, 34, 95, - 99,115,116,114,105,110,103, 34, 44, 10, 45, 45, 32, 97,110, - 100, 32, 97,108,108, 32,111, 99, 99,117,114,114,101,110, 99, - 101,115, 32,111,102, 32, 34,118,111,105,100, 42, 34, 32,119, - 105,108,108, 32, 98,101, 32,114,101,112,108, 97, 99,101,100, - 32, 98,121, 32, 34, 95,117,115,101,114,100, 97,116, 97, 34, - 10, 95, 98, 97,115,105, 99, 32, 61, 32,123, 10, 32, 91, 39, - 118,111,105,100, 39, 93, 32, 61, 32, 39, 39, 44, 10, 32, 91, - 39, 99,104, 97,114, 39, 93, 32, 61, 32, 39,110,117,109, 98, - 101,114, 39, 44, 10, 32, 91, 39,105,110,116, 39, 93, 32, 61, - 32, 39,110,117,109, 98,101,114, 39, 44, 10, 32, 91, 39,115, - 104,111,114,116, 39, 93, 32, 61, 32, 39,110,117,109, 98,101, - 114, 39, 44, 10, 32, 91, 39,108,111,110,103, 39, 93, 32, 61, - 32, 39,110,117,109, 98,101,114, 39, 44, 10, 32, 91, 39,117, - 110,115,105,103,110,101,100, 39, 93, 32, 61, 32, 39,110,117, - 109, 98,101,114, 39, 44, 10, 32, 91, 39,102,108,111, 97,116, - 39, 93, 32, 61, 32, 39,110,117,109, 98,101,114, 39, 44, 10, - 32, 91, 39,100,111,117, 98,108,101, 39, 93, 32, 61, 32, 39, - 110,117,109, 98,101,114, 39, 44, 10, 32, 91, 39, 95, 99,115, - 116,114,105,110,103, 39, 93, 32, 61, 32, 39,115,116,114,105, - 110,103, 39, 44, 10, 32, 91, 39, 95,117,115,101,114,100, 97, - 116, 97, 39, 93, 32, 61, 32, 39,117,115,101,114,100, 97,116, - 97, 39, 44, 10, 32, 91, 39, 99,104, 97,114, 42, 39, 93, 32, - 61, 32, 39,115,116,114,105,110,103, 39, 44, 10, 32, 91, 39, - 118,111,105,100, 42, 39, 93, 32, 61, 32, 39,117,115,101,114, - 100, 97,116, 97, 39, 44, 10, 32, 91, 39, 98,111,111,108, 39, - 93, 32, 61, 32, 39, 98,111,111,108,101, 97,110, 39, 44, 10, - 32, 91, 39,108,117, 97, 95, 79, 98,106,101, 99,116, 39, 93, - 32, 61, 32, 39,118, 97,108,117,101, 39, 44, 10, 32, 91, 39, - 76, 85, 65, 95, 86, 65, 76, 85, 69, 39, 93, 32, 61, 32, 39, - 118, 97,108,117,101, 39, 44, 32, 32, 32, 32, 45, 45, 32,102, - 111,114, 32, 99,111,109,112, 97,116,105, 98,105,108,105,116, - 121, 32,119,105,116,104, 32,116,111,108,117, 97, 32, 52, 46, - 48, 10, 32, 91, 39,108,117, 97, 95, 83,116, 97,116,101, 42, - 39, 93, 32, 61, 32, 39,115,116, 97,116,101, 39, 44, 10, 32, - 91, 39, 95,108,115,116, 97,116,101, 39, 93, 32, 61, 32, 39, - 115,116, 97,116,101, 39, 44, 10, 32, 91, 39,108,117, 97, 95, - 70,117,110, 99,116,105,111,110, 39, 93, 32, 61, 32, 39,118, - 97,108,117,101, 39, 44, 10,125, 10, 10, 95, 98, 97,115,105, - 99, 95, 99,116,121,112,101, 32, 61, 32,123, 10, 32,110,117, - 109, 98,101,114, 32, 61, 32, 34,108,117, 97, 95, 78,117,109, - 98,101,114, 34, 44, 10, 32,115,116,114,105,110,103, 32, 61, - 32, 34, 99,111,110,115,116, 32, 99,104, 97,114, 42, 34, 44, - 10, 32,117,115,101,114,100, 97,116, 97, 32, 61, 32, 34,118, - 111,105,100, 42, 34, 44, 10, 32, 98,111,111,108,101, 97,110, - 32, 61, 32, 34, 98,111,111,108, 34, 44, 10, 32,118, 97,108, - 117,101, 32, 61, 32, 34,105,110,116, 34, 44, 10, 32,115,116, - 97,116,101, 32, 61, 32, 34,108,117, 97, 95, 83,116, 97,116, - 101, 42, 34, 44, 10,125, 10, 10, 45, 45, 32,102,117,110, 99, - 116,105,111,110,115, 32,116,104,101, 32, 97,114,101, 32,117, - 115,101,100, 32,116,111, 32,100,111, 32, 97, 32, 39,114, 97, - 119, 32,112,117,115,104, 39, 32,111,102, 32, 98, 97,115,105, - 99, 32,116,121,112,101,115, 10, 95, 98, 97,115,105, 99, 95, - 114, 97,119, 95,112,117,115,104, 32, 61, 32,123,125, 10, 10, - 45, 45, 32, 76,105,115,116, 32,111,102, 32,117,115,101,114, - 32,100,101,102,105,110,101,100, 32,116,121,112,101,115, 10, - 45, 45, 32, 69, 97, 99,104, 32,116,121,112,101, 32, 99,111, - 114,114,101,115,112,111,110,100,115, 32,116,111, 32, 97, 32, - 118, 97,114,105, 97, 98,108,101, 32,110, 97,109,101, 32,116, - 104, 97,116, 32,115,116,111,114,101,115, 32,105,116,115, 32, - 116, 97,103, 32,118, 97,108,117,101, 46, 10, 95,117,115,101, - 114,116,121,112,101, 32, 61, 32,123,125, 10, 10, 45, 45, 32, - 76,105,115,116, 32,111,102, 32,116,121,112,101,115, 32,116, - 104, 97,116, 32,104, 97,118,101, 32,116,111, 32, 98,101, 32, - 99,111,108,108,101, 99,116,101,100, 10, 95, 99,111,108,108, - 101, 99,116, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 76,105, - 115,116, 32,111,102, 32,116,121,112,101,115, 10, 95,103,108, - 111, 98, 97,108, 95,116,121,112,101,115, 32, 61, 32,123,110, - 61, 48,125, 10, 95,103,108,111, 98, 97,108, 95,116,121,112, - 101,115, 95,104, 97,115,104, 32, 61, 32,123,125, 10, 10, 45, - 45, 32,108,105,115,116, 32,111,102, 32, 99,108, 97,115,115, - 101,115, 10, 95,103,108,111, 98, 97,108, 95, 99,108, 97,115, - 115,101,115, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 76,105, - 115,116, 32,111,102, 32,101,110,117,109, 32, 99,111,110,115, - 116, 97,110,116,115, 10, 95,103,108,111, 98, 97,108, 95,101, - 110,117,109,115, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 76, - 105,115,116, 32,111,102, 32, 97,117,116,111, 32,114,101,110, - 97,109,105,110,103, 10, 95,114,101,110, 97,109,105,110,103, - 32, 61, 32,123,125, 10,102,117,110, 99,116,105,111,110, 32, - 97,112,112,101,110,100,114,101,110, 97,109,105,110,103, 32, - 40,115, 41, 10, 32,108,111, 99, 97,108, 32, 98, 44,101, 44, - 111,108,100, 44,110,101,119, 32, 61, 32,115,116,114,102,105, - 110,100, 40,115, 44, 34, 37,115, 42, 40, 46, 45, 41, 37,115, - 42, 64, 37,115, 42, 40, 46, 45, 41, 37,115, 42, 36, 34, 41, - 10, 9,105,102, 32,110,111,116, 32, 98, 32,116,104,101,110, - 10, 9, 32,101,114,114,111,114, 40, 34, 35, 73,110,118, 97, - 108,105,100, 32,114,101,110, 97,109,105,110,103, 32,115,121, - 110,116, 97,120, 59, 32,105,116, 32,115,104,111,117,108,100, - 32, 98,101, 32,111,102, 32,116,104,101, 32,102,111,114,109, - 58, 32,112, 97,116,116,101,114,110, 64,112, 97,116,116,101, - 114,110, 34, 41, 10, 9,101,110,100, 10, 9,116,105,110,115, - 101,114,116, 40, 95,114,101,110, 97,109,105,110,103, 44,123, - 111,108,100, 61,111,108,100, 44, 32,110,101,119, 61,110,101, - 119,125, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, - 111,110, 32, 97,112,112,108,121,114,101,110, 97,109,105,110, - 103, 32, 40,115, 41, 10, 9,102,111,114, 32,105, 61, 49, 44, - 103,101,116,110, 40, 95,114,101,110, 97,109,105,110,103, 41, - 32,100,111, 10, 9, 32,108,111, 99, 97,108, 32,109, 44,110, - 32, 61, 32,103,115,117, 98, 40,115, 44, 95,114,101,110, 97, - 109,105,110,103, 91,105, 93, 46,111,108,100, 44, 95,114,101, - 110, 97,109,105,110,103, 91,105, 93, 46,110,101,119, 41, 10, - 9, 9,105,102, 32,110, 32,126, 61, 32, 48, 32,116,104,101, - 110, 10, 9, 9, 32,114,101,116,117,114,110, 32,109, 10, 9, - 9,101,110,100, 10, 9,101,110,100, 10, 9,114,101,116,117, - 114,110, 32,110,105,108, 10,101,110,100, 10, 10, 45, 45, 32, - 69,114,114,111,114, 32,104, 97,110,100,108,101,114, 10,102, - 117,110, 99,116,105,111,110, 32,116,111,108,117, 97, 95,101, - 114,114,111,114, 32, 40,115, 44,102, 41, 10,105,102, 32, 95, - 99,117,114,114, 95, 99,111,100,101, 32,116,104,101,110, 10, - 9,112,114,105,110,116, 40, 34, 42, 42, 42, 99,117,114,114, - 32, 99,111,100,101, 32,102,111,114, 32,101,114,114,111,114, - 32,105,115, 32, 34, 46, 46,116,111,115,116,114,105,110,103, - 40, 95, 99,117,114,114, 95, 99,111,100,101, 41, 41, 10, 9, - 112,114,105,110,116, 40,100,101, 98,117,103, 46,116,114, 97, - 99,101, 98, 97, 99,107, 40, 41, 41, 10,101,110,100, 10, 32, - 108,111, 99, 97,108, 32,111,117,116, 32, 61, 32, 95, 79, 85, - 84, 80, 85, 84, 10, 32, 95, 79, 85, 84, 80, 85, 84, 32, 61, - 32, 95, 83, 84, 68, 69, 82, 82, 10, 32,105,102, 32,115,116, - 114,115,117, 98, 40,115, 44, 49, 44, 49, 41, 32, 61, 61, 32, - 39, 35, 39, 32,116,104,101,110, 10, 32, 32,119,114,105,116, - 101, 40, 34, 92,110, 42, 42, 32,116,111,108,117, 97, 58, 32, - 34, 46, 46,115,116,114,115,117, 98, 40,115, 44, 50, 41, 46, - 46, 34, 46, 92,110, 92,110, 34, 41, 10, 32, 32,105,102, 32, - 95, 99,117,114,114, 95, 99,111,100,101, 32,116,104,101,110, - 10, 32, 32, 32,108,111, 99, 97,108, 32, 95, 44, 95, 44,115, - 32, 61, 32,115,116,114,102,105,110,100, 40, 95, 99,117,114, - 114, 95, 99,111,100,101, 44, 34, 94, 37,115, 42, 40, 46, 45, - 92,110, 41, 34, 41, 32, 45, 45, 32,101,120,116,114, 97, 99, - 116, 32,102,105,114,115,116, 32,108,105,110,101, 10, 32, 32, - 32,105,102, 32,115, 61, 61,110,105,108, 32,116,104,101,110, - 32,115, 32, 61, 32, 95, 99,117,114,114, 95, 99,111,100,101, - 32,101,110,100, 10, 32, 32, 32,115, 32, 61, 32,103,115,117, - 98, 40,115, 44, 34, 95,117,115,101,114,100, 97,116, 97, 34, - 44, 34,118,111,105,100, 42, 34, 41, 32, 45, 45, 32,114,101, - 116,117,114,110, 32,119,105,116,104, 32, 39,118,111,105,100, - 42, 39, 10, 32, 32, 32,115, 32, 61, 32,103,115,117, 98, 40, - 115, 44, 34, 95, 99,115,116,114,105,110,103, 34, 44, 34, 99, - 104, 97,114, 42, 34, 41, 32, 32, 45, 45, 32,114,101,116,117, - 114,110, 32,119,105,116,104, 32, 39, 99,104, 97,114, 42, 39, - 10, 32, 32, 32,115, 32, 61, 32,103,115,117, 98, 40,115, 44, - 34, 95,108,115,116, 97,116,101, 34, 44, 34,108,117, 97, 95, - 83,116, 97,116,101, 42, 34, 41, 32, 32, 45, 45, 32,114,101, - 116,117,114,110, 32,119,105,116,104, 32, 39,108,117, 97, 95, - 83,116, 97,116,101, 42, 39, 10, 32, 32, 32,119,114,105,116, - 101, 40, 34, 67,111,100,101, 32, 98,101,105,110,103, 32,112, - 114,111, 99,101,115,115,101,100, 58, 92,110, 34, 46, 46,115, - 46, 46, 34, 92,110, 34, 41, 10, 32, 32,101,110,100, 10, 32, - 101,108,115,101, 10, 32,105,102, 32,110,111,116, 32,102, 32, - 116,104,101,110, 32,102, 32, 61, 32, 34, 40,102, 32,105,115, - 32,110,105,108, 41, 34, 32,101,110,100, 10, 32, 32,112,114, - 105,110,116, 40, 34, 92,110, 42, 42, 32,116,111,108,117, 97, - 32,105,110,116,101,114,110, 97,108, 32,101,114,114,111,114, - 58, 32, 34, 46, 46,102, 46, 46,115, 46, 46, 34, 46, 92,110, - 92,110, 34, 41, 10, 32, 32,114,101,116,117,114,110, 10, 32, - 101,110,100, 10, 32, 95, 79, 85, 84, 80, 85, 84, 32, 61, 32, - 111,117,116, 10,101,110,100, 10, 10,102,117,110, 99,116,105, - 111,110, 32,119, 97,114,110,105,110,103, 32, 40,109,115,103, - 41, 10, 32,105,102, 32,102,108, 97,103,115, 46,113, 32,116, - 104,101,110, 32,114,101,116,117,114,110, 32,101,110,100, 10, - 32,108,111, 99, 97,108, 32,111,117,116, 32, 61, 32, 95, 79, - 85, 84, 80, 85, 84, 10, 32, 95, 79, 85, 84, 80, 85, 84, 32, - 61, 32, 95, 83, 84, 68, 69, 82, 82, 10, 32,119,114,105,116, - 101, 40, 34, 92,110, 42, 42, 32,116,111,108,117, 97, 32,119, - 97,114,110,105,110,103, 58, 32, 34, 46, 46,109,115,103, 46, - 46, 34, 46, 92,110, 92,110, 34, 41, 10, 32, 95, 79, 85, 84, - 80, 85, 84, 32, 61, 32,111,117,116, 10,101,110,100, 10, 10, - 45, 45, 32,114,101,103,105,115,116,101,114, 32, 97,110, 32, - 117,115,101,114, 32,100,101,102,105,110,101,100, 32,116,121, - 112,101, 58, 32,114,101,116,117,114,110,115, 32,102,117,108, - 108, 32,116,121,112,101, 10,102,117,110, 99,116,105,111,110, - 32,114,101,103,116,121,112,101, 32, 40,116, 41, 10, 9, 45, - 45,105,102, 32,105,115, 98, 97,115,105, 99, 40,116, 41, 32, - 116,104,101,110, 10, 9, 45, 45, 9,114,101,116,117,114,110, - 32,116, 10, 9, 45, 45,101,110,100, 10, 9,108,111, 99, 97, - 108, 32,102,116, 32, 61, 32,102,105,110,100,116,121,112,101, - 40,116, 41, 10, 10, 9,105,102, 32,110,111,116, 32, 95,117, - 115,101,114,116,121,112,101, 91,102,116, 93, 32,116,104,101, - 110, 10, 9, 9,114,101,116,117,114,110, 32, 97,112,112,101, - 110,100,117,115,101,114,116,121,112,101, 40,116, 41, 10, 9, - 101,110,100, 10, 9,114,101,116,117,114,110, 32,102,116, 10, - 101,110,100, 10, 10, 45, 45, 32,114,101,116,117,114,110, 32, - 116,121,112,101, 32,110, 97,109,101, 58, 32,114,101,116,117, - 114,110,115, 32,102,117,108,108, 32,116,121,112,101, 10,102, - 117,110, 99,116,105,111,110, 32,116,121,112,101,118, 97,114, - 40,116,121,112,101, 41, 10, 9,105,102, 32,116,121,112,101, - 32, 61, 61, 32, 39, 39, 32,111,114, 32,116,121,112,101, 32, - 61, 61, 32, 39,118,111,105,100, 39, 32,116,104,101,110, 10, - 9, 9,114,101,116,117,114,110, 32,116,121,112,101, 10, 9, - 101,108,115,101, 10, 9, 9,108,111, 99, 97,108, 32,102,116, - 32, 61, 32,102,105,110,100,116,121,112,101, 40,116,121,112, - 101, 41, 10, 9, 9,105,102, 32,102,116, 32,116,104,101,110, - 10, 9, 9, 9,114,101,116,117,114,110, 32,102,116, 10, 9, - 9,101,110,100, 10, 9, 9, 95,117,115,101,114,116,121,112, - 101, 91,116,121,112,101, 93, 32, 61, 32,116,121,112,101, 10, - 9, 9,114,101,116,117,114,110, 32,116,121,112,101, 10, 9, - 101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,104,101, - 99,107, 32,105,102, 32, 98, 97,115,105, 99, 32,116,121,112, - 101, 10,102,117,110, 99,116,105,111,110, 32,105,115, 98, 97, - 115,105, 99, 32, 40,116,121,112,101, 41, 10, 32,108,111, 99, - 97,108, 32,116, 32, 61, 32,103,115,117, 98, 40,116,121,112, - 101, 44, 39, 99,111,110,115,116, 32, 39, 44, 39, 39, 41, 10, - 32,108,111, 99, 97,108, 32,109, 44,116, 32, 61, 32, 97,112, - 112,108,121,116,121,112,101,100,101,102, 40, 39, 39, 44, 32, - 116, 41, 10, 32,108,111, 99, 97,108, 32, 98, 32, 61, 32, 95, - 98, 97,115,105, 99, 91,116, 93, 10, 32,105,102, 32, 98, 32, - 116,104,101,110, 10, 32, 32,114,101,116,117,114,110, 32, 98, - 44, 95, 98, 97,115,105, 99, 95, 99,116,121,112,101, 91, 98, - 93, 10, 32,101,110,100, 10, 32,114,101,116,117,114,110, 32, - 110,105,108, 10,101,110,100, 10, 10, 45, 45, 32,115,112,108, - 105,116, 32,115,116,114,105,110,103, 32,117,115,105,110,103, - 32, 97, 32,116,111,107,101,110, 10,102,117,110, 99,116,105, - 111,110, 32,115,112,108,105,116, 32, 40,115, 44,116, 41, 10, - 32,108,111, 99, 97,108, 32,108, 32, 61, 32,123,110, 61, 48, - 125, 10, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,102,117, - 110, 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32,108, 46, - 110, 32, 61, 32,108, 46,110, 32, 43, 32, 49, 10, 32, 32,108, - 91,108, 46,110, 93, 32, 61, 32,115, 10, 32, 32,114,101,116, - 117,114,110, 32, 34, 34, 10, 32,101,110,100, 10, 32,108,111, - 99, 97,108, 32,112, 32, 61, 32, 34, 37,115, 42, 40, 46, 45, - 41, 37,115, 42, 34, 46, 46,116, 46, 46, 34, 37,115, 42, 34, - 10, 32,115, 32, 61, 32,103,115,117, 98, 40,115, 44, 34, 94, - 37,115, 43, 34, 44, 34, 34, 41, 10, 32,115, 32, 61, 32,103, - 115,117, 98, 40,115, 44, 34, 37,115, 43, 36, 34, 44, 34, 34, - 41, 10, 32,115, 32, 61, 32,103,115,117, 98, 40,115, 44,112, - 44,102, 41, 10, 32,108, 46,110, 32, 61, 32,108, 46,110, 32, - 43, 32, 49, 10, 32,108, 91,108, 46,110, 93, 32, 61, 32,103, - 115,117, 98, 40,115, 44, 34, 40, 37,115, 37,115, 42, 41, 36, - 34, 44, 34, 34, 41, 10, 32,114,101,116,117,114,110, 32,108, - 10,101,110,100, 10, 10, 45, 45, 32,115,112,108,105,116,115, - 32, 97, 32,115,116,114,105,110,103, 32,117,115,105,110,103, - 32, 97, 32,112, 97,116,116,101,114,110, 44, 32, 99,111,110, - 115,105,100,101,114,105,110,103, 32,116,104,101, 32,115,112, - 97, 99,105, 97,108, 32, 99, 97,115,101,115, 32,111,102, 32, - 67, 32, 99,111,100,101, 32, 40,116,101,109,112,108, 97,116, - 101,115, 44, 32,102,117,110, 99,116,105,111,110, 32,112, 97, - 114, 97,109,101,116,101,114,115, 44, 32,101,116, 99, 41, 10, - 45, 45, 32,112, 97,116,116,101,114,110, 32, 99, 97,110, 39, - 116, 32, 99,111,110,116, 97,105,110, 32,116,104,101, 32, 39, - 94, 39, 32, 40, 97,115, 32,117,115,101,100, 32,116,111, 32, - 105,100,101,110,116,105,102,121, 32,116,104,101, 32, 98,101, - 103,105,110,105,110,103, 32,111,102, 32,116,104,101, 32,108, - 105,110,101, 41, 10, 45, 45, 32, 97,108,115,111, 32,115,116, - 114,105,112,115, 32,119,104,105,116,101,115,112, 97, 99,101, - 10,102,117,110, 99,116,105,111,110, 32,115,112,108,105,116, - 95, 99, 95,116,111,107,101,110,115, 40,115, 44, 32,112, 97, - 116, 41, 10, 10, 9,115, 32, 61, 32,115,116,114,105,110,103, - 46,103,115,117, 98, 40,115, 44, 32, 34, 94, 37,115, 42, 34, - 44, 32, 34, 34, 41, 10, 9,115, 32, 61, 32,115,116,114,105, - 110,103, 46,103,115,117, 98, 40,115, 44, 32, 34, 37,115, 42, - 36, 34, 44, 32, 34, 34, 41, 10, 10, 9,108,111, 99, 97,108, - 32,116,111,107,101,110, 95, 98,101,103,105,110, 32, 61, 32, - 49, 10, 9,108,111, 99, 97,108, 32,116,111,107,101,110, 95, - 101,110,100, 32, 61, 32, 49, 10, 9,108,111, 99, 97,108, 32, - 111,102,115, 32, 61, 32, 49, 10, 9,108,111, 99, 97,108, 32, - 114,101,116, 32, 61, 32,123,110, 61, 48,125, 10, 10, 9,102, - 117,110, 99,116,105,111,110, 32, 97,100,100, 95,116,111,107, - 101,110, 40,111,102,115, 41, 10, 10, 9, 9,108,111, 99, 97, - 108, 32,116, 32, 61, 32,115,116,114,105,110,103, 46,115,117, - 98, 40,115, 44, 32,116,111,107,101,110, 95, 98,101,103,105, - 110, 44, 32,111,102,115, 41, 10, 9, 9,116, 32, 61, 32,115, - 116,114,105,110,103, 46,103,115,117, 98, 40,116, 44, 32, 34, - 94, 37,115, 42, 34, 44, 32, 34, 34, 41, 10, 9, 9,116, 32, - 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,116, - 44, 32, 34, 37,115, 42, 36, 34, 44, 32, 34, 34, 41, 10, 9, - 9,114,101,116, 46,110, 32, 61, 32,114,101,116, 46,110, 32, - 43, 32, 49, 10, 9, 9,114,101,116, 91,114,101,116, 46,110, - 93, 32, 61, 32,116, 10, 9,101,110,100, 10, 10, 9,119,104, - 105,108,101, 32,111,102,115, 32, 60, 61, 32,115,116,114,105, - 110,103, 46,108,101,110, 40,115, 41, 32,100,111, 10, 10, 9, - 9,108,111, 99, 97,108, 32,115,117, 98, 32, 61, 32,115,116, - 114,105,110,103, 46,115,117, 98, 40,115, 44, 32,111,102,115, - 44, 32, 45, 49, 41, 10, 9, 9,108,111, 99, 97,108, 32, 98, - 44,101, 32, 61, 32,115,116,114,105,110,103, 46,102,105,110, - 100, 40,115,117, 98, 44, 32, 34, 94, 34, 46, 46,112, 97,116, - 41, 10, 9, 9,105,102, 32, 98, 32,116,104,101,110, 10, 9, - 9, 9, 97,100,100, 95,116,111,107,101,110, 40,111,102,115, - 45, 49, 41, 10, 9, 9, 9,111,102,115, 32, 61, 32,111,102, - 115, 43,101, 10, 9, 9, 9,116,111,107,101,110, 95, 98,101, - 103,105,110, 32, 61, 32,111,102,115, 10, 9, 9,101,108,115, - 101, 10, 9, 9, 9,108,111, 99, 97,108, 32, 99,104, 97,114, - 32, 61, 32,115,116,114,105,110,103, 46,115,117, 98, 40,115, - 44, 32,111,102,115, 44, 32,111,102,115, 41, 10, 9, 9, 9, - 105,102, 32, 99,104, 97,114, 32, 61, 61, 32, 34, 40, 34, 32, - 111,114, 32, 99,104, 97,114, 32, 61, 61, 32, 34, 60, 34, 32, - 116,104,101,110, 10, 10, 9, 9, 9, 9,108,111, 99, 97,108, - 32, 98,108,111, 99,107, 10, 9, 9, 9, 9,105,102, 32, 99, - 104, 97,114, 32, 61, 61, 32, 34, 40, 34, 32,116,104,101,110, - 32, 98,108,111, 99,107, 32, 61, 32, 34, 94, 37, 98, 40, 41, - 34, 32,101,110,100, 10, 9, 9, 9, 9,105,102, 32, 99,104, - 97,114, 32, 61, 61, 32, 34, 60, 34, 32,116,104,101,110, 32, - 98,108,111, 99,107, 32, 61, 32, 34, 94, 37, 98, 60, 62, 34, - 32,101,110,100, 10, 10, 9, 9, 9, 9, 98, 44,101, 32, 61, - 32,115,116,114,105,110,103, 46,102,105,110,100, 40,115,117, - 98, 44, 32, 98,108,111, 99,107, 41, 10, 9, 9, 9, 9,105, - 102, 32,110,111,116, 32, 98, 32,116,104,101,110, 10, 9, 9, - 9, 9, 9, 45, 45, 32,117,110,116,101,114,109,105,110, 97, - 116,101,100, 32, 98,108,111, 99,107, 63, 10, 9, 9, 9, 9, - 9,111,102,115, 32, 61, 32,111,102,115, 43, 49, 10, 9, 9, - 9, 9,101,108,115,101, 10, 9, 9, 9, 9, 9,111,102,115, - 32, 61, 32,111,102,115, 32, 43, 32,101, 10, 9, 9, 9, 9, - 101,110,100, 10, 10, 9, 9, 9,101,108,115,101, 10, 9, 9, - 9, 9,111,102,115, 32, 61, 32,111,102,115, 43, 49, 10, 9, - 9, 9,101,110,100, 10, 9, 9,101,110,100, 10, 10, 9,101, - 110,100, 10, 9, 97,100,100, 95,116,111,107,101,110, 40,111, - 102,115, 41, 10, 9, 45, 45,105,102, 32,114,101,116, 46,110, - 32, 61, 61, 32, 48, 32,116,104,101,110, 10, 10, 9, 45, 45, - 9,114,101,116, 46,110, 61, 49, 10, 9, 45, 45, 9,114,101, - 116, 91, 49, 93, 32, 61, 32, 34, 34, 10, 9, 45, 45,101,110, - 100, 10, 10, 9,114,101,116,117,114,110, 32,114,101,116, 10, - 10,101,110,100, 10, 10, 45, 45, 32, 99,111,110, 99, 97,116, - 101,110, 97,116,101, 32,115,116,114,105,110,103,115, 32,111, - 102, 32, 97, 32,116, 97, 98,108,101, 10,102,117,110, 99,116, - 105,111,110, 32, 99,111,110, 99, 97,116, 32, 40,116, 44,102, - 44,108, 44,106,115,116,114, 41, 10, 9,106,115,116,114, 32, - 61, 32,106,115,116,114, 32,111,114, 32, 34, 32, 34, 10, 32, - 108,111, 99, 97,108, 32,115, 32, 61, 32, 39, 39, 10, 32,108, - 111, 99, 97,108, 32,105, 61,102, 10, 32,119,104,105,108,101, - 32,105, 60, 61,108, 32,100,111, 10, 32, 32,115, 32, 61, 32, - 115, 46, 46,116, 91,105, 93, 10, 32, 32,105, 32, 61, 32,105, - 43, 49, 10, 32, 32,105,102, 32,105, 32, 60, 61, 32,108, 32, - 116,104,101,110, 32,115, 32, 61, 32,115, 46, 46,106,115,116, - 114, 32,101,110,100, 10, 32,101,110,100, 10, 32,114,101,116, - 117,114,110, 32,115, 10,101,110,100, 10, 10, 45, 45, 32, 99, - 111,110, 99, 97,116,101,110, 97,116,101, 32, 97,108,108, 32, - 112, 97,114, 97,109,101,116,101,114,115, 44, 32,102,111,108, - 108,111,119,105,110,103, 32,111,117,116,112,117,116, 32,114, - 117,108,101,115, 10,102,117,110, 99,116,105,111,110, 32, 99, - 111,110, 99, 97,116,112, 97,114, 97,109, 32, 40,108,105,110, - 101, 44, 32, 46, 46, 46, 41, 10, 32,108,111, 99, 97,108, 32, - 105, 61, 49, 10, 32,119,104,105,108,101, 32,105, 60, 61, 97, - 114,103, 46,110, 32,100,111, 10, 32, 32,105,102, 32, 95, 99, - 111,110,116, 32, 97,110,100, 32,110,111,116, 32,115,116,114, - 102,105,110,100, 40, 95, 99,111,110,116, 44, 39, 91, 37, 40, - 44, 34, 93, 39, 41, 32, 97,110,100, 10, 32, 32, 32, 32, 32, - 115,116,114,102,105,110,100, 40, 97,114,103, 91,105, 93, 44, - 34, 94, 91, 37, 97, 95,126, 93, 34, 41, 32,116,104,101,110, - 10, 9, 32, 32, 32, 32,108,105,110,101, 32, 61, 32,108,105, - 110,101, 32, 46, 46, 32, 39, 32, 39, 10, 32, 32,101,110,100, - 10, 32, 32,108,105,110,101, 32, 61, 32,108,105,110,101, 32, - 46, 46, 32, 97,114,103, 91,105, 93, 10, 32, 32,105,102, 32, - 97,114,103, 91,105, 93, 32,126, 61, 32, 39, 39, 32,116,104, - 101,110, 10, 32, 32, 32, 95, 99,111,110,116, 32, 61, 32,115, - 116,114,115,117, 98, 40, 97,114,103, 91,105, 93, 44, 45, 49, - 44, 45, 49, 41, 10, 32, 32,101,110,100, 10, 32, 32,105, 32, - 61, 32,105, 43, 49, 10, 32,101,110,100, 10, 32,105,102, 32, - 115,116,114,102,105,110,100, 40, 97,114,103, 91, 97,114,103, - 46,110, 93, 44, 34, 91, 37, 47, 37, 41, 37, 59, 37,123, 37, - 125, 93, 36, 34, 41, 32,116,104,101,110, 10, 32, 32, 95, 99, - 111,110,116, 61,110,105,108, 32,108,105,110,101, 32, 61, 32, - 108,105,110,101, 32, 46, 46, 32, 39, 92,110, 39, 10, 32,101, - 110,100, 10, 9,114,101,116,117,114,110, 32,108,105,110,101, - 10,101,110,100, 10, 10, 45, 45, 32,111,117,116,112,117,116, - 32,108,105,110,101, 10,102,117,110, 99,116,105,111,110, 32, - 111,117,116,112,117,116, 32, 40, 46, 46, 46, 41, 10, 32,108, - 111, 99, 97,108, 32,105, 61, 49, 10, 32,119,104,105,108,101, - 32,105, 60, 61, 97,114,103, 46,110, 32,100,111, 10, 32, 32, - 105,102, 32, 95, 99,111,110,116, 32, 97,110,100, 32,110,111, - 116, 32,115,116,114,102,105,110,100, 40, 95, 99,111,110,116, - 44, 39, 91, 37, 40, 44, 34, 93, 39, 41, 32, 97,110,100, 10, - 32, 32, 32, 32, 32,115,116,114,102,105,110,100, 40, 97,114, - 103, 91,105, 93, 44, 34, 94, 91, 37, 97, 95,126, 93, 34, 41, - 32,116,104,101,110, 10, 9, 32, 32, 32, 32,119,114,105,116, - 101, 40, 39, 32, 39, 41, 10, 32, 32,101,110,100, 10, 32, 32, - 119,114,105,116,101, 40, 97,114,103, 91,105, 93, 41, 10, 32, - 32,105,102, 32, 97,114,103, 91,105, 93, 32,126, 61, 32, 39, - 39, 32,116,104,101,110, 10, 32, 32, 32, 95, 99,111,110,116, - 32, 61, 32,115,116,114,115,117, 98, 40, 97,114,103, 91,105, - 93, 44, 45, 49, 44, 45, 49, 41, 10, 32, 32,101,110,100, 10, - 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32,101,110,100, 10, - 32,105,102, 32,115,116,114,102,105,110,100, 40, 97,114,103, - 91, 97,114,103, 46,110, 93, 44, 34, 91, 37, 47, 37, 41, 37, - 59, 37,123, 37,125, 93, 36, 34, 41, 32,116,104,101,110, 10, - 32, 32, 95, 99,111,110,116, 61,110,105,108, 32,119,114,105, - 116,101, 40, 39, 92,110, 39, 41, 10, 32,101,110,100, 10,101, - 110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,103,101, - 116, 95,112,114,111,112,101,114,116,121, 95,109,101,116,104, - 111,100,115, 40,112,116,121,112,101, 44, 32,110, 97,109,101, - 41, 10, 10, 9,105,102, 32,103,101,116, 95,112,114,111,112, - 101,114,116,121, 95,109,101,116,104,111,100,115, 95,104,111, - 111,107, 32, 97,110,100, 32,103,101,116, 95,112,114,111,112, - 101,114,116,121, 95,109,101,116,104,111,100,115, 95,104,111, - 111,107, 40,112,116,121,112,101, 44,110, 97,109,101, 41, 32, - 116,104,101,110, 10, 9, 9,114,101,116,117,114,110, 32,103, - 101,116, 95,112,114,111,112,101,114,116,121, 95,109,101,116, - 104,111,100,115, 95,104,111,111,107, 40,112,116,121,112,101, - 44, 32,110, 97,109,101, 41, 10, 9,101,110,100, 10, 10, 9, - 105,102, 32,112,116,121,112,101, 32, 61, 61, 32, 34,100,101, - 102, 97,117,108,116, 34, 32,116,104,101,110, 32, 45, 45, 32, - 103,101,116, 95,110, 97,109,101, 44, 32,115,101,116, 95,110, - 97,109,101, 10, 9, 9,114,101,116,117,114,110, 32, 34,103, - 101,116, 95, 34, 46, 46,110, 97,109,101, 44, 32, 34,115,101, - 116, 95, 34, 46, 46,110, 97,109,101, 10, 9,101,110,100, 10, - 10, 9,105,102, 32,112,116,121,112,101, 32, 61, 61, 32, 34, - 113,116, 34, 32,116,104,101,110, 32, 45, 45, 32,110, 97,109, - 101, 44, 32,115,101,116, 78, 97,109,101, 10, 9, 9,114,101, - 116,117,114,110, 32,110, 97,109,101, 44, 32, 34,115,101,116, - 34, 46, 46,115,116,114,105,110,103, 46,117,112,112,101,114, - 40,115,116,114,105,110,103, 46,115,117, 98, 40,110, 97,109, - 101, 44, 32, 49, 44, 32, 49, 41, 41, 46, 46,115,116,114,105, - 110,103, 46,115,117, 98, 40,110, 97,109,101, 44, 32, 50, 44, - 32, 45, 49, 41, 10, 9,101,110,100, 10, 10, 9,105,102, 32, - 112,116,121,112,101, 32, 61, 61, 32, 34,111,118,101,114,108, - 111, 97,100, 34, 32,116,104,101,110, 32, 45, 45, 32,110, 97, - 109,101, 44, 32,110, 97,109,101, 10, 9, 9,114,101,116,117, - 114,110, 32,110, 97,109,101, 44,110, 97,109,101, 10, 9,101, - 110,100, 10, 10, 9,114,101,116,117,114,110, 32,110,105,108, - 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 32,116,104,101, 32,104,111,111,107,115, - 10, 10, 45, 45, 32, 99, 97,108,108,101,100, 32,114,105,103, - 104,116, 32, 97,102,116,101,114, 32,112,114,111, 99,101,115, - 115,105,110,103, 32,116,104,101, 32, 36, 91,105, 99,104,108, - 93,102,105,108,101, 32,100,105,114,101, 99,116,105,118,101, - 115, 44, 10, 45, 45, 32,114,105,103,104,116, 32, 98,101,102, - 111,114,101, 32,112,114,111, 99,101,115,115,105,110,103, 32, - 97,110,121,116,104,105,110,103, 32,101,108,115,101, 10, 45, - 45, 32,116, 97,107,101,115, 32,116,104,101, 32,112, 97, 99, - 107, 97,103,101, 32,111, 98,106,101, 99,116, 32, 97,115, 32, - 116,104,101, 32,112, 97,114, 97,109,101,116,101,114, 10,102, - 117,110, 99,116,105,111,110, 32,112,114,101,112,114,111, 99, - 101,115,115, 95,104,111,111,107, 40,112, 41, 10, 9, 45, 45, - 32,112, 46, 99,111,100,101, 32,104, 97,115, 32, 97,108,108, - 32,116,104,101, 32,105,110,112,117,116, 32, 99,111,100,101, - 32,102,114,111,109, 32,116,104,101, 32,112,107,103, 10,101, - 110,100, 10, 10, 10, 45, 45, 32, 99, 97,108,108,101,100, 32, - 102,111,114, 32,101,118,101,114,121, 32, 36,105,102,105,108, - 101, 32,100,105,114,101, 99,116,105,118,101, 10, 45, 45, 32, - 116, 97,107,101,115, 32, 97, 32,116, 97, 98,108,101, 32,119, - 105,116,104, 32, 97, 32,115,116,114,105,110,103, 32, 99, 97, - 108,108,101,100, 32, 39, 99,111,100,101, 39, 32,105,110,115, - 105,100,101, 44, 32,116,104,101, 32,102,105,108,101,110, 97, - 109,101, 44, 32, 97,110,100, 32, 97,110,121, 32,101,120,116, - 114, 97, 32, 97,114,103,117,109,101,110,116,115, 10, 45, 45, - 32,112, 97,115,115,101,100, 32,116,111, 32, 36,105,102,105, - 108,101, 46, 32,110,111, 32,114,101,116,117,114,110, 32,118, - 97,108,117,101, 10,102,117,110, 99,116,105,111,110, 32,105, - 110, 99,108,117,100,101, 95,102,105,108,101, 95,104,111,111, - 107, 40,116, 44, 32,102,105,108,101,110, 97,109,101, 44, 32, - 46, 46, 46, 41, 10, 10,101,110,100, 10, 10, 45, 45, 32, 99, - 97,108,108,101,100, 32, 97,102,116,101,114, 32,112,114,111, - 99,101,115,115,105,110,103, 32, 97,110,121,116,104,105,110, - 103, 32,116,104, 97,116, 39,115, 32,110,111,116, 32, 99,111, - 100,101, 32, 40,108,105,107,101, 32, 39, 36,114,101,110, 97, - 109,105,110,103, 39, 44, 32, 99,111,109,109,101,110,116,115, - 44, 32,101,116, 99, 41, 10, 45, 45, 32, 97,110,100, 32,114, - 105,103,104,116, 32, 98,101,102,111,114,101, 32,112, 97,114, - 115,105,110,103, 32,116,104,101, 32, 97, 99,116,117, 97,108, - 32, 99,111,100,101, 46, 10, 45, 45, 32,116, 97,107,101,115, - 32,116,104,101, 32, 80, 97, 99,107, 97,103,101, 32,111, 98, - 106,101, 99,116, 32,119,105,116,104, 32, 97,108,108, 32,116, - 104,101, 32, 99,111,100,101, 32,111,110, 32,116,104,101, 32, - 39, 99,111,100,101, 39, 32,107,101,121, 46, 32,110,111, 32, - 114,101,116,117,114,110, 32,118, 97,108,117,101, 10,102,117, - 110, 99,116,105,111,110, 32,112,114,101,112, 97,114,115,101, - 95,104,111,111,107, 40,112, 97, 99,107, 97,103,101, 41, 10, - 10,101,110,100, 10, 10, 45, 45, 32, 99, 97,108,108,101,100, - 32, 98,101,102,111,114,101, 32,115,116, 97,114,116,105,110, - 103, 32,111,117,116,112,117,116, 10,102,117,110, 99,116,105, - 111,110, 32,112,114,101, 95,111,117,116,112,117,116, 95,104, - 111,111,107, 40,112, 97, 99,107, 97,103,101, 41, 10, 10,101, - 110,100, 10, 10, 45, 45, 32, 99, 97,108,108,101,100, 32, 97, - 102,116,101,114, 32,119,114,105,116,105,110,103, 32, 97,108, - 108, 32,116,104,101, 32,111,117,116,112,117,116, 46, 10, 45, - 45, 32,116, 97,107,101,115, 32,116,104,101, 32, 80, 97, 99, - 107, 97,103,101, 32,111, 98,106,101, 99,116, 10,102,117,110, - 99,116,105,111,110, 32,112,111,115,116, 95,111,117,116,112, - 117,116, 95,104,111,111,107, 40,112, 97, 99,107, 97,103,101, - 41, 10, 10,101,110,100, 10, 10, 10, 45, 45, 32, 99, 97,108, - 108,101,100, 32,102,114,111,109, 32, 39,103,101,116, 95,112, - 114,111,112,101,114,116,121, 95,109,101,116,104,111,100,115, - 39, 32,116,111, 32,103,101,116, 32,116,104,101, 32,109,101, - 116,104,111,100,115, 32,116,111, 32,114,101,116,114,105,101, - 118,101, 32, 97, 32,112,114,111,112,101,114,116,121, 10, 45, - 45, 32, 97, 99, 99,111,114,100,105,110,103, 32,116,111, 32, - 105,116,115, 32,116,121,112,101, 10,102,117,110, 99,116,105, - 111,110, 32,103,101,116, 95,112,114,111,112,101,114,116,121, - 95,109,101,116,104,111,100,115, 95,104,111,111,107, 40,112, - 114,111,112,101,114,116,121, 95,116,121,112,101, 44, 32,110, - 97,109,101, 41, 10, 10,101,110,100, 10, 10, 45, 45, 32, 99, - 97,108,108,101,100, 32,102,114,111,109, 32, 67,108, 97,115, - 115, 67,111,110,116, 97,105,110,101,114, 58,100,111,112, 97, - 114,115,101, 32,119,105,116,104, 32,116,104,101, 32,115,116, - 114,105,110,103, 32, 98,101,105,110,103, 32,112, 97,114,115, - 101,100, 10, 45, 45, 32,114,101,116,117,114,110, 32,110,105, - 108, 44, 32,111,114, 32, 97, 32,115,117, 98,115,116,114,105, - 110,103, 10,102,117,110, 99,116,105,111,110, 32,112, 97,114, - 115,101,114, 95,104,111,111,107, 40,115, 41, 10, 10, 9,114, - 101,116,117,114,110, 32,110,105,108, 10,101,110,100, 10, 10, - 45, 45, 32, 99, 97,108,108,101,100, 32,102,114,111,109, 32, - 99,108, 97,115,115, 70,117,110, 99,116,105,111,110, 58,115, - 117,112, 99,111,100,101, 44, 32, 98,101,102,111,114,101, 32, - 116,104,101, 32, 99, 97,108,108, 32,116,111, 32,116,104,101, - 32,102,117,110, 99,116,105,111,110, 32,105,115, 32,111,117, - 116,112,117,116, 10,102,117,110, 99,116,105,111,110, 32,112, - 114,101, 95, 99, 97,108,108, 95,104,111,111,107, 40,102, 41, - 10, 10,101,110,100, 10, 10, 45, 45, 32, 99, 97,108,108,101, - 100, 32,102,114,111,109, 32, 99,108, 97,115,115, 70,117,110, - 99,116,105,111,110, 58,115,117,112, 99,111,100,101, 44, 32, - 97,102,116,101,114, 32,116,104,101, 32, 99, 97,108,108, 32, - 116,111, 32,116,104,101, 32,102,117,110, 99,116,105,111,110, - 32,105,115, 32,111,117,116,112,117,116, 10,102,117,110, 99, - 116,105,111,110, 32,112,111,115,116, 95, 99, 97,108,108, 95, - 104,111,111,107, 40,102, 41, 10, 10,101,110,100, 10, 10, 45, - 45, 32, 99, 97,108,108,101,100, 32, 98,101,102,111,114,101, - 32,116,104,101, 32,114,101,103,105,115,116,101,114, 32, 99, - 111,100,101, 32,105,115, 32,111,117,116,112,117,116, 10,102, - 117,110, 99,116,105,111,110, 32,112,114,101, 95,114,101,103, - 105,115,116,101,114, 95,104,111,111,107, 40,112, 97, 99,107, - 97,103,101, 41, 10, 10,101,110,100, 10, 10, 45, 45, 32, 99, - 97,108,108,101,100, 32,116,111, 32,111,117,116,112,117,116, - 32, 97,110, 32,101,114,114,111,114, 32,109,101,115,115, 97, - 103,101, 10,102,117,110, 99,116,105,111,110, 32,111,117,116, - 112,117,116, 95,101,114,114,111,114, 95,104,111,111,107, 40, - 46, 46, 46, 41, 10, 9,114,101,116,117,114,110, 32,115,116, - 114,105,110,103, 46,102,111,114,109, 97,116, 40, 46, 46, 46, - 41, 10,101,110,100, 10, 10, 45, 45, 32, 99,117,115,116,111, - 109, 32,112,117,115,104,101,114,115, 10, 10, 95,112,117,115, - 104, 95,102,117,110, 99,116,105,111,110,115, 32, 61, 32,123, - 125, 10, 95,105,115, 95,102,117,110, 99,116,105,111,110,115, - 32, 61, 32,123,125, 10, 95,116,111, 95,102,117,110, 99,116, - 105,111,110,115, 32, 61, 32,123,125, 10, 10, 95, 98, 97,115, - 101, 95,112,117,115,104, 95,102,117,110, 99,116,105,111,110, - 115, 32, 61, 32,123,125, 10, 95, 98, 97,115,101, 95,105,115, - 95,102,117,110, 99,116,105,111,110,115, 32, 61, 32,123,125, - 10, 95, 98, 97,115,101, 95,116,111, 95,102,117,110, 99,116, - 105,111,110,115, 32, 61, 32,123,125, 10, 10,108,111, 99, 97, - 108, 32,102,117,110, 99,116,105,111,110, 32,115,101, 97,114, - 99,104, 95, 98, 97,115,101, 40,116, 44, 32,102,117,110, 99, - 115, 41, 10, 10, 9,108,111, 99, 97,108, 32, 99,108, 97,115, - 115, 32, 61, 32, 95,103,108,111, 98, 97,108, 95, 99,108, 97, - 115,115,101,115, 91,116, 93, 10, 10, 9,119,104,105,108,101, - 32, 99,108, 97,115,115, 32,100,111, 10, 9, 9,105,102, 32, - 102,117,110, 99,115, 91, 99,108, 97,115,115, 46,116,121,112, - 101, 93, 32,116,104,101,110, 10, 9, 9, 9,114,101,116,117, - 114,110, 32,102,117,110, 99,115, 91, 99,108, 97,115,115, 46, - 116,121,112,101, 93, 10, 9, 9,101,110,100, 10, 9, 9, 99, - 108, 97,115,115, 32, 61, 32, 95,103,108,111, 98, 97,108, 95, - 99,108, 97,115,115,101,115, 91, 99,108, 97,115,115, 46, 98, - 116,121,112,101, 93, 10, 9,101,110,100, 10, 9,114,101,116, - 117,114,110, 32,110,105,108, 10,101,110,100, 10, 10,102,117, - 110, 99,116,105,111,110, 32,103,101,116, 95,112,117,115,104, - 95,102,117,110, 99,116,105,111,110, 40,116, 41, 10, 9,114, - 101,116,117,114,110, 32, 95,112,117,115,104, 95,102,117,110, - 99,116,105,111,110,115, 91,116, 93, 32,111,114, 32,115,101, - 97,114, 99,104, 95, 98, 97,115,101, 40,116, 44, 32, 95, 98, - 97,115,101, 95,112,117,115,104, 95,102,117,110, 99,116,105, - 111,110,115, 41, 32,111,114, 32, 34,116,111,108,117, 97, 95, - 112,117,115,104,117,115,101,114,116,121,112,101, 34, 10,101, - 110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,103,101, - 116, 95,116,111, 95,102,117,110, 99,116,105,111,110, 40,116, - 41, 10, 9,114,101,116,117,114,110, 32, 95,116,111, 95,102, - 117,110, 99,116,105,111,110,115, 91,116, 93, 32,111,114, 32, - 115,101, 97,114, 99,104, 95, 98, 97,115,101, 40,116, 44, 32, - 95, 98, 97,115,101, 95,116,111, 95,102,117,110, 99,116,105, - 111,110,115, 41, 32,111,114, 32, 34,116,111,108,117, 97, 95, - 116,111,117,115,101,114,116,121,112,101, 34, 10,101,110,100, - 10, 10,102,117,110, 99,116,105,111,110, 32,103,101,116, 95, - 105,115, 95,102,117,110, 99,116,105,111,110, 40,116, 41, 10, - 9,114,101,116,117,114,110, 32, 95,105,115, 95,102,117,110, - 99,116,105,111,110,115, 91,116, 93, 32,111,114, 32,115,101, - 97,114, 99,104, 95, 98, 97,115,101, 40,116, 44, 32, 95, 98, - 97,115,101, 95,105,115, 95,102,117,110, 99,116,105,111,110, - 115, 41, 32,111,114, 32, 34,116,111,108,117, 97, 95,105,115, - 117,115,101,114,116,121,112,101, 34, 10,101,110,100,32 - }; - tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/basic.lua"); + #include "basic_lua.h" + tolua_dobuffer(tolua_S,(char*)lua_basic_lua,sizeof(lua_basic_lua),"tolua embedded: src/bin/lua/basic.lua"); lua_settop(tolua_S, top); } /* end of embedded lua code */ @@ -3788,180 +3193,11 @@ TOLUA_API int tolua_tolua_open (lua_State* tolua_S) } /* end of embedded lua code */ + { /* begin embedded lua code */ int top = lua_gettop(tolua_S); - static unsigned char B[] = { - 45, 45, 32,116,111,108,117, 97, 58, 32,101,110,117,109,101, - 114, 97,116,101, 32, 99,108, 97,115,115, 10, 45, 45, 32, 87, - 114,105,116,116,101,110, 32, 98,121, 32, 87, 97,108,100,101, - 109, 97,114, 32, 67,101,108,101,115, 10, 45, 45, 32, 84,101, - 67, 71,114, 97,102, 47, 80, 85, 67, 45, 82,105,111, 10, 45, - 45, 32, 74,117,108, 32, 49, 57, 57, 56, 10, 45, 45, 32, 36, - 73,100, 58, 32,101,110,117,109,101,114, 97,116,101, 46,108, - 117, 97, 44,118, 32, 49, 46, 51, 32, 50, 48, 48, 48, 47, 48, - 49, 47, 50, 52, 32, 50, 48, 58, 52, 49, 58, 49, 53, 32, 99, - 101,108,101,115, 32, 69,120,112, 32, 36, 10, 10, 45, 45, 32, - 84,104,105,115, 32, 99,111,100,101, 32,105,115, 32,102,114, - 101,101, 32,115,111,102,116,119, 97,114,101, 59, 32,121,111, - 117, 32, 99, 97,110, 32,114,101,100,105,115,116,114,105, 98, - 117,116,101, 32,105,116, 32, 97,110,100, 47,111,114, 32,109, - 111,100,105,102,121, 32,105,116, 46, 10, 45, 45, 32, 84,104, - 101, 32,115,111,102,116,119, 97,114,101, 32,112,114,111,118, - 105,100,101,100, 32,104,101,114,101,117,110,100,101,114, 32, - 105,115, 32,111,110, 32, 97,110, 32, 34, 97,115, 32,105,115, - 34, 32, 98, 97,115,105,115, 44, 32, 97,110,100, 10, 45, 45, - 32,116,104,101, 32, 97,117,116,104,111,114, 32,104, 97,115, - 32,110,111, 32,111, 98,108,105,103, 97,116,105,111,110, 32, - 116,111, 32,112,114,111,118,105,100,101, 32,109, 97,105,110, - 116,101,110, 97,110, 99,101, 44, 32,115,117,112,112,111,114, - 116, 44, 32,117,112,100, 97,116,101,115, 44, 10, 45, 45, 32, - 101,110,104, 97,110, 99,101,109,101,110,116,115, 44, 32,111, - 114, 32,109,111,100,105,102,105, 99, 97,116,105,111,110,115, - 46, 10, 10, 10, 45, 45, 32, 69,110,117,109,101,114, 97,116, - 101, 32, 99,108, 97,115,115, 10, 45, 45, 32, 82,101,112,114, - 101,115,101,110,116,115, 32,101,110,117,109,101,114, 97,116, - 105,111,110, 10, 45, 45, 32, 84,104,101, 32,102,111,108,108, - 111,119,105,110,103, 32,102,105,101,108,100,115, 32, 97,114, - 101, 32,115,116,111,114,101,100, 58, 10, 45, 45, 32, 32, 32, - 32,123,105,125, 32, 61, 32,108,105,115,116, 32,111,102, 32, - 99,111,110,115,116, 97,110,116, 32,110, 97,109,101,115, 10, - 99,108, 97,115,115, 69,110,117,109,101,114, 97,116,101, 32, - 61, 32,123, 10,125, 10, 99,108, 97,115,115, 69,110,117,109, - 101,114, 97,116,101, 46, 95, 95,105,110,100,101,120, 32, 61, - 32, 99,108, 97,115,115, 69,110,117,109,101,114, 97,116,101, - 10,115,101,116,109,101,116, 97,116, 97, 98,108,101, 40, 99, - 108, 97,115,115, 69,110,117,109,101,114, 97,116,101, 44, 99, - 108, 97,115,115, 70,101, 97,116,117,114,101, 41, 10, 10, 45, - 45, 32,114,101,103,105,115,116,101,114, 32,101,110,117,109, - 101,114, 97,116,105,111,110, 10,102,117,110, 99,116,105,111, - 110, 32, 99,108, 97,115,115, 69,110,117,109,101,114, 97,116, - 101, 58,114,101,103,105,115,116,101,114, 32, 40,112,114,101, - 41, 10, 9,105,102, 32,110,111,116, 32,115,101,108,102, 58, - 99,104,101, 99,107, 95,112,117, 98,108,105, 99, 95, 97, 99, - 99,101,115,115, 40, 41, 32,116,104,101,110, 10, 9, 9,114, - 101,116,117,114,110, 10, 9,101,110,100, 10, 32,112,114,101, - 32, 61, 32,112,114,101, 32,111,114, 32, 39, 39, 10, 32,108, - 111, 99, 97,108, 32,110,115,112, 97, 99,101, 32, 61, 32,103, - 101,116,110, 97,109,101,115,112, 97, 99,101, 40, 99,108, 97, - 115,115, 67,111,110,116, 97,105,110,101,114, 46, 99,117,114, - 114, 41, 10, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32, - 119,104,105,108,101, 32,115,101,108,102, 91,105, 93, 32,100, - 111, 10, 32, 9,105,102, 32,115,101,108,102, 46,108,110, 97, - 109,101,115, 91,105, 93, 32, 97,110,100, 32,115,101,108,102, - 46,108,110, 97,109,101,115, 91,105, 93, 32,126, 61, 32, 34, - 34, 32,116,104,101,110, 10, 9, 10, 9, 9,111,117,116,112, - 117,116, 40,112,114,101, 46, 46, 39,116,111,108,117, 97, 95, - 99,111,110,115,116, 97,110,116, 40,116,111,108,117, 97, 95, - 83, 44, 34, 39, 46, 46,115,101,108,102, 46,108,110, 97,109, - 101,115, 91,105, 93, 46, 46, 39, 34, 44, 39, 46, 46,110,115, - 112, 97, 99,101, 46, 46,115,101,108,102, 91,105, 93, 46, 46, - 39, 41, 59, 39, 41, 10, 9,101,110,100, 10, 32, 32,105, 32, - 61, 32,105, 43, 49, 10, 32,101,110,100, 10,101,110,100, 10, - 10, 45, 45, 32, 80,114,105,110,116, 32,109,101,116,104,111, - 100, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115, - 115, 69,110,117,109,101,114, 97,116,101, 58,112,114,105,110, - 116, 32, 40,105,100,101,110,116, 44, 99,108,111,115,101, 41, - 10, 32,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, - 34, 69,110,117,109,101,114, 97,116,101,123, 34, 41, 10, 32, - 112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32, - 110, 97,109,101, 32, 61, 32, 34, 46, 46,115,101,108,102, 46, - 110, 97,109,101, 41, 10, 32,108,111, 99, 97,108, 32,105, 61, - 49, 10, 32,119,104,105,108,101, 32,115,101,108,102, 91,105, - 93, 32,100,111, 10, 32, 32,112,114,105,110,116, 40,105,100, - 101,110,116, 46, 46, 34, 32, 39, 34, 46, 46,115,101,108,102, - 91,105, 93, 46, 46, 34, 39, 40, 34, 46, 46,115,101,108,102, - 46,108,110, 97,109,101,115, 91,105, 93, 46, 46, 34, 41, 44, - 34, 41, 10, 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32,101, - 110,100, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, - 46, 46, 34,125, 34, 46, 46, 99,108,111,115,101, 41, 10,101, - 110,100, 10, 10, 45, 45, 32, 73,110,116,101,114,110, 97,108, - 32, 99,111,110,115,116,114,117, 99,116,111,114, 10,102,117, - 110, 99,116,105,111,110, 32, 95, 69,110,117,109,101,114, 97, - 116,101, 32, 40,116, 44,118, 97,114,110, 97,109,101, 41, 10, - 32,115,101,116,109,101,116, 97,116, 97, 98,108,101, 40,116, - 44, 99,108, 97,115,115, 69,110,117,109,101,114, 97,116,101, - 41, 10, 32, 97,112,112,101,110,100, 40,116, 41, 10, 32, 97, - 112,112,101,110,100,101,110,117,109, 40,116, 41, 10, 9, 32, - 105,102, 32,118, 97,114,110, 97,109,101, 32, 97,110,100, 32, - 118, 97,114,110, 97,109,101, 32,126, 61, 32, 34, 34, 32,116, - 104,101,110, 10, 9, 9,105,102, 32,116, 46,110, 97,109,101, - 32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 9, 9, 9, - 86, 97,114,105, 97, 98,108,101, 40,116, 46,110, 97,109,101, - 46, 46, 34, 32, 34, 46, 46,118, 97,114,110, 97,109,101, 41, - 10, 9, 9,101,108,115,101, 10, 9, 9, 9,108,111, 99, 97, - 108, 32,110,115, 32, 61, 32,103,101,116, 99,117,114,114,110, - 97,109,101,115,112, 97, 99,101, 40, 41, 10, 9, 9, 9,119, - 97,114,110,105,110,103, 40, 34, 86, 97,114,105, 97, 98,108, - 101, 32, 34, 46, 46,110,115, 46, 46,118, 97,114,110, 97,109, - 101, 46, 46, 34, 32,111,102, 32,116,121,112,101, 32, 60, 97, - 110,111,110,121,109,111,117,115, 32,101,110,117,109, 62, 32, - 105,115, 32,100,101, 99,108, 97,114,101,100, 32, 97,115, 32, - 114,101, 97,100, 45,111,110,108,121, 34, 41, 10, 9, 9, 9, - 86, 97,114,105, 97, 98,108,101, 40, 34,116,111,108,117, 97, - 95,114,101, 97,100,111,110,108,121, 32,105,110,116, 32, 34, - 46, 46,118, 97,114,110, 97,109,101, 41, 10, 9, 9,101,110, - 100, 10, 9,101,110,100, 10, 9, 32,108,111, 99, 97,108, 32, - 112, 97,114,101,110,116, 32, 61, 32, 99,108, 97,115,115, 67, - 111,110,116, 97,105,110,101,114, 46, 99,117,114,114, 10, 9, - 32,105,102, 32,112, 97,114,101,110,116, 32,116,104,101,110, - 10, 9, 9,116, 46, 97, 99, 99,101,115,115, 32, 61, 32,112, - 97,114,101,110,116, 46, 99,117,114,114, 95,109,101,109, 98, - 101,114, 95, 97, 99, 99,101,115,115, 10, 9, 9,116, 46,103, - 108,111, 98, 97,108, 95, 97, 99, 99,101,115,115, 32, 61, 32, - 116, 58, 99,104,101, 99,107, 95,112,117, 98,108,105, 99, 95, - 97, 99, 99,101,115,115, 40, 41, 10, 9, 32,101,110,100, 10, - 114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10, 45, - 45, 32, 67,111,110,115,116,114,117, 99,116,111,114, 10, 45, - 45, 32, 69,120,112,101, 99,116,115, 32, 97, 32,115,116,114, - 105,110,103, 32,114,101,112,114,101,115,101,110,116,105,110, - 103, 32,116,104,101, 32,101,110,117,109,101,114, 97,116,101, - 32, 98,111,100,121, 10,102,117,110, 99,116,105,111,110, 32, - 69,110,117,109,101,114, 97,116,101, 32, 40,110, 44, 98, 44, - 118, 97,114,110, 97,109,101, 41, 10, 9, 98, 32, 61, 32,115, - 116,114,105,110,103, 46,103,115,117, 98, 40, 98, 44, 32, 34, - 44, 91, 37,115, 92,110, 93, 42,125, 34, 44, 32, 34, 92,110, - 125, 34, 41, 32, 45, 45, 32,101,108,105,109,105,110, 97,116, - 101, 32,108, 97,115,116, 32, 39, 44, 39, 10, 32,108,111, 99, - 97,108, 32,116, 32, 61, 32,115,112,108,105,116, 40,115,116, - 114,115,117, 98, 40, 98, 44, 50, 44, 45, 50, 41, 44, 39, 44, - 39, 41, 32, 45, 45, 32,101,108,105,109,105,110, 97,116,101, - 32, 98,114, 97, 99,101,115, 10, 32,108,111, 99, 97,108, 32, - 105, 32, 61, 32, 49, 10, 32,108,111, 99, 97,108, 32,101, 32, - 61, 32,123,110, 61, 48,125, 10, 32,119,104,105,108,101, 32, - 116, 91,105, 93, 32,100,111, 10, 32, 32,108,111, 99, 97,108, - 32,116,116, 32, 61, 32,115,112,108,105,116, 40,116, 91,105, - 93, 44, 39, 61, 39, 41, 32, 32, 45, 45, 32,100,105,115, 99, - 97,114,100, 32,105,110,105,116,105, 97,108, 32,118, 97,108, - 117,101, 10, 32, 32,101, 46,110, 32, 61, 32,101, 46,110, 32, - 43, 32, 49, 10, 32, 32,101, 91,101, 46,110, 93, 32, 61, 32, - 116,116, 91, 49, 93, 10, 32, 32,105, 32, 61, 32,105, 43, 49, - 10, 32,101,110,100, 10, 32, 45, 45, 32,115,101,116, 32,108, - 117, 97, 32,110, 97,109,101,115, 10, 32,105, 32, 32, 61, 32, - 49, 10, 32,101, 46,108,110, 97,109,101,115, 32, 61, 32,123, - 125, 10, 32,108,111, 99, 97,108, 32,110,115, 32, 61, 32,103, - 101,116, 99,117,114,114,110, 97,109,101,115,112, 97, 99,101, - 40, 41, 10, 32,119,104,105,108,101, 32,101, 91,105, 93, 32, - 100,111, 10, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32, - 115,112,108,105,116, 40,101, 91,105, 93, 44, 39, 64, 39, 41, - 10, 32, 32,101, 91,105, 93, 32, 61, 32,116, 91, 49, 93, 10, - 9, 9,105,102, 32,110,111,116, 32,116, 91, 50, 93, 32,116, - 104,101,110, 10, 9, 9, 32,116, 91, 50, 93, 32, 61, 32, 97, - 112,112,108,121,114,101,110, 97,109,105,110,103, 40,116, 91, - 49, 93, 41, 10, 9, 9,101,110,100, 10, 32, 32,101, 46,108, - 110, 97,109,101,115, 91,105, 93, 32, 61, 32,116, 91, 50, 93, - 32,111,114, 32,116, 91, 49, 93, 10, 32, 32, 95,103,108,111, - 98, 97,108, 95,101,110,117,109,115, 91, 32,110,115, 46, 46, - 101, 91,105, 93, 32, 93, 32, 61, 32, 40,110,115, 46, 46,101, - 91,105, 93, 41, 10, 32, 32,105, 32, 61, 32,105, 43, 49, 10, - 32,101,110,100, 10, 9,101, 46,110, 97,109,101, 32, 61, 32, - 110, 10, 9,105,102, 32,110, 32,126, 61, 32, 34, 34, 32,116, - 104,101,110, 10, 9, 9, 84,121,112,101,100,101,102, 40, 34, - 105,110,116, 32, 34, 46, 46,110, 41, 10, 9,101,110,100, 10, - 32,114,101,116,117,114,110, 32, 95, 69,110,117,109,101,114, - 97,116,101, 40,101, 44, 32,118, 97,114,110, 97,109,101, 41, - 10,101,110,100,32 - }; - tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/enumerate.lua"); + #include "enumerate_lua.h" + tolua_dobuffer(tolua_S,(char*)lua_enumerate_lua,sizeof(lua_enumerate_lua),"tolua embedded: src/bin/lua/enumerate.lua"); lua_settop(tolua_S, top); } /* end of embedded lua code */ @@ -5972,960 +5208,8 @@ TOLUA_API int tolua_tolua_open (lua_State* tolua_S) { /* begin embedded lua code */ int top = lua_gettop(tolua_S); - static unsigned char B[] = { - 45, 45, 32,116,111,108,117, 97, 58, 32,102,117,110, 99,116, - 105,111,110, 32, 99,108, 97,115,115, 10, 45, 45, 32, 87,114, - 105,116,116,101,110, 32, 98,121, 32, 87, 97,108,100,101,109, - 97,114, 32, 67,101,108,101,115, 10, 45, 45, 32, 84,101, 67, - 71,114, 97,102, 47, 80, 85, 67, 45, 82,105,111, 10, 45, 45, - 32, 74,117,108, 32, 49, 57, 57, 56, 10, 45, 45, 32, 36, 73, - 100, 58, 32, 36, 10, 10, 45, 45, 32, 84,104,105,115, 32, 99, - 111,100,101, 32,105,115, 32,102,114,101,101, 32,115,111,102, - 116,119, 97,114,101, 59, 32,121,111,117, 32, 99, 97,110, 32, - 114,101,100,105,115,116,114,105, 98,117,116,101, 32,105,116, - 32, 97,110,100, 47,111,114, 32,109,111,100,105,102,121, 32, - 105,116, 46, 10, 45, 45, 32, 84,104,101, 32,115,111,102,116, - 119, 97,114,101, 32,112,114,111,118,105,100,101,100, 32,104, - 101,114,101,117,110,100,101,114, 32,105,115, 32,111,110, 32, - 97,110, 32, 34, 97,115, 32,105,115, 34, 32, 98, 97,115,105, - 115, 44, 32, 97,110,100, 10, 45, 45, 32,116,104,101, 32, 97, - 117,116,104,111,114, 32,104, 97,115, 32,110,111, 32,111, 98, - 108,105,103, 97,116,105,111,110, 32,116,111, 32,112,114,111, - 118,105,100,101, 32,109, 97,105,110,116,101,110, 97,110, 99, - 101, 44, 32,115,117,112,112,111,114,116, 44, 32,117,112,100, - 97,116,101,115, 44, 10, 45, 45, 32,101,110,104, 97,110, 99, - 101,109,101,110,116,115, 44, 32,111,114, 32,109,111,100,105, - 102,105, 99, 97,116,105,111,110,115, 46, 10, 10, 10, 10, 45, - 45, 32, 70,117,110, 99,116,105,111,110, 32, 99,108, 97,115, - 115, 10, 45, 45, 32, 82,101,112,114,101,115,101,110,116,115, - 32, 97, 32,102,117,110, 99,116,105,111,110, 32,111,114, 32, - 97, 32, 99,108, 97,115,115, 32,109,101,116,104,111,100, 46, - 10, 45, 45, 32, 84,104,101, 32,102,111,108,108,111,119,105, - 110,103, 32,102,105,101,108,100,115, 32, 97,114,101, 32,115, - 116,111,114,101,100, 58, 10, 45, 45, 32, 32,109,111,100, 32, - 32, 61, 32,116,121,112,101, 32,109,111,100,105,102,105,101, - 114,115, 10, 45, 45, 32, 32,116,121,112,101, 32, 61, 32,116, - 121,112,101, 10, 45, 45, 32, 32,112,116,114, 32, 32, 61, 32, - 34, 42, 34, 32,111,114, 32, 34, 38, 34, 44, 32,105,102, 32, - 114,101,112,114,101,115,101,110,116,105,110,103, 32, 97, 32, - 112,111,105,110,116,101,114, 32,111,114, 32, 97, 32,114,101, - 102,101,114,101,110, 99,101, 10, 45, 45, 32, 32,110, 97,109, - 101, 32, 61, 32,110, 97,109,101, 10, 45, 45, 32, 32,108,110, - 97,109,101, 32, 61, 32,108,117, 97, 32,110, 97,109,101, 10, - 45, 45, 32, 32, 97,114,103,115, 32, 32, 61, 32,108,105,115, - 116, 32,111,102, 32, 97,114,103,117,109,101,110,116, 32,100, - 101, 99,108, 97,114, 97,116,105,111,110,115, 10, 45, 45, 32, - 32, 99,111,110,115,116, 32, 61, 32,105,102, 32,105,116, 32, - 105,115, 32, 97, 32,109,101,116,104,111,100, 32,114,101, 99, - 101,105,118,105,110,103, 32, 97, 32, 99,111,110,115,116, 32, - 34,116,104,105,115, 34, 46, 10, 99,108, 97,115,115, 70,117, - 110, 99,116,105,111,110, 32, 61, 32,123, 10, 32,109,111,100, - 32, 61, 32, 39, 39, 44, 10, 32,116,121,112,101, 32, 61, 32, - 39, 39, 44, 10, 32,112,116,114, 32, 61, 32, 39, 39, 44, 10, - 32,110, 97,109,101, 32, 61, 32, 39, 39, 44, 10, 32, 97,114, - 103,115, 32, 61, 32,123,110, 61, 48,125, 44, 10, 32, 99,111, - 110,115,116, 32, 61, 32, 39, 39, 44, 10,125, 10, 99,108, 97, - 115,115, 70,117,110, 99,116,105,111,110, 46, 95, 95,105,110, - 100,101,120, 32, 61, 32, 99,108, 97,115,115, 70,117,110, 99, - 116,105,111,110, 10,115,101,116,109,101,116, 97,116, 97, 98, - 108,101, 40, 99,108, 97,115,115, 70,117,110, 99,116,105,111, - 110, 44, 99,108, 97,115,115, 70,101, 97,116,117,114,101, 41, - 10, 10, 45, 45, 32,100,101, 99,108, 97,114,101, 32,116, 97, - 103,115, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97, - 115,115, 70,117,110, 99,116,105,111,110, 58,100,101, 99,108, - 116,121,112,101, 32, 40, 41, 10, 32,115,101,108,102, 46,116, - 121,112,101, 32, 61, 32,116,121,112,101,118, 97,114, 40,115, - 101,108,102, 46,116,121,112,101, 41, 10, 32,105,102, 32,115, - 116,114,102,105,110,100, 40,115,101,108,102, 46,109,111,100, - 44, 39, 99,111,110,115,116, 39, 41, 32,116,104,101,110, 10, - 9, 32,115,101,108,102, 46,116,121,112,101, 32, 61, 32, 39, - 99,111,110,115,116, 32, 39, 46, 46,115,101,108,102, 46,116, - 121,112,101, 10, 9, 9,115,101,108,102, 46,109,111,100, 32, - 61, 32,103,115,117, 98, 40,115,101,108,102, 46,109,111,100, - 44, 39, 99,111,110,115,116, 39, 44, 39, 39, 41, 10, 9,101, - 110,100, 10, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32, - 119,104,105,108,101, 32,115,101,108,102, 46, 97,114,103,115, - 91,105, 93, 32,100,111, 10, 32, 32,115,101,108,102, 46, 97, - 114,103,115, 91,105, 93, 58,100,101, 99,108,116,121,112,101, - 40, 41, 10, 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32,101, - 110,100, 10,101,110,100, 10, 10, 10, 45, 45, 32, 87,114,105, - 116,101, 32, 98,105,110,100,105,110,103, 32,102,117,110, 99, - 116,105,111,110, 10, 45, 45, 32, 79,117,116,112,117,116,115, - 32, 67, 47, 67, 43, 43, 32, 98,105,110,100,105,110,103, 32, - 102,117,110, 99,116,105,111,110, 46, 10,102,117,110, 99,116, - 105,111,110, 32, 99,108, 97,115,115, 70,117,110, 99,116,105, - 111,110, 58,115,117,112, 99,111,100,101, 32, 40,108,111, 99, - 97,108, 95, 99,111,110,115,116,114,117, 99,116,111,114, 41, - 10, 10, 32,108,111, 99, 97,108, 32,111,118,101,114,108,111, - 97,100, 32, 61, 32,115,116,114,115,117, 98, 40,115,101,108, - 102, 46, 99,110, 97,109,101, 44, 45, 50, 44, 45, 49, 41, 32, - 45, 32, 49, 32, 32, 45, 45, 32,105,110,100,105, 99, 97,116, - 101, 32,111,118,101,114,108,111, 97,100,101,100, 32,102,117, - 110, 99, 10, 32,108,111, 99, 97,108, 32,110,114,101,116, 32, - 61, 32, 48, 32, 32, 32, 32, 32, 32, 45, 45, 32,110,117,109, - 98,101,114, 32,111,102, 32,114,101,116,117,114,110,101,100, - 32,118, 97,108,117,101,115, 10, 32,108,111, 99, 97,108, 32, - 99,108, 97,115,115, 32, 61, 32,115,101,108,102, 58,105,110, - 99,108, 97,115,115, 40, 41, 10, 32,108,111, 99, 97,108, 32, - 95, 44, 95, 44,115,116, 97,116,105, 99, 32, 61, 32,115,116, - 114,102,105,110,100, 40,115,101,108,102, 46,109,111,100, 44, - 39, 94, 37,115, 42, 40,115,116, 97,116,105, 99, 41, 39, 41, - 10, 32,105,102, 32, 99,108, 97,115,115, 32,116,104,101,110, - 10, 10, 32, 9,105,102, 32,115,101,108,102, 46,110, 97,109, - 101, 32, 61, 61, 32, 39,110,101,119, 39, 32, 97,110,100, 32, - 115,101,108,102, 46,112, 97,114,101,110,116, 46,102,108, 97, - 103,115, 46,112,117,114,101, 95,118,105,114,116,117, 97,108, - 32,116,104,101,110, 10, 32, 9, 9, 45, 45, 32,110,111, 32, - 99,111,110,115,116,114,117, 99,116,111,114, 32,102,111,114, - 32, 99,108, 97,115,115,101,115, 32,119,105,116,104, 32,112, - 117,114,101, 32,118,105,114,116,117, 97,108, 32,109,101,116, - 104,111,100,115, 10, 32, 9, 9,114,101,116,117,114,110, 10, - 32, 9,101,110,100, 10, 10, 32, 9,105,102, 32,108,111, 99, - 97,108, 95, 99,111,110,115,116,114,117, 99,116,111,114, 32, - 116,104,101,110, 10, 9, 9,111,117,116,112,117,116, 40, 34, - 47, 42, 32,109,101,116,104,111,100, 58, 32,110,101,119, 95, - 108,111, 99, 97,108, 32,111,102, 32, 99,108, 97,115,115, 32, - 34, 44, 99,108, 97,115,115, 44, 34, 32, 42, 47, 34, 41, 10, - 9,101,108,115,101, 10, 9, 9,111,117,116,112,117,116, 40, - 34, 47, 42, 32,109,101,116,104,111,100, 58, 34, 44,115,101, - 108,102, 46,110, 97,109,101, 44, 34, 32,111,102, 32, 99,108, - 97,115,115, 32, 34, 44, 99,108, 97,115,115, 44, 34, 32, 42, - 47, 34, 41, 10, 9,101,110,100, 10, 32,101,108,115,101, 10, - 32, 32,111,117,116,112,117,116, 40, 34, 47, 42, 32,102,117, - 110, 99,116,105,111,110, 58, 34, 44,115,101,108,102, 46,110, - 97,109,101, 44, 34, 32, 42, 47, 34, 41, 10, 32,101,110,100, - 10, 10, 32,105,102, 32,108,111, 99, 97,108, 95, 99,111,110, - 115,116,114,117, 99,116,111,114, 32,116,104,101,110, 10, 32, - 32,111,117,116,112,117,116, 40, 34, 35,105,102,110,100,101, - 102, 32, 84, 79, 76, 85, 65, 95, 68, 73, 83, 65, 66, 76, 69, - 95, 34, 46, 46,115,101,108,102, 46, 99,110, 97,109,101, 46, - 46, 34, 95,108,111, 99, 97,108, 34, 41, 10, 32, 32,111,117, - 116,112,117,116, 40, 34, 92,110,115,116, 97,116,105, 99, 32, - 105,110,116, 34, 44,115,101,108,102, 46, 99,110, 97,109,101, - 46, 46, 34, 95,108,111, 99, 97,108, 34, 44, 34, 40,108,117, - 97, 95, 83,116, 97,116,101, 42, 32,116,111,108,117, 97, 95, - 83, 41, 34, 41, 10, 32,101,108,115,101, 10, 32, 32,111,117, - 116,112,117,116, 40, 34, 35,105,102,110,100,101,102, 32, 84, - 79, 76, 85, 65, 95, 68, 73, 83, 65, 66, 76, 69, 95, 34, 46, - 46,115,101,108,102, 46, 99,110, 97,109,101, 41, 10, 32, 32, - 111,117,116,112,117,116, 40, 34, 92,110,115,116, 97,116,105, - 99, 32,105,110,116, 34, 44,115,101,108,102, 46, 99,110, 97, - 109,101, 44, 34, 40,108,117, 97, 95, 83,116, 97,116,101, 42, - 32,116,111,108,117, 97, 95, 83, 41, 34, 41, 10, 32,101,110, - 100, 10, 32,111,117,116,112,117,116, 40, 34,123, 34, 41, 10, - 10, 32, 45, 45, 32, 99,104,101, 99,107, 32,116,121,112,101, - 115, 10, 9,105,102, 32,111,118,101,114,108,111, 97,100, 32, - 60, 32, 48, 32,116,104,101,110, 10, 9, 32,111,117,116,112, - 117,116, 40, 39, 35,105,102,110,100,101,102, 32, 84, 79, 76, - 85, 65, 95, 82, 69, 76, 69, 65, 83, 69, 92,110, 39, 41, 10, - 9,101,110,100, 10, 9,111,117,116,112,117,116, 40, 39, 32, - 116,111,108,117, 97, 95, 69,114,114,111,114, 32,116,111,108, - 117, 97, 95,101,114,114, 59, 39, 41, 10, 32,111,117,116,112, - 117,116, 40, 39, 32,105,102, 32, 40, 92,110, 39, 41, 10, 32, - 45, 45, 32, 99,104,101, 99,107, 32,115,101,108,102, 10, 32, - 108,111, 99, 97,108, 32,110, 97,114,103, 10, 32,105,102, 32, - 99,108, 97,115,115, 32,116,104,101,110, 32,110, 97,114,103, - 61, 50, 32,101,108,115,101, 32,110, 97,114,103, 61, 49, 32, - 101,110,100, 10, 32,105,102, 32, 99,108, 97,115,115, 32,116, - 104,101,110, 10, 9, 9,108,111, 99, 97,108, 32,102,117,110, - 99, 32, 61, 32,103,101,116, 95,105,115, 95,102,117,110, 99, - 116,105,111,110, 40,115,101,108,102, 46,112, 97,114,101,110, - 116, 46,116,121,112,101, 41, 10, 9, 9,108,111, 99, 97,108, - 32,116,121,112,101, 32, 61, 32,115,101,108,102, 46,112, 97, - 114,101,110,116, 46,116,121,112,101, 10, 9, 9,105,102, 32, - 115,101,108,102, 46,110, 97,109,101, 61, 61, 39,110,101,119, - 39, 32,111,114, 32,115,116, 97,116,105, 99,126, 61,110,105, - 108, 32,116,104,101,110, 10, 9, 9, 9,102,117,110, 99, 32, - 61, 32, 39,116,111,108,117, 97, 95,105,115,117,115,101,114, - 116, 97, 98,108,101, 39, 10, 9, 9, 9,116,121,112,101, 32, - 61, 32,115,101,108,102, 46,112, 97,114,101,110,116, 46,116, - 121,112,101, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32, - 115,101,108,102, 46, 99,111,110,115,116, 32,126, 61, 32, 39, - 39, 32,116,104,101,110, 10, 9, 9, 9,116,121,112,101, 32, - 61, 32, 34, 99,111,110,115,116, 32, 34, 46, 46,116,121,112, - 101, 10, 9, 9,101,110,100, 10, 9, 9,111,117,116,112,117, - 116, 40, 39, 32, 32, 32, 32, 32, 33, 39, 46, 46,102,117,110, - 99, 46, 46, 39, 40,116,111,108,117, 97, 95, 83, 44, 49, 44, - 34, 39, 46, 46,116,121,112,101, 46, 46, 39, 34, 44, 48, 44, - 38,116,111,108,117, 97, 95,101,114,114, 41, 32,124,124, 92, - 110, 39, 41, 10, 32,101,110,100, 10, 32, 45, 45, 32, 99,104, - 101, 99,107, 32, 97,114,103,115, 10, 32,105,102, 32,115,101, - 108,102, 46, 97,114,103,115, 91, 49, 93, 46,116,121,112,101, - 32,126, 61, 32, 39,118,111,105,100, 39, 32,116,104,101,110, - 10, 32, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32, 32, - 119,104,105,108,101, 32,115,101,108,102, 46, 97,114,103,115, - 91,105, 93, 32,100,111, 10, 32, 32, 32,108,111, 99, 97,108, - 32, 98,116,121,112,101, 32, 61, 32,105,115, 98, 97,115,105, - 99, 40,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 46, - 116,121,112,101, 41, 10, 32, 32, 32,105,102, 32, 98,116,121, - 112,101, 32,126, 61, 32, 39,118, 97,108,117,101, 39, 32, 97, - 110,100, 32, 98,116,121,112,101, 32,126, 61, 32, 39,115,116, - 97,116,101, 39, 32,116,104,101,110, 10, 32, 32, 32, 32,111, - 117,116,112,117,116, 40, 39, 32, 32, 32, 32, 32, 39, 46, 46, - 115,101,108,102, 46, 97,114,103,115, 91,105, 93, 58,111,117, - 116, 99,104,101, 99,107,116,121,112,101, 40,110, 97,114,103, - 41, 46, 46, 39, 32,124,124, 92,110, 39, 41, 10, 32, 32, 32, - 101,110,100, 10, 32, 32, 32,105,102, 32, 98,116,121,112,101, - 32,126, 61, 32, 39,115,116, 97,116,101, 39, 32,116,104,101, - 110, 10, 9, 32, 32, 32,110, 97,114,103, 32, 61, 32,110, 97, - 114,103, 43, 49, 10, 32, 32, 32,101,110,100, 10, 32, 32, 32, - 105, 32, 61, 32,105, 43, 49, 10, 32, 32,101,110,100, 10, 32, - 101,110,100, 10, 32, 45, 45, 32, 99,104,101, 99,107, 32,101, - 110,100, 32,111,102, 32,108,105,115,116, 10, 32,111,117,116, - 112,117,116, 40, 39, 32, 32, 32, 32, 32, 33,116,111,108,117, - 97, 95,105,115,110,111,111, 98,106, 40,116,111,108,117, 97, - 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, 46, 39, 44, 38, - 116,111,108,117, 97, 95,101,114,114, 41, 92,110, 32, 41, 39, - 41, 10, 9,111,117,116,112,117,116, 40, 39, 32, 32,103,111, - 116,111, 32,116,111,108,117, 97, 95,108,101,114,114,111,114, - 59, 39, 41, 10, 10, 32,111,117,116,112,117,116, 40, 39, 32, - 101,108,115,101, 92,110, 39, 41, 10, 9,105,102, 32,111,118, - 101,114,108,111, 97,100, 32, 60, 32, 48, 32,116,104,101,110, - 10, 9, 32,111,117,116,112,117,116, 40, 39, 35,101,110,100, - 105,102, 92,110, 39, 41, 10, 9,101,110,100, 10, 9,111,117, - 116,112,117,116, 40, 39, 32,123, 39, 41, 10, 10, 32, 45, 45, - 32,100,101, 99,108, 97,114,101, 32,115,101,108,102, 44, 32, - 105,102, 32,116,104,101, 32, 99, 97,115,101, 10, 32,108,111, - 99, 97,108, 32,110, 97,114,103, 10, 32,105,102, 32, 99,108, - 97,115,115, 32,116,104,101,110, 32,110, 97,114,103, 61, 50, - 32,101,108,115,101, 32,110, 97,114,103, 61, 49, 32,101,110, - 100, 10, 32,105,102, 32, 99,108, 97,115,115, 32, 97,110,100, - 32,115,101,108,102, 46,110, 97,109,101,126, 61, 39,110,101, - 119, 39, 32, 97,110,100, 32,115,116, 97,116,105, 99, 61, 61, - 110,105,108, 32,116,104,101,110, 10, 32, 32,111,117,116,112, - 117,116, 40, 39, 32, 39, 44,115,101,108,102, 46, 99,111,110, - 115,116, 44,115,101,108,102, 46,112, 97,114,101,110,116, 46, - 116,121,112,101, 44, 39, 42, 39, 44, 39,115,101,108,102, 32, - 61, 32, 39, 41, 10, 32, 32,111,117,116,112,117,116, 40, 39, - 40, 39, 44,115,101,108,102, 46, 99,111,110,115,116, 44,115, - 101,108,102, 46,112, 97,114,101,110,116, 46,116,121,112,101, - 44, 39, 42, 41, 32, 39, 41, 10, 32, 32,108,111, 99, 97,108, - 32,116,111, 95,102,117,110, 99, 32, 61, 32,103,101,116, 95, - 116,111, 95,102,117,110, 99,116,105,111,110, 40,115,101,108, - 102, 46,112, 97,114,101,110,116, 46,116,121,112,101, 41, 10, - 32, 32,111,117,116,112,117,116, 40,116,111, 95,102,117,110, - 99, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 49, 44, 48, - 41, 59, 39, 41, 10, 32,101,108,115,101,105,102, 32,115,116, - 97,116,105, 99, 32,116,104,101,110, 10, 32, 32, 95, 44, 95, - 44,115,101,108,102, 46,109,111,100, 32, 61, 32,115,116,114, - 102,105,110,100, 40,115,101,108,102, 46,109,111,100, 44, 39, - 94, 37,115, 42,115,116, 97,116,105, 99, 37,115, 37,115, 42, - 40, 46, 42, 41, 39, 41, 10, 32,101,110,100, 10, 32, 45, 45, - 32,100,101, 99,108, 97,114,101, 32,112, 97,114, 97,109,101, - 116,101,114,115, 10, 32,105,102, 32,115,101,108,102, 46, 97, - 114,103,115, 91, 49, 93, 46,116,121,112,101, 32,126, 61, 32, - 39,118,111,105,100, 39, 32,116,104,101,110, 10, 32, 32,108, - 111, 99, 97,108, 32,105, 61, 49, 10, 32, 32,119,104,105,108, - 101, 32,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 32, - 100,111, 10, 32, 32, 32,115,101,108,102, 46, 97,114,103,115, - 91,105, 93, 58,100,101, 99,108, 97,114,101, 40,110, 97,114, - 103, 41, 10, 32, 32, 32,105,102, 32,105,115, 98, 97,115,105, - 99, 40,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 46, - 116,121,112,101, 41, 32,126, 61, 32, 34,115,116, 97,116,101, - 34, 32,116,104,101,110, 10, 9, 32, 32, 32,110, 97,114,103, - 32, 61, 32,110, 97,114,103, 43, 49, 10, 32, 32, 32,101,110, - 100, 10, 32, 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32, 32, - 101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32, 99, - 104,101, 99,107, 32,115,101,108,102, 10, 32,105,102, 32, 99, - 108, 97,115,115, 32, 97,110,100, 32,115,101,108,102, 46,110, - 97,109,101,126, 61, 39,110,101,119, 39, 32, 97,110,100, 32, - 115,116, 97,116,105, 99, 61, 61,110,105,108, 32,116,104,101, - 110, 10, 9, 32,111,117,116,112,117,116, 40, 39, 35,105,102, - 110,100,101,102, 32, 84, 79, 76, 85, 65, 95, 82, 69, 76, 69, - 65, 83, 69, 92,110, 39, 41, 10, 9, 32,111,117,116,112,117, - 116, 40, 39, 32, 32,105,102, 32, 40, 33,115,101,108,102, 41, - 32,116,111,108,117, 97, 95,101,114,114,111,114, 40,116,111, - 108,117, 97, 95, 83, 44, 34, 39, 46, 46,111,117,116,112,117, - 116, 95,101,114,114,111,114, 95,104,111,111,107, 40, 34,105, - 110,118, 97,108,105,100, 32, 92, 39,115,101,108,102, 92, 39, - 32,105,110, 32,102,117,110, 99,116,105,111,110, 32, 92, 39, - 37,115, 92, 39, 34, 44, 32,115,101,108,102, 46,110, 97,109, - 101, 41, 46, 46, 39, 34, 44, 32, 78, 85, 76, 76, 41, 59, 39, - 41, 59, 10, 9, 32,111,117,116,112,117,116, 40, 39, 35,101, - 110,100,105,102, 92,110, 39, 41, 10, 32,101,110,100, 10, 10, - 32, 45, 45, 32,103,101,116, 32, 97,114,114, 97,121, 32,101, - 108,101,109,101,110,116, 32,118, 97,108,117,101,115, 10, 32, - 105,102, 32, 99,108, 97,115,115, 32,116,104,101,110, 32,110, - 97,114,103, 61, 50, 32,101,108,115,101, 32,110, 97,114,103, - 61, 49, 32,101,110,100, 10, 32,105,102, 32,115,101,108,102, - 46, 97,114,103,115, 91, 49, 93, 46,116,121,112,101, 32,126, - 61, 32, 39,118,111,105,100, 39, 32,116,104,101,110, 10, 32, - 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32, 32,119,104, - 105,108,101, 32,115,101,108,102, 46, 97,114,103,115, 91,105, - 93, 32,100,111, 10, 32, 32, 32,115,101,108,102, 46, 97,114, - 103,115, 91,105, 93, 58,103,101,116, 97,114,114, 97,121, 40, - 110, 97,114,103, 41, 10, 32, 32, 32,110, 97,114,103, 32, 61, - 32,110, 97,114,103, 43, 49, 10, 32, 32, 32,105, 32, 61, 32, - 105, 43, 49, 10, 32, 32,101,110,100, 10, 32,101,110,100, 10, - 10, 32,112,114,101, 95, 99, 97,108,108, 95,104,111,111,107, - 40,115,101,108,102, 41, 10, 10, 32,108,111, 99, 97,108, 32, - 111,117,116, 32, 61, 32,115,116,114,105,110,103, 46,102,105, - 110,100, 40,115,101,108,102, 46,109,111,100, 44, 32, 34,116, - 111,108,117, 97, 95,111,117,116,115,105,100,101, 34, 41, 10, - 32, 45, 45, 32, 99, 97,108,108, 32,102,117,110, 99,116,105, - 111,110, 10, 32,105,102, 32, 99,108, 97,115,115, 32, 97,110, - 100, 32,115,101,108,102, 46,110, 97,109,101, 61, 61, 39,100, - 101,108,101,116,101, 39, 32,116,104,101,110, 10, 32, 32,111, - 117,116,112,117,116, 40, 39, 32, 32, 77,116,111,108,117, 97, - 95,100,101,108,101,116,101, 40,115,101,108,102, 41, 59, 39, - 41, 10, 32,101,108,115,101,105,102, 32, 99,108, 97,115,115, - 32, 97,110,100, 32,115,101,108,102, 46,110, 97,109,101, 32, - 61, 61, 32, 39,111,112,101,114, 97,116,111,114, 38, 91, 93, - 39, 32,116,104,101,110, 10, 32, 32,105,102, 32,102,108, 97, - 103,115, 91, 39, 49, 39, 93, 32,116,104,101,110, 32, 45, 45, - 32,102,111,114, 32, 99,111,109,112, 97,116,105, 98,105,108, - 105,116,121, 32,119,105,116,104, 32,116,111,108,117, 97, 53, - 32, 63, 10, 9,111,117,116,112,117,116, 40, 39, 32, 32,115, - 101,108,102, 45, 62,111,112,101,114, 97,116,111,114, 91, 93, - 40, 39, 44,115,101,108,102, 46, 97,114,103,115, 91, 49, 93, - 46,110, 97,109,101, 44, 39, 45, 49, 41, 32, 61, 32, 39, 44, - 115,101,108,102, 46, 97,114,103,115, 91, 50, 93, 46,110, 97, - 109,101, 44, 39, 59, 39, 41, 10, 32, 32,101,108,115,101, 10, - 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32,115, - 101,108,102, 45, 62,111,112,101,114, 97,116,111,114, 91, 93, - 40, 39, 44,115,101,108,102, 46, 97,114,103,115, 91, 49, 93, - 46,110, 97,109,101, 44, 39, 41, 32, 61, 32, 39, 44,115,101, - 108,102, 46, 97,114,103,115, 91, 50, 93, 46,110, 97,109,101, - 44, 39, 59, 39, 41, 10, 32, 32,101,110,100, 10, 32,101,108, - 115,101, 10, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, - 123, 39, 41, 10, 32, 32,105,102, 32,115,101,108,102, 46,116, - 121,112,101, 32,126, 61, 32, 39, 39, 32, 97,110,100, 32,115, - 101,108,102, 46,116,121,112,101, 32,126, 61, 32, 39,118,111, - 105,100, 39, 32,116,104,101,110, 10, 32, 32, 32,111,117,116, - 112,117,116, 40, 39, 32, 32, 39, 44,115,101,108,102, 46,109, - 111,100, 44,115,101,108,102, 46,116,121,112,101, 44,115,101, - 108,102, 46,112,116,114, 44, 39,116,111,108,117, 97, 95,114, - 101,116, 32, 61, 32, 39, 41, 10, 32, 32, 32,111,117,116,112, - 117,116, 40, 39, 40, 39, 44,115,101,108,102, 46,109,111,100, - 44,115,101,108,102, 46,116,121,112,101, 44,115,101,108,102, - 46,112,116,114, 44, 39, 41, 32, 39, 41, 10, 32, 32,101,108, - 115,101, 10, 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, - 32, 39, 41, 10, 32, 32,101,110,100, 10, 32, 32,105,102, 32, - 99,108, 97,115,115, 32, 97,110,100, 32,115,101,108,102, 46, - 110, 97,109,101, 61, 61, 39,110,101,119, 39, 32,116,104,101, - 110, 10, 32, 32, 32,111,117,116,112,117,116, 40, 39, 77,116, - 111,108,117, 97, 95,110,101,119, 40, 40, 39, 44,115,101,108, - 102, 46,116,121,112,101, 44, 39, 41, 40, 39, 41, 10, 32, 32, - 101,108,115,101,105,102, 32, 99,108, 97,115,115, 32, 97,110, - 100, 32,115,116, 97,116,105, 99, 32,116,104,101,110, 10, 9, - 105,102, 32,111,117,116, 32,116,104,101,110, 10, 9, 9,111, - 117,116,112,117,116, 40,115,101,108,102, 46,110, 97,109,101, - 44, 39, 40, 39, 41, 10, 9,101,108,115,101, 10, 9, 9,111, - 117,116,112,117,116, 40, 99,108, 97,115,115, 46, 46, 39, 58, - 58, 39, 46, 46,115,101,108,102, 46,110, 97,109,101, 44, 39, - 40, 39, 41, 10, 9,101,110,100, 10, 32, 32,101,108,115,101, - 105,102, 32, 99,108, 97,115,115, 32,116,104,101,110, 10, 9, - 105,102, 32,111,117,116, 32,116,104,101,110, 10, 9, 9,111, - 117,116,112,117,116, 40,115,101,108,102, 46,110, 97,109,101, - 44, 39, 40, 39, 41, 10, 9,101,108,115,101, 10, 9, 32, 32, - 105,102, 32,115,101,108,102, 46, 99, 97,115,116, 95,111,112, - 101,114, 97,116,111,114, 32,116,104,101,110, 10, 9, 32, 32, - 9, 45, 45,111,117,116,112,117,116, 40, 39,115,116, 97,116, - 105, 99, 95, 99, 97,115,116, 60, 39, 44,115,101,108,102, 46, - 109,111,100, 44,115,101,108,102, 46,116,121,112,101, 44,115, - 101,108,102, 46,112,116,114, 44, 39, 32, 62, 40, 42,115,101, - 108,102, 39, 41, 10, 9, 9,111,117,116,112,117,116, 40, 39, - 115,101,108,102, 45, 62,111,112,101,114, 97,116,111,114, 32, - 39, 44,115,101,108,102, 46,109,111,100, 44,115,101,108,102, - 46,116,121,112,101, 44, 39, 40, 39, 41, 10, 9, 32, 32,101, - 108,115,101, 10, 9, 9,111,117,116,112,117,116, 40, 39,115, - 101,108,102, 45, 62, 39, 46, 46,115,101,108,102, 46,110, 97, - 109,101, 44, 39, 40, 39, 41, 10, 9, 32, 32,101,110,100, 10, - 9,101,110,100, 10, 32, 32,101,108,115,101, 10, 32, 32, 32, - 111,117,116,112,117,116, 40,115,101,108,102, 46,110, 97,109, - 101, 44, 39, 40, 39, 41, 10, 32, 32,101,110,100, 10, 10, 32, - 32,105,102, 32,111,117,116, 32, 97,110,100, 32,110,111,116, - 32,115,116, 97,116,105, 99, 32,116,104,101,110, 10, 32, 32, - 9,111,117,116,112,117,116, 40, 39,115,101,108,102, 39, 41, - 10, 9,105,102, 32,115,101,108,102, 46, 97,114,103,115, 91, - 49, 93, 32, 97,110,100, 32,115,101,108,102, 46, 97,114,103, - 115, 91, 49, 93, 46,110, 97,109,101, 32,126, 61, 32, 39, 39, - 32,116,104,101,110, 10, 9, 9,111,117,116,112,117,116, 40, - 39, 44, 39, 41, 10, 9,101,110,100, 10, 32, 32,101,110,100, - 10, 32, 32, 45, 45, 32,119,114,105,116,101, 32,112, 97,114, - 97,109,101,116,101,114,115, 10, 32, 32,108,111, 99, 97,108, - 32,105, 61, 49, 10, 32, 32,119,104,105,108,101, 32,115,101, - 108,102, 46, 97,114,103,115, 91,105, 93, 32,100,111, 10, 32, - 32, 32,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 58, - 112, 97,115,115,112, 97,114, 40, 41, 10, 32, 32, 32,105, 32, - 61, 32,105, 43, 49, 10, 32, 32, 32,105,102, 32,115,101,108, - 102, 46, 97,114,103,115, 91,105, 93, 32,116,104,101,110, 10, - 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, 44, 39, 41, - 10, 32, 32, 32,101,110,100, 10, 32, 32,101,110,100, 10, 10, - 32, 32,105,102, 32, 99,108, 97,115,115, 32, 97,110,100, 32, - 115,101,108,102, 46,110, 97,109,101, 32, 61, 61, 32, 39,111, - 112,101,114, 97,116,111,114, 91, 93, 39, 32, 97,110,100, 32, - 102,108, 97,103,115, 91, 39, 49, 39, 93, 32,116,104,101,110, - 10, 9,111,117,116,112,117,116, 40, 39, 45, 49, 41, 59, 39, - 41, 10, 32, 32,101,108,115,101, 10, 9,105,102, 32, 99,108, - 97,115,115, 32, 97,110,100, 32,115,101,108,102, 46,110, 97, - 109,101, 61, 61, 39,110,101,119, 39, 32,116,104,101,110, 10, - 9, 9,111,117,116,112,117,116, 40, 39, 41, 41, 59, 39, 41, - 32, 45, 45, 32, 99,108,111,115,101, 32, 77,116,111,108,117, - 97, 95,110,101,119, 40, 10, 9,101,108,115,101, 10, 9, 9, - 111,117,116,112,117,116, 40, 39, 41, 59, 39, 41, 10, 9,101, - 110,100, 10, 32, 32,101,110,100, 10, 10, 32, 32, 45, 45, 32, - 114,101,116,117,114,110, 32,118, 97,108,117,101,115, 10, 32, - 32,105,102, 32,115,101,108,102, 46,116,121,112,101, 32,126, - 61, 32, 39, 39, 32, 97,110,100, 32,115,101,108,102, 46,116, - 121,112,101, 32,126, 61, 32, 39,118,111,105,100, 39, 32,116, - 104,101,110, 10, 32, 32, 32,110,114,101,116, 32, 61, 32,110, - 114,101,116, 32, 43, 32, 49, 10, 32, 32, 32,108,111, 99, 97, - 108, 32,116, 44, 99,116, 32, 61, 32,105,115, 98, 97,115,105, - 99, 40,115,101,108,102, 46,116,121,112,101, 41, 10, 32, 32, - 32,105,102, 32,116, 32, 97,110,100, 32,115,101,108,102, 46, - 110, 97,109,101, 32,126, 61, 32, 34,110,101,119, 34, 32,116, - 104,101,110, 10, 32, 32, 32, 9,105,102, 32,115,101,108,102, - 46, 99, 97,115,116, 95,111,112,101,114, 97,116,111,114, 32, - 97,110,100, 32, 95, 98, 97,115,105, 99, 95,114, 97,119, 95, - 112,117,115,104, 91,116, 93, 32,116,104,101,110, 10, 9, 9, - 111,117,116,112,117,116, 40, 39, 32, 32, 32, 39, 44, 95, 98, - 97,115,105, 99, 95,114, 97,119, 95,112,117,115,104, 91,116, - 93, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 40, 39, 44, - 99,116, 44, 39, 41,116,111,108,117, 97, 95,114,101,116, 41, - 59, 39, 41, 10, 32, 32, 32, 9,101,108,115,101, 10, 9, 32, - 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32,116, - 111,108,117, 97, 95,112,117,115,104, 39, 46, 46,116, 46, 46, - 39, 40,116,111,108,117, 97, 95, 83, 44, 40, 39, 44, 99,116, - 44, 39, 41,116,111,108,117, 97, 95,114,101,116, 41, 59, 39, - 41, 10, 9,101,110,100, 10, 32, 32, 32,101,108,115,101, 10, - 9,116, 32, 61, 32,115,101,108,102, 46,116,121,112,101, 10, - 9,110,101,119, 95,116, 32, 61, 32,115,116,114,105,110,103, - 46,103,115,117, 98, 40,116, 44, 32, 34, 99,111,110,115,116, - 37,115, 43, 34, 44, 32, 34, 34, 41, 10, 9,108,111, 99, 97, - 108, 32,111,119,110,101,100, 32, 61, 32,102, 97,108,115,101, - 10, 9,105,102, 32,115,116,114,105,110,103, 46,102,105,110, - 100, 40,115,101,108,102, 46,109,111,100, 44, 32, 34,116,111, - 108,117, 97, 95,111,119,110,101,100, 34, 41, 32,116,104,101, - 110, 10, 9, 9,111,119,110,101,100, 32, 61, 32,116,114,117, - 101, 10, 9,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97, - 108, 32,112,117,115,104, 95,102,117,110, 99, 32, 61, 32,103, - 101,116, 95,112,117,115,104, 95,102,117,110, 99,116,105,111, - 110, 40,116, 41, 10, 32, 32, 32, 32,105,102, 32,115,101,108, - 102, 46,112,116,114, 32, 61, 61, 32, 39, 39, 32,116,104,101, - 110, 10, 32, 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, - 32, 32, 32,123, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116, - 112,117,116, 40, 39, 35,105,102,100,101,102, 32, 95, 95, 99, - 112,108,117,115,112,108,117,115, 92,110, 39, 41, 10, 32, 32, - 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32, - 118,111,105,100, 42, 32,116,111,108,117, 97, 95,111, 98,106, - 32, 61, 32, 77,116,111,108,117, 97, 95,110,101,119, 40, 40, - 39, 44,110,101,119, 95,116, 44, 39, 41, 40,116,111,108,117, - 97, 95,114,101,116, 41, 41, 59, 39, 41, 10, 32, 32, 32, 32, - 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32, 39, 44, - 112,117,115,104, 95,102,117,110, 99, 44, 39, 40,116,111,108, - 117, 97, 95, 83, 44,116,111,108,117, 97, 95,111, 98,106, 44, - 34, 39, 44,116, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32, 32, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32,116, - 111,108,117, 97, 95,114,101,103,105,115,116,101,114, 95,103, - 99, 40,116,111,108,117, 97, 95, 83, 44,108,117, 97, 95,103, - 101,116,116,111,112, 40,116,111,108,117, 97, 95, 83, 41, 41, - 59, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116,112,117,116, - 40, 39, 35,101,108,115,101, 92,110, 39, 41, 10, 32, 32, 32, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32,118, - 111,105,100, 42, 32,116,111,108,117, 97, 95,111, 98,106, 32, - 61, 32,116,111,108,117, 97, 95, 99,111,112,121, 40,116,111, - 108,117, 97, 95, 83, 44, 40,118,111,105,100, 42, 41, 38,116, - 111,108,117, 97, 95,114,101,116, 44,115,105,122,101,111,102, - 40, 39, 44,116, 44, 39, 41, 41, 59, 39, 41, 10, 32, 32, 32, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32, 39, - 44,112,117,115,104, 95,102,117,110, 99, 44, 39, 40,116,111, - 108,117, 97, 95, 83, 44,116,111,108,117, 97, 95,111, 98,106, - 44, 34, 39, 44,116, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32, - 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32, - 116,111,108,117, 97, 95,114,101,103,105,115,116,101,114, 95, - 103, 99, 40,116,111,108,117, 97, 95, 83, 44,108,117, 97, 95, - 103,101,116,116,111,112, 40,116,111,108,117, 97, 95, 83, 41, - 41, 59, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116,112,117, - 116, 40, 39, 35,101,110,100,105,102, 92,110, 39, 41, 10, 32, - 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, - 125, 39, 41, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32, - 115,101,108,102, 46,112,116,114, 32, 61, 61, 32, 39, 38, 39, - 32,116,104,101,110, 10, 32, 32, 32, 32, 32,111,117,116,112, - 117,116, 40, 39, 32, 32, 32, 39, 44,112,117,115,104, 95,102, - 117,110, 99, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 40, - 118,111,105,100, 42, 41, 38,116,111,108,117, 97, 95,114,101, - 116, 44, 34, 39, 44,116, 44, 39, 34, 41, 59, 39, 41, 10, 32, - 32, 32, 32,101,108,115,101, 10, 9, 32,111,117,116,112,117, - 116, 40, 39, 32, 32, 32, 39, 44,112,117,115,104, 95,102,117, - 110, 99, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 40,118, - 111,105,100, 42, 41,116,111,108,117, 97, 95,114,101,116, 44, - 34, 39, 44,116, 44, 39, 34, 41, 59, 39, 41, 10, 9, 32,105, - 102, 32,111,119,110,101,100, 32,111,114, 32,108,111, 99, 97, - 108, 95, 99,111,110,115,116,114,117, 99,116,111,114, 32,116, - 104,101,110, 10, 32, 32, 32, 32, 32, 32,111,117,116,112,117, - 116, 40, 39, 32, 32, 32, 32,116,111,108,117, 97, 95,114,101, - 103,105,115,116,101,114, 95,103, 99, 40,116,111,108,117, 97, - 95, 83, 44,108,117, 97, 95,103,101,116,116,111,112, 40,116, - 111,108,117, 97, 95, 83, 41, 41, 59, 39, 41, 10, 9, 32,101, - 110,100, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32,101, - 110,100, 10, 32, 32,101,110,100, 10, 32, 32,108,111, 99, 97, - 108, 32,105, 61, 49, 10, 32, 32,119,104,105,108,101, 32,115, - 101,108,102, 46, 97,114,103,115, 91,105, 93, 32,100,111, 10, - 32, 32, 32,110,114,101,116, 32, 61, 32,110,114,101,116, 32, - 43, 32,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 58, - 114,101,116,118, 97,108,117,101, 40, 41, 10, 32, 32, 32,105, - 32, 61, 32,105, 43, 49, 10, 32, 32,101,110,100, 10, 32, 32, - 111,117,116,112,117,116, 40, 39, 32, 32,125, 39, 41, 10, 10, - 32, 32, 45, 45, 32,115,101,116, 32, 97,114,114, 97,121, 32, - 101,108,101,109,101,110,116, 32,118, 97,108,117,101,115, 10, - 32, 32,105,102, 32, 99,108, 97,115,115, 32,116,104,101,110, - 32,110, 97,114,103, 61, 50, 32,101,108,115,101, 32,110, 97, - 114,103, 61, 49, 32,101,110,100, 10, 32, 32,105,102, 32,115, - 101,108,102, 46, 97,114,103,115, 91, 49, 93, 46,116,121,112, - 101, 32,126, 61, 32, 39,118,111,105,100, 39, 32,116,104,101, - 110, 10, 32, 32, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, - 32, 32, 32,119,104,105,108,101, 32,115,101,108,102, 46, 97, - 114,103,115, 91,105, 93, 32,100,111, 10, 32, 32, 32, 32,115, - 101,108,102, 46, 97,114,103,115, 91,105, 93, 58,115,101,116, - 97,114,114, 97,121, 40,110, 97,114,103, 41, 10, 32, 32, 32, - 32,110, 97,114,103, 32, 61, 32,110, 97,114,103, 43, 49, 10, - 32, 32, 32, 32,105, 32, 61, 32,105, 43, 49, 10, 32, 32, 32, - 101,110,100, 10, 32, 32,101,110,100, 10, 10, 32, 32, 45, 45, - 32,102,114,101,101, 32,100,121,110, 97,109,105, 99, 97,108, - 108,121, 32, 97,108,108,111, 99, 97,116,101,100, 32, 97,114, - 114, 97,121, 10, 32, 32,105,102, 32,115,101,108,102, 46, 97, - 114,103,115, 91, 49, 93, 46,116,121,112,101, 32,126, 61, 32, - 39,118,111,105,100, 39, 32,116,104,101,110, 10, 32, 32, 32, - 108,111, 99, 97,108, 32,105, 61, 49, 10, 32, 32, 32,119,104, - 105,108,101, 32,115,101,108,102, 46, 97,114,103,115, 91,105, - 93, 32,100,111, 10, 32, 32, 32, 32,115,101,108,102, 46, 97, - 114,103,115, 91,105, 93, 58,102,114,101,101, 97,114,114, 97, - 121, 40, 41, 10, 32, 32, 32, 32,105, 32, 61, 32,105, 43, 49, - 10, 32, 32, 32,101,110,100, 10, 32, 32,101,110,100, 10, 32, - 101,110,100, 10, 10, 32,112,111,115,116, 95, 99, 97,108,108, - 95,104,111,111,107, 40,115,101,108,102, 41, 10, 10, 32,111, - 117,116,112,117,116, 40, 39, 32,125, 39, 41, 10, 32,111,117, - 116,112,117,116, 40, 39, 32,114,101,116,117,114,110, 32, 39, - 46, 46,110,114,101,116, 46, 46, 39, 59, 39, 41, 10, 10, 32, - 45, 45, 32, 99, 97,108,108, 32,111,118,101,114,108,111, 97, - 100,101,100, 32,102,117,110, 99,116,105,111,110, 32,111,114, - 32,103,101,110,101,114, 97,116,101, 32,101,114,114,111,114, - 10, 9,105,102, 32,111,118,101,114,108,111, 97,100, 32, 60, - 32, 48, 32,116,104,101,110, 10, 10, 9, 9,111,117,116,112, - 117,116, 40, 39, 35,105,102,110,100,101,102, 32, 84, 79, 76, - 85, 65, 95, 82, 69, 76, 69, 65, 83, 69, 92,110, 39, 41, 10, - 9, 9,111,117,116,112,117,116, 40, 39,116,111,108,117, 97, - 95,108,101,114,114,111,114, 58, 92,110, 39, 41, 10, 9, 9, - 111,117,116,112,117,116, 40, 39, 32,116,111,108,117, 97, 95, - 101,114,114,111,114, 40,116,111,108,117, 97, 95, 83, 44, 34, - 39, 46, 46,111,117,116,112,117,116, 95,101,114,114,111,114, - 95,104,111,111,107, 40, 34, 35,102,101,114,114,111,114, 32, - 105,110, 32,102,117,110, 99,116,105,111,110, 32, 92, 39, 37, - 115, 92, 39, 46, 34, 44, 32,115,101,108,102, 46,108,110, 97, - 109,101, 41, 46, 46, 39, 34, 44, 38,116,111,108,117, 97, 95, - 101,114,114, 41, 59, 39, 41, 10, 9, 9,111,117,116,112,117, - 116, 40, 39, 32,114,101,116,117,114,110, 32, 48, 59, 39, 41, - 10, 9, 9,111,117,116,112,117,116, 40, 39, 35,101,110,100, - 105,102, 92,110, 39, 41, 10, 9,101,108,115,101, 10, 9, 9, - 108,111, 99, 97,108, 32, 95,108,111, 99, 97,108, 32, 61, 32, - 34, 34, 10, 9, 9,105,102, 32,108,111, 99, 97,108, 95, 99, - 111,110,115,116,114,117, 99,116,111,114, 32,116,104,101,110, - 10, 9, 9, 9, 95,108,111, 99, 97,108, 32, 61, 32, 34, 95, - 108,111, 99, 97,108, 34, 10, 9, 9,101,110,100, 10, 9, 9, - 111,117,116,112,117,116, 40, 39,116,111,108,117, 97, 95,108, - 101,114,114,111,114, 58, 92,110, 39, 41, 10, 9, 9,111,117, - 116,112,117,116, 40, 39, 32,114,101,116,117,114,110, 32, 39, - 46, 46,115,116,114,115,117, 98, 40,115,101,108,102, 46, 99, - 110, 97,109,101, 44, 49, 44, 45, 51, 41, 46, 46,102,111,114, - 109, 97,116, 40, 34, 37, 48, 50,100, 34, 44,111,118,101,114, - 108,111, 97,100, 41, 46, 46, 95,108,111, 99, 97,108, 46, 46, - 39, 40,116,111,108,117, 97, 95, 83, 41, 59, 39, 41, 10, 9, - 101,110,100, 10, 32,111,117,116,112,117,116, 40, 39,125, 39, - 41, 10, 32,111,117,116,112,117,116, 40, 39, 35,101,110,100, - 105,102, 32, 47, 47, 35,105,102,110,100,101,102, 32, 84, 79, - 76, 85, 65, 95, 68, 73, 83, 65, 66, 76, 69, 92,110, 39, 41, - 10, 32,111,117,116,112,117,116, 40, 39, 92,110, 39, 41, 10, - 10, 9, 45, 45, 32,114,101, 99,117,114,115,105,118,101, 32, - 99, 97,108,108, 32,116,111, 32,119,114,105,116,101, 32,108, - 111, 99, 97,108, 32, 99,111,110,115,116,114,117, 99,116,111, - 114, 10, 9,105,102, 32, 99,108, 97,115,115, 32, 97,110,100, - 32,115,101,108,102, 46,110, 97,109,101, 61, 61, 39,110,101, - 119, 39, 32, 97,110,100, 32,110,111,116, 32,108,111, 99, 97, - 108, 95, 99,111,110,115,116,114,117, 99,116,111,114, 32,116, - 104,101,110, 10, 10, 9, 9,115,101,108,102, 58,115,117,112, - 99,111,100,101, 40, 49, 41, 10, 9,101,110,100, 10, 10,101, - 110,100, 10, 10, 10, 45, 45, 32,114,101,103,105,115,116,101, - 114, 32,102,117,110, 99,116,105,111,110, 10,102,117,110, 99, - 116,105,111,110, 32, 99,108, 97,115,115, 70,117,110, 99,116, - 105,111,110, 58,114,101,103,105,115,116,101,114, 32, 40,112, - 114,101, 41, 10, 10, 9,105,102, 32,110,111,116, 32,115,101, - 108,102, 58, 99,104,101, 99,107, 95,112,117, 98,108,105, 99, - 95, 97, 99, 99,101,115,115, 40, 41, 32,116,104,101,110, 10, - 9, 9,114,101,116,117,114,110, 10, 9,101,110,100, 10, 10, - 32, 9,105,102, 32,115,101,108,102, 46,110, 97,109,101, 32, - 61, 61, 32, 39,110,101,119, 39, 32, 97,110,100, 32,115,101, - 108,102, 46,112, 97,114,101,110,116, 46,102,108, 97,103,115, - 46,112,117,114,101, 95,118,105,114,116,117, 97,108, 32,116, - 104,101,110, 10, 32, 9, 9, 45, 45, 32,110,111, 32, 99,111, - 110,115,116,114,117, 99,116,111,114, 32,102,111,114, 32, 99, - 108, 97,115,115,101,115, 32,119,105,116,104, 32,112,117,114, - 101, 32,118,105,114,116,117, 97,108, 32,109,101,116,104,111, - 100,115, 10, 32, 9, 9,114,101,116,117,114,110, 10, 32, 9, - 101,110,100, 10, 10, 32,111,117,116,112,117,116, 40,112,114, - 101, 46, 46, 39,116,111,108,117, 97, 95,102,117,110, 99,116, - 105,111,110, 40,116,111,108,117, 97, 95, 83, 44, 34, 39, 46, - 46,115,101,108,102, 46,108,110, 97,109,101, 46, 46, 39, 34, - 44, 39, 46, 46,115,101,108,102, 46, 99,110, 97,109,101, 46, - 46, 39, 41, 59, 39, 41, 10, 32, 32,105,102, 32,115,101,108, - 102, 46,110, 97,109,101, 32, 61, 61, 32, 39,110,101,119, 39, - 32,116,104,101,110, 10, 9, 32, 32,111,117,116,112,117,116, - 40,112,114,101, 46, 46, 39,116,111,108,117, 97, 95,102,117, - 110, 99,116,105,111,110, 40,116,111,108,117, 97, 95, 83, 44, - 34,110,101,119, 95,108,111, 99, 97,108, 34, 44, 39, 46, 46, - 115,101,108,102, 46, 99,110, 97,109,101, 46, 46, 39, 95,108, - 111, 99, 97,108, 41, 59, 39, 41, 10, 9, 32, 32,111,117,116, - 112,117,116, 40,112,114,101, 46, 46, 39,116,111,108,117, 97, - 95,102,117,110, 99,116,105,111,110, 40,116,111,108,117, 97, - 95, 83, 44, 34, 46, 99, 97,108,108, 34, 44, 39, 46, 46,115, - 101,108,102, 46, 99,110, 97,109,101, 46, 46, 39, 95,108,111, - 99, 97,108, 41, 59, 39, 41, 10, 9, 32, 32, 45, 45,111,117, - 116,112,117,116, 40, 39, 32,116,111,108,117, 97, 95,115,101, - 116, 95, 99, 97,108,108, 95,101,118,101,110,116, 40,116,111, - 108,117, 97, 95, 83, 44, 39, 46, 46,115,101,108,102, 46, 99, - 110, 97,109,101, 46, 46, 39, 95,108,111, 99, 97,108, 44, 32, - 34, 39, 46, 46,115,101,108,102, 46,112, 97,114,101,110,116, - 46,116,121,112,101, 46, 46, 39, 34, 41, 59, 39, 41, 10, 32, - 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 80,114, - 105,110,116, 32,109,101,116,104,111,100, 10,102,117,110, 99, - 116,105,111,110, 32, 99,108, 97,115,115, 70,117,110, 99,116, - 105,111,110, 58,112,114,105,110,116, 32, 40,105,100,101,110, - 116, 44, 99,108,111,115,101, 41, 10, 32,112,114,105,110,116, - 40,105,100,101,110,116, 46, 46, 34, 70,117,110, 99,116,105, - 111,110,123, 34, 41, 10, 32,112,114,105,110,116, 40,105,100, - 101,110,116, 46, 46, 34, 32,109,111,100, 32, 32, 61, 32, 39, - 34, 46, 46,115,101,108,102, 46,109,111,100, 46, 46, 34, 39, - 44, 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110, - 116, 46, 46, 34, 32,116,121,112,101, 32, 61, 32, 39, 34, 46, - 46,115,101,108,102, 46,116,121,112,101, 46, 46, 34, 39, 44, - 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, - 46, 46, 34, 32,112,116,114, 32, 32, 61, 32, 39, 34, 46, 46, - 115,101,108,102, 46,112,116,114, 46, 46, 34, 39, 44, 34, 41, - 10, 32,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, - 34, 32,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,115,101, - 108,102, 46,110, 97,109,101, 46, 46, 34, 39, 44, 34, 41, 10, - 32,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, - 32,108,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,115,101, - 108,102, 46,108,110, 97,109,101, 46, 46, 34, 39, 44, 34, 41, - 10, 32,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, - 34, 32, 99,111,110,115,116, 32, 61, 32, 39, 34, 46, 46,115, - 101,108,102, 46, 99,111,110,115,116, 46, 46, 34, 39, 44, 34, - 41, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, 46, - 46, 34, 32, 99,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46, - 115,101,108,102, 46, 99,110, 97,109,101, 46, 46, 34, 39, 44, - 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, - 46, 46, 34, 32,108,110, 97,109,101, 32, 61, 32, 39, 34, 46, - 46,115,101,108,102, 46,108,110, 97,109,101, 46, 46, 34, 39, - 44, 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110, - 116, 46, 46, 34, 32, 97,114,103,115, 32, 61, 32,123, 34, 41, - 10, 32,108,111, 99, 97,108, 32,105, 61, 49, 10, 32,119,104, - 105,108,101, 32,115,101,108,102, 46, 97,114,103,115, 91,105, - 93, 32,100,111, 10, 32, 32,115,101,108,102, 46, 97,114,103, - 115, 91,105, 93, 58,112,114,105,110,116, 40,105,100,101,110, - 116, 46, 46, 34, 32, 32, 34, 44, 34, 44, 34, 41, 10, 32, 32, - 105, 32, 61, 32,105, 43, 49, 10, 32,101,110,100, 10, 32,112, - 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,125, - 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, - 46, 46, 34,125, 34, 46, 46, 99,108,111,115,101, 41, 10,101, - 110,100, 10, 10, 45, 45, 32, 99,104,101, 99,107, 32,105,102, - 32,105,116, 32,114,101,116,117,114,110,115, 32, 97,110, 32, - 111, 98,106,101, 99,116, 32, 98,121, 32,118, 97,108,117,101, - 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, - 70,117,110, 99,116,105,111,110, 58,114,101,113,117,105,114, - 101, 99,111,108,108,101, 99,116,105,111,110, 32, 40,116, 41, - 10, 9,108,111, 99, 97,108, 32,114, 32, 61, 32,102, 97,108, - 115,101, 10, 9,105,102, 32,115,101,108,102, 46,116,121,112, - 101, 32,126, 61, 32, 39, 39, 32, 97,110,100, 32,110,111,116, - 32,105,115, 98, 97,115,105, 99, 40,115,101,108,102, 46,116, - 121,112,101, 41, 32, 97,110,100, 32,115,101,108,102, 46,112, - 116,114, 61, 61, 39, 39, 32,116,104,101,110, 10, 9, 9,108, - 111, 99, 97,108, 32,116,121,112,101, 32, 61, 32,103,115,117, - 98, 40,115,101,108,102, 46,116,121,112,101, 44, 34, 37,115, - 42, 99,111,110,115,116, 37,115, 43, 34, 44, 34, 34, 41, 10, - 9, 32,116, 91,116,121,112,101, 93, 32, 61, 32, 34,116,111, - 108,117, 97, 95, 99,111,108,108,101, 99,116, 95, 34, 32, 46, - 46, 32, 99,108,101, 97,110, 95,116,101,109,112,108, 97,116, - 101, 40,116,121,112,101, 41, 10, 9, 32,114, 32, 61, 32,116, - 114,117,101, 10, 9,101,110,100, 10, 9,108,111, 99, 97,108, - 32,105, 61, 49, 10, 9,119,104,105,108,101, 32,115,101,108, - 102, 46, 97,114,103,115, 91,105, 93, 32,100,111, 10, 9, 9, - 114, 32, 61, 32,115,101,108,102, 46, 97,114,103,115, 91,105, - 93, 58,114,101,113,117,105,114,101, 99,111,108,108,101, 99, - 116,105,111,110, 40,116, 41, 32,111,114, 32,114, 10, 9, 9, - 105, 32, 61, 32,105, 43, 49, 10, 9,101,110,100, 10, 9,114, - 101,116,117,114,110, 32,114, 10,101,110,100, 10, 10, 45, 45, - 32,100,101,116,101,114,109,105,110,101, 32,108,117, 97, 32, - 102,117,110, 99,116,105,111,110, 32,110, 97,109,101, 32,111, - 118,101,114,108,111, 97,100, 10,102,117,110, 99,116,105,111, - 110, 32, 99,108, 97,115,115, 70,117,110, 99,116,105,111,110, - 58,111,118,101,114,108,111, 97,100, 32, 40, 41, 10, 32,114, - 101,116,117,114,110, 32,115,101,108,102, 46,112, 97,114,101, - 110,116, 58,111,118,101,114,108,111, 97,100, 40,115,101,108, - 102, 46,108,110, 97,109,101, 41, 10,101,110,100, 10, 10, 10, - 102,117,110, 99,116,105,111,110, 32,112, 97,114, 97,109, 95, - 111, 98,106,101, 99,116, 40,112, 97,114, 41, 32, 45, 45, 32, - 114,101,116,117,114,110,115, 32,116,114,117,101, 32,105,102, - 32,116,104,101, 32,112, 97,114, 97,109,101,116,101,114, 32, - 104, 97,115, 32, 97,110, 32,111, 98,106,101, 99,116, 32, 97, - 115, 32,105,116,115, 32,100,101,102, 97,117,108,116, 32,118, - 97,108,117,101, 10, 10, 9,105,102, 32,110,111,116, 32,115, - 116,114,105,110,103, 46,102,105,110,100, 40,112, 97,114, 44, - 32, 39, 61, 39, 41, 32,116,104,101,110, 32,114,101,116,117, - 114,110, 32,102, 97,108,115,101, 32,101,110,100, 32, 45, 45, - 32,105,116, 32,104, 97,115, 32,110,111, 32,100,101,102, 97, - 117,108,116, 32,118, 97,108,117,101, 10, 10, 9,108,111, 99, - 97,108, 32, 95, 44, 95, 44,100,101,102, 32, 61, 32,115,116, - 114,105,110,103, 46,102,105,110,100, 40,112, 97,114, 44, 32, - 34, 61, 40, 46, 42, 41, 36, 34, 41, 10, 10, 9,105,102, 32, - 115,116,114,105,110,103, 46,102,105,110,100, 40,112, 97,114, - 44, 32, 34,124, 34, 41, 32,116,104,101,110, 32, 45, 45, 32, - 97, 32,108,105,115,116, 32,111,102, 32,102,108, 97,103,115, - 10, 10, 9, 9,114,101,116,117,114,110, 32,116,114,117,101, - 10, 9,101,110,100, 10, 10, 9,105,102, 32,115,116,114,105, - 110,103, 46,102,105,110,100, 40,112, 97,114, 44, 32, 34, 37, - 42, 34, 41, 32,116,104,101,110, 32, 45, 45, 32,105,116, 39, - 115, 32, 97, 32,112,111,105,110,116,101,114, 32,119,105,116, - 104, 32, 97, 32,100,101,102, 97,117,108,116, 32,118, 97,108, - 117,101, 10, 10, 9, 9,105,102, 32,115,116,114,105,110,103, - 46,102,105,110,100, 40,112, 97,114, 44, 32, 39, 61, 37,115, - 42,110,101,119, 39, 41, 32,111,114, 32,115,116,114,105,110, - 103, 46,102,105,110,100, 40,112, 97,114, 44, 32, 34, 37, 40, - 34, 41, 32,116,104,101,110, 32, 45, 45, 32,105,116, 39,115, - 32, 97, 32,112,111,105,110,116,101,114, 32,119,105,116,104, - 32, 97,110, 32,105,110,115,116, 97,110, 99,101, 32, 97,115, - 32,100,101,102, 97,117,108,116, 32,112, 97,114, 97,109,101, - 116,101,114, 46, 46, 32,105,115, 32,116,104, 97,116, 32,118, - 97,108,105,100, 63, 10, 9, 9, 9,114,101,116,117,114,110, - 32,116,114,117,101, 10, 9, 9,101,110,100, 10, 9, 9,114, - 101,116,117,114,110, 32,102, 97,108,115,101, 32, 45, 45, 32, - 100,101,102, 97,117,108,116, 32,118, 97,108,117,101, 32,105, - 115, 32, 39, 78, 85, 76, 76, 39, 32,111,114, 32,115,111,109, - 101,116,104,105,110,103, 10, 9,101,110,100, 10, 10, 10, 9, - 105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40, - 112, 97,114, 44, 32, 34, 91, 37, 40, 38, 93, 34, 41, 32,116, - 104,101,110, 10, 9, 9,114,101,116,117,114,110, 32,116,114, - 117,101, 10, 9,101,110,100, 32, 45, 45, 32,100,101,102, 97, - 117,108,116, 32,118, 97,108,117,101, 32,105,115, 32, 97, 32, - 99,111,110,115,116,114,117, 99,116,111,114, 32, 99, 97,108, - 108, 32, 40,109,111,115,116, 32,108,105,107,101,108,121, 32, - 102,111,114, 32, 97, 32, 99,111,110,115,116, 32,114,101,102, - 101,114,101,110, 99,101, 41, 10, 10, 9, 45, 45,105,102, 32, - 115,116,114,105,110,103, 46,102,105,110,100, 40,112, 97,114, - 44, 32, 34, 38, 34, 41, 32,116,104,101,110, 10, 10, 9, 45, - 45, 9,105,102, 32,115,116,114,105,110,103, 46,102,105,110, - 100, 40,100,101,102, 44, 32, 34, 58, 34, 41, 32,111,114, 32, - 115,116,114,105,110,103, 46,102,105,110,100, 40,100,101,102, - 44, 32, 34, 94, 37,115, 42,110,101,119, 37,115, 43, 34, 41, - 32,116,104,101,110, 10, 10, 9, 45, 45, 9, 9, 45, 45, 32, - 105,116, 39,115, 32, 97, 32,114,101,102,101,114,101,110, 99, - 101, 32,119,105,116,104, 32,100,101,102, 97,117,108,116, 32, - 116,111, 32,115,111,109,101,116,104,105,110,103, 32,108,105, - 107,101, 32, 67,108, 97,115,115, 58, 58,109,101,109, 98,101, - 114, 44, 32,111,114, 32, 39,110,101,119, 32, 67,108, 97,115, - 115, 39, 10, 9, 45, 45, 9, 9,114,101,116,117,114,110, 32, - 116,114,117,101, 10, 9, 45, 45, 9,101,110,100, 10, 9, 45, - 45,101,110,100, 10, 10, 9,114,101,116,117,114,110, 32,102, - 97,108,115,101, 32, 45, 45, 32, 63, 10,101,110,100, 10, 10, - 102,117,110, 99,116,105,111,110, 32,115,116,114,105,112, 95, - 108, 97,115,116, 95, 97,114,103, 40, 97,108,108, 95, 97,114, - 103,115, 44, 32,108, 97,115,116, 95, 97,114,103, 41, 32, 45, - 45, 32,115,116,114,105,112,115, 32,116,104,101, 32,100,101, - 102, 97,117,108,116, 32,118, 97,108,117,101, 32,102,114,111, - 109, 32,116,104,101, 32,108, 97,115,116, 32, 97,114,103,117, - 109,101,110,116, 10, 10, 9,108,111, 99, 97,108, 32, 95, 44, - 95, 44,115, 95, 97,114,103, 32, 61, 32,115,116,114,105,110, - 103, 46,102,105,110,100, 40,108, 97,115,116, 95, 97,114,103, - 44, 32, 34, 94, 40, 91, 94, 61, 93, 43, 41, 34, 41, 10, 9, - 108, 97,115,116, 95, 97,114,103, 32, 61, 32,115,116,114,105, - 110,103, 46,103,115,117, 98, 40,108, 97,115,116, 95, 97,114, - 103, 44, 32, 34, 40, 91, 37, 37, 37, 40, 37, 41, 93, 41, 34, - 44, 32, 34, 37, 37, 37, 49, 34, 41, 59, 10, 9, 97,108,108, - 95, 97,114,103,115, 32, 61, 32,115,116,114,105,110,103, 46, - 103,115,117, 98, 40, 97,108,108, 95, 97,114,103,115, 44, 32, - 34, 37,115, 42, 44, 37,115, 42, 34, 46, 46,108, 97,115,116, - 95, 97,114,103, 46, 46, 34, 37,115, 42, 37, 41, 37,115, 42, - 36, 34, 44, 32, 34, 41, 34, 41, 10, 9,114,101,116,117,114, - 110, 32, 97,108,108, 95, 97,114,103,115, 44, 32,115, 95, 97, - 114,103, 10,101,110,100, 10, 10, 10, 10, 45, 45, 32, 73,110, - 116,101,114,110, 97,108, 32, 99,111,110,115,116,114,117, 99, - 116,111,114, 10,102,117,110, 99,116,105,111,110, 32, 95, 70, - 117,110, 99,116,105,111,110, 32, 40,116, 41, 10, 32,115,101, - 116,109,101,116, 97,116, 97, 98,108,101, 40,116, 44, 99,108, - 97,115,115, 70,117,110, 99,116,105,111,110, 41, 10, 10, 32, - 105,102, 32,116, 46, 99,111,110,115,116, 32,126, 61, 32, 39, - 99,111,110,115,116, 39, 32, 97,110,100, 32,116, 46, 99,111, - 110,115,116, 32,126, 61, 32, 39, 39, 32,116,104,101,110, 10, - 32, 32,101,114,114,111,114, 40, 34, 35,105,110,118, 97,108, - 105,100, 32, 39, 99,111,110,115,116, 39, 32,115,112,101, 99, - 105,102,105, 99, 97,116,105,111,110, 34, 41, 10, 32,101,110, - 100, 10, 10, 32, 97,112,112,101,110,100, 40,116, 41, 10, 32, - 105,102, 32,116, 58,105,110, 99,108, 97,115,115, 40, 41, 32, - 116,104,101,110, 10, 32, 45, 45,112,114,105,110,116, 32, 40, - 39,116, 46,110, 97,109,101, 32,105,115, 32, 39, 46, 46,116, - 46,110, 97,109,101, 46, 46, 39, 44, 32,112, 97,114,101,110, - 116, 46,110, 97,109,101, 32,105,115, 32, 39, 46, 46,116, 46, - 112, 97,114,101,110,116, 46,110, 97,109,101, 41, 10, 32, 32, - 105,102, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, - 116, 46,110, 97,109,101, 44, 32, 34, 37, 98, 60, 62, 34, 44, - 32, 34, 34, 41, 32, 61, 61, 32,115,116,114,105,110,103, 46, - 103,115,117, 98, 40,116, 46,112, 97,114,101,110,116, 46,111, - 114,105,103,105,110, 97,108, 95,110, 97,109,101, 32,111,114, - 32,116, 46,112, 97,114,101,110,116, 46,110, 97,109,101, 44, - 32, 34, 37, 98, 60, 62, 34, 44, 32, 34, 34, 41, 32,116,104, - 101,110, 10, 32, 32, 32,116, 46,110, 97,109,101, 32, 61, 32, - 39,110,101,119, 39, 10, 32, 32, 32,116, 46,108,110, 97,109, - 101, 32, 61, 32, 39,110,101,119, 39, 10, 32, 32, 32,116, 46, - 112, 97,114,101,110,116, 46, 95,110,101,119, 32, 61, 32,116, - 114,117,101, 10, 32, 32, 32,116, 46,116,121,112,101, 32, 61, - 32,116, 46,112, 97,114,101,110,116, 46,110, 97,109,101, 10, - 32, 32, 32,116, 46,112,116,114, 32, 61, 32, 39, 42, 39, 10, - 32, 32,101,108,115,101,105,102, 32,115,116,114,105,110,103, - 46,103,115,117, 98, 40,116, 46,110, 97,109,101, 44, 32, 34, - 37, 98, 60, 62, 34, 44, 32, 34, 34, 41, 32, 61, 61, 32, 39, - 126, 39, 46, 46,115,116,114,105,110,103, 46,103,115,117, 98, - 40,116, 46,112, 97,114,101,110,116, 46,111,114,105,103,105, - 110, 97,108, 95,110, 97,109,101, 32,111,114, 32,116, 46,112, - 97,114,101,110,116, 46,110, 97,109,101, 44, 32, 34, 37, 98, - 60, 62, 34, 44, 32, 34, 34, 41, 32,116,104,101,110, 10, 32, - 32, 32,116, 46,110, 97,109,101, 32, 61, 32, 39,100,101,108, - 101,116,101, 39, 10, 32, 32, 32,116, 46,108,110, 97,109,101, - 32, 61, 32, 39,100,101,108,101,116,101, 39, 10, 32, 32, 32, - 116, 46,112, 97,114,101,110,116, 46, 95,100,101,108,101,116, - 101, 32, 61, 32,116,114,117,101, 10, 32, 32,101,110,100, 10, - 32,101,110,100, 10, 32,116, 46, 99,110, 97,109,101, 32, 61, - 32,116, 58, 99,102,117,110, 99,110, 97,109,101, 40, 34,116, - 111,108,117, 97, 34, 41, 46, 46,116, 58,111,118,101,114,108, - 111, 97,100, 40,116, 41, 10, 32,114,101,116,117,114,110, 32, - 116, 10,101,110,100, 10, 10, 45, 45, 32, 67,111,110,115,116, - 114,117, 99,116,111,114, 10, 45, 45, 32, 69,120,112,101, 99, - 116,115, 32,116,104,114,101,101, 32,115,116,114,105,110,103, - 115, 58, 32,111,110,101, 32,114,101,112,114,101,115,101,110, - 116,105,110,103, 32,116,104,101, 32,102,117,110, 99,116,105, - 111,110, 32,100,101, 99,108, 97,114, 97,116,105,111,110, 44, - 10, 45, 45, 32, 97,110,111,116,104,101,114, 32,114,101,112, - 114,101,115,101,110,116,105,110,103, 32,116,104,101, 32, 97, - 114,103,117,109,101,110,116, 32,108,105,115,116, 44, 32, 97, - 110,100, 32,116,104,101, 32,116,104,105,114,100, 32,114,101, - 112,114,101,115,101,110,116,105,110,103, 10, 45, 45, 32,116, - 104,101, 32, 34, 99,111,110,115,116, 34, 32,111,114, 32,101, - 109,112,116,121, 32,115,116,114,105,110,103, 46, 10,102,117, - 110, 99,116,105,111,110, 32, 70,117,110, 99,116,105,111,110, - 32, 40,100, 44, 97, 44, 99, 41, 10, 32, 45, 45,108,111, 99, - 97,108, 32,116, 32, 61, 32,115,112,108,105,116, 40,115,116, - 114,115,117, 98, 40, 97, 44, 50, 44, 45, 50, 41, 44, 39, 44, - 39, 41, 32, 45, 45, 32,101,108,105,109,105,110, 97,116,101, - 32, 98,114, 97, 99,101,115, 10, 32, 45, 45,108,111, 99, 97, - 108, 32,116, 32, 61, 32,115,112,108,105,116, 95,112, 97,114, - 97,109,115, 40,115,116,114,115,117, 98, 40, 97, 44, 50, 44, - 45, 50, 41, 41, 10, 10, 9,105,102, 32,110,111,116, 32,102, - 108, 97,103,115, 91, 39, 87, 39, 93, 32, 97,110,100, 32,115, - 116,114,105,110,103, 46,102,105,110,100, 40, 97, 44, 32, 34, - 37, 46, 37, 46, 37, 46, 37,115, 42, 37, 41, 34, 41, 32,116, - 104,101,110, 10, 10, 9, 9,119, 97,114,110,105,110,103, 40, - 34, 70,117,110, 99,116,105,111,110,115, 32,119,105,116,104, - 32,118, 97,114,105, 97, 98,108,101, 32, 97,114,103,117,109, - 101,110,116,115, 32, 40, 96, 46, 46, 46, 39, 41, 32, 97,114, - 101, 32,110,111,116, 32,115,117,112,112,111,114,116,101,100, - 46, 32, 73,103,110,111,114,105,110,103, 32, 34, 46, 46,100, - 46, 46, 97, 46, 46, 99, 41, 10, 9, 9,114,101,116,117,114, - 110, 32,110,105,108, 10, 9,101,110,100, 10, 10, 10, 32,108, - 111, 99, 97,108, 32,105, 61, 49, 10, 32,108,111, 99, 97,108, - 32,108, 32, 61, 32,123,110, 61, 48,125, 10, 10, 32, 9, 97, - 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, - 97, 44, 32, 34, 37,115, 42, 40, 91, 37, 40, 37, 41, 93, 41, - 37,115, 42, 34, 44, 32, 34, 37, 49, 34, 41, 10, 9,108,111, - 99, 97,108, 32,116, 44,115,116,114,105,112, 44,108, 97,115, - 116, 32, 61, 32,115,116,114,105,112, 95,112, 97,114,115, 40, - 115,116,114,115,117, 98, 40, 97, 44, 50, 44, 45, 50, 41, 41, - 59, 10, 9,105,102, 32,115,116,114,105,112, 32,116,104,101, - 110, 10, 9, 9, 45, 45,108,111, 99, 97,108, 32,110,115, 32, - 61, 32,115,116,114,105,110,103, 46,115,117, 98, 40,115,116, - 114,115,117, 98, 40, 97, 44, 49, 44, 45, 50, 41, 44, 32, 49, - 44, 32, 45, 40,115,116,114,105,110,103, 46,108,101,110, 40, - 108, 97,115,116, 41, 43, 49, 41, 41, 10, 9, 9,108,111, 99, - 97,108, 32,110,115, 32, 61, 32,106,111,105,110, 40,116, 44, - 32, 34, 44, 34, 44, 32, 49, 44, 32,108, 97,115,116, 45, 49, - 41, 10, 10, 9, 9,110,115, 32, 61, 32, 34, 40, 34, 46, 46, - 115,116,114,105,110,103, 46,103,115,117, 98, 40,110,115, 44, - 32, 34, 37,115, 42, 44, 37,115, 42, 36, 34, 44, 32, 34, 34, - 41, 46, 46, 39, 41, 39, 10, 9, 9, 45, 45,110,115, 32, 61, - 32,115,116,114,105,112, 95,100,101,102, 97,117,108,116,115, - 40,110,115, 41, 10, 10, 9, 9,108,111, 99, 97,108, 32,102, - 32, 61, 32, 70,117,110, 99,116,105,111,110, 40,100, 44, 32, - 110,115, 44, 32, 99, 41, 10, 9, 9,102,111,114, 32,105, 61, - 49, 44,108, 97,115,116, 32,100,111, 10, 9, 9, 9,116, 91, - 105, 93, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, - 98, 40,116, 91,105, 93, 44, 32, 34, 61, 46, 42, 36, 34, 44, - 32, 34, 34, 41, 10, 9, 9,101,110,100, 10, 9,101,110,100, - 10, 10, 32,119,104,105,108,101, 32,116, 91,105, 93, 32,100, - 111, 10, 32, 32,108, 46,110, 32, 61, 32,108, 46,110, 43, 49, - 10, 32, 32,108, 91,108, 46,110, 93, 32, 61, 32, 68,101, 99, - 108, 97,114, 97,116,105,111,110, 40,116, 91,105, 93, 44, 39, - 118, 97,114, 39, 44,116,114,117,101, 41, 10, 32, 32,105, 32, - 61, 32,105, 43, 49, 10, 32,101,110,100, 10, 32,108,111, 99, - 97,108, 32,102, 32, 61, 32, 68,101, 99,108, 97,114, 97,116, - 105,111,110, 40,100, 44, 39,102,117,110, 99, 39, 41, 10, 32, - 102, 46, 97,114,103,115, 32, 61, 32,108, 10, 32,102, 46, 99, - 111,110,115,116, 32, 61, 32, 99, 10, 32,114,101,116,117,114, - 110, 32, 95, 70,117,110, 99,116,105,111,110, 40,102, 41, 10, - 101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,106, - 111,105,110, 40,116, 44, 32,115,101,112, 44, 32,102,105,114, - 115,116, 44, 32,108, 97,115,116, 41, 10, 10, 9,102,105,114, - 115,116, 32, 61, 32,102,105,114,115,116, 32,111,114, 32, 49, - 10, 9,108, 97,115,116, 32, 61, 32,108, 97,115,116, 32,111, - 114, 32,116, 97, 98,108,101, 46,103,101,116,110, 40,116, 41, - 10, 9,108,111, 99, 97,108, 32,108,115,101,112, 32, 61, 32, - 34, 34, 10, 9,108,111, 99, 97,108, 32,114,101,116, 32, 61, - 32, 34, 34, 10, 9,108,111, 99, 97,108, 32,108,111,111,112, - 32, 61, 32,102, 97,108,115,101, 10, 9,102,111,114, 32,105, - 32, 61, 32,102,105,114,115,116, 44,108, 97,115,116, 32,100, - 111, 10, 10, 9, 9,114,101,116, 32, 61, 32,114,101,116, 46, - 46,108,115,101,112, 46, 46,116, 91,105, 93, 10, 9, 9,108, - 115,101,112, 32, 61, 32,115,101,112, 10, 9, 9,108,111,111, - 112, 32, 61, 32,116,114,117,101, 10, 9,101,110,100, 10, 9, - 105,102, 32,110,111,116, 32,108,111,111,112, 32,116,104,101, - 110, 10, 9, 9,114,101,116,117,114,110, 32, 34, 34, 10, 9, - 101,110,100, 10, 10, 9,114,101,116,117,114,110, 32,114,101, - 116, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, - 32,115,116,114,105,112, 95,112, 97,114,115, 40,115, 41, 10, - 10, 9,108,111, 99, 97,108, 32,116, 32, 61, 32,115,112,108, - 105,116, 95, 99, 95,116,111,107,101,110,115, 40,115, 44, 32, - 39, 44, 39, 41, 10, 9,108,111, 99, 97,108, 32,115,116,114, - 105,112, 32, 61, 32,102, 97,108,115,101, 10, 9,108,111, 99, - 97,108, 32,108, 97,115,116, 10, 10, 9,102,111,114, 32,105, - 61,116, 46,110, 44, 49, 44, 45, 49, 32,100,111, 10, 10, 9, - 9,105,102, 32,110,111,116, 32,115,116,114,105,112, 32, 97, - 110,100, 32,112, 97,114, 97,109, 95,111, 98,106,101, 99,116, - 40,116, 91,105, 93, 41, 32,116,104,101,110, 10, 9, 9, 9, - 108, 97,115,116, 32, 61, 32,105, 10, 9, 9, 9,115,116,114, - 105,112, 32, 61, 32,116,114,117,101, 10, 9, 9,101,110,100, - 10, 9, 9, 45, 45,105,102, 32,115,116,114,105,112, 32,116, - 104,101,110, 10, 9, 9, 45, 45, 9,116, 91,105, 93, 32, 61, - 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,116, 91, - 105, 93, 44, 32, 34, 61, 46, 42, 36, 34, 44, 32, 34, 34, 41, - 10, 9, 9, 45, 45,101,110,100, 10, 9,101,110,100, 10, 10, - 9,114,101,116,117,114,110, 32,116, 44,115,116,114,105,112, - 44,108, 97,115,116, 10, 10,101,110,100, 10, 10,102,117,110, - 99,116,105,111,110, 32,115,116,114,105,112, 95,100,101,102, - 97,117,108,116,115, 40,115, 41, 10, 10, 9,115, 32, 61, 32, - 115,116,114,105,110,103, 46,103,115,117, 98, 40,115, 44, 32, - 34, 94, 37, 40, 34, 44, 32, 34, 34, 41, 10, 9,115, 32, 61, - 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,115, 44, - 32, 34, 37, 41, 36, 34, 44, 32, 34, 34, 41, 10, 10, 9,108, - 111, 99, 97,108, 32,116, 32, 61, 32,115,112,108,105,116, 95, - 99, 95,116,111,107,101,110,115, 40,115, 44, 32, 34, 44, 34, - 41, 10, 9,108,111, 99, 97,108, 32,115,101,112, 44, 32,114, - 101,116, 32, 61, 32, 34, 34, 44, 34, 34, 10, 9,102,111,114, - 32,105, 61, 49, 44,116, 46,110, 32,100,111, 10, 9, 9,116, - 91,105, 93, 32, 61, 32,115,116,114,105,110,103, 46,103,115, - 117, 98, 40,116, 91,105, 93, 44, 32, 34, 61, 46, 42, 36, 34, - 44, 32, 34, 34, 41, 10, 9, 9,114,101,116, 32, 61, 32,114, - 101,116, 46, 46,115,101,112, 46, 46,116, 91,105, 93, 10, 9, - 9,115,101,112, 32, 61, 32, 34, 44, 34, 10, 9,101,110,100, - 10, 10, 9,114,101,116,117,114,110, 32, 34, 40, 34, 46, 46, - 114,101,116, 46, 46, 34, 41, 34, 10,101,110,100,32 - }; - tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/function.lua"); + #include "function_lua.h" + tolua_dobuffer(tolua_S,(char*)lua_function_lua,sizeof(lua_function_lua),"tolua embedded: src/bin/lua/function.lua"); lua_settop(tolua_S, top); } /* end of embedded lua code */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f8700692..6d3f6ddc6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,7 @@ if (NOT MSVC) #lib dependecies are not included set(BINDING_DEPENDECIES + tolua ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/virtual_method_hooks.lua ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/AllToLua.pkg Bindings/LuaFunctions.h -- cgit v1.2.3 From 04f1d58561c13ead8927ab0cd216f200892af086 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 15 Mar 2014 07:08:09 -0700 Subject: Fixed unessicary return --- src/DeadlockDetect.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index c42d09b89..4dc7bfde6 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -121,7 +121,6 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age) if (itr->second.m_NumCyclesSame > (1000 * m_IntervalSec) / CYCLE_MILLISECONDS) { DeadlockDetected(); - return; } } else -- cgit v1.2.3 From a427f004b8c110d3ecf66ec34ad2a1134f01e68f Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 15 Mar 2014 07:15:02 -0700 Subject: Fix indentation --- lib/tolua++/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 9c8943aac..5e04cbe1f 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -16,7 +16,7 @@ if(UNIX) COMMAND xxd -i lua/enumerate.lua >enumerate_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/enumerate.lua) - add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h COMMAND xxd -i lua/function.lua >function_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/function.lua) -- cgit v1.2.3 From 7f84c8d60b1265f31aa58bfa4e01739dd279c528 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 15 Mar 2014 10:42:35 -0700 Subject: Patched tolua to understand size_t --- lib/tolua++/src/bin/basic_lua.h | 4 +++- lib/tolua++/src/bin/lua/basic.lua | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/tolua++/src/bin/basic_lua.h b/lib/tolua++/src/bin/basic_lua.h index 9f3b114b4..6adbaa4a6 100644 --- a/lib/tolua++/src/bin/basic_lua.h +++ b/lib/tolua++/src/bin/basic_lua.h @@ -61,6 +61,8 @@ unsigned char lua_basic_lua[] = { 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, + 0x20, 0x5b, 0x27, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x74, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x5f, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, 0x2c, 0x0a, 0x20, 0x5b, 0x27, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, @@ -743,4 +745,4 @@ unsigned char lua_basic_lua[] = { 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a }; -unsigned int lua_basic_lua_len = 8909; +unsigned int lua_basic_lua_len = 8933; diff --git a/lib/tolua++/src/bin/lua/basic.lua b/lib/tolua++/src/bin/lua/basic.lua index f651f1fe6..10cb5b18b 100644 --- a/lib/tolua++/src/bin/lua/basic.lua +++ b/lib/tolua++/src/bin/lua/basic.lua @@ -23,6 +23,7 @@ _basic = { ['unsigned'] = 'number', ['float'] = 'number', ['double'] = 'number', + ['size_t'] = 'number', ['_cstring'] = 'string', ['_userdata'] = 'userdata', ['char*'] = 'string', -- cgit v1.2.3 From db73e37e2d9261a1ec27964ee453f7c59312af79 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 15 Mar 2014 20:33:34 +0100 Subject: Created a small plugin for InfoDump It allows you to dump the info of a plugin by pressing a button in the webadmin. --- MCServer/Plugins/DumpInfo/Init.lua | 49 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 MCServer/Plugins/DumpInfo/Init.lua diff --git a/MCServer/Plugins/DumpInfo/Init.lua b/MCServer/Plugins/DumpInfo/Init.lua new file mode 100644 index 000000000..0fa542bb8 --- /dev/null +++ b/MCServer/Plugins/DumpInfo/Init.lua @@ -0,0 +1,49 @@ +function Initialize(a_Plugin) + a_Plugin:SetName("DumpInfo") + a_Plugin:SetVersion(1) + + -- Check if the infodump file exists. + if (not cFile:Exists("Plugins/InfoDump.lua")) then + LOGWARN("[DumpInfo] InfoDump.lua was not found.") + return false + end + + -- Add the webtab. + a_Plugin:AddWebTab("DumpPlugin", HandleDumpPluginRequest) + return true +end + + + + + +function HandleDumpPluginRequest(a_Request) + local Content = "" + + -- Check if it already was requested to dump a plugin. + if (a_Request.PostParams["DumpInfo"] ~= nil) then + local F = loadfile("Plugins/InfoDump.lua") + F("Plugins/" .. a_Request.PostParams["DumpInfo"]) + end + + Content = Content .. [[ + +]] + + -- Loop through each plugin that is found. + for PluginName, k in pairs(cPluginManager:Get():GetAllPlugins()) do + + -- Check if there is a file called 'Info.lua' or 'info.lua' + if (cFile:Exists("Plugins/" .. PluginName .. "/Info.lua") or cFile:Exists("Plugins/" .. PluginName .. "/info.lua")) then + Content = Content .. "" + Content = Content .. "" + Content = Content .. "" + end + end + + Content = Content .. [[ +
DumpInfo
" .. PluginName .. "
" + Content = Content .. "
]] + + return Content +end -- cgit v1.2.3 From 3e0dfbc7a14f2d9784225e39a5dcf2ecdd5c6538 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 16 Mar 2014 07:59:58 -0700 Subject: Made buffers static const --- lib/tolua++/CMakeLists.txt | 6 +++--- lib/tolua++/src/bin/basic_lua.h | 2 +- lib/tolua++/src/bin/enumerate_lua.h | 2 +- lib/tolua++/src/bin/function_lua.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 5e04cbe1f..095fc152e 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -9,15 +9,15 @@ include_directories ("${PROJECT_SOURCE_DIR}") if(UNIX) add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h - COMMAND xxd -i lua/basic.lua >basic_lua.h + COMMAND xxd -i lua/basic.lua | sed 's/unsigned char/static const unsigned char/g' >basic_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/basic.lua) add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h - COMMAND xxd -i lua/enumerate.lua >enumerate_lua.h + COMMAND xxd -i lua/enumerate.lua | sed 's/unsigned char/static const unsigned char/g' >enumerate_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/enumerate.lua) add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h - COMMAND xxd -i lua/function.lua >function_lua.h + COMMAND xxd -i lua/function.lua | sed 's/unsigned char/static const unsigned char/g' >function_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/function.lua) set_property(SOURCE src/bin/toluabind.c APPEND PROPERTY OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h) diff --git a/lib/tolua++/src/bin/basic_lua.h b/lib/tolua++/src/bin/basic_lua.h index 9f3b114b4..107d1a953 100644 --- a/lib/tolua++/src/bin/basic_lua.h +++ b/lib/tolua++/src/bin/basic_lua.h @@ -1,4 +1,4 @@ -unsigned char lua_basic_lua[] = { +static const unsigned char lua_basic_lua[] = { 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x2d, 0x2d, diff --git a/lib/tolua++/src/bin/enumerate_lua.h b/lib/tolua++/src/bin/enumerate_lua.h index 271cf2a23..f7285dc9a 100644 --- a/lib/tolua++/src/bin/enumerate_lua.h +++ b/lib/tolua++/src/bin/enumerate_lua.h @@ -1,4 +1,4 @@ -unsigned char lua_enumerate_lua[] = { +static const unsigned char lua_enumerate_lua[] = { 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, diff --git a/lib/tolua++/src/bin/function_lua.h b/lib/tolua++/src/bin/function_lua.h index c1317b9fe..705cb1a8f 100644 --- a/lib/tolua++/src/bin/function_lua.h +++ b/lib/tolua++/src/bin/function_lua.h @@ -1,4 +1,4 @@ -unsigned char lua_function_lua[] = { +static const unsigned char lua_function_lua[] = { 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, -- cgit v1.2.3 From 4e0edc9fa7acca81ad28be3ff7b74d8178b29091 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 17:42:23 +0100 Subject: Add anvil direction. --- src/Blocks/BlockAnvil.h | 63 +++++++++++++++++++++++++++++++++++++++++++ src/Blocks/BlockHandler.cpp | 2 ++ src/WorldStorage/WSSAnvil.cpp | 10 ++++++- 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/Blocks/BlockAnvil.h diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h new file mode 100644 index 000000000..aadec2e94 --- /dev/null +++ b/src/Blocks/BlockAnvil.h @@ -0,0 +1,63 @@ + +#pragma once + +#include "BlockHandler.h" +#include "../World.h" +#include "../Entities/Player.h" + + + + + +class cBlockAnvilHandler : + public cBlockHandler +{ +public: + cBlockAnvilHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta)); + } + + virtual bool GetPlacementBlockTypeMeta( + cChunkInterface & a_ChunkInterface, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = m_BlockType; + + int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3; + int RawMeta = a_BlockMeta >> 2; + + Direction++; + Direction %= 4; + switch (Direction) + { + case 0: a_BlockMeta = 0x2 | RawMeta << 2; break; + case 1: a_BlockMeta = 0x3 | RawMeta << 2; break; + case 2: a_BlockMeta = 0x0 | RawMeta << 2; break; + case 3: a_BlockMeta = 0x1 | RawMeta << 2; break; + default: + { + return false; + } + } + + return true; + } + + virtual bool IsUseable() override + { + return true; + } +} ; + + + + diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index aa97b2ca9..5b8effc07 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -6,6 +6,7 @@ #include "../Root.h" #include "../Bindings/PluginManager.h" #include "../Chunk.h" +#include "BlockAnvil.h" #include "BlockBed.h" #include "BlockBrewingStand.h" #include "BlockButton.h" @@ -85,6 +86,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) // Block handlers, alphabetically sorted: case E_BLOCK_ACACIA_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_ACTIVATOR_RAIL: return new cBlockRailHandler (a_BlockType); + case E_BLOCK_ANVIL: return new cBlockAnvilHandler (a_BlockType); case E_BLOCK_BED: return new cBlockBedHandler (a_BlockType); case E_BLOCK_BIRCH_WOOD_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_BREWING_STAND: return new cBlockBrewingStandHandler (a_BlockType); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 4dd4c755d..19405f4aa 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1497,7 +1497,15 @@ void cWSSAnvil::LoadHangingFromNBT(cHangingEntity & a_Hanging, const cParsedNBT int Direction = a_NBT.FindChildByName(a_TagIdx, "Direction"); if (Direction > 0) { - a_Hanging.SetDirection(static_cast((int)a_NBT.GetByte(Direction))); + Direction = (int)a_NBT.GetByte(Direction); + if ((Direction < 0) || (Direction > 5)) + { + a_Hanging.SetDirection(BLOCK_FACE_NORTH); + } + else + { + a_Hanging.SetDirection(static_cast(Direction)); + } } else { -- cgit v1.2.3 From 568038ab5241cf7699bb74dd0c158e12bc34f68d Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 19:25:00 +0100 Subject: Fix anvil pickups. --- src/Blocks/BlockAnvil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index aadec2e94..9f5f84be0 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -20,7 +20,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta)); + a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta >> 2)); } virtual bool GetPlacementBlockTypeMeta( -- cgit v1.2.3 From 4ec5a95a7a690cb69fb5e9f44b2c9c2b3b678d09 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 20:26:13 +0100 Subject: Add cake --- src/Blocks/BlockCake.h | 55 +++++++++++++++++++++++++++++++++++++++++++++ src/Blocks/BlockHandler.cpp | 2 ++ src/Items/ItemCake.h | 41 +++++++++++++++++++++++++++++++++ src/Items/ItemHandler.cpp | 3 +++ 4 files changed, 101 insertions(+) create mode 100644 src/Blocks/BlockCake.h create mode 100644 src/Items/ItemCake.h diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h new file mode 100644 index 000000000..639f5eaba --- /dev/null +++ b/src/Blocks/BlockCake.h @@ -0,0 +1,55 @@ +#pragma once + +#include "BlockHandler.h" + + + + + +class cBlockCakeHandler : + public cBlockHandler +{ +public: + cBlockCakeHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override + { + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + + if (!a_Player->Feed(2, 0.1)) + { + return; + } + + if ((Meta + 1) >= 6) + { + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + } + else + { + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta + 1); + } + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + // Give nothing + } + + virtual bool IsUseable(void) override + { + return true; + } + + virtual const char * GetStepSound(void) override + { + return "step.cloth"; + } +} ; + + + + diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index aa97b2ca9..89a703de7 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -10,6 +10,7 @@ #include "BlockBrewingStand.h" #include "BlockButton.h" #include "BlockCactus.h" +#include "BlockCake.h" #include "BlockCarpet.h" #include "BlockCauldron.h" #include "BlockChest.h" @@ -91,6 +92,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_BRICK_STAIRS: return new cBlockStairsHandler (a_BlockType); case E_BLOCK_BROWN_MUSHROOM: return new cBlockMushroomHandler (a_BlockType); case E_BLOCK_CACTUS: return new cBlockCactusHandler (a_BlockType); + case E_BLOCK_CAKE: return new cBlockCakeHandler (a_BlockType); case E_BLOCK_CARROTS: return new cBlockCropsHandler (a_BlockType); case E_BLOCK_CARPET: return new cBlockCarpetHandler (a_BlockType); case E_BLOCK_CAULDRON: return new cBlockCauldronHandler (a_BlockType); diff --git a/src/Items/ItemCake.h b/src/Items/ItemCake.h new file mode 100644 index 000000000..48e23ed59 --- /dev/null +++ b/src/Items/ItemCake.h @@ -0,0 +1,41 @@ + +#pragma once + +#include "ItemHandler.h" + + + + + +class cItemCakeHandler : + public cItemHandler +{ +public: + cItemCakeHandler(int a_ItemType) : + cItemHandler(a_ItemType) + { + } + + + virtual bool IsPlaceable(void) override + { + return true; + } + + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + a_BlockType = E_BLOCK_CAKE; + a_BlockMeta = 0; + return true; + } +} ; + + + + diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 1d357fcf1..cd391480c 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -13,6 +13,7 @@ #include "ItemBow.h" #include "ItemBrewingStand.h" #include "ItemBucket.h" +#include "ItemCake.h" #include "ItemCauldron.h" #include "ItemCloth.h" #include "ItemComparator.h" @@ -101,6 +102,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_BOTTLE_O_ENCHANTING: return new cItemBottleOEnchantingHandler(); case E_ITEM_BOW: return new cItemBowHandler; case E_ITEM_BREWING_STAND: return new cItemBrewingStandHandler(a_ItemType); + case E_ITEM_CAKE: return new cItemCakeHandler(a_ItemType); case E_ITEM_CAULDRON: return new cItemCauldronHandler(a_ItemType); case E_ITEM_COMPARATOR: return new cItemComparatorHandler(a_ItemType); case E_ITEM_DYE: return new cItemDyeHandler(a_ItemType); @@ -337,6 +339,7 @@ char cItemHandler::GetMaxStackSize(void) case E_ITEM_BREWING_STAND: return 64; case E_ITEM_BUCKET: return 16; case E_ITEM_CARROT: return 64; + case E_ITEM_CAKE: return 1; case E_ITEM_CAULDRON: return 64; case E_ITEM_CLAY: return 64; case E_ITEM_CLAY_BRICK: return 64; -- cgit v1.2.3 From 96d80f981ee1e7d746135b99eabe3ddd84413781 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 20:57:23 +0100 Subject: Change if-clause in BlockCake.h --- src/Blocks/BlockCake.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h index 639f5eaba..36e133388 100644 --- a/src/Blocks/BlockCake.h +++ b/src/Blocks/BlockCake.h @@ -24,7 +24,7 @@ public: return; } - if ((Meta + 1) >= 6) + if (Meta >= 5) { a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); } -- cgit v1.2.3 From ef50e73a9c3053b8787ded3d26b3a5d3b6c92edc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 16 Mar 2014 18:44:23 +0100 Subject: Added common eMessageType aliases. --- src/Defines.h | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/Defines.h b/src/Defines.h index 3b7654265..38411c69d 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -530,16 +530,22 @@ enum eMessageType // http://forum.mc-server.org/showthread.php?tid=1212 // MessageType... - mtCustom, // Send raw data without any processing - mtFailure, // Something could not be done (i.e. command not executed due to insufficient privilege) - mtInformation, // Informational message (i.e. command usage) - mtSuccess, // Something executed successfully - mtWarning, // Something concerning (i.e. reload) is about to happen - mtFatal, // Something catastrophic occured (i.e. plugin crash) - mtDeath, // Denotes death of player - mtPrivateMessage, // Player to player messaging identifier - mtJoin, // A player has joined the server - mtLeave, // A player has left the server + mtCustom, // Send raw data without any processing + mtFailure, // Something could not be done (i.e. command not executed due to insufficient privilege) + mtInformation, // Informational message (i.e. command usage) + mtSuccess, // Something executed successfully + mtWarning, // Something concerning (i.e. reload) is about to happen + mtFatal, // Something catastrophic occured (i.e. plugin crash) + mtDeath, // Denotes death of player + mtPrivateMessage, // Player to player messaging identifier + mtJoin, // A player has joined the server + mtLeave, // A player has left the server + + // Common aliases: + mtFail = mtFailure, + mtError = mtFailure, + mtInfo = mtInformation, + mtPM = mtPrivateMessage, }; -- cgit v1.2.3 From 5ac863f7fa780329e9dbe4e087162e33e0b7213c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 16 Mar 2014 18:45:01 +0100 Subject: Removed the @EnableMobDebug.lua file. It is not needed anymore, ZeroBrane Studio now has direct support for invoking the debugger in MCS plugins. --- MCServer/Plugins/@EnableMobDebug.lua | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 MCServer/Plugins/@EnableMobDebug.lua diff --git a/MCServer/Plugins/@EnableMobDebug.lua b/MCServer/Plugins/@EnableMobDebug.lua deleted file mode 100644 index 48d4c36b7..000000000 --- a/MCServer/Plugins/@EnableMobDebug.lua +++ /dev/null @@ -1,29 +0,0 @@ - --- @EnableMobDebug.lua - --- Enables the MobDebug debugger, used by ZeroBrane Studio, for a plugin --- Needs to be named with a @ at the start so that it's loaded as the first file of the plugin - ---[[ -Usage: -Copy this file to your plugin's folder when you want to debug that plugin -You should neither check this file into the plugin's version control system, -nor distribute it in the final release. ---]] - - - - - --- Try to load the debugger, be silent about failures: -local IsSuccess, MobDebug = pcall(require, "mobdebug") -if (IsSuccess) then - MobDebug.start() - - -- The debugger will automatically put a breakpoint on this line, use this opportunity to set more breakpoints in your code - LOG(cPluginManager:GetCurrentPlugin():GetName() .. ": MobDebug enabled") -end - - - - -- cgit v1.2.3 From 4227066f6d564a0e816b190f2726f036bff5b34d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 16 Mar 2014 21:30:44 +0100 Subject: Fixed InfoReg.lua's handling of multi-level commands. --- MCServer/Plugins/InfoReg.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/InfoReg.lua b/MCServer/Plugins/InfoReg.lua index 1cf68dbed..b3717884a 100644 --- a/MCServer/Plugins/InfoReg.lua +++ b/MCServer/Plugins/InfoReg.lua @@ -59,13 +59,13 @@ local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_ return true; end - -- Check if the handler is valid: + -- If the handler is not valid, check the next sublevel: if (Subcommand.Handler == nil) then if (Subcommand.Subcommands == nil) then LOG("Cannot find handler for command " .. a_CmdString .. " " .. Verb); return false; end - ListSubcommands(a_Player, Subcommand.Subcommands, a_CmdString .. " " .. Verb); + MultiCommandHandler(a_Split, a_Player, a_CmdString .. " " .. Verb, Subcommand, a_Level + 1); return true; end -- cgit v1.2.3 From b9fce71bf68768ee86ce128f353fea5533f50732 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 14:01:22 +0100 Subject: Add new leaves to all classes. --- src/BlockInfo.cpp | 1 + src/Blocks/BlockLeaves.h | 3 ++- src/Blocks/BlockMushroom.h | 1 + src/Blocks/BlockVine.h | 2 +- src/ChunkMap.cpp | 7 +++++++ src/Items/ItemHandler.cpp | 1 + src/Items/ItemShears.h | 5 +++-- src/MobSpawner.cpp | 2 +- src/WorldStorage/WSSAnvil.cpp | 1 + 9 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index d1ecfdf7e..7d438ba3e 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -93,6 +93,7 @@ void cBlockInfo::Initialize(void) ms_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1; ms_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1; ms_Info[E_BLOCK_LEAVES ].m_SpreadLightFalloff = 1; + ms_Info[E_BLOCK_NEW_LEAVES ].m_SpreadLightFalloff = 1; ms_Info[E_BLOCK_SIGN_POST ].m_SpreadLightFalloff = 1; ms_Info[E_BLOCK_TORCH ].m_SpreadLightFalloff = 1; ms_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1; diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index 7b8f0b378..954b993d6 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -16,6 +16,7 @@ { \ case E_BLOCK_LEAVES: a_Area.SetBlockType(x, y, z, (BLOCKTYPE)(E_BLOCK_SPONGE + i + 1)); break; \ case E_BLOCK_LOG: return true; \ + case E_BLOCK_NEW_LOG: return true; \ } bool HasNearLog(cBlockArea &a_Area, int a_BlockX, int a_BlockY, int a_BlockZ); @@ -86,7 +87,7 @@ public: return; } - if ((Meta & 0x8) != 0) + if ((Meta & 0x8) == 0) { // These leaves have been checked for decay lately and nothing around them changed return; diff --git a/src/Blocks/BlockMushroom.h b/src/Blocks/BlockMushroom.h index 623cfda64..c30c1a401 100644 --- a/src/Blocks/BlockMushroom.h +++ b/src/Blocks/BlockMushroom.h @@ -39,6 +39,7 @@ public: case E_BLOCK_CACTUS: case E_BLOCK_ICE: case E_BLOCK_LEAVES: + case E_BLOCK_NEW_LEAVES: case E_BLOCK_AIR: { return false; diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 708583e70..8041d9359 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -73,7 +73,7 @@ public: /// Returns true if the specified block type is good for vines to attach to static bool IsBlockAttachable(BLOCKTYPE a_BlockType) { - return (a_BlockType == E_BLOCK_LEAVES) || cBlockInfo::IsSolid(a_BlockType); + return (a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType); } diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 40964c654..62c1ec544 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1383,6 +1383,13 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) } break; } + case E_BLOCK_NEW_LEAVES: + { + if (itr->BlockType == E_BLOCK_NEW_LOG) + { + Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); + } + } } } // for itr - a_Blocks[] } diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index cd391480c..136bc3096 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -95,6 +95,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) // Single item per handler, alphabetically sorted: case E_BLOCK_LEAVES: return new cItemLeavesHandler(a_ItemType); + case E_BLOCK_NEW_LEAVES: return new cItemLeavesHandler(a_ItemType); case E_BLOCK_SAPLING: return new cItemSaplingHandler(a_ItemType); case E_BLOCK_WOOL: return new cItemClothHandler(a_ItemType); case E_ITEM_BED: return new cItemBedHandler(a_ItemType); diff --git a/src/Items/ItemShears.h b/src/Items/ItemShears.h index b8f75f5ba..39d2776fa 100644 --- a/src/Items/ItemShears.h +++ b/src/Items/ItemShears.h @@ -28,10 +28,10 @@ public: virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override { BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - if (Block == E_BLOCK_LEAVES) + if ((Block == E_BLOCK_LEAVES) || (Block == E_BLOCK_NEW_LEAVES)) { cItems Drops; - Drops.push_back(cItem(E_BLOCK_LEAVES, 1, a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x03)); + Drops.push_back(cItem(Block, 1, a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) & 0x03)); a_World->SpawnItemPickups(Drops, a_BlockX, a_BlockY, a_BlockZ); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); @@ -49,6 +49,7 @@ public: case E_BLOCK_COBWEB: case E_BLOCK_VINES: case E_BLOCK_LEAVES: + case E_BLOCK_NEW_LEAVES: { return true; } diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index 7704f6cf3..a0d0f5c54 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -169,7 +169,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R (TargetBlock == E_BLOCK_AIR) && (BlockAbove == E_BLOCK_AIR) && ( - (BlockBelow == E_BLOCK_GRASS) || (BlockBelow == E_BLOCK_LEAVES) + (BlockBelow == E_BLOCK_GRASS) || (BlockBelow == E_BLOCK_LEAVES) || (BlockBelow == E_BLOCK_NEW_LEAVES) ) && (a_RelY >= 62) && (m_Random.NextInt(3, a_Biome) != 0) diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 070738164..fa916c484 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -366,6 +366,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT { case E_BLOCK_AIR: case E_BLOCK_LEAVES: + case E_BLOCK_NEW_LEAVES: { // nothing needed break; -- cgit v1.2.3 From c5740c27a9ac7df1baca802caa0bb8a45cb8005a Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 16:15:22 +0100 Subject: Wrong if in BlockLeaves --- src/Blocks/BlockLeaves.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index 954b993d6..a6d3373c1 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -87,7 +87,7 @@ public: return; } - if ((Meta & 0x8) == 0) + if ((Meta & 0x8) != 0) { // These leaves have been checked for decay lately and nothing around them changed return; -- cgit v1.2.3 From 5a9f17060d09316931fd246e7b5f059a6bf4abac Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 16 Mar 2014 21:52:28 +0100 Subject: Only check for "Info.lua" with capital I --- MCServer/Plugins/DumpInfo/Init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/DumpInfo/Init.lua b/MCServer/Plugins/DumpInfo/Init.lua index 0fa542bb8..5d9c752b0 100644 --- a/MCServer/Plugins/DumpInfo/Init.lua +++ b/MCServer/Plugins/DumpInfo/Init.lua @@ -34,7 +34,7 @@ function HandleDumpPluginRequest(a_Request) for PluginName, k in pairs(cPluginManager:Get():GetAllPlugins()) do -- Check if there is a file called 'Info.lua' or 'info.lua' - if (cFile:Exists("Plugins/" .. PluginName .. "/Info.lua") or cFile:Exists("Plugins/" .. PluginName .. "/info.lua")) then + if (cFile:Exists("Plugins/" .. PluginName .. "/Info.lua")) then Content = Content .. "" Content = Content .. "" .. PluginName .. "" Content = Content .. "

" -- cgit v1.2.3 From 260d13c7a40ab1af917158906df4b9c09974b704 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 16 Mar 2014 21:56:14 +0100 Subject: Added override specifier where appropriate in cWorld. --- src/World.h | 75 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/src/World.h b/src/World.h index 1950104a8..bd9ed8d16 100644 --- a/src/World.h +++ b/src/World.h @@ -125,15 +125,16 @@ public: // tolua_begin int GetTicksUntilWeatherChange(void) const { return m_WeatherInterval; } - virtual Int64 GetWorldAge(void) const { return m_WorldAge; } - virtual Int64 GetTimeOfDay(void) const { return m_TimeOfDay; } + + virtual Int64 GetWorldAge (void) const { return m_WorldAge; } // override, cannot specify due to tolua + virtual Int64 GetTimeOfDay(void) const { return m_TimeOfDay; } // override, cannot specify due to tolua void SetTicksUntilWeatherChange(int a_WeatherInterval) { m_WeatherInterval = a_WeatherInterval; } - virtual void SetTimeOfDay(Int64 a_TimeOfDay) + virtual void SetTimeOfDay(Int64 a_TimeOfDay) // override, cannot specify due to tolua { m_TimeOfDay = a_TimeOfDay; m_TimeOfDaySecs = (double)a_TimeOfDay / 20.0; @@ -191,35 +192,35 @@ public: void BroadcastChat (const cCompositeChat & a_Message, const cClientHandle * a_Exclude = NULL); // tolua_end - void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); - void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); - void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); - void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL); - void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL); - void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); - void BroadcastScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); - void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); - void BroadcastDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); - void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // tolua_export a_Src coords are Block * 8 - void BroadcastSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); // tolua_export - void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); - void BroadcastTimeUpdate (const cClientHandle * a_Exclude = NULL); - virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ); - void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = NULL); - - virtual cBroadcastInterface & GetBroadcastManager() + void BroadcastChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer, const cClientHandle * a_Exclude = NULL); + void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL); + void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); + void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; + void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); // tolua_export + void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL); + void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); + void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); + void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); + void BroadcastDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); + void BroadcastSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL); // tolua_export a_Src coords are Block * 8 + void BroadcastSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = NULL); // tolua_export + void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = NULL); + void BroadcastTimeUpdate (const cClientHandle * a_Exclude = NULL); + virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = NULL); + + virtual cBroadcastInterface & GetBroadcastManager(void) override { return *this; } @@ -273,7 +274,7 @@ public: void RemovePlayer( cPlayer* a_Player ); /** Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true */ - virtual bool ForEachPlayer(cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << + virtual bool ForEachPlayer(cPlayerListCallback & a_Callback) override; // >> EXPORTED IN MANUALBINDINGS << /** Calls the callback for the player of the given name; returns true if the player was found and the callback called, false if player not found. Callback return ignored */ bool DoWithPlayer(const AString & a_PlayerName, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << @@ -365,7 +366,7 @@ public: bool IsChunkLighted(int a_ChunkX, int a_ChunkZ); /** Calls the callback for each chunk in the coords specified (all cords are inclusive). Returns true if all chunks have been processed successfully */ - virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback); + virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override; // tolua_begin @@ -456,7 +457,7 @@ public: // tolua_begin bool DigBlock (int a_X, int a_Y, int a_Z); - virtual void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player); + virtual void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player); // override, cannot specify due to tolua double GetSpawnX(void) const { return m_SpawnX; } double GetSpawnY(void) const { return m_SpawnY; } @@ -507,7 +508,7 @@ public: | esWitherBirth | TBD | | esPlugin | void * | */ - virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData); // tolua_export + virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData); // tolua_export // override, cannot specify due to tolua /** Calls the callback for the block entity at the specified coords; returns false if there's no block entity at those coords, true if found */ bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp @@ -703,7 +704,7 @@ public: bool IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export /** Spawns a mob of the specified type. Returns the mob's EntityID if recognized and spawned, <0 otherwise */ - virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType); // tolua_export + virtual int SpawnMob(double a_PosX, double a_PosY, double a_PosZ, cMonster::eType a_MonsterType); // tolua_export // override, cannot specify due to tolua int SpawnMobFinalize(cMonster* a_Monster); /** Creates a projectile of the specified type. Returns the projectile's EntityID if successful, <0 otherwise */ -- cgit v1.2.3 From 89027cb67510f49114b9cd99c585009465a3ef66 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 16 Mar 2014 22:00:28 +0100 Subject: Fixed double to float conversions. --- src/BlockEntities/HopperEntity.cpp | 2 +- src/ChunkMap.cpp | 91 +++++++++++++------------- src/Mobs/Monster.cpp | 10 +-- src/Simulator/IncrementalRedstoneSimulator.cpp | 2 +- 4 files changed, 53 insertions(+), 52 deletions(-) diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index af7043767..41fb9f811 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -219,7 +219,7 @@ bool cHopperEntity::MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick) Vector3f EntityPos = a_Entity->GetPosition(); Vector3f BlockPos(m_Pos.x + 0.5f, (float)m_Pos.y + 1, m_Pos.z + 0.5f); // One block above hopper, and search from center outwards - float Distance = (EntityPos - BlockPos).Length(); + double Distance = (EntityPos - BlockPos).Length(); if (Distance < 0.5) { diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 62c1ec544..60fbf39d4 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1791,57 +1791,58 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ BLOCKTYPE Block = area.GetBlockType(bx + x, by + y, bz + z); switch (Block) { - case E_BLOCK_TNT: - { - // Activate the TNT, with a random fuse between 10 to 30 game ticks - double FuseTime = (double)(10 + m_World->GetTickRandomNumber(20)) / 20; - m_World->SpawnPrimedTNT(a_BlockX + x + 0.5, a_BlockY + y + 0.5, a_BlockZ + z + 0.5, FuseTime); - area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); - a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); - break; - } - case E_BLOCK_OBSIDIAN: - case E_BLOCK_BEDROCK: - case E_BLOCK_WATER: - case E_BLOCK_LAVA: - { - // These blocks are not affected by explosions - break; - } - - case E_BLOCK_STATIONARY_WATER: - { - // Turn into simulated water: - area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_WATER); - break; - } + case E_BLOCK_TNT: + { + // Activate the TNT, with a random fuse between 10 to 30 game ticks + int FuseTime = 10 + m_World->GetTickRandomNumber(20); + m_World->SpawnPrimedTNT(a_BlockX + x + 0.5, a_BlockY + y + 0.5, a_BlockZ + z + 0.5, FuseTime); + area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); + a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); + break; + } + + case E_BLOCK_OBSIDIAN: + case E_BLOCK_BEDROCK: + case E_BLOCK_WATER: + case E_BLOCK_LAVA: + { + // These blocks are not affected by explosions + break; + } - case E_BLOCK_STATIONARY_LAVA: - { - // Turn into simulated lava: - area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_LAVA); - break; - } + case E_BLOCK_STATIONARY_WATER: + { + // Turn into simulated water: + area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_WATER); + break; + } - case E_BLOCK_AIR: - { - // No pickups for air - break; - } + case E_BLOCK_STATIONARY_LAVA: + { + // Turn into simulated lava: + area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_LAVA); + break; + } - default: - { - if (m_World->GetTickRandomNumber(100) <= 25) // 25% chance of pickups + case E_BLOCK_AIR: { - cItems Drops; - cBlockHandler * Handler = BlockHandler(Block); + // No pickups for air + break; + } - Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. - m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); + default: + { + if (m_World->GetTickRandomNumber(100) <= 25) // 25% chance of pickups + { + cItems Drops; + cBlockHandler * Handler = BlockHandler(Block); + + Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. + m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); + } + area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); + a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); } - area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); - a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); - } } // switch (BlockType) } // for z } // for y diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 6e3c91d58..16d6aed1f 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -82,11 +82,11 @@ cMonster::cMonster(const AString & a_ConfigName, eType a_MobType, const AString , m_AttackRange(2) , m_AttackInterval(0) , m_SightDistance(25) - , m_DropChanceWeapon(0.085) - , m_DropChanceHelmet(0.085) - , m_DropChanceChestplate(0.085) - , m_DropChanceLeggings(0.085) - , m_DropChanceBoots(0.085) + , m_DropChanceWeapon(0.085f) + , m_DropChanceHelmet(0.085f) + , m_DropChanceChestplate(0.085f) + , m_DropChanceLeggings(0.085f) + , m_DropChanceBoots(0.085f) , m_CanPickUpLoot(true) , m_BurnsInDaylight(false) { diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index ca2ef4b1a..6ace8ade9 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -1062,7 +1062,7 @@ void cIncrementalRedstoneSimulator::HandlePressurePlate(int a_BlockX, int a_Bloc { Vector3f EntityPos = a_Entity->GetPosition(); Vector3f BlockPos(m_X + 0.5f, (float)m_Y, m_Z + 0.5f); - float Distance = (EntityPos - BlockPos).Length(); + double Distance = (EntityPos - BlockPos).Length(); if (Distance <= 0.7) { -- cgit v1.2.3 From 0a505576e5220113dfbcc140b70659f822a17f44 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 17 Mar 2014 10:28:04 -0700 Subject: Fixed =~ bug --- lib/tolua++/src/bin/enumerate_lua.h | 2 +- lib/tolua++/src/bin/lua/enumerate.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tolua++/src/bin/enumerate_lua.h b/lib/tolua++/src/bin/enumerate_lua.h index f7285dc9a..f460f297b 100644 --- a/lib/tolua++/src/bin/enumerate_lua.h +++ b/lib/tolua++/src/bin/enumerate_lua.h @@ -113,7 +113,7 @@ static const unsigned char lua_enumerate_lua[] = { 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, - 0x20, 0x7e, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x3d, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, 0x3d, diff --git a/lib/tolua++/src/bin/lua/enumerate.lua b/lib/tolua++/src/bin/lua/enumerate.lua index 5f0dedfe1..9c534a020 100644 --- a/lib/tolua++/src/bin/lua/enumerate.lua +++ b/lib/tolua++/src/bin/lua/enumerate.lua @@ -52,7 +52,7 @@ _global_output_enums = {} -- write support code function classEnumerate:supcode () - if _global_output_enums[self.name] ~= nil then + if _global_output_enums[self.name] == nil then _global_output_enums[self.name] = 1 output("int tolua_is" .. self.name .. " (lua_State* L, int lo, int def, tolua_Error* err)") output("{") -- cgit v1.2.3 From 9447cd20f3bff89d87bda07320c5ccbb45aa7556 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 17 Mar 2014 22:12:02 +0100 Subject: Fixed a crash in firework rockets. Fixes #816. --- src/WorldStorage/FireworksSerializer.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 3c97ae0a2..744fc731f 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -20,8 +20,14 @@ void cFireworkItem::WriteToNBTCompound(const cFireworkItem & a_FireworkItem, cFa a_Writer.AddByte("Flicker", a_FireworkItem.m_HasFlicker); a_Writer.AddByte("Trail", a_FireworkItem.m_HasTrail); a_Writer.AddByte("Type", a_FireworkItem.m_Type); - a_Writer.AddIntArray("Colors", &(a_FireworkItem.m_Colours[0]), a_FireworkItem.m_Colours.size()); - a_Writer.AddIntArray("FadeColors", &(a_FireworkItem.m_FadeColours[0]), a_FireworkItem.m_FadeColours.size()); + if (!a_FireworkItem.m_Colours.empty()) + { + a_Writer.AddIntArray("Colors", &(a_FireworkItem.m_Colours[0]), a_FireworkItem.m_Colours.size()); + } + if (!a_FireworkItem.m_FadeColours.empty()) + { + a_Writer.AddIntArray("FadeColors", &(a_FireworkItem.m_FadeColours[0]), a_FireworkItem.m_FadeColours.size()); + } a_Writer.EndCompound(); a_Writer.EndList(); a_Writer.EndCompound(); -- cgit v1.2.3 From 4dc5650023c234a9e82c97c795d8c39016063c51 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 18 Mar 2014 13:54:17 +0100 Subject: Fixed cGZipFile::ReadRestOfFile returning incorrect value. --- src/OSSupport/GZipFile.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OSSupport/GZipFile.cpp b/src/OSSupport/GZipFile.cpp index cbf6be6c4..b13e519e0 100644 --- a/src/OSSupport/GZipFile.cpp +++ b/src/OSSupport/GZipFile.cpp @@ -73,12 +73,15 @@ int cGZipFile::ReadRestOfFile(AString & a_Contents) // Since the gzip format doesn't really support getting the uncompressed length, we need to read incrementally. Yuck! int NumBytesRead = 0; + int TotalBytes = 0; char Buffer[64 KiB]; while ((NumBytesRead = gzread(m_File, Buffer, sizeof(Buffer))) > 0) { + TotalBytes += NumBytesRead; a_Contents.append(Buffer, NumBytesRead); } - return NumBytesRead; + // NumBytesRead is < 0 on error + return (NumBytesRead >= 0) ? TotalBytes : NumBytesRead; } -- cgit v1.2.3 From 38aad32a8b92a0189483f0f61a42660ee31a835c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 18 Mar 2014 13:54:32 +0100 Subject: Debuggers: Using binary file mode for .schematics. --- MCServer/Plugins/Debuggers/Debuggers.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index d2c9a2a49..fe3efa306 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -217,7 +217,7 @@ function TestBlockAreasString() return end cFile:CreateFolder("schematics") - local f = io.open("schematics/StringTest.schematic", "w") + local f = io.open("schematics/StringTest.schematic", "wb") f:write(Data) f:close() @@ -230,7 +230,7 @@ function TestBlockAreasString() BA2:Clear() -- Load another area from a string in that file: - f = io.open("schematics/StringTest.schematic", "r") + f = io.open("schematics/StringTest.schematic", "rb") Data = f:read("*all") if not(BA2:LoadFromSchematicString(Data)) then LOG("Cannot load schematic from string") -- cgit v1.2.3 From 91f64da2a6895f2dee7d010e71282b0c5fb6bf02 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 18 Mar 2014 15:45:16 +0100 Subject: Fixed chunkmap tree block replacing. --- src/ChunkMap.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 60fbf39d4..ffba52d54 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1376,19 +1376,13 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) break; } case E_BLOCK_LEAVES: - { - if (itr->BlockType == E_BLOCK_LOG) - { - Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); - } - break; - } case E_BLOCK_NEW_LEAVES: { - if (itr->BlockType == E_BLOCK_NEW_LOG) + if ((itr->BlockType == E_BLOCK_LOG) || (itr->BlockType == E_BLOCK_NEW_LOG)) { Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); } + break; } } } // for itr - a_Blocks[] -- cgit v1.2.3 From 23ffaa19b7c93f076a2d5a85018f7fb1a2260ea8 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 18 Mar 2014 20:45:10 +0000 Subject: Added levels of shrapnel --- src/ChunkMap.cpp | 10 +++++++--- src/World.cpp | 4 +++- src/World.h | 12 ++++++++---- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index ab4e01334..6ce928252 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1832,13 +1832,17 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } - else if (m_World->IsTNTShrapnelEnabled() && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around + else if ((m_World->GetTNTShrapnelLevel() > 0) && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around { - if (!cBlockInfo::FullyOccupiesVoxel(area.GetBlockType(bx + x, by + y, bz + z))) + if (!cBlockInfo::FullyOccupiesVoxel(Block)) { break; } - m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, area.GetBlockType(bx + x, by + y, bz + z), area.GetBlockMeta(bx + x, by + y, bz + z)); + else if ((m_World->GetTNTShrapnelLevel() == 1) && ((Block != E_BLOCK_SAND) && (Block != E_BLOCK_GRAVEL))) + { + break; + } + m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, Block, area.GetBlockMeta(bx + x, by + y, bz + z)); } area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); diff --git a/src/World.cpp b/src/World.cpp index cf18e3a45..18109b2af 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -578,13 +578,15 @@ void cWorld::Start(void) m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", true); m_ShouldLavaSpawnFire = IniFile.GetValueSetB("Physics", "ShouldLavaSpawnFire", true); - m_bTNTSpawnsShrapnel = IniFile.GetValueSetB("Physics", "IsTNTShrapnelEnabled", true); + m_TNTShrapnelLevel = IniFile.GetValueSetI("Physics", "TNTShrapnelLevel", 2); m_bCommandBlocksEnabled = IniFile.GetValueSetB("Mechanics", "CommandBlocksEnabled", false); m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true); m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", true); m_GameMode = (eGameMode)IniFile.GetValueSetI("General", "Gamemode", m_GameMode); + if (m_TNTShrapnelLevel > 2) + m_TNTShrapnelLevel = 2; // Load allowed mobs: const char * DefaultMonsters = ""; diff --git a/src/World.h b/src/World.h index ea24c39d5..2804e8386 100644 --- a/src/World.h +++ b/src/World.h @@ -605,8 +605,8 @@ public: bool AreCommandBlocksEnabled(void) const { return m_bCommandBlocksEnabled; } void SetCommandBlocksEnabled(bool a_Flag) { m_bCommandBlocksEnabled = a_Flag; } - bool IsTNTShrapnelEnabled(void) const { return m_bTNTSpawnsShrapnel; } - void SetTNTShrapnelEnabled(bool a_Flag) { m_bTNTSpawnsShrapnel = a_Flag; } + unsigned char GetTNTShrapnelLevel(void) const { return m_TNTShrapnelLevel; } + void SetTNTShrapnelLevel(int a_Flag) { m_TNTShrapnelLevel = a_Flag; } bool ShouldUseChatPrefixes(void) const { return m_bUseChatPrefixes; } void SetShouldUseChatPrefixes(bool a_Flag) { m_bUseChatPrefixes = a_Flag; } @@ -866,8 +866,12 @@ private: /** Whether prefixes such as [INFO] are prepended to SendMessageXXX() / BroadcastChatXXX() functions */ bool m_bUseChatPrefixes; - /** Whether TNT explosions, done via cWorld::DoExplosionAt(), should project random affected blocks as FallingBlock entities */ - bool m_bTNTSpawnsShrapnel; + /** The level of DoExplosionAt() projecting random affected blocks as FallingBlock entities + 0 = None + 1 = Only sand and gravel + 2 = All blocks + */ + int m_TNTShrapnelLevel; cChunkGenerator m_Generator; -- cgit v1.2.3 From 4a67114f5654668f746f43dfa82732257571a103 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 19 Mar 2014 13:57:06 +0100 Subject: LuaChunkStay: Removed a debugging output. --- src/Bindings/LuaChunkStay.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Bindings/LuaChunkStay.cpp b/src/Bindings/LuaChunkStay.cpp index 0e982637f..db865cfa4 100644 --- a/src/Bindings/LuaChunkStay.cpp +++ b/src/Bindings/LuaChunkStay.cpp @@ -131,9 +131,6 @@ void cLuaChunkStay::Enable(cChunkMap & a_ChunkMap, int a_OnChunkAvailableStackPo void cLuaChunkStay::OnChunkAvailable(int a_ChunkX, int a_ChunkZ) { - // DEBUG: - LOGD("LuaChunkStay: Chunk [%d, %d] is now available, calling the callback...", a_ChunkX, a_ChunkZ); - cPluginLua::cOperation Op(m_Plugin); Op().Call((int)m_OnChunkAvailable, a_ChunkX, a_ChunkZ); } -- cgit v1.2.3 From 7c717fe6df582111efc0907f5535d32ce8d72786 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 19 Mar 2014 13:57:37 +0100 Subject: APIDump: Reformatted the plugin to avoid all ZBS Analyzer issues. --- MCServer/Plugins/APIDump/main_APIDump.lua | 897 ++++++++++++++---------------- 1 file changed, 429 insertions(+), 468 deletions(-) diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua index 4ed692b52..6d4a6ebc5 100644 --- a/MCServer/Plugins/APIDump/main_APIDump.lua +++ b/MCServer/Plugins/APIDump/main_APIDump.lua @@ -7,92 +7,22 @@ -- Global variables: -g_Plugin = nil; -g_PluginFolder = ""; +local g_Plugin = nil +local g_PluginFolder = "" +local g_Stats = {} +local g_TrackedPages = {} -function Initialize(Plugin) - g_Plugin = Plugin; - g_PluginFolder = Plugin:GetLocalFolder(); - - LOG("Initialising " .. Plugin:GetName() .. " v." .. Plugin:GetVersion()) - - cPluginManager:BindConsoleCommand("api", HandleCmdApi, "Dumps the Lua API docs into the API/ subfolder") - g_Plugin:AddWebTab("APIDump", HandleWebAdminDump) - -- TODO: Add a WebAdmin tab that has a Dump button - return true -end - - - - - -function HandleCmdApi(a_Split) - DumpApi() - return true -end - - - - - -function DumpApi() - LOG("Dumping the API...") - - -- Load the API descriptions from the Classes and Hooks subfolders: - -- This needs to be done each time the command is invoked because the export modifies the tables' contents - dofile(g_PluginFolder .. "/APIDesc.lua") - if (g_APIDesc.Classes == nil) then - g_APIDesc.Classes = {}; - end - if (g_APIDesc.Hooks == nil) then - g_APIDesc.Hooks = {}; - end - LoadAPIFiles("/Classes/", g_APIDesc.Classes); - LoadAPIFiles("/Hooks/", g_APIDesc.Hooks); - - -- Reset the stats: - g_TrackedPages = {}; -- List of tracked pages, to be checked later whether they exist. Each item is an array of referring pagenames. - g_Stats = -- Statistics about the documentation - { - NumTotalClasses = 0, - NumUndocumentedClasses = 0, - NumTotalFunctions = 0, - NumUndocumentedFunctions = 0, - NumTotalConstants = 0, - NumUndocumentedConstants = 0, - NumTotalVariables = 0, - NumUndocumentedVariables = 0, - NumTotalHooks = 0, - NumUndocumentedHooks = 0, - NumTrackedLinks = 0, - NumInvalidLinks = 0, - } - - -- dump all available API functions and objects: - -- DumpAPITxt(); - - -- Dump all available API object in HTML format into a subfolder: - DumpAPIHtml(); - - LOG("APIDump finished"); - return true -end - - - - - -function LoadAPIFiles(a_Folder, a_DstTable) +local function LoadAPIFiles(a_Folder, a_DstTable) assert(type(a_Folder) == "string") assert(type(a_DstTable) == "table") local Folder = g_PluginFolder .. a_Folder; - for idx, fnam in ipairs(cFile:GetFolderContents(Folder)) do + for _, fnam in ipairs(cFile:GetFolderContents(Folder)) do local FileName = Folder .. fnam; -- We only want .lua files from the folder: if (cFile:IsFile(FileName) and fnam:match(".*%.lua$")) then @@ -113,45 +43,7 @@ end -function DumpAPITxt() - LOG("Dumping all available functions to API.txt..."); - function dump (prefix, a, Output) - for i, v in pairs (a) do - if (type(v) == "table") then - if (GetChar(i, 1) ~= ".") then - if (v == _G) then - -- LOG(prefix .. i .. " == _G, CYCLE, ignoring"); - elseif (v == _G.package) then - -- LOG(prefix .. i .. " == _G.package, ignoring"); - else - dump(prefix .. i .. ".", v, Output) - end - end - elseif (type(v) == "function") then - if (string.sub(i, 1, 2) ~= "__") then - table.insert(Output, prefix .. i .. "()"); - end - end - end - end - - local Output = {}; - dump("", _G, Output); - - table.sort(Output); - local f = io.open("API.txt", "w"); - for i, n in ipairs(Output) do - f:write(n, "\n"); - end - f:close(); - LOG("API.txt written."); -end - - - - - -function CreateAPITables() +local function CreateAPITables() --[[ We want an API table of the following shape: local API = { @@ -218,7 +110,7 @@ function CreateAPITables() -- Member variables: local SetField = a_ClassObj[".set"] or {}; if ((a_ClassObj[".get"] ~= nil) and (type(a_ClassObj[".get"]) == "table")) then - for k, v in pairs(a_ClassObj[".get"]) do + for k in pairs(a_ClassObj[".get"]) do if (SetField[k] == nil) then -- It is a read-only variable, add it as a constant: table.insert(res.Constants, {Name = k, Value = ""}); @@ -259,7 +151,7 @@ local function WriteArticles(f)

The following articles provide various extra information on plugin development

    ]]); - for i, extra in ipairs(g_APIDesc.ExtraPages) do + for _, extra in ipairs(g_APIDesc.ExtraPages) do local SrcFileName = g_PluginFolder .. "/" .. extra.FileName; if (cFile:Exists(SrcFileName)) then local DstFileName = "API/" .. extra.FileName; @@ -279,20 +171,125 @@ end -local function WriteClasses(f, a_API, a_ClassMenu) - f:write([[ -

    Class index

    -

    The following classes are available in the MCServer Lua scripting language: -

      - ]]); - for i, cls in ipairs(a_API) do - f:write("
    • ", cls.Name, "
    • \n"); - WriteHtmlClass(cls, a_API, a_ClassMenu); +-- Make a link out of anything with the special linkifying syntax {{link|title}} +local function LinkifyString(a_String, a_Referrer) + assert(a_Referrer ~= nil); + assert(a_Referrer ~= ""); + + --- Adds a page to the list of tracked pages (to be checked for existence at the end) + local function AddTrackedPage(a_PageName) + local Pg = (g_TrackedPages[a_PageName] or {}); + table.insert(Pg, a_Referrer); + g_TrackedPages[a_PageName] = Pg; end - f:write([[ -

    + + --- Creates the HTML for the specified link and title + local function CreateLink(Link, Title) + if (Link:sub(1, 7) == "http://") then + -- The link is a full absolute URL, do not modify, do not track: + return "" .. Title .. ""; + end + local idxHash = Link:find("#"); + if (idxHash ~= nil) then + -- The link contains an anchor: + if (idxHash == 1) then + -- Anchor in the current page, no need to track: + return "" .. Title .. ""; + end + -- Anchor in another page: + local PageName = Link:sub(1, idxHash - 1); + AddTrackedPage(PageName); + return "" .. Title .. ""; + end + -- Link without anchor: + AddTrackedPage(Link); + return "" .. Title .. ""; + end + + -- Linkify the strings using the CreateLink() function: + local txt = a_String:gsub("{{([^|}]*)|([^}]*)}}", CreateLink) -- {{link|title}} + txt = txt:gsub("{{([^|}]*)}}", -- {{LinkAndTitle}} + function(LinkAndTitle) + local idxHash = LinkAndTitle:find("#"); + if (idxHash ~= nil) then + -- The LinkAndTitle contains a hash, remove the hashed part from the title: + return CreateLink(LinkAndTitle, LinkAndTitle:sub(1, idxHash - 1)); + end + return CreateLink(LinkAndTitle, LinkAndTitle); + end + ); + return txt; +end + + + + + +local function WriteHtmlHook(a_Hook, a_HookNav) + local fnam = "API/" .. a_Hook.DefaultFnName .. ".html"; + local f, error = io.open(fnam, "w"); + if (f == nil) then + LOG("Cannot write \"" .. fnam .. "\": \"" .. error .. "\"."); + return; + end + local HookName = a_Hook.DefaultFnName; + + f:write([[ + + MCServer API - ]], HookName, [[ Hook + + + + + + +
    +
    +

    ]], a_Hook.Name, [[


    +
    +
    + Index:
    + Articles
    + Classes
    + Hooks
    +
    + Quick navigation:
    ]]); + f:write(a_HookNav); + f:write([[ +

    + ]]); + f:write(LinkifyString(a_Hook.Desc, HookName)); + f:write("

    \n

    Callback function

    \n

    The default name for the callback function is "); + f:write(a_Hook.DefaultFnName, ". It has the following signature:\n"); + f:write("

    function ", HookName, "(");
    +	if (a_Hook.Params == nil) then
    +		a_Hook.Params = {};
    +	end
    +	for i, param in ipairs(a_Hook.Params) do
    +		if (i > 1) then
    +			f:write(", ");
    +		end
    +		f:write(param.Name);
    +	end
    +	f:write(")
    \n

    Parameters:

    \n\n"); + for _, param in ipairs(a_Hook.Params) do + f:write("\n"); + end + f:write("
    NameTypeNotes
    ", param.Name, "", LinkifyString(param.Type, HookName), "", LinkifyString(param.Notes, HookName), "
    \n

    " .. (a_Hook.Returns or "") .. "

    \n\n"); + f:write([[

    Code examples

    Registering the callback

    ]]); + f:write("
    \n");
    +	f:write([[cPluginManager:AddHook(cPluginManager.]] .. a_Hook.Name .. ", My" .. a_Hook.DefaultFnName .. [[);]]);
    +	f:write("
    \n\n"); + local Examples = a_Hook.CodeExamples or {}; + for _, example in ipairs(Examples) do + f:write("

    ", (example.Title or "missing Title"), "

    \n"); + f:write("

    ", (example.Desc or "missing Desc"), "

    \n"); + f:write("
    ", (example.Code or "missing Code"), "\n
    \n\n"); + end + f:write([[
    ]]); + f:close(); end @@ -318,7 +315,7 @@ local function WriteHooks(f, a_Hooks, a_UndocumentedHooks, a_HookNav) Called when ]]); - for i, hook in ipairs(a_Hooks) do + for _, hook in ipairs(a_Hooks) do if (hook.DefaultFnName == nil) then -- The hook is not documented yet f:write(" \n " .. hook.Name .. "\n (No documentation yet)\n \n"); @@ -338,162 +335,13 @@ end -function DumpAPIHtml() - LOG("Dumping all available functions and constants to API subfolder..."); - - -- Create the output folder - if not(cFile:IsFolder("API")) then - cFile:CreateFolder("API"); - end - - LOG("Copying static files.."); - cFile:CreateFolder("API/Static"); - local localFolder = g_Plugin:GetLocalFolder(); - for idx, fnam in ipairs(cFile:GetFolderContents(localFolder .. "/Static")) do - cFile:Delete("API/Static/" .. fnam); - cFile:Copy(localFolder .. "/Static/" .. fnam, "API/Static/" .. fnam); - end - - LOG("Creating API tables..."); - local API, Globals = CreateAPITables(); - local Hooks = {}; - local UndocumentedHooks = {}; - - -- Sort the classes by name: - LOG("Sorting..."); - table.sort(API, - function (c1, c2) - return (string.lower(c1.Name) < string.lower(c2.Name)); - end - ); - - g_Stats.NumTotalClasses = #API; - - -- Add Globals into the API: - Globals.Name = "Globals"; - table.insert(API, Globals); - - -- Extract hook constants: - for name, obj in pairs(cPluginManager) do - if ( - (type(obj) == "number") and - name:match("HOOK_.*") and - (name ~= "HOOK_MAX") and - (name ~= "HOOK_NUM_HOOKS") - ) then - table.insert(Hooks, { Name = name }); - end - end - table.sort(Hooks, - function(Hook1, Hook2) - return (Hook1.Name < Hook2.Name); - end - ); - - -- Read in the descriptions: - LOG("Reading descriptions..."); - ReadDescriptions(API); - ReadHooks(Hooks); - - -- Create a "class index" file, write each class as a link to that file, - -- then dump class contents into class-specific file - LOG("Writing HTML files..."); - local f = io.open("API/index.html", "w"); - if (f == nil) then - LOGINFO("Cannot output HTML API: " .. err); - return; - end - - -- Create a class navigation menu that will be inserted into each class file for faster navigation (#403) - local ClassMenuTab = {}; - for idx, cls in ipairs(API) do - table.insert(ClassMenuTab, ""); - table.insert(ClassMenuTab, cls.Name); - table.insert(ClassMenuTab, "
    "); - end - local ClassMenu = table.concat(ClassMenuTab, ""); - - -- Create a hook navigation menu that will be inserted into each hook file for faster navigation(#403) - local HookNavTab = {}; - for idx, hook in ipairs(Hooks) do - table.insert(HookNavTab, ""); - table.insert(HookNavTab, (hook.Name:gsub("^HOOK_", ""))); -- remove the "HOOK_" part of the name - table.insert(HookNavTab, "
    "); - end - local HookNav = table.concat(HookNavTab, ""); - - -- Write the HTML file: - f:write([[ - - - MCServer API - Index - - - -
    -
    -

    MCServer API - Index

    -
    -
    -

    The API reference is divided into the following sections:

    - -
    - ]]); - - WriteArticles(f); - WriteClasses(f, API, ClassMenu); - WriteHooks(f, Hooks, UndocumentedHooks, HookNav); - - -- Copy the static files to the output folder: - local StaticFiles = - { - "main.css", - "prettify.js", - "prettify.css", - "lang-lua.js", - }; - for idx, fnam in ipairs(StaticFiles) do - cFile:Delete("API/" .. fnam); - cFile:Copy(g_Plugin:GetLocalFolder() .. "/" .. fnam, "API/" .. fnam); - end - - -- List the documentation problems: - LOG("Listing leftovers..."); - ListUndocumentedObjects(API, UndocumentedHooks); - ListUnexportedObjects(); - ListMissingPages(); - - WriteStats(f); - - f:write([[
- - -]]); - f:close(); - - LOG("API subfolder written"); -end - - - - - -function ReadDescriptions(a_API) +local function ReadDescriptions(a_API) -- Returns true if the class of the specified name is to be ignored local function IsClassIgnored(a_ClsName) if (g_APIDesc.IgnoreClasses == nil) then return false; end - for i, name in ipairs(g_APIDesc.IgnoreClasses) do + for _, name in ipairs(g_APIDesc.IgnoreClasses) do if (a_ClsName:match(name)) then return true; end @@ -511,7 +359,7 @@ function ReadDescriptions(a_API) return false; end local FnName = a_ClassName .. "." .. a_FnName; - for i, name in ipairs(g_APIDesc.IgnoreFunctions) do + for _, name in ipairs(g_APIDesc.IgnoreFunctions) do if (FnName:match(name)) then return true; end @@ -524,7 +372,7 @@ function ReadDescriptions(a_API) if (g_APIDesc.IgnoreConstants == nil) then return false; end; - for i, name in ipairs(g_APIDesc.IgnoreConstants) do + for _, name in ipairs(g_APIDesc.IgnoreConstants) do if (a_CnName:match(name)) then return true; end @@ -537,7 +385,7 @@ function ReadDescriptions(a_API) if (g_APIDesc.IgnoreVariables == nil) then return false; end; - for i, name in ipairs(g_APIDesc.IgnoreVariables) do + for _, name in ipairs(g_APIDesc.IgnoreVariables) do if (a_VarName:match(name)) then return true; end @@ -547,7 +395,7 @@ function ReadDescriptions(a_API) -- Remove ignored classes from a_API: local APICopy = {}; - for i, cls in ipairs(a_API) do + for _, cls in ipairs(a_API) do if not(IsClassIgnored(cls.Name)) then table.insert(APICopy, cls); end @@ -557,14 +405,14 @@ function ReadDescriptions(a_API) end; -- Process the documentation for each class: - for i, cls in ipairs(a_API) do + for _, cls in ipairs(a_API) do -- Initialize default values for each class: cls.ConstantGroups = {}; cls.NumConstantsInGroups = 0; cls.NumConstantsInGroupsForDescendants = 0; -- Rename special functions: - for j, fn in ipairs(cls.Functions) do + for _, fn in ipairs(cls.Functions) do if (fn.Name == ".call") then fn.DocID = "constructor"; fn.Name = "() (constructor)"; @@ -594,7 +442,7 @@ function ReadDescriptions(a_API) -- Process inheritance: if (APIDesc.Inherits ~= nil) then - for j, icls in ipairs(a_API) do + for _, icls in ipairs(a_API) do if (icls.Name == APIDesc.Inherits) then table.insert(icls.Descendants, cls); cls.Inherits = icls; @@ -614,7 +462,7 @@ function ReadDescriptions(a_API) if (APIDesc.Functions ~= nil) then -- Assign function descriptions: - for j, func in ipairs(cls.Functions) do + for _, func in ipairs(cls.Functions) do local FnName = func.DocID or func.Name; local FnDesc = APIDesc.Functions[FnName]; if (FnDesc == nil) then @@ -630,7 +478,7 @@ function ReadDescriptions(a_API) AddFunction(func.Name, FnDesc.Params, FnDesc.Return, FnDesc.Notes); else -- Multiple function overloads - for k, desc in ipairs(FnDesc) do + for _, desc in ipairs(FnDesc) do AddFunction(func.Name, desc.Params, desc.Return, desc.Notes); end -- for k, desc - FnDesc[] end @@ -641,7 +489,7 @@ function ReadDescriptions(a_API) -- Replace functions with their described and overload-expanded versions: cls.Functions = DoxyFunctions; else -- if (APIDesc.Functions ~= nil) - for j, func in ipairs(cls.Functions) do + for _, func in ipairs(cls.Functions) do local FnName = func.DocID or func.Name; if not(IsFunctionIgnored(cls.Name, FnName)) then table.insert(cls.UndocumentedFunctions, FnName); @@ -651,7 +499,7 @@ function ReadDescriptions(a_API) if (APIDesc.Constants ~= nil) then -- Assign constant descriptions: - for j, cons in ipairs(cls.Constants) do + for _, cons in ipairs(cls.Constants) do local CnDesc = APIDesc.Constants[cons.Name]; if (CnDesc == nil) then -- Not documented @@ -664,7 +512,7 @@ function ReadDescriptions(a_API) end end -- for j, cons else -- if (APIDesc.Constants ~= nil) - for j, cons in ipairs(cls.Constants) do + for _, cons in ipairs(cls.Constants) do if not(IsConstantIgnored(cls.Name .. "." .. cons.Name)) then table.insert(cls.UndocumentedConstants, cons.Name); end @@ -673,7 +521,7 @@ function ReadDescriptions(a_API) -- Assign member variables' descriptions: if (APIDesc.Variables ~= nil) then - for j, var in ipairs(cls.Variables) do + for _, var in ipairs(cls.Variables) do local VarDesc = APIDesc.Variables[var.Name]; if (VarDesc == nil) then -- Not documented @@ -688,7 +536,7 @@ function ReadDescriptions(a_API) end end -- for j, var else -- if (APIDesc.Variables ~= nil) - for j, var in ipairs(cls.Variables) do + for _, var in ipairs(cls.Variables) do if not(IsVariableIgnored(cls.Name .. "." .. var.Name)) then table.insert(cls.UndocumentedVariables, var.Name); end @@ -706,8 +554,8 @@ function ReadDescriptions(a_API) group.Include = { group.Include }; end local NumInGroup = 0; - for idx, incl in ipairs(group.Include or {}) do - for cidx, cons in ipairs(cls.Constants) do + for _, incl in ipairs(group.Include or {}) do + for _, cons in ipairs(cls.Constants) do if ((cons.Group == nil) and cons.Name:match(incl)) then cons.Group = group; table.insert(group.Constants, cons); @@ -733,7 +581,7 @@ function ReadDescriptions(a_API) -- Remove grouped constants from the normal list: local NewConstants = {}; - for idx, cons in ipairs(cls.Constants) do + for _, cons in ipairs(cls.Constants) do if (cons.Group == nil) then table.insert(NewConstants, cons); end @@ -749,18 +597,18 @@ function ReadDescriptions(a_API) cls.UndocumentedVariables = {}; cls.Variables = cls.Variables or {}; g_Stats.NumUndocumentedClasses = g_Stats.NumUndocumentedClasses + 1; - for j, func in ipairs(cls.Functions) do + for _, func in ipairs(cls.Functions) do local FnName = func.DocID or func.Name; if not(IsFunctionIgnored(cls.Name, FnName)) then table.insert(cls.UndocumentedFunctions, FnName); end end -- for j, func - cls.Functions[] - for j, cons in ipairs(cls.Constants) do + for _, cons in ipairs(cls.Constants) do if not(IsConstantIgnored(cls.Name .. "." .. cons.Name)) then table.insert(cls.UndocumentedConstants, cons.Name); end end -- for j, cons - cls.Constants[] - for j, var in ipairs(cls.Variables) do + for _, var in ipairs(cls.Variables) do if not(IsConstantIgnored(cls.Name .. "." .. var.Name)) then table.insert(cls.UndocumentedVariables, var.Name); end @@ -769,7 +617,7 @@ function ReadDescriptions(a_API) -- Remove ignored functions: local NewFunctions = {}; - for j, fn in ipairs(cls.Functions) do + for _, fn in ipairs(cls.Functions) do if (not(IsFunctionIgnored(cls.Name, fn.Name))) then table.insert(NewFunctions, fn); end @@ -792,7 +640,7 @@ function ReadDescriptions(a_API) -- Remove ignored constants: local NewConstants = {}; - for j, cn in ipairs(cls.Constants) do + for _, cn in ipairs(cls.Constants) do if (not(IsFunctionIgnored(cls.Name, cn.Name))) then table.insert(NewConstants, cn); end @@ -808,7 +656,7 @@ function ReadDescriptions(a_API) -- Remove ignored member variables: local NewVariables = {}; - for j, var in ipairs(cls.Variables) do + for _, var in ipairs(cls.Variables) do if (not(IsVariableIgnored(cls.Name .. "." .. var.Name))) then table.insert(NewVariables, var); end @@ -824,7 +672,7 @@ function ReadDescriptions(a_API) end -- for i, cls -- Sort the descendants lists: - for i, cls in ipairs(a_API) do + for _, cls in ipairs(a_API) do table.sort(cls.Descendants, function(c1, c2) return (c1.Name < c2.Name); @@ -837,7 +685,7 @@ end -function ReadHooks(a_Hooks) +local function ReadHooks(a_Hooks) --[[ a_Hooks = { { Name = "HOOK_1"}, @@ -846,7 +694,7 @@ function ReadHooks(a_Hooks) }; We want to add hook descriptions to each hook in this array --]] - for i, hook in ipairs(a_Hooks) do + for _, hook in ipairs(a_Hooks) do local HookDesc = g_APIDesc.Hooks[hook.Name]; if (HookDesc ~= nil) then for key, val in pairs(HookDesc) do @@ -861,63 +709,10 @@ end --- Make a link out of anything with the special linkifying syntax {{link|title}} -function LinkifyString(a_String, a_Referrer) - assert(a_Referrer ~= nil); - assert(a_Referrer ~= ""); - - --- Adds a page to the list of tracked pages (to be checked for existence at the end) - local function AddTrackedPage(a_PageName) - local Pg = (g_TrackedPages[a_PageName] or {}); - table.insert(Pg, a_Referrer); - g_TrackedPages[a_PageName] = Pg; - end - - --- Creates the HTML for the specified link and title - local function CreateLink(Link, Title) - if (Link:sub(1, 7) == "http://") then - -- The link is a full absolute URL, do not modify, do not track: - return "" .. Title .. ""; - end - local idxHash = Link:find("#"); - if (idxHash ~= nil) then - -- The link contains an anchor: - if (idxHash == 1) then - -- Anchor in the current page, no need to track: - return "" .. Title .. ""; - end - -- Anchor in another page: - local PageName = Link:sub(1, idxHash - 1); - AddTrackedPage(PageName); - return "" .. Title .. ""; - end - -- Link without anchor: - AddTrackedPage(Link); - return "" .. Title .. ""; - end - - -- Linkify the strings using the CreateLink() function: - local txt = a_String:gsub("{{([^|}]*)|([^}]*)}}", CreateLink) -- {{link|title}} - txt = txt:gsub("{{([^|}]*)}}", -- {{LinkAndTitle}} - function(LinkAndTitle) - local idxHash = LinkAndTitle:find("#"); - if (idxHash ~= nil) then - -- The LinkAndTitle contains a hash, remove the hashed part from the title: - return CreateLink(LinkAndTitle, LinkAndTitle:sub(1, idxHash - 1)); - end - return CreateLink(LinkAndTitle, LinkAndTitle); - end - ); - return txt; -end - - - - - -function WriteHtmlClass(a_ClassAPI, a_AllAPI, a_ClassMenu) +local function WriteHtmlClass(a_ClassAPI, a_ClassMenu) local cf, err = io.open("API/" .. a_ClassAPI.Name .. ".html", "w"); if (cf == nil) then + LOGINFO("Cannot write HTML API for class " .. a_ClassAPI.Name .. ": " .. err) return; end @@ -931,7 +726,7 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI, a_ClassMenu) cf:write("

Functions inherited from ", a_InheritedName, "

\n"); end cf:write("\n\n"); - for i, func in ipairs(a_Functions) do + for _, func in ipairs(a_Functions) do cf:write("\n"); cf:write("\n"); cf:write("\n"); @@ -942,7 +737,7 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI, a_ClassMenu) local function WriteConstantTable(a_Constants, a_Source) cf:write("
NameParametersReturn valueNotes
", func.Name, "", LinkifyString(func.Params or "", (a_InheritedName or a_ClassAPI.Name)), "", LinkifyString(func.Return or "", (a_InheritedName or a_ClassAPI.Name)), "
\n\n"); - for i, cons in ipairs(a_Constants) do + for _, cons in ipairs(a_Constants) do cf:write("\n"); cf:write("\n"); cf:write("\n"); @@ -965,7 +760,7 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI, a_ClassMenu) WriteConstantTable(a_Constants, Source); end - for k, group in pairs(a_ConstantGroups) do + for _, group in pairs(a_ConstantGroups) do if ((a_InheritedName == nil) or group.ShowInDescendants) then cf:write("

"); cf:write(LinkifyString(group.TextBefore or "", Source)); @@ -985,7 +780,7 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI, a_ClassMenu) end cf:write("

NameValueNotes
", cons.Name, "", cons.Value, "", LinkifyString(cons.Notes or "", a_Source), "
\n"); - for i, var in ipairs(a_Variables) do + for _, var in ipairs(a_Variables) do cf:write("\n"); cf:write("\n"); cf:write("\n \n"); @@ -998,7 +793,7 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI, a_ClassMenu) return; end cf:write("
    "); - for i, desc in ipairs(a_Descendants) do + for _, desc in ipairs(a_Descendants) do cf:write("
  • ", desc.Name, ""); WriteDescendants(desc.Descendants); cf:write("
  • \n"); @@ -1049,7 +844,7 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI, a_ClassMenu) local HasConstants = (#a_ClassAPI.Constants > 0) or (a_ClassAPI.NumConstantsInGroups > 0); local HasFunctions = (#a_ClassAPI.Functions > 0); local HasVariables = (#a_ClassAPI.Variables > 0); - for idx, cls in ipairs(InheritanceChain) do + for _, cls in ipairs(InheritanceChain) do HasConstants = HasConstants or (#cls.Constants > 0) or (cls.NumConstantsInGroupsForDescendants > 0); HasFunctions = HasFunctions or (#cls.Functions > 0); HasVariables = HasVariables or (#cls.Variables > 0); @@ -1088,7 +883,7 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI, a_ClassMenu) cf:write("

    Inheritance

    \n"); if (#InheritanceChain > 0) then cf:write("

    This class inherits from the following parent classes:

      \n"); - for i, cls in ipairs(InheritanceChain) do + for _, cls in ipairs(InheritanceChain) do cf:write("
    • ", cls.Name, "
    • \n"); end cf:write("

    \n"); @@ -1105,7 +900,7 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI, a_ClassMenu) cf:write("

    Constants

    \n"); WriteConstants(a_ClassAPI.Constants, a_ClassAPI.ConstantGroups, a_ClassAPI.NumConstantsInGroups, nil); g_Stats.NumTotalConstants = g_Stats.NumTotalConstants + #a_ClassAPI.Constants + (a_ClassAPI.NumConstantsInGroups or 0); - for i, cls in ipairs(InheritanceChain) do + for _, cls in ipairs(InheritanceChain) do WriteConstants(cls.Constants, cls.ConstantGroups, cls.NumConstantsInGroupsForDescendants, cls.Name); end; end; @@ -1115,102 +910,51 @@ function WriteHtmlClass(a_ClassAPI, a_AllAPI, a_ClassMenu) cf:write("

    Member variables

    \n"); WriteVariables(a_ClassAPI.Variables, nil); g_Stats.NumTotalVariables = g_Stats.NumTotalVariables + #a_ClassAPI.Variables; - for i, cls in ipairs(InheritanceChain) do + for _, cls in ipairs(InheritanceChain) do WriteVariables(cls.Variables, cls.Name); end; end - - -- Write the functions, including the inherited ones: - if (HasFunctions) then - cf:write("

    Functions

    \n"); - WriteFunctions(a_ClassAPI.Functions, nil); - g_Stats.NumTotalFunctions = g_Stats.NumTotalFunctions + #a_ClassAPI.Functions; - for i, cls in ipairs(InheritanceChain) do - WriteFunctions(cls.Functions, cls.Name); - end - end - - -- Write the additional infos: - if (a_ClassAPI.AdditionalInfo ~= nil) then - for i, additional in ipairs(a_ClassAPI.AdditionalInfo) do - cf:write("

    ", additional.Header, "

    \n"); - cf:write(LinkifyString(additional.Contents, ClassName)); - end - end - - cf:write([[
NameTypeNotes
", var.Name, "", LinkifyString(var.Type or "(undocumented)", a_InheritedName or a_ClassAPI.Name), "", LinkifyString(var.Notes or "", a_InheritedName or a_ClassAPI.Name), "
]]); - cf:close(); -end - - - - - -function WriteHtmlHook(a_Hook, a_HookNav) - local fnam = "API/" .. a_Hook.DefaultFnName .. ".html"; - local f, error = io.open(fnam, "w"); - if (f == nil) then - LOG("Cannot write \"" .. fnam .. "\": \"" .. error .. "\"."); - return; - end - local HookName = a_Hook.DefaultFnName; - - f:write([[ - - MCServer API - ]], HookName, [[ Hook - - - - - - -
-
-

]], a_Hook.Name, [[

-
-
-
- Index:
- Articles
- Classes
- Hooks
-
- Quick navigation:
- ]]); - f:write(a_HookNav); - f:write([[ -

- ]]); - f:write(LinkifyString(a_Hook.Desc, HookName)); - f:write("

\n

Callback function

\n

The default name for the callback function is "); - f:write(a_Hook.DefaultFnName, ". It has the following signature:\n"); - f:write("

function ", HookName, "(");
-	if (a_Hook.Params == nil) then
-		a_Hook.Params = {};
-	end
-	for i, param in ipairs(a_Hook.Params) do
-		if (i > 1) then
-			f:write(", ");
+	
+	-- Write the functions, including the inherited ones:
+	if (HasFunctions) then
+		cf:write("

Functions

\n"); + WriteFunctions(a_ClassAPI.Functions, nil); + g_Stats.NumTotalFunctions = g_Stats.NumTotalFunctions + #a_ClassAPI.Functions; + for _, cls in ipairs(InheritanceChain) do + WriteFunctions(cls.Functions, cls.Name); end - f:write(param.Name); end - f:write(")
\n

Parameters:

\n\n"); - for i, param in ipairs(a_Hook.Params) do - f:write("\n"); + + -- Write the additional infos: + if (a_ClassAPI.AdditionalInfo ~= nil) then + for i, additional in ipairs(a_ClassAPI.AdditionalInfo) do + cf:write("

", additional.Header, "

\n"); + cf:write(LinkifyString(additional.Contents, ClassName)); + end end - f:write("
NameTypeNotes
", param.Name, "", LinkifyString(param.Type, HookName), "", LinkifyString(param.Notes, HookName), "
\n

" .. (a_Hook.Returns or "") .. "

\n\n"); - f:write([[

Code examples

Registering the callback

]]); - f:write("
\n");
-	f:write([[cPluginManager:AddHook(cPluginManager.]] .. a_Hook.Name .. ", My" .. a_Hook.DefaultFnName .. [[);]]);
-	f:write("
\n\n"); - local Examples = a_Hook.CodeExamples or {}; - for i, example in ipairs(Examples) do - f:write("

", (example.Title or "missing Title"), "

\n"); - f:write("

", (example.Desc or "missing Desc"), "

\n"); - f:write("
", (example.Code or "missing Code"), "\n
\n\n"); + + cf:write([[
]]); + cf:close(); +end + + + + + +local function WriteClasses(f, a_API, a_ClassMenu) + f:write([[ +

Class index

+

The following classes are available in the MCServer Lua scripting language: +

    + ]]); + for _, cls in ipairs(a_API) do + f:write("
  • ", cls.Name, "
  • \n"); + WriteHtmlClass(cls, a_ClassMenu); end - f:write([[]]); - f:close(); + f:write([[ +

+
+ ]]); end @@ -1218,12 +962,12 @@ end --- Writes a list of undocumented objects into a file -function ListUndocumentedObjects(API, UndocumentedHooks) +local function ListUndocumentedObjects(API, UndocumentedHooks) f = io.open("API/_undocumented.lua", "w"); if (f ~= nil) then f:write("\n-- This is the list of undocumented API objects, automatically generated by APIDump\n\n"); f:write("g_APIDesc =\n{\n\tClasses =\n\t{\n"); - for i, cls in ipairs(API) do + for _, cls in ipairs(API) do local HasFunctions = ((cls.UndocumentedFunctions ~= nil) and (#cls.UndocumentedFunctions > 0)); local HasConstants = ((cls.UndocumentedConstants ~= nil) and (#cls.UndocumentedConstants > 0)); local HasVariables = ((cls.UndocumentedVariables ~= nil) and (#cls.UndocumentedVariables > 0)); @@ -1240,7 +984,7 @@ function ListUndocumentedObjects(API, UndocumentedHooks) if (HasFunctions) then f:write("\t\t\tFunctions =\n\t\t\t{\n"); table.sort(cls.UndocumentedFunctions); - for j, fn in ipairs(cls.UndocumentedFunctions) do + for _, fn in ipairs(cls.UndocumentedFunctions) do f:write("\t\t\t\t" .. fn .. " = { Params = \"\", Return = \"\", Notes = \"\" },\n"); end -- for j, fn - cls.UndocumentedFunctions[] f:write("\t\t\t},\n\n"); @@ -1249,7 +993,7 @@ function ListUndocumentedObjects(API, UndocumentedHooks) if (HasConstants) then f:write("\t\t\tConstants =\n\t\t\t{\n"); table.sort(cls.UndocumentedConstants); - for j, cn in ipairs(cls.UndocumentedConstants) do + for _, cn in ipairs(cls.UndocumentedConstants) do f:write("\t\t\t\t" .. cn .. " = { Notes = \"\" },\n"); end -- for j, fn - cls.UndocumentedConstants[] f:write("\t\t\t},\n\n"); @@ -1258,7 +1002,7 @@ function ListUndocumentedObjects(API, UndocumentedHooks) if (HasVariables) then f:write("\t\t\tVariables =\n\t\t\t{\n"); table.sort(cls.UndocumentedVariables); - for j, vn in ipairs(cls.UndocumentedVariables) do + for _, vn in ipairs(cls.UndocumentedVariables) do f:write("\t\t\t\t" .. vn .. " = { Type = \"\", Notes = \"\" },\n"); end -- for j, fn - cls.UndocumentedVariables[] f:write("\t\t\t},\n\n"); @@ -1306,7 +1050,7 @@ end --- Lists the API objects that are documented but not available in the API: -function ListUnexportedObjects() +local function ListUnexportedObjects() f = io.open("API/_unexported-documented.txt", "w"); if (f ~= nil) then for clsname, cls in pairs(g_APIDesc.Classes) do @@ -1338,7 +1082,7 @@ end -function ListMissingPages() +local function ListMissingPages() local MissingPages = {}; local NumLinks = 0; for PageName, Referrers in pairs(g_TrackedPages) do @@ -1368,7 +1112,7 @@ function ListMissingPages() LOGWARNING("Cannot open _missingPages.txt for writing: '" .. err .. "'. There are " .. #MissingPages .. " pages missing."); return; end - for idx, pg in ipairs(MissingPages) do + for _, pg in ipairs(MissingPages) do f:write(pg.Name .. ":\n"); -- Sort and output the referrers: table.sort(pg.Refs); @@ -1384,7 +1128,7 @@ end --- Writes the documentation statistics (in g_Stats) into the given HTML file -function WriteStats(f) +local function WriteStats(f) local function ExportMeter(a_Percent) local Color; if (a_Percent > 99) then @@ -1453,7 +1197,198 @@ end -function HandleWebAdminDump(a_Request) +local function DumpAPIHtml(a_API) + LOG("Dumping all available functions and constants to API subfolder..."); + + -- Create the output folder + if not(cFile:IsFolder("API")) then + cFile:CreateFolder("API"); + end + + LOG("Copying static files.."); + cFile:CreateFolder("API/Static"); + local localFolder = g_Plugin:GetLocalFolder(); + for _, fnam in ipairs(cFile:GetFolderContents(localFolder .. "/Static")) do + cFile:Delete("API/Static/" .. fnam); + cFile:Copy(localFolder .. "/Static/" .. fnam, "API/Static/" .. fnam); + end + + -- Extract hook constants: + local Hooks = {}; + local UndocumentedHooks = {}; + for name, obj in pairs(cPluginManager) do + if ( + (type(obj) == "number") and + name:match("HOOK_.*") and + (name ~= "HOOK_MAX") and + (name ~= "HOOK_NUM_HOOKS") + ) then + table.insert(Hooks, { Name = name }); + end + end + table.sort(Hooks, + function(Hook1, Hook2) + return (Hook1.Name < Hook2.Name); + end + ); + + -- Read in the descriptions: + LOG("Reading descriptions..."); + ReadDescriptions(a_API); + ReadHooks(Hooks); + + -- Create a "class index" file, write each class as a link to that file, + -- then dump class contents into class-specific file + LOG("Writing HTML files..."); + local f, err = io.open("API/index.html", "w"); + if (f == nil) then + LOGINFO("Cannot output HTML API: " .. err); + return; + end + + -- Create a class navigation menu that will be inserted into each class file for faster navigation (#403) + local ClassMenuTab = {}; + for _, cls in ipairs(a_API) do + table.insert(ClassMenuTab, ""); + table.insert(ClassMenuTab, cls.Name); + table.insert(ClassMenuTab, "
"); + end + local ClassMenu = table.concat(ClassMenuTab, ""); + + -- Create a hook navigation menu that will be inserted into each hook file for faster navigation(#403) + local HookNavTab = {}; + for _, hook in ipairs(Hooks) do + table.insert(HookNavTab, ""); + table.insert(HookNavTab, (hook.Name:gsub("^HOOK_", ""))); -- remove the "HOOK_" part of the name + table.insert(HookNavTab, "
"); + end + local HookNav = table.concat(HookNavTab, ""); + + -- Write the HTML file: + f:write([[ + + + MCServer API - Index + + + +
+
+

MCServer API - Index

+
+
+

The API reference is divided into the following sections:

+ +
+ ]]); + + WriteArticles(f); + WriteClasses(f, a_API, ClassMenu); + WriteHooks(f, Hooks, UndocumentedHooks, HookNav); + + -- Copy the static files to the output folder: + local StaticFiles = + { + "main.css", + "prettify.js", + "prettify.css", + "lang-lua.js", + }; + for _, fnam in ipairs(StaticFiles) do + cFile:Delete("API/" .. fnam); + cFile:Copy(g_Plugin:GetLocalFolder() .. "/" .. fnam, "API/" .. fnam); + end + + -- List the documentation problems: + LOG("Listing leftovers..."); + ListUndocumentedObjects(a_API, UndocumentedHooks); + ListUnexportedObjects(); + ListMissingPages(); + + WriteStats(f); + + f:write([[ +
+ +]]); + f:close(); + + LOG("API subfolder written"); +end + + + + + +local function DumpApi() + LOG("Dumping the API...") + + -- Load the API descriptions from the Classes and Hooks subfolders: + -- This needs to be done each time the command is invoked because the export modifies the tables' contents + dofile(g_PluginFolder .. "/APIDesc.lua") + if (g_APIDesc.Classes == nil) then + g_APIDesc.Classes = {}; + end + if (g_APIDesc.Hooks == nil) then + g_APIDesc.Hooks = {}; + end + LoadAPIFiles("/Classes/", g_APIDesc.Classes); + LoadAPIFiles("/Hooks/", g_APIDesc.Hooks); + + -- Reset the stats: + g_TrackedPages = {}; -- List of tracked pages, to be checked later whether they exist. Each item is an array of referring pagenames. + g_Stats = -- Statistics about the documentation + { + NumTotalClasses = 0, + NumUndocumentedClasses = 0, + NumTotalFunctions = 0, + NumUndocumentedFunctions = 0, + NumTotalConstants = 0, + NumUndocumentedConstants = 0, + NumTotalVariables = 0, + NumUndocumentedVariables = 0, + NumTotalHooks = 0, + NumUndocumentedHooks = 0, + NumTrackedLinks = 0, + NumInvalidLinks = 0, + } + + -- Create the API tables: + local API, Globals = CreateAPITables(); + + -- Sort the classes by name: + table.sort(API, + function (c1, c2) + return (string.lower(c1.Name) < string.lower(c2.Name)); + end + ); + g_Stats.NumTotalClasses = #API; + + -- Add Globals into the API: + Globals.Name = "Globals"; + table.insert(API, Globals); + + -- Dump all available API object in HTML format into a subfolder: + DumpAPIHtml(API); + + LOG("APIDump finished"); + return true +end + + + + + +local function HandleWebAdminDump(a_Request) if (a_Request.PostParams["Dump"] ~= nil) then DumpApi() end @@ -1467,3 +1402,29 @@ end + +local function HandleCmdApi(a_Split) + DumpApi() + return true +end + + + + + +function Initialize(Plugin) + g_Plugin = Plugin; + g_PluginFolder = Plugin:GetLocalFolder(); + + LOG("Initialising " .. Plugin:GetName() .. " v." .. Plugin:GetVersion()) + + cPluginManager:BindConsoleCommand("api", HandleCmdApi, "Dumps the Lua API docs into the API/ subfolder") + g_Plugin:AddWebTab("APIDump", HandleWebAdminDump) + -- TODO: Add a WebAdmin tab that has a Dump button + return true +end + + + + + -- cgit v1.2.3 From e8f7c18ba75be4e62b9b0b7f55c5fe8eae1af1ec Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 19 Mar 2014 11:34:33 -0700 Subject: Fixed type error in lua bindings --- lib/tolua++/src/bin/enumerate_lua.h | 319 +++++++++++++++++----------------- lib/tolua++/src/bin/lua/enumerate.lua | 6 +- 2 files changed, 163 insertions(+), 162 deletions(-) diff --git a/lib/tolua++/src/bin/enumerate_lua.h b/lib/tolua++/src/bin/enumerate_lua.h index f460f297b..bf209519b 100644 --- a/lib/tolua++/src/bin/enumerate_lua.h +++ b/lib/tolua++/src/bin/enumerate_lua.h @@ -118,164 +118,165 @@ static const unsigned char lua_enumerate_lua[] = { 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x22, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, - 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, - 0x61, 0x6d, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, 0x28, 0x6c, 0x75, - 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x4c, 0x2c, 0x20, - 0x69, 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, - 0x64, 0x65, 0x66, 0x2c, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x20, 0x65, 0x72, 0x72, 0x29, 0x22, 0x29, - 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7b, - 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x22, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x69, 0x73, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x4c, 0x2c, 0x6c, - 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x65, 0x72, 0x72, 0x29, 0x29, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3b, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x69, 0x6e, - 0x74, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x4c, - 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x29, 0x3b, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3e, 0x3d, 0x20, - 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x69, - 0x6e, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, 0x26, 0x26, 0x20, 0x76, 0x61, - 0x6c, 0x20, 0x3c, 0x3d, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x3b, 0x22, + 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x2e, + 0x2e, 0x20, 0x22, 0x20, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x2a, 0x20, 0x4c, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6c, + 0x6f, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x66, 0x2c, 0x20, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2a, + 0x20, 0x65, 0x72, 0x72, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7b, 0x22, 0x29, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x69, 0x66, 0x20, 0x28, + 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x28, 0x4c, 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, + 0x2c, 0x65, 0x72, 0x72, 0x29, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x30, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x28, 0x4c, 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x29, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, - 0x7d, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, - 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, - 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x28, 0x74, - 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x73, - 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, - 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x29, 0x0a, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, - 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, - 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x20, 0x69, 0x66, - 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, - 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x69, 0x66, - 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x22, - 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x56, 0x61, - 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, - 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, - 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, - 0x3d, 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x09, - 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x28, 0x22, 0x56, 0x61, 0x72, - 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x73, 0x2e, - 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, - 0x6f, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3c, 0x61, 0x6e, 0x6f, - 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x3e, - 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x64, - 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, - 0x79, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x56, 0x61, 0x72, 0x69, 0x61, - 0x62, 0x6c, 0x65, 0x28, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, - 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x6e, 0x74, 0x20, - 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x0a, - 0x09, 0x20, 0x69, 0x66, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x74, 0x2e, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x2e, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x0a, 0x09, 0x09, 0x74, 0x2e, - 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x20, 0x3d, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x28, 0x29, 0x0a, 0x09, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, - 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, 0x65, 0x63, - 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, - 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x0a, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x20, 0x28, 0x6e, 0x2c, 0x62, 0x2c, 0x76, 0x61, 0x72, 0x6e, - 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x62, 0x20, 0x3d, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x62, 0x2c, - 0x20, 0x22, 0x2c, 0x5b, 0x25, 0x73, 0x5c, 0x6e, 0x5d, 0x2a, 0x7d, 0x22, - 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x7d, 0x22, 0x29, 0x20, 0x2d, 0x2d, 0x20, - 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x6c, 0x61, - 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, - 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x62, 0x2c, 0x32, 0x2c, 0x2d, - 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x65, - 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x62, 0x72, 0x61, - 0x63, 0x65, 0x73, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, - 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, - 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x69, - 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x77, 0x68, - 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x74, 0x20, 0x3d, - 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, - 0x27, 0x3d, 0x27, 0x29, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x69, 0x73, - 0x63, 0x61, 0x72, 0x64, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, - 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x2e, 0x6e, - 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, - 0x09, 0x65, 0x5b, 0x65, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x74, - 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, - 0x3d, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x74, - 0x74, 0x5b, 0x32, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, - 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x74, 0x5b, 0x32, - 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, 0x09, - 0x65, 0x6e, 0x64, 0x20, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x2b, - 0x20, 0x31, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, - 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x69, - 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3e, 0x20, 0x6d, 0x61, - 0x78, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x61, - 0x78, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x0a, 0x09, 0x09, - 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, - 0x32, 0x5d, 0x20, 0x3c, 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x74, - 0x74, 0x5b, 0x32, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, - 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6c, 0x75, - 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x0a, 0x09, 0x69, 0x20, 0x20, - 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x65, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, - 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, - 0x29, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x65, 0x5b, 0x69, - 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x65, - 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x40, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x65, - 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, - 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x5b, 0x32, 0x5d, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x5b, 0x32, - 0x5d, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x72, 0x65, 0x6e, - 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x2e, 0x6c, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x5b, - 0x32, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, - 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x5b, 0x20, 0x6e, 0x73, 0x2e, 0x2e, 0x65, 0x5b, 0x69, 0x5d, - 0x20, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x6e, 0x73, 0x2e, 0x2e, 0x65, 0x5b, - 0x69, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, - 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x0a, 0x09, 0x65, 0x2e, 0x6d, 0x69, - 0x6e, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x0a, 0x09, 0x65, 0x2e, 0x6d, - 0x61, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x0a, 0x09, 0x69, 0x66, - 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x09, 0x09, 0x54, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, - 0x22, 0x69, 0x6e, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x29, 0x0a, 0x09, - 0x09, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x5b, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x6e, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, - 0x65, 0x2c, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, - 0x65, 0x6e, 0x64, 0x0a, 0x0a + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3e, + 0x3d, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6d, 0x69, 0x6e, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x2e, 0x30, 0x20, 0x26, + 0x26, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3c, 0x3d, 0x20, 0x22, 0x20, 0x2e, + 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x2e, 0x2e, + 0x20, 0x22, 0x2e, 0x30, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7d, 0x22, 0x29, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x20, 0x28, 0x74, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x29, 0x0a, + 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x74, + 0x29, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x09, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x22, + 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, + 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x63, + 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x28, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x28, 0x22, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x22, 0x2e, 0x2e, 0x6e, 0x73, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3c, 0x61, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, + 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x3e, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, + 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x22, 0x29, 0x0a, 0x09, 0x09, + 0x09, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x22, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, + 0x79, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x2e, 0x63, 0x75, 0x72, 0x72, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x5f, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x0a, 0x09, 0x09, 0x74, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x3a, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x28, 0x29, 0x0a, 0x09, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, + 0x20, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, + 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, + 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x62, 0x6f, 0x64, + 0x79, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, + 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x28, 0x6e, 0x2c, + 0x62, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, + 0x62, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x62, 0x2c, 0x20, 0x22, 0x2c, 0x5b, 0x25, 0x73, + 0x5c, 0x6e, 0x5d, 0x2a, 0x7d, 0x22, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x7d, + 0x22, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, + 0x61, 0x74, 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, + 0x28, 0x62, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, + 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x65, 0x20, 0x62, 0x72, 0x61, 0x63, 0x65, 0x73, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x6e, + 0x3d, 0x30, 0x7d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x3d, + 0x20, 0x30, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, + 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x74, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, + 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x20, + 0x2d, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x20, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x0a, 0x09, 0x09, 0x65, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x6e, + 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x65, 0x5b, 0x65, 0x2e, 0x6e, + 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, + 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x28, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, + 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x20, 0x0a, 0x20, + 0x20, 0x09, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x74, + 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x2d, 0x20, + 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, + 0x5d, 0x20, 0x3e, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x74, + 0x5b, 0x32, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, + 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3c, 0x20, 0x6d, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6d, + 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x0a, 0x09, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, + 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, + 0x73, 0x65, 0x74, 0x20, 0x6c, 0x75, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x0a, 0x09, 0x69, 0x20, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x65, + 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, + 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x20, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, + 0x70, 0x6c, 0x69, 0x74, 0x28, 0x65, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x40, + 0x27, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, + 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x61, 0x70, + 0x70, 0x6c, 0x79, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x28, + 0x74, 0x5b, 0x31, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, + 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x6f, 0x72, 0x20, + 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x20, 0x6e, 0x73, + 0x2e, 0x2e, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x5d, 0x20, 0x3d, 0x20, 0x28, + 0x6e, 0x73, 0x2e, 0x2e, 0x65, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x09, 0x09, + 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, + 0x0a, 0x09, 0x65, 0x2e, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6d, 0x69, + 0x6e, 0x0a, 0x09, 0x65, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x6d, + 0x61, 0x78, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, + 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x54, 0x79, + 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x22, 0x69, 0x6e, 0x74, 0x20, 0x22, + 0x2e, 0x2e, 0x6e, 0x29, 0x0a, 0x09, 0x09, 0x5f, 0x69, 0x73, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x6e, 0x5d, 0x20, + 0x3d, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, + 0x20, 0x2e, 0x2e, 0x20, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x65, 0x2c, 0x20, 0x76, 0x61, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a }; -unsigned int lua_enumerate_lua_len = 3329; +unsigned int lua_enumerate_lua_len = 3347; diff --git a/lib/tolua++/src/bin/lua/enumerate.lua b/lib/tolua++/src/bin/lua/enumerate.lua index 9c534a020..a00b434aa 100644 --- a/lib/tolua++/src/bin/lua/enumerate.lua +++ b/lib/tolua++/src/bin/lua/enumerate.lua @@ -54,11 +54,11 @@ _global_output_enums = {} function classEnumerate:supcode () if _global_output_enums[self.name] == nil then _global_output_enums[self.name] = 1 - output("int tolua_is" .. self.name .. " (lua_State* L, int lo, int def, tolua_Error* err)") + output("lua_Number tolua_is" .. self.name .. " (lua_State* L, int lo, int def, tolua_Error* err)") output("{") output("if (!tolua_isnumber(L,lo,def,err)) return 0;") - output("int val = tolua_tonumber(L,lo,def);") - output("return val >= " .. self.min .. " && val <= " ..self.max .. ";") + output("lua_Number val = tolua_tonumber(L,lo,def);") + output("return val >= " .. self.min .. ".0 && val <= " ..self.max .. ".0;") output("}") end end -- cgit v1.2.3 From 04adca34106a83e7ccd8d3e6107e16d79595ba6d Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 19 Mar 2014 12:02:26 -0700 Subject: Fixed tolua emitting isnumber insteand of is --- lib/tolua++/src/bin/basic_lua.h | 882 +++++++++++++++++----------------- lib/tolua++/src/bin/enumerate_lua.h | 21 +- lib/tolua++/src/bin/lua/basic.lua | 6 +- lib/tolua++/src/bin/lua/enumerate.lua | 2 +- 4 files changed, 462 insertions(+), 449 deletions(-) diff --git a/lib/tolua++/src/bin/basic_lua.h b/lib/tolua++/src/bin/basic_lua.h index 107d1a953..32536af6a 100644 --- a/lib/tolua++/src/bin/basic_lua.h +++ b/lib/tolua++/src/bin/basic_lua.h @@ -289,458 +289,466 @@ static const unsigned char lua_basic_lua[] = { 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x2c, 0x74, 0x20, 0x3d, - 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, - 0x66, 0x28, 0x27, 0x27, 0x2c, 0x20, 0x74, 0x29, 0x0a, 0x20, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x5f, 0x62, 0x61, 0x73, - 0x69, 0x63, 0x5b, 0x74, 0x5d, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x62, 0x2c, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x63, - 0x74, 0x79, 0x70, 0x65, 0x5b, 0x62, 0x5d, 0x0a, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, - 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, 0x6c, - 0x69, 0x74, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, - 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x6c, - 0x69, 0x74, 0x20, 0x28, 0x73, 0x2c, 0x74, 0x29, 0x0a, 0x20, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, - 0x7d, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, - 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x73, - 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x2e, - 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, - 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x22, - 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x22, 0x2e, - 0x2e, 0x74, 0x2e, 0x2e, 0x22, 0x25, 0x73, 0x2a, 0x22, 0x0a, 0x20, 0x73, - 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x5e, - 0x25, 0x73, 0x2b, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, - 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x25, 0x73, - 0x2b, 0x24, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, 0x3d, - 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x70, 0x2c, 0x66, 0x29, - 0x0a, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x2e, 0x6e, 0x20, - 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, 0x6e, 0x5d, 0x20, - 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x28, 0x25, - 0x73, 0x25, 0x73, 0x2a, 0x29, 0x24, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x0a, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x73, - 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, - 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, - 0x6e, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x69, - 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, - 0x61, 0x6c, 0x20, 0x63, 0x61, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, - 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x28, 0x74, 0x65, 0x6d, 0x70, - 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x29, 0x0a, 0x2d, 0x2d, 0x20, - 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x27, - 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x27, 0x5e, 0x27, 0x20, 0x28, 0x61, 0x73, 0x20, 0x75, 0x73, - 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, - 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, - 0x69, 0x6e, 0x65, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6c, 0x73, 0x6f, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x77, 0x68, 0x69, 0x74, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x20, 0x70, 0x61, - 0x74, 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x69, 0x73, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, + 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x2c, 0x74, 0x20, + 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, + 0x65, 0x66, 0x28, 0x27, 0x27, 0x2c, 0x20, 0x74, 0x29, 0x0a, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x5f, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x5b, 0x74, 0x5d, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x62, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x62, 0x2c, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, + 0x63, 0x74, 0x79, 0x70, 0x65, 0x5b, 0x62, 0x5d, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, + 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x20, 0x28, 0x73, 0x2c, 0x74, 0x29, 0x0a, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, + 0x30, 0x7d, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, + 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x73, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, + 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x6c, 0x5b, 0x6c, + 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x0a, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x20, 0x3d, 0x20, + 0x22, 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x22, + 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x22, 0x25, 0x73, 0x2a, 0x22, 0x0a, 0x20, + 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, + 0x5e, 0x25, 0x73, 0x2b, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x73, + 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x25, + 0x73, 0x2b, 0x24, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, + 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x70, 0x2c, 0x66, + 0x29, 0x0a, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x2e, 0x6e, + 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, 0x6e, 0x5d, + 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x28, + 0x25, 0x73, 0x25, 0x73, 0x2a, 0x29, 0x24, 0x22, 0x2c, 0x22, 0x22, 0x29, + 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, + 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, + 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, + 0x72, 0x6e, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, + 0x69, 0x61, 0x6c, 0x20, 0x63, 0x61, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x28, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x29, 0x0a, 0x2d, 0x2d, + 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x63, 0x61, 0x6e, + 0x27, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x27, 0x5e, 0x27, 0x20, 0x28, 0x61, 0x73, 0x20, 0x75, + 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, + 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x6c, 0x69, 0x6e, 0x65, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6c, 0x73, + 0x6f, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x77, 0x68, 0x69, + 0x74, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x20, 0x70, + 0x61, 0x74, 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, + 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, + 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x62, + 0x65, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x65, 0x6e, + 0x64, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x6e, + 0x3d, 0x30, 0x7d, 0x0a, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x28, 0x6f, 0x66, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x2c, 0x20, 0x6f, 0x66, + 0x73, 0x29, 0x0a, 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, - 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, - 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x62, 0x65, - 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x65, 0x6e, 0x64, - 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, - 0x30, 0x7d, 0x0a, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x61, 0x64, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, - 0x6f, 0x66, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x2c, 0x20, 0x6f, 0x66, 0x73, - 0x29, 0x0a, 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, - 0x5e, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, - 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, - 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, - 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x20, - 0x2b, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x5b, 0x72, 0x65, - 0x74, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x6f, 0x66, - 0x73, 0x20, 0x3c, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x6c, 0x65, 0x6e, 0x28, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x0a, 0x09, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x75, 0x62, 0x20, 0x3d, + 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x25, 0x73, + 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x6e, + 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x5b, 0x72, + 0x65, 0x74, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x6f, + 0x66, 0x73, 0x20, 0x3c, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x6c, 0x65, 0x6e, 0x28, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x75, 0x62, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, + 0x28, 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x2c, 0x20, 0x2d, 0x31, 0x29, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, + 0x6e, 0x64, 0x28, 0x73, 0x75, 0x62, 0x2c, 0x20, 0x22, 0x5e, 0x22, 0x2e, + 0x2e, 0x70, 0x61, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x62, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x61, 0x64, 0x64, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, 0x2d, 0x31, + 0x29, 0x0a, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, + 0x66, 0x73, 0x2b, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6f, 0x66, + 0x73, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, - 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x2c, 0x20, 0x2d, 0x31, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x20, - 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, - 0x64, 0x28, 0x73, 0x75, 0x62, 0x2c, 0x20, 0x22, 0x5e, 0x22, 0x2e, 0x2e, - 0x70, 0x61, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, 0x2d, 0x31, 0x29, - 0x0a, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, - 0x73, 0x2b, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, - 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x20, - 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, - 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x29, 0x0a, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, - 0x3d, 0x20, 0x22, 0x28, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x61, - 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x3c, 0x22, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, - 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x28, - 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x20, 0x3d, 0x20, 0x22, 0x5e, 0x25, 0x62, 0x28, 0x29, 0x22, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x68, + 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x29, + 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, + 0x3d, 0x3d, 0x20, 0x22, 0x28, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x3c, 0x22, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x22, - 0x5e, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x09, 0x09, 0x09, 0x09, 0x62, 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x75, - 0x62, 0x2c, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x29, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2d, 0x2d, 0x20, - 0x75, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, - 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3f, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, 0x31, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, - 0x20, 0x2b, 0x20, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, + 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x69, 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, + 0x28, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x20, 0x3d, 0x20, 0x22, 0x5e, 0x25, 0x62, 0x28, 0x29, 0x22, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x3c, 0x22, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x3d, 0x20, + 0x22, 0x5e, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x09, 0x62, 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, + 0x75, 0x62, 0x2c, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x29, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2d, 0x2d, + 0x20, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, + 0x64, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, - 0x31, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x61, 0x64, - 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, 0x29, - 0x0a, 0x09, 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x6e, - 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, - 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x3d, 0x31, 0x0a, - 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x5b, 0x31, 0x5d, 0x20, 0x3d, - 0x20, 0x22, 0x22, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x0a, - 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, - 0x63, 0x61, 0x74, 0x65, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x20, 0x28, 0x74, 0x2c, 0x66, - 0x2c, 0x6c, 0x2c, 0x6a, 0x73, 0x74, 0x72, 0x29, 0x0a, 0x09, 0x6a, 0x73, - 0x74, 0x72, 0x20, 0x3d, 0x20, 0x6a, 0x73, 0x74, 0x72, 0x20, 0x6f, 0x72, - 0x20, 0x22, 0x20, 0x22, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x73, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x69, 0x3d, 0x66, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, - 0x20, 0x69, 0x3c, 0x3d, 0x6c, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x73, - 0x20, 0x3d, 0x20, 0x73, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x20, - 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x69, - 0x66, 0x20, 0x69, 0x20, 0x3c, 0x3d, 0x20, 0x6c, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x2e, 0x2e, 0x6a, 0x73, 0x74, - 0x72, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x0a, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x65, - 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x66, 0x6f, 0x6c, - 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x20, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x0a, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x20, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x20, - 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, - 0x3c, 0x3d, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, - 0x64, 0x28, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x2c, 0x27, 0x5b, 0x25, 0x28, - 0x2c, 0x22, 0x5d, 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, - 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x5e, 0x5b, 0x25, 0x61, 0x5f, - 0x7e, 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, - 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x69, - 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x27, 0x20, 0x27, 0x0a, 0x20, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, - 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x61, 0x72, 0x67, - 0x5b, 0x69, 0x5d, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x72, 0x67, - 0x5b, 0x69, 0x5d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, - 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x72, 0x67, - 0x5b, 0x69, 0x5d, 0x2c, 0x2d, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x0a, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, - 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, + 0x31, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, + 0x73, 0x20, 0x2b, 0x20, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, + 0x2b, 0x31, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x61, + 0x64, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, + 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x72, 0x65, 0x74, 0x2e, + 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x3d, 0x31, + 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x5b, 0x31, 0x5d, 0x20, + 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, + 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x6f, + 0x6e, 0x63, 0x61, 0x74, 0x65, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x20, 0x28, 0x74, 0x2c, + 0x66, 0x2c, 0x6c, 0x2c, 0x6a, 0x73, 0x74, 0x72, 0x29, 0x0a, 0x09, 0x6a, + 0x73, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x6a, 0x73, 0x74, 0x72, 0x20, 0x6f, + 0x72, 0x20, 0x22, 0x20, 0x22, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x73, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x66, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, + 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x6c, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, + 0x73, 0x20, 0x3d, 0x20, 0x73, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, + 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x69, 0x20, 0x3c, 0x3d, 0x20, 0x6c, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x2e, 0x2e, 0x6a, 0x73, + 0x74, 0x72, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x65, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x66, 0x6f, + 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x20, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, + 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x69, 0x3c, 0x3d, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, + 0x6e, 0x64, 0x28, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x2c, 0x27, 0x5b, 0x25, + 0x28, 0x2c, 0x22, 0x5d, 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x5e, 0x5b, 0x25, 0x61, + 0x5f, 0x7e, 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x27, 0x20, 0x27, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x3d, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x61, 0x72, + 0x67, 0x5b, 0x69, 0x5d, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x72, + 0x67, 0x5b, 0x69, 0x5d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x72, + 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x2d, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, + 0x5b, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x5d, 0x2c, 0x22, 0x5b, 0x25, 0x2f, + 0x25, 0x29, 0x25, 0x3b, 0x25, 0x7b, 0x25, 0x7d, 0x5d, 0x24, 0x22, 0x29, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x27, 0x5c, 0x6e, + 0x27, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x28, 0x2e, 0x2e, 0x2e, + 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, + 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x61, + 0x72, 0x67, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x2c, 0x27, 0x5b, 0x25, 0x28, 0x2c, 0x22, 0x5d, + 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, - 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x5d, 0x2c, 0x22, 0x5b, 0x25, 0x2f, 0x25, - 0x29, 0x25, 0x3b, 0x25, 0x7b, 0x25, 0x7d, 0x5d, 0x24, 0x22, 0x29, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, - 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x27, 0x5c, 0x6e, 0x27, - 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x6c, 0x69, - 0x6e, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x28, 0x2e, 0x2e, 0x2e, 0x29, - 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, - 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x61, 0x72, - 0x67, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, - 0x74, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x2c, 0x27, 0x5b, 0x25, 0x28, 0x2c, 0x22, 0x5d, 0x27, - 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, - 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, - 0x5d, 0x2c, 0x22, 0x5e, 0x5b, 0x25, 0x61, 0x5f, 0x7e, 0x5d, 0x22, 0x29, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, 0x77, - 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, - 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, - 0x20, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x20, 0x7e, 0x3d, 0x20, 0x27, - 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, - 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x2d, 0x31, 0x2c, 0x2d, - 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, - 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, - 0x61, 0x72, 0x67, 0x5b, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x5d, 0x2c, 0x22, - 0x5b, 0x25, 0x2f, 0x25, 0x29, 0x25, 0x3b, 0x25, 0x7b, 0x25, 0x7d, 0x5d, - 0x24, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x77, 0x72, 0x69, - 0x74, 0x65, 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, - 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, - 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, - 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, - 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, - 0x6f, 0x6b, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x6e, 0x61, 0x6d, - 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x69, 0x5d, 0x2c, 0x22, 0x5e, 0x5b, 0x25, 0x61, 0x5f, 0x7e, 0x5d, 0x22, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, 0x20, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x20, 0x7e, 0x3d, 0x20, + 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x2d, 0x31, 0x2c, + 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, + 0x28, 0x61, 0x72, 0x67, 0x5b, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x5d, 0x2c, + 0x22, 0x5b, 0x25, 0x2f, 0x25, 0x29, 0x25, 0x3b, 0x25, 0x7b, 0x25, 0x7d, + 0x5d, 0x24, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, - 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, - 0x3d, 0x3d, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x22, 0x67, 0x65, 0x74, 0x5f, 0x22, 0x2e, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x2c, 0x20, 0x22, 0x73, 0x65, 0x74, 0x5f, 0x22, 0x2e, 0x2e, 0x6e, - 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, - 0x66, 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, - 0x71, 0x74, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, - 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, - 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x73, 0x65, 0x74, 0x22, 0x2e, 0x2e, - 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x75, 0x70, 0x70, 0x65, 0x72, - 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, - 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x29, 0x29, - 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, - 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x2d, 0x31, - 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, - 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x76, - 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x20, 0x2d, 0x2d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x6e, 0x61, + 0x73, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x67, 0x65, 0x74, 0x5f, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, + 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x6e, 0x61, + 0x6d, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x74, 0x79, 0x70, + 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x67, 0x65, + 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x22, 0x67, 0x65, 0x74, 0x5f, 0x22, 0x2e, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x73, 0x65, 0x74, 0x5f, 0x22, 0x2e, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, + 0x22, 0x71, 0x74, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x0a, 0x0a, 0x2d, - 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x72, 0x69, 0x67, - 0x68, 0x74, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x24, 0x5b, 0x69, 0x63, 0x68, 0x6c, 0x5d, 0x66, 0x69, 0x6c, 0x65, 0x20, - 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2c, 0x0a, - 0x2d, 0x2d, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x62, 0x65, 0x66, - 0x6f, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x73, 0x65, 0x74, 0x22, 0x2e, + 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x75, 0x70, 0x70, 0x65, + 0x72, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, + 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x29, + 0x29, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, + 0x62, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x2d, + 0x31, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, + 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x6f, + 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x24, 0x5b, 0x69, 0x63, 0x68, 0x6c, 0x5d, 0x66, 0x69, 0x6c, 0x65, + 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2c, + 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, + 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x61, + 0x67, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x68, + 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x70, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, + 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x70, 0x6b, 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x24, 0x69, 0x66, 0x69, + 0x6c, 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x61, 0x20, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x64, 0x20, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x27, 0x20, 0x69, 0x6e, + 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, + 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x61, 0x6e, 0x79, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x70, + 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x24, 0x69, 0x66, + 0x69, 0x6c, 0x65, 0x2e, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, + 0x74, 0x2c, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, + 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, - 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, - 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, - 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, - 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x68, 0x6f, - 0x6f, 0x6b, 0x28, 0x70, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x70, 0x2e, - 0x63, 0x6f, 0x64, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x6c, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x63, - 0x6f, 0x64, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x70, 0x6b, 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, - 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, - 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x24, 0x69, 0x66, 0x69, 0x6c, - 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x0a, - 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, - 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, - 0x64, 0x20, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x27, 0x20, 0x69, 0x6e, 0x73, - 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, - 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, - 0x6e, 0x79, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, 0x61, 0x72, 0x67, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x61, - 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x24, 0x69, 0x66, 0x69, - 0x6c, 0x65, 0x2e, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x74, 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, + 0x6f, 0x64, 0x65, 0x20, 0x28, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x27, 0x24, + 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x27, 0x2c, 0x20, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, + 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x70, 0x61, + 0x72, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, + 0x74, 0x75, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x0a, 0x2d, + 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x6f, 0x6e, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x27, 0x20, 0x6b, + 0x65, 0x79, 0x2e, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x74, - 0x2c, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, - 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, - 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, - 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x20, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x74, - 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, - 0x64, 0x65, 0x20, 0x28, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x27, 0x24, 0x72, - 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x27, 0x2c, 0x20, 0x63, 0x6f, - 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x29, - 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, - 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x74, - 0x75, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x0a, 0x2d, 0x2d, - 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x50, - 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x27, 0x20, 0x6b, 0x65, - 0x79, 0x2e, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x73, 0x65, - 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, - 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, - 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, - 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, - 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, - 0x72, 0x20, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6c, - 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, + 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, - 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, + 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x20, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, + 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, + 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x27, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, + 0x73, 0x27, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x20, 0x74, 0x6f, + 0x20, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x20, 0x61, 0x20, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x0a, 0x2d, 0x2d, 0x20, + 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, + 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, - 0x6f, 0x6d, 0x20, 0x27, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, - 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, - 0x27, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, - 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x20, 0x61, 0x20, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x0a, 0x2d, 0x2d, 0x20, 0x61, - 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, - 0x69, 0x74, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x72, 0x6f, 0x70, - 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, - 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x6f, 0x6d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x64, 0x6f, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x20, 0x6f, 0x72, + 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, + 0x72, 0x73, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x29, + 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, + 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x70, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, + 0x6b, 0x28, 0x66, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, - 0x6d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x64, 0x6f, 0x70, 0x61, 0x72, 0x73, 0x65, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x70, - 0x61, 0x72, 0x73, 0x65, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x20, 0x6f, 0x72, 0x20, - 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, - 0x73, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x29, 0x0a, - 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, + 0x6d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x2c, + 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, + 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x66, 0x29, 0x0a, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, + 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, + 0x65, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, + 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x68, 0x6f, + 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, - 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, - 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x62, 0x65, 0x66, 0x6f, - 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, - 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, - 0x72, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, - 0x28, 0x66, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, - 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, - 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, - 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, - 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, - 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x66, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, - 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, - 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x5f, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x6f, - 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, - 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, - 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x2e, 0x2e, 0x2e, - 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, - 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, - 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x70, 0x75, 0x73, 0x68, - 0x65, 0x72, 0x73, 0x0a, 0x0a, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, - 0x7d, 0x0a, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, 0x6f, - 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, - 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, - 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, - 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, - 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, - 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, - 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, - 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x65, 0x73, 0x5b, 0x74, 0x5d, 0x0a, 0x0a, 0x09, 0x77, 0x68, - 0x69, 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x64, 0x6f, - 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, - 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x65, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x62, - 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, - 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, - 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, - 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x75, 0x73, 0x65, 0x72, 0x74, - 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, - 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, - 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x74, - 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, + 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x2e, 0x2e, + 0x2e, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x70, 0x75, 0x73, + 0x68, 0x65, 0x72, 0x73, 0x0a, 0x0a, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, + 0x7b, 0x7d, 0x0a, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x65, + 0x6e, 0x75, 0x6d, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, + 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, + 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, + 0x65, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, + 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, + 0x74, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x29, 0x0a, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, + 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, 0x74, 0x5d, 0x0a, 0x0a, 0x09, 0x77, + 0x68, 0x69, 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x64, + 0x6f, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, + 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, + 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, + 0x62, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x70, 0x75, 0x73, 0x68, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, + 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, + 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, + 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x75, 0x73, 0x65, 0x72, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, + 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, + 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, + 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x65, 0x6e, + 0x75, 0x6d, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x5f, 0x69, + 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, - 0x73, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x73, 0x65, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, - 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, - 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x69, 0x73, 0x5f, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, - 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, - 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, - 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, - 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x0a, 0x65, 0x6e, 0x64, 0x0a + 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, + 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a }; -unsigned int lua_basic_lua_len = 8909; +unsigned int lua_basic_lua_len = 9007; diff --git a/lib/tolua++/src/bin/enumerate_lua.h b/lib/tolua++/src/bin/enumerate_lua.h index bf209519b..db5c1bf3f 100644 --- a/lib/tolua++/src/bin/enumerate_lua.h +++ b/lib/tolua++/src/bin/enumerate_lua.h @@ -269,14 +269,15 @@ static const unsigned char lua_enumerate_lua[] = { 0x0a, 0x09, 0x65, 0x2e, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x0a, 0x09, 0x65, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, - 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x54, 0x79, - 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x22, 0x69, 0x6e, 0x74, 0x20, 0x22, - 0x2e, 0x2e, 0x6e, 0x29, 0x0a, 0x09, 0x09, 0x5f, 0x69, 0x73, 0x5f, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x6e, 0x5d, 0x20, - 0x3d, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, - 0x20, 0x2e, 0x2e, 0x20, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x65, 0x2c, 0x20, 0x76, 0x61, 0x72, - 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a + 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x5f, 0x65, + 0x6e, 0x75, 0x6d, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x22, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, + 0x20, 0x6e, 0x29, 0x0a, 0x09, 0x09, 0x54, 0x79, 0x70, 0x65, 0x64, 0x65, + 0x66, 0x28, 0x22, 0x69, 0x6e, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x28, 0x65, 0x2c, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a }; -unsigned int lua_enumerate_lua_len = 3347; +unsigned int lua_enumerate_lua_len = 3354; diff --git a/lib/tolua++/src/bin/lua/basic.lua b/lib/tolua++/src/bin/lua/basic.lua index f651f1fe6..d195f6dec 100644 --- a/lib/tolua++/src/bin/lua/basic.lua +++ b/lib/tolua++/src/bin/lua/basic.lua @@ -148,6 +148,9 @@ end -- check if basic type function isbasic (type) local t = gsub(type,'const ','') + if _enum_is_functions[t] then + return nil + end local m,t = applytypedef('', t) local b = _basic[t] if b then @@ -382,6 +385,7 @@ end _push_functions = {} _is_functions = {} +_enum_is_functions = {} _to_functions = {} _base_push_functions = {} @@ -410,5 +414,5 @@ function get_to_function(t) end function get_is_function(t) - return _is_functions[t] or search_base(t, _base_is_functions) or "tolua_isusertype" + return _enum_is_functions[t] or _is_functions[t] or search_base(t, _base_is_functions) or "tolua_isusertype" end diff --git a/lib/tolua++/src/bin/lua/enumerate.lua b/lib/tolua++/src/bin/lua/enumerate.lua index a00b434aa..d5d4426cf 100644 --- a/lib/tolua++/src/bin/lua/enumerate.lua +++ b/lib/tolua++/src/bin/lua/enumerate.lua @@ -130,8 +130,8 @@ function Enumerate (n,b,varname) e.min = min e.max = max if n ~= "" then + _enum_is_functions[n] = ("tolua_is" .. n) Typedef("int "..n) - _is_functions[n] = "tolua_is" .. n end return _Enumerate(e, varname) end -- cgit v1.2.3 From 363c92ed534d5cffe164079359b62a0768bc0f80 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 19 Mar 2014 12:06:12 -0700 Subject: Added unreachable lines backit prtected by preprocessor guards --- src/Defines.h | 4 ++++ src/Scoreboard.cpp | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/Defines.h b/src/Defines.h index 7f7a2eeb1..1a8b3fa4a 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -290,6 +290,10 @@ inline AString BlockFaceToString(eBlockFace a_BlockFace) case BLOCK_FACE_ZP: return "BLOCK_FACE_ZP"; case BLOCK_FACE_NONE: return "BLOCK_FACE_NONE"; } + // clang optimisises this line away then warns that it has done so. + #if !defined(__clang__) + return Printf("Unknown BLOCK_FACE: %d", a_BlockFace); + #endif } diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index cfeb1d619..4c89ce265 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -30,7 +30,13 @@ AString cObjective::TypeToString(eType a_Type) case otStatBlockMine: return "stat.mineBlock"; case otStatEntityKill: return "stat.killEntity"; case otStatEntityKilledBy: return "stat.entityKilledBy"; + + // clang optimisises this line away then warns that it has done so. + #if !defined(__clang__) + default: return ""; + #endif } + } -- cgit v1.2.3 From 6a3fe7adcc2a3855a574dbfc2bb79c86e7539f26 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 19 Mar 2014 12:38:00 -0700 Subject: Fixed bugs in patched tolua output --- lib/tolua++/CMakeLists.txt | 6 +- lib/tolua++/src/bin/basic_lua.h | 36 +- lib/tolua++/src/bin/declaration_lua.h | 1264 +++++++++++++++++++ lib/tolua++/src/bin/enumerate_lua.h | 338 ++--- lib/tolua++/src/bin/function_lua.h | 2056 ++++++++++++++++--------------- lib/tolua++/src/bin/lua/basic.lua | 15 +- lib/tolua++/src/bin/lua/declaration.lua | 2 + lib/tolua++/src/bin/lua/enumerate.lua | 8 +- lib/tolua++/src/bin/lua/function.lua | 10 + lib/tolua++/src/bin/toluabind.c | 1007 +-------------- 10 files changed, 2531 insertions(+), 2211 deletions(-) create mode 100644 lib/tolua++/src/bin/declaration_lua.h diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 095fc152e..75a301a53 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -20,7 +20,11 @@ if(UNIX) COMMAND xxd -i lua/function.lua | sed 's/unsigned char/static const unsigned char/g' >function_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/function.lua) - set_property(SOURCE src/bin/toluabind.c APPEND PROPERTY OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h) + add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/declaration_lua.h + COMMAND xxd -i lua/declaration.lua | sed 's/unsigned char/static const unsigned char/g' >declaration_lua.h + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ + DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/declaration.lua) + set_property(SOURCE src/bin/toluabind.c APPEND PROPERTY OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h ${PROJECT_SOURCE_DIR}/src/bin/declaration_lua.h) message(hello) endif() diff --git a/lib/tolua++/src/bin/basic_lua.h b/lib/tolua++/src/bin/basic_lua.h index 32536af6a..d4b816a2c 100644 --- a/lib/tolua++/src/bin/basic_lua.h +++ b/lib/tolua++/src/bin/basic_lua.h @@ -282,17 +282,18 @@ static const unsigned char lua_basic_lua[] = { 0x65, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, - 0x69, 0x66, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, - 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, - 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, - 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, - 0x20, 0x69, 0x66, 0x20, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x69, 0x73, - 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, - 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x69, 0x73, 0x20, 0x65, 0x6e, 0x75, + 0x6d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x73, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x20, 0x69, 0x66, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x28, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, + 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x2c, 0x74, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x27, 0x27, 0x2c, 0x20, 0x74, 0x29, 0x0a, 0x20, 0x6c, @@ -690,8 +691,7 @@ static const unsigned char lua_basic_lua[] = { 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x65, - 0x6e, 0x75, 0x6d, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, + 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, @@ -740,9 +740,11 @@ static const unsigned char lua_basic_lua[] = { 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, - 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x65, 0x6e, - 0x75, 0x6d, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x5f, 0x69, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, + 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, @@ -751,4 +753,4 @@ static const unsigned char lua_basic_lua[] = { 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a }; -unsigned int lua_basic_lua_len = 9007; +unsigned int lua_basic_lua_len = 9031; diff --git a/lib/tolua++/src/bin/declaration_lua.h b/lib/tolua++/src/bin/declaration_lua.h new file mode 100644 index 000000000..0e3486604 --- /dev/null +++ b/lib/tolua++/src/bin/declaration_lua.h @@ -0,0 +1,1264 @@ +static const unsigned char lua_declaration_lua[] = { + 0x2d, 0x2d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x57, 0x72, 0x69, 0x74, 0x74, + 0x65, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x57, 0x61, 0x6c, 0x64, 0x65, 0x6d, + 0x61, 0x72, 0x20, 0x43, 0x65, 0x6c, 0x65, 0x73, 0x0a, 0x2d, 0x2d, 0x20, + 0x54, 0x65, 0x43, 0x47, 0x72, 0x61, 0x66, 0x2f, 0x50, 0x55, 0x43, 0x2d, + 0x52, 0x69, 0x6f, 0x0a, 0x2d, 0x2d, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x31, + 0x39, 0x39, 0x38, 0x0a, 0x2d, 0x2d, 0x20, 0x24, 0x49, 0x64, 0x3a, 0x20, + 0x24, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, + 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, + 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x3b, 0x20, 0x79, 0x6f, + 0x75, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x65, 0x64, 0x69, 0x73, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, + 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x20, + 0x69, 0x74, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, + 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6e, 0x64, + 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x20, + 0x22, 0x61, 0x73, 0x20, 0x69, 0x73, 0x22, 0x20, 0x62, 0x61, 0x73, 0x69, + 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, + 0x20, 0x6e, 0x6f, 0x20, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, + 0x65, 0x2c, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x2c, 0x20, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, + 0x65, 0x6e, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, + 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x3a, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x20, 0x3d, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x20, + 0x70, 0x74, 0x72, 0x20, 0x20, 0x3d, 0x20, 0x22, 0x2a, 0x22, 0x20, 0x6f, + 0x72, 0x20, 0x22, 0x26, 0x22, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x72, 0x65, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, + 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x6f, 0x72, 0x20, + 0x61, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x0a, + 0x2d, 0x2d, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x64, 0x69, 0x6d, 0x20, + 0x20, 0x3d, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x2c, 0x20, 0x69, 0x66, 0x20, 0x61, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x20, 0x64, 0x65, 0x66, 0x20, 0x20, 0x3d, + 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x28, + 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x20, 0x20, 0x3d, 0x20, 0x22, 0x2a, 0x22, 0x20, 0x6f, + 0x72, 0x20, 0x22, 0x26, 0x22, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x28, 0x6f, + 0x6e, 0x6c, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x2c, 0x0a, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x2c, 0x0a, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x27, + 0x2c, 0x0a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x27, + 0x2c, 0x0a, 0x20, 0x64, 0x69, 0x6d, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x2c, + 0x0a, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x2c, 0x0a, + 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x7d, 0x0a, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x73, 0x65, 0x74, 0x6d, + 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x29, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, + 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x28, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x20, 0x3d, 0x20, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x76, 0x61, 0x72, + 0x5f, 0x22, 0x2e, 0x2e, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, + 0x68, 0x65, 0x63, 0x6b, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x2d, 0x2d, + 0x20, 0x49, 0x74, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x73, 0x20, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x28, + 0x29, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x31, 0x2c, 0x31, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x5b, 0x27, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x69, 0x6e, 0x64, + 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, + 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x5b, + 0x6d, 0x2e, 0x6e, 0x5d, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x28, 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x3d, 0x27, + 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x3d, 0x3d, 0x32, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x31, 0x5d, + 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x5f, + 0x76, 0x61, 0x72, 0x28, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x29, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x62, 0x2c, 0x65, 0x2c, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x2c, 0x22, 0x25, 0x5b, 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x5d, + 0x22, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x31, 0x2c, 0x62, + 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x69, 0x6d, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x65, 0x6e, + 0x75, 0x6d, 0x5f, 0x76, 0x61, 0x72, 0x28, 0x64, 0x29, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x76, + 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6b, 0x69, + 0x6e, 0x64, 0x3d, 0x3d, 0x27, 0x76, 0x61, 0x72, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x7e, + 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, + 0x66, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x20, 0x27, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x5f, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x63, 0x68, 0x61, 0x72, + 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x27, 0x63, 0x68, 0x61, 0x72, 0x2a, 0x27, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x76, 0x61, 0x72, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x22, 0x3a, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x3f, 0x3f, 0x3f, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x53, + 0x75, 0x62, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x73, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x27, 0x73, 0x2e, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x29, + 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, + 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, + 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x74, 0x6f, + 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6b, 0x69, 0x6e, 0x64, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x3d, 0x3d, 0x27, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x5f, 0x75, + 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x27, 0x0a, 0x20, 0x09, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x22, 0x22, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x74, 0x72, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x0a, + 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, + 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x73, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, + 0x69, 0x73, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x74, 0x6f, 0x20, + 0x62, 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, + 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x72, 0x65, 0x74, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, + 0x27, 0x23, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x63, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x27, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2a, 0x27, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, + 0x74, 0x61, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x76, 0x6f, + 0x69, 0x64, 0x2a, 0x27, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x5f, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x63, 0x68, 0x61, 0x72, 0x2a, + 0x27, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x5f, 0x6c, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x2a, 0x27, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x20, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x73, + 0x6f, 0x6c, 0x76, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x0a, 0x2d, 0x2d, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x66, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x73, 0x65, 0x74, 0x20, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x72, 0x65, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x2d, + 0x2d, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x20, 0x27, 0x30, 0x27, 0x0a, 0x2d, 0x2d, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x2d, 0x2d, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x62, 0x2c, 0x5f, 0x2c, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x79, + 0x70, 0x65, 0x2c, 0x20, 0x22, 0x28, 0x25, 0x62, 0x3c, 0x3e, 0x29, 0x22, + 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x0a, 0x09, 0x09, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x6d, 0x2c, + 0x20, 0x32, 0x2c, 0x20, 0x2d, 0x32, 0x29, 0x2c, 0x20, 0x22, 0x2c, 0x22, + 0x29, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, + 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x6e, 0x28, + 0x6d, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x5b, 0x69, + 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x6d, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x25, 0x73, + 0x2a, 0x28, 0x5b, 0x25, 0x2a, 0x26, 0x5d, 0x29, 0x22, 0x2c, 0x20, 0x22, + 0x25, 0x31, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x6d, + 0x5b, 0x69, 0x5d, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x65, + 0x6e, 0x75, 0x6d, 0x28, 0x6d, 0x5b, 0x69, 0x5d, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x20, 0x5f, 0x2c, 0x20, 0x6d, 0x5b, 0x69, 0x5d, 0x20, 0x3d, + 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, + 0x66, 0x28, 0x22, 0x22, 0x2c, 0x20, 0x6d, 0x5b, 0x69, 0x5d, 0x29, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6d, 0x5b, 0x69, 0x5d, + 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x6d, 0x5b, 0x69, 0x5d, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x5b, 0x69, + 0x5d, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6d, 0x5b, 0x69, 0x5d, 0x20, 0x3d, + 0x20, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5f, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x28, + 0x6d, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x69, 0x0a, 0x09, 0x09, 0x74, 0x79, + 0x70, 0x65, 0x2c, 0x62, 0x2c, 0x69, 0x20, 0x3d, 0x20, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x28, 0x22, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x22, 0x2c, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, + 0x20, 0x31, 0x2c, 0x20, 0x6d, 0x2e, 0x6e, 0x29, 0x29, 0x0a, 0x09, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x22, 0x3c, + 0x22, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, + 0x20, 0x31, 0x2c, 0x20, 0x6d, 0x2e, 0x6e, 0x2c, 0x20, 0x22, 0x2c, 0x22, + 0x29, 0x2e, 0x2e, 0x22, 0x3e, 0x22, 0x0a, 0x09, 0x09, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x74, 0x79, 0x70, + 0x65, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, + 0x22, 0x3e, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x3e, 0x20, 0x3e, 0x22, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, + 0x73, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, + 0x65, 0x2c, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, + 0x20, 0x22, 0x28, 0x25, 0x62, 0x3c, 0x3e, 0x29, 0x22, 0x29, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, + 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x2c, 0x20, 0x62, + 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x0a, 0x09, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x73, 0x2c, 0x20, + 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x0a, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x62, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x73, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x62, 0x2d, 0x31, + 0x29, 0x2e, 0x2e, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x2e, 0x2e, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, + 0x62, 0x2c, 0x20, 0x2d, 0x31, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2c, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, + 0x6d, 0x6f, 0x64, 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2e, 0x2e, 0x22, 0x27, 0x2c, + 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, + 0x2e, 0x22, 0x20, 0x70, 0x74, 0x72, 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2e, 0x2e, + 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, + 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x64, 0x69, 0x6d, 0x20, 0x20, 0x3d, + 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, + 0x6d, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, + 0x20, 0x64, 0x65, 0x66, 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x22, 0x27, + 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x72, 0x65, 0x74, 0x20, + 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, + 0x2e, 0x22, 0x7d, 0x22, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, + 0x6f, 0x66, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x61, 0x72, + 0x65, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x4c, 0x75, 0x61, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x09, 0x20, + 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, + 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x3a, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, 0x25, 0x73, + 0x2a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, 0x2c, 0x22, + 0x22, 0x29, 0x0a, 0x09, 0x09, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, + 0x20, 0x3d, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x63, + 0x6c, 0x65, 0x61, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x74, 0x61, 0x67, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x64, 0x65, 0x63, 0x6c, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x28, 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x76, 0x61, 0x72, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x27, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, + 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2a, 0x27, 0x2c, 0x27, + 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, + 0x67, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x6f, 0x75, 0x74, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x66, 0x0a, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x64, 0x65, 0x66, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x31, + 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x64, 0x65, 0x66, + 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x2d, + 0x2d, 0x69, 0x66, 0x20, 0x74, 0x3d, 0x3d, 0x27, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x2d, 0x2d, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x69, 0x73, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, + 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, 0x09, + 0x2d, 0x2d, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x27, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, + 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, + 0x27, 0x2c, 0x30, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, + 0x72, 0x72, 0x29, 0x27, 0x0a, 0x20, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x27, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x27, 0x2e, + 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, + 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, 0x6e, + 0x75, 0x6d, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x27, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x69, 0x73, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, + 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, + 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x20, + 0x6f, 0x72, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x28, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x6e, 0x69, 0x6c, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x26, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x20, 0x7c, + 0x7c, 0x20, 0x21, 0x27, 0x2e, 0x2e, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, + 0x22, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, + 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, + 0x72, 0x72, 0x29, 0x29, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x21, 0x27, + 0x2e, 0x2e, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2e, 0x2e, 0x27, + 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, + 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x22, 0x27, 0x2e, 0x2e, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, + 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, + 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, + 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x63, 0x70, 0x6c, 0x75, 0x73, + 0x70, 0x6c, 0x75, 0x73, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, + 0x6e, 0x69, 0x6c, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x27, + 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x6f, 0x64, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x63, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x25, 0x73, 0x2b, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x27, 0x2c, 0x27, 0x27, 0x29, + 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6d, 0x6f, + 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x73, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x7e, + 0x3d, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, + 0x20, 0x27, 0x2a, 0x27, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x22, 0x20, + 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x74, + 0x79, 0x70, 0x65, 0x2c, 0x70, 0x74, 0x72, 0x29, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, + 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, + 0x65, 0x2c, 0x27, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, + 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, + 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x7e, + 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, + 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, + 0x2c, 0x27, 0x5b, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, + 0x6d, 0x2c, 0x27, 0x5d, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, 0x70, 0x6c, 0x75, 0x73, + 0x70, 0x6c, 0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, + 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, + 0x27, 0x20, 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, + 0x65, 0x77, 0x5f, 0x64, 0x69, 0x6d, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, + 0x65, 0x2c, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x2c, 0x20, 0x27, 0x2e, 0x2e, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2e, 0x2e, 0x27, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, + 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, + 0x27, 0x20, 0x3d, 0x20, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x70, 0x74, 0x72, 0x2c, 0x27, 0x2a, 0x29, 0x27, 0x2c, 0x0a, 0x09, 0x09, + 0x27, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x28, 0x28, 0x27, 0x2c, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2c, 0x27, 0x29, 0x2a, 0x73, + 0x69, 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x69, 0x6e, + 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x20, 0x3d, + 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, + 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x20, 0x27, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x20, 0x20, 0x09, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x22, 0x74, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x6f, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x29, 0x2e, 0x2e, 0x22, + 0x2c, 0x20, 0x70, 0x74, 0x72, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, 0x2e, + 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x70, 0x74, 0x72, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x09, 0x69, + 0x66, 0x20, 0x74, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x74, 0x20, 0x3d, + 0x20, 0x27, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x27, 0x0a, + 0x20, 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x74, 0x72, + 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x2a, + 0x27, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x28, 0x28, 0x27, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x69, 0x6e, + 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x2a, 0x27, + 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x29, 0x20, 0x27, + 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, + 0x28, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, + 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, + 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x28, 0x69, 0x6e, 0x74, 0x29, 0x20, 0x27, + 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x65, 0x66, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x70, 0x74, 0x72, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, + 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x64, 0x65, 0x66, + 0x20, 0x3d, 0x20, 0x22, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, + 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x29, 0x22, 0x2e, 0x2e, 0x64, 0x65, 0x66, + 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, + 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, + 0x2c, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x27, 0x2e, + 0x2e, 0x74, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x27, 0x2c, + 0x64, 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, + 0x65, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x74, + 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, + 0x2c, 0x27, 0x2c, 0x27, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, + 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x28, 0x6e, 0x61, 0x72, + 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, 0x6e, 0x69, + 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, + 0x5f, 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x64, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x61, 0x72, 0x67, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x29, 0x0a, 0x09, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6c, + 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x29, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, + 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, 0x6c, + 0x64, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, + 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x67, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, 0x6e, + 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x7b, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, + 0x4c, 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x64, 0x65, 0x66, 0x3b, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x64, 0x65, 0x66, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x64, 0x65, 0x66, 0x3d, 0x31, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x64, 0x65, 0x66, 0x3d, 0x30, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, + 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x27, 0x2e, 0x2e, 0x74, + 0x2e, 0x2e, 0x27, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, + 0x27, 0x2c, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, + 0x2c, 0x27, 0x2c, 0x27, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x27, 0x2c, 0x26, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x29, 0x27, + 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x61, 0x72, + 0x72, 0x61, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x22, 0x27, 0x2c, + 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x22, 0x2c, 0x27, 0x2c, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2c, 0x27, 0x2c, 0x27, 0x2c, 0x64, + 0x65, 0x66, 0x2c, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x65, 0x72, 0x72, 0x29, 0x29, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x20, 0x20, 0x20, 0x67, 0x6f, 0x74, 0x6f, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3b, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, + 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7b, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x3b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x20, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x3d, 0x30, 0x3b, 0x20, 0x69, + 0x3c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, + 0x2e, 0x2e, 0x27, 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, + 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x74, 0x72, + 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x7e, 0x3d, 0x27, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, + 0x2a, 0x27, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x5b, 0x69, + 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x74, + 0x72, 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x2a, 0x27, 0x29, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x28, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x29, 0x20, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, + 0x65, 0x66, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x7e, 0x3d, 0x20, + 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, + 0x67, 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x27, 0x2c, 0x64, 0x65, + 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, + 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, + 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x27, 0x2c, + 0x64, 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7d, 0x27, + 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x73, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, 0x6e, + 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x20, 0x7b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x69, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x3d, 0x30, + 0x3b, 0x20, 0x69, 0x3c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x64, 0x69, 0x6d, 0x2e, 0x2e, 0x27, 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, + 0x63, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, + 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, + 0x27, 0x29, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x27, 0x5b, 0x69, 0x5d, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x7b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, + 0x5f, 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, + 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, + 0x20, 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, + 0x77, 0x28, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, + 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x27, 0x5b, 0x69, 0x5d, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, + 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, + 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x6b, 0x65, + 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x28, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, + 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6c, + 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, + 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x63, 0x6f, 0x70, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, 0x27, 0x2c, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x5b, 0x69, + 0x5d, 0x2c, 0x73, 0x69, 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, + 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, + 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, + 0x2c, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, + 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, + 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, + 0x29, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x27, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x79, 0x70, + 0x65, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7d, 0x27, + 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20, 0x64, 0x79, 0x6e, 0x61, + 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x66, 0x72, 0x65, 0x65, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, + 0x28, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, 0x6e, 0x69, + 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, + 0x5f, 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x6d, 0x28, 0x27, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x66, 0x72, 0x65, 0x65, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, + 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x50, 0x61, 0x73, + 0x73, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x61, 0x72, 0x20, 0x28, 0x29, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, + 0x72, 0x3d, 0x3d, 0x27, 0x26, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x2a, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, 0x3d, 0x3d, 0x27, 0x2a, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x26, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x52, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x72, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x28, 0x29, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, + 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x63, 0x74, + 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x7e, 0x3d, + 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x27, 0x2e, 0x2e, 0x74, + 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x75, 0x73, 0x68, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, + 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, + 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x2c, + 0x22, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x30, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x0a, + 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x20, 0x74, + 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x28, + 0x29, 0x0a, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6e, 0x61, + 0x6d, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, + 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x20, 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x75, + 0x6d, 0x28, 0x66, 0x74, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, + 0x65, 0x64, 0x65, 0x66, 0x28, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, + 0x66, 0x74, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x74, 0x2e, 0x6b, 0x69, 0x6e, 0x64, 0x3d, 0x3d, 0x22, 0x76, + 0x61, 0x72, 0x22, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x2e, 0x6d, + 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x25, 0x73, 0x22, 0x29, 0x20, + 0x6f, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, + 0x6e, 0x64, 0x28, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x24, 0x22, 0x29, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x09, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x6d, + 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x22, 0x2c, 0x20, 0x22, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x5f, 0x5f, 0x22, 0x2e, 0x2e, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x29, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6b, 0x69, 0x6e, + 0x64, 0x20, 0x6f, 0x66, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, + 0x22, 0x76, 0x61, 0x72, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x66, 0x75, + 0x6e, 0x63, 0x22, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x73, 0x2c, 0x6b, 0x69, 0x6e, 0x64, 0x2c, 0x69, 0x73, + 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x29, 0x0a, + 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x20, 0x69, 0x66, + 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x64, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x73, 0x2c, 0x22, 0x25, 0x73, 0x2a, 0x3d, 0x25, 0x73, 0x2a, 0x22, + 0x2c, 0x22, 0x3d, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x3c, + 0x22, 0x2c, 0x20, 0x22, 0x3c, 0x22, 0x29, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x66, 0x62, 0x2c, 0x74, 0x6d, 0x70, + 0x64, 0x65, 0x66, 0x0a, 0x20, 0x64, 0x65, 0x66, 0x62, 0x2c, 0x5f, 0x2c, + 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, + 0x22, 0x28, 0x3d, 0x2e, 0x2a, 0x29, 0x24, 0x22, 0x29, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x64, 0x65, 0x66, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x3d, 0x2e, + 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x20, 0x09, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x76, + 0x61, 0x72, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x2d, + 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x6f, 0x72, 0x20, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, + 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x2c, 0x20, 0x6b, 0x69, + 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x2c, 0x20, 0x69, + 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, + 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x7d, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, + 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x26, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x2a, 0x25, + 0x73, 0x2a, 0x26, 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, + 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, + 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, + 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, + 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, + 0x70, 0x64, 0x65, 0x66, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, + 0x20, 0x3d, 0x20, 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, 0x74, + 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x5b, 0x6d, + 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, + 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, + 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, + 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, + 0x3a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x2a, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, + 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x2a, 0x25, 0x73, 0x2a, 0x25, 0x2a, + 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x20, 0x3d, + 0x3d, 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x66, + 0x75, 0x6e, 0x63, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, 0x69, 0x6e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x29, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, + 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, + 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, + 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, + 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, + 0x66, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, + 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x20, + 0x3d, 0x20, 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x2d, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, + 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, + 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, + 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, + 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x73, 0x5f, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, + 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x20, + 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x6d, + 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x26, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x0a, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, + 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, + 0x27, 0x26, 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, + 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, + 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, + 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, + 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, + 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x32, + 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, + 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, + 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, + 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, + 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, + 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x7d, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x2a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x73, 0x31, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x73, 0x2c, 0x22, 0x28, 0x25, 0x62, 0x5c, 0x5b, 0x5c, 0x5d, 0x29, + 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x6e, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x6e, 0x2c, 0x27, 0x25, 0x2a, 0x27, 0x2c, 0x27, 0x5c, + 0x31, 0x27, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x29, 0x0a, 0x20, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x31, 0x2c, 0x27, 0x25, 0x2a, 0x27, + 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x3d, + 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x74, 0x5b, + 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, + 0x32, 0x5d, 0x2c, 0x27, 0x5c, 0x31, 0x27, 0x2c, 0x27, 0x25, 0x2a, 0x27, + 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x20, 0x2a, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, + 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, + 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, + 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, + 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, + 0x66, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, + 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, + 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, + 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, + 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, + 0x31, 0x29, 0x20, 0x20, 0x20, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x73, + 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x3d, + 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, + 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x61, 0x72, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, + 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, + 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, + 0x73, 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x5b, 0x74, + 0x2e, 0x6e, 0x5d, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x76, 0x20, + 0x3d, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, + 0x76, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x3b, 0x20, + 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x2e, 0x6e, 0x2d, 0x31, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, + 0x20, 0x76, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, + 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x28, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x2c, + 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, + 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, + 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, + 0x2c, 0x31, 0x2c, 0x74, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, + 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x7d, 0x0a, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, + 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x66, 0x75, 0x6e, + 0x63, 0x22, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, + 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x20, 0x3d, 0x20, 0x73, + 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, + 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x28, 0x73, 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x20, 0x3d, 0x20, 0x74, 0x5b, + 0x74, 0x2e, 0x6e, 0x5d, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x6c, 0x61, 0x73, + 0x74, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x70, 0x2c, 0x6d, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, + 0x2e, 0x6e, 0x3e, 0x31, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x74, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x2d, + 0x31, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x64, 0x20, 0x3d, 0x20, 0x63, + 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, 0x2c, 0x31, 0x2c, 0x74, 0x2e, + 0x6e, 0x2d, 0x32, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x74, 0x70, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x74, 0x70, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, + 0x74, 0x70, 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, + 0x6c, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x20, 0x76, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x70, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x6d, 0x64, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, + 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a +}; +unsigned int lua_declaration_lua_len = 15132; diff --git a/lib/tolua++/src/bin/enumerate_lua.h b/lib/tolua++/src/bin/enumerate_lua.h index db5c1bf3f..cd5bdda83 100644 --- a/lib/tolua++/src/bin/enumerate_lua.h +++ b/lib/tolua++/src/bin/enumerate_lua.h @@ -103,6 +103,20 @@ static const unsigned char lua_enumerate_lua[] = { 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x7d, 0x22, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x6d, + 0x69, 0x74, 0x65, 0x6e, 0x75, 0x6d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x69, 0x6e, 0x74, 0x20, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, 0x3a, 0x3a, 0x22, 0x2c, 0x22, 0x5f, + 0x22, 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, 0x28, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x4c, 0x2c, 0x20, 0x69, + 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x20, + 0x65, 0x72, 0x72, 0x29, 0x3b, 0x22, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, @@ -118,166 +132,166 @@ static const unsigned char lua_enumerate_lua[] = { 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, - 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x2e, - 0x2e, 0x20, 0x22, 0x20, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x2a, 0x20, 0x4c, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6c, - 0x6f, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x66, 0x2c, 0x20, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2a, - 0x20, 0x65, 0x72, 0x72, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7b, 0x22, 0x29, 0x0a, 0x09, 0x09, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x69, 0x66, 0x20, 0x28, - 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x6e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x28, 0x4c, 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, - 0x2c, 0x65, 0x72, 0x72, 0x29, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x30, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x4e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x28, 0x4c, 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x29, 0x3b, 0x22, - 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3e, - 0x3d, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x6d, 0x69, 0x6e, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x2e, 0x30, 0x20, 0x26, - 0x26, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3c, 0x3d, 0x20, 0x22, 0x20, 0x2e, - 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x2e, 0x2e, - 0x20, 0x22, 0x2e, 0x30, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7d, 0x22, 0x29, 0x0a, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, - 0x61, 0x74, 0x65, 0x20, 0x28, 0x74, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x29, 0x0a, - 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, - 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x74, - 0x29, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x09, 0x09, 0x09, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, - 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x22, - 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, - 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x63, - 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x28, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, - 0x67, 0x28, 0x22, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, - 0x22, 0x2e, 0x2e, 0x6e, 0x73, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x3c, 0x61, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, - 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x3e, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, - 0x63, 0x6c, 0x61, 0x72, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, - 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x22, 0x29, 0x0a, 0x09, 0x09, - 0x09, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x22, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, - 0x79, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x72, - 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x2e, 0x63, 0x75, 0x72, 0x72, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x09, 0x74, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x5f, - 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x0a, 0x09, 0x09, 0x74, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x3a, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x28, 0x29, 0x0a, 0x09, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, - 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, - 0x20, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, - 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, - 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x62, 0x6f, 0x64, - 0x79, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, - 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x28, 0x6e, 0x2c, - 0x62, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, - 0x62, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, - 0x73, 0x75, 0x62, 0x28, 0x62, 0x2c, 0x20, 0x22, 0x2c, 0x5b, 0x25, 0x73, - 0x5c, 0x6e, 0x5d, 0x2a, 0x7d, 0x22, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x7d, - 0x22, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, - 0x61, 0x74, 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, - 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, - 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, - 0x28, 0x62, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, - 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, - 0x74, 0x65, 0x20, 0x62, 0x72, 0x61, 0x63, 0x65, 0x73, 0x0a, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x6e, - 0x3d, 0x30, 0x7d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x3d, - 0x20, 0x30, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, - 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x74, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, - 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x20, - 0x2d, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x20, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x0a, 0x09, 0x09, 0x65, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x6e, - 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x65, 0x5b, 0x65, 0x2e, 0x6e, - 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, - 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x28, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x29, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, - 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x09, 0x09, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x20, 0x0a, 0x20, - 0x20, 0x09, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x74, - 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x2d, 0x20, - 0x61, 0x64, 0x76, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, - 0x5d, 0x20, 0x3e, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x74, - 0x5b, 0x32, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, - 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3c, 0x20, 0x6d, - 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6d, - 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x0a, 0x09, - 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, - 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, - 0x73, 0x65, 0x74, 0x20, 0x6c, 0x75, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x0a, 0x09, 0x69, 0x20, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x65, - 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, - 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, - 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x77, 0x68, 0x69, - 0x6c, 0x65, 0x20, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, - 0x70, 0x6c, 0x69, 0x74, 0x28, 0x65, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x40, - 0x27, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, - 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, - 0x74, 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x61, 0x70, - 0x70, 0x6c, 0x79, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x28, - 0x74, 0x5b, 0x31, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x65, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, - 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x6f, 0x72, 0x20, - 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x20, 0x6e, 0x73, - 0x2e, 0x2e, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x5d, 0x20, 0x3d, 0x20, 0x28, - 0x6e, 0x73, 0x2e, 0x2e, 0x65, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x09, 0x09, - 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, - 0x0a, 0x09, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, - 0x0a, 0x09, 0x65, 0x2e, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6d, 0x69, - 0x6e, 0x0a, 0x09, 0x65, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x6d, - 0x61, 0x78, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, - 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x5f, 0x65, - 0x6e, 0x75, 0x6d, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x22, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, - 0x20, 0x6e, 0x29, 0x0a, 0x09, 0x09, 0x54, 0x79, 0x70, 0x65, 0x64, 0x65, - 0x66, 0x28, 0x22, 0x69, 0x6e, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x29, - 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x28, 0x65, 0x2c, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, - 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a + 0x22, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, + 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x3a, 0x3a, 0x22, 0x2c, 0x22, 0x5f, 0x22, + 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, 0x28, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x4c, 0x2c, 0x20, 0x69, 0x6e, + 0x74, 0x20, 0x6c, 0x6f, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x20, 0x69, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x20, 0x65, + 0x72, 0x72, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x22, 0x7b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x28, 0x4c, 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x65, + 0x72, 0x72, 0x29, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x30, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x4c, + 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x29, 0x3b, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3e, 0x3d, 0x20, + 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x69, + 0x6e, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x2e, 0x30, 0x20, 0x26, 0x26, 0x20, + 0x76, 0x61, 0x6c, 0x20, 0x3c, 0x3d, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x2e, 0x2e, 0x20, 0x22, + 0x2e, 0x30, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x22, 0x7d, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x20, 0x28, 0x74, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x29, 0x0a, 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, + 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x29, 0x0a, 0x20, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x74, 0x29, 0x0a, + 0x09, 0x20, 0x69, 0x66, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x22, 0x2e, 0x2e, + 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, 0x72, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x29, + 0x0a, 0x09, 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x28, + 0x22, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x22, 0x2e, + 0x2e, 0x6e, 0x73, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x2e, 0x2e, 0x22, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3c, 0x61, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x65, + 0x6e, 0x75, 0x6d, 0x3e, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, + 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x22, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x20, + 0x69, 0x6e, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, + 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, + 0x75, 0x72, 0x72, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x74, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x0a, + 0x09, 0x09, 0x74, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x3a, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x28, 0x29, 0x0a, 0x09, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, + 0x78, 0x70, 0x65, 0x63, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x28, 0x6e, 0x2c, 0x62, 0x2c, + 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x62, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x62, 0x2c, 0x20, 0x22, 0x2c, 0x5b, 0x25, 0x73, 0x5c, 0x6e, + 0x5d, 0x2a, 0x7d, 0x22, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x7d, 0x22, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x62, + 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, 0x29, 0x20, + 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, + 0x20, 0x62, 0x72, 0x61, 0x63, 0x65, 0x73, 0x0a, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, + 0x7d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x30, + 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, 0x69, 0x5d, + 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, + 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x20, 0x2d, 0x2d, + 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x20, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, + 0x09, 0x65, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x6e, 0x20, 0x2b, + 0x20, 0x31, 0x0a, 0x09, 0x09, 0x65, 0x5b, 0x65, 0x2e, 0x6e, 0x5d, 0x20, + 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x74, 0x74, + 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x28, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x29, 0x0a, 0x09, 0x09, + 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x3d, 0x20, + 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x20, 0x0a, 0x20, 0x20, 0x09, + 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, + 0x32, 0x5d, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x64, + 0x76, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, + 0x3e, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, + 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3c, 0x20, 0x6d, 0x69, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, + 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x0a, 0x09, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x73, 0x65, + 0x74, 0x20, 0x6c, 0x75, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x0a, + 0x09, 0x69, 0x20, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x65, 0x2e, 0x6c, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, + 0x65, 0x74, 0x63, 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, + 0x20, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, + 0x69, 0x74, 0x28, 0x65, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x40, 0x27, 0x29, + 0x0a, 0x09, 0x09, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x5b, + 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x09, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x5b, + 0x31, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, + 0x65, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20, + 0x3d, 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x5b, + 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x20, 0x6e, 0x73, 0x2e, 0x2e, + 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x6e, 0x73, + 0x2e, 0x2e, 0x65, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x20, + 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x0a, 0x09, + 0x65, 0x2e, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x0a, + 0x09, 0x65, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x5f, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x5b, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x09, + 0x54, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x22, 0x69, 0x6e, 0x74, + 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x45, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x65, 0x2c, 0x20, 0x76, 0x61, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a }; -unsigned int lua_enumerate_lua_len = 3354; +unsigned int lua_enumerate_lua_len = 3528; diff --git a/lib/tolua++/src/bin/function_lua.h b/lib/tolua++/src/bin/function_lua.h index 705cb1a8f..544a6f8a8 100644 --- a/lib/tolua++/src/bin/function_lua.h +++ b/lib/tolua++/src/bin/function_lua.h @@ -120,228 +120,202 @@ static const unsigned char lua_function_lua[] = { 0x74, 0x69, 0x63, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x29, - 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, - 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x66, - 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x69, - 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, - 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x73, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, - 0x20, 0x70, 0x75, 0x72, 0x65, 0x20, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, - 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x0a, 0x20, 0x09, - 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, - 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x6d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x22, - 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, - 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x6d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, - 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x20, 0x22, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2c, 0x22, - 0x20, 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, - 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, - 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, - 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, - 0x4c, 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, - 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x69, - 0x6e, 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, - 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, - 0x2c, 0x22, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x22, 0x29, - 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, - 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, - 0x4c, 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, - 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x20, 0x69, 0x6e, 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, - 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x53, 0x29, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7b, 0x22, 0x29, 0x0a, 0x0a, - 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, - 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, - 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, 0x27, - 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, - 0x72, 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x27, 0x20, 0x69, 0x66, 0x20, 0x28, 0x5c, 0x6e, 0x27, 0x29, - 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, - 0x61, 0x72, 0x67, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, - 0x32, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, - 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, - 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, - 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, - 0x65, 0x77, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x7e, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x27, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x27, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x3d, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x22, - 0x2e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, - 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x21, 0x27, 0x2e, 0x2e, 0x66, 0x75, 0x6e, 0x63, - 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, - 0x31, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, - 0x27, 0x22, 0x2c, 0x30, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x65, 0x72, 0x72, 0x29, 0x20, 0x7c, 0x7c, 0x5c, 0x6e, 0x27, 0x29, 0x0a, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x20, 0x61, 0x72, 0x67, 0x73, 0x0a, 0x20, 0x69, 0x66, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, - 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, - 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, - 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x74, 0x79, 0x70, 0x65, 0x20, - 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, - 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, - 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, - 0x69, 0x5d, 0x3a, 0x6f, 0x75, 0x74, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x74, - 0x79, 0x70, 0x65, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x2e, 0x2e, 0x27, - 0x20, 0x7c, 0x7c, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x74, 0x79, - 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x6e, - 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, - 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, - 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x6c, - 0x69, 0x73, 0x74, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, - 0x5f, 0x69, 0x73, 0x6e, 0x6f, 0x6f, 0x62, 0x6a, 0x28, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, - 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, - 0x72, 0x72, 0x29, 0x5c, 0x6e, 0x20, 0x29, 0x27, 0x29, 0x0a, 0x09, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x67, 0x6f, 0x74, - 0x6f, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, - 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, - 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, - 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, - 0x7b, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, - 0x6c, 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x69, - 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 0x0a, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x0a, 0x20, - 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, - 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, - 0x7e, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x27, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x2a, - 0x27, 0x2c, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x3d, 0x20, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x28, - 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, - 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x2a, 0x29, 0x20, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x5f, - 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, - 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x31, 0x2c, 0x30, 0x29, - 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x20, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, - 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, - 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, 0x5e, - 0x25, 0x73, 0x2a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x25, 0x73, 0x25, - 0x73, 0x2a, 0x28, 0x2e, 0x2a, 0x29, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, - 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x27, 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x6e, + 0x75, 0x6d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, - 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, - 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, - 0x65, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, - 0x66, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x29, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, - 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, - 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, - 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, - 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x0a, + 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, 0x6e, + 0x75, 0x6d, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6d, 0x69, 0x74, + 0x65, 0x6e, 0x75, 0x6d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, + 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, + 0x69, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, + 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x66, 0x6c, + 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x69, 0x72, + 0x74, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, + 0x09, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x70, 0x75, 0x72, 0x65, 0x20, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, + 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x0a, 0x20, 0x09, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, + 0x64, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x22, 0x2c, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, 0x29, + 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x2c, 0x22, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x22, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2c, 0x22, 0x20, + 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, + 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, + 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, + 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x22, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x69, 0x6e, + 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, + 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x2c, + 0x22, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x22, 0x29, 0x0a, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, + 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, + 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, + 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, + 0x69, 0x6e, 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x29, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7b, 0x22, 0x29, 0x0a, 0x0a, 0x20, + 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, + 0x6f, 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, + 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, + 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, 0x27, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, + 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x69, 0x66, 0x20, 0x28, 0x5c, 0x6e, 0x27, 0x29, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, + 0x72, 0x67, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, + 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, + 0x77, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x7e, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x27, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x27, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x22, 0x2e, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x21, 0x27, 0x2e, 0x2e, 0x66, 0x75, 0x6e, 0x63, 0x2e, + 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x31, + 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, + 0x22, 0x2c, 0x30, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, + 0x72, 0x72, 0x29, 0x20, 0x7c, 0x7c, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x20, 0x61, 0x72, 0x67, 0x73, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, + 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, + 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, + 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, 0x2e, + 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x3a, 0x6f, 0x75, 0x74, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x74, 0x79, + 0x70, 0x65, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x2e, 0x2e, 0x27, 0x20, + 0x7c, 0x7c, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x6e, 0x61, + 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, + 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x6c, 0x69, + 0x73, 0x74, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x69, 0x73, 0x6e, 0x6f, 0x6f, 0x62, 0x6a, 0x28, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, + 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, + 0x72, 0x29, 0x5c, 0x6e, 0x20, 0x29, 0x27, 0x29, 0x0a, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x67, 0x6f, 0x74, 0x6f, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, + 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, + 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x7b, + 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x69, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 0x0a, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x7e, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, - 0x4c, 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, - 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x73, 0x65, 0x6c, - 0x66, 0x29, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, - 0x27, 0x2e, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x22, 0x69, 0x6e, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x5c, 0x27, 0x73, 0x65, 0x6c, 0x66, - 0x5c, 0x27, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, 0x5c, 0x27, 0x22, 0x2c, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x2e, 0x2e, - 0x27, 0x22, 0x2c, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x29, 0x3b, 0x27, 0x29, - 0x3b, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, - 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, 0x69, - 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, 0x65, - 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x2a, 0x27, + 0x2c, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x3d, 0x20, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x28, 0x27, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x2a, 0x29, 0x20, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6f, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x31, 0x2c, 0x30, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, + 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, 0x5e, 0x25, + 0x73, 0x2a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x25, 0x73, 0x25, 0x73, + 0x2a, 0x28, 0x2e, 0x2a, 0x29, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, + 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, @@ -349,204 +323,268 @@ static const unsigned char lua_function_lua[] = { 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, - 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x67, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, - 0x79, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x6e, - 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, - 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, - 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x20, 0x70, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, - 0x6f, 0x6b, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x0a, 0x0a, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, 0x22, - 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x69, 0x66, 0x20, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x64, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, - 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x4d, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x65, - 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x26, 0x5b, 0x5d, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, - 0x31, 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, - 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x35, 0x20, 0x3f, 0x0a, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, - 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x28, - 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, - 0x31, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x2d, 0x31, 0x29, - 0x20, 0x3d, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, - 0x67, 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, - 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, - 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, + 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, + 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, + 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, + 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x7e, 0x3d, + 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, + 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x73, 0x65, 0x6c, 0x66, + 0x29, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, + 0x2e, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x22, 0x69, 0x6e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x20, 0x5c, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x5c, + 0x27, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, 0x5c, 0x27, 0x22, 0x2c, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x2e, 0x2e, 0x27, + 0x22, 0x2c, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x29, 0x3b, 0x27, 0x29, 0x3b, + 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, + 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x20, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, + 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, + 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, + 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, + 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, + 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x69, 0x5d, 0x3a, 0x67, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, + 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, + 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, + 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, + 0x70, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, + 0x6b, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, 0x22, 0x29, + 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x4d, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x26, 0x5b, 0x5d, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, 0x31, + 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, + 0x6c, 0x69, 0x74, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x35, 0x20, 0x3f, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x28, 0x27, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, + 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x2d, 0x31, 0x29, 0x20, + 0x3d, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, + 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x3b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x5b, 0x5d, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x27, 0x29, 0x20, 0x3d, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x27, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x28, + 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x29, 0x20, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x6e, 0x65, 0x77, 0x28, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, 0x28, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x75, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, + 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x2e, 0x2e, 0x27, 0x3a, 0x3a, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, + 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, + 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x61, 0x73, + 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x09, 0x2d, 0x2d, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x5f, 0x63, 0x61, 0x73, 0x74, 0x3c, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, + 0x27, 0x20, 0x3e, 0x28, 0x2a, 0x73, 0x65, 0x6c, 0x66, 0x27, 0x29, 0x0a, + 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, + 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x28, + 0x27, 0x29, 0x0a, 0x09, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, 0x6c, + 0x66, 0x2d, 0x3e, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x27, 0x28, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x27, 0x29, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x31, 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x2c, 0x27, 0x29, 0x20, 0x3d, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x2c, 0x27, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7b, 0x27, 0x29, 0x0a, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x2c, + 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, + 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, + 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x69, 0x5d, 0x3a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x61, 0x72, 0x28, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, + 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x27, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, 0x31, + 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x2d, 0x31, 0x29, 0x3b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, 0x77, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x20, 0x2d, + 0x2d, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, 0x28, 0x0a, 0x09, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x20, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, - 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x29, 0x20, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, 0x77, - 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, - 0x5f, 0x6e, 0x65, 0x77, 0x28, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, 0x28, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, - 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, - 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x2e, 0x27, 0x3a, 0x3a, 0x27, 0x2e, 0x2e, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, - 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6c, - 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x75, 0x74, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, - 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x61, - 0x73, 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x09, 0x2d, 0x2d, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x5f, 0x63, 0x61, 0x73, 0x74, 0x3c, 0x27, 0x2c, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, - 0x2c, 0x27, 0x20, 0x3e, 0x28, 0x2a, 0x73, 0x65, 0x6c, 0x66, 0x27, 0x29, - 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, - 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, - 0x72, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, - 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, - 0x28, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, - 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, - 0x6c, 0x66, 0x2d, 0x3e, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, - 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, - 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x27, 0x29, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, - 0x73, 0x5b, 0x31, 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, + 0x6e, 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x63, 0x74, 0x20, 0x3d, + 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x6e, 0x65, + 0x77, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x09, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x61, 0x73, 0x74, + 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x72, 0x61, 0x77, + 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x2c, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, - 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, - 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, - 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, - 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x61, 0x72, - 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, - 0x31, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x69, 0x66, - 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, - 0x27, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x27, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, - 0x31, 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x2d, 0x31, 0x29, 0x3b, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, - 0x77, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x20, - 0x2d, 0x2d, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, 0x28, 0x0a, 0x09, 0x65, 0x6c, - 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, - 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x3d, - 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x20, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x63, 0x74, 0x20, - 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x69, 0x66, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x6e, - 0x65, 0x77, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, - 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x61, 0x73, - 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x72, 0x61, - 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, - 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5b, 0x74, 0x5d, - 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, + 0x20, 0x20, 0x20, 0x27, 0x2c, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, + 0x72, 0x61, 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5b, 0x74, 0x5d, 0x2c, + 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x27, + 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x09, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x27, 0x2e, 0x2e, 0x74, 0x2e, + 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, - 0x5f, 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x27, 0x2e, 0x2e, 0x74, - 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, - 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, - 0x74, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, - 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, - 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, - 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x09, 0x09, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x74, - 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x75, 0x73, 0x68, 0x5f, - 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, - 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x28, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, - 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7b, - 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x5f, - 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, 0x6e, + 0x5f, 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, + 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, 0x2c, + 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, + 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, + 0x77, 0x6e, 0x65, 0x64, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x75, + 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7b, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x5f, 0x5f, + 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, 0x6e, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x2a, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, 0x3d, + 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, 0x28, + 0x28, 0x27, 0x2c, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x2c, 0x27, 0x29, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, - 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, - 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, - 0x28, 0x28, 0x27, 0x2c, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x2c, 0x27, 0x29, - 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x29, 0x29, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, + 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, + 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x6c, + 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x23, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x2c, 0x73, 0x69, + 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, @@ -559,634 +597,614 @@ static const unsigned char lua_function_lua[] = { 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x28, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, - 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x2c, 0x73, - 0x69, 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x29, - 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x27, 0x2c, + 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, + 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, + 0x29, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x2c, + 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, - 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x5f, 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, - 0x2c, 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, - 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, - 0x2a, 0x29, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, + 0x64, 0x2a, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, - 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, - 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, - 0x69, 0x64, 0x2a, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, - 0x74, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, - 0x29, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x64, - 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, - 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, - 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x6c, - 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, - 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, - 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, - 0x6e, 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x74, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, - 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, - 0x7d, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x65, - 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, - 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, - 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, - 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x73, - 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6e, 0x61, 0x72, 0x67, - 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, - 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, + 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x67, + 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x6c, 0x75, + 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, + 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, + 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x6e, + 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, + 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x74, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, + 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7d, + 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x74, + 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, + 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x73, 0x65, + 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, + 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x2d, + 0x2d, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x64, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, + 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, + 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, + 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x66, 0x72, 0x65, 0x65, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, - 0x2d, 0x2d, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x64, 0x79, 0x6e, 0x61, - 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, - 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, - 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, - 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, - 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x66, 0x72, 0x65, - 0x65, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, - 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x65, 0x6c, 0x66, - 0x29, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x2e, - 0x2e, 0x6e, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x27, 0x3b, 0x27, 0x29, 0x0a, - 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x76, - 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x67, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, - 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, - 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, - 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x52, - 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, - 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x5c, 0x6e, - 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, - 0x2e, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x22, 0x23, 0x66, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, 0x5c, 0x27, 0x2e, - 0x22, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, - 0x65, 0x29, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x09, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, - 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x09, 0x69, 0x66, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x09, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, - 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x0a, 0x09, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x3a, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x31, 0x2c, - 0x2d, 0x33, 0x29, 0x2e, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, - 0x22, 0x25, 0x30, 0x32, 0x64, 0x22, 0x2c, 0x6f, 0x76, 0x65, 0x72, 0x6c, - 0x6f, 0x61, 0x64, 0x29, 0x2e, 0x2e, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, - 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, - 0x66, 0x20, 0x2f, 0x2f, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, - 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, - 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, - 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x63, - 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, 0x77, - 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, - 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, - 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, - 0x28, 0x31, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x28, 0x70, 0x72, - 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, - 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, - 0x65, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, - 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, - 0x77, 0x69, 0x74, 0x68, 0x20, 0x70, 0x75, 0x72, 0x65, 0x20, 0x76, 0x69, - 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x73, 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, - 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, 0x2e, 0x2e, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, - 0x27, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, - 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x6e, 0x65, 0x77, - 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, - 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, - 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, - 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x53, 0x2c, 0x22, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x22, 0x2c, 0x27, 0x2e, - 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, - 0x2e, 0x27, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x27, 0x29, - 0x0a, 0x09, 0x20, 0x20, 0x2d, 0x2d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x73, 0x65, 0x74, - 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x28, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, - 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2c, 0x20, 0x22, 0x27, 0x2e, 0x2e, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x69, 0x64, - 0x65, 0x6e, 0x74, 0x2c, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x20, - 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, - 0x2e, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x22, - 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x20, 0x3d, - 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, - 0x64, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, - 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, - 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, - 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x70, 0x74, 0x72, - 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x70, 0x74, 0x72, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x2e, 0x2e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, - 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, + 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x2e, 0x2e, + 0x6e, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x27, 0x3b, 0x27, 0x29, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x76, 0x65, + 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, + 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x6e, + 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x52, 0x45, + 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x5c, 0x6e, 0x27, + 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, 0x2e, + 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x22, 0x23, 0x66, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, 0x5c, 0x27, 0x2e, 0x22, + 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, + 0x29, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x65, 0x72, 0x72, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x30, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, + 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x22, + 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x0a, 0x09, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x3a, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x31, 0x2c, 0x2d, + 0x33, 0x29, 0x2e, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x22, + 0x25, 0x30, 0x32, 0x64, 0x22, 0x2c, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, + 0x61, 0x64, 0x29, 0x2e, 0x2e, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, + 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, + 0x20, 0x2f, 0x2f, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, + 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, + 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x20, + 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x63, 0x61, + 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x73, + 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x28, + 0x31, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x28, 0x70, 0x72, 0x65, + 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x28, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x09, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, 0x65, + 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x70, 0x75, 0x72, 0x65, 0x20, 0x76, 0x69, 0x72, + 0x74, 0x75, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, + 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, + 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, + 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x6e, 0x65, 0x77, 0x5f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x5f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, + 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x22, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x22, 0x2c, 0x27, 0x2e, 0x2e, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, + 0x27, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x27, 0x29, 0x0a, + 0x09, 0x20, 0x20, 0x2d, 0x2d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x73, 0x65, 0x74, 0x5f, + 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x28, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x5f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2c, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2c, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x20, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, + 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x22, 0x29, + 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x20, 0x3d, 0x20, + 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, - 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, - 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, - 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x63, 0x6f, - 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2e, 0x2e, 0x22, 0x27, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x63, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, - 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, - 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, - 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x2e, 0x2e, 0x22, 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x7b, - 0x22, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, - 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, - 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, - 0x5b, 0x69, 0x5d, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, - 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x20, 0x22, 0x2c, 0x22, 0x2c, - 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, - 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, - 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x22, - 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x7d, 0x22, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, - 0x73, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x62, 0x79, 0x20, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x70, 0x74, 0x72, 0x20, + 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x74, 0x72, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, + 0x2e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, + 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6c, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, + 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2e, 0x2e, 0x22, 0x27, 0x2c, + 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x63, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, + 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, + 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, + 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, + 0x2e, 0x22, 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x22, + 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, + 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, + 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, + 0x69, 0x5d, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x20, 0x22, 0x2c, 0x22, 0x2c, 0x22, + 0x29, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x22, 0x29, + 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, + 0x74, 0x2e, 0x2e, 0x22, 0x7d, 0x22, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x73, + 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x20, 0x62, 0x79, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x63, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x74, 0x72, 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, 0x25, 0x73, 0x2a, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, 0x2c, 0x22, 0x22, 0x29, + 0x0a, 0x09, 0x20, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x3d, + 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x5f, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x63, 0x6c, 0x65, + 0x61, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x20, 0x72, 0x20, 0x3d, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x09, 0x77, 0x68, + 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, + 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x72, 0x20, + 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, + 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x20, + 0x6f, 0x72, 0x20, 0x72, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, + 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x72, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, + 0x6c, 0x75, 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, + 0x61, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x63, 0x6f, 0x6c, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x66, - 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x62, - 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x70, 0x74, 0x72, 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, 0x25, 0x73, 0x2a, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, 0x2c, 0x22, 0x22, - 0x29, 0x0a, 0x09, 0x20, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, - 0x3d, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x63, 0x6f, 0x6c, - 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x63, 0x6c, - 0x65, 0x61, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, - 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x20, 0x72, 0x20, 0x3d, - 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x09, 0x77, - 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, - 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x72, - 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, - 0x5b, 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x63, - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, - 0x20, 0x6f, 0x72, 0x20, 0x72, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, - 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, - 0x20, 0x6c, 0x75, 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, - 0x6f, 0x61, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, - 0x28, 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3a, 0x6f, - 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, - 0x70, 0x61, 0x72, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x73, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x69, 0x66, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, - 0x72, 0x2c, 0x20, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, - 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x20, - 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x64, 0x65, 0x66, - 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, - 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x3d, 0x28, 0x2e, - 0x2a, 0x29, 0x24, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, - 0x61, 0x72, 0x2c, 0x20, 0x22, 0x7c, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, - 0x6f, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x0a, 0x0a, 0x09, 0x09, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, + 0x6e, 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x28, + 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3a, 0x6f, 0x76, + 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x70, + 0x61, 0x72, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x73, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x69, 0x66, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, + 0x2c, 0x20, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x20, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x20, 0x68, + 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x3d, 0x28, 0x2e, 0x2a, + 0x29, 0x24, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, - 0x72, 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, - 0x20, 0x61, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, - 0x61, 0x72, 0x2c, 0x20, 0x27, 0x3d, 0x25, 0x73, 0x2a, 0x6e, 0x65, 0x77, - 0x27, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, - 0x25, 0x28, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, - 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x61, 0x73, 0x20, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x2e, 0x20, 0x69, 0x73, 0x20, 0x74, - 0x68, 0x61, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x3f, 0x0a, 0x09, - 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, - 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x20, 0x2d, - 0x2d, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x4e, 0x55, 0x4c, 0x4c, - 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, - 0x6e, 0x67, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x09, 0x69, - 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, - 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x5b, 0x25, 0x28, 0x26, - 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, + 0x72, 0x2c, 0x20, 0x22, 0x7c, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, + 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x0a, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, - 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, - 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, - 0x72, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x28, 0x6d, 0x6f, 0x73, 0x74, - 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x69, - 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, - 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x26, 0x22, 0x29, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x69, 0x66, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, + 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x61, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, + 0x72, 0x2c, 0x20, 0x27, 0x3d, 0x25, 0x73, 0x2a, 0x6e, 0x65, 0x77, 0x27, + 0x29, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x25, + 0x28, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, + 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x61, 0x73, 0x20, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x2e, 0x2e, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x61, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x3f, 0x0a, 0x09, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, + 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, + 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x4e, 0x55, 0x4c, 0x4c, 0x27, + 0x20, 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, + 0x67, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, - 0x28, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x3a, 0x22, 0x29, 0x20, 0x6f, - 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, - 0x64, 0x28, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, - 0x6e, 0x65, 0x77, 0x25, 0x73, 0x2b, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x69, - 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, - 0x6e, 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x64, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x6f, 0x6d, 0x65, - 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x3a, 0x3a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x20, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x27, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x2d, - 0x2d, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, - 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x3f, 0x0a, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, - 0x67, 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x2c, 0x20, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x29, 0x20, 0x2d, 0x2d, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, - 0x61, 0x73, 0x74, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, - 0x2c, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x6c, 0x61, 0x73, - 0x74, 0x5f, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x22, 0x5e, 0x28, 0x5b, 0x5e, - 0x3d, 0x5d, 0x2b, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, - 0x5f, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x6c, 0x61, 0x73, 0x74, 0x5f, - 0x61, 0x72, 0x67, 0x2c, 0x20, 0x22, 0x28, 0x5b, 0x25, 0x25, 0x25, 0x28, - 0x25, 0x29, 0x5d, 0x29, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x25, 0x25, 0x31, - 0x22, 0x29, 0x3b, 0x0a, 0x09, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, - 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, - 0x73, 0x75, 0x62, 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, - 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x2c, 0x25, 0x73, 0x2a, 0x22, 0x2e, - 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x22, - 0x25, 0x73, 0x2a, 0x25, 0x29, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, - 0x22, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x2c, 0x20, 0x73, - 0x5f, 0x61, 0x72, 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x46, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, - 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x28, 0x22, 0x23, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x27, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0a, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, - 0x28, 0x74, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x3a, 0x69, 0x6e, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x20, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x27, - 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x2e, - 0x2e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x2c, 0x20, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, - 0x69, 0x73, 0x20, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, - 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, - 0x62, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, - 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x3d, 0x3d, + 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x5b, 0x25, 0x28, 0x26, 0x5d, + 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, + 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, + 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x28, 0x6d, 0x6f, 0x73, 0x74, 0x20, + 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, + 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x69, 0x66, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, + 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x26, 0x22, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x69, 0x66, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x3a, 0x22, 0x29, 0x20, 0x6f, 0x72, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, + 0x28, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x6e, + 0x65, 0x77, 0x25, 0x73, 0x2b, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x69, 0x74, + 0x27, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, + 0x68, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x3a, 0x3a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x2c, + 0x20, 0x6f, 0x72, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x20, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x27, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x2d, 0x2d, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x3f, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, + 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x2c, 0x20, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x29, 0x20, 0x2d, 0x2d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, + 0x73, 0x74, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, + 0x73, 0x5f, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x22, 0x5e, 0x28, 0x5b, 0x5e, 0x3d, + 0x5d, 0x2b, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, + 0x72, 0x67, 0x2c, 0x20, 0x22, 0x28, 0x5b, 0x25, 0x25, 0x25, 0x28, 0x25, + 0x29, 0x5d, 0x29, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x25, 0x25, 0x31, 0x22, + 0x29, 0x3b, 0x0a, 0x09, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x2c, + 0x20, 0x22, 0x25, 0x73, 0x2a, 0x2c, 0x25, 0x73, 0x2a, 0x22, 0x2e, 0x2e, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x22, 0x25, + 0x73, 0x2a, 0x25, 0x29, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, + 0x29, 0x22, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x2c, 0x20, 0x73, 0x5f, + 0x61, 0x72, 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x73, + 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, + 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, + 0x22, 0x23, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x27, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, + 0x74, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x3a, 0x69, 0x6e, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x27, 0x74, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x2e, 0x2e, + 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x2c, 0x20, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69, + 0x73, 0x20, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, - 0x28, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x72, - 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x20, - 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, - 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x62, 0x3c, 0x3e, 0x22, - 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, - 0x20, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, - 0x6e, 0x65, 0x77, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6c, 0x6e, - 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x0a, - 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, - 0x5f, 0x6e, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, - 0x20, 0x20, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, - 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, - 0x20, 0x27, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, - 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, - 0x62, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, - 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x3d, 0x3d, - 0x20, 0x27, 0x7e, 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, - 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x3d, 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, - 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, - 0x3d, 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x0a, 0x20, + 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x62, + 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x3d, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, + 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, + 0x20, 0x22, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x6e, + 0x65, 0x77, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6c, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x5f, - 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, - 0x65, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x74, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, - 0x74, 0x3a, 0x63, 0x66, 0x75, 0x6e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x28, - 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x22, 0x29, 0x2e, 0x2e, 0x74, 0x3a, - 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x74, 0x29, 0x0a, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, - 0x65, 0x63, 0x74, 0x73, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x3a, 0x20, 0x6f, 0x6e, 0x65, 0x20, - 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, - 0x72, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, - 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, - 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64, 0x20, - 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, - 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x63, 0x6f, 0x6e, - 0x73, 0x74, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x0a, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x61, 0x2c, 0x63, 0x29, 0x0a, 0x20, - 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, - 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, - 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, - 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, - 0x74, 0x65, 0x20, 0x62, 0x72, 0x61, 0x63, 0x65, 0x73, 0x0a, 0x20, 0x2d, + 0x6e, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, + 0x20, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, + 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, + 0x27, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x62, + 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x7e, 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, + 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x0a, + 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, + 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x0a, 0x20, 0x20, + 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x5f, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, + 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x74, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x74, + 0x3a, 0x63, 0x66, 0x75, 0x6e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x22, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x22, 0x29, 0x2e, 0x2e, 0x74, 0x3a, 0x6f, + 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, 0x65, + 0x63, 0x74, 0x73, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x73, 0x3a, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x72, + 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64, 0x20, 0x72, + 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x0a, + 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x61, 0x2c, 0x63, 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, - 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x28, - 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, - 0x32, 0x29, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, - 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, 0x57, 0x27, 0x5d, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, - 0x69, 0x6e, 0x64, 0x28, 0x61, 0x2c, 0x20, 0x22, 0x25, 0x2e, 0x25, 0x2e, - 0x25, 0x2e, 0x25, 0x73, 0x2a, 0x25, 0x29, 0x22, 0x29, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, - 0x67, 0x28, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x20, 0x28, 0x60, 0x2e, 0x2e, 0x2e, 0x27, 0x29, 0x20, 0x61, 0x72, 0x65, - 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x2e, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x69, 0x6e, 0x67, - 0x20, 0x22, 0x2e, 0x2e, 0x64, 0x2e, 0x2e, 0x61, 0x2e, 0x2e, 0x63, 0x29, - 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, - 0x6c, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, - 0x0a, 0x0a, 0x20, 0x09, 0x61, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x20, 0x22, - 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x25, 0x28, 0x25, 0x29, 0x5d, 0x29, 0x25, - 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x31, 0x22, 0x29, 0x0a, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x73, 0x74, 0x72, 0x69, - 0x70, 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x70, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x28, 0x73, 0x74, 0x72, 0x73, - 0x75, 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x29, 0x3b, - 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, - 0x28, 0x61, 0x2c, 0x31, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x20, 0x31, 0x2c, - 0x20, 0x2d, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x6c, 0x65, - 0x6e, 0x28, 0x6c, 0x61, 0x73, 0x74, 0x29, 0x2b, 0x31, 0x29, 0x29, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, - 0x20, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x2c, 0x22, - 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x31, 0x29, - 0x0a, 0x0a, 0x09, 0x09, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x22, 0x28, 0x22, - 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, - 0x62, 0x28, 0x6e, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x2c, 0x25, - 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x2e, 0x2e, 0x27, - 0x29, 0x27, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6e, 0x73, 0x20, 0x3d, 0x20, - 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x73, 0x28, 0x6e, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x46, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x6e, 0x73, 0x2c, 0x20, - 0x63, 0x29, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, - 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x09, - 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, - 0x20, 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, - 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, 0x69, 0x5d, - 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, - 0x6c, 0x2e, 0x6e, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, - 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x76, - 0x61, 0x72, 0x27, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x0a, 0x20, 0x20, - 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, - 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, - 0x64, 0x2c, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x29, 0x0a, 0x20, 0x66, - 0x2e, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x0a, 0x20, 0x66, - 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x0a, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x46, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x66, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6a, 0x6f, - 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x70, 0x2c, 0x20, 0x66, - 0x69, 0x72, 0x73, 0x74, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x29, 0x0a, - 0x0a, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, - 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x61, - 0x73, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x72, - 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x6e, 0x28, - 0x74, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x73, - 0x65, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x20, - 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x66, 0x6f, 0x72, - 0x20, 0x69, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2c, 0x6c, - 0x61, 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x0a, 0x09, 0x09, 0x72, 0x65, - 0x74, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x6c, 0x73, 0x65, - 0x70, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x09, 0x09, 0x6c, 0x73, - 0x65, 0x70, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x70, 0x0a, 0x09, 0x09, 0x6c, - 0x6f, 0x6f, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, - 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x72, 0x65, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, - 0x70, 0x61, 0x72, 0x73, 0x28, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, - 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, - 0x2c, 0x20, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x66, 0x61, - 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, - 0x61, 0x73, 0x74, 0x0a, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, - 0x74, 0x2e, 0x6e, 0x2c, 0x31, 0x2c, 0x2d, 0x31, 0x20, 0x64, 0x6f, 0x0a, - 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x74, 0x5b, 0x69, - 0x5d, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6c, - 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x0a, 0x09, 0x09, 0x09, 0x73, - 0x74, 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x69, 0x66, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x2d, 0x2d, 0x09, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, - 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, - 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, - 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x65, 0x6e, - 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2c, 0x73, 0x74, 0x72, 0x69, 0x70, 0x2c, - 0x6c, 0x61, 0x73, 0x74, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, - 0x70, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x28, 0x73, - 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, - 0x5e, 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x73, - 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, - 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x29, 0x24, 0x22, 0x2c, - 0x20, 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x20, 0x22, - 0x2c, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, - 0x65, 0x70, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x22, 0x22, - 0x2c, 0x22, 0x22, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, - 0x2c, 0x74, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x74, 0x5b, - 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x22, - 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, - 0x09, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x2e, - 0x73, 0x65, 0x70, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x09, 0x09, - 0x73, 0x65, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x2c, 0x22, 0x0a, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x22, 0x28, 0x22, 0x2e, 0x2e, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x22, 0x29, - 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a + 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, + 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x65, 0x20, 0x62, 0x72, 0x61, 0x63, 0x65, 0x73, 0x0a, 0x20, 0x2d, 0x2d, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x28, 0x73, + 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, + 0x29, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, 0x57, 0x27, 0x5d, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, + 0x6e, 0x64, 0x28, 0x61, 0x2c, 0x20, 0x22, 0x25, 0x2e, 0x25, 0x2e, 0x25, + 0x2e, 0x25, 0x73, 0x2a, 0x25, 0x29, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x28, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, + 0x28, 0x60, 0x2e, 0x2e, 0x2e, 0x27, 0x29, 0x20, 0x61, 0x72, 0x65, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x2e, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x22, 0x2e, 0x2e, 0x64, 0x2e, 0x2e, 0x61, 0x2e, 0x2e, 0x63, 0x29, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, + 0x0a, 0x20, 0x09, 0x61, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x20, 0x22, 0x25, + 0x73, 0x2a, 0x28, 0x5b, 0x25, 0x28, 0x25, 0x29, 0x5d, 0x29, 0x25, 0x73, + 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x31, 0x22, 0x29, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x73, 0x74, 0x72, 0x69, 0x70, + 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x70, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x29, 0x3b, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, + 0x61, 0x2c, 0x31, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x20, 0x31, 0x2c, 0x20, + 0x2d, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x6c, 0x65, 0x6e, + 0x28, 0x6c, 0x61, 0x73, 0x74, 0x29, 0x2b, 0x31, 0x29, 0x29, 0x0a, 0x09, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, + 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x2c, 0x22, 0x2c, + 0x20, 0x31, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x31, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x22, 0x28, 0x22, 0x2e, + 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x6e, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x2c, 0x25, 0x73, + 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x2e, 0x2e, 0x27, 0x29, + 0x27, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x70, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x73, 0x28, 0x6e, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x6e, 0x73, 0x2c, 0x20, 0x63, + 0x29, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, + 0x6c, 0x61, 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x09, 0x74, + 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x20, + 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, 0x69, 0x5d, 0x20, + 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, + 0x2e, 0x6e, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, 0x6e, + 0x5d, 0x20, 0x3d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x76, 0x61, + 0x72, 0x27, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x44, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, + 0x2c, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x29, 0x0a, 0x20, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x0a, 0x20, 0x66, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x0a, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x46, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x66, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6a, 0x6f, 0x69, + 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x70, 0x2c, 0x20, 0x66, 0x69, + 0x72, 0x73, 0x74, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x29, 0x0a, 0x0a, + 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x61, 0x73, + 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x6e, 0x28, 0x74, + 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x73, 0x65, + 0x70, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x3d, + 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, + 0x69, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2c, 0x6c, 0x61, + 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, + 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x6c, 0x73, 0x65, 0x70, + 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x09, 0x09, 0x6c, 0x73, 0x65, + 0x70, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x70, 0x0a, 0x09, 0x09, 0x6c, 0x6f, + 0x6f, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, + 0x6f, 0x6f, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, + 0x65, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x70, + 0x61, 0x72, 0x73, 0x28, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, + 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, + 0x20, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x61, + 0x73, 0x74, 0x0a, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x74, + 0x2e, 0x6e, 0x2c, 0x31, 0x2c, 0x2d, 0x31, 0x20, 0x64, 0x6f, 0x0a, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x74, 0x5b, 0x69, 0x5d, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x61, + 0x73, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x0a, 0x09, 0x09, 0x09, 0x73, 0x74, + 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x69, 0x66, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x2d, 0x2d, 0x09, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, + 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, + 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x2c, 0x73, 0x74, 0x72, 0x69, 0x70, 0x2c, 0x6c, + 0x61, 0x73, 0x74, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, + 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x28, 0x73, 0x29, + 0x0a, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x5e, + 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x73, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x29, 0x24, 0x22, 0x2c, 0x20, + 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x2c, + 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x65, + 0x70, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x2c, + 0x22, 0x22, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, + 0x74, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x74, 0x5b, 0x69, + 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x22, 0x3d, + 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, + 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x73, + 0x65, 0x70, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x09, 0x09, 0x73, + 0x65, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x2c, 0x22, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, + 0x28, 0x22, 0x2e, 0x2e, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x22, 0x29, 0x22, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a }; -unsigned int lua_function_lua_len = 14264; +unsigned int lua_function_lua_len = 14479; diff --git a/lib/tolua++/src/bin/lua/basic.lua b/lib/tolua++/src/bin/lua/basic.lua index d195f6dec..b5788f2be 100644 --- a/lib/tolua++/src/bin/lua/basic.lua +++ b/lib/tolua++/src/bin/lua/basic.lua @@ -145,12 +145,14 @@ function typevar(type) end end +-- is enum +function isenum (type) + return _enums[type] +end + -- check if basic type function isbasic (type) local t = gsub(type,'const ','') - if _enum_is_functions[t] then - return nil - end local m,t = applytypedef('', t) local b = _basic[t] if b then @@ -385,7 +387,7 @@ end _push_functions = {} _is_functions = {} -_enum_is_functions = {} +_enums = {} _to_functions = {} _base_push_functions = {} @@ -414,5 +416,8 @@ function get_to_function(t) end function get_is_function(t) - return _enum_is_functions[t] or _is_functions[t] or search_base(t, _base_is_functions) or "tolua_isusertype" + if _enums[t] then + return "tolua_is" .. t + end + return _is_functions[t] or search_base(t, _base_is_functions) or "tolua_isusertype" end diff --git a/lib/tolua++/src/bin/lua/declaration.lua b/lib/tolua++/src/bin/lua/declaration.lua index 73bbe910e..5a2adfed9 100644 --- a/lib/tolua++/src/bin/lua/declaration.lua +++ b/lib/tolua++/src/bin/lua/declaration.lua @@ -229,6 +229,8 @@ function classDeclaration:outchecktype (narg) --end elseif t then return '!tolua_is'..t..'(tolua_S,'..narg..','..def..',&tolua_err)' + elseif isenum(self.type) then + return '!tolua_is'..self.type..'(tolua_S,'..narg..','..def..',&tolua_err)' else local is_func = get_is_function(self.type) if self.ptr == '&' or self.ptr == '' then diff --git a/lib/tolua++/src/bin/lua/enumerate.lua b/lib/tolua++/src/bin/lua/enumerate.lua index d5d4426cf..ef3a9574c 100644 --- a/lib/tolua++/src/bin/lua/enumerate.lua +++ b/lib/tolua++/src/bin/lua/enumerate.lua @@ -48,13 +48,17 @@ function classEnumerate:print (ident,close) print(ident.."}"..close) end +function emitenumprototype(type) + output("int tolua_is" .. string.gsub(type,"::","_") .. " (lua_State* L, int lo, const char * type, int def, tolua_Error* err);") +end + _global_output_enums = {} -- write support code function classEnumerate:supcode () if _global_output_enums[self.name] == nil then _global_output_enums[self.name] = 1 - output("lua_Number tolua_is" .. self.name .. " (lua_State* L, int lo, int def, tolua_Error* err)") + output("int tolua_is" .. string.gsub(self.name,"::","_") .. " (lua_State* L, int lo, const char * type, int def, tolua_Error* err)") output("{") output("if (!tolua_isnumber(L,lo,def,err)) return 0;") output("lua_Number val = tolua_tonumber(L,lo,def);") @@ -130,7 +134,7 @@ function Enumerate (n,b,varname) e.min = min e.max = max if n ~= "" then - _enum_is_functions[n] = ("tolua_is" .. n) + _enums[n] = 1 Typedef("int "..n) end return _Enumerate(e, varname) diff --git a/lib/tolua++/src/bin/lua/function.lua b/lib/tolua++/src/bin/lua/function.lua index 7120fb063..ad1ab4225 100644 --- a/lib/tolua++/src/bin/lua/function.lua +++ b/lib/tolua++/src/bin/lua/function.lua @@ -54,6 +54,16 @@ function classFunction:supcode (local_constructor) local nret = 0 -- number of returned values local class = self:inclass() local _,_,static = strfind(self.mod,'^%s*(static)') + -- prototypes for enum functions + if self.args[1].type ~= 'void' then + local i=1 + while self.args[i] do + if isenum(self.args[i].type) then + emitenumprototype(self.args[i].type) + end + i = i+1 + end + end if class then if self.name == 'new' and self.parent.flags.pure_virtual then diff --git a/lib/tolua++/src/bin/toluabind.c b/lib/tolua++/src/bin/toluabind.c index 6be141580..06b371f70 100644 --- a/lib/tolua++/src/bin/toluabind.c +++ b/lib/tolua++/src/bin/toluabind.c @@ -3204,1011 +3204,8 @@ TOLUA_API int tolua_tolua_open (lua_State* tolua_S) { /* begin embedded lua code */ int top = lua_gettop(tolua_S); - static unsigned char B[] = { - 45, 45, 32,116,111,108,117, 97, 58, 32,100,101, 99,108, 97, - 114, 97,116,105,111,110, 32, 99,108, 97,115,115, 10, 45, 45, - 32, 87,114,105,116,116,101,110, 32, 98,121, 32, 87, 97,108, - 100,101,109, 97,114, 32, 67,101,108,101,115, 10, 45, 45, 32, - 84,101, 67, 71,114, 97,102, 47, 80, 85, 67, 45, 82,105,111, - 10, 45, 45, 32, 74,117,108, 32, 49, 57, 57, 56, 10, 45, 45, - 32, 36, 73,100, 58, 32, 36, 10, 10, 45, 45, 32, 84,104,105, - 115, 32, 99,111,100,101, 32,105,115, 32,102,114,101,101, 32, - 115,111,102,116,119, 97,114,101, 59, 32,121,111,117, 32, 99, - 97,110, 32,114,101,100,105,115,116,114,105, 98,117,116,101, - 32,105,116, 32, 97,110,100, 47,111,114, 32,109,111,100,105, - 102,121, 32,105,116, 46, 10, 45, 45, 32, 84,104,101, 32,115, - 111,102,116,119, 97,114,101, 32,112,114,111,118,105,100,101, - 100, 32,104,101,114,101,117,110,100,101,114, 32,105,115, 32, - 111,110, 32, 97,110, 32, 34, 97,115, 32,105,115, 34, 32, 98, - 97,115,105,115, 44, 32, 97,110,100, 10, 45, 45, 32,116,104, - 101, 32, 97,117,116,104,111,114, 32,104, 97,115, 32,110,111, - 32,111, 98,108,105,103, 97,116,105,111,110, 32,116,111, 32, - 112,114,111,118,105,100,101, 32,109, 97,105,110,116,101,110, - 97,110, 99,101, 44, 32,115,117,112,112,111,114,116, 44, 32, - 117,112,100, 97,116,101,115, 44, 10, 45, 45, 32,101,110,104, - 97,110, 99,101,109,101,110,116,115, 44, 32,111,114, 32,109, - 111,100,105,102,105, 99, 97,116,105,111,110,115, 46, 10, 10, - 10, 45, 45, 32, 68,101, 99,108, 97,114, 97,116,105,111,110, - 32, 99,108, 97,115,115, 10, 45, 45, 32, 82,101,112,114,101, - 115,101,110,116,115, 32,118, 97,114,105, 97, 98,108,101, 44, - 32,102,117,110, 99,116,105,111,110, 44, 32,111,114, 32, 97, - 114,103,117,109,101,110,116, 32,100,101, 99,108, 97,114, 97, - 116,105,111,110, 46, 10, 45, 45, 32, 83,116,111,114,101,115, - 32,116,104,101, 32,102,111,108,108,111,119,105,110,103, 32, - 102,105,101,108,100,115, 58, 10, 45, 45, 32, 32,109,111,100, - 32, 32, 61, 32,116,121,112,101, 32,109,111,100,105,102,105, - 101,114,115, 10, 45, 45, 32, 32,116,121,112,101, 32, 61, 32, - 116,121,112,101, 10, 45, 45, 32, 32,112,116,114, 32, 32, 61, - 32, 34, 42, 34, 32,111,114, 32, 34, 38, 34, 44, 32,105,102, - 32,114,101,112,114,101,115,101,110,116,105,110,103, 32, 97, - 32,112,111,105,110,116,101,114, 32,111,114, 32, 97, 32,114, - 101,102,101,114,101,110, 99,101, 10, 45, 45, 32, 32,110, 97, - 109,101, 32, 61, 32,110, 97,109,101, 10, 45, 45, 32, 32,100, - 105,109, 32, 32, 61, 32,100,105,109,101,110,115,105,111,110, - 44, 32,105,102, 32, 97, 32,118,101, 99,116,111,114, 10, 45, - 45, 32, 32,100,101,102, 32, 32, 61, 32,100,101,102, 97,117, - 108,116, 32,118, 97,108,117,101, 44, 32,105,102, 32, 97,110, - 121, 32, 40,111,110,108,121, 32,102,111,114, 32, 97,114,103, - 117,109,101,110,116,115, 41, 10, 45, 45, 32, 32,114,101,116, - 32, 32, 61, 32, 34, 42, 34, 32,111,114, 32, 34, 38, 34, 44, - 32,105,102, 32,118, 97,108,117,101, 32,105,115, 32,116,111, - 32, 98,101, 32,114,101,116,117,114,110,101,100, 32, 40,111, - 110,108,121, 32,102,111,114, 32, 97,114,103,117,109,101,110, - 116,115, 41, 10, 99,108, 97,115,115, 68,101, 99,108, 97,114, - 97,116,105,111,110, 32, 61, 32,123, 10, 32,109,111,100, 32, - 61, 32, 39, 39, 44, 10, 32,116,121,112,101, 32, 61, 32, 39, - 39, 44, 10, 32,112,116,114, 32, 61, 32, 39, 39, 44, 10, 32, - 110, 97,109,101, 32, 61, 32, 39, 39, 44, 10, 32,100,105,109, - 32, 61, 32, 39, 39, 44, 10, 32,114,101,116, 32, 61, 32, 39, - 39, 44, 10, 32,100,101,102, 32, 61, 32, 39, 39, 10,125, 10, - 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111, - 110, 46, 95, 95,105,110,100,101,120, 32, 61, 32, 99,108, 97, - 115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 10,115, - 101,116,109,101,116, 97,116, 97, 98,108,101, 40, 99,108, 97, - 115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 44, 99, - 108, 97,115,115, 70,101, 97,116,117,114,101, 41, 10, 10, 45, - 45, 32, 67,114,101, 97,116,101, 32, 97,110, 32,117,110,105, - 113,117,101, 32,118, 97,114,105, 97, 98,108,101, 32,110, 97, - 109,101, 10,102,117,110, 99,116,105,111,110, 32, 99,114,101, - 97,116,101, 95,118, 97,114,110, 97,109,101, 32, 40, 41, 10, - 32,105,102, 32,110,111,116, 32, 95,118, 97,114,110,117,109, - 98,101,114, 32,116,104,101,110, 32, 95,118, 97,114,110,117, - 109, 98,101,114, 32, 61, 32, 48, 32,101,110,100, 10, 32, 95, - 118, 97,114,110,117,109, 98,101,114, 32, 61, 32, 95,118, 97, - 114,110,117,109, 98,101,114, 32, 43, 32, 49, 10, 32,114,101, - 116,117,114,110, 32, 34,116,111,108,117, 97, 95,118, 97,114, - 95, 34, 46, 46, 95,118, 97,114,110,117,109, 98,101,114, 10, - 101,110,100, 10, 10, 45, 45, 32, 67,104,101, 99,107, 32,100, - 101, 99,108, 97,114, 97,116,105,111,110, 32,110, 97,109,101, - 10, 45, 45, 32, 73,116, 32, 97,108,115,111, 32,105,100,101, - 110,116,105,102,105,101,115, 32,100,101,102, 97,117,108,116, - 32,118, 97,108,117,101,115, 10,102,117,110, 99,116,105,111, - 110, 32, 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116, - 105,111,110, 58, 99,104,101, 99,107,110, 97,109,101, 32, 40, - 41, 10, 10, 32,105,102, 32,115,116,114,115,117, 98, 40,115, - 101,108,102, 46,110, 97,109,101, 44, 49, 44, 49, 41, 32, 61, - 61, 32, 39, 91, 39, 32, 97,110,100, 32,110,111,116, 32,102, - 105,110,100,116,121,112,101, 40,115,101,108,102, 46,116,121, - 112,101, 41, 32,116,104,101,110, 10, 32, 32,115,101,108,102, - 46,110, 97,109,101, 32, 61, 32,115,101,108,102, 46,116,121, - 112,101, 46, 46,115,101,108,102, 46,110, 97,109,101, 10, 32, - 32,108,111, 99, 97,108, 32,109, 32, 61, 32,115,112,108,105, - 116, 40,115,101,108,102, 46,109,111,100, 44, 39, 37,115, 37, - 115, 42, 39, 41, 10, 32, 32,115,101,108,102, 46,116,121,112, - 101, 32, 61, 32,109, 91,109, 46,110, 93, 10, 32, 32,115,101, - 108,102, 46,109,111,100, 32, 61, 32, 99,111,110, 99, 97,116, - 40,109, 44, 49, 44,109, 46,110, 45, 49, 41, 10, 32,101,110, - 100, 10, 10, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,115, - 112,108,105,116, 40,115,101,108,102, 46,110, 97,109,101, 44, - 39, 61, 39, 41, 10, 32,105,102, 32,116, 46,110, 61, 61, 50, - 32,116,104,101,110, 10, 32, 32,115,101,108,102, 46,110, 97, - 109,101, 32, 61, 32,116, 91, 49, 93, 10, 32, 32,115,101,108, - 102, 46,100,101,102, 32, 61, 32,102,105,110,100, 95,101,110, - 117,109, 95,118, 97,114, 40,116, 91,116, 46,110, 93, 41, 10, - 32,101,110,100, 10, 10, 32,108,111, 99, 97,108, 32, 98, 44, - 101, 44,100, 32, 61, 32,115,116,114,102,105,110,100, 40,115, - 101,108,102, 46,110, 97,109,101, 44, 34, 37, 91, 40, 46, 45, - 41, 37, 93, 34, 41, 10, 32,105,102, 32, 98, 32,116,104,101, - 110, 10, 32, 32,115,101,108,102, 46,110, 97,109,101, 32, 61, - 32,115,116,114,115,117, 98, 40,115,101,108,102, 46,110, 97, - 109,101, 44, 49, 44, 98, 45, 49, 41, 10, 32, 32,115,101,108, - 102, 46,100,105,109, 32, 61, 32,102,105,110,100, 95,101,110, - 117,109, 95,118, 97,114, 40,100, 41, 10, 32,101,110,100, 10, - 10, 10, 32,105,102, 32,115,101,108,102, 46,116,121,112,101, - 32,126, 61, 32, 39, 39, 32, 97,110,100, 32,115,101,108,102, - 46,116,121,112,101, 32,126, 61, 32, 39,118,111,105,100, 39, - 32, 97,110,100, 32,115,101,108,102, 46,110, 97,109,101, 32, - 61, 61, 32, 39, 39, 32,116,104,101,110, 10, 32, 32,115,101, - 108,102, 46,110, 97,109,101, 32, 61, 32, 99,114,101, 97,116, - 101, 95,118, 97,114,110, 97,109,101, 40, 41, 10, 32,101,108, - 115,101,105,102, 32,115,101,108,102, 46,107,105,110,100, 61, - 61, 39,118, 97,114, 39, 32,116,104,101,110, 10, 32, 32,105, - 102, 32,115,101,108,102, 46,116,121,112,101, 61, 61, 39, 39, - 32, 97,110,100, 32,115,101,108,102, 46,110, 97,109,101,126, - 61, 39, 39, 32,116,104,101,110, 10, 32, 32, 32,115,101,108, - 102, 46,116,121,112,101, 32, 61, 32,115,101,108,102, 46,116, - 121,112,101, 46, 46,115,101,108,102, 46,110, 97,109,101, 10, - 32, 32, 32,115,101,108,102, 46,110, 97,109,101, 32, 61, 32, - 99,114,101, 97,116,101, 95,118, 97,114,110, 97,109,101, 40, - 41, 10, 32, 32,101,108,115,101,105,102, 32,102,105,110,100, - 116,121,112,101, 40,115,101,108,102, 46,110, 97,109,101, 41, - 32,116,104,101,110, 10, 32, 32, 32,105,102, 32,115,101,108, - 102, 46,116,121,112,101, 61, 61, 39, 39, 32,116,104,101,110, - 32,115,101,108,102, 46,116,121,112,101, 32, 61, 32,115,101, - 108,102, 46,110, 97,109,101, 10, 32, 32, 32,101,108,115,101, - 32,115,101,108,102, 46,116,121,112,101, 32, 61, 32,115,101, - 108,102, 46,116,121,112,101, 46, 46, 39, 32, 39, 46, 46,115, - 101,108,102, 46,110, 97,109,101, 32,101,110,100, 10, 32, 32, - 32,115,101,108,102, 46,110, 97,109,101, 32, 61, 32, 99,114, - 101, 97,116,101, 95,118, 97,114,110, 97,109,101, 40, 41, 10, - 32, 32,101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, 45, - 32, 97,100,106,117,115,116, 32,116,121,112,101, 32,111,102, - 32,115,116,114,105,110,103, 10, 32,105,102, 32,115,101,108, - 102, 46,116,121,112,101, 32, 61, 61, 32, 39, 99,104, 97,114, - 39, 32, 97,110,100, 32,115,101,108,102, 46,100,105,109, 32, - 126, 61, 32, 39, 39, 32,116,104,101,110, 10, 9, 32,115,101, - 108,102, 46,116,121,112,101, 32, 61, 32, 39, 99,104, 97,114, - 42, 39, 10, 32,101,110,100, 10, 10, 9,105,102, 32,115,101, - 108,102, 46,107,105,110,100, 32, 97,110,100, 32,115,101,108, - 102, 46,107,105,110,100, 32, 61, 61, 32, 39,118, 97,114, 39, - 32,116,104,101,110, 10, 9, 9,115,101,108,102, 46,110, 97, - 109,101, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, - 98, 40,115,101,108,102, 46,110, 97,109,101, 44, 32, 34, 58, - 46, 42, 36, 34, 44, 32, 34, 34, 41, 32, 45, 45, 32, 63, 63, - 63, 10, 9,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, - 67,104,101, 99,107, 32,100,101, 99,108, 97,114, 97,116,105, - 111,110, 32,116,121,112,101, 10, 45, 45, 32, 83,117, 98,115, - 116,105,116,117,116,101,115, 32,116,121,112,101,100,101,102, - 39,115, 46, 10,102,117,110, 99,116,105,111,110, 32, 99,108, - 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58, - 99,104,101, 99,107,116,121,112,101, 32, 40, 41, 10, 10, 32, - 45, 45, 32, 99,104,101, 99,107, 32,105,102, 32,116,104,101, - 114,101, 32,105,115, 32, 97, 32,112,111,105,110,116,101,114, - 32,116,111, 32, 98, 97,115,105, 99, 32,116,121,112,101, 10, - 32,108,111, 99, 97,108, 32, 98, 97,115,105, 99, 32, 61, 32, - 105,115, 98, 97,115,105, 99, 40,115,101,108,102, 46,116,121, - 112,101, 41, 10, 32,105,102, 32,115,101,108,102, 46,107,105, - 110,100, 32, 61, 61, 32, 39,102,117,110, 99, 39, 32, 97,110, - 100, 32, 98, 97,115,105, 99, 61, 61, 39,110,117,109, 98,101, - 114, 39, 32, 97,110,100, 32,115,116,114,105,110,103, 46,102, - 105,110,100, 40,115,101,108,102, 46,112,116,114, 44, 32, 34, - 37, 42, 34, 41, 32,116,104,101,110, 10, 32, 9,115,101,108, - 102, 46,116,121,112,101, 32, 61, 32, 39, 95,117,115,101,114, - 100, 97,116, 97, 39, 10, 32, 9,115,101,108,102, 46,112,116, - 114, 32, 61, 32, 34, 34, 10, 32,101,110,100, 10, 32,105,102, - 32, 98, 97,115,105, 99, 32, 97,110,100, 32,115,101,108,102, - 46,112,116,114,126, 61, 39, 39, 32,116,104,101,110, 10, 32, - 32,115,101,108,102, 46,114,101,116, 32, 61, 32,115,101,108, - 102, 46,112,116,114, 10, 32, 32,115,101,108,102, 46,112,116, - 114, 32, 61, 32,110,105,108, 10, 32, 32,105,102, 32,105,115, - 98, 97,115,105, 99, 40,115,101,108,102, 46,116,121,112,101, - 41, 32, 61, 61, 32, 39,110,117,109, 98,101,114, 39, 32,116, - 104,101,110, 10, 32, 32, 9,115,101,108,102, 46,114,101,116, - 117,114,110, 95,117,115,101,114,100, 97,116, 97, 32, 61, 32, - 116,114,117,101, 10, 32, 32,101,110,100, 10, 32,101,110,100, - 10, 10, 32, 45, 45, 32, 99,104,101, 99,107, 32,105,102, 32, - 116,104,101,114,101, 32,105,115, 32, 97,114,114, 97,121, 32, - 116,111, 32, 98,101, 32,114,101,116,117,114,110,101,100, 10, - 32,105,102, 32,115,101,108,102, 46,100,105,109,126, 61, 39, - 39, 32, 97,110,100, 32,115,101,108,102, 46,114,101,116,126, - 61, 39, 39, 32,116,104,101,110, 10, 32, 32, 32,101,114,114, - 111,114, 40, 39, 35,105,110,118, 97,108,105,100, 32,112, 97, - 114, 97,109,101,116,101,114, 58, 32, 99, 97,110,110,111,116, - 32,114,101,116,117,114,110, 32, 97,110, 32, 97,114,114, 97, - 121, 32,111,102, 32,118, 97,108,117,101,115, 39, 41, 10, 32, - 101,110,100, 10, 32, 45, 45, 32,114,101,115,116,111,114,101, - 32, 39,118,111,105,100, 42, 39, 32, 97,110,100, 32, 39,115, - 116,114,105,110,103, 42, 39, 10, 32,105,102, 32,115,101,108, - 102, 46,116,121,112,101, 32, 61, 61, 32, 39, 95,117,115,101, - 114,100, 97,116, 97, 39, 32,116,104,101,110, 32,115,101,108, - 102, 46,116,121,112,101, 32, 61, 32, 39,118,111,105,100, 42, - 39, 10, 32,101,108,115,101,105,102, 32,115,101,108,102, 46, - 116,121,112,101, 32, 61, 61, 32, 39, 95, 99,115,116,114,105, - 110,103, 39, 32,116,104,101,110, 32,115,101,108,102, 46,116, - 121,112,101, 32, 61, 32, 39, 99,104, 97,114, 42, 39, 10, 32, - 101,108,115,101,105,102, 32,115,101,108,102, 46,116,121,112, - 101, 32, 61, 61, 32, 39, 95,108,115,116, 97,116,101, 39, 32, - 116,104,101,110, 32,115,101,108,102, 46,116,121,112,101, 32, - 61, 32, 39,108,117, 97, 95, 83,116, 97,116,101, 42, 39, 10, - 32,101,110,100, 10, 10, 32, 45, 45, 32,114,101,115,111,108, - 118,101, 32,116,121,112,101,115, 32,105,110,115,105,100,101, - 32,116,104,101, 32,116,101,109,112,108, 97,116,101,115, 10, - 32,105,102, 32,115,101,108,102, 46,116,121,112,101, 32,116, - 104,101,110, 10, 9, 32,115,101,108,102, 46,116,121,112,101, - 32, 61, 32,114,101,115,111,108,118,101, 95,116,101,109,112, - 108, 97,116,101, 95,116,121,112,101,115, 40,115,101,108,102, - 46,116,121,112,101, 41, 10, 32,101,110,100, 10, 10, 45, 45, - 10, 45, 45, 32, 45, 45, 32,105,102, 32,114,101,116,117,114, - 110,105,110,103, 32,118, 97,108,117,101, 44, 32, 97,117,116, - 111,109, 97,116,105, 99, 97,108,108,121, 32,115,101,116, 32, - 100,101,102, 97,117,108,116, 32,118, 97,108,117,101, 10, 45, - 45, 32,105,102, 32,115,101,108,102, 46,114,101,116, 32,126, - 61, 32, 39, 39, 32, 97,110,100, 32,115,101,108,102, 46,100, - 101,102, 32, 61, 61, 32, 39, 39, 32,116,104,101,110, 10, 45, - 45, 32, 32,115,101,108,102, 46,100,101,102, 32, 61, 32, 39, - 48, 39, 10, 45, 45, 32,101,110,100, 10, 45, 45, 10, 10,101, - 110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,114,101, - 115,111,108,118,101, 95,116,101,109,112,108, 97,116,101, 95, - 116,121,112,101,115, 40,116,121,112,101, 41, 10, 10, 9,105, - 102, 32,105,115, 98, 97,115,105, 99, 40,116,121,112,101, 41, - 32,116,104,101,110, 10, 9, 9,114,101,116,117,114,110, 32, - 116,121,112,101, 10, 9,101,110,100, 10, 9,108,111, 99, 97, - 108, 32, 98, 44, 95, 44,109, 32, 61, 32,115,116,114,105,110, - 103, 46,102,105,110,100, 40,116,121,112,101, 44, 32, 34, 40, - 37, 98, 60, 62, 41, 34, 41, 10, 9,105,102, 32, 98, 32,116, - 104,101,110, 10, 10, 9, 9,109, 32, 61, 32,115,112,108,105, - 116, 95, 99, 95,116,111,107,101,110,115, 40,115,116,114,105, - 110,103, 46,115,117, 98, 40,109, 44, 32, 50, 44, 32, 45, 50, - 41, 44, 32, 34, 44, 34, 41, 10, 9, 9,102,111,114, 32,105, - 61, 49, 44, 32,116, 97, 98,108,101, 46,103,101,116,110, 40, - 109, 41, 32,100,111, 10, 9, 9, 9,109, 91,105, 93, 32, 61, - 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,109, 91, - 105, 93, 44, 34, 37,115, 42, 40, 91, 37, 42, 38, 93, 41, 34, - 44, 32, 34, 37, 49, 34, 41, 10, 9, 9, 9,105,102, 32,110, - 111,116, 32,105,115, 98, 97,115,105, 99, 40,109, 91,105, 93, - 41, 32,116,104,101,110, 10, 9, 9, 9, 9,105,102, 32,110, - 111,116, 32,105,115,101,110,117,109, 40,109, 91,105, 93, 41, - 32,116,104,101,110, 32, 95, 44, 32,109, 91,105, 93, 32, 61, - 32, 97,112,112,108,121,116,121,112,101,100,101,102, 40, 34, - 34, 44, 32,109, 91,105, 93, 41, 32,101,110,100, 10, 9, 9, - 9, 9,109, 91,105, 93, 32, 61, 32,102,105,110,100,116,121, - 112,101, 40,109, 91,105, 93, 41, 32,111,114, 32,109, 91,105, - 93, 10, 9, 9, 9, 9,109, 91,105, 93, 32, 61, 32,114,101, - 115,111,108,118,101, 95,116,101,109,112,108, 97,116,101, 95, - 116,121,112,101,115, 40,109, 91,105, 93, 41, 10, 9, 9, 9, - 101,110,100, 10, 9, 9,101,110,100, 10, 10, 9, 9,108,111, - 99, 97,108, 32, 98, 44,105, 10, 9, 9,116,121,112,101, 44, - 98, 44,105, 32, 61, 32, 98,114,101, 97,107, 95,116,101,109, - 112,108, 97,116,101, 40,116,121,112,101, 41, 10, 45, 45,112, - 114,105,110,116, 40, 34, 99,111,110, 99, 97,116, 32,105,115, - 32, 34, 44, 99,111,110, 99, 97,116, 40,109, 44, 32, 49, 44, - 32,109, 46,110, 41, 41, 10, 9, 9,108,111, 99, 97,108, 32, - 116,101,109,112,108, 97,116,101, 95,112, 97,114,116, 32, 61, - 32, 34, 60, 34, 46, 46, 99,111,110, 99, 97,116, 40,109, 44, - 32, 49, 44, 32,109, 46,110, 44, 32, 34, 44, 34, 41, 46, 46, - 34, 62, 34, 10, 9, 9,116,121,112,101, 32, 61, 32,114,101, - 98,117,105,108,100, 95,116,101,109,112,108, 97,116,101, 40, - 116,121,112,101, 44, 32, 98, 44, 32,116,101,109,112,108, 97, - 116,101, 95,112, 97,114,116, 41, 10, 9, 9,116,121,112,101, - 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, - 116,121,112,101, 44, 32, 34, 62, 62, 34, 44, 32, 34, 62, 32, - 62, 34, 41, 10, 9,101,110,100, 10, 9,114,101,116,117,114, - 110, 32,116,121,112,101, 10,101,110,100, 10, 10,102,117,110, - 99,116,105,111,110, 32, 98,114,101, 97,107, 95,116,101,109, - 112,108, 97,116,101, 40,115, 41, 10, 9,108,111, 99, 97,108, - 32, 98, 44,101, 44,116,105,109,112,108, 32, 61, 32,115,116, - 114,105,110,103, 46,102,105,110,100, 40,115, 44, 32, 34, 40, - 37, 98, 60, 62, 41, 34, 41, 10, 9,105,102, 32,116,105,109, - 112,108, 32,116,104,101,110, 10, 9, 9,115, 32, 61, 32,115, - 116,114,105,110,103, 46,103,115,117, 98, 40,115, 44, 32, 34, - 37, 98, 60, 62, 34, 44, 32, 34, 34, 41, 10, 9, 9,114,101, - 116,117,114,110, 32,115, 44, 32, 98, 44, 32,116,105,109,112, - 108, 10, 9,101,108,115,101, 10, 9, 9,114,101,116,117,114, - 110, 32,115, 44, 32, 48, 44, 32,110,105,108, 10, 9,101,110, - 100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, - 32,114,101, 98,117,105,108,100, 95,116,101,109,112,108, 97, - 116,101, 40,115, 44, 32, 98, 44, 32,116,105,109,112,108, 41, - 10, 10, 9,105,102, 32, 98, 32, 61, 61, 32, 48, 32,116,104, - 101,110, 10, 9, 9,114,101,116,117,114,110, 32,115, 10, 9, - 101,110,100, 10, 10, 9,114,101,116,117,114,110, 32,115,116, - 114,105,110,103, 46,115,117, 98, 40,115, 44, 32, 49, 44, 32, - 98, 45, 49, 41, 46, 46,116,105,109,112,108, 46, 46,115,116, - 114,105,110,103, 46,115,117, 98, 40,115, 44, 32, 98, 44, 32, - 45, 49, 41, 10,101,110,100, 10, 10, 45, 45, 32, 80,114,105, - 110,116, 32,109,101,116,104,111,100, 10,102,117,110, 99,116, - 105,111,110, 32, 99,108, 97,115,115, 68,101, 99,108, 97,114, - 97,116,105,111,110, 58,112,114,105,110,116, 32, 40,105,100, - 101,110,116, 44, 99,108,111,115,101, 41, 10, 32,112,114,105, - 110,116, 40,105,100,101,110,116, 46, 46, 34, 68,101, 99,108, - 97,114, 97,116,105,111,110,123, 34, 41, 10, 32,112,114,105, - 110,116, 40,105,100,101,110,116, 46, 46, 34, 32,109,111,100, - 32, 32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,109,111, - 100, 46, 46, 34, 39, 44, 34, 41, 10, 32,112,114,105,110,116, - 40,105,100,101,110,116, 46, 46, 34, 32,116,121,112,101, 32, - 61, 32, 39, 34, 46, 46,115,101,108,102, 46,116,121,112,101, - 46, 46, 34, 39, 44, 34, 41, 10, 32,112,114,105,110,116, 40, - 105,100,101,110,116, 46, 46, 34, 32,112,116,114, 32, 32, 61, - 32, 39, 34, 46, 46,115,101,108,102, 46,112,116,114, 46, 46, - 34, 39, 44, 34, 41, 10, 32,112,114,105,110,116, 40,105,100, - 101,110,116, 46, 46, 34, 32,110, 97,109,101, 32, 61, 32, 39, - 34, 46, 46,115,101,108,102, 46,110, 97,109,101, 46, 46, 34, - 39, 44, 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101, - 110,116, 46, 46, 34, 32,100,105,109, 32, 32, 61, 32, 39, 34, - 46, 46,115,101,108,102, 46,100,105,109, 46, 46, 34, 39, 44, - 34, 41, 10, 32,112,114,105,110,116, 40,105,100,101,110,116, - 46, 46, 34, 32,100,101,102, 32, 32, 61, 32, 39, 34, 46, 46, - 115,101,108,102, 46,100,101,102, 46, 46, 34, 39, 44, 34, 41, - 10, 32,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, - 34, 32,114,101,116, 32, 32, 61, 32, 39, 34, 46, 46,115,101, - 108,102, 46,114,101,116, 46, 46, 34, 39, 44, 34, 41, 10, 32, - 112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34,125, - 34, 46, 46, 99,108,111,115,101, 41, 10,101,110,100, 10, 10, - 45, 45, 32, 99,104,101, 99,107, 32,105,102, 32, 97,114,114, - 97,121, 32,111,102, 32,118, 97,108,117,101,115, 32, 97,114, - 101, 32,114,101,116,117,114,110,101,100, 32,116,111, 32, 76, - 117, 97, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97, - 115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58,114, - 101,113,117,105,114,101, 99,111,108,108,101, 99,116,105,111, - 110, 32, 40,116, 41, 10, 32,105,102, 32,115,101,108,102, 46, - 109,111,100, 32,126, 61, 32, 39, 99,111,110,115,116, 39, 32, - 97,110,100, 10, 9, 32, 32, 32, 32,115,101,108,102, 46,100, - 105,109, 32, 97,110,100, 32,115,101,108,102, 46,100,105,109, - 32,126, 61, 32, 39, 39, 32, 97,110,100, 10, 9, 9, 9, 9, - 32,110,111,116, 32,105,115, 98, 97,115,105, 99, 40,115,101, - 108,102, 46,116,121,112,101, 41, 32, 97,110,100, 10, 9, 9, - 9, 9, 32,115,101,108,102, 46,112,116,114, 32, 61, 61, 32, - 39, 39, 32, 97,110,100, 32,115,101,108,102, 58, 99,104,101, - 99,107, 95,112,117, 98,108,105, 99, 95, 97, 99, 99,101,115, - 115, 40, 41, 32,116,104,101,110, 10, 9, 9,108,111, 99, 97, - 108, 32,116,121,112,101, 32, 61, 32,103,115,117, 98, 40,115, - 101,108,102, 46,116,121,112,101, 44, 34, 37,115, 42, 99,111, - 110,115,116, 37,115, 43, 34, 44, 34, 34, 41, 10, 9, 9,116, - 91,116,121,112,101, 93, 32, 61, 32, 34,116,111,108,117, 97, - 95, 99,111,108,108,101, 99,116, 95, 34, 32, 46, 46, 32, 99, - 108,101, 97,110, 95,116,101,109,112,108, 97,116,101, 40,116, - 121,112,101, 41, 10, 9, 9,114,101,116,117,114,110, 32,116, - 114,117,101, 10, 9,101,110,100, 10, 9,114,101,116,117,114, - 110, 32,102, 97,108,115,101, 10,101,110,100, 10, 10, 45, 45, - 32,100,101, 99,108, 97,114,101, 32,116, 97,103, 10,102,117, - 110, 99,116,105,111,110, 32, 99,108, 97,115,115, 68,101, 99, - 108, 97,114, 97,116,105,111,110, 58,100,101, 99,108,116,121, - 112,101, 32, 40, 41, 10, 10, 9,115,101,108,102, 46,116,121, - 112,101, 32, 61, 32,116,121,112,101,118, 97,114, 40,115,101, - 108,102, 46,116,121,112,101, 41, 10, 9,105,102, 32,115,116, - 114,102,105,110,100, 40,115,101,108,102, 46,109,111,100, 44, - 39, 99,111,110,115,116, 39, 41, 32,116,104,101,110, 10, 9, - 9,115,101,108,102, 46,116,121,112,101, 32, 61, 32, 39, 99, - 111,110,115,116, 32, 39, 46, 46,115,101,108,102, 46,116,121, - 112,101, 10, 9, 9,115,101,108,102, 46,109,111,100, 32, 61, - 32,103,115,117, 98, 40,115,101,108,102, 46,109,111,100, 44, - 39, 99,111,110,115,116, 37,115, 42, 39, 44, 39, 39, 41, 10, - 9,101,110,100, 10,101,110,100, 10, 10, 10, 45, 45, 32,111, - 117,116,112,117,116, 32,116,121,112,101, 32, 99,104,101, 99, - 107,105,110,103, 10,102,117,110, 99,116,105,111,110, 32, 99, - 108, 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, - 58,111,117,116, 99,104,101, 99,107,116,121,112,101, 32, 40, - 110, 97,114,103, 41, 10, 32,108,111, 99, 97,108, 32,100,101, - 102, 10, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,105,115, - 98, 97,115,105, 99, 40,115,101,108,102, 46,116,121,112,101, - 41, 10, 32,105,102, 32,115,101,108,102, 46,100,101,102,126, - 61, 39, 39, 32,116,104,101,110, 10, 32, 32,100,101,102, 32, - 61, 32, 49, 10, 32,101,108,115,101, 10, 32, 32,100,101,102, - 32, 61, 32, 48, 10, 32,101,110,100, 10, 32,105,102, 32,115, - 101,108,102, 46,100,105,109, 32,126, 61, 32, 39, 39, 32,116, - 104,101,110, 10, 9, 45, 45,105,102, 32,116, 61, 61, 39,115, - 116,114,105,110,103, 39, 32,116,104,101,110, 10, 9, 45, 45, - 9,114,101,116,117,114,110, 32, 39,116,111,108,117, 97, 95, - 105,115,115,116,114,105,110,103, 97,114,114, 97,121, 40,116, - 111,108,117, 97, 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, - 46, 39, 44, 39, 46, 46,100,101,102, 46, 46, 39, 44, 38,116, - 111,108,117, 97, 95,101,114,114, 41, 39, 10, 9, 45, 45,101, - 108,115,101, 10, 9,114,101,116,117,114,110, 32, 39, 33,116, - 111,108,117, 97, 95,105,115,116, 97, 98,108,101, 40,116,111, - 108,117, 97, 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, 46, - 39, 44, 48, 44, 38,116,111,108,117, 97, 95,101,114,114, 41, - 39, 10, 32, 9, 45, 45,101,110,100, 10, 32,101,108,115,101, - 105,102, 32,116, 32,116,104,101,110, 10, 9,114,101,116,117, - 114,110, 32, 39, 33,116,111,108,117, 97, 95,105,115, 39, 46, - 46,116, 46, 46, 39, 40,116,111,108,117, 97, 95, 83, 44, 39, - 46, 46,110, 97,114,103, 46, 46, 39, 44, 39, 46, 46,100,101, - 102, 46, 46, 39, 44, 38,116,111,108,117, 97, 95,101,114,114, - 41, 39, 10, 32,101,108,115,101, 10, 32, 32,108,111, 99, 97, - 108, 32,105,115, 95,102,117,110, 99, 32, 61, 32,103,101,116, - 95,105,115, 95,102,117,110, 99,116,105,111,110, 40,115,101, - 108,102, 46,116,121,112,101, 41, 10, 32, 32,105,102, 32,115, - 101,108,102, 46,112,116,114, 32, 61, 61, 32, 39, 38, 39, 32, - 111,114, 32,115,101,108,102, 46,112,116,114, 32, 61, 61, 32, - 39, 39, 32,116,104,101,110, 10, 32, 32, 9,114,101,116,117, - 114,110, 32, 39, 40,116,111,108,117, 97, 95,105,115,118, 97, - 108,117,101,110,105,108, 40,116,111,108,117, 97, 95, 83, 44, - 39, 46, 46,110, 97,114,103, 46, 46, 39, 44, 38,116,111,108, - 117, 97, 95,101,114,114, 41, 32,124,124, 32, 33, 39, 46, 46, - 105,115, 95,102,117,110, 99, 46, 46, 39, 40,116,111,108,117, - 97, 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, 46, 39, 44, - 34, 39, 46, 46,115,101,108,102, 46,116,121,112,101, 46, 46, - 39, 34, 44, 39, 46, 46,100,101,102, 46, 46, 39, 44, 38,116, - 111,108,117, 97, 95,101,114,114, 41, 41, 39, 10, 32, 32,101, - 108,115,101, 10, 9,114,101,116,117,114,110, 32, 39, 33, 39, - 46, 46,105,115, 95,102,117,110, 99, 46, 46, 39, 40,116,111, - 108,117, 97, 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, 46, - 39, 44, 34, 39, 46, 46,115,101,108,102, 46,116,121,112,101, - 46, 46, 39, 34, 44, 39, 46, 46,100,101,102, 46, 46, 39, 44, - 38,116,111,108,117, 97, 95,101,114,114, 41, 39, 10, 32, 32, - 101,110,100, 10, 32,101,110,100, 10,101,110,100, 10, 10,102, - 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 68,101, - 99,108, 97,114, 97,116,105,111,110, 58, 98,117,105,108,100, - 100,101, 99,108, 97,114, 97,116,105,111,110, 32, 40,110, 97, - 114,103, 44, 32, 99,112,108,117,115,112,108,117,115, 41, 10, - 32,108,111, 99, 97,108, 32, 97,114,114, 97,121, 32, 61, 32, - 115,101,108,102, 46,100,105,109, 32,126, 61, 32, 39, 39, 32, - 97,110,100, 32,116,111,110,117,109, 98,101,114, 40,115,101, - 108,102, 46,100,105,109, 41, 61, 61,110,105,108, 10, 9,108, - 111, 99, 97,108, 32,108,105,110,101, 32, 61, 32, 34, 34, 10, - 32,108,111, 99, 97,108, 32,112,116,114, 32, 61, 32, 39, 39, - 10, 32,108,111, 99, 97,108, 32,109,111,100, 10, 32,108,111, - 99, 97,108, 32,116,121,112,101, 32, 61, 32,115,101,108,102, - 46,116,121,112,101, 10, 32,108,111, 99, 97,108, 32,110, 99, - 116,121,112,101, 32, 61, 32,103,115,117, 98, 40,115,101,108, - 102, 46,116,121,112,101, 44, 39, 99,111,110,115,116, 37,115, - 43, 39, 44, 39, 39, 41, 10, 32,105,102, 32,115,101,108,102, - 46,100,105,109, 32,126, 61, 32, 39, 39, 32,116,104,101,110, - 10, 9, 32,116,121,112,101, 32, 61, 32,103,115,117, 98, 40, - 115,101,108,102, 46,116,121,112,101, 44, 39, 99,111,110,115, - 116, 37,115, 43, 39, 44, 39, 39, 41, 32, 32, 45, 45, 32,101, - 108,105,109,105,110, 97,116,101,115, 32, 99,111,110,115,116, - 32,109,111,100,105,102,105,101,114, 32,102,111,114, 32, 97, - 114,114, 97,121,115, 10, 32,101,110,100, 10, 32,105,102, 32, - 115,101,108,102, 46,112,116,114,126, 61, 39, 39, 32, 97,110, - 100, 32,110,111,116, 32,105,115, 98, 97,115,105, 99, 40,116, - 121,112,101, 41, 32,116,104,101,110, 32,112,116,114, 32, 61, - 32, 39, 42, 39, 32,101,110,100, 10, 32,108,105,110,101, 32, - 61, 32, 99,111,110, 99, 97,116,112, 97,114, 97,109, 40,108, - 105,110,101, 44, 34, 32, 34, 44,115,101,108,102, 46,109,111, - 100, 44,116,121,112,101, 44,112,116,114, 41, 10, 32,105,102, - 32, 97,114,114, 97,121, 32,116,104,101,110, 10, 32, 32,108, - 105,110,101, 32, 61, 32, 99,111,110, 99, 97,116,112, 97,114, - 97,109, 40,108,105,110,101, 44, 39, 42, 39, 41, 10, 32,101, - 110,100, 10, 32,108,105,110,101, 32, 61, 32, 99,111,110, 99, - 97,116,112, 97,114, 97,109, 40,108,105,110,101, 44,115,101, - 108,102, 46,110, 97,109,101, 41, 10, 32,105,102, 32,115,101, - 108,102, 46,100,105,109, 32,126, 61, 32, 39, 39, 32,116,104, - 101,110, 10, 32, 32,105,102, 32,116,111,110,117,109, 98,101, - 114, 40,115,101,108,102, 46,100,105,109, 41,126, 61,110,105, - 108, 32,116,104,101,110, 10, 32, 32, 32,108,105,110,101, 32, - 61, 32, 99,111,110, 99, 97,116,112, 97,114, 97,109, 40,108, - 105,110,101, 44, 39, 91, 39, 44,115,101,108,102, 46,100,105, - 109, 44, 39, 93, 59, 39, 41, 10, 32, 32,101,108,115,101, 10, - 9,105,102, 32, 99,112,108,117,115,112,108,117,115, 32,116, - 104,101,110, 10, 9, 9,108,105,110,101, 32, 61, 32, 99,111, - 110, 99, 97,116,112, 97,114, 97,109, 40,108,105,110,101, 44, - 39, 32, 61, 32, 77,116,111,108,117, 97, 95,110,101,119, 95, - 100,105,109, 40, 39, 44,116,121,112,101, 44,112,116,114, 44, - 39, 44, 32, 39, 46, 46,115,101,108,102, 46,100,105,109, 46, - 46, 39, 41, 59, 39, 41, 10, 9,101,108,115,101, 10, 9, 9, - 108,105,110,101, 32, 61, 32, 99,111,110, 99, 97,116,112, 97, - 114, 97,109, 40,108,105,110,101, 44, 39, 32, 61, 32, 40, 39, - 44,116,121,112,101, 44,112,116,114, 44, 39, 42, 41, 39, 44, - 10, 9, 9, 39,109, 97,108,108,111, 99, 40, 40, 39, 44,115, - 101,108,102, 46,100,105,109, 44, 39, 41, 42,115,105,122,101, - 111,102, 40, 39, 44,116,121,112,101, 44,112,116,114, 44, 39, - 41, 41, 59, 39, 41, 10, 9,101,110,100, 10, 32, 32,101,110, - 100, 10, 32,101,108,115,101, 10, 32, 32,108,111, 99, 97,108, - 32,116, 32, 61, 32,105,115, 98, 97,115,105, 99, 40,116,121, - 112,101, 41, 10, 32, 32,108,105,110,101, 32, 61, 32, 99,111, - 110, 99, 97,116,112, 97,114, 97,109, 40,108,105,110,101, 44, - 39, 32, 61, 32, 39, 41, 10, 32, 32,105,102, 32,116, 32, 61, - 61, 32, 39,115,116, 97,116,101, 39, 32,116,104,101,110, 10, - 32, 32, 9,108,105,110,101, 32, 61, 32, 99,111,110, 99, 97, - 116,112, 97,114, 97,109, 40,108,105,110,101, 44, 32, 39,116, - 111,108,117, 97, 95, 83, 59, 39, 41, 10, 32, 32,101,108,115, - 101, 10, 32, 32, 9, 45, 45,112,114,105,110,116, 40, 34,116, - 32,105,115, 32, 34, 46, 46,116,111,115,116,114,105,110,103, - 40,116, 41, 46, 46, 34, 44, 32,112,116,114, 32,105,115, 32, - 34, 46, 46,116,111,115,116,114,105,110,103, 40,115,101,108, - 102, 46,112,116,114, 41, 41, 10, 32, 32, 9,105,102, 32,116, - 32, 61, 61, 32, 39,110,117,109, 98,101,114, 39, 32, 97,110, - 100, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,115, - 101,108,102, 46,112,116,114, 44, 32, 34, 37, 42, 34, 41, 32, - 116,104,101,110, 10, 32, 32, 9, 9,116, 32, 61, 32, 39,117, - 115,101,114,100, 97,116, 97, 39, 10, 32, 32, 9,101,110,100, - 10, 9,105,102, 32,110,111,116, 32,116, 32, 97,110,100, 32, - 112,116,114, 61, 61, 39, 39, 32,116,104,101,110, 32,108,105, - 110,101, 32, 61, 32, 99,111,110, 99, 97,116,112, 97,114, 97, - 109, 40,108,105,110,101, 44, 39, 42, 39, 41, 32,101,110,100, - 10, 9,108,105,110,101, 32, 61, 32, 99,111,110, 99, 97,116, - 112, 97,114, 97,109, 40,108,105,110,101, 44, 39, 40, 40, 39, - 44,115,101,108,102, 46,109,111,100, 44,116,121,112,101, 41, - 10, 9,105,102, 32,110,111,116, 32,116, 32,116,104,101,110, - 10, 9, 9,108,105,110,101, 32, 61, 32, 99,111,110, 99, 97, - 116,112, 97,114, 97,109, 40,108,105,110,101, 44, 39, 42, 39, - 41, 10, 9,101,110,100, 10, 9,108,105,110,101, 32, 61, 32, - 99,111,110, 99, 97,116,112, 97,114, 97,109, 40,108,105,110, - 101, 44, 39, 41, 32, 39, 41, 10, 9,105,102, 32,105,115,101, - 110,117,109, 40,110, 99,116,121,112,101, 41, 32,116,104,101, - 110, 10, 9, 9,108,105,110,101, 32, 61, 32, 99,111,110, 99, - 97,116,112, 97,114, 97,109, 40,108,105,110,101, 44, 39, 40, - 105,110,116, 41, 32, 39, 41, 10, 9,101,110,100, 10, 9,108, - 111, 99, 97,108, 32,100,101,102, 32, 61, 32, 48, 10, 9,105, - 102, 32,115,101,108,102, 46,100,101,102, 32,126, 61, 32, 39, - 39, 32,116,104,101,110, 10, 9, 9,100,101,102, 32, 61, 32, - 115,101,108,102, 46,100,101,102, 10, 9, 9,105,102, 32, 40, - 112,116,114, 32, 61, 61, 32, 39, 39, 32,111,114, 32,115,101, - 108,102, 46,112,116,114, 32, 61, 61, 32, 39, 38, 39, 41, 32, - 97,110,100, 32,110,111,116, 32,116, 32,116,104,101,110, 10, - 9, 9, 9,100,101,102, 32, 61, 32, 34, 40,118,111,105,100, - 42, 41, 38, 40, 99,111,110,115,116, 32, 34, 46, 46,116,121, - 112,101, 46, 46, 34, 41, 34, 46, 46,100,101,102, 10, 9, 9, - 101,110,100, 10, 9,101,110,100, 10, 9,105,102, 32,116, 32, - 116,104,101,110, 10, 9, 9,108,105,110,101, 32, 61, 32, 99, - 111,110, 99, 97,116,112, 97,114, 97,109, 40,108,105,110,101, - 44, 39,116,111,108,117, 97, 95,116,111, 39, 46, 46,116, 44, - 39, 40,116,111,108,117, 97, 95, 83, 44, 39, 44,110, 97,114, - 103, 44, 39, 44, 39, 44,100,101,102, 44, 39, 41, 41, 59, 39, - 41, 10, 9,101,108,115,101, 10, 9, 9,108,111, 99, 97,108, - 32,116,111, 95,102,117,110, 99, 32, 61, 32,103,101,116, 95, - 116,111, 95,102,117,110, 99,116,105,111,110, 40,116,121,112, - 101, 41, 10, 9, 9,108,105,110,101, 32, 61, 32, 99,111,110, - 99, 97,116,112, 97,114, 97,109, 40,108,105,110,101, 44,116, - 111, 95,102,117,110, 99, 46, 46, 39, 40,116,111,108,117, 97, - 95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44, 39, 44,100, - 101,102, 44, 39, 41, 41, 59, 39, 41, 10, 9,101,110,100, 10, - 32, 32,101,110,100, 10, 32,101,110,100, 10, 9,114,101,116, - 117,114,110, 32,108,105,110,101, 10,101,110,100, 10, 10, 45, - 45, 32, 68,101, 99,108, 97,114,101, 32,118, 97,114,105, 97, - 98,108,101, 10,102,117,110, 99,116,105,111,110, 32, 99,108, - 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58, - 100,101, 99,108, 97,114,101, 32, 40,110, 97,114,103, 41, 10, - 32,105,102, 32,115,101,108,102, 46,100,105,109, 32,126, 61, - 32, 39, 39, 32, 97,110,100, 32,116,111,110,117,109, 98,101, - 114, 40,115,101,108,102, 46,100,105,109, 41, 61, 61,110,105, - 108, 32,116,104,101,110, 10, 9, 32,111,117,116,112,117,116, - 40, 39, 35,105,102,100,101,102, 32, 95, 95, 99,112,108,117, - 115,112,108,117,115, 92,110, 39, 41, 10, 9, 9,111,117,116, - 112,117,116, 40,115,101,108,102, 58, 98,117,105,108,100,100, - 101, 99,108, 97,114, 97,116,105,111,110, 40,110, 97,114,103, - 44,116,114,117,101, 41, 41, 10, 9, 9,111,117,116,112,117, - 116, 40, 39, 35,101,108,115,101, 92,110, 39, 41, 10, 9, 9, - 111,117,116,112,117,116, 40,115,101,108,102, 58, 98,117,105, - 108,100,100,101, 99,108, 97,114, 97,116,105,111,110, 40,110, - 97,114,103, 44,102, 97,108,115,101, 41, 41, 10, 9, 32,111, - 117,116,112,117,116, 40, 39, 35,101,110,100,105,102, 92,110, - 39, 41, 10, 9,101,108,115,101, 10, 9, 9,111,117,116,112, - 117,116, 40,115,101,108,102, 58, 98,117,105,108,100,100,101, - 99,108, 97,114, 97,116,105,111,110, 40,110, 97,114,103, 44, - 102, 97,108,115,101, 41, 41, 10, 9,101,110,100, 10,101,110, - 100, 10, 10, 45, 45, 32, 71,101,116, 32,112, 97,114, 97,109, - 101,116,101,114, 32,118, 97,108,117,101, 10,102,117,110, 99, - 116,105,111,110, 32, 99,108, 97,115,115, 68,101, 99,108, 97, - 114, 97,116,105,111,110, 58,103,101,116, 97,114,114, 97,121, - 32, 40,110, 97,114,103, 41, 10, 32,105,102, 32,115,101,108, - 102, 46,100,105,109, 32,126, 61, 32, 39, 39, 32,116,104,101, - 110, 10, 9, 32,108,111, 99, 97,108, 32,116,121,112,101, 32, - 61, 32,103,115,117, 98, 40,115,101,108,102, 46,116,121,112, - 101, 44, 39, 99,111,110,115,116, 32, 39, 44, 39, 39, 41, 10, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32,123, 39, 41, - 10, 9, 32,111,117,116,112,117,116, 40, 39, 35,105,102,110, - 100,101,102, 32, 84, 79, 76, 85, 65, 95, 82, 69, 76, 69, 65, - 83, 69, 92,110, 39, 41, 10, 32, 32,108,111, 99, 97,108, 32, - 100,101,102, 59, 32,105,102, 32,115,101,108,102, 46,100,101, - 102,126, 61, 39, 39, 32,116,104,101,110, 32,100,101,102, 61, - 49, 32,101,108,115,101, 32,100,101,102, 61, 48, 32,101,110, - 100, 10, 9, 9,108,111, 99, 97,108, 32,116, 32, 61, 32,105, - 115, 98, 97,115,105, 99, 40,116,121,112,101, 41, 10, 9, 9, - 105,102, 32, 40,116, 41, 32,116,104,101,110, 10, 9, 9, 32, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32,105,102, - 32, 40, 33,116,111,108,117, 97, 95,105,115, 39, 46, 46,116, - 46, 46, 39, 97,114,114, 97,121, 40,116,111,108,117, 97, 95, - 83, 44, 39, 44,110, 97,114,103, 44, 39, 44, 39, 44,115,101, - 108,102, 46,100,105,109, 44, 39, 44, 39, 44,100,101,102, 44, - 39, 44, 38,116,111,108,117, 97, 95,101,114,114, 41, 41, 39, - 41, 10, 9, 9,101,108,115,101, 10, 9, 9, 32, 32, 32,111, - 117,116,112,117,116, 40, 39, 32, 32, 32,105,102, 32, 40, 33, - 116,111,108,117, 97, 95,105,115,117,115,101,114,116,121,112, - 101, 97,114,114, 97,121, 40,116,111,108,117, 97, 95, 83, 44, - 39, 44,110, 97,114,103, 44, 39, 44, 34, 39, 44,116,121,112, - 101, 44, 39, 34, 44, 39, 44,115,101,108,102, 46,100,105,109, - 44, 39, 44, 39, 44,100,101,102, 44, 39, 44, 38,116,111,108, - 117, 97, 95,101,114,114, 41, 41, 39, 41, 10, 9, 9,101,110, - 100, 10, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, - 32,103,111,116,111, 32,116,111,108,117, 97, 95,108,101,114, - 114,111,114, 59, 39, 41, 10, 32, 32,111,117,116,112,117,116, - 40, 39, 32, 32, 32,101,108,115,101, 92,110, 39, 41, 10, 9, - 32,111,117,116,112,117,116, 40, 39, 35,101,110,100,105,102, - 92,110, 39, 41, 10, 32, 32,111,117,116,112,117,116, 40, 39, - 32, 32, 32,123, 39, 41, 10, 32, 32,111,117,116,112,117,116, - 40, 39, 32, 32, 32, 32,105,110,116, 32,105, 59, 39, 41, 10, - 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32,102, - 111,114, 40,105, 61, 48, 59, 32,105, 60, 39, 46, 46,115,101, - 108,102, 46,100,105,109, 46, 46, 39, 59,105, 43, 43, 41, 39, - 41, 10, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,105, - 115, 98, 97,115,105, 99, 40,116,121,112,101, 41, 10, 32, 32, - 108,111, 99, 97,108, 32,112,116,114, 32, 61, 32, 39, 39, 10, - 32, 32,105,102, 32,115,101,108,102, 46,112,116,114,126, 61, - 39, 39, 32,116,104,101,110, 32,112,116,114, 32, 61, 32, 39, - 42, 39, 32,101,110,100, 10, 32, 32,111,117,116,112,117,116, - 40, 39, 32, 32, 32, 39, 44,115,101,108,102, 46,110, 97,109, - 101, 46, 46, 39, 91,105, 93, 32, 61, 32, 39, 41, 10, 32, 32, - 105,102, 32,110,111,116, 32,116, 32, 97,110,100, 32,112,116, - 114, 61, 61, 39, 39, 32,116,104,101,110, 32,111,117,116,112, - 117,116, 40, 39, 42, 39, 41, 32,101,110,100, 10, 32, 32,111, - 117,116,112,117,116, 40, 39, 40, 40, 39, 44,116,121,112,101, - 41, 10, 32, 32,105,102, 32,110,111,116, 32,116, 32,116,104, - 101,110, 10, 32, 32, 32,111,117,116,112,117,116, 40, 39, 42, - 39, 41, 10, 32, 32,101,110,100, 10, 32, 32,111,117,116,112, - 117,116, 40, 39, 41, 32, 39, 41, 10, 32, 32,108,111, 99, 97, - 108, 32,100,101,102, 32, 61, 32, 48, 10, 32, 32,105,102, 32, - 115,101,108,102, 46,100,101,102, 32,126, 61, 32, 39, 39, 32, - 116,104,101,110, 32,100,101,102, 32, 61, 32,115,101,108,102, - 46,100,101,102, 32,101,110,100, 10, 32, 32,105,102, 32,116, - 32,116,104,101,110, 10, 32, 32, 32,111,117,116,112,117,116, - 40, 39,116,111,108,117, 97, 95,116,111,102,105,101,108,100, - 39, 46, 46,116, 46, 46, 39, 40,116,111,108,117, 97, 95, 83, - 44, 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49, 44, 39, - 44,100,101,102, 44, 39, 41, 41, 59, 39, 41, 10, 32, 32,101, - 108,115,101, 10, 32, 32, 32,111,117,116,112,117,116, 40, 39, - 116,111,108,117, 97, 95,116,111,102,105,101,108,100,117,115, - 101,114,116,121,112,101, 40,116,111,108,117, 97, 95, 83, 44, - 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49, 44, 39, 44, - 100,101,102, 44, 39, 41, 41, 59, 39, 41, 10, 32, 32,101,110, - 100, 10, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, - 125, 39, 41, 10, 32, 32,111,117,116,112,117,116, 40, 39, 32, - 32,125, 39, 41, 10, 32,101,110,100, 10,101,110,100, 10, 10, - 45, 45, 32, 71,101,116, 32,112, 97,114, 97,109,101,116,101, - 114, 32,118, 97,108,117,101, 10,102,117,110, 99,116,105,111, - 110, 32, 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116, - 105,111,110, 58,115,101,116, 97,114,114, 97,121, 32, 40,110, - 97,114,103, 41, 10, 32,105,102, 32,110,111,116, 32,115,116, - 114,102,105,110,100, 40,115,101,108,102, 46,116,121,112,101, - 44, 39, 99,111,110,115,116, 37,115, 43, 39, 41, 32, 97,110, - 100, 32,115,101,108,102, 46,100,105,109, 32,126, 61, 32, 39, - 39, 32,116,104,101,110, 10, 9, 32,108,111, 99, 97,108, 32, - 116,121,112,101, 32, 61, 32,103,115,117, 98, 40,115,101,108, - 102, 46,116,121,112,101, 44, 39, 99,111,110,115,116, 32, 39, - 44, 39, 39, 41, 10, 32, 32,111,117,116,112,117,116, 40, 39, - 32, 32,123, 39, 41, 10, 32, 32,111,117,116,112,117,116, 40, - 39, 32, 32, 32,105,110,116, 32,105, 59, 39, 41, 10, 32, 32, - 111,117,116,112,117,116, 40, 39, 32, 32, 32,102,111,114, 40, - 105, 61, 48, 59, 32,105, 60, 39, 46, 46,115,101,108,102, 46, - 100,105,109, 46, 46, 39, 59,105, 43, 43, 41, 39, 41, 10, 32, - 32,108,111, 99, 97,108, 32,116, 44, 99,116, 32, 61, 32,105, - 115, 98, 97,115,105, 99, 40,116,121,112,101, 41, 10, 32, 32, - 105,102, 32,116, 32,116,104,101,110, 10, 32, 32, 32,111,117, - 116,112,117,116, 40, 39, 32, 32, 32, 32,116,111,108,117, 97, - 95,112,117,115,104,102,105,101,108,100, 39, 46, 46,116, 46, - 46, 39, 40,116,111,108,117, 97, 95, 83, 44, 39, 44,110, 97, - 114,103, 44, 39, 44,105, 43, 49, 44, 40, 39, 44, 99,116, 44, - 39, 41, 39, 44,115,101,108,102, 46,110, 97,109,101, 44, 39, - 91,105, 93, 41, 59, 39, 41, 10, 32, 32,101,108,115,101, 10, - 32, 32, 32,105,102, 32,115,101,108,102, 46,112,116,114, 32, - 61, 61, 32, 39, 39, 32,116,104,101,110, 10, 32, 32, 32, 32, - 32,111,117,116,112,117,116, 40, 39, 32, 32, 32,123, 39, 41, - 10, 32, 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, 35, - 105,102,100,101,102, 32, 95, 95, 99,112,108,117,115,112,108, - 117,115, 92,110, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116, - 112,117,116, 40, 39, 32, 32, 32, 32,118,111,105,100, 42, 32, - 116,111,108,117, 97, 95,111, 98,106, 32, 61, 32, 77,116,111, - 108,117, 97, 95,110,101,119, 40, 40, 39, 44,116,121,112,101, - 44, 39, 41, 40, 39, 44,115,101,108,102, 46,110, 97,109,101, - 44, 39, 91,105, 93, 41, 41, 59, 39, 41, 10, 32, 32, 32, 32, - 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, 32,116,111, - 108,117, 97, 95,112,117,115,104,102,105,101,108,100,117,115, - 101,114,116,121,112,101, 95, 97,110,100, 95,116, 97,107,101, - 111,119,110,101,114,115,104,105,112, 40,116,111,108,117, 97, - 95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49, - 44,116,111,108,117, 97, 95,111, 98,106, 44, 34, 39, 44,116, - 121,112,101, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32, 32, 32, - 32,111,117,116,112,117,116, 40, 39, 35,101,108,115,101, 92, - 110, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116,112,117,116, - 40, 39, 32, 32, 32, 32,118,111,105,100, 42, 32,116,111,108, - 117, 97, 95,111, 98,106, 32, 61, 32,116,111,108,117, 97, 95, - 99,111,112,121, 40,116,111,108,117, 97, 95, 83, 44, 40,118, - 111,105,100, 42, 41, 38, 39, 44,115,101,108,102, 46,110, 97, - 109,101, 44, 39, 91,105, 93, 44,115,105,122,101,111,102, 40, - 39, 44,116,121,112,101, 44, 39, 41, 41, 59, 39, 41, 10, 32, - 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, 32, - 32,116,111,108,117, 97, 95,112,117,115,104,102,105,101,108, - 100,117,115,101,114,116,121,112,101, 40,116,111,108,117, 97, - 95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49, - 44,116,111,108,117, 97, 95,111, 98,106, 44, 34, 39, 44,116, - 121,112,101, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32, 32, 32, - 32,111,117,116,112,117,116, 40, 39, 35,101,110,100,105,102, - 92,110, 39, 41, 10, 32, 32, 32, 32, 32,111,117,116,112,117, - 116, 40, 39, 32, 32, 32,125, 39, 41, 10, 32, 32, 32,101,108, - 115,101, 10, 32, 32, 32, 32,111,117,116,112,117,116, 40, 39, - 32, 32, 32,116,111,108,117, 97, 95,112,117,115,104,102,105, - 101,108,100,117,115,101,114,116,121,112,101, 40,116,111,108, - 117, 97, 95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44,105, - 43, 49, 44, 40,118,111,105,100, 42, 41, 39, 44,115,101,108, - 102, 46,110, 97,109,101, 44, 39, 91,105, 93, 44, 34, 39, 44, - 116,121,112,101, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32, 32, - 101,110,100, 10, 32, 32,101,110,100, 10, 32, 32,111,117,116, - 112,117,116, 40, 39, 32, 32,125, 39, 41, 10, 32,101,110,100, - 10,101,110,100, 10, 10, 45, 45, 32, 70,114,101,101, 32,100, - 121,110, 97,109,105, 99, 97,108,108,121, 32, 97,108,108,111, - 99, 97,116,101,100, 32, 97,114,114, 97,121, 10,102,117,110, - 99,116,105,111,110, 32, 99,108, 97,115,115, 68,101, 99,108, - 97,114, 97,116,105,111,110, 58,102,114,101,101, 97,114,114, - 97,121, 32, 40, 41, 10, 32,105,102, 32,115,101,108,102, 46, - 100,105,109, 32,126, 61, 32, 39, 39, 32, 97,110,100, 32,116, - 111,110,117,109, 98,101,114, 40,115,101,108,102, 46,100,105, - 109, 41, 61, 61,110,105,108, 32,116,104,101,110, 10, 9, 32, - 111,117,116,112,117,116, 40, 39, 35,105,102,100,101,102, 32, - 95, 95, 99,112,108,117,115,112,108,117,115, 92,110, 39, 41, - 10, 9, 9,111,117,116,112,117,116, 40, 39, 32, 32, 77,116, - 111,108,117, 97, 95,100,101,108,101,116,101, 95,100,105,109, - 40, 39, 44,115,101,108,102, 46,110, 97,109,101, 44, 39, 41, - 59, 39, 41, 10, 9, 32,111,117,116,112,117,116, 40, 39, 35, - 101,108,115,101, 92,110, 39, 41, 10, 32, 32,111,117,116,112, - 117,116, 40, 39, 32, 32,102,114,101,101, 40, 39, 44,115,101, - 108,102, 46,110, 97,109,101, 44, 39, 41, 59, 39, 41, 10, 9, - 32,111,117,116,112,117,116, 40, 39, 35,101,110,100,105,102, - 92,110, 39, 41, 10, 32,101,110,100, 10,101,110,100, 10, 10, - 45, 45, 32, 80, 97,115,115, 32,112, 97,114, 97,109,101,116, - 101,114, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97, - 115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58,112, - 97,115,115,112, 97,114, 32, 40, 41, 10, 32,105,102, 32,115, - 101,108,102, 46,112,116,114, 61, 61, 39, 38, 39, 32, 97,110, - 100, 32,110,111,116, 32,105,115, 98, 97,115,105, 99, 40,115, - 101,108,102, 46,116,121,112,101, 41, 32,116,104,101,110, 10, - 32, 32,111,117,116,112,117,116, 40, 39, 42, 39, 46, 46,115, - 101,108,102, 46,110, 97,109,101, 41, 10, 32,101,108,115,101, - 105,102, 32,115,101,108,102, 46,114,101,116, 61, 61, 39, 42, - 39, 32,116,104,101,110, 10, 32, 32,111,117,116,112,117,116, - 40, 39, 38, 39, 46, 46,115,101,108,102, 46,110, 97,109,101, - 41, 10, 32,101,108,115,101, 10, 32, 32,111,117,116,112,117, - 116, 40,115,101,108,102, 46,110, 97,109,101, 41, 10, 32,101, - 110,100, 10,101,110,100, 10, 10, 45, 45, 32, 82,101,116,117, - 114,110, 32,112, 97,114, 97,109,101,116,101,114, 32,118, 97, - 108,117,101, 10,102,117,110, 99,116,105,111,110, 32, 99,108, - 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58, - 114,101,116,118, 97,108,117,101, 32, 40, 41, 10, 32,105,102, - 32,115,101,108,102, 46,114,101,116, 32,126, 61, 32, 39, 39, - 32,116,104,101,110, 10, 32, 32,108,111, 99, 97,108, 32,116, - 44, 99,116, 32, 61, 32,105,115, 98, 97,115,105, 99, 40,115, - 101,108,102, 46,116,121,112,101, 41, 10, 32, 32,105,102, 32, - 116, 32, 97,110,100, 32,116,126, 61, 39, 39, 32,116,104,101, - 110, 10, 32, 32, 32,111,117,116,112,117,116, 40, 39, 32, 32, - 32,116,111,108,117, 97, 95,112,117,115,104, 39, 46, 46,116, - 46, 46, 39, 40,116,111,108,117, 97, 95, 83, 44, 40, 39, 44, - 99,116, 44, 39, 41, 39, 46, 46,115,101,108,102, 46,110, 97, - 109,101, 46, 46, 39, 41, 59, 39, 41, 10, 32, 32,101,108,115, - 101, 10, 32, 32, 32,108,111, 99, 97,108, 32,112,117,115,104, - 95,102,117,110, 99, 32, 61, 32,103,101,116, 95,112,117,115, - 104, 95,102,117,110, 99,116,105,111,110, 40,115,101,108,102, - 46,116,121,112,101, 41, 10, 32, 32, 32,111,117,116,112,117, - 116, 40, 39, 32, 32, 32, 39, 44,112,117,115,104, 95,102,117, - 110, 99, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 40,118, - 111,105,100, 42, 41, 39, 46, 46,115,101,108,102, 46,110, 97, - 109,101, 46, 46, 39, 44, 34, 39, 44,115,101,108,102, 46,116, - 121,112,101, 44, 39, 34, 41, 59, 39, 41, 10, 32, 32,101,110, - 100, 10, 32, 32,114,101,116,117,114,110, 32, 49, 10, 32,101, - 110,100, 10, 32,114,101,116,117,114,110, 32, 48, 10,101,110, - 100, 10, 10, 45, 45, 32, 73,110,116,101,114,110, 97,108, 32, - 99,111,110,115,116,114,117, 99,116,111,114, 10,102,117,110, - 99,116,105,111,110, 32, 95, 68,101, 99,108, 97,114, 97,116, - 105,111,110, 32, 40,116, 41, 10, 10, 32,115,101,116,109,101, - 116, 97,116, 97, 98,108,101, 40,116, 44, 99,108, 97,115,115, - 68,101, 99,108, 97,114, 97,116,105,111,110, 41, 10, 32,116, - 58, 98,117,105,108,100,110, 97,109,101,115, 40, 41, 10, 32, - 116, 58, 99,104,101, 99,107,110, 97,109,101, 40, 41, 10, 32, - 116, 58, 99,104,101, 99,107,116,121,112,101, 40, 41, 10, 32, - 108,111, 99, 97,108, 32,102,116, 32, 61, 32,102,105,110,100, - 116,121,112,101, 40,116, 46,116,121,112,101, 41, 32,111,114, - 32,116, 46,116,121,112,101, 10, 32,105,102, 32,110,111,116, - 32,105,115,101,110,117,109, 40,102,116, 41, 32,116,104,101, - 110, 10, 9,116, 46,109,111,100, 44, 32,116, 46,116,121,112, - 101, 32, 61, 32, 97,112,112,108,121,116,121,112,101,100,101, - 102, 40,116, 46,109,111,100, 44, 32,102,116, 41, 10, 32,101, - 110,100, 10, 10, 32,105,102, 32,116, 46,107,105,110,100, 61, - 61, 34,118, 97,114, 34, 32, 97,110,100, 32, 40,115,116,114, - 105,110,103, 46,102,105,110,100, 40,116, 46,109,111,100, 44, - 32, 34,116,111,108,117, 97, 95,112,114,111,112,101,114,116, - 121, 37,115, 34, 41, 32,111,114, 32,115,116,114,105,110,103, - 46,102,105,110,100, 40,116, 46,109,111,100, 44, 32, 34,116, - 111,108,117, 97, 95,112,114,111,112,101,114,116,121, 36, 34, - 41, 41, 32,116,104,101,110, 10, 32, 9,116, 46,109,111,100, - 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, - 116, 46,109,111,100, 44, 32, 34,116,111,108,117, 97, 95,112, - 114,111,112,101,114,116,121, 34, 44, 32, 34,116,111,108,117, - 97, 95,112,114,111,112,101,114,116,121, 95, 95, 34, 46, 46, - 103,101,116, 95,112,114,111,112,101,114,116,121, 95,116,121, - 112,101, 40, 41, 41, 10, 32,101,110,100, 10, 10, 32,114,101, - 116,117,114,110, 32,116, 10,101,110,100, 10, 10, 45, 45, 32, - 67,111,110,115,116,114,117, 99,116,111,114, 10, 45, 45, 32, - 69,120,112,101, 99,116,115, 32,116,104,101, 32,115,116,114, - 105,110,103, 32,100,101, 99,108, 97,114, 97,116,105,111,110, - 46, 10, 45, 45, 32, 84,104,101, 32,107,105,110,100, 32,111, - 102, 32,100,101, 99,108, 97,114, 97,116,105,111,110, 32, 99, - 97,110, 32, 98,101, 32, 34,118, 97,114, 34, 32,111,114, 32, - 34,102,117,110, 99, 34, 46, 10,102,117,110, 99,116,105,111, - 110, 32, 68,101, 99,108, 97,114, 97,116,105,111,110, 32, 40, - 115, 44,107,105,110,100, 44,105,115, 95,112, 97,114, 97,109, - 101,116,101,114, 41, 10, 10, 32, 45, 45, 32,101,108,105,109, - 105,110, 97,116,101, 32,115,112, 97, 99,101,115, 32,105,102, - 32,100,101,102, 97,117,108,116, 32,118, 97,108,117,101, 32, - 105,115, 32,112,114,111,118,105,100,101,100, 10, 32,115, 32, - 61, 32,103,115,117, 98, 40,115, 44, 34, 37,115, 42, 61, 37, - 115, 42, 34, 44, 34, 61, 34, 41, 10, 32,115, 32, 61, 32,103, - 115,117, 98, 40,115, 44, 32, 34, 37,115, 42, 60, 34, 44, 32, - 34, 60, 34, 41, 10, 10, 32,108,111, 99, 97,108, 32,100,101, - 102, 98, 44,116,109,112,100,101,102, 10, 32,100,101,102, 98, - 44, 95, 44,116,109,112,100,101,102, 32, 61, 32,115,116,114, - 105,110,103, 46,102,105,110,100, 40,115, 44, 32, 34, 40, 61, - 46, 42, 41, 36, 34, 41, 10, 32,105,102, 32,100,101,102, 98, - 32,116,104,101,110, 10, 32, 9,115, 32, 61, 32,115,116,114, - 105,110,103, 46,103,115,117, 98, 40,115, 44, 32, 34, 61, 46, - 42, 36, 34, 44, 32, 34, 34, 41, 10, 32,101,108,115,101, 10, - 32, 9,116,109,112,100,101,102, 32, 61, 32, 39, 39, 10, 32, - 101,110,100, 10, 32,105,102, 32,107,105,110,100, 32, 61, 61, - 32, 34,118, 97,114, 34, 32,116,104,101,110, 10, 32, 32, 45, - 45, 32, 99,104,101, 99,107, 32,116,104,101, 32,102,111,114, - 109, 58, 32,118,111,105,100, 10, 32, 32,105,102, 32,115, 32, - 61, 61, 32, 39, 39, 32,111,114, 32,115, 32, 61, 61, 32, 39, - 118,111,105,100, 39, 32,116,104,101,110, 10, 32, 32, 32,114, - 101,116,117,114,110, 32, 95, 68,101, 99,108, 97,114, 97,116, - 105,111,110,123,116,121,112,101, 32, 61, 32, 39,118,111,105, - 100, 39, 44, 32,107,105,110,100, 32, 61, 32,107,105,110,100, - 44, 32,105,115, 95,112, 97,114, 97,109,101,116,101,114, 32, - 61, 32,105,115, 95,112, 97,114, 97,109,101,116,101,114,125, - 10, 32, 32,101,110,100, 10, 32,101,110,100, 10, 10, 32, 45, - 45, 32, 99,104,101, 99,107, 32,116,104,101, 32,102,111,114, - 109, 58, 32,109,111,100, 32,116,121,112,101, 42, 38, 32,110, - 97,109,101, 10, 32,108,111, 99, 97,108, 32,116, 32, 61, 32, - 115,112,108,105,116, 95, 99, 95,116,111,107,101,110,115, 40, - 115, 44, 39, 37, 42, 37,115, 42, 38, 39, 41, 10, 32,105,102, - 32,116, 46,110, 32, 61, 61, 32, 50, 32,116,104,101,110, 10, - 32, 32,105,102, 32,107,105,110,100, 32, 61, 61, 32, 39,102, - 117,110, 99, 39, 32,116,104,101,110, 10, 32, 32, 32,101,114, - 114,111,114, 40, 34, 35,105,110,118, 97,108,105,100, 32,102, - 117,110, 99,116,105,111,110, 32,114,101,116,117,114,110, 32, - 116,121,112,101, 58, 32, 34, 46, 46,115, 41, 10, 32, 32,101, - 110,100, 10, 32, 32, 45, 45,108,111, 99, 97,108, 32,109, 32, - 61, 32,115,112,108,105,116, 40,116, 91, 49, 93, 44, 39, 37, - 115, 37,115, 42, 39, 41, 10, 32, 32,108,111, 99, 97,108, 32, - 109, 32, 61, 32,115,112,108,105,116, 95, 99, 95,116,111,107, - 101,110,115, 40,116, 91, 49, 93, 44, 39, 37,115, 43, 39, 41, - 10, 32, 32,114,101,116,117,114,110, 32, 95, 68,101, 99,108, - 97,114, 97,116,105,111,110,123, 10, 32, 32, 32,110, 97,109, - 101, 32, 61, 32,116, 91, 50, 93, 46, 46,116,109,112,100,101, - 102, 44, 10, 32, 32, 32,112,116,114, 32, 61, 32, 39, 42, 39, - 44, 10, 32, 32, 32,114,101,116, 32, 61, 32, 39, 38, 39, 44, - 10, 32, 32, 32, 45, 45,116,121,112,101, 32, 61, 32,114,101, - 98,117,105,108,100, 95,116,101,109,112,108, 97,116,101, 40, - 109, 91,109, 46,110, 93, 44, 32,116, 98, 44, 32,116,105,109, - 112,108, 41, 44, 10, 32, 32, 32,116,121,112,101, 32, 61, 32, - 109, 91,109, 46,110, 93, 44, 10, 32, 32, 32,109,111,100, 32, - 61, 32, 99,111,110, 99, 97,116, 40,109, 44, 49, 44,109, 46, - 110, 45, 49, 41, 44, 10, 32, 32, 32,105,115, 95,112, 97,114, - 97,109,101,116,101,114, 32, 61, 32,105,115, 95,112, 97,114, - 97,109,101,116,101,114, 44, 10, 32, 32, 32,107,105,110,100, - 32, 61, 32,107,105,110,100, 10, 32, 32,125, 10, 32,101,110, - 100, 10, 10, 32, 45, 45, 32, 99,104,101, 99,107, 32,116,104, - 101, 32,102,111,114,109, 58, 32,109,111,100, 32,116,121,112, - 101, 42, 42, 32,110, 97,109,101, 10, 32,116, 32, 61, 32,115, - 112,108,105,116, 95, 99, 95,116,111,107,101,110,115, 40,115, - 44, 39, 37, 42, 37,115, 42, 37, 42, 39, 41, 10, 32,105,102, - 32,116, 46,110, 32, 61, 61, 32, 50, 32,116,104,101,110, 10, - 32, 32,105,102, 32,107,105,110,100, 32, 61, 61, 32, 39,102, - 117,110, 99, 39, 32,116,104,101,110, 10, 32, 32, 32,101,114, - 114,111,114, 40, 34, 35,105,110,118, 97,108,105,100, 32,102, - 117,110, 99,116,105,111,110, 32,114,101,116,117,114,110, 32, - 116,121,112,101, 58, 32, 34, 46, 46,115, 41, 10, 32, 32,101, - 110,100, 10, 32, 32, 45, 45,108,111, 99, 97,108, 32,109, 32, - 61, 32,115,112,108,105,116, 40,116, 91, 49, 93, 44, 39, 37, - 115, 37,115, 42, 39, 41, 10, 32, 32,108,111, 99, 97,108, 32, - 109, 32, 61, 32,115,112,108,105,116, 95, 99, 95,116,111,107, - 101,110,115, 40,116, 91, 49, 93, 44, 39, 37,115, 43, 39, 41, - 10, 32, 32,114,101,116,117,114,110, 32, 95, 68,101, 99,108, - 97,114, 97,116,105,111,110,123, 10, 32, 32, 32,110, 97,109, - 101, 32, 61, 32,116, 91, 50, 93, 46, 46,116,109,112,100,101, - 102, 44, 10, 32, 32, 32,112,116,114, 32, 61, 32, 39, 42, 39, - 44, 10, 32, 32, 32,114,101,116, 32, 61, 32, 39, 42, 39, 44, - 10, 32, 32, 32, 45, 45,116,121,112,101, 32, 61, 32,114,101, - 98,117,105,108,100, 95,116,101,109,112,108, 97,116,101, 40, - 109, 91,109, 46,110, 93, 44, 32,116, 98, 44, 32,116,105,109, - 112,108, 41, 44, 10, 32, 32, 32,116,121,112,101, 32, 61, 32, - 109, 91,109, 46,110, 93, 44, 10, 32, 32, 32,109,111,100, 32, - 61, 32, 99,111,110, 99, 97,116, 40,109, 44, 49, 44,109, 46, - 110, 45, 49, 41, 44, 10, 32, 32, 32,105,115, 95,112, 97,114, - 97,109,101,116,101,114, 32, 61, 32,105,115, 95,112, 97,114, - 97,109,101,116,101,114, 44, 10, 32, 32, 32,107,105,110,100, - 32, 61, 32,107,105,110,100, 10, 32, 32,125, 10, 32,101,110, - 100, 10, 10, 32, 45, 45, 32, 99,104,101, 99,107, 32,116,104, - 101, 32,102,111,114,109, 58, 32,109,111,100, 32,116,121,112, - 101, 38, 32,110, 97,109,101, 10, 32,116, 32, 61, 32,115,112, - 108,105,116, 95, 99, 95,116,111,107,101,110,115, 40,115, 44, - 39, 38, 39, 41, 10, 32,105,102, 32,116, 46,110, 32, 61, 61, - 32, 50, 32,116,104,101,110, 10, 32, 32, 45, 45,108,111, 99, - 97,108, 32,109, 32, 61, 32,115,112,108,105,116, 40,116, 91, - 49, 93, 44, 39, 37,115, 37,115, 42, 39, 41, 10, 32, 32,108, - 111, 99, 97,108, 32,109, 32, 61, 32,115,112,108,105,116, 95, - 99, 95,116,111,107,101,110,115, 40,116, 91, 49, 93, 44, 39, - 37,115, 43, 39, 41, 10, 32, 32,114,101,116,117,114,110, 32, - 95, 68,101, 99,108, 97,114, 97,116,105,111,110,123, 10, 32, - 32, 32,110, 97,109,101, 32, 61, 32,116, 91, 50, 93, 46, 46, - 116,109,112,100,101,102, 44, 10, 32, 32, 32,112,116,114, 32, - 61, 32, 39, 38, 39, 44, 10, 32, 32, 32, 45, 45,116,121,112, - 101, 32, 61, 32,114,101, 98,117,105,108,100, 95,116,101,109, - 112,108, 97,116,101, 40,109, 91,109, 46,110, 93, 44, 32,116, - 98, 44, 32,116,105,109,112,108, 41, 44, 10, 32, 32, 32,116, - 121,112,101, 32, 61, 32,109, 91,109, 46,110, 93, 44, 10, 32, - 32, 32,109,111,100, 32, 61, 32, 99,111,110, 99, 97,116, 40, - 109, 44, 49, 44,109, 46,110, 45, 49, 41, 44, 10, 32, 32, 32, - 105,115, 95,112, 97,114, 97,109,101,116,101,114, 32, 61, 32, - 105,115, 95,112, 97,114, 97,109,101,116,101,114, 44, 10, 32, - 32, 32,107,105,110,100, 32, 61, 32,107,105,110,100, 10, 32, - 32,125, 10, 32,101,110,100, 10, 10, 32, 45, 45, 32, 99,104, - 101, 99,107, 32,116,104,101, 32,102,111,114,109, 58, 32,109, - 111,100, 32,116,121,112,101, 42, 32,110, 97,109,101, 10, 32, - 108,111, 99, 97,108, 32,115, 49, 32, 61, 32,103,115,117, 98, - 40,115, 44, 34, 40, 37, 98, 92, 91, 92, 93, 41, 34, 44,102, - 117,110, 99,116,105,111,110, 32, 40,110, 41, 32,114,101,116, - 117,114,110, 32,103,115,117, 98, 40,110, 44, 39, 37, 42, 39, - 44, 39, 92, 49, 39, 41, 32,101,110,100, 41, 10, 32,116, 32, - 61, 32,115,112,108,105,116, 95, 99, 95,116,111,107,101,110, - 115, 40,115, 49, 44, 39, 37, 42, 39, 41, 10, 32,105,102, 32, - 116, 46,110, 32, 61, 61, 32, 50, 32,116,104,101,110, 10, 32, - 32,116, 91, 50, 93, 32, 61, 32,103,115,117, 98, 40,116, 91, - 50, 93, 44, 39, 92, 49, 39, 44, 39, 37, 42, 39, 41, 32, 45, - 45, 32,114,101,115,116,111,114,101, 32, 42, 32,105,110, 32, - 100,105,109,101,110,115,105,111,110, 32,101,120,112,114,101, - 115,115,105,111,110, 10, 32, 32, 45, 45,108,111, 99, 97,108, - 32,109, 32, 61, 32,115,112,108,105,116, 40,116, 91, 49, 93, - 44, 39, 37,115, 37,115, 42, 39, 41, 10, 32, 32,108,111, 99, - 97,108, 32,109, 32, 61, 32,115,112,108,105,116, 95, 99, 95, - 116,111,107,101,110,115, 40,116, 91, 49, 93, 44, 39, 37,115, - 43, 39, 41, 10, 32, 32,114,101,116,117,114,110, 32, 95, 68, - 101, 99,108, 97,114, 97,116,105,111,110,123, 10, 32, 32, 32, - 110, 97,109,101, 32, 61, 32,116, 91, 50, 93, 46, 46,116,109, - 112,100,101,102, 44, 10, 32, 32, 32,112,116,114, 32, 61, 32, - 39, 42, 39, 44, 10, 32, 32, 32,116,121,112,101, 32, 61, 32, - 109, 91,109, 46,110, 93, 44, 10, 32, 32, 32, 45, 45,116,121, - 112,101, 32, 61, 32,114,101, 98,117,105,108,100, 95,116,101, - 109,112,108, 97,116,101, 40,109, 91,109, 46,110, 93, 44, 32, - 116, 98, 44, 32,116,105,109,112,108, 41, 44, 10, 32, 32, 32, - 109,111,100, 32, 61, 32, 99,111,110, 99, 97,116, 40,109, 44, - 49, 44,109, 46,110, 45, 49, 41, 32, 32, 32, 44, 10, 32, 32, - 32,105,115, 95,112, 97,114, 97,109,101,116,101,114, 32, 61, - 32,105,115, 95,112, 97,114, 97,109,101,116,101,114, 44, 10, - 32, 32, 32,107,105,110,100, 32, 61, 32,107,105,110,100, 10, - 32, 32,125, 10, 32,101,110,100, 10, 10, 32,105,102, 32,107, - 105,110,100, 32, 61, 61, 32, 39,118, 97,114, 39, 32,116,104, - 101,110, 10, 32, 32, 45, 45, 32, 99,104,101, 99,107, 32,116, - 104,101, 32,102,111,114,109, 58, 32,109,111,100, 32,116,121, - 112,101, 32,110, 97,109,101, 10, 32, 32, 45, 45,116, 32, 61, - 32,115,112,108,105,116, 40,115, 44, 39, 37,115, 37,115, 42, - 39, 41, 10, 32, 32,116, 32, 61, 32,115,112,108,105,116, 95, - 99, 95,116,111,107,101,110,115, 40,115, 44, 39, 37,115, 43, - 39, 41, 10, 32, 32,108,111, 99, 97,108, 32,118, 10, 32, 32, - 105,102, 32,102,105,110,100,116,121,112,101, 40,116, 91,116, - 46,110, 93, 41, 32,116,104,101,110, 32,118, 32, 61, 32, 99, - 114,101, 97,116,101, 95,118, 97,114,110, 97,109,101, 40, 41, - 32,101,108,115,101, 32,118, 32, 61, 32,116, 91,116, 46,110, - 93, 59, 32,116, 46,110, 32, 61, 32,116, 46,110, 45, 49, 32, - 101,110,100, 10, 32, 32,114,101,116,117,114,110, 32, 95, 68, - 101, 99,108, 97,114, 97,116,105,111,110,123, 10, 32, 32, 32, - 110, 97,109,101, 32, 61, 32,118, 46, 46,116,109,112,100,101, - 102, 44, 10, 32, 32, 32, 45, 45,116,121,112,101, 32, 61, 32, - 114,101, 98,117,105,108,100, 95,116,101,109,112,108, 97,116, - 101, 40,116, 91,116, 46,110, 93, 44, 32,116, 98, 44, 32,116, - 105,109,112,108, 41, 44, 10, 32, 32, 32,116,121,112,101, 32, - 61, 32,116, 91,116, 46,110, 93, 44, 10, 32, 32, 32,109,111, - 100, 32, 61, 32, 99,111,110, 99, 97,116, 40,116, 44, 49, 44, - 116, 46,110, 45, 49, 41, 44, 10, 32, 32, 32,105,115, 95,112, - 97,114, 97,109,101,116,101,114, 32, 61, 32,105,115, 95,112, - 97,114, 97,109,101,116,101,114, 44, 10, 32, 32, 32,107,105, - 110,100, 32, 61, 32,107,105,110,100, 10, 32, 32,125, 10, 10, - 32,101,108,115,101, 32, 45, 45, 32,107,105,110,100, 32, 61, - 61, 32, 34,102,117,110, 99, 34, 10, 10, 32, 32, 45, 45, 32, - 99,104,101, 99,107, 32,116,104,101, 32,102,111,114,109, 58, - 32,109,111,100, 32,116,121,112,101, 32,110, 97,109,101, 10, - 32, 32, 45, 45,116, 32, 61, 32,115,112,108,105,116, 40,115, - 44, 39, 37,115, 37,115, 42, 39, 41, 10, 32, 32,116, 32, 61, - 32,115,112,108,105,116, 95, 99, 95,116,111,107,101,110,115, - 40,115, 44, 39, 37,115, 43, 39, 41, 10, 32, 32,108,111, 99, - 97,108, 32,118, 32, 61, 32,116, 91,116, 46,110, 93, 32, 32, - 45, 45, 32,108, 97,115,116, 32,119,111,114,100, 32,105,115, - 32,116,104,101, 32,102,117,110, 99,116,105,111,110, 32,110, - 97,109,101, 10, 32, 32,108,111, 99, 97,108, 32,116,112, 44, - 109,100, 10, 32, 32,105,102, 32,116, 46,110, 62, 49, 32,116, - 104,101,110, 10, 32, 32, 32,116,112, 32, 61, 32,116, 91,116, - 46,110, 45, 49, 93, 10, 32, 32, 32,109,100, 32, 61, 32, 99, - 111,110, 99, 97,116, 40,116, 44, 49, 44,116, 46,110, 45, 50, - 41, 10, 32, 32,101,110,100, 10, 32, 32, 45, 45,105,102, 32, - 116,112, 32,116,104,101,110, 32,116,112, 32, 61, 32,114,101, - 98,117,105,108,100, 95,116,101,109,112,108, 97,116,101, 40, - 116,112, 44, 32,116, 98, 44, 32,116,105,109,112,108, 41, 32, - 101,110,100, 10, 32, 32,114,101,116,117,114,110, 32, 95, 68, - 101, 99,108, 97,114, 97,116,105,111,110,123, 10, 32, 32, 32, - 110, 97,109,101, 32, 61, 32,118, 44, 10, 32, 32, 32,116,121, - 112,101, 32, 61, 32,116,112, 44, 10, 32, 32, 32,109,111,100, - 32, 61, 32,109,100, 44, 10, 32, 32, 32,105,115, 95,112, 97, - 114, 97,109,101,116,101,114, 32, 61, 32,105,115, 95,112, 97, - 114, 97,109,101,116,101,114, 44, 10, 32, 32, 32,107,105,110, - 100, 32, 61, 32,107,105,110,100, 10, 32, 32,125, 10, 32,101, - 110,100, 10, 10,101,110,100,32 - }; - tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: src/bin/lua/declaration.lua"); + #include "declaration_lua.h" + tolua_dobuffer(tolua_S,(char*)lua_declaration_lua,sizeof(lua_declaration_lua),"tolua embedded: src/bin/lua/declaration.lua"); lua_settop(tolua_S, top); } /* end of embedded lua code */ -- cgit v1.2.3 From 96e0b2691262548442e17e114b2201ef55325621 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 19 Mar 2014 22:42:56 +0100 Subject: APIDump: Added ZeroBraneStudio API export. Fixes #821. --- MCServer/Plugins/APIDump/main_APIDump.lua | 133 ++++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 5 deletions(-) diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua index 6d4a6ebc5..2e1aa445d 100644 --- a/MCServer/Plugins/APIDump/main_APIDump.lua +++ b/MCServer/Plugins/APIDump/main_APIDump.lua @@ -1231,10 +1231,6 @@ local function DumpAPIHtml(a_API) return (Hook1.Name < Hook2.Name); end ); - - -- Read in the descriptions: - LOG("Reading descriptions..."); - ReadDescriptions(a_API); ReadHooks(Hooks); -- Create a "class index" file, write each class as a link to that file, @@ -1329,6 +1325,126 @@ end +--- Returns the string with extra tabs and CR/LFs removed +local function CleanUpDescription(a_Desc) + -- Get rid of indent and newlines, normalize whitespace: + local res = a_Desc:gsub("[\n\t]", "") + res = a_Desc:gsub("%s%s+", " ") + + -- Replace paragraph marks with newlines: + res = res:gsub("

", "\n") + res = res:gsub("

", "") + + -- Replace list items with dashes: + res = res:gsub("", "") + res = res:gsub("
  • ", "\n - ") + res = res:gsub("
  • ", "") + + return res +end + + + + + +--- Writes a list of methods into the specified file in ZBS format +local function WriteZBSMethods(f, a_Methods) + for _, func in ipairs(a_Methods or {}) do + f:write("\t\t\t[\"", func.Name, "\"] =\n") + f:write("\t\t\t{\n") + f:write("\t\t\t\ttype = \"method\",\n") + if ((func.Notes ~= nil) and (func.Notes ~= "")) then + f:write("\t\t\t\tdescription = [[", CleanUpDescription(func.Notes or ""), " ]],\n") + end + f:write("\t\t\t},\n") + end +end + + + + + +--- Writes a list of constants into the specified file in ZBS format +local function WriteZBSConstants(f, a_Constants) + for _, cons in ipairs(a_Constants or {}) do + f:write("\t\t\t[\"", cons.Name, "\"] =\n") + f:write("\t\t\t{\n") + f:write("\t\t\t\ttype = \"value\",\n") + if ((cons.Desc ~= nil) and (cons.Desc ~= "")) then + f:write("\t\t\t\tdescription = [[", CleanUpDescription(cons.Desc or ""), " ]],\n") + end + f:write("\t\t\t},\n") + end +end + + + + + +--- Writes one MCS class definition into the specified file in ZBS format +local function WriteZBSClass(f, a_Class) + assert(type(a_Class) == "table") + + -- Write class header: + f:write("\t", a_Class.Name, " =\n\t{\n") + f:write("\t\ttype = \"class\",\n") + f:write("\t\tdescription = [[", CleanUpDescription(a_Class.Desc or ""), " ]],\n") + f:write("\t\tchilds =\n") + f:write("\t\t{\n") + + -- Export methods and constants: + WriteZBSMethods(f, a_Class.Functions) + WriteZBSConstants(f, a_Class.Constants) + + -- Finish the class definition: + f:write("\t\t},\n") + f:write("\t},\n\n") +end + + + + + +--- Dumps the entire API table into a file in the ZBS format +local function DumpAPIZBS(a_API) + LOG("Dumping ZBS API description...") + local f, err = io.open("mcserver.lua", "w") + if (f == nil) then + LOG("Cannot open mcserver.lua for writing, ZBS API will not be dumped. " .. err) + return + end + + -- Write the file header: + f:write("-- This is a MCServer API file automatically generated by the APIDump plugin\n") + f:write("-- Note that any manual changes will be overwritten by the next dump\n\n") + f:write("return {\n") + + -- Export each class except Globals, store those aside: + local Globals + for _, cls in ipairs(a_API) do + if (cls.Name ~= "Globals") then + WriteZBSClass(f, cls) + else + Globals = cls + end + end + + -- Export the globals: + if (Globals) then + WriteZBSMethods(f, Globals.Functions) + WriteZBSConstants(f, Globals.Constants) + end + + -- Finish the file: + f:write("}\n") + f:close() + LOG("ZBS API dumped...") +end + + + + + local function DumpApi() LOG("Dumping the API...") @@ -1377,9 +1493,16 @@ local function DumpApi() Globals.Name = "Globals"; table.insert(API, Globals); - -- Dump all available API object in HTML format into a subfolder: + -- Read in the descriptions: + LOG("Reading descriptions..."); + ReadDescriptions(API); + + -- Dump all available API objects in HTML format into a subfolder: DumpAPIHtml(API); + -- Dump all available API objects in format used by ZeroBraneStudio API descriptions: + DumpAPIZBS(API) + LOG("APIDump finished"); return true end -- cgit v1.2.3 From d6a72da3821091f23f063942dbafdc3a5c0b34ac Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 19 Mar 2014 22:51:02 +0100 Subject: APIDump: Updated comments to reflect current code. --- MCServer/Plugins/APIDump/main_APIDump.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua index 2e1aa445d..7455c3cd2 100644 --- a/MCServer/Plugins/APIDump/main_APIDump.lua +++ b/MCServer/Plugins/APIDump/main_APIDump.lua @@ -1541,9 +1541,12 @@ function Initialize(Plugin) LOG("Initialising " .. Plugin:GetName() .. " v." .. Plugin:GetVersion()) + -- Bind a console command to dump the API: cPluginManager:BindConsoleCommand("api", HandleCmdApi, "Dumps the Lua API docs into the API/ subfolder") + + -- Add a WebAdmin tab that has a Dump button g_Plugin:AddWebTab("APIDump", HandleWebAdminDump) - -- TODO: Add a WebAdmin tab that has a Dump button + return true end -- cgit v1.2.3 From 74b7f51b898575bacec52663e5e8601d6bfd36bd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 19 Mar 2014 22:55:47 +0100 Subject: Errors in Lua don't include the error handler in the stack trace. Fixes #817. --- src/Bindings/LuaState.cpp | 10 +++++----- src/Bindings/LuaState.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index f24e15c3b..0bb047873 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -1080,20 +1080,20 @@ bool cLuaState::ReportErrors(lua_State * a_LuaState, int a_Status) -void cLuaState::LogStackTrace(void) +void cLuaState::LogStackTrace(int a_StartingDepth) { - LogStackTrace(m_LuaState); + LogStackTrace(m_LuaState, a_StartingDepth); } -void cLuaState::LogStackTrace(lua_State * a_LuaState) +void cLuaState::LogStackTrace(lua_State * a_LuaState, int a_StartingDepth) { LOGWARNING("Stack trace:"); lua_Debug entry; - int depth = 0; + int depth = a_StartingDepth; while (lua_getstack(a_LuaState, depth, &entry)) { lua_getinfo(a_LuaState, "Sln", &entry); @@ -1312,7 +1312,7 @@ void cLuaState::LogStack(lua_State * a_LuaState, const char * a_Header) int cLuaState::ReportFnCallErrors(lua_State * a_LuaState) { LOGWARNING("LUA: %s", lua_tostring(a_LuaState, -1)); - LogStackTrace(a_LuaState); + LogStackTrace(a_LuaState, 1); return 1; // We left the error message on the stack as the return value } diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index f5cb8379d..356a284e0 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -868,10 +868,10 @@ public: static bool ReportErrors(lua_State * a_LuaState, int status); /** Logs all items in the current stack trace to the server console */ - void LogStackTrace(void); + void LogStackTrace(int a_StartingDepth = 0); /** Logs all items in the current stack trace to the server console */ - static void LogStackTrace(lua_State * a_LuaState); + static void LogStackTrace(lua_State * a_LuaState, int a_StartingDepth = 0); /** Returns the type of the item on the specified position in the stack */ AString GetTypeText(int a_StackPos); -- cgit v1.2.3 From 0524d70774f830b08abb1dee4e8340b25c569d2a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 19 Mar 2014 23:06:39 +0000 Subject: ENUMified shrapnel level --- src/BlockID.h | 12 ++++++++---- src/ChunkMap.cpp | 4 ++-- src/World.cpp | 6 +++--- src/World.h | 10 ++++------ 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/BlockID.h b/src/BlockID.h index 1c454cd23..e305e9237 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -852,10 +852,14 @@ enum eExplosionSource esWitherSkullBlack, esWitherSkullBlue, esWitherBirth, - esPlugin, - - // Obsolete constants, kept for compatibility, will be removed after some time: - esCreeper = esMonster, + esPlugin +} ; + +enum eShrapnelLevel +{ + slNone, + slGravityAffectedOnly, + slAll } ; // tolua_end diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 867b37ed0..e695f0ab2 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1834,13 +1834,13 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } - else if ((m_World->GetTNTShrapnelLevel() > 0) && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around + else if ((m_World->GetTNTShrapnelLevel() > slNone) && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around { if (!cBlockInfo::FullyOccupiesVoxel(Block)) { break; } - else if ((m_World->GetTNTShrapnelLevel() == 1) && ((Block != E_BLOCK_SAND) && (Block != E_BLOCK_GRAVEL))) + else if ((m_World->GetTNTShrapnelLevel() == slGravityAffectedOnly) && ((Block != E_BLOCK_SAND) && (Block != E_BLOCK_GRAVEL))) { break; } diff --git a/src/World.cpp b/src/World.cpp index 22bc406e0..01281625a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -577,15 +577,15 @@ void cWorld::Start(void) m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", true); m_ShouldLavaSpawnFire = IniFile.GetValueSetB("Physics", "ShouldLavaSpawnFire", true); - m_TNTShrapnelLevel = IniFile.GetValueSetI("Physics", "TNTShrapnelLevel", 2); + m_TNTShrapnelLevel = (eShrapnelLevel)IniFile.GetValueSetI("Physics", "TNTShrapnelLevel", 2); m_bCommandBlocksEnabled = IniFile.GetValueSetB("Mechanics", "CommandBlocksEnabled", false); m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true); m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", true); m_GameMode = (eGameMode)IniFile.GetValueSetI("General", "Gamemode", m_GameMode); - if (m_TNTShrapnelLevel > 2) - m_TNTShrapnelLevel = 2; + if (m_TNTShrapnelLevel > slAll) + m_TNTShrapnelLevel = slAll; // Load allowed mobs: const char * DefaultMonsters = ""; diff --git a/src/World.h b/src/World.h index 21c6ea01c..46aece18f 100644 --- a/src/World.h +++ b/src/World.h @@ -605,8 +605,8 @@ public: bool AreCommandBlocksEnabled(void) const { return m_bCommandBlocksEnabled; } void SetCommandBlocksEnabled(bool a_Flag) { m_bCommandBlocksEnabled = a_Flag; } - unsigned char GetTNTShrapnelLevel(void) const { return m_TNTShrapnelLevel; } - void SetTNTShrapnelLevel(int a_Flag) { m_TNTShrapnelLevel = a_Flag; } + eShrapnelLevel GetTNTShrapnelLevel(void) const { return m_TNTShrapnelLevel; } + void SetTNTShrapnelLevel(eShrapnelLevel a_Flag) { m_TNTShrapnelLevel = a_Flag; } bool ShouldUseChatPrefixes(void) const { return m_bUseChatPrefixes; } void SetShouldUseChatPrefixes(bool a_Flag) { m_bUseChatPrefixes = a_Flag; } @@ -867,11 +867,9 @@ private: bool m_bUseChatPrefixes; /** The level of DoExplosionAt() projecting random affected blocks as FallingBlock entities - 0 = None - 1 = Only sand and gravel - 2 = All blocks + See the eShrapnelLevel enumeration for details */ - int m_TNTShrapnelLevel; + eShrapnelLevel m_TNTShrapnelLevel; cChunkGenerator m_Generator; -- cgit v1.2.3 From a0720a65d631e0f88b93067cc5ca84c650aa41cb Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 19 Mar 2014 23:07:16 +0000 Subject: Minor Entity.cpp cleanup --- src/Entities/Entity.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 97c8e2164..221cbbea7 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -733,22 +733,19 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) if( NextSpeed.SqrLength() > 0.f ) { cTracer Tracer( GetWorld() ); - int Ret = Tracer.Trace( NextPos, NextSpeed, 2 ); - if( Ret ) // Oh noez! we hit something + bool HasHit = Tracer.Trace( NextPos, NextSpeed, 2 ); + if (HasHit) // Oh noez! we hit something { // Set to hit position - if( (Tracer.RealHit - NextPos).SqrLength() <= ( NextSpeed * a_Dt ).SqrLength() ) + if ((Tracer.RealHit - NextPos).SqrLength() <= (NextSpeed * a_Dt).SqrLength()) { - if( Ret == 1 ) - { - if( Tracer.HitNormal.x != 0.f ) NextSpeed.x = 0.f; - if( Tracer.HitNormal.y != 0.f ) NextSpeed.y = 0.f; - if( Tracer.HitNormal.z != 0.f ) NextSpeed.z = 0.f; + if (Tracer.HitNormal.x != 0.f) NextSpeed.x = 0.f; + if (Tracer.HitNormal.y != 0.f) NextSpeed.y = 0.f; + if (Tracer.HitNormal.z != 0.f) NextSpeed.z = 0.f; - if( Tracer.HitNormal.y > 0 ) // means on ground - { - m_bOnGround = true; - } + if (Tracer.HitNormal.y > 0) // means on ground + { + m_bOnGround = true; } NextPos.Set(Tracer.RealHit.x,Tracer.RealHit.y,Tracer.RealHit.z); NextPos.x += Tracer.HitNormal.x * 0.3f; -- cgit v1.2.3 From 3e49cada80dc219cb9894772bae9237b5bc81562 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 19 Mar 2014 23:07:58 +0000 Subject: Added braces --- src/World.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/World.cpp b/src/World.cpp index 01281625a..14abaa242 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -585,7 +585,9 @@ void cWorld::Start(void) m_GameMode = (eGameMode)IniFile.GetValueSetI("General", "Gamemode", m_GameMode); if (m_TNTShrapnelLevel > slAll) + { m_TNTShrapnelLevel = slAll; + } // Load allowed mobs: const char * DefaultMonsters = ""; -- cgit v1.2.3 From 964647a9006af475bea71272e313f3575cf4d37f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 20 Mar 2014 09:16:47 +0100 Subject: Made pushing plain pointer to Lua a valid operation, with a warning. This is used for exotic explosions, and the NORETURNDEBUG macro caused MSVC warnings across the entire cLuaState class (MSVC marked ALL Push() function overloads as non-returning) --- src/Bindings/LuaState.cpp | 5 +++-- src/Bindings/LuaState.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 0bb047873..47380b8a7 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -689,9 +689,10 @@ void cLuaState::Push(void * a_Ptr) ASSERT(IsValid()); // Investigate the cause of this - what is the callstack? - LOGWARNING("Lua engine encountered an error - attempting to push a plain pointer"); + // One code path leading here is the OnHookExploding / OnHookExploded with exotic parameters. Need to decide what to do with them + LOGWARNING("Lua engine: attempting to push a plain pointer, pushing nil instead."); + LOGWARNING("This indicates an unimplemented part of MCS bindings"); LogStackTrace(); - ASSERT(!"A plain pointer should never be pushed on Lua stack"); lua_pushnil(m_LuaState); m_NumCurrentFunctionArgs += 1; diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 356a284e0..f0047b362 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -200,7 +200,7 @@ public: void Push(const HTTPTemplateRequest * a_Request); void Push(cTNTEntity * a_TNTEntity); void Push(Vector3i * a_Vector); - NORETURNDEBUG void Push(void * a_Ptr); + void Push(void * a_Ptr); void Push(cHopperEntity * a_Hopper); void Push(cBlockEntity * a_BlockEntity); -- cgit v1.2.3 From b1ad3322e555449879a94558e796358fe057f74b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 20 Mar 2014 09:28:29 +0100 Subject: Fixed code style after recent merge. --- src/BlockID.h | 6 +++++- src/World.cpp | 58 ++++++++++++++++++++++++++++------------------------------ 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/BlockID.h b/src/BlockID.h index e305e9237..8adefcfba 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -852,9 +852,13 @@ enum eExplosionSource esWitherSkullBlack, esWitherSkullBlue, esWitherBirth, - esPlugin + esPlugin, } ; + + + + enum eShrapnelLevel { slNone, diff --git a/src/World.cpp b/src/World.cpp index 14abaa242..3f157157a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -560,34 +560,33 @@ void cWorld::Start(void) m_SpawnZ = IniFile.GetValueF("SpawnPosition", "Z", m_SpawnZ); } - m_StorageSchema = IniFile.GetValueSet ("Storage", "Schema", m_StorageSchema); - m_StorageCompressionFactor = IniFile.GetValueSetI("Storage", "CompressionFactor", m_StorageCompressionFactor); - m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3); - m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3); - m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false); - m_IsCarrotsBonemealable = IniFile.GetValueSetB("Plants", "IsCarrotsBonemealable", true); - m_IsCropsBonemealable = IniFile.GetValueSetB("Plants", "IsCropsBonemealable", true); - m_IsGrassBonemealable = IniFile.GetValueSetB("Plants", "IsGrassBonemealable", true); - m_IsMelonStemBonemealable = IniFile.GetValueSetB("Plants", "IsMelonStemBonemealable", true); - m_IsMelonBonemealable = IniFile.GetValueSetB("Plants", "IsMelonBonemealable", false); - m_IsPotatoesBonemealable = IniFile.GetValueSetB("Plants", "IsPotatoesBonemealable", true); - m_IsPumpkinStemBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinStemBonemealable", true); - m_IsPumpkinBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinBonemealable", false); - m_IsSaplingBonemealable = IniFile.GetValueSetB("Plants", "IsSaplingBonemealable", true); - m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); - m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", true); - m_ShouldLavaSpawnFire = IniFile.GetValueSetB("Physics", "ShouldLavaSpawnFire", true); - m_TNTShrapnelLevel = (eShrapnelLevel)IniFile.GetValueSetI("Physics", "TNTShrapnelLevel", 2); - m_bCommandBlocksEnabled = IniFile.GetValueSetB("Mechanics", "CommandBlocksEnabled", false); - m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true); - m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); - m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", true); - - m_GameMode = (eGameMode)IniFile.GetValueSetI("General", "Gamemode", m_GameMode); - if (m_TNTShrapnelLevel > slAll) - { - m_TNTShrapnelLevel = slAll; - } + m_StorageSchema = IniFile.GetValueSet ("Storage", "Schema", m_StorageSchema); + m_StorageCompressionFactor = IniFile.GetValueSetI("Storage", "CompressionFactor", m_StorageCompressionFactor); + m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3); + m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3); + m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false); + m_IsCarrotsBonemealable = IniFile.GetValueSetB("Plants", "IsCarrotsBonemealable", true); + m_IsCropsBonemealable = IniFile.GetValueSetB("Plants", "IsCropsBonemealable", true); + m_IsGrassBonemealable = IniFile.GetValueSetB("Plants", "IsGrassBonemealable", true); + m_IsMelonStemBonemealable = IniFile.GetValueSetB("Plants", "IsMelonStemBonemealable", true); + m_IsMelonBonemealable = IniFile.GetValueSetB("Plants", "IsMelonBonemealable", false); + m_IsPotatoesBonemealable = IniFile.GetValueSetB("Plants", "IsPotatoesBonemealable", true); + m_IsPumpkinStemBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinStemBonemealable", true); + m_IsPumpkinBonemealable = IniFile.GetValueSetB("Plants", "IsPumpkinBonemealable", false); + m_IsSaplingBonemealable = IniFile.GetValueSetB("Plants", "IsSaplingBonemealable", true); + m_IsSugarcaneBonemealable = IniFile.GetValueSetB("Plants", "IsSugarcaneBonemealable", false); + m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", true); + m_ShouldLavaSpawnFire = IniFile.GetValueSetB("Physics", "ShouldLavaSpawnFire", true); + int TNTShrapnelLevel = IniFile.GetValueSetI("Physics", "TNTShrapnelLevel", (int)slNone); + m_bCommandBlocksEnabled = IniFile.GetValueSetB("Mechanics", "CommandBlocksEnabled", false); + m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true); + m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); + m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", true); + int GameMode = IniFile.GetValueSetI("General", "Gamemode", (int)m_GameMode); + + // Adjust the enum-backed variables into their respective bounds: + m_GameMode = (eGameMode) Clamp(GameMode, (int)gmSurvival, (int)gmAdventure); + m_TNTShrapnelLevel = (eShrapnelLevel)Clamp(TNTShrapnelLevel, (int)slNone, (int)slAll); // Load allowed mobs: const char * DefaultMonsters = ""; @@ -1730,14 +1729,13 @@ int cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks, double a_InitialVelocityCoeff) { - UNUSED(a_InitialVelocityCoeff); cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTicks); TNT->Initialize(this); TNT->SetSpeed( a_InitialVelocityCoeff * (GetTickRandomNumber(2) - 1), /** -1, 0, 1 */ a_InitialVelocityCoeff * 2, a_InitialVelocityCoeff * (GetTickRandomNumber(2) - 1) - ); + ); } -- cgit v1.2.3 From 93d4cbb989abff814800a11d8f23caa0de83e157 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 20 Mar 2014 15:21:28 +0100 Subject: ProtoProxy: Fixed MSVC compilation. --- Tools/ProtoProxy/Globals.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Tools/ProtoProxy/Globals.h b/Tools/ProtoProxy/Globals.h index 0724d3a52..e2f5aa860 100644 --- a/Tools/ProtoProxy/Globals.h +++ b/Tools/ProtoProxy/Globals.h @@ -22,6 +22,8 @@ #define ALIGN_8 #define ALIGN_16 + #define FORMATSTRING(formatIndex, va_argsIndex) + #elif defined(__GNUC__) // TODO: Can GCC explicitly mark classes as abstract (no instances can be created)? @@ -38,7 +40,7 @@ // Some portability macros :) #define stricmp strcasecmp - #define FORMATSTRING(formatIndex,va_argsIndex) + #define FORMATSTRING(formatIndex, va_argsIndex) #else @@ -61,7 +63,7 @@ #define ALIGN_16 */ - #define FORMATSTRING(formatIndex,va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) + #define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) #endif -- cgit v1.2.3 From 64d9390069650bbbc1850d5602b9854a1c1a7257 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 20 Mar 2014 15:45:42 +0100 Subject: Rewritten player speeds to be relative unit-less. Value of 1 means "default speed", 2 means "double the speed", 0.5 means "half the speed". This allows for easier plugins and is more future-proof. --- MCServer/Plugins/APIDump/APIDesc.lua | 10 +++++----- src/Entities/Player.cpp | 4 ++-- src/Entities/Player.h | 14 +++++++++----- src/Protocol/Protocol16x.cpp | 4 ++-- src/Protocol/Protocol17x.cpp | 7 ++++--- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index c5599b212..39bbb0c77 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1680,11 +1680,11 @@ a_Player:OpenWindow(Window); GetGroups = { Return = "array-table of {{cGroup}}", Notes = "Returns all the groups that this player is member of, as a table. The groups are stored in the array part of the table, beginning with index 1."}, GetIP = { Return = "string", Notes = "Returns the IP address of the player, if available. Returns an empty string if there's no IP to report."}, GetInventory = { Return = "{{cInventory|Inventory}}", Notes = "Returns the player's inventory"}, - GetMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's current maximum speed (as reported by the 1.6.1+ protocols)" }, + GetMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's current maximum speed, relative to the game default speed. Takes into account the sprinting / flying status." }, GetName = { Return = "string", Notes = "Returns the player's name" }, - GetNormalMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's maximum walking speed (as reported by the 1.6.1+ protocols)" }, + GetNormalMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's maximum walking speed, relative to the game default speed. Defaults to 1, but plugins may modify it for faster or slower walking." }, GetResolvedPermissions = { Return = "array-table of string", Notes = "Returns all the player's permissions, as a table. The permissions are stored in the array part of the table, beginning with index 1." }, - GetSprintingMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's maximum sprinting speed (as reported by the 1.6.1+ protocols)" }, + GetSprintingMaxSpeed = { Params = "", Return = "number", Notes = "Returns the player's maximum sprinting speed, relative to the game default speed. Defaults to 1.3, but plugins may modify it for faster or slower sprinting." }, GetStance = { Return = "number", Notes = "Returns the player's stance (Y-pos of player's eyes)" }, GetThrowSpeed = { Params = "SpeedCoeff", Return = "{{Vector3d}}", Notes = "Returns the speed vector for an object thrown with the specified speed coeff. Basically returns the normalized look vector multiplied by the coeff, with a slight random variation." }, GetThrowStartPos = { Params = "", Return = "{{Vector3d}}", Notes = "Returns the position where the projectiles should start when thrown by this player." }, @@ -1729,9 +1729,9 @@ a_Player:OpenWindow(Window); SetGameMode = { Params = "{{eGameMode|NewGameMode}}", Return = "", Notes = "Sets the gamemode for the player. The new gamemode overrides the world's default gamemode, unless it is set to gmInherit." }, SetIsFishing = { Params = "IsFishing, [FloaterEntityID]", Return = "", Notes = "Sets the 'IsFishing' flag for the player. The floater entity ID is expected for the true variant, it can be omitted when IsFishing is false. FIXME: Undefined behavior when multiple fishing rods are used simultanously" }, SetName = { Params = "Name", Return = "", Notes = "Sets the player name. This rename will NOT be visible to any players already in the server who are close enough to see this player." }, - SetNormalMaxSpeed = { Params = "NormalMaxSpeed", Return = "", Notes = "Sets the normal (walking) maximum speed (as reported by the 1.6.1+ protocols)" }, + SetNormalMaxSpeed = { Params = "NormalMaxSpeed", Return = "", Notes = "Sets the normal (walking) maximum speed, relative to the game default speed. The default value is 1. Sends the updated speed to the client, if appropriate." }, SetSprint = { Params = "IsSprinting", Return = "", Notes = "Sets whether the player is sprinting or not." }, - SetSprintingMaxSpeed = { Params = "SprintingMaxSpeed", Return = "", Notes = "Sets the sprinting maximum speed (as reported by the 1.6.1+ protocols)" }, + SetSprintingMaxSpeed = { Params = "SprintingMaxSpeed", Return = "", Notes = "Sets the sprinting maximum speed, relative to the game default speed. The default value is 1.3. Sends the updated speed to the client, if appropriate." }, SetVisible = { Params = "IsVisible", Return = "", Notes = "Sets the player visibility to other players" }, XpForLevel = { Params = "XPLevel", Return = "number", Notes = "(STATIC) Returns the total amount of XP needed for the specified XP level. Inverse of CalcLevelFromXp()." }, }, diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 440d30595..47d0d9c61 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -43,8 +43,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) , m_GameMode(eGameMode_NotSet) , m_IP("") , m_ClientHandle(a_Client) - , m_NormalMaxSpeed(0.1) - , m_SprintingMaxSpeed(0.13) + , m_NormalMaxSpeed(1.0) + , m_SprintingMaxSpeed(1.3) , m_IsCrouched(false) , m_IsSprinting(false) , m_IsFlying(false) diff --git a/src/Entities/Player.h b/src/Entities/Player.h index c25053c21..451dde8fc 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -331,13 +331,13 @@ public: // tolua_begin - /// Returns the current maximum speed, as reported in the 1.6.1+ protocol (takes current sprinting state into account) + /// Returns the current relative maximum speed (takes current sprinting state into account) double GetMaxSpeed(void) const; - /// Gets the normal maximum speed, as reported in the 1.6.1+ protocol, in the protocol units + /// Gets the normal relative maximum speed double GetNormalMaxSpeed(void) const { return m_NormalMaxSpeed; } - /// Gets the sprinting maximum speed, as reported in the 1.6.1+ protocol, in the protocol units + /// Gets the sprinting relative maximum speed double GetSprintingMaxSpeed(void) const { return m_SprintingMaxSpeed; } /// Sets the normal maximum speed, as reported in the 1.6.1+ protocol. Sends the update to player, if needed. @@ -432,10 +432,14 @@ protected: cSlotNums m_InventoryPaintSlots; - /// Max speed, in ENTITY_PROPERTIES packet's units, when the player is walking. 0.1 by default + /** Max speed, relative to the game default. + 1 means regular speed, 2 means twice as fast, 0.5 means half-speed. + Default value is 1. */ double m_NormalMaxSpeed; - /// Max speed, in ENTITY_PROPERTIES packet's units, when the player is sprinting. 0.13 by default + /** Max speed, relative to the game default max speed. + 1 means regular speed, 2 means twice as fast, 0.5 means half-speed. + Default value is 1.3 */ double m_SprintingMaxSpeed; bool m_IsCrouched; diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp index f6ec0a199..ecb24254f 100644 --- a/src/Protocol/Protocol16x.cpp +++ b/src/Protocol/Protocol16x.cpp @@ -135,7 +135,7 @@ void cProtocol161::SendPlayerMaxSpeed(void) WriteInt(m_Client->GetPlayer()->GetUniqueID()); WriteInt(1); WriteString("generic.movementSpeed"); - WriteDouble(m_Client->GetPlayer()->GetMaxSpeed()); + WriteDouble(0.1 * m_Client->GetPlayer()->GetMaxSpeed()); Flush(); } @@ -267,7 +267,7 @@ void cProtocol162::SendPlayerMaxSpeed(void) WriteInt(m_Client->GetPlayer()->GetUniqueID()); WriteInt(1); WriteString("generic.movementSpeed"); - WriteDouble(m_Client->GetPlayer()->GetMaxSpeed()); + WriteDouble(0.1 * m_Client->GetPlayer()->GetMaxSpeed()); WriteShort(0); Flush(); } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 6fc344eaf..21c77e903 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -689,7 +689,7 @@ void cProtocol172::SendPlayerAbilities(void) Pkt.WriteByte(Flags); // TODO: Pkt.WriteFloat(m_Client->GetPlayer()->GetMaxFlyingSpeed()); Pkt.WriteFloat(0.05f); - Pkt.WriteFloat((float)m_Client->GetPlayer()->GetMaxSpeed()); + Pkt.WriteFloat((float)(0.1 * m_Client->GetPlayer()->GetMaxSpeed())); } @@ -743,13 +743,14 @@ void cProtocol172::SendPlayerMaxSpeed(void) Pkt.WriteInt(m_Client->GetPlayer()->GetUniqueID()); Pkt.WriteInt(1); // Count Pkt.WriteString("generic.movementSpeed"); - Pkt.WriteDouble(0.1); + // The default game speed is 0.1, multiply that value by the relative speed: + Pkt.WriteDouble(0.1 * m_Client->GetPlayer()->GetNormalMaxSpeed()); if (m_Client->GetPlayer()->IsSprinting()) { Pkt.WriteShort(1); // Modifier count Pkt.WriteInt64(0x662a6b8dda3e4c1c); Pkt.WriteInt64(0x881396ea6097278d); // UUID of the modifier - Pkt.WriteDouble(0.3); + Pkt.WriteDouble(m_Client->GetPlayer()->GetSprintingMaxSpeed() - m_Client->GetPlayer()->GetNormalMaxSpeed()); Pkt.WriteByte(2); } else -- cgit v1.2.3 From 9fae50f44796c4230845c5dd29e82395827d45ff Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 20 Mar 2014 16:05:22 +0100 Subject: APIDump: Fixed wrong escaped strings. --- MCServer/Plugins/APIDump/APIDesc.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 39bbb0c77..19609295d 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2792,11 +2792,11 @@ end "Globals.xpcall", "Globals.decoda_output", -- When running under Decoda, this function gets added to the global namespace "sqlite3.__newindex", - "%a+\.__%a+", -- AnyClass.__Anything - "%a+\.\.collector", -- AnyClass..collector - "%a+\.new", -- AnyClass.new - "%a+.new_local", -- AnyClass.new_local - "%a+.delete", -- AnyClass.delete + "%a+%.__%a+", -- AnyClass.__Anything + "%a+%.%.collector", -- AnyClass..collector + "%a+%.new", -- AnyClass.new + "%a+%.new_local", -- AnyClass.new_local + "%a+%.delete", -- AnyClass.delete -- Functions global in the APIDump plugin: "CreateAPITables", -- cgit v1.2.3 From b370cacf0c0e1234aef1efd9c442ff335a379258 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 20 Mar 2014 16:14:40 +0100 Subject: Plugins can set flying speed. --- MCServer/Plugins/APIDump/APIDesc.lua | 8 +- src/Entities/Player.cpp | 33 +++++++- src/Entities/Player.h | 160 +++++++++++++++++++---------------- src/Protocol/Protocol17x.cpp | 3 +- 4 files changed, 124 insertions(+), 80 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 19609295d..74e7bf860 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1666,17 +1666,18 @@ a_Player:OpenWindow(Window); GetClientHandle = { Params = "", Return = "{{cClientHandle}}", Notes = "Returns the client handle representing the player's connection. May be nil (AI players)." }, GetColor = { Return = "string", Notes = "Returns the full color code to be used for this player (based on the first group). Prefix player messages with this code." }, GetCurrentXp = { Params = "", Return = "number", Notes = "Returns the current amount of XP" }, - GetEffectiveGameMode = { Params = "", Return = "{{eGameMode|GameMode}}", Notes = "Returns the current resolved game mode of the player. If the player is set to inherit the world's gamemode, returns that instead. See also GetGameMode() and IsGameModeXXX() functions." }, + GetEffectiveGameMode = { Params = "", Return = "{{Globals#GameMode|GameMode}}", Notes = "(OBSOLETE) Returns the current resolved game mode of the player. If the player is set to inherit the world's gamemode, returns that instead. See also GetGameMode() and IsGameModeXXX() functions. Note that this function is the same as GetGameMode(), use that function instead." }, GetEquippedItem = { Params = "", Return = "{{cItem}}", Notes = "Returns the item that the player is currently holding; empty item if holding nothing." }, GetEyeHeight = { Return = "number", Notes = "Returns the height of the player's eyes, in absolute coords" }, GetEyePosition = { Return = "{{Vector3d|EyePositionVector}}", Notes = "Returns the position of the player's eyes, as a {{Vector3d}}" }, GetFloaterID = { Params = "", Return = "number", Notes = "Returns the Entity ID of the fishing hook floater that belongs to the player. Returns -1 if no floater is associated with the player. FIXME: Undefined behavior when the player has used multiple fishing rods simultanously." }, + GetFlyingMaxSpeed = { Params = "", Return = "number", Notes = "Returns the maximum flying speed, relative to the default game flying speed. Defaults to 1, but plugins may modify it for faster or slower flying." }, GetFoodExhaustionLevel = { Params = "", Return = "number", Notes = "Returns the food exhaustion level" }, GetFoodLevel = { Params = "", Return = "number", Notes = "Returns the food level (number of half-drumsticks on-screen)" }, GetFoodPoisonedTicksRemaining = { Params = "", Return = "", Notes = "Returns the number of ticks left for the food posoning effect" }, GetFoodSaturationLevel = { Params = "", Return = "number", Notes = "Returns the food saturation (overcharge of the food level, is depleted before food level)" }, GetFoodTickTimer = { Params = "", Return = "", Notes = "Returns the number of ticks past the last food-based heal or damage action; when this timer reaches 80, a new heal / damage is applied." }, - GetGameMode = { Return = "{{eGameMode|GameMode}}", Notes = "Returns the player's gamemode. The player may have their gamemode unassigned, in which case they inherit the gamemode from the current {{cWorld|world}}.
    NOTE: Instead of comparing the value returned by this function to the gmXXX constants, use the IsGameModeXXX() functions. These functions handle the gamemode inheritance automatically."}, + GetGameMode = { Return = "{{Globals#GameMode|GameMode}}", Notes = "Returns the player's gamemode. The player may have their gamemode unassigned, in which case they inherit the gamemode from the current {{cWorld|world}}.
    NOTE: Instead of comparing the value returned by this function to the gmXXX constants, use the IsGameModeXXX() functions. These functions handle the gamemode inheritance automatically."}, GetGroups = { Return = "array-table of {{cGroup}}", Notes = "Returns all the groups that this player is member of, as a table. The groups are stored in the array part of the table, beginning with index 1."}, GetIP = { Return = "string", Notes = "Returns the IP address of the player, if available. Returns an empty string if there's no IP to report."}, GetInventory = { Return = "{{cInventory|Inventory}}", Notes = "Returns the player's inventory"}, @@ -1721,12 +1722,13 @@ a_Player:OpenWindow(Window); SetCrouch = { Params = "IsCrouched", Return = "", Notes = "Sets the crouch state, broadcasts the change to other players." }, SetCurrentExperience = { Params = "XPAmount", Return = "", Notes = "Sets the current amount of experience (and indirectly, the XP level)." }, SetFlying = { Params = "IsFlying", Notes = "Sets if the player is flying or not." }, + SetFlyingMaxSpeed = { Params = "FlyingMaxSpeed", Return = "", Notes = "Sets the flying maximum speed, relative to the game default speed. The default value is 1. Sends the updated speed to the client." }, SetFoodExhaustionLevel = { Params = "ExhaustionLevel", Return = "", Notes = "Sets the food exhaustion to the specified level." }, SetFoodLevel = { Params = "FoodLevel", Return = "", Notes = "Sets the food level (number of half-drumsticks on-screen)" }, SetFoodPoisonedTicksRemaining = { Params = "FoodPoisonedTicksRemaining", Return = "", Notes = "Sets the number of ticks remaining for food poisoning. Doesn't send foodpoisoning effect to the client, use FoodPoison() for that." }, SetFoodSaturationLevel = { Params = "FoodSaturationLevel", Return = "", Notes = "Sets the food saturation (overcharge of the food level)." }, SetFoodTickTimer = { Params = "FoodTickTimer", Return = "", Notes = "Sets the number of ticks past the last food-based heal or damage action; when this timer reaches 80, a new heal / damage is applied." }, - SetGameMode = { Params = "{{eGameMode|NewGameMode}}", Return = "", Notes = "Sets the gamemode for the player. The new gamemode overrides the world's default gamemode, unless it is set to gmInherit." }, + SetGameMode = { Params = "{{Globals#GameMode|NewGameMode}}", Return = "", Notes = "Sets the gamemode for the player. The new gamemode overrides the world's default gamemode, unless it is set to gmInherit." }, SetIsFishing = { Params = "IsFishing, [FloaterEntityID]", Return = "", Notes = "Sets the 'IsFishing' flag for the player. The floater entity ID is expected for the true variant, it can be omitted when IsFishing is false. FIXME: Undefined behavior when multiple fishing rods are used simultanously" }, SetName = { Params = "Name", Return = "", Notes = "Sets the player name. This rename will NOT be visible to any players already in the server who are close enough to see this player." }, SetNormalMaxSpeed = { Params = "NormalMaxSpeed", Return = "", Notes = "Sets the normal (walking) maximum speed, relative to the game default speed. The default value is 1. Sends the updated speed to the client, if appropriate." }, diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 47d0d9c61..863aaa799 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -45,6 +45,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) , m_ClientHandle(a_Client) , m_NormalMaxSpeed(1.0) , m_SprintingMaxSpeed(1.3) + , m_FlyingMaxSpeed(1.0) , m_IsCrouched(false) , m_IsSprinting(false) , m_IsFlying(false) @@ -684,7 +685,21 @@ const cSlotNums & cPlayer::GetInventoryPaintSlots(void) const double cPlayer::GetMaxSpeed(void) const { - return m_IsSprinting ? m_SprintingMaxSpeed : m_NormalMaxSpeed; + if (m_IsFlying) + { + return m_FlyingMaxSpeed; + } + else + { + if (m_IsSprinting) + { + return m_SprintingMaxSpeed; + } + else + { + return m_NormalMaxSpeed; + } + } } @@ -694,7 +709,7 @@ double cPlayer::GetMaxSpeed(void) const void cPlayer::SetNormalMaxSpeed(double a_Speed) { m_NormalMaxSpeed = a_Speed; - if (!m_IsSprinting) + if (!m_IsSprinting && !m_IsFlying) { m_ClientHandle->SendPlayerMaxSpeed(); } @@ -707,7 +722,7 @@ void cPlayer::SetNormalMaxSpeed(double a_Speed) void cPlayer::SetSprintingMaxSpeed(double a_Speed) { m_SprintingMaxSpeed = a_Speed; - if (m_IsSprinting) + if (m_IsSprinting && !m_IsFlying) { m_ClientHandle->SendPlayerMaxSpeed(); } @@ -717,6 +732,18 @@ void cPlayer::SetSprintingMaxSpeed(double a_Speed) +void cPlayer::SetFlyingMaxSpeed(double a_Speed) +{ + m_FlyingMaxSpeed = a_Speed; + + // Update the flying speed, always: + m_ClientHandle->SendPlayerAbilities(); +} + + + + + void cPlayer::SetCrouch(bool a_IsCrouched) { // Set the crouch status, broadcast to all visible players diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 451dde8fc..ea32dbfb9 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -47,19 +47,19 @@ public: virtual void HandlePhysics(float a_Dt, cChunk &) override { UNUSED(a_Dt); }; - /// Returns the curently equipped weapon; empty item if none + /** Returns the curently equipped weapon; empty item if none */ virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); } - /// Returns the currently equipped helmet; empty item if none + /** Returns the currently equipped helmet; empty item if none */ virtual cItem GetEquippedHelmet(void) const override { return m_Inventory.GetEquippedHelmet(); } - /// Returns the currently equipped chestplate; empty item if none + /** Returns the currently equipped chestplate; empty item if none */ virtual cItem GetEquippedChestplate(void) const override { return m_Inventory.GetEquippedChestplate(); } - /// Returns the currently equipped leggings; empty item if none + /** Returns the currently equipped leggings; empty item if none */ virtual cItem GetEquippedLeggings(void) const override { return m_Inventory.GetEquippedLeggings(); } - /// Returns the currently equipped boots; empty item if none + /** Returns the currently equipped boots; empty item if none */ virtual cItem GetEquippedBoots(void) const override { return m_Inventory.GetEquippedBoots(); } @@ -77,36 +77,41 @@ public: */ short DeltaExperience(short a_Xp_delta); - /// Gets the experience total - XpTotal for score on death + /** Gets the experience total - XpTotal for score on death */ inline short GetXpLifetimeTotal(void) { return m_LifetimeTotalXp; } - /// Gets the currrent experience + /** Gets the currrent experience */ inline short GetCurrentXp(void) { return m_CurrentXp; } - /// Gets the current level - XpLevel + /** Gets the current level - XpLevel */ short GetXpLevel(void); - /// Gets the experience bar percentage - XpP + /** Gets the experience bar percentage - XpP */ float GetXpPercentage(void); - /// Caculates the amount of XP needed for a given level, ref: http://minecraft.gamepedia.com/XP + /** Caculates the amount of XP needed for a given level + Ref: http://minecraft.gamepedia.com/XP + */ static short XpForLevel(short int a_Level); - /// inverse of XpForLevel, ref: http://minecraft.gamepedia.com/XP values are as per this with pre-calculations + /** Inverse of XpForLevel + Ref: http://minecraft.gamepedia.com/XP + values are as per this with pre-calculations + */ static short CalcLevelFromXp(short int a_CurrentXp); // tolua_end - /// Starts charging the equipped bow + /** Starts charging the equipped bow */ void StartChargingBow(void); - /// Finishes charging the current bow. Returns the number of ticks for which the bow has been charged + /** Finishes charging the current bow. Returns the number of ticks for which the bow has been charged */ int FinishChargingBow(void); - /// Cancels the current bow charging + /** Cancels the current bow charging */ void CancelChargingBow(void); - /// Returns true if the player is currently charging the bow + /** Returns true if the player is currently charging the bow */ bool IsChargingBow(void) const { return m_IsChargingBow; } void SetTouchGround( bool a_bTouchGround ); @@ -124,16 +129,16 @@ public: // tolua_begin - /// Returns the position where projectiles thrown by this player should start, player eye position + adjustment + /** Returns the position where projectiles thrown by this player should start, player eye position + adjustment */ Vector3d GetThrowStartPos(void) const; - /// Returns the initial speed vector of a throw, with a 3D length of a_SpeedCoeff. + /** Returns the initial speed vector of a throw, with a 3D length of a_SpeedCoeff. */ Vector3d GetThrowSpeed(double a_SpeedCoeff) const; - /// Returns the current gamemode. Partly OBSOLETE, you should use IsGameModeXXX() functions wherever applicable + /** Returns the current gamemode. Partly OBSOLETE, you should use IsGameModeXXX() functions wherever applicable */ eGameMode GetGameMode(void) const { return m_GameMode; } - /// Returns the current effective gamemode (inherited gamemode is resolved before returning) + /** Returns the current effective gamemode (inherited gamemode is resolved before returning) */ eGameMode GetEffectiveGameMode(void) const { return (m_GameMode == gmNotSet) ? m_World->GetGameMode() : m_GameMode; } /** Sets the gamemode for the player. @@ -142,24 +147,24 @@ public: */ void SetGameMode(eGameMode a_GameMode); - /// Returns true if the player is in Creative mode, either explicitly, or by inheriting from current world + /** Returns true if the player is in Creative mode, either explicitly, or by inheriting from current world */ bool IsGameModeCreative(void) const; - /// Returns true if the player is in Survival mode, either explicitly, or by inheriting from current world + /** Returns true if the player is in Survival mode, either explicitly, or by inheriting from current world */ bool IsGameModeSurvival(void) const; - /// Returns true if the player is in Adventure mode, either explicitly, or by inheriting from current world + /** Returns true if the player is in Adventure mode, either explicitly, or by inheriting from current world */ bool IsGameModeAdventure(void) const; AString GetIP(void) const { return m_IP; } // tolua_export - /// Returns the associated team, NULL if none + /** Returns the associated team, NULL if none */ cTeam * GetTeam(void) { return m_Team; } // tolua_export - /// Sets the player team, NULL if none + /** Sets the player team, NULL if none */ void SetTeam(cTeam * a_Team); - /// Forces the player to query the scoreboard for his team + /** Forces the player to query the scoreboard for his team */ cTeam * UpdateTeam(void); // tolua_end @@ -169,24 +174,24 @@ public: // Sets the current gamemode, doesn't check validity, doesn't send update packets to client void LoginSetGameMode(eGameMode a_GameMode); - /// Forces the player to move in the given direction. + /** Forces the player to move in the given direction. */ void ForceSetSpeed(Vector3d a_Direction); // tolua_export - /// Tries to move to a new position, with attachment-related checks (y == -999) + /** Tries to move to a new position, with attachment-related checks (y == -999) */ void MoveTo(const Vector3d & a_NewPos); // tolua_export cWindow * GetWindow(void) { return m_CurrentWindow; } // tolua_export const cWindow * GetWindow(void) const { return m_CurrentWindow; } - /// Opens the specified window; closes the current one first using CloseWindow() + /** Opens the specified window; closes the current one first using CloseWindow() */ void OpenWindow(cWindow * a_Window); // Exported in ManualBindings.cpp // tolua_begin - /// Closes the current window, resets current window to m_InventoryWindow. A plugin may refuse the closing if a_CanRefuse is true + /** Closes the current window, resets current window to m_InventoryWindow. A plugin may refuse the closing if a_CanRefuse is true */ void CloseWindow(bool a_CanRefuse = true); - /// Closes the current window if it matches the specified ID, resets current window to m_InventoryWindow + /** Closes the current window if it matches the specified ID, resets current window to m_InventoryWindow */ void CloseWindowIfID(char a_WindowID, bool a_CanRefuse = true); cClientHandle * GetClientHandle(void) const { return m_ClientHandle; } @@ -208,10 +213,10 @@ public: typedef std::list< cGroup* > GroupList; typedef std::list< std::string > StringList; - /// Adds a player to existing group or creates a new group when it doesn't exist + /** Adds a player to existing group or creates a new group when it doesn't exist */ void AddToGroup( const AString & a_GroupName ); // tolua_export - /// Removes a player from the group, resolves permissions and group inheritance (case sensitive) + /** Removes a player from the group, resolves permissions and group inheritance (case sensitive) */ void RemoveFromGroup( const AString & a_GroupName ); // tolua_export bool HasPermission( const AString & a_Permission ); // tolua_export @@ -234,7 +239,7 @@ public: /** tosses a pickup newly created from a_Item */ void TossPickup(const cItem & a_Item); - /// Heals the player by the specified amount of HPs (positive only); sends health update + /** Heals the player by the specified amount of HPs (positive only); sends health update */ void Heal(int a_Health); int GetFoodLevel (void) const { return m_FoodLevel; } @@ -243,7 +248,7 @@ public: double GetFoodExhaustionLevel (void) const { return m_FoodExhaustionLevel; } int GetFoodPoisonedTicksRemaining(void) const { return m_FoodPoisonedTicksRemaining; } - /// Returns true if the player is satiated, i. e. their foodlevel is at the max and they cannot eat anymore + /** Returns true if the player is satiated, i. e. their foodlevel is at the max and they cannot eat anymore */ bool IsSatiated(void) const { return (m_FoodLevel >= MAX_FOOD_LEVEL); } void SetFoodLevel (int a_FoodLevel); @@ -252,28 +257,28 @@ public: void SetFoodExhaustionLevel (double a_FoodExhaustionLevel); void SetFoodPoisonedTicksRemaining(int a_FoodPoisonedTicksRemaining); - /// Adds to FoodLevel and FoodSaturationLevel, returns true if any food has been consumed, false if player "full" + /** Adds to FoodLevel and FoodSaturationLevel, returns true if any food has been consumed, false if player "full" */ bool Feed(int a_Food, double a_Saturation); - /// Adds the specified exhaustion to m_FoodExhaustion. Expects only positive values. + /** Adds the specified exhaustion to m_FoodExhaustion. Expects only positive values. */ void AddFoodExhaustion(double a_Exhaustion) { m_FoodExhaustionLevel += a_Exhaustion; } - /// Starts the food poisoning for the specified amount of ticks; if already foodpoisoned, sets FoodPoisonedTicksRemaining to the larger of the two + /** Starts the food poisoning for the specified amount of ticks; if already foodpoisoned, sets FoodPoisonedTicksRemaining to the larger of the two */ void FoodPoison(int a_NumTicks); - /// Returns true if the player is currently in the process of eating the currently equipped item + /** Returns true if the player is currently in the process of eating the currently equipped item */ bool IsEating(void) const { return (m_EatingFinishTick >= 0); } - /// Returns true if the player is currently flying. + /** Returns true if the player is currently flying. */ bool IsFlying(void) const { return m_IsFlying; } /** Returns if a player is sleeping in a bed */ bool IsInBed(void) const { return m_bIsInBed; } - /// returns true if the player has thrown out a floater. + /** returns true if the player has thrown out a floater. */ bool IsFishing(void) const { return m_IsFishing; } void SetIsFishing(bool a_IsFishing, int a_FloaterID = -1) { m_IsFishing = a_IsFishing; m_FloaterID = a_FloaterID; } @@ -285,13 +290,13 @@ public: /** Sets a player's in-bed state; we can't be sure plugins will keep this value updated, so no exporting */ void SetIsInBed(bool a_Flag) { m_bIsInBed = a_Flag; } - /// Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet + /** Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet */ void StartEating(void); - /// Finishes eating the currently equipped item. Consumes the item, updates health and broadcasts the packets + /** Finishes eating the currently equipped item. Consumes the item, updates health and broadcasts the packets */ void FinishEating(void); - /// Aborts the current eating operation + /** Aborts the current eating operation */ void AbortEating(void); virtual void KilledBy(cEntity * a_Killer) override; @@ -320,45 +325,51 @@ public: cItem & GetDraggingItem(void) {return m_DraggingItem; } // In UI windows, when inventory-painting: - /// Clears the list of slots that are being inventory-painted. To be used by cWindow only + /** Clears the list of slots that are being inventory-painted. To be used by cWindow only */ void ClearInventoryPaintSlots(void); - /// Adds a slot to the list for inventory painting. To be used by cWindow only + /** Adds a slot to the list for inventory painting. To be used by cWindow only */ void AddInventoryPaintSlot(int a_SlotNum); - /// Returns the list of slots currently stored for inventory painting. To be used by cWindow only + /** Returns the list of slots currently stored for inventory painting. To be used by cWindow only */ const cSlotNums & GetInventoryPaintSlots(void) const; // tolua_begin - /// Returns the current relative maximum speed (takes current sprinting state into account) + /** Returns the current relative maximum speed (takes current sprinting / flying state into account) */ double GetMaxSpeed(void) const; - /// Gets the normal relative maximum speed + /** Gets the normal relative maximum speed */ double GetNormalMaxSpeed(void) const { return m_NormalMaxSpeed; } - /// Gets the sprinting relative maximum speed + /** Gets the sprinting relative maximum speed */ double GetSprintingMaxSpeed(void) const { return m_SprintingMaxSpeed; } - /// Sets the normal maximum speed, as reported in the 1.6.1+ protocol. Sends the update to player, if needed. + /** Gets the flying relative maximum speed */ + double GetFlyingMaxSpeed(void) const { return m_FlyingMaxSpeed; } + + /** Sets the normal relative maximum speed. Sends the update to player, if needed. */ void SetNormalMaxSpeed(double a_Speed); - /// Sets the sprinting maximum speed, as reported in the 1.6.1+ protocol. Sends the update to player, if needed. + /** Sets the sprinting relative maximum speed. Sends the update to player, if needed. */ void SetSprintingMaxSpeed(double a_Speed); - /// Sets the crouch status, broadcasts to all visible players + /** Sets the flying relative maximum speed. Sends the update to player, if needed. */ + void SetFlyingMaxSpeed(double a_Speed); + + /** Sets the crouch status, broadcasts to all visible players */ void SetCrouch(bool a_IsCrouched); - /// Starts or stops sprinting, sends the max speed update to the client, if needed + /** Starts or stops sprinting, sends the max speed update to the client, if needed */ void SetSprint(bool a_IsSprinting); - /// Flags the player as flying + /** Flags the player as flying */ void SetFlying(bool a_IsFlying); - /// If true the player can fly even when he's not in creative. + /** If true the player can fly even when he's not in creative. */ void SetCanFly(bool a_CanFly); - /// Returns wheter the player can fly or not. + /** Returns wheter the player can fly or not. */ virtual bool CanFly(void) const { return m_CanFly; } // tolua_end @@ -380,7 +391,7 @@ protected: AString m_PlayerName; AString m_LoadedWorldName; - /// Xp Level stuff + /** Xp Level stuff */ enum { XP_TO_LEVEL15 = 255, @@ -391,22 +402,22 @@ protected: bool m_bVisible; // Food-related variables: - /// Represents the food bar, one point equals half a "drumstick" + /** Represents the food bar, one point equals half a "drumstick" */ int m_FoodLevel; - /// "Overcharge" for the m_FoodLevel; is depleted before m_FoodLevel + /** "Overcharge" for the m_FoodLevel; is depleted before m_FoodLevel */ double m_FoodSaturationLevel; - /// Count-up to the healing or damaging action, based on m_FoodLevel + /** Count-up to the healing or damaging action, based on m_FoodLevel */ int m_FoodTickTimer; - /// A "buffer" which adds up hunger before it is substracted from m_FoodSaturationLevel or m_FoodLevel. Each action adds a little + /** A "buffer" which adds up hunger before it is substracted from m_FoodSaturationLevel or m_FoodLevel. Each action adds a little */ double m_FoodExhaustionLevel; - /// Number of ticks remaining for the foodpoisoning effect; zero if not foodpoisoned + /** Number of ticks remaining for the foodpoisoning effect; zero if not foodpoisoned */ int m_FoodPoisonedTicksRemaining; - /// Last position that has been recorded for food-related processing: + /** Last position that has been recorded for food-related processing: */ Vector3d m_LastFoodPos; float m_LastJumpHeight; @@ -422,7 +433,7 @@ protected: eGameMode m_GameMode; AString m_IP; - /// The item being dragged by the cursor while in a UI window + /** The item being dragged by the cursor while in a UI window */ cItem m_DraggingItem; long long m_LastPlayerListTime; @@ -437,11 +448,16 @@ protected: Default value is 1. */ double m_NormalMaxSpeed; - /** Max speed, relative to the game default max speed. + /** Max speed, relative to the game default max speed, when sprinting. 1 means regular speed, 2 means twice as fast, 0.5 means half-speed. - Default value is 1.3 */ + Default value is 1.3. */ double m_SprintingMaxSpeed; + /** Max speed, relative to the game default flying max speed, when flying. + 1 means regular speed, 2 means twice as fast, 0.5 means half-speed. + Default value is 1. */ + double m_FlyingMaxSpeed; + bool m_IsCrouched; bool m_IsSprinting; bool m_IsFlying; @@ -451,10 +467,10 @@ protected: bool m_CanFly; // If this is true the player can fly. Even if he is not in creative. - /// The world tick in which eating will be finished. -1 if not eating + /** The world tick in which eating will be finished. -1 if not eating */ Int64 m_EatingFinishTick; - /// Player Xp level + /** Player Xp level */ short int m_LifetimeTotalXp; short int m_CurrentXp; @@ -475,19 +491,19 @@ protected: virtual void Destroyed(void); - /// Filters out damage for creative mode/friendly fire + /** Filters out damage for creative mode/friendly fire */ virtual void DoTakeDamage(TakeDamageInfo & TDI) override; /** Stops players from burning in creative mode */ virtual void TickBurning(cChunk & a_Chunk) override; - /// Called in each tick to handle food-related processing + /** Called in each tick to handle food-related processing */ void HandleFood(void); - /// Called in each tick if the player is fishing to make sure the floater dissapears when the player doesn't have a fishing rod as equipped item. + /** Called in each tick if the player is fishing to make sure the floater dissapears when the player doesn't have a fishing rod as equipped item. */ void HandleFloater(void); - /// Adds food exhaustion based on the difference between Pos and LastPos, sprinting status and swimming (in water block) + /** Adds food exhaustion based on the difference between Pos and LastPos, sprinting status and swimming (in water block) */ void ApplyFoodExhaustionFromMovement(); /** Flag representing whether the player is currently in a bed diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 21c77e903..721ed349e 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -687,8 +687,7 @@ void cProtocol172::SendPlayerAbilities(void) Flags |= 0x04; } Pkt.WriteByte(Flags); - // TODO: Pkt.WriteFloat(m_Client->GetPlayer()->GetMaxFlyingSpeed()); - Pkt.WriteFloat(0.05f); + Pkt.WriteFloat((float)(0.05 * m_Client->GetPlayer()->GetFlyingMaxSpeed())); Pkt.WriteFloat((float)(0.1 * m_Client->GetPlayer()->GetMaxSpeed())); } -- cgit v1.2.3 From a69a1ef0325c5e472f1dd736f3a14a260d747ad9 Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 20 Mar 2014 13:23:15 -0700 Subject: Fixed enum checking functions not being called in generated code --- lib/tolua++/src/bin/basic_lua.h | 1214 +++++++++--------- lib/tolua++/src/bin/declaration_lua.h | 1471 +++++++++++----------- lib/tolua++/src/bin/enumerate_lua.h | 362 +++--- lib/tolua++/src/bin/function_lua.h | 2078 +++++++++++++++---------------- lib/tolua++/src/bin/lua/basic.lua | 4 +- lib/tolua++/src/bin/lua/declaration.lua | 4 +- lib/tolua++/src/bin/lua/enumerate.lua | 6 +- lib/tolua++/src/bin/lua/function.lua | 2 +- 8 files changed, 2572 insertions(+), 2569 deletions(-) diff --git a/lib/tolua++/src/bin/basic_lua.h b/lib/tolua++/src/bin/basic_lua.h index d4b816a2c..2128cb44b 100644 --- a/lib/tolua++/src/bin/basic_lua.h +++ b/lib/tolua++/src/bin/basic_lua.h @@ -135,622 +135,624 @@ static const unsigned char lua_basic_lua[] = { 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x0a, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, - 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x5f, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x64, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x73, + 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, + 0x2c, 0x6f, 0x6c, 0x64, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x25, 0x73, + 0x2a, 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x40, 0x25, 0x73, 0x2a, + 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x29, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, + 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x65, 0x6e, 0x61, + 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x3b, + 0x20, 0x69, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, + 0x6d, 0x3a, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x40, 0x70, + 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x74, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x5f, + 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x2c, 0x7b, 0x6f, 0x6c, + 0x64, 0x3d, 0x6f, 0x6c, 0x64, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x3d, 0x6e, + 0x65, 0x77, 0x7d, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x73, 0x29, - 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x2c, - 0x6f, 0x6c, 0x64, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x73, 0x74, - 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x22, 0x25, 0x73, 0x2a, - 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x40, 0x25, 0x73, 0x2a, 0x28, - 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x29, 0x0a, 0x09, 0x69, - 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x09, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, 0x49, - 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x65, 0x6e, 0x61, 0x6d, - 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x3b, 0x20, - 0x69, 0x74, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, - 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, - 0x3a, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x40, 0x70, 0x61, - 0x74, 0x74, 0x65, 0x72, 0x6e, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, - 0x0a, 0x09, 0x74, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x5f, 0x72, - 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x2c, 0x7b, 0x6f, 0x6c, 0x64, - 0x3d, 0x6f, 0x6c, 0x64, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x3d, 0x6e, 0x65, - 0x77, 0x7d, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x72, - 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x73, 0x29, 0x0a, - 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, 0x67, 0x65, 0x74, - 0x6e, 0x28, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x29, - 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x6d, 0x2c, 0x6e, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, - 0x2c, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x5b, 0x69, - 0x5d, 0x2e, 0x6f, 0x6c, 0x64, 0x2c, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, - 0x69, 0x6e, 0x67, 0x5b, 0x69, 0x5d, 0x2e, 0x6e, 0x65, 0x77, 0x29, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, 0x30, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x6d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, - 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, - 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x28, - 0x73, 0x2c, 0x66, 0x29, 0x0a, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x75, 0x72, - 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x2a, 0x2a, 0x2a, 0x63, - 0x75, 0x72, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f, 0x72, - 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, - 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x5f, 0x63, - 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x29, 0x0a, 0x09, - 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x29, - 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, - 0x54, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x20, 0x3d, - 0x20, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x0a, 0x20, 0x69, 0x66, - 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x31, 0x2c, - 0x31, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x23, 0x27, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x22, - 0x5c, 0x6e, 0x2a, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, 0x20, - 0x22, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, - 0x32, 0x29, 0x2e, 0x2e, 0x22, 0x2e, 0x5c, 0x6e, 0x5c, 0x6e, 0x22, 0x29, - 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, - 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x73, - 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x5f, - 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x22, 0x5e, - 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2d, 0x5c, 0x6e, 0x29, 0x22, 0x29, 0x20, - 0x2d, 0x2d, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, 0x66, - 0x69, 0x72, 0x73, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x20, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x73, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x63, 0x75, 0x72, - 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, - 0x20, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, - 0x2c, 0x22, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x22, - 0x2c, 0x22, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x22, 0x29, 0x20, 0x2d, 0x2d, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, - 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x20, - 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, - 0x5f, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x22, 0x63, - 0x68, 0x61, 0x72, 0x2a, 0x22, 0x29, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x27, - 0x63, 0x68, 0x61, 0x72, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x20, - 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x5f, 0x6c, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x22, 0x6c, 0x75, 0x61, 0x5f, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x22, 0x29, 0x20, 0x20, 0x2d, 0x2d, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, - 0x20, 0x27, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, - 0x27, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x22, - 0x43, 0x6f, 0x64, 0x65, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x3a, 0x5c, 0x6e, 0x22, - 0x2e, 0x2e, 0x73, 0x2e, 0x2e, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, - 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x22, 0x28, 0x66, 0x20, 0x69, 0x73, - 0x20, 0x6e, 0x69, 0x6c, 0x29, 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x2a, 0x2a, - 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, 0x22, - 0x2e, 0x2e, 0x66, 0x2e, 0x2e, 0x73, 0x2e, 0x2e, 0x22, 0x2e, 0x5c, 0x6e, - 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, - 0x50, 0x55, 0x54, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x6d, 0x73, 0x67, - 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, - 0x71, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, 0x67, 0x65, + 0x74, 0x6e, 0x28, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, + 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6d, 0x2c, 0x6e, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x5b, + 0x69, 0x5d, 0x2e, 0x6f, 0x6c, 0x64, 0x2c, 0x5f, 0x72, 0x65, 0x6e, 0x61, + 0x6d, 0x69, 0x6e, 0x67, 0x5b, 0x69, 0x5d, 0x2e, 0x6e, 0x65, 0x77, 0x29, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, 0x30, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, + 0x28, 0x73, 0x2c, 0x66, 0x29, 0x0a, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x75, + 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x2a, 0x2a, 0x2a, + 0x63, 0x75, 0x72, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x73, 0x20, 0x22, + 0x2e, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x5f, + 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x29, 0x0a, + 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x64, 0x65, 0x62, 0x75, 0x67, + 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, + 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x20, - 0x3d, 0x20, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x0a, 0x20, 0x77, - 0x72, 0x69, 0x74, 0x65, 0x28, 0x22, 0x5c, 0x6e, 0x2a, 0x2a, 0x20, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, - 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x6d, 0x73, 0x67, 0x2e, 0x2e, 0x22, 0x2e, - 0x5c, 0x6e, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, - 0x50, 0x55, 0x54, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x20, 0x61, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, - 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3a, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x66, 0x75, 0x6c, - 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x67, 0x74, 0x79, 0x70, 0x65, 0x20, - 0x28, 0x74, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x69, 0x73, - 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x29, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x74, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, - 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x29, 0x0a, 0x0a, 0x09, - 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x5f, 0x75, 0x73, 0x65, 0x72, - 0x74, 0x79, 0x70, 0x65, 0x5b, 0x66, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, - 0x70, 0x70, 0x65, 0x6e, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, - 0x65, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x74, 0x0a, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x76, 0x61, 0x72, 0x28, 0x74, 0x79, - 0x70, 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x65, 0x6c, 0x73, - 0x65, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x74, - 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, - 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, - 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x74, 0x0a, 0x09, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x09, 0x09, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, - 0x65, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x69, 0x73, 0x20, 0x65, 0x6e, 0x75, - 0x6d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, - 0x73, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, - 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x65, - 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x20, 0x69, 0x66, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x28, 0x74, 0x79, 0x70, - 0x65, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, - 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x79, 0x70, 0x65, 0x2c, - 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, - 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x2c, 0x74, 0x20, - 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, - 0x65, 0x66, 0x28, 0x27, 0x27, 0x2c, 0x20, 0x74, 0x29, 0x0a, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x5f, 0x62, 0x61, - 0x73, 0x69, 0x63, 0x5b, 0x74, 0x5d, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x62, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x62, 0x2c, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, - 0x63, 0x74, 0x79, 0x70, 0x65, 0x5b, 0x62, 0x5d, 0x0a, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, - 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, - 0x6c, 0x69, 0x74, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, - 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, - 0x6c, 0x69, 0x74, 0x20, 0x28, 0x73, 0x2c, 0x74, 0x29, 0x0a, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, - 0x30, 0x7d, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, - 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, - 0x73, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, - 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x6c, 0x5b, 0x6c, - 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x0a, 0x20, 0x20, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x20, 0x3d, 0x20, - 0x22, 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x22, - 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x22, 0x25, 0x73, 0x2a, 0x22, 0x0a, 0x20, - 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, - 0x5e, 0x25, 0x73, 0x2b, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x73, - 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x25, - 0x73, 0x2b, 0x24, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, - 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x70, 0x2c, 0x66, - 0x29, 0x0a, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x2e, 0x6e, - 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, 0x6e, 0x5d, - 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x28, - 0x25, 0x73, 0x25, 0x73, 0x2a, 0x29, 0x24, 0x22, 0x2c, 0x22, 0x22, 0x29, - 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x0a, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, - 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, - 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, - 0x72, 0x6e, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, - 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, - 0x69, 0x61, 0x6c, 0x20, 0x63, 0x61, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, - 0x20, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x28, 0x74, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x29, 0x0a, 0x2d, 0x2d, - 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x63, 0x61, 0x6e, - 0x27, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x27, 0x5e, 0x27, 0x20, 0x28, 0x61, 0x73, 0x20, 0x75, - 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, - 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x6c, 0x69, 0x6e, 0x65, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6c, 0x73, - 0x6f, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x77, 0x68, 0x69, - 0x74, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x20, 0x70, - 0x61, 0x74, 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, - 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, - 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, - 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x62, - 0x65, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x65, 0x6e, - 0x64, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x6e, - 0x3d, 0x30, 0x7d, 0x0a, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x28, 0x6f, 0x66, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x2c, 0x20, 0x6f, 0x66, - 0x73, 0x29, 0x0a, 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, - 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x25, 0x73, - 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x72, - 0x65, 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x6e, - 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x5b, 0x72, - 0x65, 0x74, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x0a, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x6f, - 0x66, 0x73, 0x20, 0x3c, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x6c, 0x65, 0x6e, 0x28, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x75, 0x62, 0x20, - 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, - 0x28, 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x2c, 0x20, 0x2d, 0x31, 0x29, - 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, - 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, - 0x6e, 0x64, 0x28, 0x73, 0x75, 0x62, 0x2c, 0x20, 0x22, 0x5e, 0x22, 0x2e, - 0x2e, 0x70, 0x61, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x62, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x61, 0x64, 0x64, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, 0x2d, 0x31, - 0x29, 0x0a, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, - 0x66, 0x73, 0x2b, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6f, 0x66, - 0x73, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, + 0x3d, 0x20, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x31, + 0x2c, 0x31, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x23, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, + 0x22, 0x5c, 0x6e, 0x2a, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x3a, + 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x2c, 0x32, 0x29, 0x2e, 0x2e, 0x22, 0x2e, 0x5c, 0x6e, 0x5c, 0x6e, 0x22, + 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x75, 0x72, 0x72, + 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, + 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, + 0x5f, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x22, + 0x5e, 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2d, 0x5c, 0x6e, 0x29, 0x22, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x20, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x63, 0x75, + 0x72, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x22, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x2c, 0x22, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x22, 0x29, 0x20, 0x2d, + 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x27, 0x0a, 0x20, 0x20, + 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, + 0x22, 0x5f, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x22, + 0x63, 0x68, 0x61, 0x72, 0x2a, 0x22, 0x29, 0x20, 0x20, 0x2d, 0x2d, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x27, 0x63, 0x68, 0x61, 0x72, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x73, + 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x5f, + 0x6c, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x22, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x22, 0x29, 0x20, 0x20, 0x2d, + 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x27, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, + 0x22, 0x43, 0x6f, 0x64, 0x65, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x3a, 0x5c, 0x6e, + 0x22, 0x2e, 0x2e, 0x73, 0x2e, 0x2e, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x22, 0x28, 0x66, 0x20, 0x69, + 0x73, 0x20, 0x6e, 0x69, 0x6c, 0x29, 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x2a, + 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x20, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, + 0x22, 0x2e, 0x2e, 0x66, 0x2e, 0x2e, 0x73, 0x2e, 0x2e, 0x22, 0x2e, 0x5c, + 0x6e, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x5f, 0x4f, 0x55, + 0x54, 0x50, 0x55, 0x54, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x6d, 0x73, + 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, + 0x2e, 0x71, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5f, 0x4f, 0x55, 0x54, + 0x50, 0x55, 0x54, 0x0a, 0x20, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, + 0x20, 0x3d, 0x20, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x0a, 0x20, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x22, 0x5c, 0x6e, 0x2a, 0x2a, 0x20, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x20, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x6d, 0x73, 0x67, 0x2e, 0x2e, 0x22, + 0x2e, 0x5c, 0x6e, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x5f, 0x4f, 0x55, + 0x54, 0x50, 0x55, 0x54, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x66, 0x75, + 0x6c, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x67, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x69, + 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x66, + 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x29, 0x0a, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x74, 0x79, 0x70, 0x65, 0x5b, 0x66, 0x74, 0x5d, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, + 0x70, 0x65, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x74, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x66, 0x75, 0x6c, 0x6c, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x76, 0x61, 0x72, 0x28, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, + 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, + 0x66, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x74, 0x0a, 0x09, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, + 0x70, 0x65, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x69, 0x73, 0x20, 0x65, 0x6e, + 0x75, 0x6d, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, + 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, + 0x63, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6d, 0x2c, 0x74, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x27, 0x27, 0x2c, + 0x20, 0x74, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, + 0x20, 0x3d, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5b, 0x74, 0x5d, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x62, 0x2c, 0x5f, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x63, 0x74, 0x79, 0x70, 0x65, 0x5b, + 0x62, 0x5d, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, + 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x20, 0x28, 0x73, + 0x2c, 0x74, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, + 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x73, 0x29, 0x0a, 0x20, 0x20, 0x6c, + 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, + 0x0a, 0x20, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, + 0x73, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, + 0x22, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x28, 0x2e, + 0x2d, 0x29, 0x25, 0x73, 0x2a, 0x22, 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x22, + 0x25, 0x73, 0x2a, 0x22, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x2c, 0x22, 0x5e, 0x25, 0x73, 0x2b, 0x22, 0x2c, + 0x22, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x22, 0x25, 0x73, 0x2b, 0x24, 0x22, 0x2c, 0x22, + 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x73, 0x2c, 0x70, 0x2c, 0x66, 0x29, 0x0a, 0x20, 0x6c, 0x2e, 0x6e, + 0x20, 0x3d, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, + 0x6c, 0x5b, 0x6c, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x2c, 0x22, 0x28, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x29, + 0x24, 0x22, 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, + 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, + 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x2c, 0x20, 0x63, 0x6f, + 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, 0x61, 0x6c, 0x20, 0x63, 0x61, + 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x43, 0x20, 0x63, 0x6f, 0x64, + 0x65, 0x20, 0x28, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, + 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x65, + 0x74, 0x63, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, + 0x72, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x27, 0x74, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x5e, 0x27, + 0x20, 0x28, 0x61, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x29, 0x0a, + 0x2d, 0x2d, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x70, 0x73, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, + 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x28, 0x73, 0x2c, 0x20, 0x70, 0x61, 0x74, 0x29, 0x0a, 0x0a, 0x09, + 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, + 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, + 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x20, 0x3d, + 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x5f, 0x65, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x31, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x73, 0x20, 0x3d, + 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, + 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, 0x0a, 0x09, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, - 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x29, - 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, - 0x3d, 0x3d, 0x20, 0x22, 0x28, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x68, - 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x3c, 0x22, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x0a, 0x09, 0x09, 0x09, 0x09, - 0x69, 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, - 0x28, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x20, 0x3d, 0x20, 0x22, 0x5e, 0x25, 0x62, 0x28, 0x29, 0x22, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, - 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x3c, 0x22, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x3d, 0x20, - 0x22, 0x5e, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x09, 0x09, 0x09, 0x09, 0x62, 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, - 0x75, 0x62, 0x2c, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x29, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x2d, 0x2d, - 0x20, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, - 0x64, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3f, 0x0a, 0x09, 0x09, 0x09, - 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, - 0x31, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, - 0x73, 0x20, 0x2b, 0x20, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, - 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, - 0x2b, 0x31, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, - 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x61, - 0x64, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, - 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x72, 0x65, 0x74, 0x2e, - 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x3d, 0x31, - 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, 0x65, 0x74, 0x5b, 0x31, 0x5d, 0x20, - 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, - 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x6f, - 0x6e, 0x63, 0x61, 0x74, 0x65, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x20, 0x28, 0x74, 0x2c, - 0x66, 0x2c, 0x6c, 0x2c, 0x6a, 0x73, 0x74, 0x72, 0x29, 0x0a, 0x09, 0x6a, - 0x73, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x6a, 0x73, 0x74, 0x72, 0x20, 0x6f, - 0x72, 0x20, 0x22, 0x20, 0x22, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x73, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x66, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, - 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x6c, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, - 0x73, 0x20, 0x3d, 0x20, 0x73, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, - 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, - 0x69, 0x66, 0x20, 0x69, 0x20, 0x3c, 0x3d, 0x20, 0x6c, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x2e, 0x2e, 0x6a, 0x73, - 0x74, 0x72, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x0a, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, - 0x65, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x66, 0x6f, - 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x20, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x0a, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, - 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, - 0x69, 0x3c, 0x3d, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, - 0x6e, 0x64, 0x28, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x2c, 0x27, 0x5b, 0x25, - 0x28, 0x2c, 0x22, 0x5d, 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, - 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x5e, 0x5b, 0x25, 0x61, - 0x5f, 0x7e, 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x6c, - 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x27, 0x20, 0x27, 0x0a, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, - 0x3d, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x61, 0x72, - 0x67, 0x5b, 0x69, 0x5d, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x72, - 0x67, 0x5b, 0x69, 0x5d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x72, - 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x2d, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x0a, - 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, - 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, - 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, - 0x5b, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x5d, 0x2c, 0x22, 0x5b, 0x25, 0x2f, - 0x25, 0x29, 0x25, 0x3b, 0x25, 0x7b, 0x25, 0x7d, 0x5d, 0x24, 0x22, 0x29, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, - 0x74, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, - 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, 0x20, 0x27, 0x5c, 0x6e, - 0x27, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x2d, 0x2d, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x6c, - 0x69, 0x6e, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x28, 0x2e, 0x2e, 0x2e, - 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, - 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x61, - 0x72, 0x67, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x69, 0x66, - 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, - 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x2c, 0x27, 0x5b, 0x25, 0x28, 0x2c, 0x22, 0x5d, - 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, - 0x69, 0x5d, 0x2c, 0x22, 0x5e, 0x5b, 0x25, 0x61, 0x5f, 0x7e, 0x5d, 0x22, - 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, - 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, 0x20, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x20, 0x20, 0x69, - 0x66, 0x20, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x20, 0x7e, 0x3d, 0x20, - 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, - 0x62, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x2d, 0x31, 0x2c, - 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, - 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, - 0x28, 0x61, 0x72, 0x67, 0x5b, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x5d, 0x2c, - 0x22, 0x5b, 0x25, 0x2f, 0x25, 0x29, 0x25, 0x3b, 0x25, 0x7b, 0x25, 0x7d, - 0x5d, 0x24, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, - 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x77, 0x72, - 0x69, 0x74, 0x65, 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, - 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x73, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, - 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x67, 0x65, 0x74, 0x5f, - 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x73, 0x2c, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x62, 0x65, 0x67, + 0x69, 0x6e, 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x29, 0x0a, 0x09, 0x09, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x22, + 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x74, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, + 0x22, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x20, 0x3d, + 0x20, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x5b, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x5d, 0x20, + 0x3d, 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x77, + 0x68, 0x69, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x73, 0x20, 0x3c, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x6c, 0x65, 0x6e, 0x28, 0x73, + 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x73, 0x75, 0x62, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x6f, 0x66, + 0x73, 0x2c, 0x20, 0x2d, 0x31, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x62, 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x75, 0x62, + 0x2c, 0x20, 0x22, 0x5e, 0x22, 0x2e, 0x2e, 0x70, 0x61, 0x74, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x28, 0x6f, 0x66, 0x73, 0x2d, 0x31, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x6f, + 0x66, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, 0x65, 0x0a, 0x09, + 0x09, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x62, 0x65, 0x67, 0x69, + 0x6e, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x0a, 0x09, 0x09, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x6f, 0x66, 0x73, + 0x2c, 0x20, 0x6f, 0x66, 0x73, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x28, 0x22, + 0x20, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, 0x20, + 0x22, 0x3c, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x28, 0x22, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x22, 0x5e, + 0x25, 0x62, 0x28, 0x29, 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x3d, 0x3d, + 0x20, 0x22, 0x3c, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x22, 0x5e, 0x25, 0x62, 0x3c, 0x3e, + 0x22, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x62, + 0x2c, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x75, 0x62, 0x2c, 0x20, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x75, 0x6e, 0x74, 0x65, 0x72, + 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x3f, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, 0x20, + 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, 0x31, 0x0a, 0x09, 0x09, 0x09, 0x09, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x6f, 0x66, + 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x20, 0x2b, 0x20, 0x65, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x09, 0x09, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6f, 0x66, 0x73, + 0x20, 0x3d, 0x20, 0x6f, 0x66, 0x73, 0x2b, 0x31, 0x0a, 0x09, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x28, 0x6f, 0x66, 0x73, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x69, + 0x66, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x30, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, + 0x65, 0x74, 0x2e, 0x6e, 0x3d, 0x31, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x72, + 0x65, 0x74, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, + 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x6e, + 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x20, + 0x6f, 0x66, 0x20, 0x61, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x63, + 0x61, 0x74, 0x20, 0x28, 0x74, 0x2c, 0x66, 0x2c, 0x6c, 0x2c, 0x6a, 0x73, + 0x74, 0x72, 0x29, 0x0a, 0x09, 0x6a, 0x73, 0x74, 0x72, 0x20, 0x3d, 0x20, + 0x6a, 0x73, 0x74, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x20, 0x22, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x27, + 0x27, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x66, + 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x6c, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x2e, + 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x20, 0x3c, + 0x3d, 0x20, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x73, 0x20, 0x3d, + 0x20, 0x73, 0x2e, 0x2e, 0x6a, 0x73, 0x74, 0x72, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x73, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x6e, 0x61, 0x74, 0x65, 0x20, + 0x61, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x2c, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, + 0x67, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x20, + 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x61, 0x72, 0x67, + 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x2c, 0x27, 0x5b, 0x25, 0x28, 0x2c, 0x22, 0x5d, 0x27, 0x29, + 0x20, 0x61, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, + 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, + 0x2c, 0x22, 0x5e, 0x5b, 0x25, 0x61, 0x5f, 0x7e, 0x5d, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x2e, + 0x20, 0x27, 0x20, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x2e, 0x2e, 0x20, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x20, 0x7e, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x73, 0x75, 0x62, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x2d, + 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, + 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x61, 0x72, 0x67, 0x2e, 0x6e, + 0x5d, 0x2c, 0x22, 0x5b, 0x25, 0x2f, 0x25, 0x29, 0x25, 0x3b, 0x25, 0x7b, + 0x25, 0x7d, 0x5d, 0x24, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x3d, 0x6e, 0x69, 0x6c, 0x20, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x2e, 0x2e, 0x20, 0x27, 0x5c, 0x6e, 0x27, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x69, 0x6e, + 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x20, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, + 0x65, 0x20, 0x69, 0x3c, 0x3d, 0x61, 0x72, 0x67, 0x2e, 0x6e, 0x20, 0x64, + 0x6f, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x2c, 0x27, + 0x5b, 0x25, 0x28, 0x2c, 0x22, 0x5d, 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x5e, 0x5b, + 0x25, 0x61, 0x5f, 0x7e, 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, + 0x27, 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x69, + 0x5d, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x61, 0x72, 0x67, 0x5b, + 0x69, 0x5d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x72, 0x67, 0x5b, + 0x69, 0x5d, 0x2c, 0x2d, 0x31, 0x2c, 0x2d, 0x31, 0x29, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, + 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x72, 0x67, 0x5b, 0x61, + 0x72, 0x67, 0x2e, 0x6e, 0x5d, 0x2c, 0x22, 0x5b, 0x25, 0x2f, 0x25, 0x29, + 0x25, 0x3b, 0x25, 0x7b, 0x25, 0x7d, 0x5d, 0x24, 0x22, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x3d, + 0x6e, 0x69, 0x6c, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x27, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, + 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x28, 0x70, 0x74, 0x79, 0x70, + 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, - 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x6e, 0x61, - 0x6d, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x74, 0x79, 0x70, - 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x6f, 0x6f, 0x6b, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x67, 0x65, 0x74, 0x5f, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x74, + 0x79, 0x70, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, + 0x6b, 0x28, 0x70, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, + 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x20, 0x73, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x67, 0x65, 0x74, + 0x5f, 0x22, 0x2e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x73, + 0x65, 0x74, 0x5f, 0x22, 0x2e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x71, 0x74, 0x22, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, + 0x22, 0x73, 0x65, 0x74, 0x22, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x75, 0x70, 0x70, 0x65, 0x72, 0x28, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x31, 0x2c, 0x20, 0x31, 0x29, 0x29, 0x2e, 0x2e, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x2d, 0x31, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x67, 0x65, - 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x22, 0x67, 0x65, 0x74, 0x5f, 0x22, 0x2e, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x73, 0x65, 0x74, 0x5f, 0x22, 0x2e, 0x2e, + 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, + 0x64, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, - 0x69, 0x66, 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, - 0x22, 0x71, 0x74, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, - 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x73, 0x65, 0x74, 0x22, 0x2e, - 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x75, 0x70, 0x70, 0x65, - 0x72, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, - 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x29, - 0x29, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, - 0x62, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x2d, - 0x31, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, - 0x20, 0x70, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x6f, - 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x6e, - 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x09, - 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x72, 0x69, - 0x67, 0x68, 0x74, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x24, 0x5b, 0x69, 0x63, 0x68, 0x6c, 0x5d, 0x66, 0x69, 0x6c, 0x65, - 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2c, - 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x62, 0x65, - 0x66, 0x6f, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, - 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x61, - 0x67, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x68, - 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x29, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x70, - 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6c, - 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, - 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x70, 0x6b, 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x6f, - 0x72, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x24, 0x69, 0x66, 0x69, - 0x6c, 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x61, 0x20, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x61, 0x6c, 0x6c, - 0x65, 0x64, 0x20, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x27, 0x20, 0x69, 0x6e, - 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, - 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x61, 0x6e, 0x79, 0x20, 0x65, 0x78, 0x74, 0x72, 0x61, 0x20, 0x61, 0x72, - 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x70, - 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x24, 0x69, 0x66, - 0x69, 0x6c, 0x65, 0x2e, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, - 0x74, 0x2c, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2c, - 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, + 0x6f, 0x6f, 0x6b, 0x73, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, - 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, - 0x74, 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, - 0x6f, 0x64, 0x65, 0x20, 0x28, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x27, 0x24, - 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x27, 0x2c, 0x20, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, - 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x69, 0x67, - 0x68, 0x74, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x70, 0x61, - 0x72, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, - 0x74, 0x75, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x0a, 0x2d, - 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x6f, 0x6e, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x27, 0x63, 0x6f, 0x64, 0x65, 0x27, 0x20, 0x6b, - 0x65, 0x79, 0x2e, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x73, - 0x65, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, - 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, - 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x62, 0x65, 0x66, 0x6f, - 0x72, 0x65, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, - 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, - 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, - 0x65, 0x72, 0x20, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, - 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, - 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, - 0x72, 0x6f, 0x6d, 0x20, 0x27, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, - 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x73, 0x27, 0x20, 0x74, 0x6f, 0x20, 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x20, 0x74, 0x6f, - 0x20, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x20, 0x61, 0x20, - 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x0a, 0x2d, 0x2d, 0x20, - 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, - 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x72, 0x6f, - 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, - 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, - 0x6f, 0x6d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x64, 0x6f, 0x70, 0x61, 0x72, 0x73, - 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, - 0x70, 0x61, 0x72, 0x73, 0x65, 0x64, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x20, 0x6f, 0x72, - 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, - 0x72, 0x73, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x29, - 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, - 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, - 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, - 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x62, 0x65, 0x66, - 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, - 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x70, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, - 0x6b, 0x28, 0x66, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, - 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, - 0x6d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x2c, - 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, - 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, - 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x66, 0x29, 0x0a, 0x0a, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, - 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, - 0x65, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, - 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x68, 0x6f, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x24, 0x5b, 0x69, 0x63, 0x68, + 0x6c, 0x5d, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x73, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, + 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x70, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x29, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x70, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x20, + 0x68, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x6b, 0x67, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x76, 0x65, 0x72, + 0x79, 0x20, 0x24, 0x69, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, + 0x6b, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x27, 0x63, 0x6f, + 0x64, 0x65, 0x27, 0x20, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x65, 0x78, + 0x74, 0x72, 0x61, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x0a, 0x2d, 0x2d, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x24, 0x69, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x20, 0x6e, + 0x6f, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, + 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x74, 0x2c, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x79, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x61, 0x74, 0x27, 0x73, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x28, 0x6c, + 0x69, 0x6b, 0x65, 0x20, 0x27, 0x24, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, + 0x6e, 0x67, 0x27, 0x2c, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2c, 0x20, 0x65, 0x74, 0x63, 0x29, 0x0a, 0x2d, 0x2d, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x73, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x61, 0x63, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x63, + 0x6f, 0x64, 0x65, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x61, 0x6b, 0x65, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, + 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, + 0x64, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x27, 0x63, + 0x6f, 0x64, 0x65, 0x27, 0x20, 0x6b, 0x65, 0x79, 0x2e, 0x20, 0x6e, 0x6f, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x73, 0x65, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, + 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x64, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, + 0x65, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x6f, 0x6f, + 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x64, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, 0x20, 0x77, 0x72, 0x69, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x0a, 0x2d, 0x2d, 0x20, + 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x50, 0x61, + 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, + 0x73, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x27, 0x67, + 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x27, 0x20, 0x74, 0x6f, 0x20, + 0x67, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x65, 0x74, 0x68, + 0x6f, 0x64, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x74, 0x72, 0x69, + 0x65, 0x76, 0x65, 0x20, 0x61, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x72, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x5f, 0x68, 0x6f, + 0x6f, 0x6b, 0x28, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, - 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x2e, 0x2e, - 0x2e, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, - 0x2d, 0x20, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x70, 0x75, 0x73, - 0x68, 0x65, 0x72, 0x73, 0x0a, 0x0a, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, - 0x7b, 0x7d, 0x0a, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x65, - 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, - 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, - 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, + 0x6c, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, + 0x64, 0x6f, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x62, 0x65, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x64, + 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x69, 0x6c, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x73, 0x75, 0x62, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x5f, 0x68, + 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x66, + 0x72, 0x6f, 0x6d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, + 0x65, 0x2c, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x66, 0x29, 0x0a, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x75, + 0x70, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x61, 0x66, 0x74, 0x65, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, 0x73, + 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, + 0x66, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x70, 0x61, 0x63, + 0x6b, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x68, + 0x6f, 0x6f, 0x6b, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x20, 0x70, 0x75, 0x73, 0x68, 0x65, 0x72, 0x73, 0x0a, 0x0a, + 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x69, 0x73, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, + 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, + 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, + 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x73, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, + 0x74, 0x5d, 0x0a, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x62, 0x74, 0x79, 0x70, 0x65, 0x5d, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, - 0x65, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x5f, 0x62, 0x61, 0x73, - 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, - 0x74, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x29, 0x0a, 0x0a, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, - 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, 0x74, 0x5d, 0x0a, 0x0a, 0x09, 0x77, - 0x68, 0x69, 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x64, - 0x6f, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, - 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x73, 0x5b, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x09, - 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, - 0x3d, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x65, 0x73, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, - 0x62, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, + 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, + 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, + 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, + 0x73, 0x68, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x70, 0x75, 0x73, 0x68, - 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, - 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, - 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, - 0x65, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x75, 0x73, 0x65, 0x72, - 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, - 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, - 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, - 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, - 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, - 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, - 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, - 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, - 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, - 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x69, - 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, - 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, - 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, - 0x73, 0x65, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, - 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a + 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, + 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, + 0x28, 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x6f, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, + 0x6f, 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, + 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f, + 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, + 0x20, 0x74, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x74, 0x5d, 0x20, 0x6f, 0x72, 0x20, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x28, + 0x74, 0x2c, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x69, 0x73, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x6f, + 0x72, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, + 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x22, 0x0a, 0x65, 0x6e, 0x64, + 0x0a }; -unsigned int lua_basic_lua_len = 9031; +unsigned int lua_basic_lua_len = 9049; diff --git a/lib/tolua++/src/bin/declaration_lua.h b/lib/tolua++/src/bin/declaration_lua.h index 0e3486604..28deb4f60 100644 --- a/lib/tolua++/src/bin/declaration_lua.h +++ b/lib/tolua++/src/bin/declaration_lua.h @@ -476,724 +476,758 @@ static const unsigned char lua_declaration_lua[] = { 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x30, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, 0x20, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x27, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x27, 0x2e, - 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, - 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, 0x6e, - 0x75, 0x6d, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x72, 0x65, 0x74, + 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, + 0x6e, 0x75, 0x6d, 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x7e, 0x3d, 0x20, 0x6e, 0x69, + 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, - 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x20, - 0x6f, 0x72, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, - 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, - 0x20, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x28, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x6e, 0x69, 0x6c, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, - 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x26, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x20, 0x7c, - 0x7c, 0x20, 0x21, 0x27, 0x2e, 0x2e, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, - 0x63, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, + 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x27, 0x2e, 0x2e, + 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, - 0x22, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, - 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, - 0x72, 0x72, 0x29, 0x29, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, - 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x21, 0x27, - 0x2e, 0x2e, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2e, 0x2e, 0x27, - 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, - 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x22, 0x27, 0x2e, 0x2e, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, - 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, - 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, - 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, - 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x28, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x63, 0x70, 0x6c, 0x75, 0x73, - 0x70, 0x6c, 0x75, 0x73, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, - 0x6e, 0x69, 0x6c, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, - 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x27, - 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x6f, 0x64, 0x0a, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, - 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x63, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, - 0x74, 0x25, 0x73, 0x2b, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, 0x69, - 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, - 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x27, 0x2c, 0x27, 0x27, 0x29, - 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, - 0x74, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6d, 0x6f, - 0x64, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, - 0x72, 0x72, 0x61, 0x79, 0x73, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, - 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x7e, - 0x3d, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, - 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, - 0x20, 0x27, 0x2a, 0x27, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x69, - 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x22, 0x20, - 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x74, - 0x79, 0x70, 0x65, 0x2c, 0x70, 0x74, 0x72, 0x29, 0x0a, 0x20, 0x69, 0x66, - 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, - 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, - 0x65, 0x2c, 0x27, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, - 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, - 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, - 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, - 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x7e, - 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, + 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x20, 0x6f, + 0x72, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x28, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x6e, + 0x69, 0x6c, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, + 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x20, 0x7c, 0x7c, + 0x20, 0x21, 0x27, 0x2e, 0x2e, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x22, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, + 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, + 0x72, 0x29, 0x29, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x21, 0x27, 0x2e, + 0x2e, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2e, 0x2e, 0x27, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, + 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x22, + 0x2c, 0x27, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x2e, 0x2e, 0x27, 0x2c, 0x26, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x27, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x64, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, + 0x6c, 0x75, 0x73, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, 0x6e, + 0x69, 0x6c, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x6f, 0x64, 0x0a, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x25, 0x73, 0x2b, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x20, + 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x65, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x6d, 0x6f, 0x64, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x72, + 0x72, 0x61, 0x79, 0x73, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x7e, 0x3d, + 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, + 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, + 0x27, 0x2a, 0x27, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x69, 0x6e, + 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x22, 0x20, 0x22, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x74, 0x79, + 0x70, 0x65, 0x2c, 0x70, 0x74, 0x72, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, - 0x2c, 0x27, 0x5b, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, - 0x6d, 0x2c, 0x27, 0x5d, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, - 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, 0x70, 0x6c, 0x75, 0x73, - 0x70, 0x6c, 0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x2c, 0x27, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, - 0x27, 0x20, 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, - 0x65, 0x77, 0x5f, 0x64, 0x69, 0x6d, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, - 0x65, 0x2c, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x2c, 0x20, 0x27, 0x2e, 0x2e, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2e, 0x2e, 0x27, 0x29, - 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, + 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x7e, 0x3d, + 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, - 0x27, 0x20, 0x3d, 0x20, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, - 0x70, 0x74, 0x72, 0x2c, 0x27, 0x2a, 0x29, 0x27, 0x2c, 0x0a, 0x09, 0x09, - 0x27, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x28, 0x28, 0x27, 0x2c, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2c, 0x27, 0x29, 0x2a, 0x73, - 0x69, 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, - 0x2c, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, - 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, - 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x69, 0x6e, - 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x20, 0x3d, - 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x3d, - 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, - 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x20, 0x27, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x53, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, - 0x65, 0x0a, 0x20, 0x20, 0x09, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, - 0x28, 0x22, 0x74, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x6f, - 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x29, 0x2e, 0x2e, 0x22, - 0x2c, 0x20, 0x70, 0x74, 0x72, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, 0x2e, - 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x70, 0x74, 0x72, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x09, 0x69, - 0x66, 0x20, 0x74, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, 0x29, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x74, 0x20, 0x3d, - 0x20, 0x27, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x27, 0x0a, - 0x20, 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, - 0x6f, 0x74, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x74, 0x72, - 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x69, - 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x2a, - 0x27, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x65, + 0x27, 0x5b, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, + 0x2c, 0x27, 0x5d, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, + 0x6c, 0x75, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, + 0x20, 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, + 0x77, 0x5f, 0x64, 0x69, 0x6d, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x2c, 0x20, 0x27, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2e, 0x2e, 0x27, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, + 0x20, 0x3d, 0x20, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x70, + 0x74, 0x72, 0x2c, 0x27, 0x2a, 0x29, 0x27, 0x2c, 0x0a, 0x09, 0x09, 0x27, + 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x28, 0x28, 0x27, 0x2c, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2c, 0x27, 0x29, 0x2a, 0x73, 0x69, + 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x70, 0x74, 0x72, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x28, 0x28, 0x27, - 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x74, 0x79, - 0x70, 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x69, 0x6e, + 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x20, 0x3d, 0x20, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, + 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, + 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x20, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x0a, 0x20, 0x20, 0x09, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x22, 0x74, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x6f, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x29, 0x2e, 0x2e, 0x22, 0x2c, + 0x20, 0x70, 0x74, 0x72, 0x20, 0x69, 0x73, 0x20, 0x22, 0x2e, 0x2e, 0x74, + 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x74, 0x72, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x09, 0x69, 0x66, + 0x20, 0x74, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x74, 0x72, 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, + 0x27, 0x75, 0x73, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x27, 0x0a, 0x20, + 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x74, 0x72, 0x3d, + 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x2a, 0x27, - 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x65, + 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x28, 0x28, 0x27, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x29, 0x20, 0x27, - 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, - 0x28, 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, - 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, - 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x28, 0x69, 0x6e, 0x74, 0x29, 0x20, 0x27, - 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x69, - 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x7e, - 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, - 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, - 0x65, 0x66, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x70, 0x74, 0x72, - 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, - 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x64, 0x65, 0x66, - 0x20, 0x3d, 0x20, 0x22, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, - 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x29, 0x22, 0x2e, 0x2e, 0x64, 0x65, 0x66, - 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, - 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, - 0x2c, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x27, 0x2e, - 0x2e, 0x74, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, - 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x27, 0x2c, - 0x64, 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, - 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, - 0x65, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x6c, - 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x74, - 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, - 0x2c, 0x27, 0x2c, 0x27, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, - 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, - 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, - 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, - 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x28, 0x6e, 0x61, 0x72, - 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, 0x6e, 0x69, - 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, - 0x5f, 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, - 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x64, - 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, - 0x61, 0x72, 0x67, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x29, 0x0a, 0x09, - 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6c, - 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x66, 0x61, 0x6c, 0x73, 0x65, - 0x29, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, - 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x2a, 0x27, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x27, 0x29, 0x20, 0x27, 0x29, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, 0x28, + 0x6e, 0x63, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, + 0x6e, 0x63, 0x61, 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, + 0x6e, 0x65, 0x2c, 0x27, 0x28, 0x69, 0x6e, 0x74, 0x29, 0x20, 0x27, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x69, 0x66, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x64, + 0x65, 0x66, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, + 0x66, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x70, 0x74, 0x72, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, 0x27, + 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x64, 0x65, 0x66, 0x20, + 0x3d, 0x20, 0x22, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, 0x28, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x2e, 0x2e, 0x22, 0x29, 0x22, 0x2e, 0x2e, 0x64, 0x65, 0x66, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, + 0x74, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, + 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x27, 0x2e, 0x2e, + 0x74, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x27, 0x2c, 0x64, + 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, + 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, + 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x74, 0x6f, + 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, + 0x27, 0x2c, 0x27, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, + 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x64, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x28, 0x6e, 0x61, 0x72, 0x67, + 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x5f, + 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x64, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x61, + 0x72, 0x67, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x29, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6c, 0x73, + 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, - 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x3a, 0x67, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, 0x6e, - 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, - 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, - 0x7b, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, - 0x4c, 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, - 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x64, 0x65, 0x66, 0x3b, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x64, 0x65, 0x66, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x20, 0x64, 0x65, 0x66, 0x3d, 0x31, 0x20, 0x65, 0x6c, 0x73, 0x65, - 0x20, 0x64, 0x65, 0x66, 0x3d, 0x30, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, - 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, - 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x29, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x27, 0x2e, 0x2e, 0x74, - 0x2e, 0x2e, 0x27, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, - 0x27, 0x2c, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, - 0x2c, 0x27, 0x2c, 0x27, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x27, 0x2c, 0x26, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x29, 0x27, - 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x20, - 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x61, 0x72, - 0x72, 0x61, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, - 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x22, 0x27, 0x2c, - 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x22, 0x2c, 0x27, 0x2c, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2c, 0x27, 0x2c, 0x27, 0x2c, 0x64, - 0x65, 0x66, 0x2c, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x65, 0x72, 0x72, 0x29, 0x29, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x20, 0x20, 0x20, 0x67, 0x6f, 0x74, 0x6f, 0x20, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3b, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, - 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, - 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, - 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7b, 0x27, 0x29, + 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x47, 0x65, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x67, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, 0x6e, 0x61, + 0x72, 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7b, + 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, + 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, + 0x65, 0x66, 0x3b, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x64, 0x65, 0x66, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x64, 0x65, 0x66, 0x3d, 0x31, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, + 0x64, 0x65, 0x66, 0x3d, 0x30, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x74, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x27, 0x2e, 0x2e, 0x74, 0x2e, + 0x2e, 0x27, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, + 0x2c, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2c, + 0x27, 0x2c, 0x27, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x27, 0x2c, 0x26, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x29, 0x27, 0x29, + 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, + 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, + 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x22, 0x27, 0x2c, 0x74, + 0x79, 0x70, 0x65, 0x2c, 0x27, 0x22, 0x2c, 0x27, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2c, 0x27, 0x2c, 0x27, 0x2c, 0x64, 0x65, + 0x66, 0x2c, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, + 0x72, 0x72, 0x29, 0x29, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, - 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x3b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x67, 0x6f, 0x74, 0x6f, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, - 0x20, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x3d, 0x30, 0x3b, 0x20, 0x69, - 0x3c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, - 0x2e, 0x2e, 0x27, 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, - 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, - 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x74, 0x72, - 0x20, 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x7e, 0x3d, 0x27, 0x27, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, - 0x2a, 0x27, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x5b, 0x69, - 0x5d, 0x20, 0x3d, 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x74, - 0x72, 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x2a, 0x27, 0x29, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x28, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x29, 0x20, - 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, - 0x65, 0x66, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x7e, 0x3d, 0x20, - 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x64, 0x65, 0x66, 0x20, - 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, - 0x67, 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x27, 0x2c, 0x64, 0x65, - 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, - 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, - 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, - 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x27, 0x2c, - 0x64, 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7d, 0x27, - 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x3a, 0x73, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, 0x6e, - 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, - 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, - 0x74, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, - 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, - 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, - 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x20, 0x7b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x69, - 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x3d, 0x30, - 0x3b, 0x20, 0x69, 0x3c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x64, 0x69, 0x6d, 0x2e, 0x2e, 0x27, 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x27, - 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, - 0x63, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, - 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, - 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, - 0x27, 0x29, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x2c, 0x27, 0x5b, 0x69, 0x5d, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, - 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, + 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, - 0x7b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, - 0x5f, 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, - 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, - 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, - 0x20, 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, - 0x77, 0x28, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, - 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, - 0x2c, 0x27, 0x5b, 0x69, 0x5d, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, - 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, - 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x6b, 0x65, - 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x28, 0x74, 0x6f, + 0x20, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x3d, 0x30, 0x3b, 0x20, 0x69, 0x3c, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x2e, + 0x2e, 0x27, 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, + 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x74, 0x72, 0x20, + 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x7e, 0x3d, 0x27, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x2a, + 0x27, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x5b, 0x69, 0x5d, + 0x20, 0x3d, 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x74, 0x72, + 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x2a, 0x27, 0x29, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x28, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x29, 0x20, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, + 0x66, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x7e, 0x3d, 0x20, 0x27, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x65, 0x66, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, - 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x74, 0x6f, 0x6c, 0x75, 0x61, - 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, - 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6c, - 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, - 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x63, 0x6f, 0x70, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, - 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, 0x27, 0x2c, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x5b, 0x69, - 0x5d, 0x2c, 0x73, 0x69, 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, - 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, - 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, - 0x79, 0x70, 0x65, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, - 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, - 0x2c, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, - 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, - 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, - 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, - 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, - 0x29, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, - 0x2c, 0x27, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x79, 0x70, - 0x65, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7d, 0x27, - 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20, 0x64, 0x79, 0x6e, 0x61, - 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x3a, 0x66, 0x72, 0x65, 0x65, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, - 0x28, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, 0x6e, 0x69, - 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, - 0x5f, 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, - 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x20, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x6d, 0x28, 0x27, 0x2c, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x29, - 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, - 0x66, 0x72, 0x65, 0x65, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, - 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, - 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x50, 0x61, 0x73, - 0x73, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x3a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x61, 0x72, 0x20, 0x28, 0x29, - 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, - 0x72, 0x3d, 0x3d, 0x27, 0x26, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, - 0x6f, 0x74, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x2a, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, 0x3d, 0x3d, 0x27, 0x2a, - 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x26, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, - 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x52, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x27, 0x2c, 0x64, 0x65, 0x66, + 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x74, 0x6f, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, + 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x27, 0x2c, 0x64, + 0x65, 0x66, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7d, 0x27, 0x29, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x47, 0x65, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, - 0x72, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x28, 0x29, 0x0a, - 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, - 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x63, 0x74, - 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, - 0x69, 0x66, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x7e, 0x3d, - 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x27, 0x2e, 0x2e, 0x74, - 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, - 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x27, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x29, - 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, - 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x75, 0x73, 0x68, - 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, - 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, - 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, - 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, - 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x27, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x2c, - 0x22, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, - 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x20, 0x30, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, - 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x0a, - 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, - 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x20, 0x74, - 0x3a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x28, - 0x29, 0x0a, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6e, 0x61, - 0x6d, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, - 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, - 0x20, 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x20, - 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x75, - 0x6d, 0x28, 0x66, 0x74, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, - 0x65, 0x64, 0x65, 0x66, 0x28, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, - 0x66, 0x74, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x69, - 0x66, 0x20, 0x74, 0x2e, 0x6b, 0x69, 0x6e, 0x64, 0x3d, 0x3d, 0x22, 0x76, - 0x61, 0x72, 0x22, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x2e, 0x6d, - 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x25, 0x73, 0x22, 0x29, 0x20, - 0x6f, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, - 0x6e, 0x64, 0x28, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, - 0x79, 0x24, 0x22, 0x29, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, - 0x09, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x6d, - 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x22, 0x2c, 0x20, 0x22, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, - 0x79, 0x5f, 0x5f, 0x22, 0x2e, 0x2e, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, - 0x29, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, - 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, - 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6b, 0x69, 0x6e, - 0x64, 0x20, 0x6f, 0x66, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, - 0x22, 0x76, 0x61, 0x72, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x66, 0x75, - 0x6e, 0x63, 0x22, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x28, 0x73, 0x2c, 0x6b, 0x69, 0x6e, 0x64, 0x2c, 0x69, 0x73, - 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x29, 0x0a, - 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, - 0x74, 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x20, 0x69, 0x66, - 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x64, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, - 0x28, 0x73, 0x2c, 0x22, 0x25, 0x73, 0x2a, 0x3d, 0x25, 0x73, 0x2a, 0x22, - 0x2c, 0x22, 0x3d, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, - 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x3c, - 0x22, 0x2c, 0x20, 0x22, 0x3c, 0x22, 0x29, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x66, 0x62, 0x2c, 0x74, 0x6d, 0x70, - 0x64, 0x65, 0x66, 0x0a, 0x20, 0x64, 0x65, 0x66, 0x62, 0x2c, 0x5f, 0x2c, - 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, - 0x22, 0x28, 0x3d, 0x2e, 0x2a, 0x29, 0x24, 0x22, 0x29, 0x0a, 0x20, 0x69, - 0x66, 0x20, 0x64, 0x65, 0x66, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x20, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x3d, 0x2e, - 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6c, - 0x73, 0x65, 0x0a, 0x20, 0x09, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x20, - 0x3d, 0x20, 0x27, 0x27, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, - 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x76, - 0x61, 0x72, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x2d, - 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x0a, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, - 0x6f, 0x72, 0x20, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, - 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x20, - 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x2c, 0x20, 0x6b, 0x69, - 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x2c, 0x20, 0x69, + 0x73, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, 0x6e, 0x61, + 0x72, 0x67, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x25, 0x73, 0x2b, 0x27, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x7b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x3b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x3d, 0x30, 0x3b, + 0x20, 0x69, 0x3c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x69, 0x6d, 0x2e, 0x2e, 0x27, 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x63, + 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, + 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, + 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, + 0x29, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x27, 0x5b, 0x69, 0x5d, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x5f, + 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, + 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, + 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, + 0x28, 0x28, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, 0x28, + 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x27, 0x5b, 0x69, 0x5d, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, + 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x6b, 0x65, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, + 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6c, 0x73, + 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, + 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x63, + 0x6f, 0x70, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, 0x27, 0x2c, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x5b, 0x69, 0x5d, + 0x2c, 0x73, 0x69, 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, 0x79, + 0x70, 0x65, 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, + 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x75, 0x73, 0x65, 0x72, 0x74, 0x79, + 0x70, 0x65, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, + 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, 0x2c, 0x69, 0x2b, 0x31, 0x2c, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, + 0x2c, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x75, + 0x73, 0x65, 0x72, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2c, 0x6e, 0x61, 0x72, 0x67, 0x2c, 0x27, + 0x2c, 0x69, 0x2b, 0x31, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, + 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x27, 0x5b, 0x69, 0x5d, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7d, 0x27, 0x29, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x46, 0x72, 0x65, 0x65, 0x20, 0x64, 0x79, 0x6e, 0x61, 0x6d, + 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x66, 0x72, 0x65, 0x65, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x28, + 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x64, + 0x69, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x64, 0x69, 0x6d, 0x29, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x5f, + 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x6d, 0x28, 0x27, 0x2c, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x66, + 0x72, 0x65, 0x65, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, + 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x50, 0x61, 0x73, 0x73, + 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x61, 0x72, 0x20, 0x28, 0x29, 0x0a, + 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, + 0x3d, 0x3d, 0x27, 0x26, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, + 0x74, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x2a, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, 0x3d, 0x3d, 0x27, 0x2a, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x26, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, + 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, + 0x65, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x28, 0x29, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x65, 0x74, 0x20, + 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x63, 0x74, 0x20, + 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x7e, 0x3d, 0x27, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x27, 0x2e, 0x2e, 0x74, 0x2e, + 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, + 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x27, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x75, 0x73, 0x68, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, + 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x27, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x2c, 0x22, + 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, + 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x30, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x0a, 0x20, + 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x20, 0x74, 0x3a, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x28, 0x29, + 0x0a, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6e, 0x61, 0x6d, + 0x65, 0x28, 0x29, 0x0a, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x74, + 0x79, 0x70, 0x65, 0x28, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, + 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x65, 0x6e, 0x75, 0x6d, + 0x28, 0x66, 0x74, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x74, + 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x74, 0x79, 0x70, 0x65, + 0x64, 0x65, 0x66, 0x28, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x66, + 0x74, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x74, 0x2e, 0x6b, 0x69, 0x6e, 0x64, 0x3d, 0x3d, 0x22, 0x76, 0x61, + 0x72, 0x22, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x2e, 0x6d, 0x6f, + 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x25, 0x73, 0x22, 0x29, 0x20, 0x6f, + 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x24, 0x22, 0x29, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, + 0x74, 0x2e, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x6d, 0x6f, + 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x22, 0x2c, 0x20, 0x22, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x5f, 0x5f, 0x22, 0x2e, 0x2e, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x29, + 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, + 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, + 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, + 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6b, 0x69, 0x6e, 0x64, + 0x20, 0x6f, 0x66, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x22, + 0x76, 0x61, 0x72, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x66, 0x75, 0x6e, + 0x63, 0x22, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x73, 0x2c, 0x6b, 0x69, 0x6e, 0x64, 0x2c, 0x69, 0x73, 0x5f, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x29, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x65, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x20, 0x69, 0x66, 0x20, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x64, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x22, 0x25, 0x73, 0x2a, 0x3d, 0x25, 0x73, 0x2a, 0x22, 0x2c, + 0x22, 0x3d, 0x22, 0x29, 0x0a, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x3c, 0x22, + 0x2c, 0x20, 0x22, 0x3c, 0x22, 0x29, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x64, 0x65, 0x66, 0x62, 0x2c, 0x74, 0x6d, 0x70, 0x64, + 0x65, 0x66, 0x0a, 0x20, 0x64, 0x65, 0x66, 0x62, 0x2c, 0x5f, 0x2c, 0x74, + 0x6d, 0x70, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x2c, 0x20, 0x22, + 0x28, 0x3d, 0x2e, 0x2a, 0x29, 0x24, 0x22, 0x29, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x64, 0x65, 0x66, 0x62, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x3d, 0x2e, 0x2a, + 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x20, 0x09, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x20, 0x3d, + 0x20, 0x27, 0x27, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x76, 0x61, + 0x72, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x0a, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x6f, + 0x72, 0x20, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x2c, 0x20, 0x6b, 0x69, 0x6e, + 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x2c, 0x20, 0x69, 0x73, + 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x3d, + 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x7d, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x6d, + 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x26, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x2a, 0x25, 0x73, + 0x2a, 0x26, 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, + 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, 0x69, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, + 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, + 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, + 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, + 0x64, 0x65, 0x66, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, + 0x3d, 0x20, 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x20, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, + 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, 0x74, 0x62, + 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x5b, 0x6d, 0x2e, + 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, + 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, 0x2c, + 0x6d, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x7d, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, - 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x26, 0x20, 0x6e, - 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, - 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x2a, 0x25, - 0x73, 0x2a, 0x26, 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, - 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, - 0x20, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x20, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, - 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x29, 0x0a, - 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, + 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, + 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, + 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x2a, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x28, 0x73, 0x2c, 0x27, 0x25, 0x2a, 0x25, 0x73, 0x2a, 0x25, 0x2a, 0x27, + 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x3d, + 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x66, 0x75, + 0x6e, 0x63, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, 0x69, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, + 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, + 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x2b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, + 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, + 0x20, 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, + 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x6d, + 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, + 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, + 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, + 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x69, + 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, + 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x6d, 0x6f, + 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x26, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x0a, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, + 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x27, + 0x26, 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x20, + 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, + 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, + 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, - 0x74, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, - 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, - 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, - 0x70, 0x64, 0x65, 0x66, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, - 0x20, 0x3d, 0x20, 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x72, - 0x65, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x2c, 0x0a, 0x20, 0x20, + 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x74, + 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x32, 0x5d, + 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, + 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, + 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, + 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, + 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, + 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, + 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x7d, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x6d, 0x3a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x2a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x73, 0x31, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x73, 0x2c, 0x22, 0x28, 0x25, 0x62, 0x5c, 0x5b, 0x5c, 0x5d, 0x29, 0x22, + 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6e, + 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x6e, 0x2c, 0x27, 0x25, 0x2a, 0x27, 0x2c, 0x27, 0x5c, 0x31, + 0x27, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x29, 0x0a, 0x20, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x73, 0x28, 0x73, 0x31, 0x2c, 0x27, 0x25, 0x2a, 0x27, 0x29, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x3d, 0x20, + 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x74, 0x5b, 0x32, + 0x5d, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x32, + 0x5d, 0x2c, 0x27, 0x5c, 0x31, 0x27, 0x2c, 0x27, 0x25, 0x2a, 0x27, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x20, + 0x2a, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, + 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, + 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x2b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, + 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x3d, 0x20, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x5b, 0x6d, - 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, - 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, - 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, - 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, - 0x3a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x2a, - 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, - 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x73, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x2a, 0x25, 0x73, 0x2a, 0x25, 0x2a, - 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x20, 0x3d, - 0x3d, 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x69, - 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x66, - 0x75, 0x6e, 0x63, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, - 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, 0x69, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x3a, 0x20, 0x22, 0x2e, 0x2e, 0x73, 0x29, 0x0a, 0x20, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, - 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, - 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, - 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, - 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, - 0x66, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, - 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x20, - 0x3d, 0x20, 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x2d, - 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, - 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, - 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, - 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, - 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, - 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x73, 0x5f, + 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, + 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, 0x31, + 0x29, 0x20, 0x20, 0x20, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x61, 0x72, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x6d, - 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x26, 0x20, 0x6e, 0x61, 0x6d, - 0x65, 0x0a, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, - 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, - 0x27, 0x26, 0x27, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, - 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, - 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, - 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, - 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, - 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, - 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, - 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, - 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x32, - 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, - 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, - 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, - 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, - 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, - 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, - 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, - 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, - 0x20, 0x7d, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, - 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, - 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x2a, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x73, 0x31, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, - 0x28, 0x73, 0x2c, 0x22, 0x28, 0x25, 0x62, 0x5c, 0x5b, 0x5c, 0x5d, 0x29, - 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, - 0x6e, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x73, - 0x75, 0x62, 0x28, 0x6e, 0x2c, 0x27, 0x25, 0x2a, 0x27, 0x2c, 0x27, 0x5c, - 0x31, 0x27, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x29, 0x0a, 0x20, 0x74, 0x20, - 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x31, 0x2c, 0x27, 0x25, 0x2a, 0x27, - 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x3d, - 0x20, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x74, 0x5b, - 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, - 0x32, 0x5d, 0x2c, 0x27, 0x5c, 0x31, 0x27, 0x2c, 0x27, 0x25, 0x2a, 0x27, - 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x20, 0x2a, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, - 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, 0x29, - 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, - 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x73, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x27, 0x25, 0x73, - 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, - 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, - 0x66, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, - 0x27, 0x2a, 0x27, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x3d, 0x20, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, + 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, + 0x69, 0x74, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, 0x2a, 0x27, + 0x29, 0x0a, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, + 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x76, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x66, + 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x5b, 0x74, 0x2e, + 0x6e, 0x5d, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x76, 0x20, 0x3d, + 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x28, 0x29, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x76, + 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x3b, 0x20, 0x74, + 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x2e, 0x6e, 0x2d, 0x31, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, + 0x76, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x74, 0x65, 0x28, 0x6d, 0x5b, 0x6d, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, + 0x61, 0x74, 0x65, 0x28, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, - 0x63, 0x61, 0x74, 0x28, 0x6d, 0x2c, 0x31, 0x2c, 0x6d, 0x2e, 0x6e, 0x2d, - 0x31, 0x29, 0x20, 0x20, 0x20, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x73, - 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x20, 0x3d, + 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x5b, + 0x74, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, 0x64, + 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, 0x2c, + 0x31, 0x2c, 0x74, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, - 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x69, 0x6e, 0x64, - 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x76, 0x61, 0x72, 0x27, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, + 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, + 0x0a, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x6b, + 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x66, 0x75, 0x6e, 0x63, + 0x22, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, @@ -1201,64 +1235,31 @@ static const unsigned char lua_declaration_lua[] = { 0x27, 0x29, 0x0a, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x66, 0x69, 0x6e, 0x64, 0x74, 0x79, 0x70, 0x65, 0x28, 0x74, 0x5b, 0x74, - 0x2e, 0x6e, 0x5d, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x76, 0x20, - 0x3d, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, - 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, - 0x76, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x3b, 0x20, - 0x74, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x2e, 0x6e, 0x2d, 0x31, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, - 0x20, 0x76, 0x2e, 0x2e, 0x74, 0x6d, 0x70, 0x64, 0x65, 0x66, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, - 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, - 0x6c, 0x61, 0x74, 0x65, 0x28, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x2c, - 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, 0x29, 0x2c, - 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, - 0x5b, 0x74, 0x2e, 0x6e, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x6f, - 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, - 0x2c, 0x31, 0x2c, 0x74, 0x2e, 0x6e, 0x2d, 0x31, 0x29, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, - 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, - 0x7d, 0x0a, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, - 0x6b, 0x69, 0x6e, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x66, 0x75, 0x6e, - 0x63, 0x22, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x3a, - 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6e, 0x61, - 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x74, 0x20, 0x3d, 0x20, 0x73, - 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, 0x2c, 0x27, 0x25, 0x73, 0x25, 0x73, - 0x2a, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, - 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, - 0x28, 0x73, 0x2c, 0x27, 0x25, 0x73, 0x2b, 0x27, 0x29, 0x0a, 0x20, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x20, 0x3d, 0x20, 0x74, 0x5b, - 0x74, 0x2e, 0x6e, 0x5d, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x6c, 0x61, 0x73, - 0x74, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, - 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x74, 0x70, 0x2c, 0x6d, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, - 0x2e, 0x6e, 0x3e, 0x31, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, - 0x20, 0x74, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x2d, - 0x31, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x64, 0x20, 0x3d, 0x20, 0x63, - 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, 0x2c, 0x31, 0x2c, 0x74, 0x2e, - 0x6e, 0x2d, 0x32, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, - 0x20, 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x74, 0x70, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x20, 0x74, 0x70, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, - 0x74, 0x70, 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, - 0x6c, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x3d, 0x20, 0x76, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x70, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x6d, 0x64, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, - 0x64, 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, - 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x74, + 0x2e, 0x6e, 0x5d, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x6c, 0x61, 0x73, 0x74, + 0x20, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x70, 0x2c, 0x6d, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, + 0x6e, 0x3e, 0x31, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x74, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x74, 0x2e, 0x6e, 0x2d, 0x31, + 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x6d, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x6f, + 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, 0x2c, 0x31, 0x2c, 0x74, 0x2e, 0x6e, + 0x2d, 0x32, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, + 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x74, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x74, 0x70, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, + 0x64, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x74, + 0x70, 0x2c, 0x20, 0x74, 0x62, 0x2c, 0x20, 0x74, 0x69, 0x6d, 0x70, 0x6c, + 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x5f, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x20, 0x76, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x74, 0x70, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6d, + 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x6d, 0x64, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x20, 0x3d, 0x20, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x6b, 0x69, 0x6e, 0x64, + 0x20, 0x3d, 0x20, 0x6b, 0x69, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x7d, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a }; -unsigned int lua_declaration_lua_len = 15132; +unsigned int lua_declaration_lua_len = 15143; diff --git a/lib/tolua++/src/bin/enumerate_lua.h b/lib/tolua++/src/bin/enumerate_lua.h index cd5bdda83..d23c9624a 100644 --- a/lib/tolua++/src/bin/enumerate_lua.h +++ b/lib/tolua++/src/bin/enumerate_lua.h @@ -112,186 +112,184 @@ static const unsigned char lua_enumerate_lua[] = { 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, 0x3a, 0x3a, 0x22, 0x2c, 0x22, 0x5f, 0x22, 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x4c, 0x2c, 0x20, 0x69, - 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x20, 0x74, 0x79, 0x70, 0x65, - 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x20, - 0x65, 0x72, 0x72, 0x29, 0x3b, 0x22, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x20, 0x3d, 0x20, - 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x63, 0x6f, 0x64, - 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x28, 0x29, - 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, - 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, - 0x20, 0x3d, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, 0x3d, - 0x20, 0x31, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x22, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, - 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, - 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x3a, 0x3a, 0x22, 0x2c, 0x22, 0x5f, 0x22, - 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, 0x28, 0x6c, 0x75, 0x61, 0x5f, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x4c, 0x2c, 0x20, 0x69, 0x6e, - 0x74, 0x20, 0x6c, 0x6f, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, - 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x20, 0x74, 0x79, 0x70, 0x65, 0x2c, - 0x20, 0x69, 0x6e, 0x74, 0x20, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x20, 0x65, - 0x72, 0x72, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x22, 0x7b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x28, 0x4c, 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x65, - 0x72, 0x72, 0x29, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x30, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x4e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x4c, - 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x29, 0x3b, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3e, 0x3d, 0x20, - 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x69, - 0x6e, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x2e, 0x30, 0x20, 0x26, 0x26, 0x20, - 0x76, 0x61, 0x6c, 0x20, 0x3c, 0x3d, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x2e, 0x2e, 0x20, 0x22, - 0x2e, 0x30, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x22, 0x7d, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, - 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x20, 0x28, 0x74, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x29, 0x0a, 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, - 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x29, 0x0a, 0x20, 0x61, - 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x61, 0x70, - 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x74, 0x29, 0x0a, - 0x09, 0x20, 0x69, 0x66, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, - 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x09, 0x09, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, - 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x22, 0x2e, 0x2e, - 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, - 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, 0x72, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x29, - 0x0a, 0x09, 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x28, - 0x22, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x22, 0x2e, - 0x2e, 0x6e, 0x73, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x2e, 0x2e, 0x22, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, - 0x3c, 0x61, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x65, - 0x6e, 0x75, 0x6d, 0x3e, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x63, 0x6c, - 0x61, 0x72, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, - 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x56, - 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x22, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x20, - 0x69, 0x6e, 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, - 0x75, 0x72, 0x72, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x74, - 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x0a, - 0x09, 0x09, 0x74, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x3a, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x28, 0x29, 0x0a, 0x09, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, - 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, - 0x78, 0x70, 0x65, 0x63, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, - 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x75, - 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x75, - 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x28, 0x6e, 0x2c, 0x62, 0x2c, - 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x62, 0x20, - 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, - 0x62, 0x28, 0x62, 0x2c, 0x20, 0x22, 0x2c, 0x5b, 0x25, 0x73, 0x5c, 0x6e, - 0x5d, 0x2a, 0x7d, 0x22, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x7d, 0x22, 0x29, - 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, - 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x0a, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, - 0x6c, 0x69, 0x74, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x62, - 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, 0x29, 0x20, - 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, - 0x20, 0x62, 0x72, 0x61, 0x63, 0x65, 0x73, 0x0a, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, - 0x7d, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x30, - 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, 0x69, 0x5d, - 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x74, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, - 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x20, 0x2d, 0x2d, - 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x20, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, - 0x09, 0x65, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x6e, 0x20, 0x2b, - 0x20, 0x31, 0x0a, 0x09, 0x09, 0x65, 0x5b, 0x65, 0x2e, 0x6e, 0x5d, 0x20, - 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x74, 0x74, - 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x28, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x29, 0x0a, 0x09, 0x09, - 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x3d, 0x20, - 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, - 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x20, 0x0a, 0x20, 0x20, 0x09, - 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, - 0x32, 0x5d, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x64, - 0x76, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, - 0x3e, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x09, 0x09, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, - 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, - 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3c, 0x20, 0x6d, 0x69, 0x6e, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, - 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x0a, 0x09, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, - 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x73, 0x65, - 0x74, 0x20, 0x6c, 0x75, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x0a, - 0x09, 0x69, 0x20, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x65, 0x2e, 0x6c, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, - 0x65, 0x74, 0x63, 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, - 0x20, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, - 0x69, 0x74, 0x28, 0x65, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x40, 0x27, 0x29, - 0x0a, 0x09, 0x09, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x5b, - 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, - 0x09, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, - 0x79, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x5b, - 0x31, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, - 0x65, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20, - 0x3d, 0x20, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x5b, - 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x20, 0x6e, 0x73, 0x2e, 0x2e, - 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x6e, 0x73, - 0x2e, 0x2e, 0x65, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x20, - 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, - 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x0a, 0x09, - 0x65, 0x2e, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x0a, - 0x09, 0x65, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, - 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x5f, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x5b, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x09, - 0x54, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x22, 0x69, 0x6e, 0x74, - 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x45, 0x6e, 0x75, - 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x65, 0x2c, 0x20, 0x76, 0x61, - 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a + 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x64, + 0x65, 0x66, 0x2c, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x2a, 0x20, 0x65, 0x72, 0x72, 0x29, 0x3b, 0x22, 0x29, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, + 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, + 0x64, 0x65, 0x20, 0x28, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x5f, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x20, 0x3d, 0x3d, 0x20, 0x6e, 0x69, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x3a, 0x3a, + 0x22, 0x2c, 0x22, 0x5f, 0x22, 0x29, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x20, + 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, + 0x4c, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6c, 0x6f, 0x2c, 0x20, 0x69, + 0x6e, 0x74, 0x20, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2a, 0x20, 0x65, 0x72, 0x72, + 0x29, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x22, 0x7b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x22, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x69, 0x73, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, + 0x4c, 0x2c, 0x6c, 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x2c, 0x65, 0x72, 0x72, + 0x29, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3b, + 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x22, 0x6c, 0x75, 0x61, 0x5f, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, + 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x28, 0x4c, 0x2c, 0x6c, + 0x6f, 0x2c, 0x64, 0x65, 0x66, 0x29, 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3e, 0x3d, 0x20, 0x22, 0x20, + 0x2e, 0x2e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x69, 0x6e, 0x20, + 0x2e, 0x2e, 0x20, 0x22, 0x2e, 0x30, 0x20, 0x26, 0x26, 0x20, 0x76, 0x61, + 0x6c, 0x20, 0x3c, 0x3d, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x2e, 0x30, + 0x3b, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x22, 0x7d, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x5f, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, + 0x28, 0x74, 0x2c, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x45, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x29, 0x0a, 0x20, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x6d, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x20, + 0x69, 0x66, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, + 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x69, 0x66, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, + 0x20, 0x22, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x74, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, + 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x63, 0x75, 0x72, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x28, 0x29, 0x0a, 0x09, + 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x28, 0x22, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x22, 0x2e, 0x2e, 0x6e, + 0x73, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, + 0x22, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3c, 0x61, + 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x20, 0x65, 0x6e, 0x75, + 0x6d, 0x3e, 0x20, 0x69, 0x73, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, + 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, 0x61, 0x64, 0x2d, 0x6f, + 0x6e, 0x6c, 0x79, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x72, 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x6e, + 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x76, 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x63, 0x75, 0x72, + 0x72, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x74, 0x2e, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x5f, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x0a, 0x09, 0x09, + 0x74, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x3a, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x28, 0x29, 0x0a, 0x09, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, + 0x65, 0x63, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x75, 0x6d, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x20, 0x28, 0x6e, 0x2c, 0x62, 0x2c, 0x76, 0x61, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x62, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, + 0x62, 0x2c, 0x20, 0x22, 0x2c, 0x5b, 0x25, 0x73, 0x5c, 0x6e, 0x5d, 0x2a, + 0x7d, 0x22, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x7d, 0x22, 0x29, 0x20, 0x2d, + 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, + 0x6c, 0x61, 0x73, 0x74, 0x20, 0x27, 0x2c, 0x27, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x62, 0x2c, 0x32, + 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, 0x29, 0x20, 0x2d, 0x2d, + 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x62, + 0x72, 0x61, 0x63, 0x65, 0x73, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, + 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x64, + 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x74, 0x5b, 0x69, + 0x5d, 0x2c, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x64, + 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x65, + 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x6e, 0x20, 0x2b, 0x20, 0x31, + 0x0a, 0x09, 0x09, 0x65, 0x5b, 0x65, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, + 0x74, 0x74, 0x5b, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x74, 0x74, 0x5b, 0x32, + 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x28, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, + 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x3d, 0x20, 0x6e, 0x69, + 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x74, + 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x20, 0x0a, 0x20, 0x20, 0x09, 0x09, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, + 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x64, 0x76, 0x61, + 0x6e, 0x63, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x09, + 0x09, 0x69, 0x66, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3e, 0x20, + 0x6d, 0x61, 0x78, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x74, + 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x3c, 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x20, 0x3d, + 0x20, 0x74, 0x74, 0x5b, 0x32, 0x5d, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x74, 0x20, + 0x6c, 0x75, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x0a, 0x09, 0x69, + 0x20, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x65, 0x2e, 0x6c, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, + 0x63, 0x75, 0x72, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x28, 0x29, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x65, + 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, + 0x28, 0x65, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x40, 0x27, 0x29, 0x0a, 0x09, + 0x09, 0x65, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x5b, 0x31, 0x5d, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x74, 0x5b, + 0x32, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, + 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x72, + 0x65, 0x6e, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x5b, 0x31, 0x5d, + 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x2e, + 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, + 0x74, 0x5b, 0x32, 0x5d, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x5b, 0x31, 0x5d, + 0x0a, 0x09, 0x09, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x5b, 0x20, 0x6e, 0x73, 0x2e, 0x2e, 0x65, 0x5b, + 0x69, 0x5d, 0x20, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x6e, 0x73, 0x2e, 0x2e, + 0x65, 0x5b, 0x69, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, + 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x0a, 0x09, 0x65, 0x2e, + 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x0a, 0x09, 0x65, + 0x2e, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x6e, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x73, + 0x5b, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, + 0x09, 0x54, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x28, 0x22, 0x69, 0x6e, + 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x6e, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x45, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x65, 0x2c, 0x20, 0x76, + 0x61, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a }; -unsigned int lua_enumerate_lua_len = 3528; +unsigned int lua_enumerate_lua_len = 3493; diff --git a/lib/tolua++/src/bin/function_lua.h b/lib/tolua++/src/bin/function_lua.h index 544a6f8a8..bcb0bfca2 100644 --- a/lib/tolua++/src/bin/function_lua.h +++ b/lib/tolua++/src/bin/function_lua.h @@ -130,1081 +130,1081 @@ static const unsigned char lua_function_lua[] = { 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x73, 0x65, 0x6e, - 0x75, 0x6d, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, - 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6d, 0x69, 0x74, - 0x65, 0x6e, 0x75, 0x6d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, - 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, - 0x69, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, - 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, - 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x66, 0x6c, - 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x69, 0x72, - 0x74, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, - 0x09, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, - 0x70, 0x75, 0x72, 0x65, 0x20, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, - 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x0a, 0x20, 0x09, 0x09, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, 0x09, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x22, 0x2c, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, 0x29, - 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x6d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x2c, 0x22, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x75, 0x6d, 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6d, 0x69, 0x74, 0x65, 0x6e, 0x75, 0x6d, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x74, 0x79, 0x70, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, + 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x20, 0x09, + 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, 0x65, + 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x70, 0x75, 0x72, 0x65, 0x20, 0x76, 0x69, 0x72, + 0x74, 0x75, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, + 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x6d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3a, 0x20, 0x6e, 0x65, 0x77, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x22, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2c, 0x22, 0x20, - 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, - 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, - 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, - 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, - 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x22, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x69, 0x6e, - 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, - 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x2c, - 0x22, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, - 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x22, 0x29, 0x0a, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, - 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, - 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, - 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, - 0x69, 0x6e, 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, - 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, + 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x20, 0x6f, 0x66, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x22, 0x2c, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x2f, 0x2a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x20, 0x2a, 0x2f, 0x22, 0x29, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, + 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, + 0x53, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x20, 0x69, 0x6e, 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x22, 0x2c, 0x22, 0x28, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, - 0x29, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7b, 0x22, 0x29, 0x0a, 0x0a, 0x20, - 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, - 0x6f, 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, - 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, - 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, 0x27, 0x29, - 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, - 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x20, 0x69, 0x66, 0x20, 0x28, 0x5c, 0x6e, 0x27, 0x29, 0x0a, - 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, - 0x72, 0x67, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, - 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, - 0x77, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x7e, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x27, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, 0x73, 0x65, 0x72, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x27, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x3d, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x22, 0x2e, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x21, 0x27, 0x2e, 0x2e, 0x66, 0x75, 0x6e, 0x63, 0x2e, - 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x31, - 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, - 0x22, 0x2c, 0x30, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, - 0x72, 0x72, 0x29, 0x20, 0x7c, 0x7c, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x20, 0x61, 0x72, 0x67, 0x73, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, - 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, - 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, - 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, - 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x74, - 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, 0x74, 0x79, 0x70, 0x65, - 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, 0x2e, - 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, - 0x5d, 0x3a, 0x6f, 0x75, 0x74, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x74, 0x79, - 0x70, 0x65, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x2e, 0x2e, 0x27, 0x20, - 0x7c, 0x7c, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x62, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x65, 0x27, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x6e, 0x61, - 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, - 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, - 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x6c, 0x69, - 0x73, 0x74, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x69, 0x73, 0x6e, 0x6f, 0x6f, 0x62, 0x6a, 0x28, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, 0x61, 0x72, 0x67, 0x2e, - 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, - 0x72, 0x29, 0x5c, 0x6e, 0x20, 0x29, 0x27, 0x29, 0x0a, 0x09, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x67, 0x6f, 0x74, 0x6f, - 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x27, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, - 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, - 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, - 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, - 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x7b, - 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, 0x6c, - 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x69, 0x66, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 0x0a, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x0a, 0x20, 0x69, - 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, 0x65, - 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x7e, - 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, - 0x6e, 0x73, 0x74, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x2a, 0x27, - 0x2c, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x3d, 0x20, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x28, 0x27, - 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x2a, 0x29, 0x20, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6f, 0x5f, 0x66, - 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x6f, - 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x31, 0x2c, 0x30, 0x29, 0x3b, - 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, - 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, - 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, 0x69, 0x6e, 0x64, 0x28, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x27, 0x5e, 0x25, - 0x73, 0x2a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x25, 0x73, 0x25, 0x73, - 0x2a, 0x28, 0x2e, 0x2a, 0x29, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, - 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, - 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, - 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, - 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, - 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, - 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, - 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, - 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, - 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x29, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x20, - 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, - 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, - 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, - 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x20, - 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x7e, 0x3d, - 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, - 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, - 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, - 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x73, 0x65, 0x6c, 0x66, - 0x29, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, - 0x2e, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x22, 0x69, 0x6e, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x20, 0x5c, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x5c, - 0x27, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, 0x5c, 0x27, 0x22, 0x2c, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x2e, 0x2e, 0x27, - 0x22, 0x2c, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x29, 0x3b, 0x27, 0x29, 0x3b, - 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, - 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x20, - 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, 0x69, 0x66, - 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, - 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, - 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x29, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x23, 0x69, 0x66, 0x6e, + 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, + 0x53, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x5c, 0x6e, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x20, 0x69, 0x6e, 0x74, 0x22, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x22, 0x28, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x20, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x29, 0x22, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x22, 0x7b, 0x22, + 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, + 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, + 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, + 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x65, 0x72, 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x69, 0x66, 0x20, 0x28, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, + 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, + 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x69, 0x73, 0x5f, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x7e, 0x3d, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, + 0x20, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x75, 0x73, + 0x65, 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x27, 0x0a, 0x09, 0x09, 0x09, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x20, 0x22, 0x2e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x09, + 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x27, 0x2e, 0x2e, 0x66, + 0x75, 0x6e, 0x63, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x2c, 0x31, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x30, 0x2c, 0x26, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x20, 0x7c, 0x7c, 0x5c, 0x6e, + 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x61, 0x72, 0x67, 0x73, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, - 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, - 0x5b, 0x69, 0x5d, 0x3a, 0x67, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, - 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x61, - 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, - 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, - 0x70, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, - 0x6b, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x6f, 0x75, 0x74, 0x73, 0x69, 0x64, 0x65, 0x22, 0x29, - 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x64, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x4d, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x28, - 0x73, 0x65, 0x6c, 0x66, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6c, - 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, - 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, - 0x72, 0x26, 0x5b, 0x5d, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, 0x31, - 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x35, 0x20, 0x3f, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x28, 0x27, - 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, - 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x2d, 0x31, 0x29, 0x20, - 0x3d, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, - 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x3b, - 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x5b, 0x5d, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, - 0x2c, 0x27, 0x29, 0x20, 0x3d, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x62, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x62, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x6f, 0x75, 0x74, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x74, 0x79, 0x70, 0x65, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, + 0x2e, 0x2e, 0x27, 0x20, 0x7c, 0x7c, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x62, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, + 0x20, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, + 0x67, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, + 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x6f, + 0x66, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x69, 0x73, 0x6e, 0x6f, 0x6f, 0x62, 0x6a, 0x28, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x6e, + 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x27, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x5c, 0x6e, 0x20, 0x29, 0x27, 0x29, + 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x67, 0x6f, 0x74, 0x6f, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3b, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, + 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x7b, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, + 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2c, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x61, 0x73, + 0x65, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x72, + 0x67, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x7e, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, + 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x27, 0x2a, 0x27, 0x2c, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x20, 0x3d, + 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x2a, 0x29, + 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, + 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x74, 0x6f, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x31, + 0x2c, 0x30, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x69, 0x66, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x66, + 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, + 0x2c, 0x27, 0x5e, 0x25, 0x73, 0x2a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, + 0x25, 0x73, 0x25, 0x73, 0x2a, 0x28, 0x2e, 0x2a, 0x29, 0x27, 0x29, 0x0a, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x65, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x7e, 0x3d, 0x20, 0x22, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, + 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x7e, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x3d, 0x3d, 0x6e, 0x69, + 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, + 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, + 0x53, 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, + 0x73, 0x65, 0x6c, 0x66, 0x29, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, + 0x22, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x5c, 0x27, 0x73, + 0x65, 0x6c, 0x66, 0x5c, 0x27, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, 0x5c, 0x27, + 0x22, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x29, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x20, 0x4e, 0x55, 0x4c, 0x4c, 0x29, + 0x3b, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, + 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, + 0x67, 0x65, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x0a, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x67, 0x65, 0x74, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, + 0x20, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, + 0x67, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, + 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x20, 0x70, 0x72, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x0a, + 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, + 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x75, 0x74, 0x73, 0x69, + 0x64, 0x65, 0x22, 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, + 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, + 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, + 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x20, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x26, 0x5b, 0x5d, 0x27, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, + 0x73, 0x5b, 0x27, 0x31, 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, + 0x2d, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x74, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x20, 0x77, 0x69, 0x74, + 0x68, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x35, 0x20, 0x3f, 0x0a, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x5b, 0x5d, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, + 0x2d, 0x31, 0x29, 0x20, 0x3d, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x32, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x2c, 0x27, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7b, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, - 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, - 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x28, - 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x29, 0x20, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x6e, 0x65, 0x77, 0x28, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, 0x28, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x75, - 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, - 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x2e, 0x2e, 0x27, 0x3a, 0x3a, 0x27, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, - 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, - 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, - 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x61, 0x73, - 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x09, 0x2d, 0x2d, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x5f, 0x63, 0x61, 0x73, 0x74, 0x3c, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, + 0x65, 0x2c, 0x27, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x28, 0x27, 0x2c, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x29, 0x20, 0x3d, 0x20, 0x27, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x32, 0x5d, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x3b, 0x27, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, - 0x27, 0x20, 0x3e, 0x28, 0x2a, 0x73, 0x65, 0x6c, 0x66, 0x27, 0x29, 0x0a, - 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, - 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x28, - 0x27, 0x29, 0x0a, 0x09, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, - 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, 0x6c, - 0x66, 0x2d, 0x3e, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, - 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, - 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, - 0x27, 0x28, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x27, 0x29, 0x0a, 0x09, - 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, - 0x5b, 0x31, 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x2c, - 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x0a, - 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, - 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, - 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, - 0x5b, 0x69, 0x5d, 0x3a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x61, 0x72, 0x28, - 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, - 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x5b, 0x5d, 0x27, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, 0x31, - 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x2d, 0x31, 0x29, 0x3b, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, 0x77, - 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x20, 0x2d, - 0x2d, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, 0x28, 0x0a, 0x09, 0x65, 0x6c, 0x73, - 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, - 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, - 0x6e, 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x20, 0x20, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x63, 0x74, 0x20, 0x3d, - 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, - 0x66, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x6e, 0x65, - 0x77, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x09, - 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x61, 0x73, 0x74, - 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x72, 0x61, 0x77, - 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5b, 0x74, 0x5d, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x20, 0x20, 0x27, 0x2c, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, - 0x72, 0x61, 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5b, 0x74, 0x5d, 0x2c, - 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x27, - 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x09, - 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x27, 0x2e, 0x2e, 0x74, 0x2e, - 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, - 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, - 0x5f, 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x74, - 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2c, - 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, 0x2c, - 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, - 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, - 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, - 0x77, 0x6e, 0x65, 0x64, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x09, 0x09, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, - 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, - 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x75, - 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, - 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7b, 0x27, - 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x5f, 0x5f, - 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, 0x73, 0x5c, 0x6e, 0x27, + 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x20, 0x3d, + 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x28, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, + 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2c, 0x27, 0x29, + 0x20, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, + 0x6e, 0x65, 0x77, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x4d, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, 0x28, 0x28, 0x27, 0x2c, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x27, 0x29, 0x28, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, + 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2e, 0x2e, 0x27, 0x3a, 0x3a, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, + 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x09, + 0x2d, 0x2d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x5f, 0x63, 0x61, 0x73, 0x74, 0x3c, 0x27, 0x2c, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x70, 0x74, 0x72, 0x2c, 0x27, 0x20, 0x3e, 0x28, 0x2a, 0x73, 0x65, 0x6c, + 0x66, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x28, 0x27, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x20, 0x27, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6d, 0x6f, 0x64, 0x2c, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x73, 0x65, 0x6c, 0x66, 0x2d, 0x3e, 0x27, 0x2e, 0x2e, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, + 0x0a, 0x09, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x28, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x75, 0x74, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x73, 0x65, 0x6c, 0x66, + 0x27, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x77, + 0x72, 0x69, 0x74, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x70, 0x61, 0x73, 0x73, + 0x70, 0x61, 0x72, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, + 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x5b, 0x5d, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x6c, 0x61, 0x67, + 0x73, 0x5b, 0x27, 0x31, 0x27, 0x5d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x2d, 0x31, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, + 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x29, 0x29, 0x3b, + 0x27, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x20, + 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, 0x28, 0x0a, + 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x2d, + 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, + 0x74, 0x20, 0x3d, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x31, + 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, + 0x63, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7e, 0x3d, + 0x20, 0x22, 0x6e, 0x65, 0x77, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x63, 0x61, 0x73, 0x74, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, + 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5b, 0x74, 0x5d, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x5f, 0x62, 0x61, + 0x73, 0x69, 0x63, 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x70, 0x75, 0x73, 0x68, + 0x5b, 0x74, 0x5d, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x2c, 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x27, + 0x2e, 0x2e, 0x74, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x2c, 0x28, 0x27, 0x2c, 0x63, 0x74, 0x2c, 0x27, 0x29, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x0a, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, + 0x62, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, + 0x73, 0x2b, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, 0x3d, 0x20, + 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x2c, 0x20, 0x22, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x22, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, + 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x75, + 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x67, 0x65, + 0x74, 0x5f, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x7b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x64, 0x65, + 0x66, 0x20, 0x5f, 0x5f, 0x63, 0x70, 0x6c, 0x75, 0x73, 0x70, 0x6c, 0x75, + 0x73, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, + 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x6e, 0x65, 0x77, 0x28, 0x28, 0x27, 0x2c, 0x6e, 0x65, 0x77, 0x5f, 0x74, + 0x2c, 0x27, 0x29, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, + 0x74, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, + 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, + 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x74, 0x6f, + 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, + 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x5f, 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x2c, 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, + 0x70, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, 0x3d, - 0x20, 0x4d, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6e, 0x65, 0x77, 0x28, - 0x28, 0x27, 0x2c, 0x6e, 0x65, 0x77, 0x5f, 0x74, 0x2c, 0x27, 0x29, 0x28, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x29, 0x29, 0x3b, - 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, - 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, - 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, - 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, - 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x6c, - 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x23, 0x65, 0x6c, 0x73, 0x65, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, - 0x20, 0x20, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x20, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x2c, 0x73, 0x69, - 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x29, 0x29, - 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, - 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x74, 0x6f, 0x6c, 0x75, 0x61, - 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, - 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, - 0x5f, 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, - 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x26, 0x27, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, - 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, 0x74, 0x6f, - 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, - 0x29, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, 0x2c, - 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x20, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x27, 0x2c, - 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x27, 0x28, + 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, 0x6f, 0x69, - 0x64, 0x2a, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x74, - 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, - 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x20, - 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, - 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x67, - 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x6c, 0x75, - 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, 0x28, 0x74, 0x6f, 0x6c, - 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, - 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, - 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, - 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x6e, - 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, - 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x74, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, - 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, - 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x7d, - 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x65, 0x74, - 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x0a, 0x20, 0x20, - 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, 0x20, 0x65, 0x6c, 0x73, - 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, 0x20, 0x65, 0x6e, 0x64, - 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, - 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, - 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, + 0x64, 0x2a, 0x29, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, + 0x74, 0x2c, 0x73, 0x69, 0x7a, 0x65, 0x6f, 0x66, 0x28, 0x27, 0x2c, 0x74, + 0x2c, 0x27, 0x29, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x20, 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, + 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6f, 0x62, 0x6a, 0x2c, 0x22, 0x27, 0x2c, + 0x74, 0x2c, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x5f, 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, + 0x61, 0x5f, 0x53, 0x2c, 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, + 0x6f, 0x70, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x5c, + 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x3d, 0x20, 0x27, + 0x26, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, + 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x2c, + 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x28, 0x76, + 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x72, 0x65, 0x74, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x0a, 0x09, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x20, 0x20, 0x27, 0x2c, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x66, 0x75, 0x6e, + 0x63, 0x2c, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, + 0x28, 0x76, 0x6f, 0x69, 0x64, 0x2a, 0x29, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x72, 0x65, 0x74, 0x2c, 0x22, 0x27, 0x2c, 0x74, 0x2c, 0x27, 0x22, + 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x69, 0x66, 0x20, 0x6f, 0x77, + 0x6e, 0x65, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x20, 0x20, 0x20, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x5f, 0x67, 0x63, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x53, 0x2c, 0x6c, 0x75, 0x61, 0x5f, 0x67, 0x65, 0x74, 0x74, 0x6f, 0x70, + 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x29, 0x3b, 0x27, + 0x29, 0x0a, 0x09, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, - 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x73, 0x65, - 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6e, 0x61, 0x72, 0x67, 0x29, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, - 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, - 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x20, 0x2d, - 0x2d, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x64, 0x79, 0x6e, 0x61, 0x6d, - 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x0a, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, - 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, - 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, - 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, - 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x66, 0x72, 0x65, 0x65, - 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x20, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x6c, - 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x29, - 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, - 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x2e, 0x2e, - 0x6e, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x27, 0x3b, 0x27, 0x29, 0x0a, 0x0a, - 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x76, 0x65, - 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, 0x67, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0a, 0x09, - 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, - 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x69, 0x66, 0x6e, - 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x52, 0x45, - 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x5c, 0x6e, 0x27, + 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x6e, 0x72, 0x65, 0x74, + 0x20, 0x3d, 0x20, 0x6e, 0x72, 0x65, 0x74, 0x20, 0x2b, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x72, + 0x65, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x65, + 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x27, 0x20, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x20, 0x2d, 0x2d, + 0x20, 0x73, 0x65, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x65, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x32, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x3d, 0x31, + 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, + 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, + 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, + 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, + 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, + 0x5d, 0x3a, 0x73, 0x65, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6e, + 0x61, 0x72, 0x67, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x61, 0x72, + 0x67, 0x20, 0x3d, 0x20, 0x6e, 0x61, 0x72, 0x67, 0x2b, 0x31, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, + 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x64, + 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x61, + 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x31, 0x5d, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x76, 0x6f, 0x69, 0x64, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, + 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, + 0x66, 0x72, 0x65, 0x65, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, + 0x20, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, + 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x70, 0x6f, 0x73, 0x74, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x29, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x28, 0x27, 0x20, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x27, 0x2e, 0x2e, 0x6e, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x27, 0x3b, + 0x27, 0x29, 0x0a, 0x0a, 0x20, 0x2d, 0x2d, 0x20, 0x63, 0x61, 0x6c, 0x6c, + 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, + 0x6f, 0x61, 0x64, 0x20, 0x3c, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, + 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, + 0x41, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, - 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, 0x2e, - 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x22, 0x23, 0x66, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, 0x5c, 0x27, 0x2e, 0x22, - 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, - 0x29, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x26, 0x74, 0x6f, 0x6c, 0x75, 0x61, - 0x5f, 0x65, 0x72, 0x72, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x30, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, - 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x09, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x09, 0x09, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x22, - 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x0a, 0x09, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x31, 0x2c, 0x2d, - 0x33, 0x29, 0x2e, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x22, - 0x25, 0x30, 0x32, 0x64, 0x22, 0x2c, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, - 0x61, 0x64, 0x29, 0x2e, 0x2e, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, - 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x29, 0x3b, - 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x28, 0x27, 0x7d, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, - 0x20, 0x2f, 0x2f, 0x23, 0x69, 0x66, 0x6e, 0x64, 0x65, 0x66, 0x20, 0x54, - 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, - 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x20, - 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x63, 0x61, - 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, 0x6c, - 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, 0x6e, 0x65, 0x77, 0x27, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, - 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x73, - 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x75, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x28, - 0x31, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x28, 0x70, 0x72, 0x65, - 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, - 0x65, 0x6c, 0x66, 0x3a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x28, - 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x09, - 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, - 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x70, 0x75, 0x72, 0x65, - 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x6e, 0x6f, 0x20, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x77, - 0x69, 0x74, 0x68, 0x20, 0x70, 0x75, 0x72, 0x65, 0x20, 0x76, 0x69, 0x72, - 0x74, 0x75, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, - 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x20, - 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, - 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, - 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, - 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x6e, 0x65, 0x77, 0x5f, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x5f, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, - 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, - 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, - 0x2c, 0x22, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x22, 0x2c, 0x27, 0x2e, 0x2e, - 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, - 0x27, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x27, 0x29, 0x0a, - 0x09, 0x20, 0x20, 0x2d, 0x2d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, - 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x73, 0x65, 0x74, 0x5f, - 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x28, 0x74, - 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x5f, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2c, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x29, 0x3b, 0x27, 0x29, 0x0a, - 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, - 0x2d, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x2c, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x20, 0x70, - 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, - 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x22, 0x29, - 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6d, 0x6f, 0x64, 0x20, 0x20, 0x3d, 0x20, - 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6d, 0x6f, 0x64, + 0x75, 0x74, 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, + 0x2c, 0x22, 0x27, 0x2e, 0x2e, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x68, 0x6f, 0x6f, 0x6b, 0x28, 0x22, + 0x23, 0x66, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5c, 0x27, 0x25, 0x73, + 0x5c, 0x27, 0x2e, 0x22, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, + 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x26, 0x74, + 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x65, 0x72, 0x72, 0x29, 0x3b, 0x27, 0x29, + 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3b, 0x27, 0x29, 0x0a, + 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, + 0x6e, 0x64, 0x69, 0x66, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6c, + 0x73, 0x65, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, + 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x3d, 0x20, 0x22, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x28, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x6c, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x09, 0x09, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x73, 0x75, + 0x62, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, + 0x2c, 0x31, 0x2c, 0x2d, 0x33, 0x29, 0x2e, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x28, 0x22, 0x25, 0x30, 0x32, 0x64, 0x22, 0x2c, 0x6f, 0x76, + 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x29, 0x2e, 0x2e, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x2e, 0x2e, 0x27, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, + 0x5f, 0x53, 0x29, 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x7d, 0x27, 0x29, + 0x0a, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x23, 0x65, + 0x6e, 0x64, 0x69, 0x66, 0x20, 0x2f, 0x2f, 0x23, 0x69, 0x66, 0x6e, 0x64, + 0x65, 0x66, 0x20, 0x54, 0x4f, 0x4c, 0x55, 0x41, 0x5f, 0x44, 0x49, 0x53, + 0x41, 0x42, 0x4c, 0x45, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x20, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x28, 0x27, 0x5c, 0x6e, 0x27, 0x29, 0x0a, 0x0a, + 0x09, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, + 0x65, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x6f, 0x20, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x3d, 0x27, + 0x6e, 0x65, 0x77, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x73, 0x75, 0x70, 0x63, + 0x6f, 0x64, 0x65, 0x28, 0x31, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x20, + 0x28, 0x70, 0x72, 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x3a, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x20, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, + 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, + 0x70, 0x75, 0x72, 0x65, 0x5f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x09, 0x09, 0x2d, 0x2d, 0x20, + 0x6e, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x65, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x70, 0x75, 0x72, 0x65, + 0x20, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x20, 0x6d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x73, 0x0a, 0x20, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x0a, 0x20, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, + 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x29, 0x3b, + 0x27, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x6e, 0x65, + 0x77, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, + 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, + 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x2c, 0x27, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, + 0x2e, 0x2e, 0x27, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x27, + 0x29, 0x0a, 0x09, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, + 0x70, 0x72, 0x65, 0x2e, 0x2e, 0x27, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x6f, 0x6c, + 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x22, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x22, + 0x2c, 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, + 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x09, 0x20, 0x20, 0x2d, 0x2d, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x28, 0x27, 0x20, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x73, 0x65, 0x74, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x28, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x53, 0x2c, 0x27, + 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, + 0x2e, 0x2e, 0x27, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2c, 0x20, 0x22, + 0x27, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x27, 0x22, 0x29, + 0x3b, 0x27, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2c, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x7b, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6d, 0x6f, 0x64, + 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x6d, 0x6f, 0x64, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x2e, 0x2e, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, + 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x2e, 0x22, 0x27, - 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x70, 0x74, 0x72, 0x20, - 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x70, 0x74, 0x72, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, + 0x70, 0x74, 0x72, 0x20, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x2e, 0x2e, 0x22, 0x27, 0x2c, + 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, - 0x2e, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, - 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, + 0x2e, 0x22, 0x20, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, + 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, + 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, + 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, + 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, - 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6c, + 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, - 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, + 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, - 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x63, 0x6f, 0x6e, - 0x73, 0x74, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2e, 0x2e, 0x22, 0x27, 0x2c, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6c, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, + 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, - 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x63, 0x6e, 0x61, 0x6d, 0x65, - 0x20, 0x3d, 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, - 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, - 0x20, 0x27, 0x22, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, - 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x22, 0x27, 0x2c, 0x22, 0x29, 0x0a, 0x20, - 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, - 0x2e, 0x22, 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x22, - 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, - 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, + 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, + 0x3d, 0x20, 0x7b, 0x22, 0x29, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, + 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, + 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x20, 0x22, + 0x2c, 0x22, 0x2c, 0x22, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, + 0x20, 0x7d, 0x22, 0x29, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x7d, 0x22, 0x2e, 0x2e, + 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x2d, 0x2d, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, + 0x69, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, + 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x62, 0x79, 0x20, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x74, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x20, + 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, + 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x69, 0x73, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x74, 0x72, 0x3d, 0x3d, 0x27, 0x27, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, + 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, + 0x25, 0x73, 0x2a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, + 0x2c, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x20, 0x74, 0x5b, 0x74, 0x79, 0x70, + 0x65, 0x5d, 0x20, 0x3d, 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, + 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x22, 0x20, 0x2e, 0x2e, + 0x20, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x28, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x20, + 0x72, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, + 0x64, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, + 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, - 0x20, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, - 0x69, 0x5d, 0x3a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x20, 0x22, 0x2c, 0x22, 0x2c, 0x22, - 0x29, 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, - 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, - 0x69, 0x64, 0x65, 0x6e, 0x74, 0x2e, 0x2e, 0x22, 0x20, 0x7d, 0x22, 0x29, - 0x0a, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x2e, 0x2e, 0x22, 0x7d, 0x22, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x73, - 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x63, - 0x68, 0x65, 0x63, 0x6b, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x20, 0x62, 0x79, 0x20, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x63, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x66, 0x61, - 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x73, 0x62, 0x61, - 0x73, 0x69, 0x63, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x70, 0x74, 0x72, 0x3d, 0x3d, 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x20, 0x3d, 0x20, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x65, 0x6c, - 0x66, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x22, 0x25, 0x73, 0x2a, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x25, 0x73, 0x2b, 0x22, 0x2c, 0x22, 0x22, 0x29, - 0x0a, 0x09, 0x20, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x20, 0x3d, - 0x20, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x5f, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x63, 0x6c, 0x65, - 0x61, 0x6e, 0x5f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, - 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x09, 0x20, 0x72, 0x20, 0x3d, 0x20, - 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x09, 0x77, 0x68, - 0x69, 0x6c, 0x65, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, - 0x73, 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x72, 0x20, - 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x5b, - 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x63, 0x6f, - 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x20, - 0x6f, 0x72, 0x20, 0x72, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, - 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x72, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, - 0x2d, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x65, 0x20, - 0x6c, 0x75, 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, - 0x61, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x28, - 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x65, - 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3a, 0x6f, 0x76, - 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, - 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x70, - 0x61, 0x72, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x73, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x69, 0x66, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, 0x73, 0x20, 0x64, 0x65, + 0x09, 0x09, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x61, + 0x72, 0x67, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x72, 0x0a, 0x09, 0x09, 0x69, + 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x0a, 0x65, 0x6e, + 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, + 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x75, 0x61, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x76, + 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, + 0x61, 0x64, 0x20, 0x28, 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x73, + 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x28, 0x70, 0x61, 0x72, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, + 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x20, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x61, 0x73, 0x20, 0x69, 0x74, + 0x73, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, + 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, + 0x69, 0x74, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, - 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, - 0x2c, 0x20, 0x27, 0x3d, 0x27, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, - 0x20, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x20, 0x68, - 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, 0x64, 0x65, 0x66, 0x20, - 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, - 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x3d, 0x28, 0x2e, 0x2a, - 0x29, 0x24, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, - 0x72, 0x2c, 0x20, 0x22, 0x7c, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, - 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x0a, 0x0a, 0x09, 0x09, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, - 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, + 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, + 0x3d, 0x28, 0x2e, 0x2a, 0x29, 0x24, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x7c, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x61, 0x20, 0x6c, 0x69, + 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x0a, + 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x69, 0x66, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, + 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x27, 0x73, + 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x09, 0x69, + 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, + 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x27, 0x3d, 0x25, 0x73, 0x2a, + 0x6e, 0x65, 0x77, 0x27, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, - 0x2c, 0x20, 0x22, 0x25, 0x2a, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x2c, 0x20, 0x22, 0x25, 0x28, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, - 0x61, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x0a, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, - 0x72, 0x2c, 0x20, 0x27, 0x3d, 0x25, 0x73, 0x2a, 0x6e, 0x65, 0x77, 0x27, + 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, + 0x61, 0x73, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x2e, 0x20, 0x69, + 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x3f, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x4e, + 0x55, 0x4c, 0x4c, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x5b, + 0x25, 0x28, 0x26, 0x5d, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, + 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x28, 0x6d, + 0x6f, 0x73, 0x74, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x29, 0x0a, 0x0a, 0x09, + 0x2d, 0x2d, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x26, + 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, + 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, + 0x69, 0x6e, 0x64, 0x28, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x3a, 0x22, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x66, 0x69, 0x6e, 0x64, 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x25, - 0x28, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x2d, 0x2d, 0x20, - 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x61, 0x73, 0x20, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x2e, 0x2e, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x61, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x3f, 0x0a, 0x09, 0x09, + 0x66, 0x69, 0x6e, 0x64, 0x28, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x5e, + 0x25, 0x73, 0x2a, 0x6e, 0x65, 0x77, 0x25, 0x73, 0x2b, 0x22, 0x29, 0x20, + 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x2d, + 0x2d, 0x20, 0x69, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x73, + 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x69, 0x6b, + 0x65, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3a, 0x3a, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x27, 0x6e, 0x65, 0x77, + 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, - 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, - 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x4e, 0x55, 0x4c, 0x4c, 0x27, - 0x20, 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, - 0x67, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x09, 0x69, 0x66, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, - 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x5b, 0x25, 0x28, 0x26, 0x5d, - 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, - 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, - 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, - 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, - 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x20, 0x28, 0x6d, 0x6f, 0x73, 0x74, 0x20, - 0x6c, 0x69, 0x6b, 0x65, 0x6c, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, - 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x29, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x69, 0x66, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, - 0x28, 0x70, 0x61, 0x72, 0x2c, 0x20, 0x22, 0x26, 0x22, 0x29, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x69, 0x66, 0x20, + 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x3f, 0x0a, + 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74, + 0x5f, 0x61, 0x72, 0x67, 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, + 0x73, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x29, + 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x5f, 0x2c, 0x5f, 0x2c, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, - 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x3a, 0x22, 0x29, 0x20, 0x6f, 0x72, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, - 0x28, 0x64, 0x65, 0x66, 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x73, 0x2a, 0x6e, - 0x65, 0x77, 0x25, 0x73, 0x2b, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, - 0x0a, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x69, 0x74, - 0x27, 0x73, 0x20, 0x61, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x64, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x74, - 0x68, 0x69, 0x6e, 0x67, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x3a, 0x3a, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x2c, - 0x20, 0x6f, 0x72, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x20, 0x43, 0x6c, 0x61, - 0x73, 0x73, 0x27, 0x0a, 0x09, 0x2d, 0x2d, 0x09, 0x09, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x2d, 0x2d, - 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, - 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x20, 0x3f, 0x0a, 0x65, 0x6e, 0x64, 0x0a, - 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, - 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x2c, 0x20, 0x6c, - 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x29, 0x20, 0x2d, 0x2d, 0x20, - 0x73, 0x74, 0x72, 0x69, 0x70, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, - 0x73, 0x74, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x0a, - 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x5f, 0x2c, - 0x73, 0x5f, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x6c, 0x61, 0x73, 0x74, - 0x5f, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x22, 0x5e, 0x28, 0x5b, 0x5e, 0x3d, - 0x5d, 0x2b, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x5f, - 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, - 0x72, 0x67, 0x2c, 0x20, 0x22, 0x28, 0x5b, 0x25, 0x25, 0x25, 0x28, 0x25, - 0x29, 0x5d, 0x29, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x25, 0x25, 0x31, 0x22, - 0x29, 0x3b, 0x0a, 0x09, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, - 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, - 0x75, 0x62, 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x2c, - 0x20, 0x22, 0x25, 0x73, 0x2a, 0x2c, 0x25, 0x73, 0x2a, 0x22, 0x2e, 0x2e, - 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x2e, 0x2e, 0x22, 0x25, - 0x73, 0x2a, 0x25, 0x29, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, - 0x29, 0x22, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, - 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x2c, 0x20, 0x73, 0x5f, - 0x61, 0x72, 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x0a, 0x2d, - 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x46, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x73, - 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x28, - 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x63, 0x6f, - 0x6e, 0x73, 0x74, 0x27, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, 0x27, 0x27, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, - 0x22, 0x23, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x27, 0x63, - 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x0a, 0x20, 0x65, - 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, - 0x74, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, 0x3a, 0x69, 0x6e, 0x63, - 0x6c, 0x61, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, - 0x20, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x27, 0x74, - 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x2e, 0x2e, - 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, 0x27, 0x2c, 0x20, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69, - 0x73, 0x20, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, 0x66, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, - 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x62, - 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x3d, 0x3d, 0x20, - 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, - 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x72, 0x69, - 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, - 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, - 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, - 0x20, 0x22, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, - 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x6e, - 0x65, 0x77, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6c, 0x6e, 0x61, - 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x0a, 0x20, - 0x20, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x5f, - 0x6e, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, - 0x20, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, + 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x22, 0x5e, + 0x28, 0x5b, 0x5e, 0x3d, 0x5d, 0x2b, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x6c, 0x61, + 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, 0x2c, 0x20, 0x22, 0x28, 0x5b, 0x25, + 0x25, 0x25, 0x28, 0x25, 0x29, 0x5d, 0x29, 0x22, 0x2c, 0x20, 0x22, 0x25, + 0x25, 0x25, 0x31, 0x22, 0x29, 0x3b, 0x0a, 0x09, 0x61, 0x6c, 0x6c, 0x5f, + 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x61, 0x6c, 0x6c, 0x5f, 0x61, + 0x72, 0x67, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x2c, 0x25, 0x73, + 0x2a, 0x22, 0x2e, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x67, + 0x2e, 0x2e, 0x22, 0x25, 0x73, 0x2a, 0x25, 0x29, 0x25, 0x73, 0x2a, 0x24, + 0x22, 0x2c, 0x20, 0x22, 0x29, 0x22, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x6c, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x73, + 0x2c, 0x20, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x6f, 0x72, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x5f, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, + 0x29, 0x0a, 0x20, 0x73, 0x65, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x28, 0x74, 0x2c, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x0a, 0x0a, 0x20, 0x69, + 0x66, 0x20, 0x74, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, + 0x20, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x74, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x7e, 0x3d, 0x20, + 0x27, 0x27, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x28, 0x22, 0x23, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x20, 0x27, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x27, 0x20, 0x73, 0x70, + 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x29, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, 0x69, 0x66, 0x20, 0x74, + 0x3a, 0x69, 0x6e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x2d, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x20, 0x28, 0x27, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x73, + 0x20, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x2e, + 0x27, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x69, 0x73, 0x20, 0x27, 0x2e, 0x2e, 0x74, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x22, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x20, 0x3d, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, + 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x62, + 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, + 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x3d, 0x20, 0x27, 0x6e, 0x65, 0x77, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, + 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x6e, 0x65, + 0x77, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x5f, 0x6e, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x20, 0x3d, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x74, + 0x72, 0x20, 0x3d, 0x20, 0x27, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, + 0x20, 0x22, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x7e, 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, - 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, - 0x27, 0x2a, 0x27, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x69, 0x66, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, - 0x28, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, 0x62, - 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x3d, 0x3d, 0x20, - 0x27, 0x7e, 0x27, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, - 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x25, - 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, - 0x20, 0x3d, 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x0a, - 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6c, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, - 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x27, 0x0a, 0x20, 0x20, - 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x5f, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, - 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x74, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x74, - 0x3a, 0x63, 0x66, 0x75, 0x6e, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x22, - 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x22, 0x29, 0x2e, 0x2e, 0x74, 0x3a, 0x6f, - 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x74, 0x29, 0x0a, 0x20, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x0a, 0x65, 0x6e, 0x64, - 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, - 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, 0x45, 0x78, 0x70, 0x65, - 0x63, 0x74, 0x73, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x73, 0x3a, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x72, - 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, - 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, - 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x69, 0x72, 0x64, 0x20, 0x72, - 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x0a, - 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x73, - 0x74, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x20, - 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x61, 0x2c, 0x63, 0x29, 0x0a, 0x20, 0x2d, - 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, - 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, - 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x27, 0x2c, 0x27, 0x29, - 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, - 0x65, 0x20, 0x62, 0x72, 0x61, 0x63, 0x65, 0x73, 0x0a, 0x20, 0x2d, 0x2d, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, - 0x6c, 0x69, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x28, 0x73, + 0x2c, 0x20, 0x22, 0x25, 0x62, 0x3c, 0x3e, 0x22, 0x2c, 0x20, 0x22, 0x22, + 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x6c, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x27, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x27, 0x0a, 0x20, 0x20, 0x20, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x2e, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x3d, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x74, 0x2e, 0x63, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x3d, 0x20, 0x74, 0x3a, 0x63, 0x66, 0x75, 0x6e, 0x63, 0x6e, 0x61, + 0x6d, 0x65, 0x28, 0x22, 0x74, 0x6f, 0x6c, 0x75, 0x61, 0x22, 0x29, 0x2e, + 0x2e, 0x74, 0x3a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x28, + 0x74, 0x29, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x0a, 0x2d, 0x2d, 0x20, + 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x73, 0x20, 0x74, 0x68, 0x72, 0x65, + 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x3a, 0x20, 0x6f, + 0x6e, 0x65, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x0a, 0x2d, 0x2d, 0x20, 0x61, 0x6e, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x2c, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x68, 0x69, + 0x72, 0x64, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, + 0x69, 0x6e, 0x67, 0x0a, 0x2d, 0x2d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x22, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x22, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x61, 0x2c, 0x63, + 0x29, 0x0a, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, + 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x73, 0x74, 0x72, + 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x2c, + 0x27, 0x2c, 0x27, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x65, 0x6c, 0x69, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x65, 0x20, 0x62, 0x72, 0x61, 0x63, 0x65, 0x73, + 0x0a, 0x20, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, + 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, 0x57, + 0x27, 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x2c, 0x20, 0x22, 0x25, + 0x2e, 0x25, 0x2e, 0x25, 0x2e, 0x25, 0x73, 0x2a, 0x25, 0x29, 0x22, 0x29, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x28, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x20, 0x28, 0x60, 0x2e, 0x2e, 0x2e, 0x27, 0x29, 0x20, + 0x61, 0x72, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x2e, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, + 0x69, 0x6e, 0x67, 0x20, 0x22, 0x2e, 0x2e, 0x64, 0x2e, 0x2e, 0x61, 0x2e, + 0x2e, 0x63, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, + 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x6e, + 0x3d, 0x30, 0x7d, 0x0a, 0x0a, 0x20, 0x09, 0x61, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x61, + 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x28, 0x5b, 0x25, 0x28, 0x25, 0x29, + 0x5d, 0x29, 0x25, 0x73, 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x31, 0x22, + 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x73, + 0x74, 0x72, 0x69, 0x70, 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, - 0x29, 0x29, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5b, 0x27, 0x57, 0x27, 0x5d, 0x20, 0x61, - 0x6e, 0x64, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x69, - 0x6e, 0x64, 0x28, 0x61, 0x2c, 0x20, 0x22, 0x25, 0x2e, 0x25, 0x2e, 0x25, - 0x2e, 0x25, 0x73, 0x2a, 0x25, 0x29, 0x22, 0x29, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, 0x0a, 0x09, 0x09, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, - 0x28, 0x22, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, - 0x77, 0x69, 0x74, 0x68, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, - 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, - 0x28, 0x60, 0x2e, 0x2e, 0x2e, 0x27, 0x29, 0x20, 0x61, 0x72, 0x65, 0x20, - 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x2e, 0x20, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x20, - 0x22, 0x2e, 0x2e, 0x64, 0x2e, 0x2e, 0x61, 0x2e, 0x2e, 0x63, 0x29, 0x0a, - 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, - 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a, 0x20, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x69, 0x3d, 0x31, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x6c, 0x20, 0x3d, 0x20, 0x7b, 0x6e, 0x3d, 0x30, 0x7d, 0x0a, - 0x0a, 0x20, 0x09, 0x61, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x20, 0x22, 0x25, - 0x73, 0x2a, 0x28, 0x5b, 0x25, 0x28, 0x25, 0x29, 0x5d, 0x29, 0x25, 0x73, - 0x2a, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x31, 0x22, 0x29, 0x0a, 0x09, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x2c, 0x73, 0x74, 0x72, 0x69, 0x70, - 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, - 0x70, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, - 0x62, 0x28, 0x61, 0x2c, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x29, 0x3b, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x74, 0x72, 0x73, 0x75, 0x62, 0x28, - 0x61, 0x2c, 0x31, 0x2c, 0x2d, 0x32, 0x29, 0x2c, 0x20, 0x31, 0x2c, 0x20, - 0x2d, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x6c, 0x65, 0x6e, - 0x28, 0x6c, 0x61, 0x73, 0x74, 0x29, 0x2b, 0x31, 0x29, 0x29, 0x0a, 0x09, - 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, - 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x22, 0x2c, 0x22, 0x2c, - 0x20, 0x31, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x31, 0x29, 0x0a, - 0x0a, 0x09, 0x09, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x22, 0x28, 0x22, 0x2e, - 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, - 0x28, 0x6e, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, 0x2a, 0x2c, 0x25, 0x73, - 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x2e, 0x2e, 0x27, 0x29, - 0x27, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x73, + 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x28, 0x73, 0x74, 0x72, + 0x73, 0x75, 0x62, 0x28, 0x61, 0x2c, 0x31, 0x2c, 0x2d, 0x32, 0x29, 0x2c, + 0x20, 0x31, 0x2c, 0x20, 0x2d, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x6c, 0x65, 0x6e, 0x28, 0x6c, 0x61, 0x73, 0x74, 0x29, 0x2b, 0x31, + 0x29, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, + 0x73, 0x20, 0x3d, 0x20, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, + 0x22, 0x2c, 0x22, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, + 0x2d, 0x31, 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x6e, 0x73, 0x20, 0x3d, 0x20, + 0x22, 0x28, 0x22, 0x2e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, + 0x67, 0x73, 0x75, 0x62, 0x28, 0x6e, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x73, + 0x2a, 0x2c, 0x25, 0x73, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x2e, 0x2e, 0x27, 0x29, 0x27, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x6e, 0x73, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x73, 0x28, 0x6e, 0x73, 0x29, 0x0a, 0x0a, 0x09, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x6e, + 0x73, 0x2c, 0x20, 0x63, 0x29, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, + 0x69, 0x3d, 0x31, 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, + 0x09, 0x09, 0x09, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, + 0x69, 0x5d, 0x2c, 0x20, 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, + 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, + 0x5b, 0x69, 0x5d, 0x20, 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x2e, 0x6e, + 0x20, 0x3d, 0x20, 0x6c, 0x2e, 0x6e, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x6c, + 0x5b, 0x6c, 0x2e, 0x6e, 0x5d, 0x20, 0x3d, 0x20, 0x44, 0x65, 0x63, 0x6c, + 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x5b, 0x69, 0x5d, + 0x2c, 0x27, 0x76, 0x61, 0x72, 0x27, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, + 0x0a, 0x20, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, + 0x65, 0x6e, 0x64, 0x0a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, + 0x20, 0x3d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x64, 0x2c, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x29, + 0x0a, 0x20, 0x66, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x6c, + 0x0a, 0x20, 0x66, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, + 0x63, 0x0a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x66, 0x29, 0x0a, 0x65, + 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x70, + 0x2c, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2c, 0x20, 0x6c, 0x61, 0x73, + 0x74, 0x29, 0x0a, 0x0a, 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x3d, + 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x31, 0x0a, + 0x09, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x61, 0x73, 0x74, + 0x20, 0x6f, 0x72, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x67, 0x65, + 0x74, 0x6e, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x6c, 0x73, 0x65, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, + 0x22, 0x22, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x6f, + 0x6f, 0x70, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, + 0x66, 0x6f, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x0a, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x2e, + 0x6c, 0x73, 0x65, 0x70, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x09, + 0x09, 0x6c, 0x73, 0x65, 0x70, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x70, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x70, 0x5f, 0x70, 0x61, 0x72, 0x73, 0x28, 0x73, 0x29, 0x0a, 0x0a, + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, + 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x28, 0x73, 0x2c, 0x20, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x3d, + 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x0a, 0x0a, 0x09, 0x66, 0x6f, 0x72, + 0x20, 0x69, 0x3d, 0x74, 0x2e, 0x6e, 0x2c, 0x31, 0x2c, 0x2d, 0x31, 0x20, + 0x64, 0x6f, 0x0a, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, + 0x74, 0x5b, 0x69, 0x5d, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, + 0x09, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x0a, 0x09, + 0x09, 0x09, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x2d, + 0x2d, 0x69, 0x66, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x74, 0x68, + 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x09, 0x74, 0x5b, 0x69, 0x5d, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, + 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x22, 0x3d, 0x2e, + 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x2d, + 0x2d, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2c, 0x73, 0x74, 0x72, + 0x69, 0x70, 0x2c, 0x6c, 0x61, 0x73, 0x74, 0x0a, 0x0a, 0x65, 0x6e, 0x64, + 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x73, 0x28, 0x6e, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x6e, 0x73, 0x2c, 0x20, 0x63, - 0x29, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, - 0x6c, 0x61, 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x09, 0x74, - 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x20, - 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, - 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x5b, 0x69, 0x5d, 0x20, - 0x64, 0x6f, 0x0a, 0x20, 0x20, 0x6c, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x6c, - 0x2e, 0x6e, 0x2b, 0x31, 0x0a, 0x20, 0x20, 0x6c, 0x5b, 0x6c, 0x2e, 0x6e, - 0x5d, 0x20, 0x3d, 0x20, 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x27, 0x76, 0x61, - 0x72, 0x27, 0x2c, 0x74, 0x72, 0x75, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x69, - 0x20, 0x3d, 0x20, 0x69, 0x2b, 0x31, 0x0a, 0x20, 0x65, 0x6e, 0x64, 0x0a, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x20, 0x3d, 0x20, 0x44, - 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, - 0x2c, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x27, 0x29, 0x0a, 0x20, 0x66, 0x2e, - 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x0a, 0x20, 0x66, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x0a, 0x20, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x46, 0x75, 0x6e, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x28, 0x66, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6a, 0x6f, 0x69, - 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x70, 0x2c, 0x20, 0x66, 0x69, - 0x72, 0x73, 0x74, 0x2c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x29, 0x0a, 0x0a, - 0x09, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x72, - 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x61, 0x73, - 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x6e, 0x28, 0x74, - 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x73, 0x65, - 0x70, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x3d, - 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, - 0x69, 0x20, 0x3d, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2c, 0x6c, 0x61, - 0x73, 0x74, 0x20, 0x64, 0x6f, 0x0a, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, - 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x6c, 0x73, 0x65, 0x70, - 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x09, 0x09, 0x6c, 0x73, 0x65, - 0x70, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x70, 0x0a, 0x09, 0x09, 0x6c, 0x6f, - 0x6f, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, - 0x6e, 0x64, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, - 0x6f, 0x6f, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, - 0x65, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x5f, 0x70, - 0x61, 0x72, 0x73, 0x28, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, - 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, - 0x20, 0x27, 0x2c, 0x27, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, - 0x73, 0x65, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x61, - 0x73, 0x74, 0x0a, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x74, - 0x2e, 0x6e, 0x2c, 0x31, 0x2c, 0x2d, 0x31, 0x20, 0x64, 0x6f, 0x0a, 0x0a, - 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x74, 0x72, - 0x69, 0x70, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x74, 0x5b, 0x69, 0x5d, - 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x61, - 0x73, 0x74, 0x20, 0x3d, 0x20, 0x69, 0x0a, 0x09, 0x09, 0x09, 0x73, 0x74, - 0x72, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, - 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x69, 0x66, 0x20, - 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, - 0x09, 0x2d, 0x2d, 0x09, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, - 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, - 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x65, 0x6e, 0x64, + 0x73, 0x28, 0x73, 0x29, 0x0a, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, + 0x2c, 0x20, 0x22, 0x5e, 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, + 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x29, + 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x5f, 0x63, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, + 0x2c, 0x20, 0x22, 0x2c, 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x20, 0x73, 0x65, 0x70, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, + 0x20, 0x22, 0x22, 0x2c, 0x22, 0x22, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, + 0x69, 0x3d, 0x31, 0x2c, 0x74, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x09, + 0x09, 0x74, 0x5b, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, + 0x2c, 0x20, 0x22, 0x3d, 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, + 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x72, 0x65, + 0x74, 0x2e, 0x2e, 0x73, 0x65, 0x70, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, + 0x0a, 0x09, 0x09, 0x73, 0x65, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x2c, 0x22, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x74, 0x2c, 0x73, 0x74, 0x72, 0x69, 0x70, 0x2c, 0x6c, - 0x61, 0x73, 0x74, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, - 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x28, 0x73, 0x29, - 0x0a, 0x0a, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x2e, 0x67, 0x73, 0x75, 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x5e, - 0x25, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x73, 0x20, - 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, 0x73, 0x75, - 0x62, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x25, 0x29, 0x24, 0x22, 0x2c, 0x20, - 0x22, 0x22, 0x29, 0x0a, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x74, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x28, 0x73, 0x2c, 0x20, 0x22, 0x2c, - 0x22, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x65, - 0x70, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x2c, - 0x22, 0x22, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, - 0x74, 0x2e, 0x6e, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x74, 0x5b, 0x69, - 0x5d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x67, - 0x73, 0x75, 0x62, 0x28, 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x22, 0x3d, - 0x2e, 0x2a, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x09, - 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x73, - 0x65, 0x70, 0x2e, 0x2e, 0x74, 0x5b, 0x69, 0x5d, 0x0a, 0x09, 0x09, 0x73, - 0x65, 0x70, 0x20, 0x3d, 0x20, 0x22, 0x2c, 0x22, 0x0a, 0x09, 0x65, 0x6e, - 0x64, 0x0a, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x22, - 0x28, 0x22, 0x2e, 0x2e, 0x72, 0x65, 0x74, 0x2e, 0x2e, 0x22, 0x29, 0x22, - 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a + 0x72, 0x6e, 0x20, 0x22, 0x28, 0x22, 0x2e, 0x2e, 0x72, 0x65, 0x74, 0x2e, + 0x2e, 0x22, 0x29, 0x22, 0x0a, 0x65, 0x6e, 0x64, 0x0a, 0x0a, 0x0a }; -unsigned int lua_function_lua_len = 14479; +unsigned int lua_function_lua_len = 14483; diff --git a/lib/tolua++/src/bin/lua/basic.lua b/lib/tolua++/src/bin/lua/basic.lua index b5788f2be..425cb6861 100644 --- a/lib/tolua++/src/bin/lua/basic.lua +++ b/lib/tolua++/src/bin/lua/basic.lua @@ -66,6 +66,8 @@ _global_enums = {} -- List of auto renaming _renaming = {} + +_enums = {} function appendrenaming (s) local b,e,old,new = strfind(s,"%s*(.-)%s*@%s*(.-)%s*$") if not b then @@ -146,7 +148,7 @@ function typevar(type) end -- is enum -function isenum (type) +function isenumtype (type) return _enums[type] end diff --git a/lib/tolua++/src/bin/lua/declaration.lua b/lib/tolua++/src/bin/lua/declaration.lua index 5a2adfed9..26ceeba22 100644 --- a/lib/tolua++/src/bin/lua/declaration.lua +++ b/lib/tolua++/src/bin/lua/declaration.lua @@ -227,10 +227,10 @@ function classDeclaration:outchecktype (narg) --else return '!tolua_istable(tolua_S,'..narg..',0,&tolua_err)' --end + elseif isenumtype(self.type) ~= nil then + return '!tolua_is'..self.type..'(tolua_S,'..narg..','..def..',&tolua_err)' elseif t then return '!tolua_is'..t..'(tolua_S,'..narg..','..def..',&tolua_err)' - elseif isenum(self.type) then - return '!tolua_is'..self.type..'(tolua_S,'..narg..','..def..',&tolua_err)' else local is_func = get_is_function(self.type) if self.ptr == '&' or self.ptr == '' then diff --git a/lib/tolua++/src/bin/lua/enumerate.lua b/lib/tolua++/src/bin/lua/enumerate.lua index ef3a9574c..09b22a094 100644 --- a/lib/tolua++/src/bin/lua/enumerate.lua +++ b/lib/tolua++/src/bin/lua/enumerate.lua @@ -49,7 +49,7 @@ function classEnumerate:print (ident,close) end function emitenumprototype(type) - output("int tolua_is" .. string.gsub(type,"::","_") .. " (lua_State* L, int lo, const char * type, int def, tolua_Error* err);") + output("int tolua_is" .. string.gsub(type,"::","_") .. " (lua_State* L, int lo, int def, tolua_Error* err);") end _global_output_enums = {} @@ -58,7 +58,7 @@ _global_output_enums = {} function classEnumerate:supcode () if _global_output_enums[self.name] == nil then _global_output_enums[self.name] = 1 - output("int tolua_is" .. string.gsub(self.name,"::","_") .. " (lua_State* L, int lo, const char * type, int def, tolua_Error* err)") + output("int tolua_is" .. string.gsub(self.name,"::","_") .. " (lua_State* L, int lo, int def, tolua_Error* err)") output("{") output("if (!tolua_isnumber(L,lo,def,err)) return 0;") output("lua_Number val = tolua_tonumber(L,lo,def);") @@ -134,7 +134,7 @@ function Enumerate (n,b,varname) e.min = min e.max = max if n ~= "" then - _enums[n] = 1 + _enums[n] = true Typedef("int "..n) end return _Enumerate(e, varname) diff --git a/lib/tolua++/src/bin/lua/function.lua b/lib/tolua++/src/bin/lua/function.lua index ad1ab4225..3b6b53c5e 100644 --- a/lib/tolua++/src/bin/lua/function.lua +++ b/lib/tolua++/src/bin/lua/function.lua @@ -58,7 +58,7 @@ function classFunction:supcode (local_constructor) if self.args[1].type ~= 'void' then local i=1 while self.args[i] do - if isenum(self.args[i].type) then + if isenumtype(self.args[i].type) then emitenumprototype(self.args[i].type) end i = i+1 -- cgit v1.2.3 From 20fc7d6aea1831da215beaa8f892557a2b8244d8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 20 Mar 2014 22:40:59 +0100 Subject: Updated the tolua++ executable for Win builds. --- src/Bindings/tolua++.exe | Bin 484864 -> 185856 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/Bindings/tolua++.exe b/src/Bindings/tolua++.exe index e5cec6d78..86ab1d70f 100644 Binary files a/src/Bindings/tolua++.exe and b/src/Bindings/tolua++.exe differ -- cgit v1.2.3 From c9163d39f74302fc943e6c9b3b8442061a5f089e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 21 Mar 2014 22:53:46 +0100 Subject: Implemented faster upscaling using templates. Fixes #819. --- src/Generating/BioGen.cpp | 16 ++++++------- src/Generating/CompoGen.cpp | 4 ++-- src/Generating/HeiGen.cpp | 2 +- src/Generating/Noise3DGenerator.cpp | 2 +- src/Generating/StructGen.cpp | 4 ++-- src/LinearUpscale.h | 46 +++++++++++++++++++------------------ 6 files changed, 38 insertions(+), 36 deletions(-) diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index 967deba6a..32a687201 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -371,8 +371,8 @@ void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::B Distort(BaseX + x * 4, BaseZ + z * 4, DistortX[4 * x][4 * z], DistortZ[4 * x][4 * z]); } - LinearUpscale2DArrayInPlace(&DistortX[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); - LinearUpscale2DArrayInPlace(&DistortZ[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); + LinearUpscale2DArrayInPlace(&DistortX[0][0]); + LinearUpscale2DArrayInPlace(&DistortZ[0][0]); for (int z = 0; z < cChunkDef::Width; z++) { @@ -477,8 +477,8 @@ void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cC { Distort(BaseX + x * 4, BaseZ + z * 4, DistortX[4 * x][4 * z], DistortZ[4 * x][4 * z], DistortSize); } - LinearUpscale2DArrayInPlace(&DistortX[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); - LinearUpscale2DArrayInPlace(&DistortZ[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); + LinearUpscale2DArrayInPlace(&DistortX[0][0]); + LinearUpscale2DArrayInPlace(&DistortZ[0][0]); // Prepare a 9x9 area of neighboring cell seeds // (assuming that 7x7 cell area is larger than a chunk being generated) @@ -651,8 +651,8 @@ void cBioGenMultiStepMap::BuildTemperatureHumidityMaps(int a_ChunkX, int a_Chunk HumidityMap[x + 17 * z] = NoiseH; } // for x } // for z - LinearUpscale2DArrayInPlace(TemperatureMap, 17, 17, 8, 8); - LinearUpscale2DArrayInPlace(HumidityMap, 17, 17, 8, 8); + LinearUpscale2DArrayInPlace<17, 17, 8, 8>(TemperatureMap); + LinearUpscale2DArrayInPlace<17, 17, 8, 8>(HumidityMap); // Re-map into integral values in [0 .. 255] range: for (size_t idx = 0; idx < ARRAYCOUNT(a_TemperatureMap); idx++) @@ -778,8 +778,8 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ); } - LinearUpscale2DArrayInPlace(&DistortX[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); - LinearUpscale2DArrayInPlace(&DistortZ[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); + LinearUpscale2DArrayInPlace(&DistortX[0][0]); + LinearUpscale2DArrayInPlace(&DistortZ[0][0]); // Apply distortion to each block coord, then query the voronoi maps for biome group and biome index and choose biome based on that: for (int z = 0; z < cChunkDef::Width; z++) diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index 60356fe46..578bb2481 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -566,7 +566,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc) m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z) / 256; } // for x, z - FloorLo[] - LinearUpscale2DArrayInPlace(FloorLo, 17, 17, INTERPOL_X, INTERPOL_Z); + LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo); // Interpolate segments: for (int Segment = 0; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) @@ -579,7 +579,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc) m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / 256; } // for x, z - FloorLo[] - LinearUpscale2DArrayInPlace(FloorHi, 17, 17, INTERPOL_X, INTERPOL_Z); + LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi); // Interpolate between FloorLo and FloorHi: for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 10710b4a1..3621421c2 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -428,7 +428,7 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa Height[x + 17 * z] = GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes); } } - LinearUpscale2DArrayInPlace(Height, 17, 17, STEPX, STEPZ); + LinearUpscale2DArrayInPlace<17, 17, STEPX, STEPZ>(Height); // Copy into the heightmap for (int z = 0; z < cChunkDef::Width; z++) diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp index afa40c647..15a588d45 100644 --- a/src/Generating/Noise3DGenerator.cpp +++ b/src/Generating/Noise3DGenerator.cpp @@ -420,7 +420,7 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ) } } // Linear-interpolate this XZ floor: - LinearUpscale2DArrayInPlace(CurFloor, 17, 17, UPSCALE_X, UPSCALE_Z); + LinearUpscale2DArrayInPlace<17, 17, UPSCALE_X, UPSCALE_Z>(CurFloor); } // Finish the 3D linear interpolation by interpolating between each XZ-floors on the Y axis diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index 3cc8a09c3..db9d5578c 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -578,7 +578,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) / 256; } // for x, z - FloorLo[] - LinearUpscale2DArrayInPlace(FloorLo, 17, 17, INTERPOL_X, INTERPOL_Z); + LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo); // Interpolate segments: for (int Segment = BaseY; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) @@ -591,7 +591,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / 256; } // for x, z - FloorLo[] - LinearUpscale2DArrayInPlace(FloorHi, 17, 17, INTERPOL_X, INTERPOL_Z); + LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi); // Interpolate between FloorLo and FloorHi: for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) diff --git a/src/LinearUpscale.h b/src/LinearUpscale.h index b337b3219..0b04408cf 100644 --- a/src/LinearUpscale.h +++ b/src/LinearUpscale.h @@ -18,7 +18,7 @@ Therefore, there is no cpp file. InPlace upscaling works on a single array and assumes that the values to work on have already been interspersed into the array to the cell boundaries. -Specifically, a_Array[x * a_AnchorStepX + y * a_AnchorStepY] contains the anchor value. +Specifically, a_Array[x * AnchorStepX + y * AnchorStepY] contains the anchor value. Regular upscaling takes two arrays and "moves" the input from src to dst; src is expected packed. */ @@ -29,46 +29,48 @@ Regular upscaling takes two arrays and "moves" the input from src to dst; src is /** Linearly interpolates values in the array between the equidistant anchor points (upscales). Works in-place (input is already present at the correct output coords) +Uses templates to make it possible for the compiler to further optimizer the loops */ -template void LinearUpscale2DArrayInPlace( - TYPE * a_Array, - int a_SizeX, int a_SizeY, // Dimensions of the array - int a_AnchorStepX, int a_AnchorStepY // Distances between the anchor points in each direction -) +template< + int SizeX, int SizeY, // Dimensions of the array + int AnchorStepX, int AnchorStepY, + typename TYPE +> +void LinearUpscale2DArrayInPlace(TYPE * a_Array) { // First interpolate columns where the anchor points are: - int LastYCell = a_SizeY - a_AnchorStepY; - for (int y = 0; y < LastYCell; y += a_AnchorStepY) + int LastYCell = SizeY - AnchorStepY; + for (int y = 0; y < LastYCell; y += AnchorStepY) { - int Idx = a_SizeX * y; - for (int x = 0; x < a_SizeX; x += a_AnchorStepX) + int Idx = SizeX * y; + for (int x = 0; x < SizeX; x += AnchorStepX) { TYPE StartValue = a_Array[Idx]; - TYPE EndValue = a_Array[Idx + a_SizeX * a_AnchorStepY]; + TYPE EndValue = a_Array[Idx + SizeX * AnchorStepY]; TYPE Diff = EndValue - StartValue; - for (int CellY = 1; CellY < a_AnchorStepY; CellY++) + for (int CellY = 1; CellY < AnchorStepY; CellY++) { - a_Array[Idx + a_SizeX * CellY] = StartValue + Diff * CellY / a_AnchorStepY; + a_Array[Idx + SizeX * CellY] = StartValue + Diff * CellY / AnchorStepY; } // for CellY - Idx += a_AnchorStepX; + Idx += AnchorStepX; } // for x } // for y // Now interpolate in rows, each row has values in the anchor columns - int LastXCell = a_SizeX - a_AnchorStepX; - for (int y = 0; y < a_SizeY; y++) + int LastXCell = SizeX - AnchorStepX; + for (int y = 0; y < SizeY; y++) { - int Idx = a_SizeX * y; - for (int x = 0; x < LastXCell; x += a_AnchorStepX) + int Idx = SizeX * y; + for (int x = 0; x < LastXCell; x += AnchorStepX) { TYPE StartValue = a_Array[Idx]; - TYPE EndValue = a_Array[Idx + a_AnchorStepX]; + TYPE EndValue = a_Array[Idx + AnchorStepX]; TYPE Diff = EndValue - StartValue; - for (int CellX = 1; CellX < a_AnchorStepX; CellX++) + for (int CellX = 1; CellX < AnchorStepX; CellX++) { - a_Array[Idx + CellX] = StartValue + CellX * Diff / a_AnchorStepX; + a_Array[Idx + CellX] = StartValue + CellX * Diff / AnchorStepX; } // for CellY - Idx += a_AnchorStepX; + Idx += AnchorStepX; } } } -- cgit v1.2.3 From 0cfb12f0d11b40d48974177f01494758ed800ff9 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 22 Mar 2014 08:30:49 -0700 Subject: Added Additonal check for xxd existance --- lib/tolua++/CMakeLists.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 75a301a53..7e7498411 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -7,25 +7,28 @@ include_directories ("${PROJECT_SOURCE_DIR}/include/") include_directories ("${PROJECT_SOURCE_DIR}/../") include_directories ("${PROJECT_SOURCE_DIR}") -if(UNIX) +find_program(XXD_EXECUTABLE xxd) + +if(NOT XXD_EXECUTABLE STREQUAL "xxd-NOTFOUND") add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h - COMMAND xxd -i lua/basic.lua | sed 's/unsigned char/static const unsigned char/g' >basic_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/basic.lua | sed 's/unsigned char/static const unsigned char/g' >basic_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/basic.lua) add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h - COMMAND xxd -i lua/enumerate.lua | sed 's/unsigned char/static const unsigned char/g' >enumerate_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/enumerate.lua | sed 's/unsigned char/static const unsigned char/g' >enumerate_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/enumerate.lua) add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h - COMMAND xxd -i lua/function.lua | sed 's/unsigned char/static const unsigned char/g' >function_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/function.lua | sed 's/unsigned char/static const unsigned char/g' >function_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/function.lua) add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/declaration_lua.h - COMMAND xxd -i lua/declaration.lua | sed 's/unsigned char/static const unsigned char/g' >declaration_lua.h + COMMAND ${XXD_EXECUTABLE} -i lua/declaration.lua | sed 's/unsigned char/static const unsigned char/g' >declaration_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/lua/declaration.lua) set_property(SOURCE src/bin/toluabind.c APPEND PROPERTY OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/src/bin/enumerate_lua.h ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h ${PROJECT_SOURCE_DIR}/src/bin/function_lua.h ${PROJECT_SOURCE_DIR}/src/bin/declaration_lua.h) - message(hello) +else() + message("xxd not found, changes to tolua scripts will be ignored") endif() -- cgit v1.2.3 From fd8e5bf551db4c138b8c2ebe8e464c85603c0ef2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 23 Mar 2014 20:54:37 +0100 Subject: Updated the ToLua windows executable. --- src/Bindings/tolua++.exe | Bin 185856 -> 200192 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/Bindings/tolua++.exe b/src/Bindings/tolua++.exe index 86ab1d70f..1e3cc7789 100644 Binary files a/src/Bindings/tolua++.exe and b/src/Bindings/tolua++.exe differ -- cgit v1.2.3 From 83d0c6d6a7358bc18176d4e5432d635f9ffdfd55 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 23 Mar 2014 20:37:23 +0000 Subject: Fixed bad cmake document interpretation Docs say: "If nothing is found, the result will be -NOTFOUND" --- lib/tolua++/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tolua++/CMakeLists.txt b/lib/tolua++/CMakeLists.txt index 7e7498411..e5c8ce3e8 100644 --- a/lib/tolua++/CMakeLists.txt +++ b/lib/tolua++/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories ("${PROJECT_SOURCE_DIR}") find_program(XXD_EXECUTABLE xxd) -if(NOT XXD_EXECUTABLE STREQUAL "xxd-NOTFOUND") +if(NOT XXD_EXECUTABLE STREQUAL "XXD_EXECUTABLE-NOTFOUND") add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/src/bin/basic_lua.h COMMAND ${XXD_EXECUTABLE} -i lua/basic.lua | sed 's/unsigned char/static const unsigned char/g' >basic_lua.h WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/bin/ -- cgit v1.2.3 From f622f4317c76aa287649da965456562a32bce41b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 23 Mar 2014 22:32:45 +0000 Subject: Implemented lilypad placement --- src/Blocks/BlockHandler.cpp | 2 ++ src/Blocks/BlockLilypad.h | 84 +++++++++++++++++++++++++++++++++++++++++++++ src/ClientHandle.cpp | 12 ++++--- src/Items/ItemBucket.h | 8 ++--- 4 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 src/Blocks/BlockLilypad.h diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 4f74e2f45..7fd8c183c 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -41,6 +41,7 @@ #include "BlockIce.h" #include "BlockLadder.h" #include "BlockLeaves.h" +#include "BlockLilypad.h" #include "BlockNewLeaves.h" #include "BlockLever.h" #include "BlockMelon.h" @@ -142,6 +143,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_LAPIS_ORE: return new cBlockOreHandler (a_BlockType); case E_BLOCK_LAVA: return new cBlockLavaHandler (a_BlockType); case E_BLOCK_LEAVES: return new cBlockLeavesHandler (a_BlockType); + case E_BLOCK_LILY_PAD: return new cBlockLilypadHandler (a_BlockType); case E_BLOCK_LIT_FURNACE: return new cBlockFurnaceHandler (a_BlockType); case E_BLOCK_LOG: return new cBlockSidewaysHandler (a_BlockType); case E_BLOCK_MELON: return new cBlockMelonHandler (a_BlockType); diff --git a/src/Blocks/BlockLilypad.h b/src/Blocks/BlockLilypad.h new file mode 100644 index 000000000..3db280d80 --- /dev/null +++ b/src/Blocks/BlockLilypad.h @@ -0,0 +1,84 @@ + +#pragma once + +#include "BlockHandler.h" +#include "../Entities/Player.h" +#include "Vector3.h" +#include "../LineBlockTracer.h" + + + + + +class cBlockLilypadHandler : + public cBlockHandler +{ + typedef cBlockHandler super; + +public: + cBlockLilypadHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + + } + + virtual bool GetPlacementBlockTypeMeta( + cChunkInterface & a_ChunkInterface, cPlayer * a_Player, + int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, + int a_CursorX, int a_CursorY, int a_CursorZ, + BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta + ) override + { + if (a_BlockFace > 0) + { + return false; + } + + class cCallbacks : + public cBlockTracer::cCallbacks + { + public: + cCallbacks(void) : + m_HasHitFluid(false) + { + } + + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override + { + if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) + { + if ((a_BlockMeta != 0) || (a_EntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is for AddFaceDir below + { + return false; + } + m_HasHitFluid = true; + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace); + m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); + return true; + } + return false; + } + + Vector3i m_Pos; + bool m_HasHitFluid; + + } Callbacks; + + cLineBlockTracer Tracer(*a_Player->GetWorld(), Callbacks); + Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector()); + Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5); + + Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); + + if (Callbacks.m_HasHitFluid) + { + a_Player->GetWorld()->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0); + } + + return false; + } +}; + + + + diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 46c10ae82..2c47faa65 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -988,7 +988,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemType); - if (ItemHandler->IsPlaceable() && (a_BlockFace > -1)) + if (ItemHandler->IsPlaceable() && ((a_BlockFace > -1) || (Equipped.m_ItemType == E_BLOCK_LILY_PAD))) { HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); } @@ -1026,7 +1026,8 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler) { - if (a_BlockFace < 0) + BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType); + if ((a_BlockFace < 0) && (EquippedBlock != E_BLOCK_LILY_PAD)) { // Clicked in air return; @@ -1036,7 +1037,6 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e BLOCKTYPE ClickedBlock; NIBBLETYPE ClickedBlockMeta; - BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType); NIBBLETYPE EquippedBlockDamage = (NIBBLETYPE)(m_Player->GetEquippedItem().m_ItemDamage); if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) @@ -1085,7 +1085,10 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e } else { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + if (EquippedBlock != E_BLOCK_LILY_PAD) + { + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + } if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { @@ -1106,6 +1109,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e else { if ( + (EquippedBlock != E_BLOCK_LILY_PAD) && !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() && !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(m_Player, PlaceMeta) ) diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h index 72cb8fa0a..68c89dd85 100644 --- a/src/Items/ItemBucket.h +++ b/src/Items/ItemBucket.h @@ -172,12 +172,12 @@ public: virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override { - if (a_BlockMeta != 0) // Even if it was a water block it would not be a source. - { - return false; - } if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) { + if (a_BlockMeta != 0) // GetBlockFromTrace is called for scooping up fluids; the hit block should be a source + { + return false; + } m_HasHitFluid = true; m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); return true; -- cgit v1.2.3 From 2343b0dfbe12f6db76de1b4ed03cd902975d77b3 Mon Sep 17 00:00:00 2001 From: narroo Date: Sun, 23 Mar 2014 22:11:01 -0400 Subject: Added MetaRotate/Mirror Support for a number of classes. --- src/Blocks/BlockChest.h | 4 +- src/Blocks/BlockDoor.cpp | 75 +++++++++++++++++++++ src/Blocks/BlockDoor.h | 66 ++---------------- src/Blocks/BlockFurnace.h | 8 +-- src/Blocks/BlockHopper.h | 21 +++++- src/Blocks/BlockLadder.h | 4 +- src/Blocks/BlockLever.h | 37 +++++++++- src/Blocks/BlockPumpkin.h | 6 +- src/Blocks/BlockRail.h | 135 +++++++++++++++++++++++++++++++++++++ src/Blocks/BlockRedstoneRepeater.h | 6 +- src/Blocks/BlockSlab.h | 11 ++- src/Blocks/BlockTrapdoor.h | 6 +- 12 files changed, 295 insertions(+), 84 deletions(-) diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 30588d8fc..890b5b933 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -11,11 +11,11 @@ class cBlockChestHandler : - public cMetaRotater + public cMetaRotater { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 4e38ef334..c027daed2 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -110,3 +110,78 @@ const char * cBlockDoorHandler::GetStepSound(void) + +NIBBLETYPE cBlockDoorHandler::MetaRotateCCW(NIBBLETYPE a_Meta) +{ + if (a_Meta & 0x08) + { + return a_Meta; + } + else + { + return super::MetaRotateCCW(a_Meta); + } +} + + + +NIBBLETYPE cBlockDoorHandler::MetaRotateCW(NIBBLETYPE a_Meta) +{ + if (a_Meta & 0x08) + { + return a_Meta; + } + else + { + return super::MetaRotateCW(a_Meta); + } +} + + + +NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) +{ + // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data + // Return a_Meta if panel is a top panel (0x08 bit is set to 1) + LOG("Test MirrorXY"); + if (a_Meta & 0x08) return a_Meta; + + // Holds open/closed meta data. 0x0C == 1100. + NIBBLETYPE OtherMeta = a_Meta & 0x0C; + + // Mirrors according to a table. 0x03 == 0011. + switch (a_Meta & 0x03) + { + case 0x03: return 0x01 + OtherMeta; // South -> North + case 0x01: return 0x03 + OtherMeta; // North -> South + } + + // Not Facing North or South; No change. + return a_Meta; +} + + + +NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) +{ + // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data + // Return a_Meta if panel is a top panel (0x08 bit is set to 1) + LOG("Test MirrorYZ"); + if (a_Meta & 0x08) return a_Meta; + + // Holds open/closed meta data. 0x0C == 1100. + NIBBLETYPE OtherMeta = a_Meta & 0x0C; + + // Mirrors according to a table. 0x03 == 0011. + switch (a_Meta & 0x03) + { + case 0x00: return 0x02 + OtherMeta; // West -> East + case 0x02: return 0x00 + OtherMeta; // East -> West + } + + // Not Facing North or South; No change. + return a_Meta; +} + + + diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 981774c17..066e1ab28 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -21,6 +21,10 @@ public: virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override; virtual const char * GetStepSound(void) override; + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override; virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, @@ -142,14 +146,14 @@ public: static void ChangeDoor(cChunkInterface & a_ChunkInterface, int a_X, int a_Y, int a_Z) { NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_X, a_Y, a_Z); - + a_ChunkInterface.SetBlockMeta(a_X, a_Y, a_Z, ChangeStateMetaData(OldMetaData)); - + if (OldMetaData & 8) { // Current block is top of the door BLOCKTYPE BottomBlock = a_ChunkInterface.GetBlock(a_X, a_Y - 1, a_Z); - NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z); + NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z); if (IsDoor(BottomBlock) && !(BottomMeta & 8)) { @@ -168,62 +172,6 @@ public: } } } - - - virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaRotateCCW(a_Meta); - } - } - - - - virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaRotateCW(a_Meta); - } - } - - - - virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaMirrorXY(a_Meta); - } - } - - - - virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override - { - if (a_Meta & 0x08) - { - return a_Meta; - } - else - { - return super::MetaMirrorYZ(a_Meta); - } - } - } ; diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h index 27ef2689f..c7f8ff8d2 100644 --- a/src/Blocks/BlockFurnace.h +++ b/src/Blocks/BlockFurnace.h @@ -4,17 +4,17 @@ #include "BlockEntity.h" #include "../World.h" #include "../Piston.h" - +#include "MetaRotater.h" class cBlockFurnaceHandler : - public cBlockEntityHandler + public cMetaRotater { public: - cBlockFurnaceHandler(BLOCKTYPE a_BlockType) : - cBlockEntityHandler(a_BlockType) + cBlockFurnaceHandler(BLOCKTYPE a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h index 59b84aa0e..610296529 100644 --- a/src/Blocks/BlockHopper.h +++ b/src/Blocks/BlockHopper.h @@ -3,16 +3,16 @@ // Declares the cBlockHopperHandler class representing the handler for the Hopper block - +#include "MetaRotator.h" class cBlockHopperHandler : - public cBlockEntityHandler + public cMetaRotater { public: cBlockHopperHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } @@ -39,6 +39,21 @@ public: } return true; } + + + virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag. Lowest three bits are position. 0x08 == 1000 + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Mirrors defined by by a table. (Source, mincraft.gamepedia.com) 0x07 == 0111 + switch (a_Meta & 0x07) + { + case 0x00: return 0x01 + OtherMeta; // Down -> Up + case 0x01: return 0x00 + OtherMeta; // Up -> Down + } + // Not Facing Up or Down; No change. + return a_Meta; + } } ; diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h index a3e9edc6b..12408759e 100644 --- a/src/Blocks/BlockLadder.h +++ b/src/Blocks/BlockLadder.h @@ -9,11 +9,11 @@ class cBlockLadderHandler : - public cBlockHandler + public cMetaRotater { public: cBlockLadderHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotater(a_BlockType) { } diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index ef6e102cd..ad2ae29e5 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -1,17 +1,18 @@ #pragma once #include "BlockHandler.h" - +#include "MetaRotator.h" class cBlockLeverHandler : - public cBlockHandler + public cMetaRotator { + typedef cMetaRotator super; public: cBlockLeverHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotator(a_BlockType) { } @@ -104,6 +105,36 @@ public: return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn); } + + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override + { + switch (a_Meta) + { + case 0x00: return 0x07; // Ceiling rotation + case 0x07: return 0x00; + + case 0x05: return 0x06; // Ground rotation + case 0x06: return 0x05; + + default: return super::MetaRotateCCW(a_Meta); // Wall Rotation + } + } + + + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override + { + switch (a_Meta) + { + case 0x00: return 0x07; // Ceiling rotation + case 0x07: return 0x00; + + case 0x05: return 0x06; // Ground rotation + case 0x06: return 0x05; + + default: return super::MetaRotateCCW(a_Meta); // Wall Rotation + } + } } ; diff --git a/src/Blocks/BlockPumpkin.h b/src/Blocks/BlockPumpkin.h index 349f52605..ac2b9817a 100644 --- a/src/Blocks/BlockPumpkin.h +++ b/src/Blocks/BlockPumpkin.h @@ -1,16 +1,16 @@ #pragma once #include "BlockHandler.h" - +#include "MetaRotator.h" class cBlockPumpkinHandler : - public cBlockHandler + public cMetaRotator { public: cBlockPumpkinHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index 07e9814cd..f56ec7152 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -434,6 +434,141 @@ public: } return true; } + + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag when a_Meta is in the range 0x00--0x05 and 0x0A--0x0F. + // Bit 0x08 specifies direction when a_Meta is in the range 0x06-0x09. + if ((a_Meta < 0x06) || (a_Meta > 0x09)) + { + // Save powered rail flag. + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Rotates according to table; 0x07 == 0111. + // Rails can either be flat (North/South) or Ascending (Asc. East) + switch (a_Meta & 0x07) + { + case 0x00: return 0x01 + OtherMeta; // North/South -> East/West + case 0x01: return 0x00 + OtherMeta; // East/West -> North/South + + case 0x02: return 0x04 + OtherMeta; // Asc. East -> Asc. North + case 0x04: return 0x03 + OtherMeta; // Asc. North -> Asc. West + case 0x03: return 0x05 + OtherMeta; // Asc. West -> Asc. South + case 0x05: return 0x02 + OtherMeta; // Asc. South -> Asc. East + } + } + else + { + switch (a_Meta) + { + // Corner Directions + case 0x06: return 0x09; // Northwest Cnr. -> Southwest Cnr. + case 0x07: return 0x06; // Northeast Cnr. -> Northwest Cnr. + case 0x08: return 0x07; // Southeast Cnr. -> Northeast Cnr. + case 0x09: return 0x08; // Southwest Cnr. -> Southeast Cnr. + } + } + // To avoid a compiler warning; + return a_Meta; + } + + + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09. + if ((a_Meta < 0x06) || (a_Meta > 0x09)) + { + // Save powered rail flag. + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Rotates according to table; 0x07 == 0111. + // Rails can either be flat (North/South) or Ascending (Asc. East) + switch (a_Meta & 0x07) + { + case 0x00: return 0x01 + OtherMeta; // North/South -> East/West + case 0x01: return 0x00 + OtherMeta; // East/West -> North/South + + case 0x02: return 0x05 + OtherMeta; // Asc. East -> Asc. South + case 0x05: return 0x03 + OtherMeta; // Asc. South -> Asc. West + case 0x03: return 0x04 + OtherMeta; // Asc. West -> Asc. North + case 0x04: return 0x02 + OtherMeta; // Asc. North -> Asc. East + } + } + else + { + switch (a_Meta) + { + // Corner Directions + case 0x06: return 0x07; // Northwest Cnr. -> Northeast Cnr. + case 0x07: return 0x08; // Northeast Cnr. -> Southeast Cnr. + case 0x08: return 0x09; // Southeast Cnr. -> Southwest Cnr. + case 0x09: return 0x06; // Southwest Cnr. -> Northwest Cnr. + } + } + // To avoid a compiler warning; + return a_Meta; + } + + + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09. + if ((a_Meta < 0x06) || (a_Meta > 0x09)) + { + // Save powered rail flag. + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Mirrors according to table; 0x07 == 0111. + // Rails can either be flat (North/South) or Ascending (Asc. East) + switch (a_Meta & 0x07) + { + case 0x05: return 0x04 + OtherMeta; // Asc. South -> Asc. North + case 0x04: return 0x05 + OtherMeta; // Asc. North -> Asc. South + } + } + else + { + switch (a_Meta) + { + // Corner Directions + case 0x06: return 0x09; // Northwest Cnr. -> Southwest Cnr. + case 0x07: return 0x08; // Northeast Cnr. -> Southeast Cnr. + case 0x08: return 0x07; // Southeast Cnr. -> Northeast Cnr. + case 0x09: return 0x06; // Southwest Cnr. -> Northwest Cnr. + } + } + // To avoid a compiler warning; + return a_Meta; + } + + + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override + { + // Bit 0x08 is a flag for value in the range 0x00--0x05 and specifies direction for values withint 0x006--0x09. + if ((a_Meta < 0x06) || (a_Meta > 0x09)) + { + // Save powered rail flag. + NIBBLETYPE OtherMeta = a_Meta & 0x08; + // Mirrors according to table; 0x07 == 0111. + // Rails can either be flat (North/South) or Ascending (Asc. East) + switch (a_Meta & 0x07) + { + case 0x02: return 0x03 + OtherMeta; // Asc. East -> Asc. West + case 0x03: return 0x02 + OtherMeta; // Asc. West -> Asc. East + } + } + else + { + switch (a_Meta) + { + // Corner Directions + case 0x06: return 0x07; // Northwest Cnr. -> Northeast Cnr. + case 0x07: return 0x06; // Northeast Cnr. -> Northwest Cnr. + case 0x08: return 0x09; // Southeast Cnr. -> Southwest Cnr. + case 0x09: return 0x08; // Southwest Cnr. -> Southeast Cnr. + } + } + // To avoid a compiler warning; + return a_Meta; + } } ; diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index 1e2a86949..fe6cd21b9 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -3,17 +3,17 @@ #include "BlockHandler.h" #include "Chunk.h" - +#include "MetaRotator.h" class cBlockRedstoneRepeaterHandler : - public cBlockHandler + public cMetaRotator { public: cBlockRedstoneRepeaterHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 7cd2c97b2..b18bf7ef3 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -14,8 +14,6 @@ - - class cBlockSlabHandler : public cBlockHandler { @@ -184,6 +182,15 @@ public: ASSERT(!"Unhandled double slab type!"); return ""; } + + + virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override + { + NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelate meta data. + + // 8th bit is up/down. 1 right-side-up, 0 is up-side-down. + return (a_Meta & 0x08) ? 0x00 + OtherMeta : 0x01 + OtherMeta; + } } ; diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 9bae92c4d..6a36ab874 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" - +#include "MetaRotator.h" class cBlockTrapdoorHandler : - public cBlockHandler + public cMetaRotator { public: cBlockTrapdoorHandler(BLOCKTYPE a_BlockType) - : cBlockHandler(a_BlockType) + : cMetaRotator(a_BlockType) { } -- cgit v1.2.3 From 6b77dc74ade3d8088da09d26c1b701d92ef28e9e Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 24 Mar 2014 12:29:19 +0200 Subject: Wither invulnerability --- src/Blocks/BlockMobHead.h | 14 +++++++++ src/Mobs/Monster.cpp | 1 + src/Mobs/Wither.cpp | 52 ++++++++++++++++++++++++++++++++- src/Mobs/Wither.h | 14 +++++++++ src/World.h | 2 +- src/WorldStorage/MapSerializer.cpp | 6 +++- src/WorldStorage/NBTChunkSerializer.cpp | 8 ++++- src/WorldStorage/WSSAnvil.cpp | 8 ++++- 8 files changed, 100 insertions(+), 5 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 2b128f13b..6aa01f986 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -21,6 +21,18 @@ public: { a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0)); } + + bool TrySpawnWither(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) + { + if (a_BlockY < 2) + { + return false; + } + + // TODO 2014-03-24 xdot + + return false; + } virtual void OnPlacedByPlayer( cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, @@ -62,6 +74,8 @@ public: cWorld * World = (cWorld *) &a_WorldInterface; World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); + + TrySpawnWither(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); } } ; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 16d6aed1f..d3e0f1c26 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -758,6 +758,7 @@ cMonster::eFamily cMonster::FamilyFromType(eType a_Type) case mtSquid: return mfWater; case mtVillager: return mfPassive; case mtWitch: return mfHostile; + case mtWither: return mfHostile; case mtWolf: return mfHostile; case mtZombie: return mfHostile; case mtZombiePigman: return mfHostile; diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index c46e0beab..0e42194ac 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -2,14 +2,64 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Wither.h" +#include "../World.h" cWither::cWither(void) : - super("Wither", mtWither, "mob.wither.hurt", "mob.wither.death", 0.9, 4.0) + super("Wither", mtWither, "mob.wither.hurt", "mob.wither.death", 0.9, 4.0), + m_InvulnerableTicks(220) { + SetMaxHealth(300); + + SetHealth(GetMaxHealth() / 3); +} + + + + + +void cWither::DoTakeDamage(TakeDamageInfo & a_TDI) +{ + if (a_TDI.DamageType == dtDrowning) + { + return; + } + + if (m_InvulnerableTicks > 0) + { + return; + } + + super::DoTakeDamage(a_TDI); +} + + + + + +void cWither::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + + if (m_InvulnerableTicks > 0) + { + unsigned int NewTicks = m_InvulnerableTicks - 1; + + if (NewTicks == 0) + { + m_World->DoExplosionAt(7.0, GetPosX(), GetPosY(), GetPosZ(), false, esWitherBirth, this); + } + + m_InvulnerableTicks = NewTicks; + + if ((NewTicks % 10) == 0) + { + Heal(10); + } + } } diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index 56effc6bb..df3a57798 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -16,8 +16,22 @@ public: cWither(void); CLASS_PROTODEF(cWither); + + unsigned int GetNumInvulnerableTicks(void) const { return m_InvulnerableTicks; } + + void SetNumInvulnerableTicks(unsigned int a_Ticks) { m_InvulnerableTicks = a_Ticks; } + // Override functions virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + + virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; + + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + +private: + + /** The number of ticks of invulnerability left after being initially created. Zero once invulnerability has expired. */ + unsigned int m_InvulnerableTicks; } ; diff --git a/src/World.h b/src/World.h index 46aece18f..79fcc5616 100644 --- a/src/World.h +++ b/src/World.h @@ -505,7 +505,7 @@ public: | esGhastFireball | cGhastFireball * | | esWitherSkullBlack | TBD | | esWitherSkullBlue | TBD | - | esWitherBirth | TBD | + | esWitherBirth | cWither * | | esPlugin | void * | */ virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData); // tolua_export // override, cannot specify due to tolua diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index a4a0aab57..df72d1cc9 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -141,7 +141,11 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) { eDimension Dimension = (eDimension) a_NBT.GetByte(CurrLine); - ASSERT(Dimension == m_Map->m_World->GetDimension()); + if (Dimension != m_Map->m_World->GetDimension()) + { + // TODO 2014-03-20 xdot: We should store nether maps in nether worlds, e.t.c. + return false; + } } CurrLine = a_NBT.FindChildByName(Data, "width"); diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index acca96ba8..f9cca1495 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -43,6 +43,7 @@ #include "../Mobs/Slime.h" #include "../Mobs/Skeleton.h" #include "../Mobs/Villager.h" +#include "../Mobs/Wither.h" #include "../Mobs/Wolf.h" #include "../Mobs/Zombie.h" @@ -422,7 +423,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) case cMonster::mtSquid: EntityClass = "Squid"; break; case cMonster::mtVillager: EntityClass = "Villager"; break; case cMonster::mtWitch: EntityClass = "Witch"; break; - case cMonster::mtWither: EntityClass = "Wither"; break; + case cMonster::mtWither: EntityClass = "WitherBoss"; break; case cMonster::mtWolf: EntityClass = "Wolf"; break; case cMonster::mtZombie: EntityClass = "Zombie"; break; case cMonster::mtZombiePigman: EntityClass = "PigZombie"; break; @@ -501,6 +502,11 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) m_Writer.AddInt("Profession", ((const cVillager *)a_Monster)->GetVilType()); break; } + case cMonster::mtWither: + { + m_Writer.AddInt("Invul", ((const cWither *)a_Monster)->GetNumInvulnerableTicks()); + break; + } case cMonster::mtWolf: { m_Writer.AddString("Owner", ((const cWolf *)a_Monster)->GetOwner()); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 7a2366755..2516ac07a 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1238,7 +1238,7 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadWitchFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } - else if (strncmp(a_IDTag, "Wither", a_IDTagLength) == 0) + else if (strncmp(a_IDTag, "WitherBoss", a_IDTagLength) == 0) { LoadWitherFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } @@ -2250,6 +2250,12 @@ void cWSSAnvil::LoadWitherFromNBT(cEntityList & a_Entities, const cParsedNBT & a return; } + int CurrLine = a_NBT.FindChildByName(a_TagIdx, "Invul"); + if (CurrLine > 0) + { + Monster->SetNumInvulnerableTicks(a_NBT.GetInt(CurrLine)); + } + a_Entities.push_back(Monster.release()); } -- cgit v1.2.3 From a6414d334834692c1d8b573b1e90c464d4d4469c Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 24 Mar 2014 19:52:35 +0100 Subject: Add log pickups. --- src/Blocks/BlockSideways.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Blocks/BlockSideways.h b/src/Blocks/BlockSideways.h index 69c0a7230..d67c3aa24 100644 --- a/src/Blocks/BlockSideways.h +++ b/src/Blocks/BlockSideways.h @@ -29,7 +29,13 @@ public: return true; } - + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.Add(m_BlockType, 1, a_BlockMeta & 0x3); + } + + inline static NIBBLETYPE BlockFaceToMetaData(eBlockFace a_BlockFace, NIBBLETYPE a_WoodMeta) { switch (a_BlockFace) -- cgit v1.2.3 From 4f3377bbbfa12623be61561ae75bdd9d8d5fbe8c Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 25 Mar 2014 09:10:55 +0200 Subject: Minor fixes --- src/Mobs/Villager.h | 2 +- src/Mobs/Wither.h | 5 ++--- src/World.h | 20 ++++++++++---------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index b99ae876f..5bba4d4ba 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -29,7 +29,7 @@ public: CLASS_PROTODEF(cVillager); - // Override functions + // cEntity overrides virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Tick (float a_Dt, cChunk & a_Chunk) override; diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index df3a57798..d09e3607a 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -21,17 +21,16 @@ public: void SetNumInvulnerableTicks(unsigned int a_Ticks) { m_InvulnerableTicks = a_Ticks; } - // Override functions + // cEntity overrides virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; - virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override; private: /** The number of ticks of invulnerability left after being initially created. Zero once invulnerability has expired. */ unsigned int m_InvulnerableTicks; + } ; diff --git a/src/World.h b/src/World.h index 79fcc5616..bb2eb0b21 100644 --- a/src/World.h +++ b/src/World.h @@ -497,16 +497,16 @@ public: /** Does an explosion with the specified strength at the specified coordinate a_SourceData exact type depends on the a_Source: - | esOther | void * | - | esPrimedTNT | cTNTEntity * | - | esMonster | cMonster * | - | esBed | cVector3i * | - | esEnderCrystal | Vector3i * | - | esGhastFireball | cGhastFireball * | - | esWitherSkullBlack | TBD | - | esWitherSkullBlue | TBD | - | esWitherBirth | cWither * | - | esPlugin | void * | + | esOther | void * | + | esPrimedTNT | cTNTEntity * | + | esMonster | cMonster * | + | esBed | cVector3i * | + | esEnderCrystal | Vector3i * | + | esGhastFireball | cGhastFireball * | + | esWitherSkullBlack | TBD | + | esWitherSkullBlue | TBD | + | esWitherBirth | cMonster * | + | esPlugin | void * | */ virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData); // tolua_export // override, cannot specify due to tolua -- cgit v1.2.3 From 0fe1e50ffc744d861744e4aa4905e1b4b15e10fd Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 25 Mar 2014 10:32:58 +0200 Subject: Protocol: Wither metadata --- src/Blocks/BlockMobHead.h | 82 ++++++++++++++++++++++++++++++++++++++++++-- src/Mobs/Wither.cpp | 16 +++++++++ src/Mobs/Wither.h | 3 ++ src/Protocol/Protocol125.cpp | 8 +++++ src/Protocol/Protocol17x.cpp | 10 ++++++ 5 files changed, 116 insertions(+), 3 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 6aa01f986..9935c2496 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -22,14 +22,90 @@ public: a_Pickups.push_back(cItem(E_ITEM_HEAD, 1, 0)); } - bool TrySpawnWither(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) + bool TrySpawnWither(cChunkInterface & a_ChunkInterface, cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { if (a_BlockY < 2) { return false; } + + class cCallback : public cMobHeadCallback + { + bool m_IsWither; + + virtual bool Item (cMobHeadEntity * a_MobHeadEntity) + { + m_IsWither = (a_MobHeadEntity->GetType() == SKULL_TYPE_WITHER); + + return false; + } + + public: + cCallback () : m_IsWither(false) {} + + bool IsWither(void) const { return m_IsWither; } + + void Reset(void) { m_IsWither = false; } + } CallbackA, CallbackB; + + BLOCKTYPE BlockY1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); + BLOCKTYPE BlockY2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ); + + if ((BlockY1 != E_BLOCK_SOULSAND) || (BlockY2 != E_BLOCK_SOULSAND)) + { + return false; + } - // TODO 2014-03-24 xdot + a_World->DoWithMobHeadAt(a_BlockX - 1, a_BlockY, a_BlockZ, CallbackA); + a_World->DoWithMobHeadAt(a_BlockX + 1, a_BlockY, a_BlockZ, CallbackB); + + BLOCKTYPE Block1 = a_ChunkInterface.GetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ); + BLOCKTYPE Block2 = a_ChunkInterface.GetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ); + + if ((Block1 == E_BLOCK_SOULSAND) && (Block2 == E_BLOCK_SOULSAND) && CallbackA.IsWither() && CallbackB.IsWither()) + { + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(a_BlockX + 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(a_BlockX - 1, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); + + // Block entities + a_World->SetBlock(a_BlockX + 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_World->SetBlock(a_BlockX - 1, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + + // Spawn the wither: + a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + + return true; + } + + CallbackA.Reset(); + CallbackB.Reset(); + + a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ - 1, CallbackA); + a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ + 1, CallbackB); + + Block1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1); + Block2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1); + + if ((Block1 == E_BLOCK_SOULSAND) && (Block2 == E_BLOCK_SOULSAND) && CallbackA.IsWither() && CallbackB.IsWither()) + { + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ + 1, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 1, a_BlockZ - 1, E_BLOCK_AIR, 0); + a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY - 2, a_BlockZ, E_BLOCK_AIR, 0); + + // Block entities + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ + 1, E_BLOCK_AIR, 0); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ - 1, E_BLOCK_AIR, 0); + + // Spawn the wither: + a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + + return true; + } return false; } @@ -75,7 +151,7 @@ public: World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); - TrySpawnWither(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + TrySpawnWither(a_ChunkInterface, World, a_BlockX, a_BlockY, a_BlockZ); } } ; diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index 0e42194ac..790f127f2 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -21,6 +21,15 @@ cWither::cWither(void) : +bool cWither::IsArmored(void) const +{ + return GetHealth() <= (GetMaxHealth() / 2); +} + + + + + void cWither::DoTakeDamage(TakeDamageInfo & a_TDI) { if (a_TDI.DamageType == dtDrowning) @@ -33,6 +42,11 @@ void cWither::DoTakeDamage(TakeDamageInfo & a_TDI) return; } + if (IsArmored() && (a_TDI.DamageType == dtRangedAttack)) + { + return; + } + super::DoTakeDamage(a_TDI); } @@ -60,6 +74,8 @@ void cWither::Tick(float a_Dt, cChunk & a_Chunk) Heal(10); } } + + m_World->BroadcastEntityMetadata(*this); } diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index d09e3607a..52666a190 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -20,6 +20,9 @@ public: unsigned int GetNumInvulnerableTicks(void) const { return m_InvulnerableTicks; } void SetNumInvulnerableTicks(unsigned int a_Ticks) { m_InvulnerableTicks = a_Ticks; } + + /** Returns whether the wither is invulnerable to arrows. */ + bool IsArmored(void) const; // cEntity overrides virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 69f4934d8..d8b340350 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1972,6 +1972,14 @@ void cProtocol125::WriteMobMetadata(const cMonster & a_Mob) WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); // Aggravated? Doesn't seem to do anything break; } + case cMonster::mtWither: + { + WriteByte(0x54); // Int at index 20 + WriteInt(((const cWither &)a_Mob).GetNumInvulnerableTicks()); + WriteByte(0x66); // Float at index 6 + WriteFloat((float)(a_Mob.GetHealth())); + break; + } case cMonster::mtSlime: case cMonster::mtMagmaCube: { diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 721ed349e..c678fc9a0 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -2535,6 +2535,7 @@ void cProtocol172::cPacketizer::WriteEntityMetadata(const cEntity & a_Entity) WriteByte(Frame.GetRotation()); break; } + default: break; } } @@ -2659,6 +2660,15 @@ void cProtocol172::cPacketizer::WriteMobMetadata(const cMonster & a_Mob) WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); break; } + + case cMonster::mtWither: + { + WriteByte(0x54); // Int at index 20 + WriteInt(((const cWither &)a_Mob).GetNumInvulnerableTicks()); + WriteByte(0x66); // Float at index 6 + WriteFloat((float)(a_Mob.GetHealth())); + break; + } case cMonster::mtSlime: { -- cgit v1.2.3 From ba4216641120ec2f49464ed0b136af3198d48f89 Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 25 Mar 2014 11:13:27 +0200 Subject: Fixed wither summoning --- src/Blocks/BlockMobHead.h | 25 ++++++++++++++++++++++++- src/Mobs/Wither.cpp | 14 ++++++++++++-- src/Mobs/Wither.h | 1 + 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 9935c2496..693240898 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -47,6 +47,15 @@ public: void Reset(void) { m_IsWither = false; } } CallbackA, CallbackB; + + a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA); + + if (!CallbackA.IsWither()) + { + return false; + } + + CallbackA.Reset(); BLOCKTYPE BlockY1 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); BLOCKTYPE BlockY2 = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY - 2, a_BlockZ); @@ -151,7 +160,21 @@ public: World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); - TrySpawnWither(a_ChunkInterface, World, a_BlockX, a_BlockY, a_BlockZ); + static const Vector3i Coords[] = + { + Vector3i( 0, 0, 0), + Vector3i( 1, 0, 0), + Vector3i(-1, 0, 0), + Vector3i( 0, 0, 1), + Vector3i( 0, 0, -1), + }; + for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i) + { + if (TrySpawnWither(a_ChunkInterface, World, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z)) + { + break; + } + } // for i - Coords[] } } ; diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index 790f127f2..39dc6aab9 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -13,8 +13,6 @@ cWither::cWither(void) : m_InvulnerableTicks(220) { SetMaxHealth(300); - - SetHealth(GetMaxHealth() / 3); } @@ -30,6 +28,18 @@ bool cWither::IsArmored(void) const +bool cWither::Initialize(cWorld * a_World) override +{ + // Set health before BroadcastSpawnEntity() + SetHealth(GetMaxHealth() / 3); + + return super::Initialize(a_World); +} + + + + + void cWither::DoTakeDamage(TakeDamageInfo & a_TDI) { if (a_TDI.DamageType == dtDrowning) diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index 52666a190..bc78bfaad 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -25,6 +25,7 @@ public: bool IsArmored(void) const; // cEntity overrides + virtual bool Initialize(cWorld * a_World) override; virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Tick(float a_Dt, cChunk & a_Chunk) override; -- cgit v1.2.3 From c8445cd93479d4729a180b21df1783449ce01b7e Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 25 Mar 2014 11:40:54 +0200 Subject: Fixed clang compilation --- src/Blocks/BlockMobHead.h | 29 ++++++++++++++++------------- src/Mobs/Wither.cpp | 2 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 693240898..e172cee69 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -160,21 +160,24 @@ public: World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); - static const Vector3i Coords[] = + if (a_BlockMeta == SKULL_TYPE_WITHER) { - Vector3i( 0, 0, 0), - Vector3i( 1, 0, 0), - Vector3i(-1, 0, 0), - Vector3i( 0, 0, 1), - Vector3i( 0, 0, -1), - }; - for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i) - { - if (TrySpawnWither(a_ChunkInterface, World, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z)) + static const Vector3i Coords[] = { - break; - } - } // for i - Coords[] + Vector3i( 0, 0, 0), + Vector3i( 1, 0, 0), + Vector3i(-1, 0, 0), + Vector3i( 0, 0, 1), + Vector3i( 0, 0, -1), + }; + for (size_t i = 0; i < ARRAYCOUNT(Coords); ++i) + { + if (TrySpawnWither(a_ChunkInterface, World, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z)) + { + break; + } + } // for i - Coords[] + } } } ; diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index 39dc6aab9..8f5d28b68 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -28,7 +28,7 @@ bool cWither::IsArmored(void) const -bool cWither::Initialize(cWorld * a_World) override +bool cWither::Initialize(cWorld * a_World) { // Set health before BroadcastSpawnEntity() SetHealth(GetMaxHealth() / 3); -- cgit v1.2.3 From d77a6417f62990f5c986e03a7e226c03b5a74fb8 Mon Sep 17 00:00:00 2001 From: Samuel Barney Date: Tue, 25 Mar 2014 10:33:52 -0600 Subject: Added newlines. Without them, the files would not compile. --- src/Entities/Effects.h | 2 +- src/Entities/Floater.h | 2 +- src/OSSupport/Sleep.h | 2 +- src/OSSupport/Thread.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Entities/Effects.h b/src/Entities/Effects.h index e7611847d..baf3302fb 100644 --- a/src/Entities/Effects.h +++ b/src/Entities/Effects.h @@ -27,4 +27,4 @@ enum ENUM_ENTITY_EFFECT E_EFFECT_ABSORPTION = 22, E_EFFECT_SATURATION = 23, } ; -// tolua_end \ No newline at end of file +// tolua_end diff --git a/src/Entities/Floater.h b/src/Entities/Floater.h index f3b51d77b..547d503f1 100644 --- a/src/Entities/Floater.h +++ b/src/Entities/Floater.h @@ -43,4 +43,4 @@ protected: // Entity IDs int m_PlayerID; int m_AttachedMobID; -} ; // tolua_export \ No newline at end of file +} ; // tolua_export diff --git a/src/OSSupport/Sleep.h b/src/OSSupport/Sleep.h index 5298c15da..0ec0adf9d 100644 --- a/src/OSSupport/Sleep.h +++ b/src/OSSupport/Sleep.h @@ -4,4 +4,4 @@ class cSleep { public: static void MilliSleep( unsigned int a_MilliSeconds ); -}; \ No newline at end of file +}; diff --git a/src/OSSupport/Thread.h b/src/OSSupport/Thread.h index 3c9316424..4153b2427 100644 --- a/src/OSSupport/Thread.h +++ b/src/OSSupport/Thread.h @@ -23,4 +23,4 @@ private: cEvent* m_StopEvent; AString m_ThreadName; -}; \ No newline at end of file +}; -- cgit v1.2.3 From 71e9133e49c238ce74de144c5ab3b3d01d29152e Mon Sep 17 00:00:00 2001 From: Samuel Barney Date: Tue, 25 Mar 2014 10:34:31 -0600 Subject: Added one more missing newline. --- src/WorldStorage/FireworksSerializer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WorldStorage/FireworksSerializer.h b/src/WorldStorage/FireworksSerializer.h index 5b87bafdb..cbc544a14 100644 --- a/src/WorldStorage/FireworksSerializer.h +++ b/src/WorldStorage/FireworksSerializer.h @@ -89,4 +89,4 @@ public: short m_FlightTimeInTicks; std::vector m_Colours; std::vector m_FadeColours; -}; \ No newline at end of file +}; -- cgit v1.2.3 From eb3cc729d4e367c54a47369f712831908f8da22c Mon Sep 17 00:00:00 2001 From: Samuel Barney Date: Tue, 25 Mar 2014 11:15:05 -0600 Subject: More fixes to get it to compile for me on Mac 10.9. Mostly just newline additions, but some of the unused variables were causing errors, so I wrapped them in #ifndef __APPLE__ calls, since I didn't know if they were going to be used in the future. Also had to undefine TOLUA_TEMPLATE_BIND a couple of times. --- lib/md5/md5.h | 2 +- src/Bindings/DeprecatedBindings.cpp | 1 + src/Bindings/LuaState.cpp | 1 + src/Bindings/ManualBindings.cpp | 1 + src/Bindings/ManualBindings.h | 2 +- src/Bindings/PluginLua.cpp | 5 +++++ src/Bindings/WebPlugin.cpp | 2 +- src/DeadlockDetect.cpp | 2 ++ src/Entities/Boat.cpp | 2 -- src/Entities/ExpOrb.h | 2 +- src/Group.cpp | 2 +- src/Mobs/Blaze.cpp | 2 +- src/Mobs/Blaze.h | 4 ---- src/Mobs/Skeleton.cpp | 2 +- src/OSSupport/Errors.cpp | 2 +- src/World.cpp | 3 ++- 16 files changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/md5/md5.h b/lib/md5/md5.h index ad5ad5384..3aa88ac22 100644 --- a/lib/md5/md5.h +++ b/lib/md5/md5.h @@ -90,4 +90,4 @@ private: std::string md5(const std::string & str); -#endif \ No newline at end of file +#endif diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index 408b1b84a..fbc008be6 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "DeprecatedBindings.h" +#undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" #include "Plugin.h" diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 47380b8a7..7afae5e38 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -11,6 +11,7 @@ extern "C" #include "lua/src/lualib.h" } +#undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" #include "Bindings.h" #include "ManualBindings.h" diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 20bbc48f2..081ea4d59 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2,6 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "ManualBindings.h" +#undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" #include "Plugin.h" diff --git a/src/Bindings/ManualBindings.h b/src/Bindings/ManualBindings.h index e6594947e..f38e26267 100644 --- a/src/Bindings/ManualBindings.h +++ b/src/Bindings/ManualBindings.h @@ -5,4 +5,4 @@ class ManualBindings { public: static void Bind( lua_State* tolua_S ); -}; \ No newline at end of file +}; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index cccbc3c93..ebabeb222 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -5,7 +5,11 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules +#ifdef __APPLE__ +#define LUA_USE_MACOSX +#else #define LUA_USE_POSIX +#endif #include "PluginLua.h" #include "../CommandOutput.h" @@ -14,6 +18,7 @@ extern "C" #include "lua/src/lualib.h" } +#undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" diff --git a/src/Bindings/WebPlugin.cpp b/src/Bindings/WebPlugin.cpp index 3b71d553c..bf45405ba 100644 --- a/src/Bindings/WebPlugin.cpp +++ b/src/Bindings/WebPlugin.cpp @@ -110,4 +110,4 @@ AString cWebPlugin::SafeString( const AString & a_String ) RetVal.push_back( c ); } return RetVal; -} \ No newline at end of file +} diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index 4dc7bfde6..8e1283bba 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -17,7 +17,9 @@ const int CYCLE_MILLISECONDS = 100; /// When the number of cycles for the same world age hits this value, it is considered a deadlock +#ifndef __APPLE__ const int NUM_CYCLES_LIMIT = 200; // 200 = twenty seconds +#endif diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp index 94b24c5af..921252253 100644 --- a/src/Entities/Boat.cpp +++ b/src/Entities/Boat.cpp @@ -122,5 +122,3 @@ void cBoat::HandleSpeedFromAttachee(float a_Forward, float a_Sideways) AddSpeed(ToAddSpeed); } - - \ No newline at end of file diff --git a/src/Entities/ExpOrb.h b/src/Entities/ExpOrb.h index c1150bd03..e76274ac9 100644 --- a/src/Entities/ExpOrb.h +++ b/src/Entities/ExpOrb.h @@ -42,4 +42,4 @@ protected: /** The number of ticks that the entity has existed / timer between collect and destroy; in msec */ float m_Timer; -} ; // tolua_export \ No newline at end of file +} ; // tolua_export diff --git a/src/Group.cpp b/src/Group.cpp index 5f1f25782..9c2467144 100644 --- a/src/Group.cpp +++ b/src/Group.cpp @@ -38,4 +38,4 @@ void cGroup::InheritFrom( cGroup* a_Group ) void cGroup::ClearPermission() { m_Permissions.clear(); -} \ No newline at end of file +} diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp index ac42cf40b..84ff8929b 100644 --- a/src/Mobs/Blaze.cpp +++ b/src/Mobs/Blaze.cpp @@ -53,4 +53,4 @@ void cBlaze::Attack(float a_Dt) m_AttackInterval = 0.0; // ToDo: Shoot 3 fireballs instead of 1. } -} \ No newline at end of file +} diff --git a/src/Mobs/Blaze.h b/src/Mobs/Blaze.h index cdb3a1306..5970451c7 100644 --- a/src/Mobs/Blaze.h +++ b/src/Mobs/Blaze.h @@ -20,7 +20,3 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void Attack(float a_Dt) override; } ; - - - - diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp index 47fcdbb26..1685f40c5 100644 --- a/src/Mobs/Skeleton.cpp +++ b/src/Mobs/Skeleton.cpp @@ -88,4 +88,4 @@ void cSkeleton::Attack(float a_Dt) m_World->BroadcastSpawnEntity(*Arrow); m_AttackInterval = 0.0; } -} \ No newline at end of file +} diff --git a/src/OSSupport/Errors.cpp b/src/OSSupport/Errors.cpp index 2e05f1df1..6072b6ac6 100644 --- a/src/OSSupport/Errors.cpp +++ b/src/OSSupport/Errors.cpp @@ -22,7 +22,7 @@ AString GetOSErrorString( int a_ErrNo ) // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r(): - #if ( _GNU_SOURCE ) && !defined(ANDROID_NDK) // GNU version of strerror_r() + #if !defined(__APPLE__) && ( _GNU_SOURCE ) && !defined(ANDROID_NDK) // GNU version of strerror_r() char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); if( res != NULL ) diff --git a/src/World.cpp b/src/World.cpp index 3f157157a..98f6a4b5a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -59,9 +59,10 @@ - +#ifndef __APPLE__ /// Up to this many m_SpreadQueue elements are handled each world tick const int MAX_LIGHTING_SPREAD_PER_TICK = 10; +#endif const int TIME_SUNSET = 12000; const int TIME_NIGHT_START = 13187; -- cgit v1.2.3 From 2e28c09770a937b253680d7f62b9b2f4c8f4670c Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 25 Mar 2014 20:59:33 +0200 Subject: Ender crystals --- src/Entities/EnderCrystal.cpp | 56 +++++++++++++++++++++++++++++++++ src/Entities/EnderCrystal.h | 33 +++++++++++++++++++ src/Entities/Entity.h | 24 +++++++------- src/WorldStorage/NBTChunkSerializer.cpp | 13 ++++++++ src/WorldStorage/NBTChunkSerializer.h | 2 ++ src/WorldStorage/WSSAnvil.cpp | 19 +++++++++++ src/WorldStorage/WSSAnvil.h | 1 + 7 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 src/Entities/EnderCrystal.cpp create mode 100644 src/Entities/EnderCrystal.h diff --git a/src/Entities/EnderCrystal.cpp b/src/Entities/EnderCrystal.cpp new file mode 100644 index 000000000..a640b236c --- /dev/null +++ b/src/Entities/EnderCrystal.cpp @@ -0,0 +1,56 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "EnderCrystal.h" +#include "ClientHandle.h" +#include "Player.h" +#include "../Chunk.h" + + + + + +cEnderCrystal::cEnderCrystal(double a_X, double a_Y, double a_Z) + : cEntity(etEnderCrystal, a_X, a_Y, a_Z, 1.0, 1.0) +{ + SetMaxHealth(5); +} + + + + + +void cEnderCrystal::SpawnOn(cClientHandle & a_ClientHandle) +{ + a_ClientHandle.SendSpawnObject(*this, 51, 0, (Byte)GetYaw(), (Byte)GetPitch()); +} + + + + + +void cEnderCrystal::Tick(float a_Dt, cChunk & a_Chunk) +{ + UNUSED(a_Dt); + + a_Chunk.SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_FIRE, 0); + + // No further processing (physics e.t.c.) is needed +} + + + + + +void cEnderCrystal::KilledBy(cEntity * a_Killer) +{ + super::KilledBy(a_Killer); + + m_World->DoExplosionAt(6.0, GetPosX(), GetPosY(), GetPosZ(), true, esEnderCrystal, this); + + Destroy(); +} + + + + diff --git a/src/Entities/EnderCrystal.h b/src/Entities/EnderCrystal.h new file mode 100644 index 000000000..5b86df987 --- /dev/null +++ b/src/Entities/EnderCrystal.h @@ -0,0 +1,33 @@ + +#pragma once + +#include "Entity.h" + + + + + +// tolua_begin +class cEnderCrystal : + public cEntity +{ + // tolua_end + typedef cEntity super; + +public: + CLASS_PROTODEF(cEnderCrystal); + + cEnderCrystal(double a_X, double a_Y, double a_Z); + +private: + + // cEntity overrides: + virtual void SpawnOn(cClientHandle & a_ClientHandle) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void KilledBy(cEntity * a_Killer) override; + +}; // tolua_export + + + + diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index df80093e5..e41f74b09 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -69,6 +69,7 @@ public: enum eEntityType { etEntity, // For all other types + etEnderCrystal, etPlayer, etPickup, etMonster, @@ -130,18 +131,19 @@ public: eEntityType GetEntityType(void) const { return m_EntityType; } - bool IsPlayer (void) const { return (m_EntityType == etPlayer); } - bool IsPickup (void) const { return (m_EntityType == etPickup); } - bool IsMob (void) const { return (m_EntityType == etMonster); } + bool IsEnderCrystal(void) const { return (m_EntityType == etEnderCrystal); } + bool IsPlayer (void) const { return (m_EntityType == etPlayer); } + bool IsPickup (void) const { return (m_EntityType == etPickup); } + bool IsMob (void) const { return (m_EntityType == etMonster); } bool IsFallingBlock(void) const { return (m_EntityType == etFallingBlock); } - bool IsMinecart (void) const { return (m_EntityType == etMinecart); } - bool IsBoat (void) const { return (m_EntityType == etBoat); } - bool IsTNT (void) const { return (m_EntityType == etTNT); } - bool IsProjectile (void) const { return (m_EntityType == etProjectile); } - bool IsExpOrb (void) const { return (m_EntityType == etExpOrb); } - bool IsFloater (void) const { return (m_EntityType == etFloater); } - bool IsItemFrame (void) const { return (m_EntityType == etItemFrame); } - bool IsPainting (void) const { return (m_EntityType == etPainting); } + bool IsMinecart (void) const { return (m_EntityType == etMinecart); } + bool IsBoat (void) const { return (m_EntityType == etBoat); } + bool IsTNT (void) const { return (m_EntityType == etTNT); } + bool IsProjectile (void) const { return (m_EntityType == etProjectile); } + bool IsExpOrb (void) const { return (m_EntityType == etExpOrb); } + bool IsFloater (void) const { return (m_EntityType == etFloater); } + bool IsItemFrame (void) const { return (m_EntityType == etItemFrame); } + bool IsPainting (void) const { return (m_EntityType == etPainting); } /// Returns true if the entity is of the specified class or a subclass (cPawn's IsA("cEntity") returns true) virtual bool IsA(const char * a_ClassName) const; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index acca96ba8..9a14d7152 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -23,6 +23,7 @@ #include "../BlockEntities/FlowerPotEntity.h" #include "../Entities/Entity.h" +#include "../Entities/EnderCrystal.h" #include "../Entities/FallingBlock.h" #include "../Entities/Boat.h" #include "../Entities/Minecart.h" @@ -335,6 +336,17 @@ void cNBTChunkSerializer::AddBoatEntity(cBoat * a_Boat) +void cNBTChunkSerializer::AddEnderCrystalEntity(cEnderCrystal * a_EnderCrystal) +{ + m_Writer.BeginCompound(""); + AddBasicEntity(a_EnderCrystal, "EnderCrystal"); + m_Writer.EndCompound(); +} + + + + + void cNBTChunkSerializer::AddFallingBlockEntity(cFallingBlock * a_FallingBlock) { m_Writer.BeginCompound(""); @@ -729,6 +741,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) switch (a_Entity->GetEntityType()) { case cEntity::etBoat: AddBoatEntity ((cBoat *) a_Entity); break; + case cEntity::etEnderCrystal: AddEnderCrystalEntity((cEnderCrystal *) a_Entity); break; case cEntity::etFallingBlock: AddFallingBlockEntity((cFallingBlock *) a_Entity); break; case cEntity::etMinecart: AddMinecartEntity ((cMinecart *) a_Entity); break; case cEntity::etMonster: AddMonsterEntity ((cMonster *) a_Entity); break; diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index c1134cd00..51d104970 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -24,6 +24,7 @@ class cChestEntity; class cCommandBlockEntity; class cDispenserEntity; class cDropperEntity; +class cEnderCrystal; class cFurnaceEntity; class cHopperEntity; class cJukeboxEntity; @@ -106,6 +107,7 @@ protected: // Entities: void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName); void AddBoatEntity (cBoat * a_Boat); + void AddEnderCrystalEntity(cEnderCrystal * a_EnderCrystal); void AddFallingBlockEntity(cFallingBlock * a_FallingBlock); void AddMinecartEntity (cMinecart * a_Minecart); void AddMonsterEntity (cMonster * a_Monster); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 7a2366755..1214089a1 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -32,6 +32,7 @@ #include "../Mobs/IncludeAllMonsters.h" #include "../Entities/Boat.h" +#include "../Entities/EnderCrystal.h" #include "../Entities/FallingBlock.h" #include "../Entities/Minecart.h" #include "../Entities/Pickup.h" @@ -1057,6 +1058,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadBoatFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } + else if (strncmp(a_IDTag, "EnderCrystal", a_IDTagLength) == 0) + { + LoadEnderCrystalFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } else if (strncmp(a_IDTag, "FallingBlock", a_IDTagLength) == 0) { LoadFallingBlockFromNBT(a_Entities, a_NBT, a_EntityTagIdx); @@ -1275,6 +1280,20 @@ void cWSSAnvil::LoadBoatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N +void cWSSAnvil::LoadEnderCrystalFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr EnderCrystal(new cEnderCrystal(0, 0, 0)); + if (!LoadEntityBaseFromNBT(*EnderCrystal.get(), a_NBT, a_TagIdx)) + { + return; + } + a_Entities.push_back(EnderCrystal.release()); +} + + + + + void cWSSAnvil::LoadFallingBlockFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "TileID"); diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 50d0e555e..1773ee882 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -148,6 +148,7 @@ protected: void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, int a_IDTagLength); void LoadBoatFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadEnderCrystalFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadFallingBlockFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPickupFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadTNTFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); -- cgit v1.2.3 From f67ad369659307c4148f825cd3e0cdba909ab229 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 24 Mar 2014 08:15:27 +0100 Subject: InfoReg updated for multi-verb console commands. --- MCServer/Plugins/InfoReg.lua | 51 +++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/MCServer/Plugins/InfoReg.lua b/MCServer/Plugins/InfoReg.lua index b3717884a..27e63aa5b 100644 --- a/MCServer/Plugins/InfoReg.lua +++ b/MCServer/Plugins/InfoReg.lua @@ -9,16 +9,30 @@ --- Lists all the subcommands that the player has permissions for local function ListSubcommands(a_Player, a_Subcommands, a_CmdString) - a_Player:SendMessage("The " .. a_CmdString .. " command requires another verb:"); + if (a_Player == nil) then + LOGINFO("The " .. a_CmdString .. " command requires another verb:") + else + a_Player:SendMessage("The " .. a_CmdString .. " command requires another verb:") + end + + -- Enum all the subcommands: local Verbs = {}; for cmd, info in pairs(a_Subcommands) do if (a_Player:HasPermission(info.Permission or "")) then - table.insert(Verbs, a_CmdString .. " " .. cmd); + table.insert(Verbs, " " .. a_CmdString .. " " .. cmd); end end table.sort(Verbs); - for idx, verb in ipairs(Verbs) do - a_Player:SendMessage(verb); + + -- Send the list: + if (a_Player == nil) then + for idx, verb in ipairs(Verbs) do + LOGINFO(verb); + end + else + for idx, verb in ipairs(Verbs) do + a_Player:SendMessage(verb); + end end end @@ -28,6 +42,7 @@ end --- This is a generic command callback used for handling multicommands' parent commands -- For example, if there are "/gal save" and "/gal load" commands, this callback handles the "/gal" command +-- It is used for both console and in-game commands; the console version has a_Player set to nil local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_Level) local Verb = a_Split[a_Level + 1]; if (Verb == nil) then @@ -46,7 +61,11 @@ local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_ if (a_Level > 1) then -- This is a true subcommand, display the message and make MCS think the command was handled -- Otherwise we get weird behavior: for "/cmd verb" we get "unknown command /cmd" although "/cmd" is valid - a_Player:SendMessage("The " .. a_CmdString .. " command doesn't support verb " .. Verb); + if (a_Player == nil) then + LOGWARNING("The " .. a_CmdString .. " command doesn't support verb " .. Verb) + else + a_Player:SendMessage("The " .. a_CmdString .. " command doesn't support verb " .. Verb) + end return true; end -- This is a top-level command, let MCS handle the unknown message @@ -54,9 +73,11 @@ local function MultiCommandHandler(a_Split, a_Player, a_CmdString, a_CmdInfo, a_ end -- Check the permission: - if not(a_Player:HasPermission(Subcommand.Permission or "")) then - a_Player:SendMessage("You don't have permission to execute this command"); - return true; + if (a_Player ~= nil) then + if not(a_Player:HasPermission(Subcommand.Permission or "")) then + a_Player:SendMessage("You don't have permission to execute this command"); + return true; + end end -- If the handler is not valid, check the next sublevel: @@ -149,21 +170,27 @@ end function RegisterPluginInfoConsoleCommands() -- A sub-function that registers all subcommands of a single command, using the command's Subcommands table -- The a_Prefix param already contains the space after the previous command - local function RegisterSubcommands(a_Prefix, a_Subcommands) + local function RegisterSubcommands(a_Prefix, a_Subcommands, a_Level) assert(a_Subcommands ~= nil); for cmd, info in pairs(a_Subcommands) do local CmdName = a_Prefix .. cmd; - cPluginManager.BindConsoleCommand(cmd, info.Handler, info.HelpString or ""); + local Handler = info.Handler + if (Handler == nil) then + Handler = function(a_Split) + return MultiCommandHandler(a_Split, nil, CmdName, info, a_Level); + end + end + cPluginManager.BindConsoleCommand(CmdName, Handler, info.HelpString or ""); -- Recursively register any subcommands: if (info.Subcommands ~= nil) then - RegisterSubcommands(a_Prefix .. cmd .. " ", info.Subcommands); + RegisterSubcommands(a_Prefix .. cmd .. " ", info.Subcommands, a_Level + 1); end end end -- Loop through all commands in the plugin info, register each: - RegisterSubcommands("", g_PluginInfo.ConsoleCommands); + RegisterSubcommands("", g_PluginInfo.ConsoleCommands, 1); end -- cgit v1.2.3 From 0984cf9deb4b60e119adeac56c5d891d2a7cbec6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 21:33:23 +0100 Subject: Added Vector3::Move(const Vector3 &). --- src/Vector3.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Vector3.h b/src/Vector3.h index ba4abe3eb..a00e14508 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -121,6 +121,13 @@ public: z += a_Z; } + inline void Move(const Vector3 & a_Diff) + { + x += a_Diff.x; + y += a_Diff.y; + z += a_Diff.z; + } + // tolua_end inline void operator += (const Vector3 & a_Rhs) -- cgit v1.2.3 From 87e0bd54b426bafb6b267725b0e1a94511a38f4e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 21:59:25 +0100 Subject: BlockArea: Switched internal coords to Vector3i. --- src/BlockArea.cpp | 324 ++++++++++++--------------- src/BlockArea.h | 36 +-- src/Generating/ChunkDesc.cpp | 6 +- src/WorldStorage/SchematicFileSerializer.cpp | 10 +- 4 files changed, 176 insertions(+), 200 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 406e18a3b..692b006d5 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -162,13 +162,6 @@ static void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBB // cBlockArea: cBlockArea::cBlockArea(void) : - m_OriginX(0), - m_OriginY(0), - m_OriginZ(0), - m_SizeX(0), - m_SizeY(0), - m_SizeZ(0), - m_WEOffset(0, 0, 0), m_BlockTypes(NULL), m_BlockMetas(NULL), m_BlockLight(NULL), @@ -195,12 +188,8 @@ void cBlockArea::Clear(void) delete[] m_BlockMetas; m_BlockMetas = NULL; delete[] m_BlockLight; m_BlockLight = NULL; delete[] m_BlockSkyLight; m_BlockSkyLight = NULL; - m_OriginX = 0; - m_OriginY = 0; - m_OriginZ = 0; - m_SizeX = 0; - m_SizeY = 0; - m_SizeZ = 0; + m_Origin.Set(0, 0, 0); + m_Size.Set(0, 0, 0); } @@ -243,12 +232,8 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) m_BlockSkyLight[i] = 0x0f; } } - m_SizeX = a_SizeX; - m_SizeY = a_SizeY; - m_SizeZ = a_SizeZ; - m_OriginX = 0; - m_OriginY = 0; - m_OriginZ = 0; + m_Size.Set(a_SizeX, a_SizeY, a_SizeZ); + m_Origin.Set(0, 0, 0); } @@ -275,9 +260,7 @@ void cBlockArea::SetWEOffset(const Vector3i & a_Offset) void cBlockArea::SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ) { - m_OriginX = a_OriginX; - m_OriginY = a_OriginY; - m_OriginZ = a_OriginZ; + m_Origin.Set(a_OriginX, a_OriginY, a_OriginZ); } @@ -286,7 +269,7 @@ void cBlockArea::SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ) void cBlockArea::SetOrigin(const Vector3i & a_Origin) { - SetOrigin(a_Origin.x, a_Origin.y, a_Origin.z); + m_Origin.Set(a_Origin.x, a_Origin.y, a_Origin.z); } @@ -342,9 +325,7 @@ bool cBlockArea::Read(cForEachChunkProvider * a_ForEachChunkProvider, int a_MinB { return false; } - m_OriginX = a_MinBlockX; - m_OriginY = a_MinBlockY; - m_OriginZ = a_MinBlockZ; + m_Origin.Set(a_MinBlockX, a_MinBlockY, a_MinBlockZ); cChunkReader Reader(*this); // Convert block coords to chunks coords: @@ -408,10 +389,10 @@ bool cBlockArea::Write(cForEachChunkProvider * a_ForEachChunkProvider, int a_Min LOGWARNING("%s: MinBlockY less than zero, adjusting to zero", __FUNCTION__); a_MinBlockY = 0; } - else if (a_MinBlockY > cChunkDef::Height - m_SizeY) + else if (a_MinBlockY > cChunkDef::Height - m_Size.y) { LOGWARNING("%s: MinBlockY + m_SizeY more than chunk height, adjusting to chunk height", __FUNCTION__); - a_MinBlockY = cChunkDef::Height - m_SizeY; + a_MinBlockY = cChunkDef::Height - m_Size.y; } return a_ForEachChunkProvider->WriteBlockArea(*this, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes); @@ -443,10 +424,8 @@ void cBlockArea::CopyTo(cBlockArea & a_Into) const } a_Into.Clear(); - a_Into.SetSize(m_SizeX, m_SizeY, m_SizeZ, GetDataTypes()); - a_Into.m_OriginX = m_OriginX; - a_Into.m_OriginY = m_OriginY; - a_Into.m_OriginZ = m_OriginZ; + a_Into.SetSize(m_Size.x, m_Size.y, m_Size.z, GetDataTypes()); + a_Into.m_Origin = m_Origin; int BlockCount = GetBlockCount(); if (HasBlockTypes()) { @@ -487,9 +466,9 @@ void cBlockArea::DumpToRawFile(const AString & a_FileName) LOGWARNING("cBlockArea: Cannot open file \"%s\" for raw dump", a_FileName.c_str()); return; } - UInt32 SizeX = ntohl(m_SizeX); - UInt32 SizeY = ntohl(m_SizeY); - UInt32 SizeZ = ntohl(m_SizeZ); + UInt32 SizeX = ntohl(m_Size.x); + UInt32 SizeY = ntohl(m_Size.y); + UInt32 SizeZ = ntohl(m_Size.z); f.Write(&SizeX, 4); f.Write(&SizeY, 4); f.Write(&SizeZ, 4); @@ -532,13 +511,13 @@ void cBlockArea::DumpToRawFile(const AString & a_FileName) void cBlockArea::Crop(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ) { if ( - (a_AddMinX + a_SubMaxX >= m_SizeX) || - (a_AddMinY + a_SubMaxY >= m_SizeY) || - (a_AddMinZ + a_SubMaxZ >= m_SizeZ) + (a_AddMinX + a_SubMaxX >= m_Size.x) || + (a_AddMinY + a_SubMaxY >= m_Size.y) || + (a_AddMinZ + a_SubMaxZ >= m_Size.z) ) { LOGWARNING("cBlockArea:Crop called with more croping than the dimensions: %d x %d x %d with cropping %d, %d and %d", - m_SizeX, m_SizeY, m_SizeZ, + m_Size.x, m_Size.y, m_Size.z, a_AddMinX + a_SubMaxX, a_AddMinY + a_SubMaxY, a_AddMinZ + a_SubMaxZ ); return; @@ -560,12 +539,10 @@ void cBlockArea::Crop(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY { CropNibbles(m_BlockSkyLight, a_AddMinX, a_SubMaxX, a_AddMinY, a_SubMaxY, a_AddMinZ, a_SubMaxZ); } - m_OriginX += a_AddMinX; - m_OriginY += a_AddMinY; - m_OriginZ += a_AddMinZ; - m_SizeX -= a_AddMinX + a_SubMaxX; - m_SizeY -= a_AddMinY + a_SubMaxY; - m_SizeZ -= a_AddMinZ + a_SubMaxZ; + m_Origin.Move(a_AddMinX, a_AddMinY, a_AddMinZ); + m_Size.x -= a_AddMinX + a_SubMaxX; + m_Size.y -= a_AddMinY + a_SubMaxY; + m_Size.z -= a_AddMinZ + a_SubMaxZ; } @@ -590,12 +567,10 @@ void cBlockArea::Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMa { ExpandNibbles(m_BlockSkyLight, a_SubMinX, a_AddMaxX, a_SubMinY, a_AddMaxY, a_SubMinZ, a_AddMaxZ); } - m_OriginX -= a_SubMinX; - m_OriginY -= a_SubMinY; - m_OriginZ -= a_SubMinZ; - m_SizeX += a_SubMinX + a_AddMaxX; - m_SizeY += a_SubMinY + a_AddMaxY; - m_SizeZ += a_SubMinZ + a_AddMaxZ; + m_Origin.Move(-a_SubMinX, -a_SubMinY, -a_SubMinZ); + m_Size.x += a_SubMinX + a_AddMaxX; + m_Size.y += a_SubMinY + a_AddMaxY; + m_Size.z += a_SubMinZ + a_AddMaxZ; } @@ -645,7 +620,7 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), - m_SizeX, m_SizeY, m_SizeZ, + m_Size.x, m_Size.y, m_Size.z, MergeCombinatorOverwrite ); break; @@ -660,7 +635,7 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), - m_SizeX, m_SizeY, m_SizeZ, + m_Size.x, m_Size.y, m_Size.z, MergeCombinatorFillAir ); break; @@ -675,7 +650,7 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), - m_SizeX, m_SizeY, m_SizeZ, + m_Size.x, m_Size.y, m_Size.z, MergeCombinatorImprint ); break; @@ -690,7 +665,7 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), - m_SizeX, m_SizeY, m_SizeZ, + m_Size.x, m_Size.y, m_Size.z, MergeCombinatorLake ); break; @@ -982,17 +957,17 @@ void cBlockArea::RotateCCW(void) } // We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time: - BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ]; - NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int x = 0; x < m_SizeX; x++) + BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; + NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; + for (int x = 0; x < m_Size.x; x++) { - int NewZ = m_SizeX - x - 1; - for (int z = 0; z < m_SizeZ; z++) + int NewZ = m_Size.x - x - 1; + for (int z = 0; z < m_Size.z; z++) { int NewX = z; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - int NewIdx = NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ; + int NewIdx = NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z; int OldIdx = MakeIndex(x, y, z); NewTypes[NewIdx] = m_BlockTypes[OldIdx]; NewMetas[NewIdx] = BlockHandler(m_BlockTypes[OldIdx])->MetaRotateCCW(m_BlockMetas[OldIdx]); @@ -1004,7 +979,7 @@ void cBlockArea::RotateCCW(void) delete[] NewTypes; delete[] NewMetas; - std::swap(m_SizeX, m_SizeZ); + std::swap(m_Size.x, m_Size.z); } @@ -1027,17 +1002,17 @@ void cBlockArea::RotateCW(void) } // We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time: - BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ]; - NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int x = 0; x < m_SizeX; x++) + BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; + NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; + for (int x = 0; x < m_Size.x; x++) { int NewZ = x; - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { - int NewX = m_SizeZ - z - 1; - for (int y = 0; y < m_SizeY; y++) + int NewX = m_Size.z - z - 1; + for (int y = 0; y < m_Size.y; y++) { - int NewIdx = NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ; + int NewIdx = NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z; int OldIdx = MakeIndex(x, y, z); NewTypes[NewIdx] = m_BlockTypes[OldIdx]; NewMetas[NewIdx] = BlockHandler(m_BlockTypes[OldIdx])->MetaRotateCW(m_BlockMetas[OldIdx]); @@ -1049,7 +1024,7 @@ void cBlockArea::RotateCW(void) delete[] NewTypes; delete[] NewMetas; - std::swap(m_SizeX, m_SizeZ); + std::swap(m_Size.x, m_Size.z); } @@ -1072,13 +1047,13 @@ void cBlockArea::MirrorXY(void) } // We are guaranteed that both blocktypes and blockmetas exist; mirror both at the same time: - int HalfZ = m_SizeZ / 2; - int MaxZ = m_SizeZ - 1; - for (int y = 0; y < m_SizeY; y++) + int HalfZ = m_Size.z / 2; + int MaxZ = m_Size.z - 1; + for (int y = 0; y < m_Size.y; y++) { for (int z = 0; z < HalfZ; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { int Idx1 = MakeIndex(x, y, z); int Idx2 = MakeIndex(x, y, MaxZ - z); @@ -1112,13 +1087,13 @@ void cBlockArea::MirrorXZ(void) } // We are guaranteed that both blocktypes and blockmetas exist; mirror both at the same time: - int HalfY = m_SizeY / 2; - int MaxY = m_SizeY - 1; + int HalfY = m_Size.y / 2; + int MaxY = m_Size.y - 1; for (int y = 0; y < HalfY; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { int Idx1 = MakeIndex(x, y, z); int Idx2 = MakeIndex(x, MaxY - y, z); @@ -1152,11 +1127,11 @@ void cBlockArea::MirrorYZ(void) } // We are guaranteed that both blocktypes and blockmetas exist; mirror both at the same time: - int HalfX = m_SizeX / 2; - int MaxX = m_SizeX - 1; - for (int y = 0; y < m_SizeY; y++) + int HalfX = m_Size.x / 2; + int MaxX = m_Size.x - 1; + for (int y = 0; y < m_Size.y; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { for (int x = 0; x < HalfX; x++) { @@ -1180,16 +1155,16 @@ void cBlockArea::RotateCCWNoMeta(void) { if (HasBlockTypes()) { - BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int x = 0; x < m_SizeX; x++) + BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; + for (int x = 0; x < m_Size.x; x++) { - int NewZ = m_SizeX - x - 1; - for (int z = 0; z < m_SizeZ; z++) + int NewZ = m_Size.x - x - 1; + for (int z = 0; z < m_Size.z; z++) { int NewX = z; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - NewTypes[NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ] = m_BlockTypes[MakeIndex(x, y, z)]; + NewTypes[NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z] = m_BlockTypes[MakeIndex(x, y, z)]; } // for y } // for z } // for x @@ -1198,23 +1173,23 @@ void cBlockArea::RotateCCWNoMeta(void) } if (HasBlockMetas()) { - NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int x = 0; x < m_SizeX; x++) + NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; + for (int x = 0; x < m_Size.x; x++) { - int NewZ = m_SizeX - x - 1; - for (int z = 0; z < m_SizeZ; z++) + int NewZ = m_Size.x - x - 1; + for (int z = 0; z < m_Size.z; z++) { int NewX = z; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - NewMetas[NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ] = m_BlockMetas[MakeIndex(x, y, z)]; + NewMetas[NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z] = m_BlockMetas[MakeIndex(x, y, z)]; } // for y } // for z } // for x std::swap(m_BlockMetas, NewMetas); delete[] NewMetas; } - std::swap(m_SizeX, m_SizeZ); + std::swap(m_Size.x, m_Size.z); } @@ -1225,16 +1200,16 @@ void cBlockArea::RotateCWNoMeta(void) { if (HasBlockTypes()) { - BLOCKTYPE * NewTypes = new BLOCKTYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int z = 0; z < m_SizeZ; z++) + BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; + for (int z = 0; z < m_Size.z; z++) { - int NewX = m_SizeZ - z - 1; - for (int x = 0; x < m_SizeX; x++) + int NewX = m_Size.z - z - 1; + for (int x = 0; x < m_Size.x; x++) { int NewZ = x; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - NewTypes[NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ] = m_BlockTypes[MakeIndex(x, y, z)]; + NewTypes[NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z] = m_BlockTypes[MakeIndex(x, y, z)]; } // for y } // for x } // for z @@ -1243,23 +1218,23 @@ void cBlockArea::RotateCWNoMeta(void) } if (HasBlockMetas()) { - NIBBLETYPE * NewMetas = new NIBBLETYPE[m_SizeX * m_SizeY * m_SizeZ]; - for (int z = 0; z < m_SizeZ; z++) + NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; + for (int z = 0; z < m_Size.z; z++) { - int NewX = m_SizeZ - z - 1; - for (int x = 0; x < m_SizeX; x++) + int NewX = m_Size.z - z - 1; + for (int x = 0; x < m_Size.x; x++) { int NewZ = x; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - NewMetas[NewX + NewZ * m_SizeZ + y * m_SizeX * m_SizeZ] = m_BlockMetas[MakeIndex(x, y, z)]; + NewMetas[NewX + NewZ * m_Size.z + y * m_Size.x * m_Size.z] = m_BlockMetas[MakeIndex(x, y, z)]; } // for y } // for x } // for z std::swap(m_BlockMetas, NewMetas); delete[] NewMetas; } - std::swap(m_SizeX, m_SizeZ); + std::swap(m_Size.x, m_Size.z); } @@ -1268,15 +1243,15 @@ void cBlockArea::RotateCWNoMeta(void) void cBlockArea::MirrorXYNoMeta(void) { - int HalfZ = m_SizeZ / 2; - int MaxZ = m_SizeZ - 1; + int HalfZ = m_Size.z / 2; + int MaxZ = m_Size.z - 1; if (HasBlockTypes()) { - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { for (int z = 0; z < HalfZ; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { std::swap(m_BlockTypes[MakeIndex(x, y, z)], m_BlockTypes[MakeIndex(x, y, MaxZ - z)]); } // for x @@ -1286,11 +1261,11 @@ void cBlockArea::MirrorXYNoMeta(void) if (HasBlockMetas()) { - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { for (int z = 0; z < HalfZ; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { std::swap(m_BlockMetas[MakeIndex(x, y, z)], m_BlockMetas[MakeIndex(x, y, MaxZ - z)]); } // for x @@ -1305,15 +1280,15 @@ void cBlockArea::MirrorXYNoMeta(void) void cBlockArea::MirrorXZNoMeta(void) { - int HalfY = m_SizeY / 2; - int MaxY = m_SizeY - 1; + int HalfY = m_Size.y / 2; + int MaxY = m_Size.y - 1; if (HasBlockTypes()) { for (int y = 0; y < HalfY; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { std::swap(m_BlockTypes[MakeIndex(x, y, z)], m_BlockTypes[MakeIndex(x, MaxY - y, z)]); } // for x @@ -1325,9 +1300,9 @@ void cBlockArea::MirrorXZNoMeta(void) { for (int y = 0; y < HalfY; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { std::swap(m_BlockMetas[MakeIndex(x, y, z)], m_BlockMetas[MakeIndex(x, MaxY - y, z)]); } // for x @@ -1342,13 +1317,13 @@ void cBlockArea::MirrorXZNoMeta(void) void cBlockArea::MirrorYZNoMeta(void) { - int HalfX = m_SizeX / 2; - int MaxX = m_SizeX - 1; + int HalfX = m_Size.x / 2; + int MaxX = m_Size.x - 1; if (HasBlockTypes()) { - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { for (int x = 0; x < HalfX; x++) { @@ -1360,9 +1335,9 @@ void cBlockArea::MirrorYZNoMeta(void) if (HasBlockMetas()) { - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - for (int z = 0; z < m_SizeZ; z++) + for (int z = 0; z < m_Size.z; z++) { for (int x = 0; x < HalfX; x++) { @@ -1393,7 +1368,7 @@ void cBlockArea::SetRelBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a void cBlockArea::SetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType) { - SetRelBlockType(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_BlockType); + SetRelBlockType(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_BlockType); } @@ -1470,7 +1445,7 @@ BLOCKTYPE cBlockArea::GetRelBlockType(int a_RelX, int a_RelY, int a_RelZ) const BLOCKTYPE cBlockArea::GetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ) const { - return GetRelBlockType(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ); + return GetRelBlockType(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z); } @@ -1533,7 +1508,7 @@ NIBBLETYPE cBlockArea::GetBlockSkyLight(int a_BlockX, int a_BlockY, int a_BlockZ void cBlockArea::SetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - SetRelBlockTypeMeta(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_BlockType, a_BlockMeta); + SetRelBlockTypeMeta(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_BlockType, a_BlockMeta); } @@ -1567,7 +1542,7 @@ void cBlockArea::SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, B void cBlockArea::GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const { - return GetRelBlockTypeMeta(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_BlockType, a_BlockMeta); + return GetRelBlockTypeMeta(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_BlockType, a_BlockMeta); } @@ -1670,9 +1645,7 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) return false; } } - m_SizeX = a_SizeX; - m_SizeY = a_SizeY; - m_SizeZ = a_SizeZ; + m_Size.Set(a_SizeX, a_SizeY, a_SizeZ); return true; } @@ -1683,13 +1656,13 @@ bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) int cBlockArea::MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const { ASSERT(a_RelX >= 0); - ASSERT(a_RelX < m_SizeX); + ASSERT(a_RelX < m_Size.x); ASSERT(a_RelY >= 0); - ASSERT(a_RelY < m_SizeY); + ASSERT(a_RelY < m_Size.y); ASSERT(a_RelZ >= 0); - ASSERT(a_RelZ < m_SizeZ); + ASSERT(a_RelZ < m_Size.z); - return a_RelX + a_RelZ * m_SizeX + a_RelY * m_SizeX * m_SizeZ; + return a_RelX + a_RelZ * m_Size.x + a_RelY * m_Size.x * m_Size.z; } @@ -1712,7 +1685,7 @@ void cBlockArea::SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_V void cBlockArea::SetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array) { - SetRelNibble(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_Value, a_Array); + SetRelNibble(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_Value, a_Array); } @@ -1735,7 +1708,7 @@ NIBBLETYPE cBlockArea::GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETY NIBBLETYPE cBlockArea::GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE * a_Array) const { - return GetRelNibble(a_BlockX - m_OriginX, a_BlockY - m_OriginY, a_BlockZ - m_OriginZ, a_Array); + return GetRelNibble(a_BlockX - m_Origin.x, a_BlockY - m_Origin.y, a_BlockZ - m_Origin.z, a_Array); } @@ -1748,9 +1721,7 @@ NIBBLETYPE cBlockArea::GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBL cBlockArea::cChunkReader::cChunkReader(cBlockArea & a_Area) : m_Area(a_Area), - m_OriginX(a_Area.m_OriginX), - m_OriginY(a_Area.m_OriginY), - m_OriginZ(a_Area.m_OriginZ) + m_Origin(a_Area.m_Origin.x, a_Area.m_Origin.y, a_Area.m_Origin.z) { } @@ -1760,8 +1731,8 @@ cBlockArea::cChunkReader::cChunkReader(cBlockArea & a_Area) : void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLETYPE * a_ChunkSrc) { - int SizeY = m_Area.m_SizeY; - int MinY = m_OriginY; + int SizeY = m_Area.m_Size.y; + int MinY = m_Origin.y; // SizeX, SizeZ are the dmensions of the block data to copy from the current chunk (size of the geometric union) // OffX, OffZ are the offsets of the current chunk data from the area origin @@ -1770,7 +1741,7 @@ void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLET int SizeZ = cChunkDef::Width; int OffX, OffZ; int BaseX, BaseZ; - OffX = m_CurrentChunkX * cChunkDef::Width - m_OriginX; + OffX = m_CurrentChunkX * cChunkDef::Width - m_Origin.x; if (OffX < 0) { BaseX = -OffX; @@ -1781,7 +1752,7 @@ void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLET { BaseX = 0; } - OffZ = m_CurrentChunkZ * cChunkDef::Width - m_OriginZ; + OffZ = m_CurrentChunkZ * cChunkDef::Width - m_Origin.z; if (OffZ < 0) { BaseZ = -OffZ; @@ -1793,13 +1764,13 @@ void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLET BaseZ = 0; } // If the chunk extends beyond the area in the X or Z axis, cut off the Size: - if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_OriginX + m_Area.m_SizeX) + if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_Origin.x + m_Area.m_Size.x) { - SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_OriginX + m_Area.m_SizeX); + SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_Origin.x + m_Area.m_Size.x); } - if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_OriginZ + m_Area.m_SizeZ) + if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_Origin.z + m_Area.m_Size.z) { - SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_OriginZ + m_Area.m_SizeZ); + SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_Origin.z + m_Area.m_Size.z); } for (int y = 0; y < SizeY; y++) @@ -1843,8 +1814,8 @@ void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) return; } - int SizeY = m_Area.m_SizeY; - int MinY = m_OriginY; + int SizeY = m_Area.m_Size.y; + int MinY = m_Origin.y; // SizeX, SizeZ are the dmensions of the block data to copy from the current chunk (size of the geometric union) // OffX, OffZ are the offsets of the current chunk data from the area origin @@ -1853,7 +1824,7 @@ void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) int SizeZ = cChunkDef::Width; int OffX, OffZ; int BaseX, BaseZ; - OffX = m_CurrentChunkX * cChunkDef::Width - m_OriginX; + OffX = m_CurrentChunkX * cChunkDef::Width - m_Origin.x; if (OffX < 0) { BaseX = -OffX; @@ -1864,7 +1835,7 @@ void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) { BaseX = 0; } - OffZ = m_CurrentChunkZ * cChunkDef::Width - m_OriginZ; + OffZ = m_CurrentChunkZ * cChunkDef::Width - m_Origin.z; if (OffZ < 0) { BaseZ = -OffZ; @@ -1876,13 +1847,13 @@ void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) BaseZ = 0; } // If the chunk extends beyond the area in the X or Z axis, cut off the Size: - if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_OriginX + m_Area.m_SizeX) + if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_Origin.x + m_Area.m_Size.x) { - SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_OriginX + m_Area.m_SizeX); + SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_Origin.x + m_Area.m_Size.x); } - if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_OriginZ + m_Area.m_SizeZ) + if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_Origin.z + m_Area.m_Size.z) { - SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_OriginZ + m_Area.m_SizeZ); + SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_Origin.z + m_Area.m_Size.z); } for (int y = 0; y < SizeY; y++) @@ -2002,21 +1973,21 @@ void cBlockArea::CropNibbles(NIBBLEARRAY & a_Array, int a_AddMinX, int a_SubMaxX void cBlockArea::ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ) { - int NewSizeX = m_SizeX + a_SubMinX + a_AddMaxX; - int NewSizeY = m_SizeY + a_SubMinY + a_AddMaxY; - int NewSizeZ = m_SizeZ + a_SubMinZ + a_AddMaxZ; + int NewSizeX = m_Size.x + a_SubMinX + a_AddMaxX; + int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY; + int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ; int BlockCount = NewSizeX * NewSizeY * NewSizeZ; BLOCKTYPE * NewBlockTypes = new BLOCKTYPE[BlockCount]; memset(NewBlockTypes, 0, BlockCount * sizeof(BLOCKTYPE)); int OldIndex = 0; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - int IndexBaseY = (y + a_SubMinY) * m_SizeX * m_SizeZ; - for (int z = 0; z < m_SizeZ; z++) + int IndexBaseY = (y + a_SubMinY) * m_Size.x * m_Size.z; + for (int z = 0; z < m_Size.z; z++) { - int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) * m_SizeX; + int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) * m_Size.x; int idx = IndexBaseZ + a_SubMinX; - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { NewBlockTypes[idx++] = m_BlockTypes[OldIndex++]; } // for x @@ -2032,21 +2003,21 @@ void cBlockArea::ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, i void cBlockArea::ExpandNibbles(NIBBLEARRAY & a_Array, int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ) { - int NewSizeX = m_SizeX + a_SubMinX + a_AddMaxX; - int NewSizeY = m_SizeY + a_SubMinY + a_AddMaxY; - int NewSizeZ = m_SizeZ + a_SubMinZ + a_AddMaxZ; + int NewSizeX = m_Size.x + a_SubMinX + a_AddMaxX; + int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY; + int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ; int BlockCount = NewSizeX * NewSizeY * NewSizeZ; NIBBLETYPE * NewNibbles = new NIBBLETYPE[BlockCount]; memset(NewNibbles, 0, BlockCount * sizeof(NIBBLETYPE)); int OldIndex = 0; - for (int y = 0; y < m_SizeY; y++) + for (int y = 0; y < m_Size.y; y++) { - int IndexBaseY = (y + a_SubMinY) * m_SizeX * m_SizeZ; - for (int z = 0; z < m_SizeZ; z++) + int IndexBaseY = (y + a_SubMinY) * m_Size.x * m_Size.z; + for (int z = 0; z < m_Size.z; z++) { - int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) * m_SizeX; + int IndexBaseZ = IndexBaseY + (z + a_SubMinZ) * m_Size.x; int idx = IndexBaseZ + a_SubMinX; - for (int x = 0; x < m_SizeX; x++) + for (int x = 0; x < m_Size.x; x++) { NewNibbles[idx++] = a_Array[OldIndex++]; } // for x @@ -2057,6 +2028,9 @@ void cBlockArea::ExpandNibbles(NIBBLEARRAY & a_Array, int a_SubMinX, int a_AddMa } + + + void cBlockArea::RelSetData( int a_RelX, int a_RelY, int a_RelZ, int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, diff --git a/src/BlockArea.h b/src/BlockArea.h index e0e8fe972..22d55e2c9 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -43,6 +43,8 @@ public: baSkyLight = 8, } ; + /** The per-block strategy to use when merging another block area into this object. + See the Merge function for the description of these */ enum eMergeStrategy { msOverwrite, @@ -232,18 +234,24 @@ public: void GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; void GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; + // GetSize() is already exported manually to return 3 numbers, can't auto-export + const Vector3i & GetSize(void) const { return m_Size; } + + // GetOrigin() is already exported manually to return 3 numbers, can't auto-export + const Vector3i & GetOrigin(void) const { return m_Origin; } + // tolua_begin - int GetSizeX(void) const { return m_SizeX; } - int GetSizeY(void) const { return m_SizeY; } - int GetSizeZ(void) const { return m_SizeZ; } + int GetSizeX(void) const { return m_Size.x; } + int GetSizeY(void) const { return m_Size.y; } + int GetSizeZ(void) const { return m_Size.z; } /** Returns the volume of the area, as number of blocks */ - int GetVolume(void) const { return m_SizeX * m_SizeY * m_SizeZ; } + int GetVolume(void) const { return m_Size.x * m_Size.y * m_Size.z; } - int GetOriginX(void) const { return m_OriginX; } - int GetOriginY(void) const { return m_OriginY; } - int GetOriginZ(void) const { return m_OriginZ; } + int GetOriginX(void) const { return m_Origin.x; } + int GetOriginY(void) const { return m_Origin.y; } + int GetOriginZ(void) const { return m_Origin.z; } /** Returns the datatypes that are stored in the object (bitmask of baXXX values) */ int GetDataTypes(void) const; @@ -261,7 +269,7 @@ public: NIBBLETYPE * GetBlockMetas (void) const { return m_BlockMetas; } // NOTE: one byte per block! NIBBLETYPE * GetBlockLight (void) const { return m_BlockLight; } // NOTE: one byte per block! NIBBLETYPE * GetBlockSkyLight(void) const { return m_BlockSkyLight; } // NOTE: one byte per block! - int GetBlockCount(void) const { return m_SizeX * m_SizeY * m_SizeZ; } + int GetBlockCount(void) const { return m_Size.x * m_Size.y * m_Size.z; } int MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const; protected: @@ -276,9 +284,7 @@ protected: protected: cBlockArea & m_Area; - int m_OriginX; - int m_OriginY; - int m_OriginZ; + Vector3i m_Origin; int m_CurrentChunkX; int m_CurrentChunkZ; @@ -295,12 +301,8 @@ protected: typedef NIBBLETYPE * NIBBLEARRAY; - int m_OriginX; - int m_OriginY; - int m_OriginZ; - int m_SizeX; - int m_SizeY; - int m_SizeZ; + Vector3i m_Origin; + Vector3i m_Size; /** An extra data value sometimes stored in the .schematic file. Used mainly by the WorldEdit plugin. cBlockArea doesn't use this value in any way. */ diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index 308fbe423..7711723fc 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -343,9 +343,9 @@ void cChunkDesc::ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX int SizeY = a_MaxRelY - a_MinRelY; int SizeZ = a_MaxRelZ - a_MinRelZ; a_Dest.Clear(); - a_Dest.m_OriginX = m_ChunkX * cChunkDef::Width + a_MinRelX; - a_Dest.m_OriginY = a_MinRelY; - a_Dest.m_OriginZ = m_ChunkZ * cChunkDef::Width + a_MinRelZ; + a_Dest.m_Origin.x = m_ChunkX * cChunkDef::Width + a_MinRelX; + a_Dest.m_Origin.y = a_MinRelY; + a_Dest.m_Origin.z = m_ChunkZ * cChunkDef::Width + a_MinRelZ; a_Dest.SetSize(SizeX, SizeY, SizeZ, cBlockArea::baTypes | cBlockArea::baMetas); for (int y = 0; y < SizeY; y++) diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index ef67fdb13..d8531d965 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -197,7 +197,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP } // Copy the block types and metas: - int NumBytes = a_BlockArea.m_SizeX * a_BlockArea.m_SizeY * a_BlockArea.m_SizeZ; + int NumBytes = a_BlockArea.GetBlockCount(); if (a_NBT.GetDataLength(TBlockTypes) < NumBytes) { LOG("BlockTypes truncated in the schematic file (exp %d, got %d bytes). Loading partial.", @@ -209,7 +209,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP if (AreMetasPresent) { - int NumBytes = a_BlockArea.m_SizeX * a_BlockArea.m_SizeY * a_BlockArea.m_SizeZ; + int NumBytes = a_BlockArea.GetBlockCount(); if (a_NBT.GetDataLength(TBlockMetas) < NumBytes) { LOG("BlockMetas truncated in the schematic file (exp %d, got %d bytes). Loading partial.", @@ -230,9 +230,9 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockArea) { cFastNBTWriter Writer("Schematic"); - Writer.AddShort("Width", a_BlockArea.m_SizeX); - Writer.AddShort("Height", a_BlockArea.m_SizeY); - Writer.AddShort("Length", a_BlockArea.m_SizeZ); + Writer.AddShort("Width", a_BlockArea.m_Size.x); + Writer.AddShort("Height", a_BlockArea.m_Size.y); + Writer.AddShort("Length", a_BlockArea.m_Size.z); Writer.AddString("Materials", "Alpha"); if (a_BlockArea.HasBlockTypes()) { -- cgit v1.2.3 From 87de5960785e0e007eaee0a8dbb77c64e20e7c8c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 22:05:45 +0100 Subject: BlockArea: Create() can take the size as Vector3i, too. --- src/BlockArea.cpp | 9 +++++++++ src/BlockArea.h | 10 ++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 692b006d5..f6d54e41c 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -240,6 +240,15 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) +void cBlockArea::Create(const Vector3i & a_Size, int a_DataTypes) +{ + Create(a_Size.x, a_Size.y, a_Size.z, a_DataTypes); +} + + + + + void cBlockArea::SetWEOffset(int a_OffsetX, int a_OffsetY, int a_OffsetZ) { m_WEOffset.Set(a_OffsetX, a_OffsetY, a_OffsetZ); diff --git a/src/BlockArea.h b/src/BlockArea.h index 22d55e2c9..d28325d7d 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -59,12 +59,18 @@ public: /** Clears the data stored to reclaim memory */ void Clear(void); - /** Creates a new area of the specified size and contents. - Origin is set to all zeroes. + /** Creates a new area of the specified size and contents. + Origin is set to all zeroes. BlockTypes are set to air, block metas to zero, blocklights to zero and skylights to full light. */ void Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes = baTypes | baMetas); + /** Creates a new area of the specified size and contents. + Origin is set to all zeroes. + BlockTypes are set to air, block metas to zero, blocklights to zero and skylights to full light. + */ + void Create(const Vector3i & a_Size, int a_DataTypes = baTypes | baMetas); + /** Resets the origin. No other changes are made, contents are untouched. */ void SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ); -- cgit v1.2.3 From 37778e5f82f02eb417642390a36587a970e5479c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 22:10:53 +0100 Subject: Added a basic cPrefab class. Can be defined in the source by GalExport's cpp output. --- src/Generating/Prefab.cpp | 139 ++++++++++++++++++++++++++++++++++++++++++++++ src/Generating/Prefab.h | 83 +++++++++++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 src/Generating/Prefab.cpp create mode 100644 src/Generating/Prefab.h diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp new file mode 100644 index 000000000..824800119 --- /dev/null +++ b/src/Generating/Prefab.cpp @@ -0,0 +1,139 @@ + +// Prefab.cpp + +/* +Implements the cPrefab class, representing a cPiece descendant for the cPieceGenerator that +uses a prefabricate in a cBlockArea for drawing itself. +*/ + +#include "Globals.h" +#include "Prefab.h" +#include "../WorldStorage/SchematicFileSerializer.h" + + + + + +cPrefab::cPrefab(const cPrefab::sDef & a_Def) : + m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), + m_HitBox(0, 0, 0, a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), + m_AllowedRotations(7), // TODO: All rotations allowed (not in the definition yet) + m_MergeStrategy(cBlockArea::msImprint) +{ + m_BlockArea.Create(m_Size); + CharMap cm; + ParseCharMap(cm, a_Def.m_CharMap); + ParseBlockImage(cm, a_Def.m_Image); +} + + + + + +void cPrefab::Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement) +{ + Vector3i Placement = a_Placement->GetCoords(); + Placement.Move(a_Dest.GetOrigin() * (-1)); + a_Dest.Merge(m_BlockArea, Placement, m_MergeStrategy); + +} + + + + + +void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) +{ + // Initialize the charmap to all-invalid values: + for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) + { + a_CharMapOut[i] = -1; + } + + // Process the lines in the definition: + AStringVector Lines = StringSplitAndTrim(a_CharMapDef, "\n"); + for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) + { + AStringVector CharDef = StringSplitAndTrim(*itr, ":"); + size_t NumElements = CharDef.size(); + if ((NumElements < 2) || CharDef[0].empty() || CharDef[1].empty()) + { + LOGWARNING("Bad prefab CharMap definition line: \"%s\", skipping.", itr->c_str()); + continue; + } + unsigned char Src = (unsigned char)CharDef[0][0]; + BLOCKTYPE BlockType = (BLOCKTYPE)atoi(CharDef[1].c_str()); + NIBBLETYPE BlockMeta = 0; + if ((NumElements >= 3) && !CharDef[2].empty()) + { + BlockMeta = (NIBBLETYPE)atoi(CharDef[2].c_str()); + ASSERT((BlockMeta >= 0) && (BlockMeta <= 15)); + } + ASSERT(a_CharMapOut[Src] == -1); // Any duplicates letter-wise? + a_CharMapOut[Src] = (BlockType << 4) | BlockMeta; + } // for itr - Lines[] +} + + + + + +void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage) +{ + // Map each letter in the a_BlockImage (from the in-source definition) to real blocktype / blockmeta: + for (int y = 0; y < m_Size.y; y++) + { + for (int z = 0; z < m_Size.z; z++) + { + const unsigned char * BlockImage = (const unsigned char *)a_BlockImage + y * m_Size.x * m_Size.z + z * m_Size.x; + for (int x = 0; x < m_Size.x; x++) + { + int MappedValue = a_CharMap[BlockImage[x]]; + ASSERT(MappedValue != -1); // Using a letter not defined in the CharMap? + BLOCKTYPE BlockType = MappedValue >> 4; + NIBBLETYPE BlockMeta = MappedValue & 0x0f; + m_BlockArea.SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta); + } + } + } +} + + + + + +cPiece::cConnectors cPrefab::GetConnectors(void) const +{ + return m_Connectors; +} + + + + + +Vector3i cPrefab::GetSize(void) const +{ + return m_Size; +} + + + + + +cCuboid cPrefab::GetHitBox(void) const +{ + return m_HitBox; +} + + + + + +bool cPrefab::CanRotateCCW(int a_NumRotations) const +{ + return ((m_AllowedRotations & (1 << (a_NumRotations % 4))) != 0); +} + + + + diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h new file mode 100644 index 000000000..6596b906b --- /dev/null +++ b/src/Generating/Prefab.h @@ -0,0 +1,83 @@ + +// Prefab.h + +/* +Declares the cPrefab class, representing a cPiece descendant for the cPieceGenerator that +uses a prefabricate in a cBlockArea for drawing itself. +The class can be constructed from data that is stored directly in the executable, in a sPrefabDef structure +declared in this file as well; the Gallery server exports areas in this format. +*/ + + + + + +#pragma once + +#include "PieceGenerator.h" +#include "../BlockArea.h" + + + + + + +class cPrefab : + public cPiece +{ +public: + struct sDef + { + int m_SizeX; + int m_SizeY; + int m_SizeZ; + const char * m_CharMap; + const char * m_Image; + // TODO: Connectors + }; + + cPrefab(const sDef & a_Def); + + /** Draws the prefab into the specified block area, according to the placement stored in the PlacedPiece. */ + void Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement); + +protected: + /** Maps letters in the sDef::m_Image onto a number, BlockType * 16 | BlockMeta */ + typedef int CharMap[256]; + + + /** The cBlockArea that contains the block definitions for the prefab */ + cBlockArea m_BlockArea; + + /** The size of the prefab */ + Vector3i m_Size; + + /** The hitbox of the prefab. In first version is the same as the m_BlockArea dimensions */ + cCuboid m_HitBox; + + /** The connectors through which the piece connects to other pieces */ + cConnectors m_Connectors; + + /** Bitmask, bit N set -> N rotations CCW supported */ + int m_AllowedRotations; + + /** The merge strategy to use when drawing the prefab into a block area */ + cBlockArea::eMergeStrategy m_MergeStrategy; + + + // cPiece overrides: + virtual cConnectors GetConnectors(void) const override; + virtual Vector3i GetSize(void) const override; + virtual cCuboid GetHitBox(void) const override; + virtual bool CanRotateCCW(int a_NumRotations) const override; + + /** Parses the CharMap in the definition into a CharMap binary data used for translating the definition into BlockArea. */ + void ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef); + + /** Parses the Image in the definition into m_BlockArea's block types and metas, using the specified CharMap. */ + void ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage); +}; + + + + -- cgit v1.2.3 From e1285eb84f357c3111f5c7382c94bccc7068c660 Mon Sep 17 00:00:00 2001 From: narroo Date: Tue, 25 Mar 2014 17:17:05 -0400 Subject: Changed Rotater to Rotator. Added partial sign post rotation support. --- src/Blocks/BlockSign.h | 12 +++++ src/Blocks/MetaRotater.h | 120 ----------------------------------------------- src/Blocks/MetaRotator.h | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 120 deletions(-) delete mode 100644 src/Blocks/MetaRotater.h create mode 100644 src/Blocks/MetaRotator.h diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h index cd0c02a40..82d9a2fcc 100644 --- a/src/Blocks/BlockSign.h +++ b/src/Blocks/BlockSign.h @@ -71,6 +71,18 @@ public: { a_Player->GetClientHandle()->SendEditSign(a_BlockX, a_BlockY, a_BlockZ); } + + + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override + { + return ++a_Meta; + } + + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override + { + return --a_Meta; + } } ; diff --git a/src/Blocks/MetaRotater.h b/src/Blocks/MetaRotater.h deleted file mode 100644 index dde88e6db..000000000 --- a/src/Blocks/MetaRotater.h +++ /dev/null @@ -1,120 +0,0 @@ -// MetaRotater.h - -// Provides a mixin for rotations and reflections - -#pragma once - -// MSVC generates warnings for the templated AssertIfNotMatched parameter conditions, so disable it: -#ifdef _MSC_VER - #pragma warning(disable: 4127) // Conditional expression is constant -#endif - - - - - -/* -Provides a mixin for rotations and reflections following the standard pattern of apply mask then use case. - -Usage: -Inherit from this class providing your base class as Base, the BitMask for the direction bits in bitmask and the masked value for the directions in North, East, South, West. There is also an aptional parameter AssertIfNotMatched. Set this if it is invalid for a block to exist in any other state. -*/ - -template -class cMetaRotater : public Base -{ -public: - - cMetaRotater(BLOCKTYPE a_BlockType) : - Base(a_BlockType) - {} - - virtual ~cMetaRotater() {} - - virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; - virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; - virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override; - virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override; -}; - - - - - -template -NIBBLETYPE cMetaRotater::MetaRotateCW(NIBBLETYPE a_Meta) -{ - NIBBLETYPE OtherMeta = a_Meta & (~BitMask); - switch (a_Meta & BitMask) - { - case South: return West | OtherMeta; - case West: return North | OtherMeta; - case North: return East | OtherMeta; - case East: return South | OtherMeta; - } - if (AssertIfNotMatched) - { - ASSERT(!"Invalid Meta value"); - } - return a_Meta; -} - - - - - -template -NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) -{ - NIBBLETYPE OtherMeta = a_Meta & (~BitMask); - switch (a_Meta & BitMask) - { - case South: return East | OtherMeta; - case East: return North | OtherMeta; - case North: return West | OtherMeta; - case West: return South | OtherMeta; - } - if (AssertIfNotMatched) - { - ASSERT(!"Invalid Meta value"); - } - return a_Meta; -} - - - - - -template -NIBBLETYPE cMetaRotater::MetaMirrorXY(NIBBLETYPE a_Meta) -{ - NIBBLETYPE OtherMeta = a_Meta & (~BitMask); - switch (a_Meta & BitMask) - { - case South: return North | OtherMeta; - case North: return South | OtherMeta; - } - // Not Facing North or South; No change. - return a_Meta; -} - - - - - -template -NIBBLETYPE cMetaRotater::MetaMirrorYZ(NIBBLETYPE a_Meta) -{ - NIBBLETYPE OtherMeta = a_Meta & (~BitMask); - switch (a_Meta & BitMask) - { - case West: return East | OtherMeta; - case East: return West | OtherMeta; - } - // Not Facing East or West; No change. - return a_Meta; -} - - - - diff --git a/src/Blocks/MetaRotator.h b/src/Blocks/MetaRotator.h new file mode 100644 index 000000000..dde88e6db --- /dev/null +++ b/src/Blocks/MetaRotator.h @@ -0,0 +1,120 @@ +// MetaRotater.h + +// Provides a mixin for rotations and reflections + +#pragma once + +// MSVC generates warnings for the templated AssertIfNotMatched parameter conditions, so disable it: +#ifdef _MSC_VER + #pragma warning(disable: 4127) // Conditional expression is constant +#endif + + + + + +/* +Provides a mixin for rotations and reflections following the standard pattern of apply mask then use case. + +Usage: +Inherit from this class providing your base class as Base, the BitMask for the direction bits in bitmask and the masked value for the directions in North, East, South, West. There is also an aptional parameter AssertIfNotMatched. Set this if it is invalid for a block to exist in any other state. +*/ + +template +class cMetaRotater : public Base +{ +public: + + cMetaRotater(BLOCKTYPE a_BlockType) : + Base(a_BlockType) + {} + + virtual ~cMetaRotater() {} + + virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override; + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override; +}; + + + + + +template +NIBBLETYPE cMetaRotater::MetaRotateCW(NIBBLETYPE a_Meta) +{ + NIBBLETYPE OtherMeta = a_Meta & (~BitMask); + switch (a_Meta & BitMask) + { + case South: return West | OtherMeta; + case West: return North | OtherMeta; + case North: return East | OtherMeta; + case East: return South | OtherMeta; + } + if (AssertIfNotMatched) + { + ASSERT(!"Invalid Meta value"); + } + return a_Meta; +} + + + + + +template +NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) +{ + NIBBLETYPE OtherMeta = a_Meta & (~BitMask); + switch (a_Meta & BitMask) + { + case South: return East | OtherMeta; + case East: return North | OtherMeta; + case North: return West | OtherMeta; + case West: return South | OtherMeta; + } + if (AssertIfNotMatched) + { + ASSERT(!"Invalid Meta value"); + } + return a_Meta; +} + + + + + +template +NIBBLETYPE cMetaRotater::MetaMirrorXY(NIBBLETYPE a_Meta) +{ + NIBBLETYPE OtherMeta = a_Meta & (~BitMask); + switch (a_Meta & BitMask) + { + case South: return North | OtherMeta; + case North: return South | OtherMeta; + } + // Not Facing North or South; No change. + return a_Meta; +} + + + + + +template +NIBBLETYPE cMetaRotater::MetaMirrorYZ(NIBBLETYPE a_Meta) +{ + NIBBLETYPE OtherMeta = a_Meta & (~BitMask); + switch (a_Meta & BitMask) + { + case West: return East | OtherMeta; + case East: return West | OtherMeta; + } + // Not Facing East or West; No change. + return a_Meta; +} + + + + -- cgit v1.2.3 From 3df4f8609dc2e28c2328ddf448fa53f5483f4262 Mon Sep 17 00:00:00 2001 From: narroo Date: Tue, 25 Mar 2014 17:26:13 -0400 Subject: Fixed spelling; Rotater to Rotator. --- src/Blocks/BlockBed.h | 6 +++--- src/Blocks/BlockButton.h | 6 +++--- src/Blocks/BlockChest.h | 6 +++--- src/Blocks/BlockComparator.h | 6 +++--- src/Blocks/BlockDoor.h | 6 +++--- src/Blocks/BlockDropSpenser.h | 6 +++--- src/Blocks/BlockEnderchest.h | 6 +++--- src/Blocks/BlockFenceGate.h | 6 +++--- src/Blocks/BlockFurnace.h | 6 +++--- src/Blocks/BlockHopper.h | 4 ++-- src/Blocks/BlockLadder.h | 4 ++-- src/Blocks/BlockStairs.h | 6 +++--- src/Blocks/BlockTorch.h | 6 +++--- src/Blocks/BlockVine.h | 2 +- src/Blocks/MetaRotator.h | 16 ++++++++-------- 15 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index 6daa94730..92804aaac 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -4,7 +4,7 @@ #include "BlockHandler.h" #include "ChunkInterface.h" #include "WorldInterface.h" -#include "MetaRotater.h" +#include "MetaRotator.h" #include "../Entities/Player.h" @@ -12,11 +12,11 @@ class cBlockBedHandler : - public cMetaRotater + public cMetaRotator { public: cBlockBedHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index 740cbe3c4..4b2f6f618 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -2,17 +2,17 @@ #include "BlockHandler.h" #include "Chunk.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockButtonHandler : - public cMetaRotater + public cMetaRotator { public: cBlockButtonHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 890b5b933..a1ded4c26 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -4,18 +4,18 @@ #include "BlockEntity.h" #include "../BlockArea.h" #include "../Entities/Player.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockChestHandler : - public cMetaRotater + public cMetaRotator { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index e570ff302..4dd05366d 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -3,18 +3,18 @@ #include "BlockHandler.h" #include "BlockRedstoneRepeater.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockComparatorHandler : - public cMetaRotater + public cMetaRotator { public: cBlockComparatorHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 066e1ab28..797fe484c 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -4,15 +4,15 @@ #include "BlockHandler.h" #include "../Entities/Player.h" #include "Chunk.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockDoorHandler : - public cMetaRotater + public cMetaRotator { - typedef cMetaRotater super; + typedef cMetaRotator super; public: cBlockDoorHandler(BLOCKTYPE a_BlockType); diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h index 7e0ad0e55..88b61a418 100644 --- a/src/Blocks/BlockDropSpenser.h +++ b/src/Blocks/BlockDropSpenser.h @@ -6,18 +6,18 @@ #pragma once #include "../Piston.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockDropSpenserHandler : - public cMetaRotater + public cMetaRotator { public: cBlockDropSpenserHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h index 97cf484fb..67955f8ce 100644 --- a/src/Blocks/BlockEnderchest.h +++ b/src/Blocks/BlockEnderchest.h @@ -2,17 +2,17 @@ #pragma once #include "BlockEntity.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockEnderchestHandler : - public cMetaRotater + public cMetaRotator { public: cBlockEnderchestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index e3162bbd6..e202c6610 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockFenceGateHandler : - public cMetaRotater + public cMetaRotator { public: cBlockFenceGateHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h index c7f8ff8d2..a7a807957 100644 --- a/src/Blocks/BlockFurnace.h +++ b/src/Blocks/BlockFurnace.h @@ -4,17 +4,17 @@ #include "BlockEntity.h" #include "../World.h" #include "../Piston.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockFurnaceHandler : - public cMetaRotater + public cMetaRotator { public: cBlockFurnaceHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h index 610296529..a882bb077 100644 --- a/src/Blocks/BlockHopper.h +++ b/src/Blocks/BlockHopper.h @@ -8,11 +8,11 @@ class cBlockHopperHandler : - public cMetaRotater + public cMetaRotator { public: cBlockHopperHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h index 12408759e..a605edf3f 100644 --- a/src/Blocks/BlockLadder.h +++ b/src/Blocks/BlockLadder.h @@ -9,11 +9,11 @@ class cBlockLadderHandler : - public cMetaRotater + public cMetaRotator { public: cBlockLadderHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index ea8405597..1072b7e71 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -2,17 +2,17 @@ #pragma once #include "BlockHandler.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockStairsHandler : - public cMetaRotater + public cMetaRotator { public: cBlockStairsHandler(BLOCKTYPE a_BlockType) : - cMetaRotater(a_BlockType) + cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index d32c77629..8ddec8de1 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -2,17 +2,17 @@ #include "BlockHandler.h" #include "../Chunk.h" -#include "MetaRotater.h" +#include "MetaRotator.h" class cBlockTorchHandler : - public cMetaRotater + public cMetaRotator { public: cBlockTorchHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotator(a_BlockType) { } diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 708583e70..0b57acc7b 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -1,7 +1,7 @@ #pragma once #include "BlockHandler.h" -#include "MetaRotater.h" +#include "MetaRotator.h" diff --git a/src/Blocks/MetaRotator.h b/src/Blocks/MetaRotator.h index dde88e6db..899c583e1 100644 --- a/src/Blocks/MetaRotator.h +++ b/src/Blocks/MetaRotator.h @@ -1,4 +1,4 @@ -// MetaRotater.h +// MetaRotator.h // Provides a mixin for rotations and reflections @@ -21,15 +21,15 @@ Inherit from this class providing your base class as Base, the BitMask for the d */ template -class cMetaRotater : public Base +class cMetaRotator : public Base { public: - cMetaRotater(BLOCKTYPE a_BlockType) : + cMetaRotator(BLOCKTYPE a_BlockType) : Base(a_BlockType) {} - virtual ~cMetaRotater() {} + virtual ~cMetaRotator() {} virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override; @@ -42,7 +42,7 @@ public: template -NIBBLETYPE cMetaRotater::MetaRotateCW(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator::MetaRotateCW(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) @@ -64,7 +64,7 @@ NIBBLETYPE cMetaRotater -NIBBLETYPE cMetaRotater::MetaRotateCCW(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator::MetaRotateCCW(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) @@ -86,7 +86,7 @@ NIBBLETYPE cMetaRotater -NIBBLETYPE cMetaRotater::MetaMirrorXY(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator::MetaMirrorXY(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) @@ -103,7 +103,7 @@ NIBBLETYPE cMetaRotater -NIBBLETYPE cMetaRotater::MetaMirrorYZ(NIBBLETYPE a_Meta) +NIBBLETYPE cMetaRotator::MetaMirrorYZ(NIBBLETYPE a_Meta) { NIBBLETYPE OtherMeta = a_Meta & (~BitMask); switch (a_Meta & BitMask) -- cgit v1.2.3 From d5c7fc6bd65bfabf8d95b6f2c4cbdf5dd2b447b7 Mon Sep 17 00:00:00 2001 From: narroo Date: Tue, 25 Mar 2014 17:35:48 -0400 Subject: Added a comment about the behavior of doors under mirros. Simply put, the current implementation of MetaMirror causes glitchy behavior. The door class itself needs to be edited. (I've got an idea on that....) --- src/Blocks/BlockDoor.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index c027daed2..100f48e6c 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -143,7 +143,10 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) { // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data // Return a_Meta if panel is a top panel (0x08 bit is set to 1) - LOG("Test MirrorXY"); + + // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored + // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time, + // so the function can only see either the hinge position or orientation, but not both, at any given time. if (a_Meta & 0x08) return a_Meta; // Holds open/closed meta data. 0x0C == 1100. @@ -166,7 +169,10 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) { // Top bit (0x08) contains door panel type (Top/Bottom panel) Only Bottom panels contain position data // Return a_Meta if panel is a top panel (0x08 bit is set to 1) - LOG("Test MirrorYZ"); + + // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored + // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time, + // so the function can only see either the hinge position or orientation, but not both, at any given time. if (a_Meta & 0x08) return a_Meta; // Holds open/closed meta data. 0x0C == 1100. -- cgit v1.2.3 From 9032ff96c7c6db4264eedda95de7ea55f155bc47 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 23:35:50 +0100 Subject: Removed unused constants. DeadlockDetect reads the value from the ini file, and world lighting has a separate queue now. --- src/DeadlockDetect.cpp | 5 +---- src/World.cpp | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index 4dc7bfde6..322084dc4 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -7,7 +7,7 @@ #include "DeadlockDetect.h" #include "Root.h" #include "World.h" -# include +#include @@ -16,9 +16,6 @@ /// Number of milliseconds per cycle const int CYCLE_MILLISECONDS = 100; -/// When the number of cycles for the same world age hits this value, it is considered a deadlock -const int NUM_CYCLES_LIMIT = 200; // 200 = twenty seconds - diff --git a/src/World.cpp b/src/World.cpp index 3f157157a..e39a605bb 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -60,9 +60,6 @@ -/// Up to this many m_SpreadQueue elements are handled each world tick -const int MAX_LIGHTING_SPREAD_PER_TICK = 10; - const int TIME_SUNSET = 12000; const int TIME_NIGHT_START = 13187; const int TIME_NIGHT_END = 22812; -- cgit v1.2.3 From 1b00b62a4b8f27e14e31e251020321e41a284b21 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 25 Mar 2014 23:49:58 +0100 Subject: Ignoring the default GalExports folder. --- MCServer/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/.gitignore b/MCServer/.gitignore index 64f062ef7..69826ef06 100644 --- a/MCServer/.gitignore +++ b/MCServer/.gitignore @@ -6,6 +6,7 @@ MCServer MCServer_debug CommLogs/ +GalExports/ logs players world* -- cgit v1.2.3 From 90415ff79886f63cacced59f202228ddac69765a Mon Sep 17 00:00:00 2001 From: narroo Date: Wed, 26 Mar 2014 08:54:17 -0400 Subject: Fixed Minor typos. --- src/Blocks/BlockDoor.cpp | 7 +++++-- src/Blocks/BlockRail.h | 12 ++++++------ src/Blocks/BlockSlab.h | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 100f48e6c..479c68153 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -146,7 +146,8 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorXY(NIBBLETYPE a_Meta) // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time, - // so the function can only see either the hinge position or orientation, but not both, at any given time. + // so the function can only see either the hinge position or orientation, but not both, at any given time. The class itself + // needs extra datamembers. if (a_Meta & 0x08) return a_Meta; // Holds open/closed meta data. 0x0C == 1100. @@ -172,7 +173,9 @@ NIBBLETYPE cBlockDoorHandler::MetaMirrorYZ(NIBBLETYPE a_Meta) // Note: Currently, you can not properly mirror the hinges on a double door. The orientation of the door is stored // in only the bottom tile while the hinge position is in the top tile. This function only operates on one tile at a time, - // so the function can only see either the hinge position or orientation, but not both, at any given time. + // so the function can only see either the hinge position or orientation, but not both, at any given time.The class itself + // needs extra datamembers. + if (a_Meta & 0x08) return a_Meta; // Holds open/closed meta data. 0x0C == 1100. diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index f56ec7152..477707a91 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -453,8 +453,8 @@ public: case 0x02: return 0x04 + OtherMeta; // Asc. East -> Asc. North case 0x04: return 0x03 + OtherMeta; // Asc. North -> Asc. West - case 0x03: return 0x05 + OtherMeta; // Asc. West -> Asc. South - case 0x05: return 0x02 + OtherMeta; // Asc. South -> Asc. East + case 0x03: return 0x05 + OtherMeta; // Asc. West -> Asc. South + case 0x05: return 0x02 + OtherMeta; // Asc. South -> Asc. East } } else @@ -489,8 +489,8 @@ public: case 0x02: return 0x05 + OtherMeta; // Asc. East -> Asc. South case 0x05: return 0x03 + OtherMeta; // Asc. South -> Asc. West - case 0x03: return 0x04 + OtherMeta; // Asc. West -> Asc. North - case 0x04: return 0x02 + OtherMeta; // Asc. North -> Asc. East + case 0x03: return 0x04 + OtherMeta; // Asc. West -> Asc. North + case 0x04: return 0x02 + OtherMeta; // Asc. North -> Asc. East } } else @@ -521,7 +521,7 @@ public: switch (a_Meta & 0x07) { case 0x05: return 0x04 + OtherMeta; // Asc. South -> Asc. North - case 0x04: return 0x05 + OtherMeta; // Asc. North -> Asc. South + case 0x04: return 0x05 + OtherMeta; // Asc. North -> Asc. South } } else @@ -552,7 +552,7 @@ public: switch (a_Meta & 0x07) { case 0x02: return 0x03 + OtherMeta; // Asc. East -> Asc. West - case 0x03: return 0x02 + OtherMeta; // Asc. West -> Asc. East + case 0x03: return 0x02 + OtherMeta; // Asc. West -> Asc. East } } else diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index b18bf7ef3..77e8b8e55 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -186,7 +186,7 @@ public: virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override { - NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelate meta data. + NIBBLETYPE OtherMeta = a_Meta & 0x07; // Contains unrelated meta data. // 8th bit is up/down. 1 right-side-up, 0 is up-side-down. return (a_Meta & 0x08) ? 0x00 + OtherMeta : 0x01 + OtherMeta; -- cgit v1.2.3 From 6553c8ff447a1e006095dc7e5aad76b37c410038 Mon Sep 17 00:00:00 2001 From: narroo Date: Wed, 26 Mar 2014 13:25:10 -0400 Subject: Altered the rotates for cBlockSignHandler. The functions as a whole is still unfinished though; no wall sign or mirroring support yet. --- src/Blocks/BlockSign.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h index 82d9a2fcc..24346b930 100644 --- a/src/Blocks/BlockSign.h +++ b/src/Blocks/BlockSign.h @@ -75,13 +75,13 @@ public: virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) override { - return ++a_Meta; + return (++a_Meta) & 0x0F; } virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override { - return --a_Meta; + return (--a_Meta) & 0x0F; } } ; -- cgit v1.2.3 From 8c2c4f2463fcc429d336019fa0fd39098eb7d97f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 26 Mar 2014 22:01:01 +0100 Subject: Prefabs support connectors, rotations and merge strategy. --- src/Generating/Prefab.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++-- src/Generating/Prefab.h | 10 +++++++- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 824800119..ded4f6c41 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -17,13 +17,14 @@ uses a prefabricate in a cBlockArea for drawing itself. cPrefab::cPrefab(const cPrefab::sDef & a_Def) : m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), m_HitBox(0, 0, 0, a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), - m_AllowedRotations(7), // TODO: All rotations allowed (not in the definition yet) - m_MergeStrategy(cBlockArea::msImprint) + m_AllowedRotations(a_Def.m_AllowedRotations), + m_MergeStrategy(a_Def.m_MergeStrategy) { m_BlockArea.Create(m_Size); CharMap cm; ParseCharMap(cm, a_Def.m_CharMap); ParseBlockImage(cm, a_Def.m_Image); + ParseConnectors(a_Def.m_Connectors); } @@ -42,6 +43,22 @@ void cPrefab::Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement) +bool cPrefab::HasConnectorType(int a_ConnectorType) const +{ + for (cConnectors::const_iterator itr = m_Connectors.begin(), end = m_Connectors.end(); itr != end; ++itr) + { + if (itr->m_Type == a_ConnectorType) + { + return true; + } + } // for itr - m_Connectors[] + return false; +} + + + + + void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) { // Initialize the charmap to all-invalid values: @@ -102,6 +119,50 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma +void cPrefab::ParseConnectors(const char * a_ConnectorsDef) +{ + AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); + for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) + { + if (itr->empty()) + { + continue; + } + // Split into components: "Type: X, Y, Z: Face": + AStringVector Defs = StringSplitAndTrim(*itr, ":"); + if (Defs.size() != 3) + { + LOGWARNING("Bad prefab Connector definition line: \"%s\", skipping.", itr->c_str()); + continue; + } + AStringVector Coords = StringSplitAndTrim(Defs[1], ","); + if (Coords.size() != 3) + { + LOGWARNING("Bad prefab Connector coords definition: \"%s\", skipping.", Defs[1].c_str()); + continue; + } + + // Check that the BlockFace is within range: + int BlockFace = atoi(Defs[2].c_str()); + if ((BlockFace < 0) || (BlockFace >= 6)) + { + LOGWARNING("Bad prefab Connector Blockface: \"%s\", skipping.", Defs[2].c_str()); + continue; + } + + // Add the connector: + m_Connectors.push_back(cPiece::cConnector( + atoi(Coords[0].c_str()), atoi(Coords[1].c_str()), atoi(Coords[2].c_str()), // Connector pos + atoi(Defs[0].c_str()), // Connector type + (eBlockFace)BlockFace + )); + } // for itr - Lines[] +} + + + + + cPiece::cConnectors cPrefab::GetConnectors(void) const { return m_Connectors; diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index 6596b906b..3733166ab 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -33,13 +33,18 @@ public: int m_SizeZ; const char * m_CharMap; const char * m_Image; - // TODO: Connectors + const char * m_Connectors; + int m_AllowedRotations; + cBlockArea::eMergeStrategy m_MergeStrategy; }; cPrefab(const sDef & a_Def); /** Draws the prefab into the specified block area, according to the placement stored in the PlacedPiece. */ void Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement); + + /** Returns true if the prefab has any connector of the specified type. */ + bool HasConnectorType(int a_ConnectorType) const; protected: /** Maps letters in the sDef::m_Image onto a number, BlockType * 16 | BlockMeta */ @@ -76,6 +81,9 @@ protected: /** Parses the Image in the definition into m_BlockArea's block types and metas, using the specified CharMap. */ void ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage); + + /** Parses the connectors definition text into m_Connectors member. */ + void ParseConnectors(const char * a_ConnectorsDef); }; -- cgit v1.2.3 From bbebb3a2cdbd888e63e4a40b1bcc730105c11377 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 27 Mar 2014 18:13:52 +0100 Subject: Fixed chunk neighbor-getting for long distances. This fixes a server hang when teleporting to coords too far away. --- src/Chunk.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 957d7d575..bd4cb9937 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -2510,6 +2510,17 @@ cChunk * cChunk::GetNeighborChunk(int a_BlockX, int a_BlockZ) cChunk * cChunk::GetRelNeighborChunk(int a_RelX, int a_RelZ) { + // If the relative coords are too far away, use the parent's chunk lookup instead: + if ((a_RelX < 128) || (a_RelX > 128) || (a_RelZ < -128) || (a_RelZ > 128)) + { + int BlockX = m_PosX * cChunkDef::Width + a_RelX; + int BlockZ = m_PosZ * cChunkDef::Width + a_RelZ; + int BlockY, ChunkX, ChunkZ; + AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); + return m_ChunkMap->GetChunkNoLoad(ChunkX, ZERO_CHUNK_Y, ChunkZ); + } + + // Walk the neighbors: bool ReturnThis = true; if (a_RelX < 0) { -- cgit v1.2.3 From 7b585290fccd3dc074b1f9feef0af754ab3dd632 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 27 Mar 2014 23:03:57 +0100 Subject: cPrefab can draw itself into a cChunkDesc. --- src/Generating/Prefab.cpp | 11 +++++++---- src/Generating/Prefab.h | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index ded4f6c41..145c875a1 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -9,6 +9,7 @@ uses a prefabricate in a cBlockArea for drawing itself. #include "Globals.h" #include "Prefab.h" #include "../WorldStorage/SchematicFileSerializer.h" +#include "ChunkDesc.h" @@ -16,7 +17,7 @@ uses a prefabricate in a cBlockArea for drawing itself. cPrefab::cPrefab(const cPrefab::sDef & a_Def) : m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), - m_HitBox(0, 0, 0, a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), + m_HitBox(0, 0, 0, a_Def.m_SizeX - 1, a_Def.m_SizeY - 1, a_Def.m_SizeZ - 1), m_AllowedRotations(a_Def.m_AllowedRotations), m_MergeStrategy(a_Def.m_MergeStrategy) { @@ -31,11 +32,13 @@ cPrefab::cPrefab(const cPrefab::sDef & a_Def) : -void cPrefab::Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement) +void cPrefab::Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const { Vector3i Placement = a_Placement->GetCoords(); - Placement.Move(a_Dest.GetOrigin() * (-1)); - a_Dest.Merge(m_BlockArea, Placement, m_MergeStrategy); + int ChunkStartX = a_Dest.GetChunkX() * cChunkDef::Width; + int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width; + Placement.Move(-ChunkStartX, 0, -ChunkStartZ); + a_Dest.WriteBlockArea(m_BlockArea, Placement.x, Placement.y, Placement.z, m_MergeStrategy); } diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index 3733166ab..ec95c909b 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -40,8 +40,8 @@ public: cPrefab(const sDef & a_Def); - /** Draws the prefab into the specified block area, according to the placement stored in the PlacedPiece. */ - void Draw(cBlockArea & a_Dest, const cPlacedPiece * a_Placement); + /** Draws the prefab into the specified chunk, according to the placement stored in the PlacedPiece. */ + void Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const; /** Returns true if the prefab has any connector of the specified type. */ bool HasConnectorType(int a_ConnectorType) const; -- cgit v1.2.3 From 7089c5e2671d2bf7781ab2eab7129bb5bd25b1a1 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 14:01:22 +0100 Subject: Add new leaves to all classes. --- src/Blocks/BlockLeaves.h | 2 +- src/ChunkMap.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index a6d3373c1..954b993d6 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -87,7 +87,7 @@ public: return; } - if ((Meta & 0x8) != 0) + if ((Meta & 0x8) == 0) { // These leaves have been checked for decay lately and nothing around them changed return; diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index e695f0ab2..da5dd90e4 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1384,6 +1384,13 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) } break; } + case E_BLOCK_NEW_LEAVES: + { + if (itr->BlockType == E_BLOCK_NEW_LOG) + { + Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); + } + } } } // for itr - a_Blocks[] } -- cgit v1.2.3 From c4a8336e847d2f4731dd9d899d6af200631f8aef Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 14:38:41 +0100 Subject: Add HOOK_BLOCK_SPREAD --- src/Bindings/Plugin.h | 1 + src/Bindings/PluginLua.cpp | 21 +++++++++++++++++++++ src/Bindings/PluginLua.h | 1 + src/Bindings/PluginManager.cpp | 21 +++++++++++++++++++++ src/Bindings/PluginManager.h | 2 ++ src/Simulator/FireSimulator.cpp | 14 +++++++++++--- 6 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 949e4693a..4c6d5a938 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -46,6 +46,7 @@ public: * On all these functions, return true if you want to override default behavior and not call other plugins on that callback. * You can also return false, so default behavior is used. **/ + virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) = 0; virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; virtual bool OnChat (cPlayer * a_Player, AString & a_Message) = 0; virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index cccbc3c93..cefeb4996 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -195,6 +195,26 @@ void cPluginLua::Tick(float a_Dt) +bool cPluginLua::OnBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BLOCK_SPREAD]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnBlockToPickups(cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) { cCSLock Lock(m_CriticalSection); @@ -1430,6 +1450,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType) { switch (a_HookType) { + case cPluginManager::HOOK_BLOCK_SPREAD: return "OnBlockSpread"; case cPluginManager::HOOK_BLOCK_TO_PICKUPS: return "OnBlockToPickups"; case cPluginManager::HOOK_CHAT: return "OnChat"; case cPluginManager::HOOK_CHUNK_AVAILABLE: return "OnChunkAvailable"; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index a177f5288..5c2c9e57f 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -69,6 +69,7 @@ public: virtual void Tick(float a_Dt) override; + virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override; virtual bool OnChat (cPlayer * a_Player, AString & a_Message) override; virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index b9cf160c4..142b4b5ad 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -205,6 +205,27 @@ void cPluginManager::Tick(float a_Dt) +bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_SPREAD); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnBlockSpread(a_World, a_BlockX, a_BlockY, a_BlockZ)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookBlockToPickups( cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 44bc5a8d7..18d34a50d 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -58,6 +58,7 @@ public: // tolua_export // tolua_begin enum PluginHook { + HOOK_BLOCK_SPREAD, HOOK_BLOCK_TO_PICKUPS, HOOK_CHAT, HOOK_CHUNK_AVAILABLE, @@ -154,6 +155,7 @@ public: // tolua_export unsigned int GetNumPlugins() const; // tolua_export // Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort + bool CallHookBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ); bool CallHookBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups); bool CallHookChat (cPlayer * a_Player, AString & a_Message); bool CallHookChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ); diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 26712e6e6..871a1ec5c 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -6,6 +6,8 @@ #include "../BlockID.h" #include "../Defines.h" #include "../Chunk.h" +#include "Root.h" +#include "PluginManager.h" @@ -315,9 +317,15 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int */ if (CanStartFireInBlock(a_Chunk, x, y, z)) { - FLOG("FS: Starting new fire at {%d, %d, %d}.", - x + a_Chunk->GetPosX() * cChunkDef::Width, y, z + a_Chunk->GetPosZ() * cChunkDef::Width - ); + int a_PosX = x + a_Chunk->GetPosX() * cChunkDef::Width; + int a_PosZ = z + a_Chunk->GetPosZ() * cChunkDef::Width; + + if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ)) + { + return; + } + + FLOG("FS: Starting new fire at {%d, %d, %d}.", a_PosX, y, a_PosZ); a_Chunk->UnboundedRelSetBlock(x, y, z, E_BLOCK_FIRE, 0); } } // for y -- cgit v1.2.3 From 3774b1be6445257a28677fbdce17bab58c168df9 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 16:06:03 +0100 Subject: Add SpreadSource --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 ++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 4 ++-- src/Bindings/PluginManager.h | 2 +- src/BlockID.h | 13 +++++++++++++ src/Blocks/BlockDirt.h | 5 ++++- src/Blocks/BlockMushroom.h | 3 +++ src/Blocks/BlockMycelium.h | 2 ++ src/Blocks/BlockVine.h | 5 ++++- src/Simulator/FireSimulator.cpp | 2 +- 11 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 4c6d5a938..057fa0304 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -46,7 +46,7 @@ public: * On all these functions, return true if you want to override default behavior and not call other plugins on that callback. * You can also return false, so default behavior is used. **/ - virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) = 0; + virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0; virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; virtual bool OnChat (cPlayer * a_Player, AString & a_Message) = 0; virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index cefeb4996..4f0e13f12 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -195,14 +195,14 @@ void cPluginLua::Tick(float a_Dt) -bool cPluginLua::OnBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +bool cPluginLua::OnBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_BLOCK_SPREAD]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), a_World, a_BlockX, a_BlockY, a_BlockZ, a_Source, cLuaState::Return, res); if (res) { return true; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 5c2c9e57f..f51056186 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -69,7 +69,7 @@ public: virtual void Tick(float a_Dt) override; - virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override; + virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) override; virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) override; virtual bool OnChat (cPlayer * a_Player, AString & a_Message) override; virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 142b4b5ad..7d346c522 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -205,7 +205,7 @@ void cPluginManager::Tick(float a_Dt) -bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) { HookMap::iterator Plugins = m_Hooks.find(HOOK_BLOCK_SPREAD); if (Plugins == m_Hooks.end()) @@ -214,7 +214,7 @@ bool cPluginManager::CallHookBlockSpread(cWorld * a_World, int a_BlockX, int a_B } for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnBlockSpread(a_World, a_BlockX, a_BlockY, a_BlockZ)) + if ((*itr)->OnBlockSpread(a_World, a_BlockX, a_BlockY, a_BlockZ, a_Source)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 18d34a50d..03f19e831 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -155,7 +155,7 @@ public: // tolua_export unsigned int GetNumPlugins() const; // tolua_export // Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort - bool CallHookBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ); + bool CallHookBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source); bool CallHookBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups); bool CallHookChat (cPlayer * a_Player, AString & a_Message); bool CallHookChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ); diff --git a/src/BlockID.h b/src/BlockID.h index 8adefcfba..a1a445da4 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -866,6 +866,19 @@ enum eShrapnelLevel slAll } ; + + + + +enum eSpreadSource +{ + esFireSpread, + esGrassSpread, + esMushroomSpread, + esMycelSpread, + esVineSpread, +} ; + // tolua_end diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 544424a04..6240e5e3f 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -79,7 +79,10 @@ public: Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); if ((cBlockInfo::IsOneHitDig(AboveDest) || cBlockInfo::IsTransparent(AboveDest)) && !IsBlockWater(AboveDest)) { - Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, esGrassSpread)) + { + Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); + } } } // for i - repeat twice } diff --git a/src/Blocks/BlockMushroom.h b/src/Blocks/BlockMushroom.h index c30c1a401..135d418d7 100644 --- a/src/Blocks/BlockMushroom.h +++ b/src/Blocks/BlockMushroom.h @@ -17,6 +17,9 @@ public: } + // TODO: Add Mushroom Spread + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to 0 diff --git a/src/Blocks/BlockMycelium.h b/src/Blocks/BlockMycelium.h index 7f897c72a..2a8ef5fca 100644 --- a/src/Blocks/BlockMycelium.h +++ b/src/Blocks/BlockMycelium.h @@ -16,6 +16,8 @@ public: { } + // TODO: Add Mycel Spread + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0)); diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 8041d9359..9d84b720e 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -175,7 +175,10 @@ public: a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block); if (Block == E_BLOCK_AIR) { - a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, esVineSpread)) + { + a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); + } } } diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 871a1ec5c..932ccf6bd 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -320,7 +320,7 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int int a_PosX = x + a_Chunk->GetPosX() * cChunkDef::Width; int a_PosZ = z + a_Chunk->GetPosZ() * cChunkDef::Width; - if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ)) + if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ, esFireSpread)) { return; } -- cgit v1.2.3 From 54d55b31ef9b17673212184ac523f6f2a964338d Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 16:12:16 +0100 Subject: Add documentation for new Block spread --- MCServer/Plugins/APIDump/APIDesc.lua | 9 ++++++ MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua | 40 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 74e7bf860..92b57865f 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1826,6 +1826,7 @@ cPluginManager.AddHook(cPluginManager.HOOK_CHAT, OnChatMessage); }, Constants = { + HOOK_BLOCK_SPREAD = { Notes = "Called when a block spreads based on world conditions" }, HOOK_BLOCK_TO_PICKUPS = { Notes = "Called when a block has been dug and is being converted to pickups. The server has provided the default pickups and the plugins may modify them." }, HOOK_CHAT = { Notes = "Called when a client sends a chat message that is not a command. The plugin may modify the chat message" }, HOOK_CHUNK_AVAILABLE = { Notes = "Called when a chunk is loaded or generated and becomes available in the {{cWorld|world}}." }, @@ -2767,6 +2768,14 @@ end data provided with the explosions, such as the exploding {{cCreeper|creeper}} entity or the {{Vector3i|coords}} of the exploding bed. ]], + }, + SpreadSource = + { + Include = "^es.*", + TextBefore = [[ + These constants are used to differentiate the various sources of spreads. They are used in + the {{OnBlockSpread|HOOK_BLOCK_SPREAD}} hook. + ]], } }, }, -- Globals diff --git a/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua new file mode 100644 index 000000000..1dde55f36 --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua @@ -0,0 +1,40 @@ +return +{ + HOOK_BLOCK_SPREAD = + { + CalledWhen = "Called when a block spreads based on world conditions", + DefaultFnName = "OnBlockSpread", -- also used as pagename + Desc = [[ + This hook is called when a block spreads.

    +

    + The explosion carries with it the type of its source - whether it's a creeper exploding, or TNT, + etc. It also carries the identification of the actual source. The exact type of the identification + depends on the source kind: + + + + + + + +
    SourceNotes
    esFireSpreadFire spreading
    esGrassSpreadGrass spreading
    esMushroomSpreadMushroom spreading
    esMycelSpreadMycel spreading
    esVineSpreadVine spreading

    + ]], + Params = + { + { Name = "World", Type = "{{cWorld}}", Notes = "The world in which the block resides" }, + { Name = "BlockX", Type = "number", Notes = "X-coord of the block" }, + { Name = "BlockY", Type = "number", Notes = "Y-coord of the block" }, + { Name = "BlockZ", Type = "number", Notes = "Z-coord of the block" }, + { Name = "Source", Type = "eSpreadSource", Notes = "Source of the spread. See the table above." }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called, and finally + MCServer will process the spread. If the function + returns true, no other callback is called for this event and the spread will not occur. + ]], + }, -- HOOK_BLOCK_SPREAD +} + + + + -- cgit v1.2.3 From 09794e65bb8d752148250c40c710c08d0acf7ff8 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 16:15:22 +0100 Subject: Wrong if in BlockLeaves --- src/Blocks/BlockLeaves.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index 954b993d6..a6d3373c1 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -87,7 +87,7 @@ public: return; } - if ((Meta & 0x8) == 0) + if ((Meta & 0x8) != 0) { // These leaves have been checked for decay lately and nothing around them changed return; -- cgit v1.2.3 From 9c461124866cd16d04206f49da6650a2219de50f Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 22:28:12 +0100 Subject: Change SpreadSource prefix to ss --- src/BlockID.h | 10 +++++----- src/Blocks/BlockDirt.h | 2 +- src/Blocks/BlockVine.h | 2 +- src/Simulator/FireSimulator.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/BlockID.h b/src/BlockID.h index a1a445da4..2fec512e2 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -872,11 +872,11 @@ enum eShrapnelLevel enum eSpreadSource { - esFireSpread, - esGrassSpread, - esMushroomSpread, - esMycelSpread, - esVineSpread, + ssFireSpread, + ssGrassSpread, + ssMushroomSpread, + ssMycelSpread, + ssVineSpread, } ; // tolua_end diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 6240e5e3f..a1ab74257 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -79,7 +79,7 @@ public: Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); if ((cBlockInfo::IsOneHitDig(AboveDest) || cBlockInfo::IsTransparent(AboveDest)) && !IsBlockWater(AboveDest)) { - if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, esGrassSpread)) + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, ssGrassSpread)) { Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); } diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 9d84b720e..d096c81a8 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -175,7 +175,7 @@ public: a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block); if (Block == E_BLOCK_AIR) { - if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, esVineSpread)) + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, ssVineSpread)) { a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); } diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 932ccf6bd..e4d4a540d 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -320,7 +320,7 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int int a_PosX = x + a_Chunk->GetPosX() * cChunkDef::Width; int a_PosZ = z + a_Chunk->GetPosZ() * cChunkDef::Width; - if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ, esFireSpread)) + if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(&m_World, a_PosX, y, a_PosZ, ssFireSpread)) { return; } -- cgit v1.2.3 From 9ac3e3405a92d458bf3d09d0ec0f60031d31823d Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 22:28:53 +0100 Subject: Change SpreadSource documentation --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 92b57865f..f8ad74226 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2771,7 +2771,7 @@ end }, SpreadSource = { - Include = "^es.*", + Include = "^ss.*", TextBefore = [[ These constants are used to differentiate the various sources of spreads. They are used in the {{OnBlockSpread|HOOK_BLOCK_SPREAD}} hook. diff --git a/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua index 1dde55f36..a2f7d7ef9 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua @@ -12,11 +12,11 @@ return depends on the source kind: - - - - - + + + + +
    SourceNotes
    esFireSpreadFire spreading
    esGrassSpreadGrass spreading
    esMushroomSpreadMushroom spreading
    esMycelSpreadMycel spreading
    esVineSpreadVine spreading
    ssFireSpreadFire spreading
    ssGrassSpreadGrass spreading
    ssMushroomSpreadMushroom spreading
    ssMycelSpreadMycel spreading
    ssVineSpreadVine spreading

    ]], Params = -- cgit v1.2.3 From 327b70e769bd3bb826320027a1b7d56f6e386a6b Mon Sep 17 00:00:00 2001 From: Howaner Date: Mon, 24 Mar 2014 20:01:57 +0100 Subject: Change documentation text --- MCServer/Plugins/APIDump/APIDesc.lua | 4 ++-- MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index f8ad74226..01f000182 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2773,8 +2773,8 @@ end { Include = "^ss.*", TextBefore = [[ - These constants are used to differentiate the various sources of spreads. They are used in - the {{OnBlockSpread|HOOK_BLOCK_SPREAD}} hook. + These constants are used to differentiate the various sources of spreads, such as grass growing. + They are used in the {{OnBlockSpread|HOOK_BLOCK_SPREAD}} hook. ]], } }, diff --git a/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua index a2f7d7ef9..ed0b5f46f 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnBlockSpread.lua @@ -7,8 +7,8 @@ return Desc = [[ This hook is called when a block spreads.

    - The explosion carries with it the type of its source - whether it's a creeper exploding, or TNT, - etc. It also carries the identification of the actual source. The exact type of the identification + The spread carries with it the type of its source - whether it's a block spreads. + It also carries the identification of the actual source. The exact type of the identification depends on the source kind: -- cgit v1.2.3 From 8301f479bba4c12579d56c2274b85033a336057c Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 27 Mar 2014 23:21:04 +0100 Subject: Fix merge conflicts --- src/ChunkMap.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index da5dd90e4..e695f0ab2 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1384,13 +1384,6 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) } break; } - case E_BLOCK_NEW_LEAVES: - { - if (itr->BlockType == E_BLOCK_NEW_LOG) - { - Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); - } - } } } // for itr - a_Blocks[] } -- cgit v1.2.3 From 7cc44d4d8b6b6142ab45f955890a92e395604142 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 13:34:32 +0100 Subject: Debuggers: Deactivated the chunk generator callback. --- MCServer/Plugins/Debuggers/Debuggers.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index fe3efa306..2cb014875 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -27,11 +27,13 @@ function Initialize(Plugin) PM:AddHook(cPluginManager.HOOK_CHAT, OnChat); PM:AddHook(cPluginManager.HOOK_PLAYER_RIGHT_CLICKING_ENTITY, OnPlayerRightClickingEntity); PM:AddHook(cPluginManager.HOOK_WORLD_TICK, OnWorldTick); - PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated); PM:AddHook(cPluginManager.HOOK_PLUGINS_LOADED, OnPluginsLoaded); PM:AddHook(cPluginManager.HOOK_PLUGIN_MESSAGE, OnPluginMessage); PM:AddHook(cPluginManager.HOOK_PLAYER_JOINED, OnPlayerJoined) + -- _X: Disabled so that the normal operation doesn't interfere with anything + -- PM:AddHook(cPluginManager.HOOK_CHUNK_GENERATED, OnChunkGenerated); + PM:BindCommand("/le", "debuggers", HandleListEntitiesCmd, "- Shows a list of all the loaded entities"); PM:BindCommand("/ke", "debuggers", HandleKillEntitiesCmd, "- Kills all the loaded entities"); PM:BindCommand("/wool", "debuggers", HandleWoolCmd, "- Sets all your armor to blue wool"); -- cgit v1.2.3 From a2c4def518b0021a7575c9a9517f4f824369fe6d Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 28 Mar 2014 14:59:40 +0100 Subject: Add missing ChunkDesc import. --- src/Generating/Prefab.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index ec95c909b..c80de21b2 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -16,7 +16,7 @@ declared in this file as well; the Gallery server exports areas in this format. #include "PieceGenerator.h" #include "../BlockArea.h" - +#include "ChunkDesc.h" -- cgit v1.2.3 From 910e770a18520a96a5823b24b4b6a41068499414 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 16:36:33 +0100 Subject: Fixed Prefab's rotations. --- src/Generating/Prefab.cpp | 32 ++++++++++++++++++++++++++++---- src/Generating/Prefab.h | 14 +++++++++++--- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 145c875a1..1af1faec1 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -21,11 +21,33 @@ cPrefab::cPrefab(const cPrefab::sDef & a_Def) : m_AllowedRotations(a_Def.m_AllowedRotations), m_MergeStrategy(a_Def.m_MergeStrategy) { - m_BlockArea.Create(m_Size); + m_BlockArea[0].Create(m_Size); CharMap cm; ParseCharMap(cm, a_Def.m_CharMap); ParseBlockImage(cm, a_Def.m_Image); ParseConnectors(a_Def.m_Connectors); + + // 1 CCW rotation: + if ((m_AllowedRotations & 0x01) != 0) + { + m_BlockArea[1].CopyFrom(m_BlockArea[0]); + m_BlockArea[1].RotateCCW(); + } + + // 2 rotations are the same as mirroring twice; mirroring is faster because it has no reallocations + if ((m_AllowedRotations & 0x02) != 0) + { + m_BlockArea[2].CopyFrom(m_BlockArea[0]); + m_BlockArea[2].MirrorXY(); + m_BlockArea[2].MirrorYZ(); + } + + // 3 CCW rotations = 1 CW rotation: + if ((m_AllowedRotations & 0x04) != 0) + { + m_BlockArea[3].CopyFrom(m_BlockArea[0]); + m_BlockArea[3].RotateCW(); + } } @@ -38,7 +60,7 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const int ChunkStartX = a_Dest.GetChunkX() * cChunkDef::Width; int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width; Placement.Move(-ChunkStartX, 0, -ChunkStartZ); - a_Dest.WriteBlockArea(m_BlockArea, Placement.x, Placement.y, Placement.z, m_MergeStrategy); + a_Dest.WriteBlockArea(m_BlockArea[a_Placement->GetNumCCWRotations()], Placement.x, Placement.y, Placement.z, m_MergeStrategy); } @@ -112,7 +134,7 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma ASSERT(MappedValue != -1); // Using a letter not defined in the CharMap? BLOCKTYPE BlockType = MappedValue >> 4; NIBBLETYPE BlockMeta = MappedValue & 0x0f; - m_BlockArea.SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta); + m_BlockArea[0].SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta); } } } @@ -195,7 +217,9 @@ cCuboid cPrefab::GetHitBox(void) const bool cPrefab::CanRotateCCW(int a_NumRotations) const { - return ((m_AllowedRotations & (1 << (a_NumRotations % 4))) != 0); + // Either zero rotations + // Or the proper bit in m_AllowedRotations is set + return (a_NumRotations == 0) || ((m_AllowedRotations & (1 << ((a_NumRotations + 3) % 4))) != 0); } diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index ec95c909b..d6ab5658f 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -22,6 +22,13 @@ declared in this file as well; the Gallery server exports areas in this format. +// fwd: +class cChunkDesc; + + + + + class cPrefab : public cPiece { @@ -51,8 +58,9 @@ protected: typedef int CharMap[256]; - /** The cBlockArea that contains the block definitions for the prefab */ - cBlockArea m_BlockArea; + /** The cBlockArea that contains the block definitions for the prefab. + The index identifies the number of CCW rotations applied (0 = no rotation, 1 = 1 CCW rotation, ...). */ + cBlockArea m_BlockArea[4]; /** The size of the prefab */ Vector3i m_Size; @@ -79,7 +87,7 @@ protected: /** Parses the CharMap in the definition into a CharMap binary data used for translating the definition into BlockArea. */ void ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef); - /** Parses the Image in the definition into m_BlockArea's block types and metas, using the specified CharMap. */ + /** Parses the Image in the definition into m_BlockArea[0]'s block types and metas, using the specified CharMap. */ void ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage); /** Parses the connectors definition text into m_Connectors member. */ -- cgit v1.2.3 From 5b7215ec24c2b835a0f1342cf1479f757084d1e2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 16:42:32 +0100 Subject: Initial NetherFortGen import. Simple fortresses of 2 different rooms will generate. --- src/CMakeLists.txt | 27 +-- src/Generating/ComposableGenerator.cpp | 17 +- src/Generating/MineShafts.cpp | 2 +- src/Generating/NetherFortGen.cpp | 265 +++++++++++++++++++++++ src/Generating/NetherFortGen.h | 86 ++++++++ src/Generating/Prefabs/CMakeLists.txt | 13 ++ src/Generating/Prefabs/NetherFortPrefabs.cpp | 303 +++++++++++++++++++++++++++ src/Generating/Prefabs/NetherFortPrefabs.h | 15 ++ 8 files changed, 713 insertions(+), 15 deletions(-) create mode 100644 src/Generating/NetherFortGen.cpp create mode 100644 src/Generating/NetherFortGen.h create mode 100644 src/Generating/Prefabs/CMakeLists.txt create mode 100644 src/Generating/Prefabs/NetherFortPrefabs.cpp create mode 100644 src/Generating/Prefabs/NetherFortPrefabs.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 448dc4b70..ca874517e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,14 +6,14 @@ include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/jsoncpp/include") include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include") set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating) -set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities) +set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities Generating/Prefabs) if (NOT MSVC) - #Bindings needs to reference other folders so are done here + # Bindings need to reference other folders, so they are done here instead - #lib dependecies are not included + # lib dependencies are not included set(BINDING_DEPENDECIES tolua @@ -104,7 +104,6 @@ if (NOT MSVC) Bindings/PluginLua Bindings/PluginManager Bindings/WebPlugin - Bindings/WebPlugin ) target_link_libraries(Bindings lua sqlite tolualib) @@ -138,6 +137,7 @@ if (NOT MSVC) else () + # MSVC-specific handling: Put all files into one project, separate by the folders: # Generate the Bindings if they don't exist: if (NOT EXISTS "${PROJECT_SOURCE_DIR}/Bindings/Bindings.cpp") @@ -149,6 +149,14 @@ else () ) endif() + # Get all files in this folder: + file(GLOB_RECURSE SOURCE + "*.cpp" + "*.h" + "*.pkg" + ) + source_group("" FILES ${SOURCE}) + # Add all subfolders as solution-folders: list(APPEND FOLDERS "Resources") list(APPEND FOLDERS "Bindings") @@ -159,23 +167,16 @@ else () "${PATH}/*.rc" "${PATH}/*.pkg" ) - source_group("${PATH}" FILES ${FOLDER_FILES}) + string(REPLACE "/" "\\" PROJECT_PATH ${PATH}) + source_group("${PROJECT_PATH}" FILES ${FOLDER_FILES}) endfunction(includefolder) foreach(folder ${FOLDERS}) includefolder(${folder}) endforeach(folder) - file(GLOB_RECURSE SOURCE - "*.cpp" - "*.h" - "*.pkg" - ) - include_directories("${PROJECT_SOURCE_DIR}") - source_group("" FILES ${SOURCE}) - # Precompiled headers (1st part) SET_SOURCE_FILES_PROPERTIES( Globals.cpp PROPERTIES COMPILE_FLAGS "/Yc\"Globals.h\"" diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 6c00b5905..339f5709a 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -21,6 +21,7 @@ #include "DistortedHeightmap.h" #include "EndGen.h" #include "MineShafts.h" +#include "NetherFortGen.h" #include "Noise3DGenerator.h" #include "POCPieceGenerator.h" #include "Ravines.h" @@ -191,9 +192,11 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a m_HeightGen->GenHeightMap(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetHeightMap()); } + bool ShouldUpdateHeightmap = false; if (a_ChunkDesc.IsUsingDefaultComposition()) { m_CompositionGen->ComposeTerrain(a_ChunkDesc); + ShouldUpdateHeightmap = true; } if (a_ChunkDesc.IsUsingDefaultFinish()) @@ -202,6 +205,12 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a { (*itr)->GenFinish(a_ChunkDesc); } // for itr - m_FinishGens[] + ShouldUpdateHeightmap = true; + } + + if (ShouldUpdateHeightmap) + { + a_ChunkDesc.UpdateHeightmap(); } } @@ -349,7 +358,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); m_FinishGens.push_back(new cStructGenMineShafts( - Seed, GridSize, MaxSystemSize, + Seed, GridSize, MaxSystemSize, ChanceCorridor, ChanceCrossing, ChanceStaircase )); } @@ -361,6 +370,12 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed)); } + else if (NoCaseCompare(*itr, "NetherForts") == 0) + { + int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512); + int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 6); + m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxDepth)); + } else if (NoCaseCompare(*itr, "OreNests") == 0) { m_FinishGens.push_back(new cStructGenOreNests(Seed)); diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index 28dc37567..231295c3f 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -1340,7 +1340,7 @@ void cStructGenMineShafts::GetMineShaftSystemsForChunk( BaseX -= NEIGHBORHOOD_SIZE / 2; BaseZ -= NEIGHBORHOOD_SIZE / 2; - // Walk the cache, move each cave system that we want into a_Caves: + // Walk the cache, move each cave system that we want into a_Mineshafts: int StartX = BaseX * m_GridSize; int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_GridSize; int StartZ = BaseZ * m_GridSize; diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp new file mode 100644 index 000000000..25658da46 --- /dev/null +++ b/src/Generating/NetherFortGen.cpp @@ -0,0 +1,265 @@ + +// NetherFortGen.cpp + +// Implements the cNetherFortGen class representing the nether fortress generator + +#include "Globals.h" +#include "NetherFortGen.h" +#include "Prefabs/NetherFortPrefabs.h" + + + + + +static const int NEIGHBORHOOD_SIZE = 3; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cNetherFortGen::cNetherFort: + +class cNetherFortGen::cNetherFort +{ +public: + cNetherFortGen & m_ParentGen; + int m_BlockX, m_BlockZ; + int m_GridSize; + int m_Seed; + cPlacedPieces m_Pieces; + + cNetherFort(cNetherFortGen & a_ParentGen, int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxDepth, int a_Seed) : + m_ParentGen(a_ParentGen), + m_BlockX(a_BlockX), + m_BlockZ(a_BlockZ), + m_GridSize(a_GridSize), + m_Seed(a_Seed) + { + // TODO: Proper Y-coord placement + int BlockY = 64; + + // Generate pieces: + cBFSPieceGenerator pg(m_ParentGen, a_Seed); + pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); + } + + + /** Carves the system into the chunk data */ + void ProcessChunk(cChunkDesc & a_Chunk) + { + for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr) + { + const cPrefab & Prefab = (const cPrefab &)((*itr)->GetPiece()); + Prefab.Draw(a_Chunk, *itr); + } // for itr - m_PlacedPieces[] + } +}; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cNetherFortGen: + +cNetherFortGen::cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth) : + m_Seed(a_Seed), + m_Noise(a_Seed), + m_GridSize(a_GridSize), + m_MaxDepth(a_MaxDepth) +{ + // Initialize the prefabs: + for (size_t i = 0; i < g_NetherFortPrefabs1Count; i++) + { + cPrefab * Prefab = new cPrefab(g_NetherFortPrefabs1[i]); + m_AllPieces.push_back(Prefab); + if (Prefab->HasConnectorType(0)) + { + m_OuterPieces.push_back(Prefab); + } + if (Prefab->HasConnectorType(1)) + { + m_InnerPieces.push_back(Prefab); + } + } + + // Initialize the starting piece prefabs: + for (size_t i = 0; i < g_NetherFortStartingPrefabs1Count; i++) + { + m_StartingPieces.push_back(new cPrefab(g_NetherFortStartingPrefabs1[i])); + } + + // DEBUG: Try one round of placement: + cPlacedPieces Pieces; + cBFSPieceGenerator pg(*this, a_Seed); + pg.PlacePieces(0, 64, 0, a_MaxDepth, Pieces); +} + + + + + +cNetherFortGen::~cNetherFortGen() +{ + ClearCache(); + for (cPieces::iterator itr = m_AllPieces.begin(), end = m_AllPieces.end(); itr != end; ++itr) + { + delete *itr; + } // for itr - m_AllPieces[] + m_AllPieces.clear(); +} + + + + + +void cNetherFortGen::ClearCache(void) +{ + // TODO +} + + + + + +void cNetherFortGen::GetFortsForChunk(int a_ChunkX, int a_ChunkZ, cNetherForts & a_Forts) +{ + int BaseX = a_ChunkX * cChunkDef::Width / m_GridSize; + int BaseZ = a_ChunkZ * cChunkDef::Width / m_GridSize; + if (BaseX < 0) + { + --BaseX; + } + if (BaseZ < 0) + { + --BaseZ; + } + BaseX -= NEIGHBORHOOD_SIZE / 2; + BaseZ -= NEIGHBORHOOD_SIZE / 2; + + // Walk the cache, move each cave system that we want into a_Forts: + int StartX = BaseX * m_GridSize; + int EndX = (BaseX + NEIGHBORHOOD_SIZE + 1) * m_GridSize; + int StartZ = BaseZ * m_GridSize; + int EndZ = (BaseZ + NEIGHBORHOOD_SIZE + 1) * m_GridSize; + for (cNetherForts::iterator itr = m_Cache.begin(), end = m_Cache.end(); itr != end;) + { + if ( + ((*itr)->m_BlockX >= StartX) && ((*itr)->m_BlockX < EndX) && + ((*itr)->m_BlockZ >= StartZ) && ((*itr)->m_BlockZ < EndZ) + ) + { + // want + a_Forts.push_back(*itr); + itr = m_Cache.erase(itr); + } + else + { + // don't want + ++itr; + } + } // for itr - m_Cache[] + + // Create those forts that haven't been in the cache: + for (int x = 0; x < NEIGHBORHOOD_SIZE; x++) + { + int RealX = (BaseX + x) * m_GridSize; + for (int z = 0; z < NEIGHBORHOOD_SIZE; z++) + { + int RealZ = (BaseZ + z) * m_GridSize; + bool Found = false; + for (cNetherForts::const_iterator itr = a_Forts.begin(), end = a_Forts.end(); itr != end; ++itr) + { + if (((*itr)->m_BlockX == RealX) && ((*itr)->m_BlockZ == RealZ)) + { + Found = true; + break; + } + } // for itr - a_Mineshafts + if (!Found) + { + a_Forts.push_back(new cNetherFort(*this, RealX, RealZ, m_GridSize, m_MaxDepth, m_Seed)); + } + } // for z + } // for x + + // Copy a_Forts into m_Cache to the beginning: + cNetherForts FortsCopy (a_Forts); + m_Cache.splice(m_Cache.begin(), FortsCopy, FortsCopy.begin(), FortsCopy.end()); + + // Trim the cache if it's too long: + if (m_Cache.size() > 100) + { + cNetherForts::iterator itr = m_Cache.begin(); + std::advance(itr, 100); + for (cNetherForts::iterator end = m_Cache.end(); itr != end; ++itr) + { + delete *itr; + } + itr = m_Cache.begin(); + std::advance(itr, 100); + m_Cache.erase(itr, m_Cache.end()); + } +} + + + + + +void cNetherFortGen::GenFinish(cChunkDesc & a_ChunkDesc) +{ + int ChunkX = a_ChunkDesc.GetChunkX(); + int ChunkZ = a_ChunkDesc.GetChunkZ(); + cNetherForts Forts; + GetFortsForChunk(ChunkX, ChunkZ, Forts); + for (cNetherForts::const_iterator itr = Forts.begin(); itr != Forts.end(); ++itr) + { + (*itr)->ProcessChunk(a_ChunkDesc); + } // for itr - Forts[] +} + + + + + +cPieces cNetherFortGen::GetPiecesWithConnector(int a_ConnectorType) +{ + switch (a_ConnectorType) + { + case 0: return m_OuterPieces; + case 1: return m_InnerPieces; + default: return cPieces(); + } +} + + + + + +cPieces cNetherFortGen::GetStartingPieces(void) +{ + return m_StartingPieces; +} + + + + + +void cNetherFortGen::PiecePlaced(const cPiece & a_Piece) +{ + UNUSED(a_Piece); +} + + + + + +void cNetherFortGen::Reset(void) +{ + // Nothing needed +} + + + + diff --git a/src/Generating/NetherFortGen.h b/src/Generating/NetherFortGen.h new file mode 100644 index 000000000..10ba01396 --- /dev/null +++ b/src/Generating/NetherFortGen.h @@ -0,0 +1,86 @@ + +// NetherFortGen.h + +// Declares the cNetherFortGen class representing the nether fortress generator + + + + + +#pragma once + +#include "ComposableGenerator.h" +#include "PieceGenerator.h" + + + + + +class cNetherFortGen : + public cFinishGen, + public cPiecePool +{ +public: + cNetherFortGen(int a_Seed, int a_GridSize, int a_MaxDepth); + + virtual ~cNetherFortGen(); + +protected: + class cNetherFort; // fwd: NetherFortGen.cpp + typedef std::list cNetherForts; + + + /** The seed used for generating*/ + int m_Seed; + + /** The noise used for generating */ + cNoise m_Noise; + + /** Average spacing between the fortresses*/ + int m_GridSize; + + /** Maximum depth of the piece-generator tree */ + int m_MaxDepth; + + /** Cache of the most recently used systems. MoveToFront used. */ + cNetherForts m_Cache; + + /** All the pieces that are allowed for building. + This is the list that's used for memory allocation and deallocation for the pieces. */ + cPieces m_AllPieces; + + /** The pieces that are used as starting pieces. + This list is not shared and the pieces need deallocation. */ + cPieces m_StartingPieces; + + /** The pieces that have an "outer" connector. + The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */ + cPieces m_OuterPieces; + + /** The pieces that have an "inner" connector. + The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */ + cPieces m_InnerPieces; + + + /** Clears everything from the cache. + Also invalidates the forst returned by GetFortsForChunk(). */ + void ClearCache(void); + + /** Returns all forts that *may* intersect the given chunk. + The returned forts live within m_Cache.They are valid until the next call + to this function (which may delete some of the pointers). */ + void GetFortsForChunk(int a_ChunkX, int a_ChunkZ, cNetherForts & a_Forts); + + // cFinishGen overrides: + virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; + + // cPiecePool overrides: + virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override; + virtual cPieces GetStartingPieces(void) override; + virtual void PiecePlaced(const cPiece & a_Piece) override; + virtual void Reset(void) override; +} ; + + + + diff --git a/src/Generating/Prefabs/CMakeLists.txt b/src/Generating/Prefabs/CMakeLists.txt new file mode 100644 index 000000000..1e60447e7 --- /dev/null +++ b/src/Generating/Prefabs/CMakeLists.txt @@ -0,0 +1,13 @@ + +cmake_minimum_required (VERSION 2.6) +project (MCServer) + +include_directories ("${PROJECT_SOURCE_DIR}/../../") + +file(GLOB SOURCE + "*.cpp" +) + +add_library(Generating_Prefabs ${SOURCE}) + +target_link_libraries(Generating_Prefabs OSSupport iniFile Blocks) diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp new file mode 100644 index 000000000..ea3a298c0 --- /dev/null +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -0,0 +1,303 @@ + +// NetherFortPrefabs.cpp + +// Defines all the prefabs for nether forts + +#include "Globals.h" +#include "NetherFortPrefabs.h" + + + + + +/* +The nether fortress has two types of connectors, Outer and Inner. Outer is Type 0, Inner is Type 1. +*/ + + + + + +const cPrefab::sDef g_NetherFortPrefabs1[] = +{ + // BalconyCorridor: + // The data has been exported from gallery Nether, area index 37, ID 288 + { + // Size: + 13, 7, 9, // SizeX = 13, SizeY = 7, SizeZ = 9 + + // Block definitions: + "a:112: 0\n" /* netherbrick */ + "b: 0: 0\n" /* air */ + "c:114: 4\n" /* netherbrickstairs */ + "d:114: 7\n" /* netherbrickstairs */ + "e:114: 5\n" /* netherbrickstairs */ + "f: 44: 6\n" /* step */ + "g:113: 0\n" /* netherbrickfence */ + "h:114: 2\n" /* netherbrickstairs */ + "i:114: 3\n" /* netherbrickstairs */ + "j:114: 0\n" /* netherbrickstairs */ + "k:114: 1\n" /* netherbrickstairs */, + + // Block data: + // Level 1 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "bbbbaaaaabbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + + // Level 2 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaabaaabaaaa" + "bbcdaaaaadebb" + "bbbcdddddebbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + + // Level 3 + "aaaaaaaaaaaaa" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "aaaabfffbaaaa" + "bbaaaaaaaaabb" + "bbaaaaaaaaabb" + "bbaaaaaaaaabb" + "bbaaaaaaaaabb" + + // Level 4 + "agagagagagaga" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "agaabbbbbaaga" + "bbaaabbbaaabb" + "bbgbbbbbbbgbb" + "bbgbbbbbbbgbb" + "bbgggggggggbb" + + // Level 5 + "agagagagagaga" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "agaabbbbbaaga" + "bbaaabbbaaabb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + + // Level 6 + "agagagagagaga" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "agaabbbbbaaga" + "bbaaabbbaaabb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + + // Level 7 + "hhhhhhhhhhhhh" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "iijaaaaaaaiii" + "bbjiiiiiiikbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb", + + // Connections: + "1: 0, 2, 2: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 12, 2, 2: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msImprint, + }, +} ; // g_NetherFortPrefabs1 + + + + + +const cPrefab::sDef g_NetherFortStartingPrefabs1[] = +{ + // CentralRoom: + // The data has been exported from gallery Nether, area index 22, ID 164 + { + // Size: + 13, 9, 13, // SizeX = 13, SizeY = 9, SizeZ = 13 + + // Block definitions: + "a:112: 0\n" /* netherbrick */ + "b: 0: 0\n" /* air */ + "c: 10: 0\n" /* lava */ + "d:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "aaaaabbbaaaaa" + "aaaaabbbaaaaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbaaabbbaa" + "aabbbacabbbaa" + "aabbbaaabbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aaaaabbbaaaaa" + "aaaaabbbaaaaa" + + // Level 3 + "aaaaabbbaaaaa" + "aaadabbbadaaa" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "aaadabbbadaaa" + "aaaaabbbaaaaa" + + // Level 4 + "aaaaabbbaaaaa" + "aaadabbbadaaa" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "adbbbbbbbbbda" + "aabbbbbbbbbaa" + "aaadabbbadaaa" + "aaaaabbbaaaaa" + + // Level 5 + "adadabbbadada" + "daaaabbbaaaad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "daaaabbbaaaad" + "adadabbbadada" + + // Level 6 + "adadaaaaadada" + "daaaaaaaaaaad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "dabbbbbbbbbad" + "aabbbbbbbbbaa" + "daaaaaaaaaaad" + "adadaaaaadada" + + // Level 7 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 8 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 9 + "dadadadadadad" + "abbbbbbbbbbba" + "dbbbbbbbbbbbd" + "abbbbbbbbbbba" + "dbbbbbbbbbbbd" + "abbbbbbbbbbba" + "dbbbbbbbbbbbd" + "abbbbbbbbbbba" + "dbbbbbbbbbbbd" + "abbbbbbbbbbba" + "dbbbbbbbbbbbd" + "abbbbbbbbbbba" + "dadadadadadad", + + // Connections: + "0: 6, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "1: 6, 1, 12: 3\n" /* Type 1, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msImprint, + }, +} ; // g_NetherFortStartingPrefabs1 + +const size_t g_NetherFortPrefabs1Count = ARRAYCOUNT(g_NetherFortPrefabs1); +const size_t g_NetherFortStartingPrefabs1Count = ARRAYCOUNT(g_NetherFortStartingPrefabs1); + + + + diff --git a/src/Generating/Prefabs/NetherFortPrefabs.h b/src/Generating/Prefabs/NetherFortPrefabs.h new file mode 100644 index 000000000..37a91689d --- /dev/null +++ b/src/Generating/Prefabs/NetherFortPrefabs.h @@ -0,0 +1,15 @@ + +// NetherFortPrefabs.h + +// Declares the data used for nether fortress prefabs + +#include "../Prefab.h" + + + + + +extern const cPrefab::sDef g_NetherFortPrefabs1[]; +extern const cPrefab::sDef g_NetherFortStartingPrefabs1[]; +extern const size_t g_NetherFortPrefabs1Count; +extern const size_t g_NetherFortStartingPrefabs1Count; -- cgit v1.2.3 From 1802234b4ab58d1afc258a40341e54484c045899 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 16:44:12 +0100 Subject: Fixed compilation after last PR merge. --- src/Simulator/FireSimulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index e4d4a540d..470dfc791 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -7,7 +7,7 @@ #include "../Defines.h" #include "../Chunk.h" #include "Root.h" -#include "PluginManager.h" +#include "../Bindings/PluginManager.h" -- cgit v1.2.3 From ae0954f1d443822f7f6693f0dd42d5601a50f835 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 17:05:43 +0100 Subject: Sponged the netherfort balcony prefab. This is a preparation for the msSpongePrint merge strategy, used for imprinting most prefabs. It will carve out even air, but will ignore sponge blocks. --- src/Generating/Prefabs/NetherFortPrefabs.cpp | 61 ++++++++++++++-------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp index ea3a298c0..29df15c1f 100644 --- a/src/Generating/Prefabs/NetherFortPrefabs.cpp +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -28,7 +28,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Block definitions: "a:112: 0\n" /* netherbrick */ - "b: 0: 0\n" /* air */ + "b: 19: 0\n" /* sponge */ "c:114: 4\n" /* netherbrickstairs */ "d:114: 7\n" /* netherbrickstairs */ "e:114: 5\n" /* netherbrickstairs */ @@ -37,7 +37,8 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = "h:114: 2\n" /* netherbrickstairs */ "i:114: 3\n" /* netherbrickstairs */ "j:114: 0\n" /* netherbrickstairs */ - "k:114: 1\n" /* netherbrickstairs */, + "k:114: 1\n" /* netherbrickstairs */ + "l: 0: 0\n" /* air */, // Block data: // Level 1 @@ -56,7 +57,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = "aaaaaaaaaaaaa" "aaaaaaaaaaaaa" "aaaaaaaaaaaaa" - "aaaabaaabaaaa" + "aaaalaaalaaaa" "bbcdaaaaadebb" "bbbcdddddebbb" "bbbbbbbbbbbbb" @@ -64,10 +65,10 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Level 3 "aaaaaaaaaaaaa" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "aaaabfffbaaaa" + "lllllllllllll" + "lllllllllllll" + "lllllllllllll" + "aaaalffflaaaa" "bbaaaaaaaaabb" "bbaaaaaaaaabb" "bbaaaaaaaaabb" @@ -75,36 +76,36 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Level 4 "agagagagagaga" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "agaabbbbbaaga" - "bbaaabbbaaabb" - "bbgbbbbbbbgbb" - "bbgbbbbbbbgbb" + "lllllllllllll" + "lllllllllllll" + "lllllllllllll" + "agaalllllaaga" + "bbaaalllaaabb" + "bbglllllllgbb" + "bbglllllllgbb" "bbgggggggggbb" // Level 5 "agagagagagaga" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "agaabbbbbaaga" - "bbaaabbbaaabb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" + "lllllllllllll" + "lllllllllllll" + "lllllllllllll" + "agaalllllaaga" + "bbaaalllaaabb" + "bblllllllllbb" + "bblllllllllbb" + "bblllllllllbb" // Level 6 "agagagagagaga" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "agaabbbbbaaga" - "bbaaabbbaaabb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" - "bbbbbbbbbbbbb" + "lllllllllllll" + "lllllllllllll" + "lllllllllllll" + "agaalllllaaga" + "bbaaalllaaabb" + "bblllllllllbb" + "bblllllllllbb" + "bblllllllllbb" // Level 7 "hhhhhhhhhhhhh" -- cgit v1.2.3 From 3c84a995a90122279cdb2f8cd60491e4d33c297f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 17:09:47 +0100 Subject: Fixed a memory leak in NetherFortGen. --- src/Generating/NetherFortGen.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp index 25658da46..d111c7cee 100644 --- a/src/Generating/NetherFortGen.cpp +++ b/src/Generating/NetherFortGen.cpp @@ -29,6 +29,7 @@ public: int m_Seed; cPlacedPieces m_Pieces; + cNetherFort(cNetherFortGen & a_ParentGen, int a_BlockX, int a_BlockZ, int a_GridSize, int a_MaxDepth, int a_Seed) : m_ParentGen(a_ParentGen), m_BlockX(a_BlockX), @@ -43,6 +44,12 @@ public: cBFSPieceGenerator pg(m_ParentGen, a_Seed); pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); } + + + ~cNetherFort() + { + cPieceGenerator::FreePieces(m_Pieces); + } /** Carves the system into the chunk data */ -- cgit v1.2.3 From 113343d336e28613f344aa43cf654baa177463f6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 17:35:05 +0100 Subject: NetherFort: Added BalconyTee2 prefab. --- src/Generating/Prefabs/NetherFortPrefabs.cpp | 187 ++++++++++++++++++++++----- 1 file changed, 158 insertions(+), 29 deletions(-) diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp index 29df15c1f..6d6b11cdd 100644 --- a/src/Generating/Prefabs/NetherFortPrefabs.cpp +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -20,6 +20,7 @@ The nether fortress has two types of connectors, Outer and Inner. Outer is Type const cPrefab::sDef g_NetherFortPrefabs1[] = { + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // BalconyCorridor: // The data has been exported from gallery Nether, area index 37, ID 288 { @@ -38,7 +39,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = "i:114: 3\n" /* netherbrickstairs */ "j:114: 0\n" /* netherbrickstairs */ "k:114: 1\n" /* netherbrickstairs */ - "l: 0: 0\n" /* air */, + ".: 0: 0\n" /* air */, // Block data: // Level 1 @@ -57,7 +58,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = "aaaaaaaaaaaaa" "aaaaaaaaaaaaa" "aaaaaaaaaaaaa" - "aaaalaaalaaaa" + "aaaa.aaa.aaaa" "bbcdaaaaadebb" "bbbcdddddebbb" "bbbbbbbbbbbbb" @@ -65,10 +66,10 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Level 3 "aaaaaaaaaaaaa" - "lllllllllllll" - "lllllllllllll" - "lllllllllllll" - "aaaalffflaaaa" + "............." + "............." + "............." + "aaaa.fff.aaaa" "bbaaaaaaaaabb" "bbaaaaaaaaabb" "bbaaaaaaaaabb" @@ -76,36 +77,36 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Level 4 "agagagagagaga" - "lllllllllllll" - "lllllllllllll" - "lllllllllllll" - "agaalllllaaga" - "bbaaalllaaabb" - "bbglllllllgbb" - "bbglllllllgbb" + "............." + "............." + "............." + "agaa.....aaga" + "bbaaa...aaabb" + "bbg.......gbb" + "bbg.......gbb" "bbgggggggggbb" // Level 5 "agagagagagaga" - "lllllllllllll" - "lllllllllllll" - "lllllllllllll" - "agaalllllaaga" - "bbaaalllaaabb" - "bblllllllllbb" - "bblllllllllbb" - "bblllllllllbb" + "............." + "............." + "............." + "agaa.....aaga" + "bbaaa...aaabb" + "bb.........bb" + "bb.........bb" + "bb.........bb" // Level 6 "agagagagagaga" - "lllllllllllll" - "lllllllllllll" - "lllllllllllll" - "agaalllllaaga" - "bbaaalllaaabb" - "bblllllllllbb" - "bblllllllllbb" - "bblllllllllbb" + "............." + "............." + "............." + "agaa.....aaga" + "bbaaa...aaabb" + "bb.........bb" + "bb.........bb" + "bb.........bb" // Level 7 "hhhhhhhhhhhhh" @@ -125,9 +126,136 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // AllowedRotations: 7, /* 1, 2, 3 CCW rotations */ + // Merge strategy: + cBlockArea::msImprint, + }, // BalconyCorridor + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BalconyTee2: + // The data has been exported from gallery Nether, area index 38, ID 289 + { + // Size: + 13, 7, 11, // SizeX = 13, SizeY = 7, SizeZ = 11 + + // Block definitions: + "a: 19: 0\n" /* sponge */ + "b:112: 0\n" /* netherbrick */ + "c:114: 4\n" /* netherbrickstairs */ + "d:114: 7\n" /* netherbrickstairs */ + "e:114: 5\n" /* netherbrickstairs */ + "f: 44: 6\n" /* step */ + "g:113: 0\n" /* netherbrickfence */ + "h:114: 0\n" /* netherbrickstairs */ + "i:114: 1\n" /* netherbrickstairs */ + "j:114: 2\n" /* netherbrickstairs */ + "k:114: 3\n" /* netherbrickstairs */ + ".: 0: 0\n" /* air */, + + // Block data: + // Level 1 + "aaaabbbbbaaaa" + "aaaabbbbbaaaa" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "aaaabbbbbaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "aaaabbbbbaaaa" + "aaaabbbbbaaaa" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbb.bbb.bbbb" + "aacdbbbbbdeaa" + "aaacdddddeaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 3 + "aaaab...baaaa" + "aaaab...baaaa" + "bbbbb...bbbbb" + "............." + "............." + "............." + "bbbb.fff.bbbb" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + + // Level 4 + "aaaab...baaaa" + "aaaag...gaaaa" + "bgbgb...bgbgb" + "............." + "............." + "............." + "bgbb.....bbgb" + "aabbb...bbbaa" + "aag.......gaa" + "aag.......gaa" + "aagggggggggaa" + + // Level 5 + "aaaab...baaaa" + "aaaag...gaaaa" + "bgbgb...bgbgb" + "............." + "............." + "............." + "bgbb.....bbgb" + "aabbb...bbbaa" + "aa.........aa" + "aa.........aa" + "aa.........aa" + + // Level 6 + "aaaab...baaaa" + "aaaag...gaaaa" + "bgbgb...bgbgb" + "............." + "............." + "............." + "bgbb.....bbgb" + "aabbb...bbbaa" + "aa.........aa" + "aa.........aa" + "aa.........aa" + + // Level 7 + "aaaahbbbiaaaa" + "aaaahbbbiaaaa" + "jjjjjbbbjjjjj" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "bbbbbbbbbbbbb" + "kkhbbbbbbbkkk" + "aahkkkkkkkiaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa", + + // Connections: + "1: 0, 2, 4: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 12, 2, 4: 5\n" /* Type 1, BLOCK_FACE_XP */ + "1: 6, 2, 0: 2\n" /* Type 1, BLOCK_FACE_ZM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + // Merge strategy: cBlockArea::msImprint, }, + } ; // g_NetherFortPrefabs1 @@ -136,6 +264,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = const cPrefab::sDef g_NetherFortStartingPrefabs1[] = { + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CentralRoom: // The data has been exported from gallery Nether, area index 22, ID 164 { -- cgit v1.2.3 From 8557549cfac260867112be96e24b2c0e059db47e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 18:03:37 +0100 Subject: Implemented the msSpongePrint merge strategy. Similar to msImprint, but allows prefabs to carve out air pockets, too. The sponge block is used as the NOP block. --- MCServer/Plugins/APIDump/APIDesc.lua | 24 +++++++++++++++--- src/BlockArea.cpp | 38 +++++++++++++++++++++++++--- src/BlockArea.h | 13 ++++++++-- src/Generating/Prefabs/NetherFortPrefabs.cpp | 6 ++--- 4 files changed, 68 insertions(+), 13 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 01f000182..6f8a14421 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -258,12 +258,11 @@ g_APIDesc =

    -

    - Special strategies: -

    +

    Special strategies

    +

    For each strategy, evaluate the table rows from top downwards, the first match wins.

    - msLake (evaluate top-down, first match wins): + msLake - used for merging areas with lava and water lakes, in the appropriate generator.

    SourceNotes
    @@ -293,6 +292,23 @@ g_APIDesc =
    area block Notes A * A Everything else is left as it is
    + + +

    + msSpongePrint - used for most prefab-generators to merge the prefabs. Similar to + msImprint, but uses the sponge block as the NOP block instead, so that the prefabs may carve out air + pockets, too. +

    + + + + + + + + + +
    area block Notes
    this Src result
    A sponge A Sponge is the NOP block
    * B B Everything else overwrites anything
    ]], }, -- Merge strategies }, -- AdditionalInfo diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index f6d54e41c..2b950378a 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -54,7 +54,7 @@ template void InternalMergeBlocks( /// Combinator used for cBlockArea::msOverwrite merging -static void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +static inline void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { a_DstType = a_SrcType; a_DstMeta = a_SrcMeta; @@ -65,7 +65,7 @@ static void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, /// Combinator used for cBlockArea::msFillAir merging -static void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +static inline void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { if (a_DstType == E_BLOCK_AIR) { @@ -80,7 +80,7 @@ static void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, N /// Combinator used for cBlockArea::msImprint merging -static void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +static inline void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { if (a_SrcType != E_BLOCK_AIR) { @@ -95,7 +95,7 @@ static void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, N /// Combinator used for cBlockArea::msLake merging -static void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +static inline void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) { // Sponge is the NOP block if (a_SrcType == E_BLOCK_SPONGE) @@ -158,6 +158,21 @@ static void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBB +/** Combinator used for cBlockArea::msSpongePrint merging */ +static inline void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +{ + // Sponge overwrites nothing, everything else overwrites anything + if (a_SrcType != E_BLOCK_SPONGE) + { + a_DstType = a_SrcType; + a_DstMeta = a_SrcMeta; + } +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cBlockArea: @@ -680,6 +695,21 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R break; } // case msLake + case msSpongePrint: + { + InternalMergeBlocks( + m_BlockTypes, a_Src.GetBlockTypes(), + DstMetas, SrcMetas, + SizeX, SizeY, SizeZ, + SrcOffX, SrcOffY, SrcOffZ, + DstOffX, DstOffY, DstOffZ, + a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), + m_Size.x, m_Size.y, m_Size.z, + MergeCombinatorSpongePrint + ); + break; + } // case msSpongePrint + default: { LOGWARNING("Unknown block area merge strategy: %d", a_Strategy); diff --git a/src/BlockArea.h b/src/BlockArea.h index d28325d7d..d37f0d182 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -51,6 +51,7 @@ public: msFillAir, msImprint, msLake, + msSpongePrint, } ; cBlockArea(void); @@ -127,8 +128,8 @@ public: - msFillAir overwrites only those blocks that were air - msImprint overwrites with only those blocks that are non-air - Special strategies: - msLake (evaluate top-down, first match wins): + Special strategies (evaluate top-down, first match wins): + msLake: | area block | | | this | Src | result | +----------+--------+--------+ @@ -143,6 +144,14 @@ public: | mycelium | stone | stone | ... and mycelium | A | stone | A | ... but nothing else | A | * | A | Everything else is left as it is + + msSpongePrint: + Used for most generators, it allows carving out air pockets, too, and uses the Sponge as the NOP block + | area block | | + | this | Src | result | + +----------+--------+--------+ + | A | sponge | A | Sponge is the NOP block + | * | B | B | Everything else overwrites anything */ void Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy); diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp index 6d6b11cdd..31eaa5078 100644 --- a/src/Generating/Prefabs/NetherFortPrefabs.cpp +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -127,7 +127,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = 7, /* 1, 2, 3 CCW rotations */ // Merge strategy: - cBlockArea::msImprint, + cBlockArea::msSpongePrint, }, // BalconyCorridor @@ -253,7 +253,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = 7, /* 1, 2, 3 CCW rotations */ // Merge strategy: - cBlockArea::msImprint, + cBlockArea::msSpongePrint, }, } ; // g_NetherFortPrefabs1 @@ -421,7 +421,7 @@ const cPrefab::sDef g_NetherFortStartingPrefabs1[] = 7, /* 1, 2, 3 CCW rotations */ // Merge strategy: - cBlockArea::msImprint, + cBlockArea::msSpongePrint, }, } ; // g_NetherFortStartingPrefabs1 -- cgit v1.2.3 From 773ce7fde692e86531e1e92f42776e316b793d83 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 21:35:45 +0100 Subject: Fixed non-virtual destructors warnings. --- src/Bindings/PluginManager.h | 2 ++ src/Blocks/BroadcastInterface.h | 3 ++- src/Blocks/WorldInterface.h | 3 ++- src/ForEachChunkProvider.h | 2 ++ src/Globals.h | 10 +++++++-- src/HTTPServer/HTTPServer.h | 4 +++- src/Inventory.h | 2 ++ src/ItemGrid.h | 46 +++++++++++++++++++++-------------------- src/OSSupport/ListenThread.h | 20 ++++++++++-------- src/RCONServer.h | 2 +- src/UI/WindowOwner.h | 4 ++++ 11 files changed, 61 insertions(+), 37 deletions(-) diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 03f19e831..7895be959 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -128,6 +128,8 @@ public: // tolua_export class cCommandEnumCallback { public: + virtual ~cCommandEnumCallback() {} + /** Called for each command; return true to abort enumeration For console commands, a_Permission is not used (set to empty string) */ diff --git a/src/Blocks/BroadcastInterface.h b/src/Blocks/BroadcastInterface.h index 01966ffbd..b1b450690 100644 --- a/src/Blocks/BroadcastInterface.h +++ b/src/Blocks/BroadcastInterface.h @@ -4,7 +4,8 @@ class cBroadcastInterface { public: - + virtual ~cBroadcastInterface() {} + virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; virtual void BroadcastSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = NULL) = 0; virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) = 0; diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index 580339d32..bfbb053d9 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -9,7 +9,8 @@ class cItems; class cWorldInterface { public: - + virtual ~cWorldInterface() {} + virtual Int64 GetTimeOfDay(void) const = 0; virtual Int64 GetWorldAge(void) const = 0; diff --git a/src/ForEachChunkProvider.h b/src/ForEachChunkProvider.h index 6017173ee..7a6e8c5c6 100644 --- a/src/ForEachChunkProvider.h +++ b/src/ForEachChunkProvider.h @@ -24,6 +24,8 @@ class cBlockArea; class cForEachChunkProvider { public: + virtual ~cForEachChunkProvider() {} + /** Calls the callback for each chunk in the specified range. */ virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) = 0; diff --git a/src/Globals.h b/src/Globals.h index 3e62832b7..a1cee5c2f 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -264,11 +264,17 @@ template class SizeChecker; #define assert_test(x) ( !!(x) || (assert(!#x), exit(1), 0)) #endif -/// A generic interface used mainly in ForEach() functions + + + + +/** A generic interface used mainly in ForEach() functions */ template class cItemCallback { public: - /// Called for each item in the internal list; return true to stop the loop, or false to continue enumerating + virtual ~cItemCallback() {} + + /** Called for each item in the internal list; return true to stop the loop, or false to continue enumerating */ virtual bool Item(Type * a_Type) = 0; } ; diff --git a/src/HTTPServer/HTTPServer.h b/src/HTTPServer/HTTPServer.h index 24baf8c95..383abb4b6 100644 --- a/src/HTTPServer/HTTPServer.h +++ b/src/HTTPServer/HTTPServer.h @@ -37,6 +37,8 @@ public: class cCallbacks { public: + virtual ~cCallbacks() {} + /** Called when a new request arrives over a connection and its headers have been parsed. The request body needn't have arrived yet. */ @@ -50,7 +52,7 @@ public: } ; cHTTPServer(void); - ~cHTTPServer(); + virtual ~cHTTPServer(); /// Initializes the server on the specified ports bool Initialize(const AString & a_PortsIPv4, const AString & a_PortsIPv6); diff --git a/src/Inventory.h b/src/Inventory.h index fd2089a13..1ad7c4776 100644 --- a/src/Inventory.h +++ b/src/Inventory.h @@ -52,6 +52,8 @@ public: cInventory(cPlayer & a_Owner); + virtual ~cInventory() {} + // tolua_begin /// Removes all items from the entire inventory diff --git a/src/ItemGrid.h b/src/ItemGrid.h index b344e3daf..c34d5e9e2 100644 --- a/src/ItemGrid.h +++ b/src/ItemGrid.h @@ -20,11 +20,13 @@ class cItemGrid public: // tolua_end - /// This class is used as a callback for when a slot changes + /** This class is used as a callback for when a slot changes */ class cListener { public: - /// Called whenever a slot changes + virtual ~cListener() {} + + /** Called whenever a slot changes */ virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) = 0; } ; typedef std::vector cListeners; @@ -38,12 +40,12 @@ public: int GetHeight (void) const { return m_Height; } int GetNumSlots(void) const { return m_NumSlots; } - /// Converts XY coords into slot number; returns -1 on invalid coords + /** Converts XY coords into slot number; returns -1 on invalid coords */ int GetSlotNum(int a_X, int a_Y) const; // tolua_end - /// Converts slot number into XY coords; sets coords to -1 on invalid slot number. Exported in ManualBindings.cpp + /** Converts slot number into XY coords; sets coords to -1 on invalid slot number. Exported in ManualBindings.cpp */ void GetSlotCoords(int a_SlotNum, int & a_X, int & a_Y) const; // tolua_begin @@ -62,16 +64,16 @@ public: void EmptySlot(int a_X, int a_Y); void EmptySlot(int a_SlotNum); - /// Returns true if the specified slot is empty or the slot doesn't exist + /** Returns true if the specified slot is empty or the slot doesn't exist */ bool IsSlotEmpty(int a_SlotNum) const; - /// Returns true if the specified slot is empty or the slot doesn't exist + /** Returns true if the specified slot is empty or the slot doesn't exist */ bool IsSlotEmpty(int a_X, int a_Y) const; - /// Sets all items as empty + /** Sets all items as empty */ void Clear(void); - /// Returns number of items out of a_ItemStack that can fit in the storage + /** Returns number of items out of a_ItemStack that can fit in the storage */ int HowManyCanFit(const cItem & a_ItemStack, bool a_AllowNewStacks = true); /** Adds as many items out of a_ItemStack as can fit. @@ -117,37 +119,37 @@ public: */ cItem RemoveOneItem(int a_X, int a_Y); - /// Returns the number of items of type a_Item that are stored + /** Returns the number of items of type a_Item that are stored */ int HowManyItems(const cItem & a_Item); - /// Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack + /** Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack */ bool HasItems(const cItem & a_ItemStack); - /// Returns the index of the first empty slot; -1 if all full + /** Returns the index of the first empty slot; -1 if all full */ int GetFirstEmptySlot(void) const; - /// Returns the index of the first non-empty slot; -1 if all empty + /** Returns the index of the first non-empty slot; -1 if all empty */ int GetFirstUsedSlot(void) const; - /// Returns the index of the last empty slot; -1 if all full + /** Returns the index of the last empty slot; -1 if all full */ int GetLastEmptySlot(void) const; - /// Returns the index of the last used slot; -1 if all empty + /** Returns the index of the last used slot; -1 if all empty */ int GetLastUsedSlot(void) const; - /// Returns the index of the first empty slot following a_StartFrom (a_StartFrom is not checked) + /** Returns the index of the first empty slot following a_StartFrom (a_StartFrom is not checked) */ int GetNextEmptySlot(int a_StartFrom) const; - /// Returns the index of the first used slot following a_StartFrom (a_StartFrom is not checked) + /** Returns the index of the first used slot following a_StartFrom (a_StartFrom is not checked) */ int GetNextUsedSlot(int a_StartFrom) const; - /// Copies the contents into a cItems object; preserves the original a_Items contents + /** Copies the contents into a cItems object; preserves the original a_Items contents */ void CopyToItems(cItems & a_Items) const; - /// Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) + /** Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) */ bool DamageItem(int a_SlotNum, short a_Amount); - /// Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) + /** Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) */ bool DamageItem(int a_X, int a_Y, short a_Amount); // tolua_end @@ -159,10 +161,10 @@ public: */ void GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, size_t a_CountLootProbabs, int a_NumSlots, int a_Seed); - /// Adds a callback that gets called whenever a slot changes. Must not be called from within the listener callback! + /** Adds a callback that gets called whenever a slot changes. Must not be called from within the listener callback! */ void AddListener(cListener & a_Listener); - /// Removes a slot-change-callback. Must not be called from within the listener callback! + /** Removes a slot-change-callback. Must not be called from within the listener callback! */ void RemoveListener(cListener & a_Listener); // tolua_begin @@ -177,7 +179,7 @@ protected: cCriticalSection m_CSListeners; ///< CS that guards the m_Listeners against multi-thread access bool m_IsInTriggerListeners; ///< Set to true while TriggerListeners is running, to detect attempts to manipulate listener list while triggerring - /// Calls all m_Listeners for the specified slot number + /** Calls all m_Listeners for the specified slot number */ void TriggerListeners(int a_SlotNum); /** Adds up to a_Num items out of a_ItemStack, as many as can fit, in specified slot diff --git a/src/OSSupport/ListenThread.h b/src/OSSupport/ListenThread.h index 4e337d814..b2d806c82 100644 --- a/src/OSSupport/ListenThread.h +++ b/src/OSSupport/ListenThread.h @@ -29,43 +29,45 @@ class cListenThread : typedef cIsThread super; public: - /// Used as the callback for connection events + /** Used as the callback for connection events */ class cCallback { public: - /// This callback is called whenever a socket connection is accepted + virtual ~cCallback() {} + + /** This callback is called whenever a socket connection is accepted */ virtual void OnConnectionAccepted(cSocket & a_Socket) = 0; } ; cListenThread(cCallback & a_Callback, cSocket::eFamily a_Family, const AString & a_ServiceName = ""); ~cListenThread(); - /// Creates all the sockets, returns trus if successful, false if not. + /** Creates all the sockets, returns trus if successful, false if not. */ bool Initialize(const AString & a_PortsString); bool Start(void); void Stop(void); - /// Call before Initialize() to set the "reuse" flag on the sockets + /** Call before Initialize() to set the "reuse" flag on the sockets */ void SetReuseAddr(bool a_Reuse = true); protected: typedef std::vector cSockets; - /// The callback which to notify of incoming connections + /** The callback which to notify of incoming connections */ cCallback & m_Callback; - /// Socket address family to use + /** Socket address family to use */ cSocket::eFamily m_Family; - /// Sockets that are being monitored + /** Sockets that are being monitored */ cSockets m_Sockets; - /// If set to true, the SO_REUSEADDR socket option is set to true + /** If set to true, the SO_REUSEADDR socket option is set to true */ bool m_ShouldReuseAddr; - /// Name of the service that's listening on the ports; for logging purposes only + /** Name of the service that's listening on the ports; for logging purposes only */ AString m_ServiceName; diff --git a/src/RCONServer.h b/src/RCONServer.h index 0e89800a2..88aac4b5f 100644 --- a/src/RCONServer.h +++ b/src/RCONServer.h @@ -29,7 +29,7 @@ class cRCONServer : { public: cRCONServer(cServer & a_Server); - ~cRCONServer(); + virtual ~cRCONServer(); void Initialize(cIniFile & a_IniFile); diff --git a/src/UI/WindowOwner.h b/src/UI/WindowOwner.h index d41abf66d..e3c73edc4 100644 --- a/src/UI/WindowOwner.h +++ b/src/UI/WindowOwner.h @@ -33,6 +33,10 @@ public: { } + virtual ~cWindowOwner() + { + } + void CloseWindow(void) { m_Window = NULL; -- cgit v1.2.3 From 0f1087b7d51d998ac311c16588c599938934f2bd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 22:04:59 +0100 Subject: Added Prefabs to *nix builds. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ca874517e..30e9dbfd4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -232,7 +232,7 @@ endif () if (NOT MSVC) target_link_libraries(${EXECUTABLE} OSSupport HTTPServer Bindings Items Blocks) - target_link_libraries(${EXECUTABLE} Protocol Generating WorldStorage) + target_link_libraries(${EXECUTABLE} Protocol Generating Generating_Prefabs WorldStorage) target_link_libraries(${EXECUTABLE} Mobs Entities Simulator UI BlockEntities) endif () if (WIN32) -- cgit v1.2.3 From 76f0d167b15de08a810a1348614e8b8c2b6f2e60 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 23:39:40 +0100 Subject: NetherFortGen: Added several more prefabs. Also extended the defauls MaxDepth value to 12. --- src/Generating/ComposableGenerator.cpp | 2 +- src/Generating/Prefabs/NetherFortPrefabs.cpp | 783 ++++++++++++++++++++++++++- 2 files changed, 783 insertions(+), 2 deletions(-) diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 339f5709a..2e886336f 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -373,7 +373,7 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) else if (NoCaseCompare(*itr, "NetherForts") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "NetherFortsGridSize", 512); - int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 6); + int MaxDepth = a_IniFile.GetValueSetI("Generator", "NetherFortsMaxDepth", 12); m_FinishGens.push_back(new cNetherFortGen(Seed, GridSize, MaxDepth)); } else if (NoCaseCompare(*itr, "OreNests") == 0) diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp index 31eaa5078..24bde1baf 100644 --- a/src/Generating/Prefabs/NetherFortPrefabs.cpp +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -254,8 +254,789 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Merge strategy: cBlockArea::msSpongePrint, - }, + }, // BalconyTee2 + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BlazePlatform + // The data has been exported from gallery Nether, area index 26, ID 276 + { + // Size: + 10, 7, 7, // SizeX = 10, SizeY = 7, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b: 52: 0\n" /* mobspawner */ + "c:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + ".........." + "aaaaaaaaaa" + "aaaaaaaaaa" + "aaaaaaaaaa" + "aaaaaaaaaa" + "aaaaaaaaaa" + ".........." + + // Level 2 + ".........." + "aaaaaaaaaa" + "..aaaaaaaa" + "..aaaaaaaa" + "..aaaaaaaa" + "aaaaaaaaaa" + ".........." + + // Level 3 + "....aaaaaa" + "aaaaaaaaaa" + "...aaaaaaa" + "...aaaaaaa" + "...aaaaaaa" + "aaaaaaaaaa" + "....aaaaaa" + + // Level 4 + "....aaaaaa" + "..aaa....a" + ".........a" + "......b..a" + ".........a" + "..aaa....a" + "....aaaaaa" + + // Level 5 + "....cccccc" + "...cc....c" + ".........c" + ".........c" + ".........c" + "...cc....c" + "....cccccc" + + // Level 6 + ".........." + ".........c" + ".........c" + ".........c" + ".........c" + ".........c" + ".........." + + // Level 7 + ".........." + ".........." + ".........c" + ".........c" + ".........c" + ".........." + "..........", + + // Connections: + "0: 0, 1, 3: 4\n" /* Type 0, BLOCK_FACE_XM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BlazePlatform + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BlazePlatformOverhang: + // The data has been exported from gallery Nether, area index 20, ID 162 + { + // Size: + 14, 9, 7, // SizeX = 14, SizeY = 9, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* 0 */ + "a:112: 0\n" /* netherbrick */ + "b:114: 5\n" /* netherbrickstairs */ + "c: 44:14\n" /* step */ + "d:114: 6\n" /* netherbrickstairs */ + "e:114: 7\n" /* netherbrickstairs */ + "f:114: 0\n" /* netherbrickstairs */ + "g:114: 4\n" /* netherbrickstairs */ + "h:113: 0\n" /* netherbrickfence */ + "i: 52: 0\n" /* mobspawner */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + "aammmmmmmmmmmm" + "aammmmmmmmmmmm" + "aammmmmmmmmmmm" + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + + // Level 2 + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + "aabcmmmmmmmmmm" + "aabcmmmmmmmmmm" + "aabcmmmmmmmmmm" + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + + // Level 3 + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + "aaaaabmmmmmmmm" + "aaaaabmmmmmmmm" + "aaaaabmmmmmmmm" + "mmmmmmmmmmmmmm" + "mmmmmmmmmmmmmm" + + // Level 4 + "mmmmmmmmmmmmmm" + "dddddddmmmmmmm" + "aaaaaabmmmmmmm" + "aaaaaabmmmmmmm" + "aaaaaabmmmmmmm" + "eeeeeeemmmmmmm" + "mmmmmmmmmmmmmm" + + // Level 5 + "mmmmmmmmmmmmmm" + "aaaaaaadmmmmmm" + "aaaaaaabmmmmmm" + "aaaaaaabmmmmmm" + "aaaaaaabmmmmmm" + "aaaaaaaemmmmmm" + "mmmmmmmmmmmmmm" + + // Level 6 + "mmmmmmmmmmmmmm" + "aaaaaaaabddddm" + "......faaaaabm" + "......faaaaabm" + "......faaaaabm" + "aaaaaaaaabeebm" + "mmmmmmmmmmmmmm" + + // Level 7 + "mmmmmmmmgdddbm" + "......aaaaaaad" + ".......faaaaab" + ".......faaaaab" + ".......faaaaab" + "......aaaaaaae" + "mmmmmmmmgeeebm" + + // Level 8 + "mmmmmmmmaaaaam" + "......haa...aa" + ".............a" + "..........i..a" + ".............a" + "......haa...aa" + "mmmmmmmmaaaaam" + + // Level 9 + "mmmmmmmmhhhhhm" + "......hhh...hh" + ".............h" + ".............h" + ".............h" + "......hhh...hh" + "mmmmmmmmhhhhhm", + + // Connections: + "0: 0, 5, 3: 4\n" /* Type 0, BLOCK_FACE_XM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BlazePlatformOverhang + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BridgeCrossing: + // The data has been exported from gallery Nether, area index 17, ID 159 + { + // Size: + 15, 8, 15, // SizeX = 15, SizeY = 8, SizeZ = 15 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:114: 7\n" /* netherbrickstairs */ + "c:114: 5\n" /* netherbrickstairs */ + "d:114: 4\n" /* netherbrickstairs */ + "e:114: 6\n" /* netherbrickstairs */ + "f: 44:14\n" /* step */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 2 + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmbbbmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "aacmmmmmmmmmdaa" + "aacmmmmmmmmmdaa" + "aacmmmmmmmmmdaa" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmeeemmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 3 + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmbbbmmmmmm" + "mmmmmmfffmmmmmm" + "mmmmmmmmmmmmmmm" + "aaacfmmmmmfdaaa" + "aaacfmmmmmfdaaa" + "aaacfmmmmmfdaaa" + "mmmmmmmmmmmmmmm" + "mmmmmmfffmmmmmm" + "mmmmmmeeemmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 4 + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "eeeeeeaaaeeeeee" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "bbbbbdaaacbbbbb" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + "mmmmmdaaacmmmmm" + + // Level 5 + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + + // Level 6 + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "aaaaaa...aaaaaa" + "..............." + "..............." + "..............." + "aaaaaa...aaaaaa" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + + // Level 7 + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "..............." + "..............." + "..............." + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + + // Level 8 + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "..............." + "..............." + "..............." + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm", + + // Connections: + "0: 0, 5, 7: 4\n" /* Type 0, BLOCK_FACE_XM */ + "0: 7, 5, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "0: 14, 5, 7: 5\n" /* Type 0, BLOCK_FACE_XP */ + "0: 7, 5, 14: 3\n" /* Type 0, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BridgeCrossing + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BridgeCrumble1: + // The data has been exported from gallery Nether, area index 19, ID 161 + { + // Size: + 9, 6, 5, // SizeX = 9, SizeY = 6, SizeZ = 5 + + // Block definitions: + ".: 19: 0\n" /* sponge */ + "a:112: 0\n" /* netherbrick */ + "b:114: 5\n" /* netherbrickstairs */ + "c: 44:14\n" /* step */ + "d:114: 6\n" /* netherbrickstairs */ + "e:114: 7\n" /* netherbrickstairs */, + + // Block data: + // Level 1 + "........." + "aa......." + "aa......." + "aa......." + "........." + + // Level 2 + "........." + "aab......" + "aab......" + "aab......" + "........." + + // Level 3 + "........." + "aaabc...." + "aaabc...." + "aaabc...." + "........." + + // Level 4 + "ddddddd.." + "aaaaaaaa." + "aaaaaaaaa" + "aaaaaaa.." + "eeeee...." + + // Level 5 + "aaaaaaaaa" + "aaaaa...." + "aaaaaa..." + "aaaaaa..." + "aaaaaaaa." + + // Level 6 + "aaaaaa..." + "........." + "........." + "........." + "aaaaaaa..", + + // Connections: + "0: 0, 5, 2: 4\n" /* Type 0, BLOCK_FACE_XM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BridgeCrumble1 + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BridgeCrumble2 + // The data has been exported from gallery Nether, area index 18, ID 160 + { + // Size: + 13, 6, 5, // SizeX = 13, SizeY = 6, SizeZ = 5 + + // Block definitions: + ".: 19: 0\n" /* sponge */ + "a:112: 0\n" /* netherbrick */ + "b:114: 5\n" /* netherbrickstairs */ + "c: 44:14\n" /* step */ + "d:114: 6\n" /* netherbrickstairs */ + "e:114: 7\n" /* netherbrickstairs */, + + // Block data: + // Level 1 + "............." + "aa..........." + "aa..........." + "aa..........." + "............." + + // Level 2 + "............." + "aab.........." + "aab.........." + "aab.........." + "............." + // Level 3 + "............." + "aaabc........" + "aaabc........" + "aaabc........" + "............." + + // Level 4 + "ddddddddd...." + "aaaaaaaaaaaaa" + "aaaaaaaaa...." + "aaaaaaaaaaaa." + "eeeeeeeee...." + + // Level 5 + "aaaaaaaaaaaa." + "aaaaaaaaaa..." + "aaaaaaaaaaa.." + "aaaaaaaaa...." + "aaaaaaaaaaaaa" + + // Level 6 + "aaaaaaaaa...." + "............." + "............." + "............." + "aaaaaaaaaa...", + + // Connections: + "0: 0, 5, 2: 4\n" /* Type 0, BLOCK_FACE_XM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BridgeCrumble2 + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BridgeSegment: + // The data has been exported from gallery Nether, area index 16, ID 158 + { + // Size: + 15, 8, 5, // SizeX = 15, SizeY = 8, SizeZ = 5 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:114: 5\n" /* netherbrickstairs */ + "c:114: 4\n" /* netherbrickstairs */ + "d: 44:14\n" /* step */ + "e:114: 6\n" /* netherbrickstairs */ + "f:114: 7\n" /* netherbrickstairs */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmmmmmmmmmmmm" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "mmmmmmmmmmmmmmm" + + // Level 2 + "mmmmmmmmmmmmmmm" + "aabmmmmmmmmmcaa" + "aabmmmmmmmmmcaa" + "aabmmmmmmmmmcaa" + "mmmmmmmmmmmmmmm" + + // Level 3 + "mmmmmmmmmmmmmmm" + "aaabdmmmmmdcaaa" + "aaabdmmmmmdcaaa" + "aaabdmmmmmdcaaa" + "mmmmmmmmmmmmmmm" + + // Level 4 + "eeeeeeeeeeeeeee" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "fffffffffffffff" + + // Level 5 + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + + // Level 6 + "aaaaaaaaaaaaaaa" + "..............." + "..............." + "..............." + "aaaaaaaaaaaaaaa" + + // Level 7 + "mmmmmmmmmmmmmmm" + "..............." + "..............." + "..............." + "mmmmmmmmmmmmmmm" + + // Level 8 + "mmmmmmmmmmmmmmm" + "..............." + "..............." + "..............." + "mmmmmmmmmmmmmmm", + + // Connections: + "0: 0, 5, 2: 4\n" /* Type 0, BLOCK_FACE_XM */ + "0: 14, 5, 2: 5\n" /* Type 0, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BridgeSegment + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Corridor13: + // The data has been exported from gallery Nether, area index 35, ID 286 + { + // Size: + 13, 6, 5, // SizeX = 13, SizeY = 6, SizeZ = 5 + + // Block definitions: + "a:112: 0\n" /* netherbrick */ + ".: 0: 0\n" /* air */ + "c:113: 0\n" /* netherbrickfence */ + "d:114: 2\n" /* netherbrickstairs */ + "e:114: 3\n" /* netherbrickstairs */, + + // Block data: + // Level 1 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "aaaaaaaaaaaaa" + "............." + "............." + "............." + "aaaaaaaaaaaaa" + + // Level 3 + "acacacacacaca" + "............." + "............." + "............." + "acacacacacaca" + + // Level 4 + "acacacacacaca" + "............." + "............." + "............." + "acacacacacaca" + + // Level 5 + "acacacacacaca" + "............." + "............." + "............." + "acacacacacaca" + + // Level 6 + "ddddddddddddd" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "eeeeeeeeeeeee", + + // Connections: + "1: 0, 1, 2: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 12, 1, 2: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // Corridor13 + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // CorridorStairs: + // The data has been exported from gallery Nether, area index 12, ID 42 + { + // Size: + 9, 13, 5, // SizeX = 9, SizeY = 13, SizeZ = 5 + + // Block definitions: + ".: 0: 0\n" /* 0 */ + "a:112: 0\n" /* netherbrick */ + "b:114: 0\n" /* netherbrickstairs */ + "c:113: 0\n" /* netherbrickfence */ + "d:114: 2\n" /* netherbrickstairs */ + "e:114: 3\n" /* netherbrickstairs */ + "f: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "aaaaaaaaa" + "aaaaaaaaa" + "aaaaaaaaa" + "aaaaaaaaa" + "aaaaaaaaa" + + // Level 2 + "aaaaaaaaa" + ".baaaaaaa" + ".baaaaaaa" + ".baaaaaaa" + "aaaaaaaaa" + + // Level 3 + "acaaaaaaa" + "..baaaaaa" + "..baaaaaa" + "..baaaaaa" + "acaaaaaaa" + + // Level 4 + "acaaaaaaa" + "...baaaaa" + "...baaaaa" + "...baaaaa" + "acaaaaaaa" + + // Level 5 + "acacaaaaa" + "....baaaa" + "....baaaa" + "....baaaa" + "acacaaaaa" + + // Level 6 + "aaacaaaaa" + ".....baaa" + ".....baaa" + ".....baaa" + "aaacaaaaa" + + // Level 7 + "daacacaaa" + "a.....baa" + "a.....baa" + "a.....baa" + "eaacacaaa" + + // Level 8 + "fdaaacaaa" + "fa.....ba" + "fa.....ba" + "fa.....ba" + "feaaacaaa" + + // Level 9 + "ffdaacaca" + "ffa......" + "ffa......" + "ffa......" + "ffeaacaca" + + // Level 10 + "fffdaaaca" + "fffa....." + "fffa....." + "fffa....." + "fffeaaaca" + + // Level 11 + "ffffdaaca" + "ffffa...." + "ffffa...." + "ffffa...." + "ffffeaaca" + + // Level 12 + "fffffdaaa" + "fffffa..." + "fffffa..." + "fffffa..." + "fffffeaaa" + + // Level 13 + "ffffffddd" + "ffffffaaa" + "ffffffaaa" + "ffffffaaa" + "ffffffeee", + + // Connections: + "1: 0, 1, 2: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 8, 8, 2: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // CorridorStairs } ; // g_NetherFortPrefabs1 -- cgit v1.2.3 From 283a66bcae5f26d2b5038ba0959314a687c4d8b6 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 22:51:30 +0000 Subject: Some fixes to lilypads * Fixed placement on lava * Fixed placement on side of blocks * Fixed placement through blocks + Added washing-away of pads + Added ice as a block that fully occupies its voxel --- src/BlockInfo.cpp | 3 +- src/Blocks/BlockLilypad.h | 66 ++---------------------- src/Items/ItemHandler.cpp | 2 + src/Items/ItemLilypad.h | 106 +++++++++++++++++++++++++++++++++++++++ src/Simulator/FluidSimulator.cpp | 1 + 5 files changed, 116 insertions(+), 62 deletions(-) create mode 100644 src/Items/ItemLilypad.h diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 7d438ba3e..6fb5aa5b3 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -365,7 +365,7 @@ void cBlockInfo::Initialize(void) ms_Info[E_BLOCK_WOODEN_SLAB ].m_IsSolid = false; - // Torch placeable blocks: + // Blocks that fully occupy their voxel - used as a guide for torch placeable blocks, amongst other things: ms_Info[E_BLOCK_NEW_LOG ].m_FullyOccupiesVoxel = true; ms_Info[E_BLOCK_BEDROCK ].m_FullyOccupiesVoxel = true; ms_Info[E_BLOCK_BLOCK_OF_COAL ].m_FullyOccupiesVoxel = true; @@ -397,6 +397,7 @@ void cBlockInfo::Initialize(void) ms_Info[E_BLOCK_HAY_BALE ].m_FullyOccupiesVoxel = true; ms_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_FullyOccupiesVoxel = true; ms_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_FullyOccupiesVoxel = true; + ms_Info[E_BLOCK_ICE ].m_FullyOccupiesVoxel = true; ms_Info[E_BLOCK_IRON_BLOCK ].m_FullyOccupiesVoxel = true; ms_Info[E_BLOCK_IRON_ORE ].m_FullyOccupiesVoxel = true; ms_Info[E_BLOCK_JACK_O_LANTERN ].m_FullyOccupiesVoxel = true; diff --git a/src/Blocks/BlockLilypad.h b/src/Blocks/BlockLilypad.h index 3db280d80..2dd4ec768 100644 --- a/src/Blocks/BlockLilypad.h +++ b/src/Blocks/BlockLilypad.h @@ -2,10 +2,7 @@ #pragma once #include "BlockHandler.h" -#include "../Entities/Player.h" -#include "Vector3.h" -#include "../LineBlockTracer.h" - +#include "Entities/Pickup.h" @@ -13,69 +10,16 @@ class cBlockLilypadHandler : public cBlockHandler { - typedef cBlockHandler super; - public: cBlockLilypadHandler(BLOCKTYPE a_BlockType) : cBlockHandler(a_BlockType) { - } - - virtual bool GetPlacementBlockTypeMeta( - cChunkInterface & a_ChunkInterface, cPlayer * a_Player, - int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, - int a_CursorX, int a_CursorY, int a_CursorZ, - BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - if (a_BlockFace > 0) - { - return false; - } - - class cCallbacks : - public cBlockTracer::cCallbacks - { - public: - cCallbacks(void) : - m_HasHitFluid(false) - { - } - - virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override - { - if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) - { - if ((a_BlockMeta != 0) || (a_EntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is for AddFaceDir below - { - return false; - } - m_HasHitFluid = true; - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace); - m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); - return true; - } - return false; - } - - Vector3i m_Pos; - bool m_HasHitFluid; - - } Callbacks; - - cLineBlockTracer Tracer(*a_Player->GetWorld(), Callbacks); - Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector()); - Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5); - - Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); - - if (Callbacks.m_HasHitFluid) - { - a_Player->GetWorld()->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0); - } - - return false; + // Reset meta to zero + a_Pickups.push_back(cItem(E_BLOCK_LILY_PAD, 1, 0)); } }; diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 454fabdd7..337b3a83c 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -27,6 +27,7 @@ #include "ItemHoe.h" #include "ItemLeaves.h" #include "ItemLighter.h" +#include "ItemLilypad.h" #include "ItemMap.h" #include "ItemMinecart.h" #include "ItemNetherWart.h" @@ -115,6 +116,7 @@ cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_FISHING_ROD: return new cItemFishingRodHandler(a_ItemType); case E_ITEM_FLINT_AND_STEEL: return new cItemLighterHandler(a_ItemType); case E_ITEM_FLOWER_POT: return new cItemFlowerPotHandler(a_ItemType); + case E_BLOCK_LILY_PAD: return new cItemLilypadHandler(a_ItemType); case E_ITEM_MAP: return new cItemMapHandler(); case E_ITEM_ITEM_FRAME: return new cItemItemFrameHandler(a_ItemType); case E_ITEM_NETHER_WART: return new cItemNetherWartHandler(a_ItemType); diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h new file mode 100644 index 000000000..8496b9f31 --- /dev/null +++ b/src/Items/ItemLilypad.h @@ -0,0 +1,106 @@ + +#pragma once + +#include "ItemHandler.h" +#include "../Entities/Player.h" +#include "Vector3.h" +#include "../LineBlockTracer.h" +#include "BlockInfo.h" + + + + + +class cItemLilypadHandler : + public cItemHandler +{ + typedef cItemHandler super; + +public: + cItemLilypadHandler(BLOCKTYPE a_BlockType) + : cItemHandler(a_BlockType) + { + + } + + virtual bool IsPlaceable(void) override + { + return false; // Set as not placeable so OnItemUse is called + } + + virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override + { + if (a_BlockFace > BLOCK_FACE_NONE) + { + // Clicked on the side of a submerged block; vanilla allows placement, so should we + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LILY_PAD, 0); + if (!a_Player->IsGameModeCreative()) + a_Player->GetInventory().RemoveOneEquippedItem(); + return true; + } + + class cCallbacks : + public cBlockTracer::cCallbacks + { + public: + cCallbacks(cWorld * a_World) : + m_HasHitFluid(false), + m_World(a_World) + { + } + + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override + { + if (IsBlockWater(a_BlockType)) + { + if ((a_BlockMeta != 0) || (a_EntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is clicking whilst submerged + { + return false; + } + a_EntryFace = BLOCK_FACE_YP; // Always place pad at top of water block + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, (eBlockFace)a_EntryFace); + BLOCKTYPE Block = m_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); + if ( + !IsBlockWater(Block) && + cBlockInfo::FullyOccupiesVoxel(Block) + ) + { + // Can't place lilypad on air/in another block! + return true; + } + m_HasHitFluid = true; + m_Pos.Set(a_BlockX, a_BlockY, a_BlockZ); + return true; + } + return false; + } + + Vector3i m_Pos; + bool m_HasHitFluid; + cWorld * m_World; + + }; + + cCallbacks Callbacks(a_World); + cLineBlockTracer Tracer(*a_Player->GetWorld(), Callbacks); + Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector()); + Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5); + + Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); + + if (Callbacks.m_HasHitFluid) + { + a_World->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0); + if (!a_Player->IsGameModeCreative()) + a_Player->GetInventory().RemoveOneEquippedItem(); + return true; + } + + return false; + } +}; + + + + diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp index 61c93ed73..7779573d7 100644 --- a/src/Simulator/FluidSimulator.cpp +++ b/src/Simulator/FluidSimulator.cpp @@ -36,6 +36,7 @@ bool cFluidSimulator::CanWashAway(BLOCKTYPE a_BlockType) case E_BLOCK_COBWEB: case E_BLOCK_CROPS: case E_BLOCK_DEAD_BUSH: + case E_BLOCK_LILY_PAD: case E_BLOCK_RAIL: case E_BLOCK_REDSTONE_TORCH_OFF: case E_BLOCK_REDSTONE_TORCH_ON: -- cgit v1.2.3 From 8ece214920cc9cbec2c04cfa046b451a2553e279 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 22:51:39 +0000 Subject: Fixed a potential crash --- src/Chunk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 957d7d575..ea961733f 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -884,7 +884,7 @@ void cChunk::ApplyWeatherToTop() FastSetBlock(X, Height, Z, E_BLOCK_SNOW, TopMeta - 1); } } - else if (cBlockInfo::IsSnowable(TopBlock)) + else if (cBlockInfo::IsSnowable(TopBlock) && (Height + 1 < cChunkDef::Height)) { SetBlock(X, Height + 1, Z, E_BLOCK_SNOW, 0); } -- cgit v1.2.3 From aee1f8f9d13c501a53e3636596c09dbce0f289bb Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 22:52:04 +0000 Subject: Fixed block interaction rate check --- src/ClientHandle.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 2c47faa65..443c248b0 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -941,6 +941,8 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e } return; } + + m_NumBlockChangeInteractionsThisTick++; if (!CheckBlockInteractionsRate()) { @@ -1053,8 +1055,8 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e cBlockSlabHandler::IsAnySlabType(EquippedBlock) && // Is the player placing another slab? ((ClickedBlockMeta & 0x07) == EquippedBlockDamage) && // Is it the same slab type? ( - (a_BlockFace == BLOCK_FACE_TOP) || // Clicking the top of a bottom slab - (a_BlockFace == BLOCK_FACE_BOTTOM) // Clicking the bottom of a top slab + (a_BlockFace == BLOCK_FACE_TOP) || // Clicking the top of a bottom slab + (a_BlockFace == BLOCK_FACE_BOTTOM) // Clicking the bottom of a top slab ) ) { -- cgit v1.2.3 From 79aa082b048ba1c4a0407d1faa8fb96a33dd4415 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 22:52:23 +0000 Subject: Fixed infinite minecart items --- src/Items/ItemMinecart.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h index bcaa5635a..bf6f70eed 100644 --- a/src/Items/ItemMinecart.h +++ b/src/Items/ItemMinecart.h @@ -72,6 +72,9 @@ public: } } // switch (m_ItemType) Minecart->Initialize(a_World); + + if (!a_Player->IsGameModeCreative()) + a_Player->GetInventory().RemoveOneEquippedItem(); return true; } -- cgit v1.2.3 From 6eacf1aa922b9dd2193a835e6a45ddf71fbbb729 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 23:07:50 +0000 Subject: Fixed a minor ini key duplication bug --- src/Root.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Root.cpp b/src/Root.cpp index 3555afb45..ba4398b35 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -304,6 +304,7 @@ void cRoot::LoadWorlds(cIniFile & IniFile) { if (IniFile.GetKeyComment("Worlds", 0) != " World=secondworld") { + IniFile.DeleteKeyComment("Worlds", 0); IniFile.AddKeyComment("Worlds", " World=secondworld"); } } -- cgit v1.2.3 From 6dea7993f2a563a8b3a0746feeb2174922631526 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 23:25:11 +0000 Subject: Fixed #721 and FS439 --- src/Entities/Player.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 863aaa799..646aad50f 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1489,6 +1489,7 @@ bool cPlayer::MoveToWorld(const char * a_WorldName) // Add player to all the necessary parts of the new world SetWorld(World); + m_ClientHandle->StreamChunks(); World->AddEntity(this); World->AddPlayer(this); -- cgit v1.2.3 From 519bd0b989fb931fd0925bad6a5cb1a9e223d85f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 28 Mar 2014 23:51:52 +0000 Subject: Curly brackets --- src/Items/ItemLilypad.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Items/ItemLilypad.h b/src/Items/ItemLilypad.h index 8496b9f31..5a29abe94 100644 --- a/src/Items/ItemLilypad.h +++ b/src/Items/ItemLilypad.h @@ -1,4 +1,3 @@ - #pragma once #include "ItemHandler.h" @@ -36,7 +35,9 @@ public: AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LILY_PAD, 0); if (!a_Player->IsGameModeCreative()) + { a_Player->GetInventory().RemoveOneEquippedItem(); + } return true; } @@ -93,7 +94,9 @@ public: { a_World->SetBlock(Callbacks.m_Pos.x, Callbacks.m_Pos.y, Callbacks.m_Pos.z, E_BLOCK_LILY_PAD, 0); if (!a_Player->IsGameModeCreative()) + { a_Player->GetInventory().RemoveOneEquippedItem(); + } return true; } -- cgit v1.2.3 From fb16554322e3995f065135b481fffd58a5b2551e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 29 Mar 2014 01:21:56 +0000 Subject: Fixed players not updating after world change Addendum to 6dea7993f2a563a8b3a0746feeb2174922631526 --- src/ClientHandle.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 46c10ae82..eb05ebdb7 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1606,10 +1606,8 @@ void cClientHandle::MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket) m_Protocol->SendUnloadChunk(itr->m_ChunkX, itr->m_ChunkZ); } // for itr - Chunks[] - // Do NOT stream new chunks, the new world runs its own tick thread and may deadlock - // Instead, the chunks will be streamed when the client is moved to the new world's Tick list, - // by setting state to csAuthenticated - m_State = csAuthenticated; + // StreamChunks() called in cPlayer::MoveToWorld() after new world has been set + // Meanwhile here, we set last streamed values to bogus ones so everything is resent m_LastStreamedChunkX = 0x7fffffff; m_LastStreamedChunkZ = 0x7fffffff; m_HasSentPlayerChunk = false; -- cgit v1.2.3 From aefabfcafa1103b0bea80b40508748635def67a0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 29 Mar 2014 10:25:40 +0000 Subject: Removed leftover clienthandle code --- src/ClientHandle.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 443c248b0..27c6b1226 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -933,7 +933,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - if (a_BlockFace != BLOCK_FACE_NONE) + if (a_BlockFace > BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); @@ -962,7 +962,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e ); // Let's send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block - if (a_BlockFace > -1) + if (a_BlockFace > BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); @@ -990,7 +990,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemType); - if (ItemHandler->IsPlaceable() && ((a_BlockFace > -1) || (Equipped.m_ItemType == E_BLOCK_LILY_PAD))) + if (ItemHandler->IsPlaceable() && (a_BlockFace > BLOCK_FACE_NONE)) { HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); } @@ -1029,7 +1029,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler) { BLOCKTYPE EquippedBlock = (BLOCKTYPE)(m_Player->GetEquippedItem().m_ItemType); - if ((a_BlockFace < 0) && (EquippedBlock != E_BLOCK_LILY_PAD)) + if (a_BlockFace < 0) { // Clicked in air return; @@ -1087,10 +1087,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e } else { - if (EquippedBlock != E_BLOCK_LILY_PAD) - { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - } + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { @@ -1111,7 +1108,6 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e else { if ( - (EquippedBlock != E_BLOCK_LILY_PAD) && !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision() && !BlockHandler(PlaceBlock)->DoesIgnoreBuildCollision(m_Player, PlaceMeta) ) @@ -1144,7 +1140,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e // The actual block placement: World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); - if (m_Player->GetGameMode() != gmCreative) + if (!m_Player->IsGameModeCreative()) { m_Player->GetInventory().RemoveOneEquippedItem(); } -- cgit v1.2.3 From 0f6688fe9e2df97a6979be452efa789245acfadb Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 12:24:26 +0100 Subject: Updated the android files --- Android/jni/Android.mk | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Android/jni/Android.mk b/Android/jni/Android.mk index 3542e588b..ce142d446 100644 --- a/Android/jni/Android.mk +++ b/Android/jni/Android.mk @@ -5,7 +5,7 @@ LOCAL_MODULE := mcserver -LOCAL_SRC_FILES := $(shell find ../CryptoPP ../lua ../jsoncpp ../zlib ../src ../tolua++ ../iniFile ../expat ../md5 ../sqlite ../luaexpat '(' -name '*.cpp' -o -name '*.c' ')') +LOCAL_SRC_FILES := $(shell find ../lib/polarssl ../lib/lua ../lib/jsoncpp ../lib/zlib ../src ../lib/tolua++ ../lib/iniFile ../lib/expat ../lib/md5 ../lib/sqlite ../lib/luaexpat '(' -name '*.cpp' -o -name '*.c' ')') LOCAL_SRC_FILES := $(filter-out %SquirrelFunctions.cpp %SquirrelBindings.cpp %cPlugin_Squirrel.cpp %cSquirrelCommandBinder.cpp %minigzip.c %lua.c %tolua.c %toluabind.c %LeakFinder.cpp %StackWalker.cpp %example.c,$(LOCAL_SRC_FILES)) LOCAL_SRC_FILES := $(patsubst %.cpp,../%.cpp,$(LOCAL_SRC_FILES)) LOCAL_SRC_FILES := $(patsubst %.c,../%.c,$(LOCAL_SRC_FILES)) @@ -24,17 +24,17 @@ LOCAL_C_INCLUDES := ../src \ ../src/packets \ ../src/items \ ../src/blocks \ - ../tolua++/src/lib \ - ../lua/src \ - ../zlib-1.2.7 \ - ../iniFile \ - ../tolua++/include \ - ../jsoncpp/include \ - ../jsoncpp/src/lib_json \ - ../expat/ \ - ../md5/ \ - ../sqlite/ \ - ../luaexpat/ \ + ../lib/tolua++/src/lib \ + ../lib/lua/src \ + ../lib/zlib-1.2.7 \ + ../lib/iniFile \ + ../lib/tolua++/include \ + ../lib/jsoncpp/include \ + ../lib/jsoncpp/src/lib_json \ + ../lib/expat/ \ + ../lib/md5/ \ + ../lib/sqlite/ \ + ../lib/luaexpat/ \ .. \ -- cgit v1.2.3 From 515e4bdb13de8fc749fb3f0910beb18974895d6c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 29 Mar 2014 13:18:26 +0000 Subject: Compare for inequality in FACE_NONE checks --- src/ClientHandle.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 27c6b1226..37672b7f0 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -933,7 +933,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType); BlockHandler->OnCancelRightClick(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - if (a_BlockFace > BLOCK_FACE_NONE) + if (a_BlockFace != BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); @@ -962,7 +962,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e ); // Let's send the current world block to the client, so that it can immediately "let the user know" that they haven't placed the block - if (a_BlockFace > BLOCK_FACE_NONE) + if (a_BlockFace != BLOCK_FACE_NONE) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); @@ -990,7 +990,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e cItemHandler * ItemHandler = cItemHandler::GetItemHandler(Equipped.m_ItemType); - if (ItemHandler->IsPlaceable() && (a_BlockFace > BLOCK_FACE_NONE)) + if (ItemHandler->IsPlaceable() && (a_BlockFace != BLOCK_FACE_NONE)) { HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); } -- cgit v1.2.3 From 4492bd58f1dc93e5c5d6c1b9ff64d7ed44accee3 Mon Sep 17 00:00:00 2001 From: narroo Date: Sat, 29 Mar 2014 10:00:44 -0400 Subject: Added in MetaMirrorXY and MetaMirrorYZ to cBlockSignHandler. --- src/Blocks/BlockSign.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Blocks/BlockSign.h b/src/Blocks/BlockSign.h index 24346b930..6c0becfd6 100644 --- a/src/Blocks/BlockSign.h +++ b/src/Blocks/BlockSign.h @@ -83,6 +83,25 @@ public: { return (--a_Meta) & 0x0F; } + + virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override + { + // Mirrors signs over the XY plane (North-South Mirroring) + + // There are 16 meta values which correspond to different directions. + // These values are equated to angles on a circle; 0x08 = 180 degrees. + return (a_Meta < 0x08) ? 0x08 + a_Meta : 0x08 - a_Meta; + } + + + virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override + { + // Mirrors signs over the YZ plane (East-West Mirroring) + + // There are 16 meta values which correspond to different directions. + // These values are equated to angles on a circle; 0x10 = 360 degrees. + return 0x10 - a_Meta; + } } ; -- cgit v1.2.3 From 339d55511127981335193d07037719a4b26c4600 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 15:26:41 +0100 Subject: Added HOOK_PROJECTILE_HIT_ENTITY --- src/Bindings/Plugin.h | 1 + src/Bindings/PluginLua.cpp | 20 ++++++++++++++++++++ src/Bindings/PluginLua.h | 1 + src/Bindings/PluginManager.cpp | 21 +++++++++++++++++++++ src/Bindings/PluginManager.h | 5 +++++ src/Entities/ProjectileEntity.cpp | 6 ++++++ 6 files changed, 54 insertions(+) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 057fa0304..75b04d12f 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -90,6 +90,7 @@ public: virtual bool OnPluginsLoaded (void) = 0; virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; + virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 4f0e13f12..d4e4b3ee8 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,6 +1108,26 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a +bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PROJECTILE_HIT_ENTITY]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Projectile, &a_HitEntity, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnSpawnedEntity(cWorld & a_World, cEntity & a_Entity) { cCSLock Lock(m_CriticalSection); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index f51056186..1533b1a66 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -113,6 +113,7 @@ public: virtual bool OnPluginsLoaded (void) override; virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 7d346c522..aa2c09a3d 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,6 +1154,27 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti +bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_ENTITY); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnProjectileHitEntity(a_Projectile, a_HitEntity)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookSpawnedEntity(cWorld & a_World, cEntity & a_Entity) { HookMap::iterator Plugins = m_Hooks.find(HOOK_SPAWNED_ENTITY); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 7895be959..c5071ee83 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -18,6 +18,9 @@ class cChunkDesc; // fwd: Entities/Entity.h class cEntity; +// fwd: Entities/ProjectileEntity.h +class cProjectileEntity; + // fwd: Mobs/Monster.h class cMonster; @@ -102,6 +105,7 @@ public: // tolua_export HOOK_PLUGINS_LOADED, HOOK_POST_CRAFTING, HOOK_PRE_CRAFTING, + HOOK_PROJECTILE_HIT_ENTITY, HOOK_SPAWNED_ENTITY, HOOK_SPAWNED_MONSTER, HOOK_SPAWNING_ENTITY, @@ -201,6 +205,7 @@ public: // tolua_export bool CallHookPluginsLoaded (void); bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index f4ab825f2..bc359e1da 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -4,6 +4,7 @@ // Implements the cProjectileEntity class representing the common base class for projectiles, as well as individual projectile types #include "Globals.h" +#include "../Bindings/PluginManager.h" #include "ProjectileEntity.h" #include "../ClientHandle.h" #include "Player.h" @@ -148,6 +149,11 @@ public: // TODO: Some entities don't interact with the projectiles (pickups, falling blocks) // TODO: Allow plugins to interfere about which entities can be hit + if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity)) + { + // A plugin disagreed. + return false; + } if (LineCoeff < m_MinCoeff) { -- cgit v1.2.3 From a6ef40cb6efa1b8da549c81c7e1137d523240c17 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 15:43:03 +0100 Subject: Fixed error when the hook gets called. --- src/Bindings/LuaState.cpp | 12 ++++++++++++ src/Bindings/LuaState.h | 2 ++ src/Entities/ProjectileEntity.cpp | 1 - 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 47380b8a7..13eb17f7d 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -479,6 +479,18 @@ void cLuaState::Push(cEntity * a_Entity) +void cLuaState::Push(cProjectileEntity * a_ProjectileEntity) +{ + ASSERT(IsValid()); + + tolua_pushusertype(m_LuaState, a_ProjectileEntity, "cProjectileEntity"); + m_NumCurrentFunctionArgs += 1; +} + + + + + void cLuaState::Push(cMonster * a_Monster) { ASSERT(IsValid()); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index f0047b362..b9ca2f29b 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -38,6 +38,7 @@ extern "C" class cWorld; class cPlayer; class cEntity; +class cProjectileEntity; class cMonster; class cItem; class cItems; @@ -183,6 +184,7 @@ public: void Push(cPlayer * a_Player); void Push(const cPlayer * a_Player); void Push(cEntity * a_Entity); + void Push(cProjectileEntity * a_ProjectileEntity); void Push(cMonster * a_Monster); void Push(cItem * a_Item); void Push(cItems * a_Items); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index bc359e1da..07cb34f35 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -148,7 +148,6 @@ public: } // TODO: Some entities don't interact with the projectiles (pickups, falling blocks) - // TODO: Allow plugins to interfere about which entities can be hit if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity)) { // A plugin disagreed. -- cgit v1.2.3 From ec4638a228edcf4c745088838e972ea07edc7cba Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 16:00:45 +0100 Subject: Added HOOK_PROJECTILE_HIT_BLOCK. --- src/Bindings/Plugin.h | 1 + src/Bindings/PluginLua.cpp | 20 ++++++++++++++++++++ src/Bindings/PluginLua.h | 1 + src/Bindings/PluginManager.cpp | 21 +++++++++++++++++++++ src/Bindings/PluginManager.h | 2 ++ src/Entities/ProjectileEntity.cpp | 5 +++++ 6 files changed, 50 insertions(+) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 75b04d12f..df0bd4dcc 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -90,6 +90,7 @@ public: virtual bool OnPluginsLoaded (void) = 0; virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; + virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile) = 0; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index d4e4b3ee8..7e69e0f4b 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,6 +1108,26 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a +bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PROJECTILE_HIT_BLOCK]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Projectile, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) { cCSLock Lock(m_CriticalSection); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 1533b1a66..59542d23a 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -113,6 +113,7 @@ public: virtual bool OnPluginsLoaded (void) override; virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; + virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile) override; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index aa2c09a3d..6a5356c0b 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,6 +1154,27 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti +bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_BLOCK); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnProjectileHitBlock(a_Projectile)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity & a_HitEntity) { HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_ENTITY); diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index c5071ee83..512bc1351 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -105,6 +105,7 @@ public: // tolua_export HOOK_PLUGINS_LOADED, HOOK_POST_CRAFTING, HOOK_PRE_CRAFTING, + HOOK_PROJECTILE_HIT_BLOCK, HOOK_PROJECTILE_HIT_ENTITY, HOOK_SPAWNED_ENTITY, HOOK_SPAWNED_MONSTER, @@ -205,6 +206,7 @@ public: // tolua_export bool CallHookPluginsLoaded (void); bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 07cb34f35..b724c9c55 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -67,6 +67,11 @@ protected: eBlockFace Face; if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face)) { + if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile)) + { + return true; + } + Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff; m_Projectile->OnHitSolidBlock(Intersection, Face); return true; -- cgit v1.2.3 From 379d403443e5ecf3e66cf151391f5a8c4bd4d5c6 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 16:08:39 +0100 Subject: Documented both hooks. --- .../Plugins/APIDump/Hooks/OnProjectileHitBlock.lua | 24 +++++++++++++++++++++ .../APIDump/Hooks/OnProjectileHitEntity.lua | 25 ++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua create mode 100644 MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua diff --git a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua new file mode 100644 index 000000000..1588d420c --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua @@ -0,0 +1,24 @@ +return +{ + HOOK_PROJECTILE_HIT_BLOCK = + { + CalledWhen = "A projectile hits a solid block.", + DefaultFnName = "OnProjectileHitBlock", -- also used as pagename + Desc = [[ + This hook is called when a {{cProjectileEntity|projectile}} hits a solid block.. + ]], + Params = + { + { Name = "ProjectileEntity", Type = "{{cProjectileEntity}}", Notes = "The projectile that hit an entity." }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called. If the function + returns true, no other callback is called for this event and the projectile flies through block.. + ]], + }, -- HOOK_PROJECTILE_HIT_BLOCK +} + + + + + diff --git a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua new file mode 100644 index 000000000..dd949fb46 --- /dev/null +++ b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitEntity.lua @@ -0,0 +1,25 @@ +return +{ + HOOK_PROJECTILE_HIT_ENTITY = + { + CalledWhen = "A projectile hits another entity.", + DefaultFnName = "OnProjectileHitEntity", -- also used as pagename + Desc = [[ + This hook is called when a {{cProjectileEntity|projectile}} hits another entity. + ]], + Params = + { + { Name = "ProjectileEntity", Type = "{{cProjectileEntity}}", Notes = "The projectile that hit an entity." }, + { Name = "Entity", Type = "{{cEntity}}", Notes = "The entity wich was hit." }, + }, + Returns = [[ + If the function returns false or no value, the next plugin's callback is called. If the function + returns true, no other callback is called for this event and the projectile flies through the entity. + ]], + }, -- HOOK_PROJECTILE_HIT_ENTITY +} + + + + + -- cgit v1.2.3 From 98a12127ceaa0834bfea66fa6f9e381b1f8f4357 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 29 Mar 2014 17:05:24 +0100 Subject: Fixed the OnProjectileHitBlock hook not stopping projectiles. --- src/Entities/ProjectileEntity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index b724c9c55..a9735a53c 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -69,7 +69,7 @@ protected: { if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile)) { - return true; + return false; } Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff; -- cgit v1.2.3 From 782c111b815b3a49a340e1f1133e1c15ac76e551 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 29 Mar 2014 22:29:34 +0100 Subject: Renamed lua dll for tolua++.exe. Fixes #843. --- src/Bindings/lua5.1.dll | Bin 167424 -> 0 bytes src/Bindings/lua51.dll | Bin 0 -> 167424 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/Bindings/lua5.1.dll create mode 100644 src/Bindings/lua51.dll diff --git a/src/Bindings/lua5.1.dll b/src/Bindings/lua5.1.dll deleted file mode 100644 index 515cf8b30..000000000 Binary files a/src/Bindings/lua5.1.dll and /dev/null differ diff --git a/src/Bindings/lua51.dll b/src/Bindings/lua51.dll new file mode 100644 index 000000000..515cf8b30 Binary files /dev/null and b/src/Bindings/lua51.dll differ -- cgit v1.2.3 From d64d9145d1d84caaf21a906d5924c3855988fa33 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 29 Mar 2014 22:56:16 +0100 Subject: cPrefab now uses a struct for block type definition in CharMap. As suggested by worktycho in 7b585290fccd3dc074b1f9feef0af754ab3dd632, instead of packing the two values into a single int, they're packed into a struct. Also added a test code for the prefab parsing in SELF_TEST. --- src/Generating/Prefab.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++---- src/Generating/Prefab.h | 9 +++- 2 files changed, 102 insertions(+), 10 deletions(-) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 1af1faec1..a9e0a839d 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -15,6 +15,92 @@ uses a prefabricate in a cBlockArea for drawing itself. +#ifdef SELF_TEST + +// Create one static prefab to test the parser: +static const cPrefab::sDef g_TestPrefabDef = +{ + // Size: + 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* 0 */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + + // Level 2 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 3 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 4 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 5 + "aabbbaa" + "a.....a" + "b.....b" + "b.....b" + "b.....b" + "a.....a" + "aabbbaa" + + // Level 6 + "aaaaaaa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "aaaaaaa", + + // Connections: + "0: 0, 3, 2: 4\n" + "0: 2, 3, 0: 2\n", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msImprint +}; + +static cPrefab g_TestPrefab(g_TestPrefabDef); +#endif + + + + + cPrefab::cPrefab(const cPrefab::sDef & a_Def) : m_Size(a_Def.m_SizeX, a_Def.m_SizeY, a_Def.m_SizeZ), m_HitBox(0, 0, 0, a_Def.m_SizeX - 1, a_Def.m_SizeY - 1, a_Def.m_SizeZ - 1), @@ -89,7 +175,8 @@ void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) // Initialize the charmap to all-invalid values: for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) { - a_CharMapOut[i] = -1; + a_CharMapOut[i].m_BlockType = 0; + a_CharMapOut[i].m_BlockMeta = 16; // Mark unassigned entries with a meta that is impossible otherwise } // Process the lines in the definition: @@ -104,15 +191,15 @@ void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) continue; } unsigned char Src = (unsigned char)CharDef[0][0]; - BLOCKTYPE BlockType = (BLOCKTYPE)atoi(CharDef[1].c_str()); + ASSERT(a_CharMapOut[Src].m_BlockMeta == 16); // This letter has not been assigned yet? + a_CharMapOut[Src].m_BlockType = (BLOCKTYPE)atoi(CharDef[1].c_str()); NIBBLETYPE BlockMeta = 0; if ((NumElements >= 3) && !CharDef[2].empty()) { BlockMeta = (NIBBLETYPE)atoi(CharDef[2].c_str()); ASSERT((BlockMeta >= 0) && (BlockMeta <= 15)); } - ASSERT(a_CharMapOut[Src] == -1); // Any duplicates letter-wise? - a_CharMapOut[Src] = (BlockType << 4) | BlockMeta; + a_CharMapOut[Src].m_BlockMeta = BlockMeta; } // for itr - Lines[] } @@ -130,11 +217,9 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma const unsigned char * BlockImage = (const unsigned char *)a_BlockImage + y * m_Size.x * m_Size.z + z * m_Size.x; for (int x = 0; x < m_Size.x; x++) { - int MappedValue = a_CharMap[BlockImage[x]]; - ASSERT(MappedValue != -1); // Using a letter not defined in the CharMap? - BLOCKTYPE BlockType = MappedValue >> 4; - NIBBLETYPE BlockMeta = MappedValue & 0x0f; - m_BlockArea[0].SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta); + const sBlockTypeDef & MappedValue = a_CharMap[BlockImage[x]]; + ASSERT(MappedValue.m_BlockMeta != 16); // Using a letter not defined in the CharMap? + m_BlockArea[0].SetRelBlockTypeMeta(x, y, z, MappedValue.m_BlockType, MappedValue.m_BlockMeta); } } } diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index 0b254c03b..04c4f09da 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -53,8 +53,15 @@ public: bool HasConnectorType(int a_ConnectorType) const; protected: + /** Packs complete definition of a single block, for per-letter assignment. */ + struct sBlockTypeDef + { + BLOCKTYPE m_BlockType; + NIBBLETYPE m_BlockMeta; + }; + /** Maps letters in the sDef::m_Image onto a number, BlockType * 16 | BlockMeta */ - typedef int CharMap[256]; + typedef sBlockTypeDef CharMap[256]; /** The cBlockArea that contains the block definitions for the prefab. -- cgit v1.2.3 From 597bdd9f8010c455c1c4ce83dc2ed5e227666a1c Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 00:12:19 +0100 Subject: NetherForts have a minimum number of pieces. The fort will generate a different image if it has less than the minimum; the max depth affects the minimum number of pieces. --- src/Generating/NetherFortGen.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp index d111c7cee..09c992e22 100644 --- a/src/Generating/NetherFortGen.cpp +++ b/src/Generating/NetherFortGen.cpp @@ -41,8 +41,11 @@ public: int BlockY = 64; // Generate pieces: - cBFSPieceGenerator pg(m_ParentGen, a_Seed); - pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); + for (int i = 0; m_Pieces.size() < (size_t)(a_MaxDepth * a_MaxDepth / 16 + a_MaxDepth); i++) + { + cBFSPieceGenerator pg(m_ParentGen, a_Seed + 1); + pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); + } } -- cgit v1.2.3 From 475fc4b1ab76955dc1e3625e75549dc86f0ca860 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 00:12:54 +0100 Subject: Fixed chest rotator. --- src/Blocks/BlockChest.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index 30588d8fc..7abf01301 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -11,11 +11,11 @@ class cBlockChestHandler : - public cMetaRotater + public cMetaRotater { public: cBlockChestHandler(BLOCKTYPE a_BlockType) - : cMetaRotater(a_BlockType) + : cMetaRotater(a_BlockType) { } -- cgit v1.2.3 From 6b29edc1582940a08c0d28822a4ea4c95c55d2e0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 00:20:06 +0100 Subject: Re-fixed nether fort piece count check. --- src/Generating/NetherFortGen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Generating/NetherFortGen.cpp b/src/Generating/NetherFortGen.cpp index 09c992e22..02779a8a3 100644 --- a/src/Generating/NetherFortGen.cpp +++ b/src/Generating/NetherFortGen.cpp @@ -41,9 +41,9 @@ public: int BlockY = 64; // Generate pieces: - for (int i = 0; m_Pieces.size() < (size_t)(a_MaxDepth * a_MaxDepth / 16 + a_MaxDepth); i++) + for (int i = 0; m_Pieces.size() < (size_t)(a_MaxDepth * a_MaxDepth / 8 + a_MaxDepth); i++) { - cBFSPieceGenerator pg(m_ParentGen, a_Seed + 1); + cBFSPieceGenerator pg(m_ParentGen, a_Seed + i); pg.PlacePieces(a_BlockX, BlockY, a_BlockZ, a_MaxDepth, m_Pieces); } } -- cgit v1.2.3 From 3eb531a8c81fa4df014dc32b1aba42508910b481 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 00:20:28 +0100 Subject: Added asserts for critical data in cPrefab. --- src/Generating/Prefab.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index a9e0a839d..131b6acb2 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -172,6 +172,8 @@ bool cPrefab::HasConnectorType(int a_ConnectorType) const void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) { + ASSERT(a_CharMapDef != NULL); + // Initialize the charmap to all-invalid values: for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) { @@ -231,6 +233,8 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma void cPrefab::ParseConnectors(const char * a_ConnectorsDef) { + ASSERT(a_ConnectorsDef != NULL); + AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { -- cgit v1.2.3 From ceabb372f083c9f45ab1c05154c780c5092961ec Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 00:33:59 +0100 Subject: Added all current NetherFort prefabs. --- src/Generating/Prefabs/NetherFortPrefabs.cpp | 1628 +++++++++++++++++++++++++- 1 file changed, 1586 insertions(+), 42 deletions(-) diff --git a/src/Generating/Prefabs/NetherFortPrefabs.cpp b/src/Generating/Prefabs/NetherFortPrefabs.cpp index 24bde1baf..5e8685e32 100644 --- a/src/Generating/Prefabs/NetherFortPrefabs.cpp +++ b/src/Generating/Prefabs/NetherFortPrefabs.cpp @@ -353,7 +353,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = 14, 9, 7, // SizeX = 14, SizeY = 9, SizeZ = 7 // Block definitions: - ".: 0: 0\n" /* 0 */ + ".: 0: 0\n" /* air */ "a:112: 0\n" /* netherbrick */ "b:114: 5\n" /* netherbrickstairs */ "c: 44:14\n" /* step */ @@ -850,6 +850,200 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = }, // BridgeSegment + // BridgeTee: + // The data has been exported from gallery Nether, area index 39, ID 290 + { + // Size: + 15, 8, 10, // SizeX = 15, SizeY = 8, SizeZ = 10 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:114: 5\n" /* netherbrickstairs */ + "c:114: 4\n" /* netherbrickstairs */ + "d:114: 6\n" /* netherbrickstairs */ + "e: 44:14\n" /* step */ + "f:114: 7\n" /* netherbrickstairs */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmmmmmmmmmmmm" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "aammmmmmmmmmmaa" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 2 + "mmmmmmmmmmmmmmm" + "aabmmmmmmmmmcaa" + "aabmmmmmmmmmcaa" + "aabmmmmmmmmmcaa" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmmmmmmmmmm" + "mmmmmmdddmmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 3 + "mmmmmmmmmmmmmmm" + "aaabemmmmmecaaa" + "aaabemmmmmecaaa" + "aaabemmmmmecaaa" + "mmmmmmmmmmmmmmm" + "mmmmmmeeemmmmmm" + "mmmmmmdddmmmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + "mmmmmmaaammmmmm" + + // Level 4 + "ddddddddddddddd" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "fffffcaaabfffff" + "mmmmmcaaabmmmmm" + "mmmmmcaaabmmmmm" + "mmmmmcaaabmmmmm" + "mmmmmcaaabmmmmm" + "mmmmmcaaabmmmmm" + + // Level 5 + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + "mmmmmaaaaammmmm" + + // Level 6 + "aaaaaaaaaaaaaaa" + "..............." + "..............." + "..............." + "aaaaaa...aaaaaa" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + "mmmmma...ammmmm" + + // Level 7 + "mmmmmmmmmmmmmmm" + "..............." + "..............." + "..............." + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + + // Level 8 + "mmmmmmmmmmmmmmm" + "..............." + "..............." + "..............." + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm" + "mmmmmm...mmmmmm", + + // Connections: + "0: 0, 5, 2: 4\n" /* Type 0, BLOCK_FACE_XM */ + "0: 14, 5, 2: 5\n" /* Type 0, BLOCK_FACE_XP */ + "0: 7, 5, 9: 3\n" /* Type 0, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // BridgeTee + + + // Corridor11: + // The data has been exported from gallery Nether, area index 36, ID 287 + { + // Size: + 11, 6, 5, // SizeX = 11, SizeY = 6, SizeZ = 5 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c:114: 2\n" /* netherbrickstairs */ + "d:114: 3\n" /* netherbrickstairs */, + + // Block data: + // Level 1 + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + + // Level 2 + "aaaaaaaaaaa" + "..........." + "..........." + "..........." + "aaaaaaaaaaa" + + // Level 3 + "abababababa" + "..........." + "..........." + "..........." + "abababababa" + + // Level 4 + "abababababa" + "..........." + "..........." + "..........." + "abababababa" + + // Level 5 + "abababababa" + "..........." + "..........." + "..........." + "abababababa" + + // Level 6 + "ccccccccccc" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "ddddddddddd", + + // Connections: + "1: 0, 1, 2: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 10, 1, 2: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // Corridor11 + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Corridor13: // The data has been exported from gallery Nether, area index 35, ID 286 @@ -919,6 +1113,221 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = }, // Corridor13 + // CorridorCorner5: + // The data has been exported from gallery Nether, area index 10, ID 40 + { + // Size: + 11, 6, 11, // SizeX = 11, SizeY = 6, SizeZ = 11 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c:114: 2\n" /* netherbrickstairs */ + "d:114: 0\n" /* netherbrickstairs */ + "e:114: 3\n" /* netherbrickstairs */ + "f:114: 1\n" /* netherbrickstairs */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + + // Level 2 + "aaaaaaaaaaa" + "a.........." + "a.........." + "a.........." + "a...aaaaaaa" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + + // Level 3 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 4 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 5 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 6 + "ccccccccccc" + "daaaaaaaaaa" + "daaaaaaaaaa" + "daaaaaaaaaa" + "daaaeeeeeee" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm", + + // Connections: + "1: 10, 1, 2: 5\n" /* Type 1, BLOCK_FACE_XP */ + "1: 2, 1, 10: 3\n" /* Type 1, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // CorridorCorner5 + + + // CorridorCorner5: + // The data has been exported from gallery Nether, area index 10, ID 40 + { + // Size: + 11, 6, 11, // SizeX = 11, SizeY = 6, SizeZ = 11 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c:114: 2\n" /* netherbrickstairs */ + "d:114: 0\n" /* netherbrickstairs */ + "e:114: 3\n" /* netherbrickstairs */ + "f:114: 1\n" /* netherbrickstairs */ + "g: 54: 5\n" /* chest */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaaaaaaaa" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + "aaaaammmmmm" + + // Level 2 + "aaaaaaaaaaa" + "ag........." + "a.........." + "a.........." + "a...aaaaaaa" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + "a...ammmmmm" + + // Level 3 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 4 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 5 + "abababababa" + "b.........." + "a.........." + "b.........." + "a...abababa" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + "b...bmmmmmm" + "a...ammmmmm" + + // Level 6 + "ccccccccccc" + "daaaaaaaaaa" + "daaaaaaaaaa" + "daaaaaaaaaa" + "daaaeeeeeee" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm" + "daaafmmmmmm", + + // Connections: + "1: 10, 1, 2: 5\n" /* Type 1, BLOCK_FACE_XP */ + "1: 2, 1, 10: 3\n" /* Type 1, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // CorridorCorner5Chest + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CorridorStairs: // The data has been exported from gallery Nether, area index 12, ID 42 @@ -927,7 +1336,7 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = 9, 13, 5, // SizeX = 9, SizeY = 13, SizeZ = 5 // Block definitions: - ".: 0: 0\n" /* 0 */ + ".: 0: 0\n" /* air */ "a:112: 0\n" /* netherbrick */ "b:114: 0\n" /* netherbrickstairs */ "c:113: 0\n" /* netherbrickfence */ @@ -1037,57 +1446,1192 @@ const cPrefab::sDef g_NetherFortPrefabs1[] = // Merge strategy: cBlockArea::msSpongePrint, }, // CorridorStairs -} ; // g_NetherFortPrefabs1 - - - -const cPrefab::sDef g_NetherFortStartingPrefabs1[] = -{ - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // CentralRoom: - // The data has been exported from gallery Nether, area index 22, ID 164 + // LavaStaircase: + // The data has been exported from gallery Nether, area index 28, ID 278 { // Size: - 13, 9, 13, // SizeX = 13, SizeY = 9, SizeZ = 13 + 15, 11, 15, // SizeX = 15, SizeY = 11, SizeZ = 15 // Block definitions: + ".: 0: 0\n" /* air */ "a:112: 0\n" /* netherbrick */ - "b: 0: 0\n" /* air */ - "c: 10: 0\n" /* lava */ - "d:113: 0\n" /* netherbrickfence */, + "b:113: 0\n" /* netherbrickfence */ + "c: 11: 0\n" /* lava */, // Block data: // Level 1 - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" - "aaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" // Level 2 - "aaaaabbbaaaaa" - "aaaaabbbaaaaa" - "aabbbbbbbbbaa" - "aabbbbbbbbbaa" - "aabbbbbbbbbaa" - "aabbbaaabbbaa" - "aabbbacabbbaa" - "aabbbaaabbbaa" - "aabbbbbbbbbaa" - "aabbbbbbbbbaa" - "aabbbbbbbbbaa" - "aaaaabbbaaaaa" - "aaaaabbbaaaaa" + "aaaaaaaa...aaaa" + "aaaaa.........a" + "aaaaa.........a" + "aaaaab........a" + "accca...aaaa..a" + "accca...acca..a" + "acccaaaaacca..a" + "acccccccccca..a" + "acccaaaaacca..a" + "accca...acca..a" + "accca...aaaa..a" + "aaaaab........a" + "aaaaa.........a" + "aaaaa.........a" + "aaaaaaaa...aaaa" + + // Level 3 + "aaaaaaaa...aaaa" + "aaaa..........a" + "aaaa..........a" + "aaaabb........a" + "aaaa..........a" + "a.............a" + "a.............a" + "a.............a" + "a.............a" + "a.............a" + "aaaa..........a" + "aaaabb........a" + "aaaa..........a" + "aaaa..........a" + "aaaaaaaa...aaaa" + + // Level 4 + "aaaaaaaa...aaaa" + "a.............a" + "a.............a" + "a..bb.........a" + "aaaa..........a" + "aaaa..........a" + "a.............a" + "a.............a" + "a.............a" + "aaaa..........a" + "aaaa..........a" + "a..bb.........a" + "a.............a" + "a.............a" + "aaaaaaaa...aaaa" + + // Level 5 + "aaaaaaaabbbaaaa" + "a.............a" + "a.............a" + "a..b..........a" + "a..b..........a" + "aaaa..........a" + "aaaa..........a" + "a.............a" + "aaaa..........a" + "aaaa..........a" + "a..b..........a" + "a..b..........a" + "a.............a" + "a.............a" + "aaaaaaaabbbaaaa" + + // Level 6 + "aaaaaaaaaaaaaaa" + "a.............a" + "a.............a" + "a.............a" + "a..b..........a" + "a..b..........a" + "aaaa..........a" + "aaaa..........a" + "aaaa..........a" + "a..b..........a" + "a..b..........a" + "a.............a" + "a.............a" + "a.............a" + "aaaaaaaaaaaaaaa" + + // Level 7 + "aaaaaaaaaaaaaaa" + "a.............a" + "a.............a" + "a.............a" + "a.............a" + "a..b..........a" + "...b..........a" + "...b..........a" + "...b..........a" + "a..b..........a" + "a.............a" + "a.............a" + "a.............a" + "a.............a" + "aaaaaaaaaaaaaaa" + + // Level 8 + "aababababababaa" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "..............b" + "..............a" + "..............b" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "aababababababaa" + + // Level 9 + "aababababababaa" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "..............b" + "..............a" + "..............b" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "aababababababaa" + + // Level 10 + "aababababababaa" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "..............b" + "..............a" + "..............b" + "a.............a" + "b.............b" + "a.............a" + "b.............b" + "a.............a" + "aababababababaa" + + // Level 11 + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaa", + + // Connections: + "1: 0, 6, 7: 4\n" /* Type 1, BLOCK_FACE_XM */ + "0: 9, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "0: 9, 1, 14: 3\n" /* Type 0, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // LavaStaircase + + + // LavaStaircaseBig: + // The data has been exported from gallery Nether, area index 31, ID 282 + { + // Size: + 12, 15, 15, // SizeX = 12, SizeY = 15, SizeZ = 15 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b: 10: 0\n" /* lava */ + "c:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + + // Level 2 + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "abbbbbaaaaaa" + "abbbbbbaaaaa" + "abbbbbba...." + "abbbbbba...." + "abbbbbba...." + "abbbbbbaaaaa" + "abbbbb.aaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + + // Level 3 + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "abbbbbaaaaaa" + "abbbbbba...a" + "abbbbbba...." + "abbbbbba...." + "abbbbbba...." + "abbbbbba...a" + "abbbbb.aaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + + // Level 4 + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "abbbbbaa...a" + "abbbbbba...a" + "abbbbbba...." + "abbbbbba...." + "abbbbbba...." + "abbbbbba...a" + "abbbbbaa...a" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + + // Level 5 + "aaaaaaaaaaaa" + "aaaaa......a" + "aaaaa......a" + "aaaaacc....a" + "a.....cc...a" + "a......c...a" + "a......c...." + "a......c...." + "a......c...." + "a......c...a" + "a.....cc...a" + "aaaaacc....a" + "aaaaa......a" + "aaaaa......a" + "aaaaaaaaaaaa" + + // Level 6 + "aaaaaaaaaaaa" + "aaaa.......a" + "aaaa.......a" + "aaaacc.....a" + "aaaa.......a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "aaaa.......a" + "aaaacc.....a" + "aaaa.......a" + "aaaa.......a" + "aaaaaaaaaaaa" + + // Level 7 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..cc......a" + "aaaa.......a" + "aaaa.......a" + "a..........a" + "a..........a" + "a..........a" + "aaaa.......a" + "aaaa.......a" + "a..cc......a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 8 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..c.......a" + "a..c.......a" + "aaaa.......a" + "aaaa.......a" + "a..........a" + "aaaa.......a" + "aaaa.......a" + "a..c.......a" + "a..c.......a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 9 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..........a" + "a..c.......a" + "a..c.......a" + "aaaa.......a" + "aaaa.......a" + "aaaa.......a" + "a..c.......a" + "a..c.......a" + "a..........a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 10 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..c.......a" + "...c.......a" + "...c.......a" + "...c.......a" + "a..c.......a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 11 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "...........a" + "...........a" + "...........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 12 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "...........a" + "...........a" + "...........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 13 + "aaaaaaaaaaaa" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "...........a" + "...........a" + "...........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "a..........a" + "aaaaaaaaaaaa" + + // Level 14 + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + "aaaaaaaaaaaa" + + // Level 15 + "aaaaaaaaaaaa" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "abbbbbbbbbba" + "aaaaaaaaaaaa", + + // Connections: + "1: 0, 9, 7: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 11, 1, 7: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // LavaStaircaseBig + + + // MidStaircase: + // The data has been exported from gallery Nether, area index 23, ID 165 + { + // Size: + 13, 8, 13, // SizeX = 13, SizeY = 8, SizeZ = 13 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b: 88: 0\n" /* soulsand */ + "c:115: 7\n" /* netherwartblock */ + "d:114: 3\n" /* netherbrickstairs */ + "e:114: 0\n" /* netherbrickstairs */ + "f:114: 1\n" /* netherbrickstairs */ + "g:114: 2\n" /* netherbrickstairs */ + "h: 10: 0\n" /* lava */ + "i:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaabbbbbaaaa" + "aaaabbbbbaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaabbbbbaaaa" + "aaaabbbbbaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaacccccaaaa" + "addecccccfdda" + "...eaaaaad..." + "...eaaaaa...." + "...eaaaaag..." + "agggcccccfgga" + "aaaacccccaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 3 + "aaaaaaaaaaaaa" + "aha.......aha" + "aaa.......aaa" + "a...........a" + "a...........a" + "....eaaaa...." + "....eaaaa...." + "....eaaaa...." + "a...........a" + "a...........a" + "aaa.......aaa" + "aha.......aha" + "aaaaaaaaaaaaa" + + // Level 4 + "aaaiiaaaiiaaa" + "a...........a" + "a...........a" + "a...........a" + "a...........a" + ".....eaaa...." + ".....eaaa...." + ".....eaaa...." + "a...........a" + "a...........a" + "a...........a" + "a...........a" + "aaaiiaaaiiaaa" + + // Level 5 + "aaaiiaaaiiaaa" + "a...........a" + "a...........a" + "a...........a" + "a...........a" + "......eaa...." + "......eaa...." + "......eaa...." + "a...........a" + "a...........a" + "a...........a" + "a...........a" + "aaaiiaaaiiaaa" + + // Level 6 + "aaaaaaaaaaaaa" + "a...........a" + "a...........a" + "a...........a" + "a...........a" + "a......ea...a" + "a......ea...a" + "a......ea...a" + "a...........a" + "a...........a" + "a...........a" + "a...........a" + "aaaaaaaaaaaaa" + + // Level 7 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaa....eaaaa" + "aaaa....eaaaa" + "aaaa....eaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 8 + "iaiaiaiaiaiai" + "a...........a" + "i...........i" + "a...........a" + "i...........i" + "a............" + "i............" + "a............" + "i...........i" + "a...........a" + "i...........i" + "a...........a" + "iaiaiaiaiaiai", + + // Connections: + "1: 0, 1, 6: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 12, 1, 6: 5\n" /* Type 1, BLOCK_FACE_XP */ + "1: 12, 7, 6: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // MidStaircase + + + // StairsToOpen1: + // The data has been exported from gallery Nether, area index 27, ID 277 + { + // Size: + 7, 10, 7, // SizeX = 7, SizeY = 10, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + + // Level 2 + "aa...aa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "aaaaaaa" + "aaaaaaa" + + // Level 3 + "aa...aa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a.aaaaa" + "aabaaba" + + // Level 4 + "aa...aa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a..aaaa" + "aabaaba" + + // Level 5 + "aabbbaa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a...aaa" + "aabaaba" + + // Level 6 + "aaaaaaa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "a....aa" + "aaaaaaa" + + // Level 7 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "a.....a" + "aaaaaaa" + + // Level 8 + "aaaaaaa" + "a.....a" + "a......" + "a......" + "a......" + "a.....a" + "aaaaaaa" + + // Level 9 + "mmmmmmm" + "m.....m" + "m......" + "m......" + "m......" + "m.....m" + "mmmmmmm" + + // Level 10 + "mmmmmmm" + "m.....m" + "m......" + "m......" + "m......" + "m.....m" + "mmmmmmm", + + // Connections: + "0: 3, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "0: 6, 7, 3: 5\n" /* Type 0, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // StairsToOpen1 + + + // StairsToOpen2: + // The data has been exported from gallery Nether, area index 8, ID 35 + { + // Size: + 7, 10, 7, // SizeX = 7, SizeY = 10, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + + // Level 2 + "aa...aa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "aaaaaaa" + "aaaaaaa" + + // Level 3 + "aa...aa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a.aaaaa" + "aabaaba" + + // Level 4 + "aa...aa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a..aaaa" + "aabaaba" + + // Level 5 + "aabbbaa" + "a.....a" + "b.....b" + "a.....a" + "b.....b" + "a...aaa" + "aabaaba" + + // Level 6 + "aaaaaaa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "a....aa" + "aaaaaaa" + + // Level 7 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "a.....a" + "aaaaaaa" + + // Level 8 + "aaaaaaa" + "a.....a" + "......a" + "......a" + "......a" + "a.....a" + "aaaaaaa" + + // Level 9 + "mmmmmmm" + "m.....m" + "......m" + "......m" + "......m" + "m.....m" + "mmmmmmm" + + // Level 10 + "mmmmmmm" + "m.....m" + "......m" + "......m" + "......m" + "m.....m" + "mmmmmmm", + + // Connections: + "0: 3, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "0: 0, 7, 3: 4\n" /* Type 0, BLOCK_FACE_XM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // StairsToOpen2 + + + // Tee2x4: + // The data has been exported from gallery Nether, area index 40, ID 291 + { + // Size: + 13, 6, 7, // SizeX = 13, SizeY = 6, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c:114: 0\n" /* netherbrickstairs */ + "d:114: 1\n" /* netherbrickstairs */ + "e:114: 2\n" /* netherbrickstairs */ + "f:114: 3\n" /* netherbrickstairs */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmaaaaammmm" + "mmmmaaaaammmm" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "mmmma...ammmm" + "mmmma...ammmm" + "aaaaa...aaaaa" + "............." + "............." + "............." + "aaaaaaaaaaaaa" + + // Level 3 + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 4 + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 5 + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 6 + "mmmmcaaadmmmm" + "mmmmcaaadmmmm" + "eeeecaaadeeee" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "fffffffffffff", + + // Connections: + "1: 0, 1, 4: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 6, 1, 0: 2\n" /* Type 1, BLOCK_FACE_ZM */ + "1: 12, 1, 4: 5\n" /* Type 1, BLOCK_FACE_XP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // Tee2x4 + + + // Tee4x4: + // The data has been exported from gallery Nether, area index 41, ID 292 + { + // Size: + 13, 6, 9, // SizeX = 13, SizeY = 6, SizeZ = 9 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */ + "c:114: 0\n" /* netherbrickstairs */ + "d:114: 1\n" /* netherbrickstairs */ + "e:114: 2\n" /* netherbrickstairs */ + "f:114: 3\n" /* netherbrickstairs */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 1 + "mmmmaaaaammmm" + "mmmmaaaaammmm" + "mmmmaaaaammmm" + "mmmmaaaaammmm" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "mmmma...ammmm" + "mmmma...ammmm" + "mmmma...ammmm" + "mmmma...ammmm" + "aaaaa...aaaaa" + "............." + "............." + "............." + "aaaaaaaaaaaaa" + + // Level 3 + "mmmma...ammmm" + "mmmmb...bmmmm" + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 4 + "mmmma...ammmm" + "mmmmb...bmmmm" + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 5 + "mmmma...ammmm" + "mmmmb...bmmmm" + "mmmma...ammmm" + "mmmmb...bmmmm" + "ababa...ababa" + "............." + "............." + "............." + "ababababababa" + + // Level 6 + "mmmmcaaadmmmm" + "mmmmcaaadmmmm" + "mmmmcaaadmmmm" + "mmmmcaaadmmmm" + "eeeecaaadeeee" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "fffffffffffff", + + // Connections: + "1: 0, 1, 6: 4\n" /* Type 1, BLOCK_FACE_XM */ + "1: 12, 1, 6: 5\n" /* Type 1, BLOCK_FACE_XP */ + "1: 6, 1, 0: 2\n" /* Type 1, BLOCK_FACE_ZM */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // Tee4x4 + + // Turret: + // The data has been exported from gallery Nether, area index 7, ID 34 + { + // Size: + 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7 + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:112: 0\n" /* netherbrick */ + "b:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + "aaaaaaa" + + // Level 2 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 3 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 4 + "aa...aa" + "a.....a" + "......." + "......." + "......." + "a.....a" + "aa...aa" + + // Level 5 + "aabbbaa" + "a.....a" + "b.....b" + "b.....b" + "b.....b" + "a.....a" + "aabbbaa" + + // Level 6 + "aaaaaaa" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "a.....a" + "aaaaaaa", + + // Connections: + "0: 0, 1, 3: 4\n" /* Type 0, BLOCK_FACE_XM */ + "0: 3, 1, 0: 2\n" /* Type 0, BLOCK_FACE_ZM */ + "0: 6, 1, 3: 5\n" /* Type 0, BLOCK_FACE_XP */ + "0: 3, 1, 6: 3\n" /* Type 0, BLOCK_FACE_ZP */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotations */ + + // Merge strategy: + cBlockArea::msSpongePrint, + }, // Turret + +} ; // g_NetherFortPrefabs1 + + + + + +const cPrefab::sDef g_NetherFortStartingPrefabs1[] = +{ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // CentralRoom: + // The data has been exported from gallery Nether, area index 22, ID 164 + { + // Size: + 13, 9, 13, // SizeX = 13, SizeY = 9, SizeZ = 13 + + // Block definitions: + "a:112: 0\n" /* netherbrick */ + "b: 0: 0\n" /* air */ + "c: 10: 0\n" /* lava */ + "d:113: 0\n" /* netherbrickfence */, + + // Block data: + // Level 1 + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + "aaaaaaaaaaaaa" + + // Level 2 + "aaaaabbbaaaaa" + "aaaaabbbaaaaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbaaabbbaa" + "aabbbacabbbaa" + "aabbbaaabbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aabbbbbbbbbaa" + "aaaaabbbaaaaa" + "aaaaabbbaaaaa" // Level 3 "aaaaabbbaaaaa" @@ -1120,7 +2664,7 @@ const cPrefab::sDef g_NetherFortStartingPrefabs1[] = "aaaaabbbaaaaa" // Level 5 - "adadabbbadada" + "adadadddadada" "daaaabbbaaaad" "aabbbbbbbbbaa" "dabbbbbbbbbad" -- cgit v1.2.3 From a87bd5788f7e3e489282b3f69e0bb0ba1ddbafd8 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 30 Mar 2014 13:07:28 +0100 Subject: Another curly --- src/Items/ItemMinecart.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h index bf6f70eed..25500aeb9 100644 --- a/src/Items/ItemMinecart.h +++ b/src/Items/ItemMinecart.h @@ -1,4 +1,3 @@ - // ItemMinecart.h // Declares the various minecart ItemHandlers @@ -74,7 +73,9 @@ public: Minecart->Initialize(a_World); if (!a_Player->IsGameModeCreative()) + { a_Player->GetInventory().RemoveOneEquippedItem(); + } return true; } -- cgit v1.2.3 From 451a3e97c3748bcccb2ea2aef224b53bd8cbba9b Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 30 Mar 2014 19:25:17 +0300 Subject: Apache license --- LICENSE | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 566c55b46..69b3c7390 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,199 @@ - Copyright MCServer Contributors +MCServer: A performant C++ Minecraft Server +www: http://mc-server.org/ + +Copyright 2014 MCServer Team + +------ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. -- cgit v1.2.3 From b64a1daf6cc5a80ace34d348e9f8bb4b679a7651 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 18:47:57 +0200 Subject: APIDump: Added article: Setting up ZeroBrane Studio. Fixes #824. --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + MCServer/Plugins/APIDump/SettingUpZeroBrane.html | 45 ++++++++++++++++++++++ MCServer/Plugins/APIDump/Static/zbs_logo.png | Bin 0 -> 1306 bytes MCServer/Plugins/APIDump/Static/zbs_workspace.png | Bin 0 -> 72631 bytes 4 files changed, 46 insertions(+) create mode 100644 MCServer/Plugins/APIDump/SettingUpZeroBrane.html create mode 100644 MCServer/Plugins/APIDump/Static/zbs_logo.png create mode 100644 MCServer/Plugins/APIDump/Static/zbs_workspace.png diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 01f000182..83d544173 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2845,6 +2845,7 @@ end -- No sorting is provided for these, they will be output in the same order as defined here { FileName = "Writing-a-MCServer-plugin.html", Title = "Writing a MCServer plugin" }, { FileName = "SettingUpDecoda.html", Title = "Setting up the Decoda Lua IDE" }, + { FileName = "SettingUpZeroBrane.html", Title = "Setting up the ZeroBrane Studio Lua IDE" }, { FileName = "WebWorldThreads.html", Title = "Webserver vs World threads" }, } } ; diff --git a/MCServer/Plugins/APIDump/SettingUpZeroBrane.html b/MCServer/Plugins/APIDump/SettingUpZeroBrane.html new file mode 100644 index 000000000..0fb89e49d --- /dev/null +++ b/MCServer/Plugins/APIDump/SettingUpZeroBrane.html @@ -0,0 +1,45 @@ + + + + + MCServer - Setting up ZeroBrane Studio + + + + + + + +
    +

    Setting up the ZeroBrane Studio IDE

    +

    + This article will explain how to set up ZeroBrane Studio, an IDE for writing Lua code, so that you can develop MCServer plugins with the comfort of an IDE.

    + +

    About ZeroBrane Studio

    + +

    To quickly introduce ZeroBrane Studio, it is an IDE for writing Lua code. It has the basic features expected of an IDE - it allows you to manage groups of files as a project, you can edit multiple files in a tabbed editor, the code is syntax-highlighted. Code completion, symbol browsing, and more. It also features a Lua debugger that allows you to debug your Lua code within any application that uses Lua and can load Lua packages. It is written using the multiplatform WxWidgets toolkit, and runs on multiple platforms, including Windows, Linux and MacOS.

    +

    Here's a screenshot of a default ZBS window with the debugger stepping through the code (scaled down):
    +

    +

    As you can see, you can set breakpoints in the code, inspect variables' values, view the Lua call-stacks.

    +

    ZBS is open-source, the sources are on GitHub: https://github.com/pkulchenko/ZeroBraneStudio. The project's homepage is at http://studio.zerobrane.com/. + +

    First-time setup

    +

    Since ZBS is a universal Lua IDE, you need to first set it up so that it is ready for MCS plugin development. For that, you need to download one file, mcserver.lua from the ZBS's plugin repository. Place that file in the "packages" folder inside your ZBS's folder. Note that there are other useful plugins in the repository and you may want to have a look there later on to further customize your ZBS. To install them, simply save them into the same folder.

    +

    After you download the mcserver.lua file, you need to restart ZBS in order for the plugin to load. If there are no errors, you should see two new items in the Project -> Lua Interpreter submenu: "MCServer - debug mode" and "MCServer - release mode". The only difference between the two is which filename they use to launch MCServer - mcserver_debug(.exe) for the debug option and "mcserver(.exe)" for the release option. If you built your own MCServer executable and you built it in debug mode, you should select the debug mode option. In all other cases, including if you downloaded the already-compiled MCServer executable from the internet, you should select the release mode option.

    +

    For a first time user, it might be a bit overwhelming that there are no GUI settings in the ZBS, yet the IDE is very configurable. There are two files that you edit in order to change settings, either system-wide (all users of the computer share those settings) or user-wide (the settings are only for a specific user of the computer). Those files are regular Lua sources and you can quickly locate them and edit them from within the IDE itself, select Edit -> Preferences -> Settings: XYZ from the menu, with XYZ being either System or User.

    +

    There is a documentation on most of the settings on ZBS's webpage, have a look at http://studio.zerobrane.com/documentation.html, especially the Preferences section. Personally I recommend setting editor.usetabs to true and possibly adjusting the editor.tabwidth, turn off the editor.smartindent feature and for debugging the option debugger.alloweditting should be set to true unless you feel like punishing yourself.

    + +

    Project management

    +

    ZBS works with projects, it considers all files and subfolder in a specific folder to be a project. There's no need for a special project file nor for adding individual files to the workspace, all files are added automatically. To open a MCS plugin as the project, click the triple-dot button in the Project pane, or select Project -> Project directory -> Choose... from the menu. Browse and select the MCS plugin's folder. ZBS will load all the files in the plugin's folder and you can start editting code.

    +

    Note that although ZBS allows you to work with subfolders in your plugins (and you should, especially with larger plugins), the current mcserver ZBS plugin will not be able to start debugging unless you have a file open in the editor that is at the root level of the MCS plugin's folder.

    + +

    Debugging

    +

    You are now ready to debug your code. Before doing that, though, don't forget to save your project files. If you haven't done so already, enable your plugin in the settings.ini file. If you want the program to break at a certain line, it is best to set the breakpoint before starting the program. Set the cursor on the line and hit F9 (or use menu Project -> Toggle Breakpoint) to toggle a breakpoint on that line. Finally, hit F5, or select menu Project -> Start Debugging to launch MCServer under the debugger. The MCServer window comes up and loads your plugin. If the window doesn't come up, inspect the Output pane in ZBS, there are usually two reasons for failure:

      +
    • Your code in the currently open file has a hard syntax error. These are reported as "Compilation error" in the Output pane, double-click the line to go to the error
    • +
    • ZBS cannot find the MCServer executable. Make sure you are editting a file two levels down the folder hierarchy from the MCS executable and that the MCS executable is named properly (mcserver[.exe] or mcserver_debug[.exe]). Also make sure you have selected the right Interpreter (menu Project -> Lua Interpreter).
    • +

    +

    Once running, if the execution hits a breakpoint, the ZBS window will come up and a green arrow is displayed next to the breakpoint line. You can step through the code using F10 (Step Into) and Shift+F10 (Step Over). You can also use the Watch window to inspect variable values, or simply hover your mouse over a variable to display its value in the tooltip. Use the Remote console pane to execute commands directly *inside* the MCServer's plugin context.

    +

    You can also use the Project -> Break menu item to break into the debugger as soon as possible. You can also set breakpoints while the MCS plugin is running. Note that due to the way in which the debugger is implemented, MCS may execute some more Lua code before the break / breakpoint comes into effect. If MCS is not executing any Lua code in your plugin, it will not break until the plugin code kicks in again. This may result in missed breakpoints and delays before the Break command becomes effective. Therefore it's best to set breakpoints before running the program, or while the program is waiting in another breakpoint.

    +
    + + diff --git a/MCServer/Plugins/APIDump/Static/zbs_logo.png b/MCServer/Plugins/APIDump/Static/zbs_logo.png new file mode 100644 index 000000000..c8d6d6278 Binary files /dev/null and b/MCServer/Plugins/APIDump/Static/zbs_logo.png differ diff --git a/MCServer/Plugins/APIDump/Static/zbs_workspace.png b/MCServer/Plugins/APIDump/Static/zbs_workspace.png new file mode 100644 index 000000000..9ce17e35a Binary files /dev/null and b/MCServer/Plugins/APIDump/Static/zbs_workspace.png differ -- cgit v1.2.3 From a5c0600e6c69c329fcafc2f9138b9439cf5f65ce Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 20:02:30 +0200 Subject: Fixed a few clang warnings. --- src/Blocks/BlockPluginInterface.h | 6 ++++++ src/Item.h | 2 +- src/LightingThread.h | 6 +++--- src/World.h | 6 +++--- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Blocks/BlockPluginInterface.h b/src/Blocks/BlockPluginInterface.h index 7428c9a7a..3a36c40b1 100644 --- a/src/Blocks/BlockPluginInterface.h +++ b/src/Blocks/BlockPluginInterface.h @@ -1,8 +1,14 @@ #pragma once +/** This interface is used to decouple block handlers from the cPluginManager dependancy through cWorld. +The block handlers call this interface, which is then implemented by the specific classes that +the caller provides. +*/ class cBlockPluginInterface { public: + virtual ~cBlockPluginInterface() {} + virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; }; diff --git a/src/Item.h b/src/Item.h index 4bdfb12dd..910ecb382 100644 --- a/src/Item.h +++ b/src/Item.h @@ -209,7 +209,7 @@ public: void Add (const cItem & a_Item) {push_back(a_Item); } void Delete(int a_Idx); void Clear (void) {clear(); } - int Size (void) {return size(); } + size_t Size (void) {return size(); } void Set (int a_Idx, short a_ItemType, char a_ItemCount, short a_ItemDamage); void Add (short a_ItemType, char a_ItemCount, short a_ItemDamage) diff --git a/src/LightingThread.h b/src/LightingThread.h index 198f27248..3209ad9b2 100644 --- a/src/LightingThread.h +++ b/src/LightingThread.h @@ -160,14 +160,14 @@ protected: inline void PropagateLight( NIBBLETYPE * a_Light, - int a_SrcIdx, int a_DstIdx, + unsigned int a_SrcIdx, unsigned int a_DstIdx, int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut ) { ASSERT(a_SrcIdx >= 0); - ASSERT(a_SrcIdx < (int)ARRAYCOUNT(m_SkyLight)); + ASSERT(a_SrcIdx < ARRAYCOUNT(m_SkyLight)); ASSERT(a_DstIdx >= 0); - ASSERT(a_DstIdx < (int)ARRAYCOUNT(m_BlockTypes)); + ASSERT(a_DstIdx < ARRAYCOUNT(m_BlockTypes)); if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + cBlockInfo::GetSpreadLightFalloff(m_BlockTypes[a_DstIdx])) { diff --git a/src/World.h b/src/World.h index bb2eb0b21..b3ee94a27 100644 --- a/src/World.h +++ b/src/World.h @@ -646,9 +646,9 @@ public: // Various queues length queries (cannot be const, they lock their CS): inline int GetGeneratorQueueLength (void) { return m_Generator.GetQueueLength(); } // tolua_export - inline int GetLightingQueueLength (void) { return m_Lighting.GetQueueLength(); } // tolua_export - inline int GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export - inline int GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export + inline size_t GetLightingQueueLength (void) { return m_Lighting.GetQueueLength(); } // tolua_export + inline size_t GetStorageLoadQueueLength(void) { return m_Storage.GetLoadQueueLength(); } // tolua_export + inline size_t GetStorageSaveQueueLength(void) { return m_Storage.GetSaveQueueLength(); } // tolua_export void InitializeSpawn(void); -- cgit v1.2.3 From 8288e53c0be9f4f746a045d5ce8fca6bf6799824 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 30 Mar 2014 23:13:13 +0200 Subject: Fixed a few Clang warnings in BlockHandlers. --- src/Blocks/BlockAnvil.h | 10 +++++----- src/Blocks/BlockCauldron.h | 2 +- src/Blocks/BlockCrops.h | 12 ++++++------ src/Blocks/BlockDirt.h | 10 +++++----- src/Blocks/BlockFire.h | 22 ++++++++++++---------- src/Blocks/BlockLeaves.h | 19 ++++++++++--------- src/Blocks/BlockMobHead.h | 4 ++-- src/Blocks/BlockNetherWart.h | 15 ++++++++------- src/Blocks/BlockRail.h | 1 + src/Blocks/BlockStems.h | 3 ++- src/Blocks/BlockVine.h | 4 ++-- 11 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index 9f5f84be0..57d10ebce 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -33,16 +33,16 @@ public: a_BlockType = m_BlockType; int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3; - int RawMeta = a_BlockMeta >> 2; + NIBBLETYPE RawMeta = a_BlockMeta >> 2; Direction++; Direction %= 4; switch (Direction) { - case 0: a_BlockMeta = 0x2 | RawMeta << 2; break; - case 1: a_BlockMeta = 0x3 | RawMeta << 2; break; - case 2: a_BlockMeta = 0x0 | RawMeta << 2; break; - case 3: a_BlockMeta = 0x1 | RawMeta << 2; break; + case 0: a_BlockMeta = 0x2 | (RawMeta << 2); break; + case 1: a_BlockMeta = 0x3 | (RawMeta << 2); break; + case 2: a_BlockMeta = 0x0 | (RawMeta << 2); break; + case 3: a_BlockMeta = 0x1 | (RawMeta << 2); break; default: { return false; diff --git a/src/Blocks/BlockCauldron.h b/src/Blocks/BlockCauldron.h index 2e1032d2b..41b79b6c3 100644 --- a/src/Blocks/BlockCauldron.h +++ b/src/Blocks/BlockCauldron.h @@ -23,7 +23,7 @@ public: virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { - char Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); switch (a_Player->GetEquippedItem().m_ItemType) { case E_ITEM_WATER_BUCKET: diff --git a/src/Blocks/BlockCrops.h b/src/Blocks/BlockCrops.h index ffc2b3f8b..8606cf3f3 100644 --- a/src/Blocks/BlockCrops.h +++ b/src/Blocks/BlockCrops.h @@ -2,7 +2,7 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" +#include "../FastRandom.h" @@ -21,7 +21,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override { - MTRand rand; + cFastRandom rand; if (a_Meta == 0x7) { @@ -31,18 +31,18 @@ public: case E_BLOCK_CROPS: { a_Pickups.push_back(cItem(E_ITEM_WHEAT, 1, 0)); - a_Pickups.push_back(cItem(E_ITEM_SEEDS, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); // [1 .. 3] with high preference of 2 + a_Pickups.push_back(cItem(E_ITEM_SEEDS, (char)(1 + (rand.NextInt(3) + rand.NextInt(3)) / 2), 0)); // [1 .. 3] with high preference of 2 break; } case E_BLOCK_CARROTS: { - a_Pickups.push_back(cItem(E_ITEM_CARROT, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); // [1 .. 3] with high preference of 2 + a_Pickups.push_back(cItem(E_ITEM_CARROT, (char)(1 + (rand.NextInt(3) + rand.NextInt(3)) / 2), 0)); // [1 .. 3] with high preference of 2 break; } case E_BLOCK_POTATOES: { - a_Pickups.push_back(cItem(E_ITEM_POTATO, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); // [1 .. 3] with high preference of 2 - if (rand.randInt(20) == 0) + a_Pickups.push_back(cItem(E_ITEM_POTATO, (char)(1 + (rand.NextInt(3) + rand.NextInt(3)) / 2), 0)); // [1 .. 3] with high preference of 2 + if (rand.NextInt(21) == 0) { // With a 5% chance, drop a poisonous potato as well a_Pickups.push_back(cItem(E_ITEM_POISONOUS_POTATO, 1, 0)); diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index a1ab74257..aa24b8668 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -2,7 +2,7 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" +#include "../FastRandom.h" @@ -44,12 +44,12 @@ public: } // Grass spreads to adjacent dirt blocks: - MTRand rand; // TODO: Replace with cFastRandom + cFastRandom rand; for (int i = 0; i < 2; i++) // Pick two blocks to grow to { - int OfsX = rand.randInt(2) - 1; // [-1 .. 1] - int OfsY = rand.randInt(4) - 3; // [-3 .. 1] - int OfsZ = rand.randInt(2) - 1; // [-1 .. 1] + int OfsX = rand.NextInt(3, a_RelX) - 1; // [-1 .. 1] + int OfsY = rand.NextInt(5, a_RelY) - 3; // [-3 .. 1] + int OfsZ = rand.NextInt(3, a_RelZ) - 1; // [-1 .. 1] BLOCKTYPE DestBlock; NIBBLETYPE DestMeta; diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index a25b87858..c8f158e7e 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -17,25 +17,27 @@ public: } /// Portal boundary and direction variables - int XZP, XZM, Dir; // For wont of a better name... + // 2014_03_30 _X: What are these used for? Why do we need extra variables? + int XZP, XZM; + NIBBLETYPE Dir; virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override { /* PORTAL FINDING ALGORITH ======================= - -Get clicked base block - -Trace upwards to find first obsidian block; aborts if anything other than obsidian or air is encountered. - Uses this value as a reference (the 'ceiling') - -For both directions (if one fails, try the other), BASE (clicked) block: - -Go in one direction, only stop if a non obsidian block is encountered (abort) OR a portal border is encountered (FindObsidianCeiling returns -1) - -If a border was encountered, go the other direction and repeat above - -Write borders to XZP and XZM, write direction portal faces to Dir - -Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir + - Get clicked base block + - Trace upwards to find first obsidian block; aborts if anything other than obsidian or air is encountered. + Uses this value as a reference (the 'ceiling') + - For both directions (if one fails, try the other), BASE (clicked) block: + - Go in one direction, only stop if a non obsidian block is encountered (abort) OR a portal border is encountered (FindObsidianCeiling returns -1) + - If a border was encountered, go the other direction and repeat above + - Write borders to XZP and XZM, write direction portal faces to Dir + - Loop through boundary variables, and fill with portal blocks based on Dir with meta from Dir */ a_BlockY--; // Because we want the block below the fire - FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_ChunkInterface, a_WorldInterface); // Brought to you by Aperture Science + FindAndSetPortalFrame(a_BlockX, a_BlockY, a_BlockZ, a_ChunkInterface, a_WorldInterface); } virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index a6d3373c1..8af14686e 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -1,6 +1,6 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" +#include "../FastRandom.h" #include "../World.h" #include "../BlockArea.h" @@ -37,16 +37,18 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - MTRand rand; + cFastRandom rand; // Only the first 2 bits contain the display information, the others are for growing - if (rand.randInt(5) == 0) + if (rand.NextInt(6) == 0) { a_Pickups.push_back(cItem(E_BLOCK_SAPLING, 1, a_BlockMeta & 3)); } - if ((a_BlockMeta & 3) == E_META_SAPLING_APPLE) + + // 1 % chance of dropping an apple, if the leaves' type is Apple Leaves + if ((a_BlockMeta & 3) == E_META_LEAVES_APPLE) { - if (rand.rand(100) == 0) + if (rand.NextInt(101) == 0) { a_Pickups.push_back(cItem(E_ITEM_RED_APPLE, 1, 0)); } @@ -58,11 +60,10 @@ public: { cBlockHandler::OnDestroyed(a_ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); - //0.5% chance of dropping an apple + // 0.5% chance of dropping an apple, if the leaves' type is Apple Leaves: NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - //check if Oak (0x1 and 0x2 bit not set) - MTRand rand; - if(!(Meta & 3) && rand.randInt(200) == 100) + cFastRandom rand; + if (((Meta & 3) == E_META_LEAVES_APPLE) && (rand.NextInt(201) == 100)) { cItems Drops; Drops.push_back(cItem(E_ITEM_RED_APPLE, 1, 0)); diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 6aa01f986..080843a73 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -62,8 +62,8 @@ public: } public: - cCallback (cPlayer * a_Player, NIBBLETYPE a_OldBlockMeta, NIBBLETYPE a_NewBlockMeta) : - m_Player(a_Player), + cCallback (cPlayer * a_CBPlayer, NIBBLETYPE a_OldBlockMeta, NIBBLETYPE a_NewBlockMeta) : + m_Player(a_CBPlayer), m_OldBlockMeta(a_OldBlockMeta), m_NewBlockMeta(a_NewBlockMeta) {} diff --git a/src/Blocks/BlockNetherWart.h b/src/Blocks/BlockNetherWart.h index 923180e19..812cf906f 100644 --- a/src/Blocks/BlockNetherWart.h +++ b/src/Blocks/BlockNetherWart.h @@ -2,14 +2,13 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" +#include "../FastRandom.h" #include "../World.h" -/// Common class that takes care of carrots, potatoes and wheat class cBlockNetherWartHandler : public cBlockHandler { @@ -22,12 +21,12 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_Meta) override { - MTRand rand; + cFastRandom rand; if (a_Meta == 0x7) { - // Is fully grown, drop the entire produce: - a_Pickups.push_back(cItem(E_ITEM_NETHER_WART, 1 + (int)(rand.randInt(2) + rand.randInt(2)) / 2, 0)); + // Fully grown, drop the entire produce: + a_Pickups.push_back(cItem(E_ITEM_NETHER_WART, (char)(1 + (rand.NextInt(3) + rand.NextInt(3))) / 2, 0)); } else { @@ -35,18 +34,20 @@ public: } } + virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { - NIBBLETYPE Meta = a_Chunk.GetMeta (a_RelX, a_RelY, a_RelZ); - + NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); if (Meta < 7) { a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_NETHER_WART, ++Meta); } } + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { + // Needs to be placed on top of a Soulsand block: return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_SOULSAND)); } } ; diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index 477707a91..ad78d290a 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -431,6 +431,7 @@ public: } break; } + default: break; } return true; } diff --git a/src/Blocks/BlockStems.h b/src/Blocks/BlockStems.h index 705436345..b726a0901 100644 --- a/src/Blocks/BlockStems.h +++ b/src/Blocks/BlockStems.h @@ -17,9 +17,10 @@ public: { } + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - int ItemType = (m_BlockType == E_BLOCK_MELON_STEM) ? E_ITEM_MELON_SEEDS : E_ITEM_PUMPKIN_SEEDS; + short ItemType = (m_BlockType == E_BLOCK_MELON_STEM) ? E_ITEM_MELON_SEEDS : E_ITEM_PUMPKIN_SEEDS; a_Pickups.push_back(cItem(ItemType, 1, 0)); } diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index e14218633..e796a45ae 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -83,7 +83,7 @@ public: static const struct { int x, z; - int Bit; + NIBBLETYPE Bit; } Coords[] = { { 0, 1, 1}, // south, ZP @@ -91,7 +91,7 @@ public: { 0, -1, 4}, // north, ZM { 1, 0, 8}, // east, XP } ; - int res = 0; + NIBBLETYPE res = 0; for (size_t i = 0; i < ARRAYCOUNT(Coords); i++) { BLOCKTYPE BlockType; -- cgit v1.2.3 From 43844fc0f04ffd326af4ebc9e46ec220e27d1309 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 31 Mar 2014 13:28:38 +0200 Subject: cCompositeChat has a MessageType param in the constructor. This should make it easier to use. --- src/CompositeChat.cpp | 4 ++-- src/CompositeChat.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index a917ee70f..94f8a5901 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -112,8 +112,8 @@ cCompositeChat::cCompositeChat(void) : -cCompositeChat::cCompositeChat(const AString & a_ParseText) : - m_MessageType(mtCustom) +cCompositeChat::cCompositeChat(const AString & a_ParseText, eMessageType a_MessageType) : + m_MessageType(a_MessageType) { ParseText(a_ParseText); } diff --git a/src/CompositeChat.h b/src/CompositeChat.h index 27319490d..d5f4ebb24 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -117,7 +117,7 @@ public: /** Creates a new chat message and parses the text into parts. Recognizes "http:" and "https:" links and @color-codes. Uses ParseText() for the actual parsing. */ - cCompositeChat(const AString & a_ParseText); + cCompositeChat(const AString & a_ParseText, eMessageType a_MessageType = mtCustom); ~cCompositeChat(); -- cgit v1.2.3 From f38a009b3cc5caf25d11496fda5caf75531127d0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 31 Mar 2014 18:25:00 +0200 Subject: APIDump: Renamed the ZBS API dump file to mcserver_api.lua. This is to avoid confusion with ZBS, where two "mcserver.lua" files were present. --- MCServer/Plugins/APIDump/main_APIDump.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/APIDump/main_APIDump.lua b/MCServer/Plugins/APIDump/main_APIDump.lua index 7455c3cd2..52199740b 100644 --- a/MCServer/Plugins/APIDump/main_APIDump.lua +++ b/MCServer/Plugins/APIDump/main_APIDump.lua @@ -1408,9 +1408,9 @@ end --- Dumps the entire API table into a file in the ZBS format local function DumpAPIZBS(a_API) LOG("Dumping ZBS API description...") - local f, err = io.open("mcserver.lua", "w") + local f, err = io.open("mcserver_api.lua", "w") if (f == nil) then - LOG("Cannot open mcserver.lua for writing, ZBS API will not be dumped. " .. err) + LOG("Cannot open mcserver_lua.lua for writing, ZBS API will not be dumped. " .. err) return end -- cgit v1.2.3 From 55d0db1606f947c1b232e6329345fe7493805dcc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 31 Mar 2014 18:34:27 +0200 Subject: APIDump: Added code completion support file to ZBS tutorial. --- MCServer/Plugins/APIDump/SettingUpZeroBrane.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/SettingUpZeroBrane.html b/MCServer/Plugins/APIDump/SettingUpZeroBrane.html index 0fb89e49d..4ebbcb6e6 100644 --- a/MCServer/Plugins/APIDump/SettingUpZeroBrane.html +++ b/MCServer/Plugins/APIDump/SettingUpZeroBrane.html @@ -25,7 +25,8 @@

    First-time setup

    Since ZBS is a universal Lua IDE, you need to first set it up so that it is ready for MCS plugin development. For that, you need to download one file, mcserver.lua from the ZBS's plugin repository. Place that file in the "packages" folder inside your ZBS's folder. Note that there are other useful plugins in the repository and you may want to have a look there later on to further customize your ZBS. To install them, simply save them into the same folder.

    -

    After you download the mcserver.lua file, you need to restart ZBS in order for the plugin to load. If there are no errors, you should see two new items in the Project -> Lua Interpreter submenu: "MCServer - debug mode" and "MCServer - release mode". The only difference between the two is which filename they use to launch MCServer - mcserver_debug(.exe) for the debug option and "mcserver(.exe)" for the release option. If you built your own MCServer executable and you built it in debug mode, you should select the debug mode option. In all other cases, including if you downloaded the already-compiled MCServer executable from the internet, you should select the release mode option.

    +

    Next you should install the code-completion support specific for MCServer. You should repeat this step from time to time, because the API evolves in time so new functions and classes are added to it quite often. You should have an APIDump plugin in your MCServer installation. Enable the APIDump plugin in the server settings, it's very cheap to keep it enabled and it doesn't cost any performance during normal gameplay. To generate the code-completion support file, enter the api command into the server console. This will create a new file, "mcserver_api.lua", next to the MCS executable. Move that file into the "api/lua" subfolder inside your ZBS's folder.

    +

    After you download the mcserver.lua file and install the completion support, you need to restart ZBS in order for the plugin to load. If there are no errors, you should see two new items in the Project -> Lua Interpreter submenu: "MCServer - debug mode" and "MCServer - release mode". The only difference between the two is which filename they use to launch MCServer - mcserver_debug(.exe) for the debug option and "mcserver(.exe)" for the release option. If you built your own MCServer executable and you built it in debug mode, you should select the debug mode option. In all other cases, including if you downloaded the already-compiled MCServer executable from the internet, you should select the release mode option.

    For a first time user, it might be a bit overwhelming that there are no GUI settings in the ZBS, yet the IDE is very configurable. There are two files that you edit in order to change settings, either system-wide (all users of the computer share those settings) or user-wide (the settings are only for a specific user of the computer). Those files are regular Lua sources and you can quickly locate them and edit them from within the IDE itself, select Edit -> Preferences -> Settings: XYZ from the menu, with XYZ being either System or User.

    There is a documentation on most of the settings on ZBS's webpage, have a look at http://studio.zerobrane.com/documentation.html, especially the Preferences section. Personally I recommend setting editor.usetabs to true and possibly adjusting the editor.tabwidth, turn off the editor.smartindent feature and for debugging the option debugger.alloweditting should be set to true unless you feel like punishing yourself.

    -- cgit v1.2.3 From c4e07631c803debf1047a5607c96d9bf5c1e5f95 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 31 Mar 2014 19:47:18 +0200 Subject: Added new merge strategy "msDifference" --- src/BlockArea.cpp | 34 ++++++++++++++++++++++++++++++++++ src/BlockArea.h | 1 + 2 files changed, 35 insertions(+) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 2b950378a..17d3cbb00 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -173,6 +173,25 @@ static inline void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a +/** Combinator used for cBlockArea::msDifference merging */ +static inline void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +{ + if ((a_DstType == a_SrcType) && (a_DstMeta == a_SrcMeta)) + { + a_DstType = E_BLOCK_AIR; + a_DstMeta = 0; + } + else + { + a_DstType = a_SrcType; + a_DstMeta = a_SrcMeta; + } +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cBlockArea: @@ -709,6 +728,21 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R ); break; } // case msSpongePrint + + case msDifference: + { + InternalMergeBlocks( + m_BlockTypes, a_Src.GetBlockTypes(), + DstMetas, SrcMetas, + SizeX, SizeY, SizeZ, + SrcOffX, SrcOffY, SrcOffZ, + DstOffX, DstOffY, DstOffZ, + a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), + m_Size.x, m_Size.y, m_Size.z, + MergeCombinatorDifference + ); + break; + } // case msDifference default: { diff --git a/src/BlockArea.h b/src/BlockArea.h index d37f0d182..0bb272fd9 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -52,6 +52,7 @@ public: msImprint, msLake, msSpongePrint, + msDifference, } ; cBlockArea(void); -- cgit v1.2.3 From f7df8e133b66aafcf35f0590a0ac525a7d2f9278 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 31 Mar 2014 19:58:19 +0200 Subject: Documented msDifference --- MCServer/Plugins/APIDump/APIDesc.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 6f8a14421..532b4b665 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -230,22 +230,22 @@ g_APIDesc =

    - + - + - + - + - + - +
    area blockresultarea blockresult
    this Src msOverwrite msFillAir msImprint this Src msOverwrite msFillAir msImprint msDifference
    air air air air air air air air air air air
    A air air A A A air air A A air
    air B B B B air B B B B B
    A B B A B A B B A B B
    @@ -255,6 +255,8 @@ g_APIDesc =
  • msOverwrite completely overwrites all blocks with the Src's blocks
  • msFillAir overwrites only those blocks that were air
  • msImprint overwrites with only those blocks that are non-air
  • +
  • msSpongePrint Sponge overwrites nothing, everything else overwrites anything
  • +
  • msDifference changes all the blocks wich are the same to air. Otherwise the source block gets placed.
  • -- cgit v1.2.3 From a8bc27f8728a0c1f222871cbd3f5534646e59085 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 31 Mar 2014 20:05:48 +0200 Subject: Fixed typo --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 532b4b665..1b020501c 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -256,7 +256,7 @@ g_APIDesc =
  • msFillAir overwrites only those blocks that were air
  • msImprint overwrites with only those blocks that are non-air
  • msSpongePrint Sponge overwrites nothing, everything else overwrites anything
  • -
  • msDifference changes all the blocks wich are the same to air. Otherwise the source block gets placed.
  • +
  • msDifference changes all the blocks which are the same to air. Otherwise the source block gets placed.
  • -- cgit v1.2.3 From b19022fc7ea4cb6bd1bc6f4b212478e65b5fa5a1 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 31 Mar 2014 20:13:08 +0200 Subject: Added extra table which should make it more clear what msDifference does. --- MCServer/Plugins/APIDump/APIDesc.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 1b020501c..657ac6aa6 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -247,6 +247,9 @@ g_APIDesc = A B B A B B + + A A A A B air +

    @@ -255,7 +258,6 @@ g_APIDesc =

  • msOverwrite completely overwrites all blocks with the Src's blocks
  • msFillAir overwrites only those blocks that were air
  • msImprint overwrites with only those blocks that are non-air
  • -
  • msSpongePrint Sponge overwrites nothing, everything else overwrites anything
  • msDifference changes all the blocks which are the same to air. Otherwise the source block gets placed.
  • -- cgit v1.2.3 From 0836fe9a84e59b083db368205cbf6496355378bf Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 31 Mar 2014 20:33:33 +0100 Subject: Fixed a few Y too high/low asserts --- src/Blocks/BlockFluid.h | 5 +++-- src/MobSpawner.cpp | 12 +++++++----- src/Mobs/Monster.cpp | 10 +++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h index 37885e4de..361b97c60 100644 --- a/src/Blocks/BlockFluid.h +++ b/src/Blocks/BlockFluid.h @@ -93,8 +93,8 @@ public: // Check if it's fuel: BLOCKTYPE BlockType; if ( - !a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || - !cFireSimulator::IsFuel(BlockType) + ((a_RelY + y < 0) || (a_RelY + y > cChunkDef::Height)) || + (!a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || !cFireSimulator::IsFuel(BlockType)) ) { return false; @@ -119,6 +119,7 @@ public: for (size_t i = 0; i < ARRAYCOUNT(CrossCoords); i++) { if ( + ((RelY + CrossCoords[i].y >= 0) && (RelY + CrossCoords[i].y <= cChunkDef::Height)) && a_Chunk.UnboundedRelGetBlockType(RelX + CrossCoords[i].x, RelY + CrossCoords[i].y, RelZ + CrossCoords[i].z, BlockType) && (BlockType == E_BLOCK_AIR) ) diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index a0d0f5c54..216681b48 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -129,6 +129,11 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R BLOCKTYPE TargetBlock = E_BLOCK_AIR; if (m_AllowedTypes.find(a_MobType) != m_AllowedTypes.end() && a_Chunk->UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, TargetBlock)) { + if ((a_RelY + 1 > cChunkDef::Height) || (a_RelY - 1 < 0)) + { + return false; + } + NIBBLETYPE BlockLight = a_Chunk->GetBlockLight(a_RelX, a_RelY, a_RelZ); NIBBLETYPE SkyLight = a_Chunk->GetSkyLight(a_RelX, a_RelY, a_RelZ); BLOCKTYPE BlockAbove = a_Chunk->GetBlock(a_RelX, a_RelY + 1, a_RelZ); @@ -212,11 +217,8 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R return false; } HaveFloor = ( - HaveFloor || - ( - a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1, a_RelZ + z, TargetBlock) && - !cBlockInfo::IsTransparent(TargetBlock) - ) + a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1 /* Checked at start of function */, a_RelZ + z, TargetBlock) && + !cBlockInfo::IsTransparent(TargetBlock) ); } } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index d3e0f1c26..83003006e 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -111,9 +111,9 @@ void cMonster::SpawnOn(cClientHandle & a_Client) void cMonster::TickPathFinding() { - int PosX = (int)floor(GetPosX()); - int PosY = (int)floor(GetPosY()); - int PosZ = (int)floor(GetPosZ()); + const int PosX = (int)floor(GetPosX()); + const int PosY = (int)floor(GetPosY()); + const int PosZ = (int)floor(GetPosZ()); m_FinalDestination.y = (double)FindFirstNonAirBlockPosition(m_FinalDestination.x, m_FinalDestination.z); @@ -133,9 +133,9 @@ void cMonster::TickPathFinding() for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) { - if ((gCrossCoords[i].x + PosX == PosX) && (gCrossCoords[i].z + PosZ == PosZ)) + if ((PosY - 1 < 0) || (PosY + 1 > cChunkDef::Height) || (PosY + 2 > cChunkDef::Height)) { - continue; + break; } if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ))) -- cgit v1.2.3 From ee07b7ae3ec9cd283fe61aede067e7fc9e4bcb49 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 31 Mar 2014 20:34:11 +0100 Subject: Simplified and fixed slabs, fixes #835 --- src/Blocks/BlockSlab.h | 43 ++++++++++--------------------------------- src/ClientHandle.cpp | 2 +- src/ClientHandle.h | 4 ++-- 3 files changed, 13 insertions(+), 36 deletions(-) diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 77e8b8e55..3f0fef0c7 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -11,6 +11,7 @@ #include "BlockHandler.h" #include "../Items/ItemHandler.h" +#include "Root.h" @@ -38,41 +39,9 @@ public: ) override { a_BlockType = m_BlockType; - BLOCKTYPE Type = (BLOCKTYPE) (a_Player->GetEquippedItem().m_ItemType); NIBBLETYPE Meta = (NIBBLETYPE) a_Player->GetEquippedItem().m_ItemDamage; - // HandlePlaceBlock wants a cItemHandler pointer thing, so let's give it one - cItemHandler * ItemHandler = cItemHandler::GetItemHandler(GetDoubleSlabType(Type)); - - // Check if the block at the coordinates is a slab. Eligibility for combining has already been processed in ClientHandle - if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))) - { - // Call the function in ClientHandle that places a block when the client sends the packet, - // so that plugins may interfere with the placement. - - if ((a_BlockFace == BLOCK_FACE_TOP) || (a_BlockFace == BLOCK_FACE_BOTTOM)) - { - // Top and bottom faces need no parameter modification - a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); - } - else - { - // The other faces need to distinguish between top and bottom cursor positions - if (a_CursorY > 7) - { - // Edit the call to use BLOCK_FACE_BOTTOM, otherwise it places incorrectly - a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_TOP, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); - } - else - { - // Edit the call to use BLOCK_FACE_TOP, otherwise it places incorrectly - a_Player->GetClientHandle()->HandlePlaceBlock(a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_BOTTOM, a_CursorX, a_CursorY, a_CursorZ, *ItemHandler); - } - } - return false; // Cancel the event, because dblslabs were already placed, nothing else needed - } - - // Place the single-slab with correct metas: + // Set the correct metadata based on player equipped item (i.e. a_BlockMeta not initialised yet) switch (a_BlockFace) { case BLOCK_FACE_TOP: @@ -104,6 +73,14 @@ public: } } } // switch (a_BlockFace) + + // Check if the block at the coordinates is a single slab. Eligibility for combining has already been processed in ClientHandle + // Changed to-be-placed to a double slab if we are clicking on a single slab, as opposed to placing one for the first time + if (IsAnySlabType(a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))) + { + a_BlockType = GetDoubleSlabType(m_BlockType); + } + return true; } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 5ed5f1085..23ba4dbab 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1064,7 +1064,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e // If clicked top face and slab occupies the top voxel, we want a slab to be placed above it (therefore increment Y) // Else if clicked bottom face and slab occupies the bottom voxel, decrement Y for the same reason // Don't touch coordinates if anything else because a dblslab opportunity is present - if((ClickedBlockMeta & 0x08) && (a_BlockFace == BLOCK_FACE_TOP)) + if ((ClickedBlockMeta & 0x08) && (a_BlockFace == BLOCK_FACE_TOP)) { ++a_BlockY; } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 8366caa16..5496e61a7 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -230,10 +230,10 @@ public: /** Called when the player moves into a different world; queues sreaming the new chunks */ void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket); +private: + /** Handles the block placing packet when it is a real block placement (not block-using, item-using or eating) */ void HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler); - -private: /** The type used for storing the names of registered plugin channels. */ typedef std::set cChannels; -- cgit v1.2.3 From fc940b6da4fd446e718879a19790af03dadfe2f4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 31 Mar 2014 21:36:19 +0100 Subject: Realised suggestions --- src/Blocks/BlockFluid.h | 5 ++++- src/MobSpawner.cpp | 13 ++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h index 361b97c60..1200997ff 100644 --- a/src/Blocks/BlockFluid.h +++ b/src/Blocks/BlockFluid.h @@ -94,7 +94,10 @@ public: BLOCKTYPE BlockType; if ( ((a_RelY + y < 0) || (a_RelY + y > cChunkDef::Height)) || - (!a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || !cFireSimulator::IsFuel(BlockType)) + ( + !a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || + !cFireSimulator::IsFuel(BlockType) + ) ) { return false; diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index 216681b48..05da5d01c 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -205,7 +205,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R case cMonster::mtSpider: { bool CanSpawn = true; - bool HaveFloor = false; + bool HasFloor = false; for (int x = 0; x < 2; ++x) { for(int z = 0; z < 2; ++z) @@ -216,13 +216,16 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R { return false; } - HaveFloor = ( - a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1 /* Checked at start of function */, a_RelZ + z, TargetBlock) && - !cBlockInfo::IsTransparent(TargetBlock) + HasFloor = ( + HasFloor || + ( + a_Chunk->UnboundedRelGetBlockType(a_RelX + x, a_RelY - 1, a_RelZ + z, TargetBlock) && + !cBlockInfo::IsTransparent(TargetBlock) + ) ); } } - return CanSpawn && HaveFloor && (SkyLight <= 7) && (BlockLight <= 7); + return CanSpawn && HasFloor && (SkyLight <= 7) && (BlockLight <= 7); } case cMonster::mtCreeper: -- cgit v1.2.3 From 8126d9e66ef1ac90db2660ae357c9aa1c14c7126 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 31 Mar 2014 22:51:14 +0200 Subject: Console logging supports cCompositeChat as its parameters. --- MCServer/Plugins/Debuggers/Debuggers.lua | 9 +++++++ src/Bindings/ManualBindings.cpp | 46 +++++++++++++++++++++++--------- src/CompositeChat.cpp | 29 ++++++++++++++++++++ src/CompositeChat.h | 5 ++++ src/Protocol/Protocol125.cpp | 23 +--------------- 5 files changed, 78 insertions(+), 34 deletions(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 2cb014875..2619bd6c4 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -75,6 +75,15 @@ function Initialize(Plugin) -- TestPluginCalls(); TestBlockAreasString() + + --[[ + -- Test cCompositeChat usage in console-logging: + LOGINFO(cCompositeChat("This is a simple message with some @2 color formatting @4 and http://links.to .") + :AddSuggestCommandPart("(Suggested command)", "cmd") + :AddRunCommandPart("(Run command)", "cmd") + :SetMessageType(mtInfo) + ) + --]] return true end; diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 20bbc48f2..95cd5e904 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -115,10 +115,35 @@ static int tolua_StringSplitAndTrim(lua_State * tolua_S) -static int tolua_LOG(lua_State* tolua_S) +/** Retrieves the log message from the first param on the Lua stack. +Can take either a string or a cCompositeChat. +*/ +static AString GetLogMessage(lua_State * tolua_S) { - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 0 ); + tolua_Error err; + if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err)) + { + return ((cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL))->ExtractText(); + } + else + { + size_t len = 0; + const char * str = lua_tolstring(tolua_S, 1, &len); + if (str != NULL) + { + return AString(str, len); + } + } + return ""; +} + + + + + +static int tolua_LOG(lua_State * tolua_S) +{ + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 0); return 0; } @@ -126,10 +151,9 @@ static int tolua_LOG(lua_State* tolua_S) -static int tolua_LOGINFO(lua_State* tolua_S) +static int tolua_LOGINFO(lua_State * tolua_S) { - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 1 ); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 1); return 0; } @@ -137,10 +161,9 @@ static int tolua_LOGINFO(lua_State* tolua_S) -static int tolua_LOGWARN(lua_State* tolua_S) +static int tolua_LOGWARN(lua_State * tolua_S) { - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 2 ); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 2); return 0; } @@ -148,10 +171,9 @@ static int tolua_LOGWARN(lua_State* tolua_S) -static int tolua_LOGERROR(lua_State* tolua_S) +static int tolua_LOGERROR(lua_State * tolua_S) { - const char* str = tolua_tocppstring(tolua_S,1,0); - cMCLogger::GetInstance()->LogSimple( str, 3 ); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 3); return 0; } diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index 94f8a5901..918e4f90e 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -314,6 +314,35 @@ void cCompositeChat::UnderlineUrls(void) +AString cCompositeChat::ExtractText(void) const +{ + AString Msg; + for (cParts::const_iterator itr = m_Parts.begin(), end = m_Parts.end(); itr != end; ++itr) + { + switch ((*itr)->m_PartType) + { + case ptText: + case ptClientTranslated: + case ptRunCommand: + case ptSuggestCommand: + { + Msg.append((*itr)->m_Text); + break; + } + case ptUrl: + { + Msg.append(((cUrlPart *)(*itr))->m_Url); + break; + } + } // switch (PartType) + } // for itr - m_Parts[] + return Msg; +} + + + + + void cCompositeChat::AddStyle(AString & a_Style, const AString & a_AddStyle) { if (a_AddStyle.empty()) diff --git a/src/CompositeChat.h b/src/CompositeChat.h index d5f4ebb24..0f56cde9b 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -164,6 +164,11 @@ public: /** Returns the message type set previously by SetMessageType(). */ eMessageType GetMessageType(void) const { return m_MessageType; } + /** Returns the text from the parts that comprises the human-readable data. + Used for older protocols that don't support composite chat + and for console-logging. */ + AString ExtractText(void) const; + // tolua_end const cParts & GetParts(void) const { return m_Parts; } diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 69f4934d8..ea844c044 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -239,32 +239,11 @@ void cProtocol125::SendChat(const AString & a_Message) void cProtocol125::SendChat(const cCompositeChat & a_Message) { // This version doesn't support composite messages, just extract each part's text and use it: - AString Msg; - const cCompositeChat::cParts & Parts = a_Message.GetParts(); - for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr) - { - switch ((*itr)->m_PartType) - { - case cCompositeChat::ptText: - case cCompositeChat::ptClientTranslated: - case cCompositeChat::ptRunCommand: - case cCompositeChat::ptSuggestCommand: - { - Msg.append((*itr)->m_Text); - break; - } - case cCompositeChat::ptUrl: - { - Msg.append(((cCompositeChat::cUrlPart *)(*itr))->m_Url); - break; - } - } // switch (PartType) - } // for itr - Parts[] // Send the message: cCSLock Lock(m_CSPacket); WriteByte (PACKET_CHAT); - WriteString(Msg); + WriteString(a_Message.ExtractText()); Flush(); } -- cgit v1.2.3 From 58f255032176c5e4e3a0f5e6ffea76128355ee61 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 31 Mar 2014 23:05:31 +0200 Subject: APIDump: Documented the cCompositeChat support in logging functions. --- MCServer/Plugins/APIDump/APIDesc.lua | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index eceb19bd7..b1b660bb0 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2663,11 +2663,31 @@ end ItemToFullString = {Params = "{{cItem|cItem}}", Return = "string", Notes = "Returns the string representation of the item, in the format 'ItemTypeText:ItemDamage * Count'"}, ItemToString = {Params = "{{cItem|cItem}}", Return = "string", Notes = "Returns the string representation of the item type"}, ItemTypeToString = {Params = "ItemType", Return = "string", Notes = "Returns the string representation of ItemType "}, - LOG = {Params = "string", Notes = "Logs a text into the server console using 'normal' severity (gray text) "}, - LOGERROR = {Params = "string", Notes = "Logs a text into the server console using 'error' severity (black text on red background)"}, - LOGINFO = {Params = "string", Notes = "Logs a text into the server console using 'info' severity (yellow text)"}, - LOGWARN = {Params = "string", Notes = "Logs a text into the server console using 'warning' severity (red text); OBSOLETE, use LOGWARNING() instead"}, - LOGWARNING = {Params = "string", Notes = "Logs a text into the server console using 'warning' severity (red text)"}, + LOG = + { + {Params = "string", Notes = "Logs a text into the server console using 'normal' severity (gray text) "}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'normal' severity (gray text) "}, + }, + LOGERROR = + { + {Params = "string", Notes = "Logs a text into the server console using 'error' severity (black text on red background)"}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'error' severity (black text on red background)"}, + }, + LOGINFO = + { + {Params = "string", Notes = "Logs a text into the server console using 'info' severity (yellow text)"}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'info' severity (yellow text)"}, + }, + LOGWARN = + { + {Params = "string", Notes = "Logs a text into the server console using 'warning' severity (red text); OBSOLETE, use LOGWARNING() instead"}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'warning' severity (red text); OBSOLETE, use LOGWARNING() instead"}, + }, + LOGWARNING = + { + {Params = "string", Notes = "Logs a text into the server console using 'warning' severity (red text)"}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'warning' severity (red text)"}, + }, MirrorBlockFaceY = { Params = "{{Globals#BlockFaces|eBlockFace}}", Return = "{{Globals#BlockFaces|eBlockFace}}", Notes = "Returns the {{Globals#BlockFaces|eBlockFace}} that corresponds to the given {{Globals#BlockFaces|eBlockFace}} after mirroring it around the Y axis (or rotating 180 degrees around it)." }, NoCaseCompare = {Params = "string, string", Return = "number", Notes = "Case-insensitive string comparison; returns 0 if the strings are the same"}, NormalizeAngleDegrees = { Params = "AngleDegrees", Return = "AngleDegrees", Notes = "Returns the angle, wrapped into the [-180, +180) range." }, -- cgit v1.2.3 From ef48b30baaed9c6ad1782047d4e2d60d6248ad89 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 31 Mar 2014 22:37:05 +0100 Subject: Final realisation of suggestions --- src/Mobs/Monster.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 83003006e..aa6071515 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -130,14 +130,16 @@ void cMonster::TickPathFinding() { 0, 1}, { 0,-1}, } ; + + if ((PosY - 1 < 0) || (PosY + 2 > cChunkDef::Height) /* PosY + 1 will never be true if PosY + 2 is not */) + { + // Too low/high, can't really do anything + FinishPathFinding(); + return; + } for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) { - if ((PosY - 1 < 0) || (PosY + 1 > cChunkDef::Height) || (PosY + 2 > cChunkDef::Height)) - { - break; - } - if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ))) { continue; -- cgit v1.2.3 From 7aa6a3b86663ef28295ffb914f66a8f0359a353f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 09:32:14 +0200 Subject: LOG() API reads the LogLevel from the cCompositeChat's MessageType. --- MCServer/Plugins/APIDump/APIDesc.lua | 4 ++-- src/Bindings/ManualBindings.cpp | 17 +++++++++++++---- src/CompositeChat.cpp | 23 +++++++++++++++++++++++ src/CompositeChat.h | 4 ++++ src/MCLogger.cpp | 24 +++++++++++++++++------- src/MCLogger.h | 33 ++++++++++++++++++++++----------- 6 files changed, 81 insertions(+), 24 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index b1b660bb0..28e7744ed 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2665,8 +2665,8 @@ end ItemTypeToString = {Params = "ItemType", Return = "string", Notes = "Returns the string representation of ItemType "}, LOG = { - {Params = "string", Notes = "Logs a text into the server console using 'normal' severity (gray text) "}, - {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console using 'normal' severity (gray text) "}, + {Params = "string", Notes = "Logs a text into the server console using 'normal' severity (gray text)"}, + {Params = "{{cCompositeChat|CompositeChat}}", Notes = "Logs the {{cCompositeChat}}'s human-readable text into the server console. The severity is converted from the CompositeChat's MessageType."}, }, LOGERROR = { diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 95cd5e904..9d1a367df 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -143,7 +143,16 @@ static AString GetLogMessage(lua_State * tolua_S) static int tolua_LOG(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 0); + // If the param is a cCompositeChat, read the log level from it: + cMCLogger::eLogLevel LogLevel = cMCLogger::llRegular; + tolua_Error err; + if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err)) + { + LogLevel = cCompositeChat::MessageTypeToLogLevel(((cCompositeChat *)tolua_tousertype(tolua_S, 1, NULL))->GetMessageType()); + } + + // Log the message: + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); return 0; } @@ -153,7 +162,7 @@ static int tolua_LOG(lua_State * tolua_S) static int tolua_LOGINFO(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 1); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llInfo); return 0; } @@ -163,7 +172,7 @@ static int tolua_LOGINFO(lua_State * tolua_S) static int tolua_LOGWARN(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 2); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llWarning); return 0; } @@ -173,7 +182,7 @@ static int tolua_LOGWARN(lua_State * tolua_S) static int tolua_LOGERROR(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), 3); + cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llError); return 0; } diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index 918e4f90e..c70ef1070 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -343,6 +343,29 @@ AString cCompositeChat::ExtractText(void) const +cMCLogger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType) +{ + switch (a_MessageType) + { + case mtCustom: return cMCLogger::llRegular; + case mtFailure: return cMCLogger::llWarning; + case mtInformation: return cMCLogger::llInfo; + case mtSuccess: return cMCLogger::llRegular; + case mtWarning: return cMCLogger::llWarning; + case mtFatal: return cMCLogger::llError; + case mtDeath: return cMCLogger::llRegular; + case mtPrivateMessage: return cMCLogger::llRegular; + case mtJoin: return cMCLogger::llRegular; + case mtLeave: return cMCLogger::llRegular; + } + ASSERT(!"Unhandled MessageType"); + return cMCLogger::llError; +} + + + + + void cCompositeChat::AddStyle(AString & a_Style, const AString & a_AddStyle) { if (a_AddStyle.empty()) diff --git a/src/CompositeChat.h b/src/CompositeChat.h index 0f56cde9b..5b9c5f612 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -173,6 +173,10 @@ public: const cParts & GetParts(void) const { return m_Parts; } + /** Converts the MessageType to a LogLevel value. + Used by the logging bindings when logging a cCompositeChat object. */ + static cMCLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); + protected: /** All the parts that */ cParts m_Parts; diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index 4f3e5dc0f..509833f37 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -93,25 +93,35 @@ void cMCLogger::InitLog(const AString & a_FileName) -void cMCLogger::LogSimple(const char* a_Text, int a_LogType /* = 0 */ ) +void cMCLogger::LogSimple(const char * a_Text, eLogLevel a_LogLevel) { - switch( a_LogType ) + switch (a_LogLevel) { - case 0: + case llRegular: + { LOG("%s", a_Text); break; - case 1: + } + case llInfo: + { LOGINFO("%s", a_Text); break; - case 2: + } + case llWarning: + { LOGWARN("%s", a_Text); break; - case 3: + } + case llError: + { LOGERROR("%s", a_Text); break; + } default: - LOG("(#%d#: %s", a_LogType, a_Text); + { + LOG("(#%d#: %s", (int)a_LogLevel, a_Text); break; + } } } diff --git a/src/MCLogger.h b/src/MCLogger.h index 996e60329..c0150c124 100644 --- a/src/MCLogger.h +++ b/src/MCLogger.h @@ -10,25 +10,36 @@ class cLog; -class cMCLogger // tolua_export -{ // tolua_export -public: // tolua_export - /// Creates a logger with the default filename, "logs/LOG_.log" +// tolua_begin +class cMCLogger +{ +public: + enum eLogLevel + { + llRegular, + llInfo, + llWarning, + llError, + }; + // tolua_end + + /** Creates a logger with the default filename, "logs/LOG_.log" */ cMCLogger(void); - /// Creates a logger with the specified filename inside "logs" folder + /** Creates a logger with the specified filename inside "logs" folder */ cMCLogger(const AString & a_FileName); // tolua_export ~cMCLogger(); // tolua_export - void Log(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Info(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Warn(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Error(const char* a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Log (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Info (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Warn (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); + void Error(const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void LogSimple(const char* a_Text, int a_LogType = 0 ); // tolua_export + /** Logs the simple text message at the specified log level. */ + void LogSimple(const char * a_Text, eLogLevel a_LogLevel = llRegular); // tolua_export - static cMCLogger* GetInstance(); + static cMCLogger * GetInstance(); private: enum eColorScheme { -- cgit v1.2.3 From e610262fb10c6fafd3c3ff5f2c4f83ada9220e6d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 09:44:11 +0200 Subject: Attempt at disabling the useless clang warnings. Ref.: #846, #847 --- SetFlags.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/SetFlags.cmake b/SetFlags.cmake index bbd8254ad..d90ad8b48 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -198,6 +198,7 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") + add_flags_cxx("-Wno-weak-vtables -Wno-switch-enum") endif() endif() -- cgit v1.2.3 From 7cc322332baa22475674f93b9ec76e1546d7e941 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 13:38:40 +0200 Subject: Removed an unneeded code branch. --- src/MCLogger.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp index 509833f37..80fa7b173 100644 --- a/src/MCLogger.cpp +++ b/src/MCLogger.cpp @@ -117,11 +117,6 @@ void cMCLogger::LogSimple(const char * a_Text, eLogLevel a_LogLevel) LOGERROR("%s", a_Text); break; } - default: - { - LOG("(#%d#: %s", (int)a_LogLevel, a_Text); - break; - } } } -- cgit v1.2.3 From aa7552309abb6943f8ba0ac3d8013689655e74b2 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 14:23:11 +0200 Subject: Simplified the anvil placement code. --- src/Blocks/BlockAnvil.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index 57d10ebce..93a796ef7 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -18,11 +18,13 @@ public: { } + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta >> 2)); } + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -31,27 +33,23 @@ public: ) override { a_BlockType = m_BlockType; - - int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 0.5) & 0x3; - NIBBLETYPE RawMeta = a_BlockMeta >> 2; - - Direction++; - Direction %= 4; + NIBBLETYPE HighBits = a_BlockMeta & 0x0c; // Only highest two bits are preserved + int Direction = (int)floor(a_Player->GetYaw() * 4.0 / 360.0 + 1.5) & 0x3; switch (Direction) { - case 0: a_BlockMeta = 0x2 | (RawMeta << 2); break; - case 1: a_BlockMeta = 0x3 | (RawMeta << 2); break; - case 2: a_BlockMeta = 0x0 | (RawMeta << 2); break; - case 3: a_BlockMeta = 0x1 | (RawMeta << 2); break; + case 0: a_BlockMeta = 0x2 | HighBits; break; + case 1: a_BlockMeta = 0x3 | HighBits; break; + case 2: a_BlockMeta = 0x0 | HighBits; break; + case 3: a_BlockMeta = 0x1 | HighBits; break; default: { return false; } } - return true; } + virtual bool IsUseable() override { return true; -- cgit v1.2.3 From 45150e97541aa8dfda7f0fdba75acf2ec616654d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 14:58:05 +0200 Subject: Fixed clang warnings in cFile. We only support 32-bit filesizes (files < 2 GiB). --- src/OSSupport/File.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 17070030f..75ea198a8 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -152,7 +152,7 @@ int cFile::Read (void * iBuffer, int iNumBytes) return -1; } - return fread(iBuffer, 1, iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count + return (int)fread(iBuffer, 1, (size_t)iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count } @@ -168,7 +168,7 @@ int cFile::Write(const void * iBuffer, int iNumBytes) return -1; } - int res = fwrite(iBuffer, 1, iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count + int res = (int)fwrite(iBuffer, 1, (size_t)iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count return res; } @@ -189,7 +189,7 @@ int cFile::Seek (int iPosition) { return -1; } - return ftell(m_File); + return (int)ftell(m_File); } @@ -206,7 +206,7 @@ int cFile::Tell (void) const return -1; } - return ftell(m_File); + return (int)ftell(m_File); } @@ -222,7 +222,7 @@ int cFile::GetSize(void) const return -1; } - int CurPos = ftell(m_File); + int CurPos = Tell(); if (CurPos < 0) { return -1; @@ -231,8 +231,8 @@ int cFile::GetSize(void) const { return -1; } - int res = ftell(m_File); - if (fseek(m_File, CurPos, SEEK_SET) != 0) + int res = Tell(); + if (fseek(m_File, (size_t)CurPos, SEEK_SET) != 0) { return -1; } @@ -255,7 +255,7 @@ int cFile::ReadRestOfFile(AString & a_Contents) int DataSize = GetSize() - Tell(); // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly - a_Contents.assign(DataSize, '\0'); + a_Contents.assign((size_t)DataSize, '\0'); return Read((void *)a_Contents.data(), DataSize); } @@ -350,7 +350,7 @@ int cFile::GetSize(const AString & a_FileName) struct stat st; if (stat(a_FileName.c_str(), &st) == 0) { - return st.st_size; + return (int)st.st_size; } return -1; } @@ -456,7 +456,7 @@ int cFile::Printf(const char * a_Fmt, ...) va_start(args, a_Fmt); AppendVPrintf(buf, a_Fmt, args); va_end(args); - return Write(buf.c_str(), buf.length()); + return Write(buf.c_str(), (int)buf.length()); } -- cgit v1.2.3 From 42e30b6513c8f905d419dd6621ad11959eea9dc9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 14:55:46 +0200 Subject: Fixed clang warnings in BlockHandlers. --- src/Blocks/BlockMobHead.h | 2 +- src/Blocks/BlockSlab.h | 1 + src/Blocks/BlockStairs.h | 4 ++-- src/Blocks/BlockVine.h | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 080843a73..c4f41ba34 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -70,7 +70,7 @@ public: }; cCallback Callback(a_Player, a_BlockMeta, static_cast(a_BlockFace)); - a_BlockMeta = a_BlockFace; + a_BlockMeta = (NIBBLETYPE)a_BlockFace; cWorld * World = (cWorld *) &a_WorldInterface; World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, Callback); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, a_BlockMeta); diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index 77e8b8e55..4f94d45f6 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -103,6 +103,7 @@ public: a_BlockMeta = Meta & 0x7; break; } } + case BLOCK_FACE_NONE: return false; } // switch (a_BlockFace) return true; } diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index 1072b7e71..09ff254a6 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -30,9 +30,7 @@ public: UNUSED(a_BlockY); UNUSED(a_BlockZ); UNUSED(a_CursorX); - UNUSED(a_CursorY); UNUSED(a_CursorZ); - UNUSED(a_BlockMeta); a_BlockType = m_BlockType; a_BlockMeta = RotationToMetaData(a_Player->GetYaw()); switch (a_BlockFace) @@ -51,10 +49,12 @@ public: } break; } + case BLOCK_FACE_NONE: return false; } return true; } + virtual const char * GetStepSound(void) override { if ( diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index e796a45ae..7bb9dc484 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -197,14 +197,14 @@ public: virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) override { // Bits 2 and 4 stay, bits 1 and 3 swap - return ((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2)); + return (NIBBLETYPE)((a_Meta & 0x0a) | ((a_Meta & 0x01) << 2) | ((a_Meta & 0x04) >> 2)); } virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override { // Bits 1 and 3 stay, bits 2 and 4 swap - return ((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2)); + return (NIBBLETYPE)((a_Meta & 0x05) | ((a_Meta & 0x02) << 2) | ((a_Meta & 0x08) >> 2)); } } ; -- cgit v1.2.3 From b9a090d835c9434570166b7cddcb8b6d7e2628e4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 15:00:30 +0200 Subject: Fixed clang warnings in cGZipFile. --- src/OSSupport/GZipFile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OSSupport/GZipFile.cpp b/src/OSSupport/GZipFile.cpp index b13e519e0..7a8433f4f 100644 --- a/src/OSSupport/GZipFile.cpp +++ b/src/OSSupport/GZipFile.cpp @@ -78,7 +78,7 @@ int cGZipFile::ReadRestOfFile(AString & a_Contents) while ((NumBytesRead = gzread(m_File, Buffer, sizeof(Buffer))) > 0) { TotalBytes += NumBytesRead; - a_Contents.append(Buffer, NumBytesRead); + a_Contents.append(Buffer, (size_t)NumBytesRead); } // NumBytesRead is < 0 on error return (NumBytesRead >= 0) ? TotalBytes : NumBytesRead; @@ -102,7 +102,7 @@ bool cGZipFile::Write(const char * a_Contents, int a_Size) return false; } - return (gzwrite(m_File, a_Contents, a_Size) != 0); + return (gzwrite(m_File, a_Contents, (unsigned int)a_Size) != 0); } -- cgit v1.2.3 From 2672b14c036f74548f970349aa08b6cb02600688 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 16:00:20 +0200 Subject: More cFile warning fixes. --- src/OSSupport/File.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 75ea198a8..7f0f0ad2f 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -232,7 +232,7 @@ int cFile::GetSize(void) const return -1; } int res = Tell(); - if (fseek(m_File, (size_t)CurPos, SEEK_SET) != 0) + if (fseek(m_File, (long)CurPos, SEEK_SET) != 0) { return -1; } -- cgit v1.2.3 From 0d916a3e2f8947af6bc7da6e19d23522ba014f6d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 16:10:08 +0200 Subject: Removed the exit-time-destructors flag from clang. We don't care about exit-time destructors, at least for now. --- SetFlags.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index d90ad8b48..c5a3a0697 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -198,7 +198,7 @@ macro(set_exe_flags) add_flags_cxx("-Wno-error=covered-switch-default -Wno-error=shadow") add_flags_cxx("-Wno-error=exit-time-destructors -Wno-error=missing-variable-declarations") add_flags_cxx("-Wno-error=global-constructors -Wno-implicit-fallthrough") - add_flags_cxx("-Wno-weak-vtables -Wno-switch-enum") + add_flags_cxx("-Wno-weak-vtables -Wno-switch-enum -Wno-exit-time-destructors") endif() endif() -- cgit v1.2.3 From 1229795ff0fd82412e780fffc9f37a2d6eed5522 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 20:50:10 +0200 Subject: cBlockArea: Added the msMask merge strategy. --- MCServer/Plugins/APIDump/APIDesc.lua | 23 ++++++++++++++++++++--- src/BlockArea.cpp | 30 ++++++++++++++++++++++++++++++ src/BlockArea.h | 9 +++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 28e7744ed..9bcd6edde 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -200,6 +200,8 @@ g_APIDesc = msFillAir = { Notes = "Dst is overwritten by Src only where Src has air blocks" }, msImprint = { Notes = "Src overwrites Dst anywhere where Dst has non-air blocks" }, msLake = { Notes = "Special mode for merging lake images" }, + msSpongePrint = { Notes = "Similar to msImprint, sponge block doesn't overwrite anything, all other blocks overwrite everything"}, + msMask = { Notes = "The blocks that are exactly the same are kept in Dst, all differing blocks are replaced by air"}, }, ConstantGroups = { @@ -293,7 +295,6 @@ g_APIDesc = -

    msSpongePrint - used for most prefab-generators to merge the prefabs. Similar to msImprint, but uses the sponge block as the NOP block instead, so that the prefabs may carve out air @@ -306,10 +307,26 @@ g_APIDesc = A sponge A Sponge is the NOP block - * B B Everything else overwrites anything + * B B Everything else overwrites anything - ]], + +

    + msMask - the blocks that are the same in the other area are kept, all the + differing blocks are replaced with air. Meta is used in the comparison, too, two blocks of the + same type but different meta are considered different and thus replaced with air. +

    + + + + + + + + + +
    area block Notes
    this Src result
    A A A Same blocks are kept
    A non-A air Differing blocks are replaced with air
    +]], }, -- Merge strategies }, -- AdditionalInfo }, -- cBlockArea diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 2b950378a..543dbe04d 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -173,6 +173,21 @@ static inline void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a +/** Combinator used for cBlockArea::msMask merging */ +static inline void MergeCombinatorMask(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta) +{ + // If the blocks are the same, keep the dest; otherwise replace with air + if ((a_SrcType != a_DstType) || (a_SrcMeta != a_DstMeta)) + { + a_DstType = E_BLOCK_AIR; + a_DstMeta = 0; + } +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cBlockArea: @@ -710,6 +725,21 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R break; } // case msSpongePrint + case msMask: + { + InternalMergeBlocks( + m_BlockTypes, a_Src.GetBlockTypes(), + DstMetas, SrcMetas, + SizeX, SizeY, SizeZ, + SrcOffX, SrcOffY, SrcOffZ, + DstOffX, DstOffY, DstOffZ, + a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), + m_Size.x, m_Size.y, m_Size.z, + MergeCombinatorMask + ); + break; + } // case msMask + default: { LOGWARNING("Unknown block area merge strategy: %d", a_Strategy); diff --git a/src/BlockArea.h b/src/BlockArea.h index d37f0d182..34a0ef926 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -52,6 +52,7 @@ public: msImprint, msLake, msSpongePrint, + msMask, } ; cBlockArea(void); @@ -152,6 +153,14 @@ public: +----------+--------+--------+ | A | sponge | A | Sponge is the NOP block | * | B | B | Everything else overwrites anything + + msMask: + Combines two areas, the blocks that are the same are kept, differing ones are reset to air + | area block | | + | this | Src | result | + +------+-------+--------+ + | A | A | A | Same blocks are kept + | A | non-A | air | Everything else is replaced with air */ void Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy); -- cgit v1.2.3 From 21e0607e49745f0a431fa045967cc45679ab22de Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 1 Apr 2014 21:12:48 +0200 Subject: APIDump: Gave msDifference it's own table. --- MCServer/Plugins/APIDump/APIDesc.lua | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 657ac6aa6..b01be6118 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -230,25 +230,25 @@ g_APIDesc =

    - + - + - + - + - + - + - +
    area blockresultarea blockresult
    this Src msOverwrite msFillAir msImprint msDifference this Src msOverwrite msFillAir msImprint
    air air air air air air air air air air air
    A air air A A air A air air A A
    air B B B B B air B B B B
    A B B A B B A B B A B
    A A A A B air A A A A A
    @@ -258,13 +258,25 @@ g_APIDesc =
  • msOverwrite completely overwrites all blocks with the Src's blocks
  • msFillAir overwrites only those blocks that were air
  • msImprint overwrites with only those blocks that are non-air
  • -
  • msDifference changes all the blocks which are the same to air. Otherwise the source block gets placed.
  • Special strategies

    For each strategy, evaluate the table rows from top downwards, the first match wins.

    - + +

    + msDifference - changes all the blocks which are the same to air. Otherwise the source block gets placed. +

    + + + + + + + +
    area block Notes
    * B B The blocks are different so we use block B
    B B Air The blocks are the same so we get air.
    + +

    msLake - used for merging areas with lava and water lakes, in the appropriate generator.

    -- cgit v1.2.3 From bcf5021feb3bbb8069b80e3b892f0c80db35a4c6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 22:47:39 +0200 Subject: Exported the Base64 encoding and decoding functions to Lua API. --- src/Bindings/ManualBindings.cpp | 46 +++++++++++++++++++++++++++++++++++++++++ src/StringUtils.h | 4 ++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 9d1a367df..51b9f3e27 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -190,6 +190,50 @@ static int tolua_LOGERROR(lua_State * tolua_S) +static int tolua_Base64Encode(lua_State * tolua_S) +{ + cLuaState L(tolua_S); + if ( + !L.CheckParamString(1) || + !L.CheckParamEnd(2) + ) + { + return 0; + } + + AString Src; + L.GetStackValue(1, Src); + AString res = Base64Encode(Src); + L.Push(res); + return 1; +} + + + + + +static int tolua_Base64Decode(lua_State * tolua_S) +{ + cLuaState L(tolua_S); + if ( + !L.CheckParamString(1) || + !L.CheckParamEnd(2) + ) + { + return 0; + } + + AString Src; + L.GetStackValue(1, Src); + AString res = Base64Decode(Src); + L.Push(res); + return 1; +} + + + + + cPluginLua * GetLuaPlugin(lua_State * L) { // Get the plugin identification out of LuaState: @@ -2869,6 +2913,8 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "LOGWARN", tolua_LOGWARN); tolua_function(tolua_S, "LOGWARNING", tolua_LOGWARN); tolua_function(tolua_S, "LOGERROR", tolua_LOGERROR); + tolua_function(tolua_S, "Base64Encode", tolua_Base64Encode); + tolua_function(tolua_S, "Base64Decode", tolua_Base64Decode); tolua_beginmodule(tolua_S, "cFile"); tolua_function(tolua_S, "GetFolderContents", tolua_cFile_GetFolderContents); diff --git a/src/StringUtils.h b/src/StringUtils.h index 4feff7553..da395e5b5 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -79,10 +79,10 @@ extern AString URLDecode(const AString & a_String); // Cannot export to Lua aut extern AString ReplaceAllCharOccurrences(const AString & a_String, char a_From, char a_To); // Needn't export to Lua, since Lua doesn't have chars anyway /// Decodes a Base64-encoded string into the raw data -extern AString Base64Decode(const AString & a_Base64String); +extern AString Base64Decode(const AString & a_Base64String); // Exported manually due to embedded NULs and extra parameter /// Encodes a string into Base64 -extern AString Base64Encode(const AString & a_Input); +extern AString Base64Encode(const AString & a_Input); // Exported manually due to embedded NULs and extra parameter /// Reads two bytes from the specified memory location and interprets them as BigEndian short extern short GetBEShort(const char * a_Mem); -- cgit v1.2.3 From 3301c5be1ff9d26d3189c031eb28e5f46c9edccd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 11:56:10 +0200 Subject: Fixed StringCompression's GZIP handling for larger strings. --- src/StringCompression.cpp | 8 +++++--- src/StringCompression.h | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/StringCompression.cpp b/src/StringCompression.cpp index 5b9a3bb0a..2a85649a1 100644 --- a/src/StringCompression.cpp +++ b/src/StringCompression.cpp @@ -53,7 +53,7 @@ int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed -int CompressStringGZIP(const char * a_Data, int a_Length, AString & a_Compressed) +int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compressed) { // Compress a_Data into a_Compressed using GZIP; return Z_XXX error constants same as zlib's compress2() @@ -83,6 +83,7 @@ int CompressStringGZIP(const char * a_Data, int a_Length, AString & a_Compressed { // Some data has been compressed. Consume the buffer and continue compressing a_Compressed.append(Buffer, sizeof(Buffer) - strm.avail_out); + strm.next_out = (Bytef *)Buffer; strm.avail_out = sizeof(Buffer); if (strm.avail_in == 0) { @@ -116,7 +117,7 @@ int CompressStringGZIP(const char * a_Data, int a_Length, AString & a_Compressed -extern int UncompressStringGZIP(const char * a_Data, int a_Length, AString & a_Uncompressed) +extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Uncompressed) { // Uncompresses a_Data into a_Uncompressed using GZIP; returns Z_OK for success or Z_XXX error constants same as zlib @@ -139,13 +140,14 @@ extern int UncompressStringGZIP(const char * a_Data, int a_Length, AString & a_U for (;;) { - res = inflate(&strm, Z_FINISH); + res = inflate(&strm, Z_NO_FLUSH); switch (res) { case Z_OK: { // Some data has been uncompressed. Consume the buffer and continue uncompressing a_Uncompressed.append(Buffer, sizeof(Buffer) - strm.avail_out); + strm.next_out = (Bytef *)Buffer; strm.avail_out = sizeof(Buffer); if (strm.avail_in == 0) { diff --git a/src/StringCompression.h b/src/StringCompression.h index 3f4e12d2d..c3a9eca91 100644 --- a/src/StringCompression.h +++ b/src/StringCompression.h @@ -16,10 +16,10 @@ extern int CompressString(const char * a_Data, int a_Length, AString & a_Compres extern int UncompressString(const char * a_Data, int a_Length, AString & a_Uncompressed, int a_UncompressedSize); /// Compresses a_Data into a_Compressed using GZIP; returns Z_OK for success or Z_XXX error constants same as zlib -extern int CompressStringGZIP(const char * a_Data, int a_Length, AString & a_Compressed); +extern int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compressed); /// Uncompresses a_Data into a_Uncompressed using GZIP; returns Z_OK for success or Z_XXX error constants same as zlib -extern int UncompressStringGZIP(const char * a_Data, int a_Length, AString & a_Uncompressed); +extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Uncompressed); -- cgit v1.2.3 From bcd7f9669ba98f4ecb71ba728d72836ff14b3c0f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 11:56:27 +0200 Subject: Added schematic string serializer self-test. --- src/WorldStorage/SchematicFileSerializer.cpp | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index d8531d965..9d594a084 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -14,6 +14,39 @@ +#ifdef SELF_TEST + +static class cSchematicStringSelfTest +{ +public: + cSchematicStringSelfTest(void) + { + cBlockArea ba; + ba.Create(21, 256, 21); + ba.RelLine(0, 0, 0, 9, 8, 7, cBlockArea::baTypes | cBlockArea::baMetas, E_BLOCK_WOODEN_STAIRS, 1); + AString Schematic; + if (!cSchematicFileSerializer::SaveToSchematicString(ba, Schematic)) + { + assert_test(!"Schematic failed to save!"); + } + cBlockArea ba2; + if (!cSchematicFileSerializer::LoadFromSchematicString(ba2, Schematic)) + { + assert_test(!"Schematic failed to load!"); + } + } +} g_SelfTest; + +#endif + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cSchematicFileSerializer: + bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName) { // Un-GZip the contents: -- cgit v1.2.3 From 67d7ad86896e90b799a0479a86a6e764c7fe36da Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 11:58:19 +0200 Subject: Debuggers: Added a Base64 API roundtrip test. --- MCServer/Plugins/Debuggers/Debuggers.lua | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 2619bd6c4..064d5d772 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -69,12 +69,13 @@ function Initialize(Plugin) LOG("Initialized " .. Plugin:GetName() .. " v." .. Plugin:GetVersion()) - -- TestBlockAreas(); - -- TestSQLiteBindings(); - -- TestExpatBindings(); - -- TestPluginCalls(); + -- TestBlockAreas() + -- TestSQLiteBindings() + -- TestExpatBindings() + -- TestPluginCalls() TestBlockAreasString() + TestStringBase64() --[[ -- Test cCompositeChat usage in console-logging: @@ -252,6 +253,24 @@ end +function TestStringBase64() + -- Create a binary string: + local s = "" + for i = 0, 255 do + s = s .. string.char(i) + end + + -- Roundtrip through Base64: + local Base64 = Base64Encode(s) + local UnBase64 = Base64Decode(Base64) + + assert(UnBase64 == s) +end + + + + + function TestSQLiteBindings() LOG("Testing SQLite bindings..."); -- cgit v1.2.3 From 26c3bc4076a455fd61b56c34215771bddb548e1d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 16:39:42 +0200 Subject: Fixed more virtual destructors for interfaces. --- src/BlockTracer.h | 3 +++ src/HTTPServer/EnvelopeParser.h | 3 +++ src/HTTPServer/HTTPFormParser.h | 3 +++ src/HTTPServer/MultipartParser.h | 3 +++ 4 files changed, 12 insertions(+) diff --git a/src/BlockTracer.h b/src/BlockTracer.h index 40d80da1a..a18c8df4d 100644 --- a/src/BlockTracer.h +++ b/src/BlockTracer.h @@ -28,6 +28,9 @@ public: class cCallbacks abstract { public: + // Force a virtual destructor in descendants: + virtual ~cCallbacks() {} + /** Called on each block encountered along the path, including the first block (path start) When this callback returns true, the tracing is aborted. */ diff --git a/src/HTTPServer/EnvelopeParser.h b/src/HTTPServer/EnvelopeParser.h index 6430fbebf..866bed11d 100644 --- a/src/HTTPServer/EnvelopeParser.h +++ b/src/HTTPServer/EnvelopeParser.h @@ -19,6 +19,9 @@ public: class cCallbacks { public: + // Force a virtual destructor in descendants: + virtual ~cCallbacks() {} + /// Called when a full header line is parsed virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) = 0; } ; diff --git a/src/HTTPServer/HTTPFormParser.h b/src/HTTPServer/HTTPFormParser.h index a554ca5a4..f2a509cb8 100644 --- a/src/HTTPServer/HTTPFormParser.h +++ b/src/HTTPServer/HTTPFormParser.h @@ -36,6 +36,9 @@ public: class cCallbacks { public: + // Force a virtual destructor in descendants: + virtual ~cCallbacks() {} + /// Called when a new file part is encountered in the form data virtual void OnFileStart(cHTTPFormParser & a_Parser, const AString & a_FileName) = 0; diff --git a/src/HTTPServer/MultipartParser.h b/src/HTTPServer/MultipartParser.h index d853929ed..77695fe4a 100644 --- a/src/HTTPServer/MultipartParser.h +++ b/src/HTTPServer/MultipartParser.h @@ -22,6 +22,9 @@ public: class cCallbacks { public: + // Force a virtual destructor in descendants: + virtual ~cCallbacks() {} + /// Called when a new part starts virtual void OnPartStart(void) = 0; -- cgit v1.2.3 From 5c6d4745990a0aa90d0c6c01da65d6e8dfa32bfc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 16:40:13 +0200 Subject: Fixed boat placement code. --- src/Items/ItemBoat.h | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h index a28ec8e22..42f4ffc8f 100644 --- a/src/Items/ItemBoat.h +++ b/src/Items/ItemBoat.h @@ -39,12 +39,20 @@ public: public cBlockTracer::cCallbacks { public: - Vector3d Pos; - virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override + Vector3d m_Pos; + bool m_HasFound; + + cCallbacks(void) : + m_HasFound(false) { - if (a_BlockType != E_BLOCK_AIR) + } + + virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, char a_CBEntryFace) override + { + if (a_CBBlockType != E_BLOCK_AIR) { - Pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); + m_Pos.Set(a_CBBlockX, a_CBBlockY, a_CBBlockZ); + m_HasFound = true; return true; } return false; @@ -57,15 +65,15 @@ public: Tracer.Trace(Start.x, Start.y, Start.z, End.x, End.y, End.z); - double x = Callbacks.Pos.x; - double y = Callbacks.Pos.y; - double z = Callbacks.Pos.z; - - if ((x == 0) && (y == 0) && (z == 0)) + if (!Callbacks.m_HasFound) { return false; } + double x = Callbacks.m_Pos.x; + double y = Callbacks.m_Pos.y; + double z = Callbacks.m_Pos.z; + cBoat * Boat = new cBoat(x + 0.5, y + 1, z + 0.5); Boat->Initialize(a_World); -- cgit v1.2.3 From 43af11ee3808fa9836fc9467cacd73b78118c3c2 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 2 Apr 2014 20:03:42 +0100 Subject: Removed extra brackets --- src/Blocks/BlockFluid.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h index 1200997ff..1f0c3833c 100644 --- a/src/Blocks/BlockFluid.h +++ b/src/Blocks/BlockFluid.h @@ -1,4 +1,3 @@ - #pragma once #include "BlockHandler.h" @@ -94,10 +93,8 @@ public: BLOCKTYPE BlockType; if ( ((a_RelY + y < 0) || (a_RelY + y > cChunkDef::Height)) || - ( - !a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || - !cFireSimulator::IsFuel(BlockType) - ) + !a_Chunk.UnboundedRelGetBlockType(a_RelX + x, a_RelY + y, a_RelZ + z, BlockType) || + !cFireSimulator::IsFuel(BlockType) ) { return false; -- cgit v1.2.3 From da267649a183e84280da7eadcb391952fb6a0d1d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 2 Apr 2014 20:04:41 +0100 Subject: With eXtra line! --- src/Blocks/BlockFluid.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h index 1f0c3833c..d486d642d 100644 --- a/src/Blocks/BlockFluid.h +++ b/src/Blocks/BlockFluid.h @@ -1,3 +1,4 @@ + #pragma once #include "BlockHandler.h" -- cgit v1.2.3 From 12b82de502888103710c1aeae0217a3dcb640637 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 3 Apr 2014 09:26:44 +0200 Subject: Removed the bindings to set old g_BlockXXX arrays. Those were supposed to be read-only; there's no point in writing to them anyway. Also fixed MSVC type warnings in the code. --- src/Bindings/DeprecatedBindings.cpp | 362 +++++++----------------------------- 1 file changed, 65 insertions(+), 297 deletions(-) diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index fbc008be6..d51ba2da3 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -21,47 +21,23 @@ #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockLightValue static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) + { tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + } } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetLightValue(tolua_index)); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - - - - - -/* set function: g_BlockLightValue */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockLightValue -static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + tolua_error(tolua_S, "array indexing out of range.", NULL); } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_LightValue = ((unsigned char) tolua_tonumber(tolua_S,3,0)); - return 0; + tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetLightValue((BLOCKTYPE)BlockType)); + return 1; } #endif //#ifndef TOLUA_DISABLE @@ -73,7 +49,7 @@ static int tolua_set_AllToLua_g_BlockLightValue(lua_State* tolua_S) #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockSpreadLightFalloff static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -81,39 +57,13 @@ static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetSpreadLightFalloff(tolua_index)); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - - - - - -/* set function: g_BlockSpreadLightFalloff */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockSpreadLightFalloff -static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + tolua_error(tolua_S, "array indexing out of range.", NULL); } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_SpreadLightFalloff = ((unsigned char) tolua_tonumber(tolua_S,3,0)); - return 0; + tolua_pushnumber(tolua_S, (lua_Number)cBlockInfo::GetSpreadLightFalloff((BLOCKTYPE)BlockType)); + return 1; } #endif //#ifndef TOLUA_DISABLE @@ -125,7 +75,7 @@ static int tolua_set_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockTransparent static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -133,39 +83,13 @@ static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S, cBlockInfo::IsTransparent(tolua_index)); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - - - - - -/* set function: g_BlockTransparent */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockTransparent -static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + tolua_error(tolua_S, "array indexing out of range.", NULL); } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_Transparent = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; + tolua_pushboolean(tolua_S, cBlockInfo::IsTransparent((BLOCKTYPE)BlockType)); + return 1; } #endif //#ifndef TOLUA_DISABLE @@ -177,7 +101,7 @@ static int tolua_set_AllToLua_g_BlockTransparent(lua_State* tolua_S) #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockOneHitDig static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -185,39 +109,13 @@ static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsOneHitDig(tolua_index)); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - - - - - -/* set function: g_BlockOneHitDig */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockOneHitDig -static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + tolua_error(tolua_S, "array indexing out of range.", NULL); } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_OneHitDig = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; + tolua_pushboolean(tolua_S, cBlockInfo::IsOneHitDig((BLOCKTYPE)BlockType)); + return 1; } #endif //#ifndef TOLUA_DISABLE @@ -229,7 +127,7 @@ static int tolua_set_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockPistonBreakable static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -237,39 +135,13 @@ static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsPistonBreakable(tolua_index)); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - - - - - -/* set function: g_BlockPistonBreakable */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockPistonBreakable -static int tolua_set_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + tolua_error(tolua_S, "array indexing out of range.", NULL); } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_PistonBreakable = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; + tolua_pushboolean(tolua_S, cBlockInfo::IsPistonBreakable((BLOCKTYPE)BlockType)); + return 1; } #endif //#ifndef TOLUA_DISABLE @@ -281,7 +153,7 @@ static int tolua_set_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockIsSnowable static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -289,39 +161,13 @@ static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsSnowable(tolua_index)); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - - - - - -/* set function: g_BlockIsSnowable */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockIsSnowable -static int tolua_set_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + tolua_error(tolua_S, "array indexing out of range.", NULL); } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_IsSnowable = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; + tolua_pushboolean(tolua_S, cBlockInfo::IsSnowable((BLOCKTYPE)BlockType)); + return 1; } #endif //#ifndef TOLUA_DISABLE @@ -333,7 +179,7 @@ static int tolua_set_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockRequiresSpecialTool static int tolua_get_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -341,39 +187,13 @@ static int tolua_get_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::RequiresSpecialTool(tolua_index)); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - - - - - -/* set function: g_BlockRequiresSpecialTool */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockRequiresSpecialTool -static int tolua_set_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + tolua_error(tolua_S, "array indexing out of range.", NULL); } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_RequiresSpecialTool = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; + tolua_pushboolean(tolua_S, cBlockInfo::RequiresSpecialTool((BLOCKTYPE)BlockType)); + return 1; } #endif //#ifndef TOLUA_DISABLE @@ -385,7 +205,7 @@ static int tolua_set_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockIsSolid static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -393,39 +213,13 @@ static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::IsSolid(tolua_index)); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - - - - - -/* set function: g_BlockIsSolid */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockIsSolid -static int tolua_set_AllToLua_g_BlockIsSolid(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + tolua_error(tolua_S, "array indexing out of range.", NULL); } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_IsSolid = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; + tolua_pushboolean(tolua_S, (bool)cBlockInfo::IsSolid((BLOCKTYPE)BlockType)); + return 1; } #endif //#ifndef TOLUA_DISABLE @@ -437,7 +231,7 @@ static int tolua_set_AllToLua_g_BlockIsSolid(lua_State* tolua_S) #ifndef TOLUA_DISABLE_tolua_get_AllToLua_g_BlockFullyOccupiesVoxel static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) { - int tolua_index; + int BlockType; #ifndef TOLUA_RELEASE { tolua_Error tolua_err; @@ -445,39 +239,13 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); } #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - tolua_pushboolean(tolua_S,(bool)cBlockInfo::FullyOccupiesVoxel(tolua_index)); - return 1; -} -#endif //#ifndef TOLUA_DISABLE - - - - - -/* set function: g_BlockFullyOccupiesVoxel */ -#ifndef TOLUA_DISABLE_tolua_set_AllToLua_g_BlockFullyOccupiesVoxel -static int tolua_set_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) -{ - int tolua_index; - #ifndef TOLUA_RELEASE + BlockType = (int)tolua_tonumber(tolua_S, 2, 0); + if ((BlockType < 0) || (BlockType > E_BLOCK_MAX_TYPE_ID)) { - tolua_Error tolua_err; - if (!tolua_isnumber(tolua_S,2,0,&tolua_err)) - tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err); + tolua_error(tolua_S, "array indexing out of range.", NULL); } - #endif - tolua_index = (int)tolua_tonumber(tolua_S,2,0); - #ifndef TOLUA_RELEASE - if (tolua_index<0 || tolua_index>=256) - tolua_error(tolua_S,"array indexing out of range.",NULL); - #endif - cBlockInfo::Get(tolua_index).m_FullyOccupiesVoxel = (tolua_toboolean(tolua_S,3,0) != 0); - return 0; + tolua_pushboolean(tolua_S, (bool)cBlockInfo::FullyOccupiesVoxel((BLOCKTYPE)BlockType)); + return 1; } #endif //#ifndef TOLUA_DISABLE @@ -489,15 +257,15 @@ void DeprecatedBindings::Bind(lua_State * tolua_S) { tolua_beginmodule(tolua_S, NULL); - tolua_array(tolua_S, "g_BlockLightValue", tolua_get_AllToLua_g_BlockLightValue, tolua_set_AllToLua_g_BlockLightValue); - tolua_array(tolua_S, "g_BlockSpreadLightFalloff", tolua_get_AllToLua_g_BlockSpreadLightFalloff, tolua_set_AllToLua_g_BlockSpreadLightFalloff); - tolua_array(tolua_S, "g_BlockTransparent", tolua_get_AllToLua_g_BlockTransparent, tolua_set_AllToLua_g_BlockTransparent); - tolua_array(tolua_S, "g_BlockOneHitDig", tolua_get_AllToLua_g_BlockOneHitDig, tolua_set_AllToLua_g_BlockOneHitDig); - tolua_array(tolua_S, "g_BlockPistonBreakable", tolua_get_AllToLua_g_BlockPistonBreakable, tolua_set_AllToLua_g_BlockPistonBreakable); - tolua_array(tolua_S, "g_BlockIsSnowable", tolua_get_AllToLua_g_BlockIsSnowable, tolua_set_AllToLua_g_BlockIsSnowable); - tolua_array(tolua_S, "g_BlockRequiresSpecialTool", tolua_get_AllToLua_g_BlockRequiresSpecialTool, tolua_set_AllToLua_g_BlockRequiresSpecialTool); - tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, tolua_set_AllToLua_g_BlockIsSolid); - tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, tolua_set_AllToLua_g_BlockFullyOccupiesVoxel); + tolua_array(tolua_S, "g_BlockLightValue", tolua_get_AllToLua_g_BlockLightValue, NULL); + tolua_array(tolua_S, "g_BlockSpreadLightFalloff", tolua_get_AllToLua_g_BlockSpreadLightFalloff, NULL); + tolua_array(tolua_S, "g_BlockTransparent", tolua_get_AllToLua_g_BlockTransparent, NULL); + tolua_array(tolua_S, "g_BlockOneHitDig", tolua_get_AllToLua_g_BlockOneHitDig, NULL); + tolua_array(tolua_S, "g_BlockPistonBreakable", tolua_get_AllToLua_g_BlockPistonBreakable, NULL); + tolua_array(tolua_S, "g_BlockIsSnowable", tolua_get_AllToLua_g_BlockIsSnowable, NULL); + tolua_array(tolua_S, "g_BlockRequiresSpecialTool", tolua_get_AllToLua_g_BlockRequiresSpecialTool, NULL); + tolua_array(tolua_S, "g_BlockIsSolid", tolua_get_AllToLua_g_BlockIsSolid, NULL); + tolua_array(tolua_S, "g_BlockFullyOccupiesVoxel", tolua_get_AllToLua_g_BlockFullyOccupiesVoxel, NULL); tolua_endmodule(tolua_S); } -- cgit v1.2.3 From 25529ba62f949b98ed30e905ee4921c737d7df87 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Thu, 3 Apr 2014 09:27:17 +0200 Subject: Fixed a few MSVC type warnings. --- src/BlockArea.cpp | 2 +- src/BlockEntities/CommandBlockEntity.cpp | 2 +- src/Globals.h | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 60e4f11e5..40cca8882 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -530,7 +530,7 @@ void cBlockArea::DumpToRawFile(const AString & a_FileName) f.Write(&SizeX, 4); f.Write(&SizeY, 4); f.Write(&SizeZ, 4); - unsigned char DataTypes = GetDataTypes(); + unsigned char DataTypes = (unsigned char)GetDataTypes(); f.Write(&DataTypes, 1); int NumBlocks = GetBlockCount(); if (HasBlockTypes()) diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index d395997a6..96ca0ac37 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -160,7 +160,7 @@ bool cCommandBlockEntity::LoadFromJson(const Json::Value & a_Value) m_Command = a_Value.get("Command", "").asString(); m_LastOutput = a_Value.get("LastOutput", "").asString(); - m_Result = a_Value.get("SuccessCount", 0).asInt(); + m_Result = (NIBBLETYPE)a_Value.get("SuccessCount", 0).asInt(); return true; } diff --git a/src/Globals.h b/src/Globals.h index a1cee5c2f..26a0d87a9 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -29,6 +29,9 @@ // Disabling this warning, because we know what we're doing when we're doing this: #pragma warning(disable: 4355) // 'this' used in initializer list + + // Disabled because it's useless: + #pragma warning(disable: 4512) // 'class': assignment operator could not be generated - reported for each class that has a reference-type member // 2014_01_06 xoft: Disabled this warning because MSVC is stupid and reports it in obviously wrong places // #pragma warning(3 : 4244) // Conversion from 'type1' to 'type2', possible loss of data -- cgit v1.2.3 From 1b78bef4b355c84ee86688eb4f802e5f8a8ccd78 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 2 Apr 2014 17:57:14 +0200 Subject: Removed unneeded asserts. --- src/LightingThread.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/LightingThread.h b/src/LightingThread.h index 3209ad9b2..770ae809f 100644 --- a/src/LightingThread.h +++ b/src/LightingThread.h @@ -164,9 +164,7 @@ protected: int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut ) { - ASSERT(a_SrcIdx >= 0); ASSERT(a_SrcIdx < ARRAYCOUNT(m_SkyLight)); - ASSERT(a_DstIdx >= 0); ASSERT(a_DstIdx < ARRAYCOUNT(m_BlockTypes)); if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + cBlockInfo::GetSpreadLightFalloff(m_BlockTypes[a_DstIdx])) -- cgit v1.2.3 From e304bd08a2363f43bf845b2b370c18a60d1b66d1 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 3 Apr 2014 21:44:03 +0200 Subject: Documented the units and range for entity rotations. --- MCServer/Plugins/APIDump/APIDesc.lua | 6 +++--- src/Entities/Entity.h | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 451b7364a..b0086d740 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -777,14 +777,14 @@ end GetMass = { Params = "", Return = "number", Notes = "Returns the mass of the entity. Currently unused." }, GetMaxHealth = { Params = "", Return = "number", Notes = "Returns the maximum number of hitpoints this entity is allowed to have." }, GetParentClass = { Params = "", Return = "string", Notes = "Returns the name of the direct parent class for this entity" }, - GetPitch = { Params = "", Return = "number", Notes = "Returns the pitch (nose-down rotation) of the entity" }, + GetPitch = { Params = "", Return = "number", Notes = "Returns the pitch (nose-down rotation) of the entity. Measured in degrees, values range from -90 to +90." }, GetPosition = { Params = "", Return = "{{Vector3d}}", Notes = "Returns the entity's pivot position as a 3D vector" }, GetPosX = { Params = "", Return = "number", Notes = "Returns the X-coord of the entity's pivot" }, GetPosY = { Params = "", Return = "number", Notes = "Returns the Y-coord of the entity's pivot" }, GetPosZ = { Params = "", Return = "number", Notes = "Returns the Z-coord of the entity's pivot" }, GetRawDamageAgainst = { Params = "ReceiverEntity", Return = "number", Notes = "Returns the raw damage that this entity's equipment would cause when attacking the ReceiverEntity. This includes this entity's weapon {{cEnchantments|enchantments}}, but excludes the receiver's armor or potion effects. See {{TakeDamageInfo}} for more information on attack damage." }, GetRoll = { Params = "", Return = "number", Notes = "Returns the roll (sideways rotation) of the entity. Currently unused." }, - GetRot = { Params = "", Return = "{{Vector3f}}", Notes = "Returns the entire rotation vector (Yaw, Pitch, Roll)" }, + GetRot = { Params = "", Return = "{{Vector3f}}", Notes = "(OBSOLETE) Returns the entire rotation vector (Yaw, Pitch, Roll)" }, GetSpeed = { Params = "", Return = "{{Vector3d}}", Notes = "Returns the complete speed vector of the entity" }, GetSpeedX = { Params = "", Return = "number", Notes = "Returns the X-part of the speed vector" }, GetSpeedY = { Params = "", Return = "number", Notes = "Returns the Y-part of the speed vector" }, @@ -792,7 +792,7 @@ end GetUniqueID = { Params = "", Return = "number", Notes = "Returns the ID that uniquely identifies the entity within the running server. Note that this ID is not persisted to the data files." }, GetWidth = { Params = "", Return = "number", Notes = "Returns the width (X and Z size) of the entity." }, GetWorld = { Params = "", Return = "{{cWorld}}", Notes = "Returns the world where the entity resides" }, - GetYaw = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity." }, + GetYaw = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity. Measured in degrees, values range from -180 to +180." }, Heal = { Params = "Hitpoints", Return = "", Notes = "Heals the specified number of hitpoints. Hitpoints is expected to be a positive number." }, IsA = { Params = "ClassName", Return = "bool", Notes = "Returns true if the entity class is a descendant of the specified class name, or the specified class itself" }, IsBoat = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cBoat|boat}}." }, diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index e41f74b09..6e3f8292b 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -159,7 +159,7 @@ public: cWorld * GetWorld(void) const { return m_World; } - double GetHeadYaw (void) const { return m_HeadYaw; } + double GetHeadYaw (void) const { return m_HeadYaw; } // In degrees double GetHeight (void) const { return m_Height; } double GetMass (void) const { return m_Mass; } const Vector3d & GetPosition (void) const { return m_Pos; } @@ -167,9 +167,9 @@ public: double GetPosY (void) const { return m_Pos.y; } double GetPosZ (void) const { return m_Pos.z; } const Vector3d & GetRot (void) const { return m_Rot; } // OBSOLETE, use individual GetYaw(), GetPitch, GetRoll() components - double GetYaw (void) const { return m_Rot.x; } - double GetPitch (void) const { return m_Rot.y; } - double GetRoll (void) const { return m_Rot.z; } + double GetYaw (void) const { return m_Rot.x; } // In degrees, [-180, +180) + double GetPitch (void) const { return m_Rot.y; } // In degrees, [-180, +180), but normal client clips to [-90, +90] + double GetRoll (void) const { return m_Rot.z; } // In degrees, unused in current client Vector3d GetLookVector(void) const; const Vector3d & GetSpeed (void) const { return m_Speed; } double GetSpeedX (void) const { return m_Speed.x; } @@ -189,9 +189,9 @@ public: void SetPosition(double a_PosX, double a_PosY, double a_PosZ); void SetPosition(const Vector3d & a_Pos) { SetPosition(a_Pos.x, a_Pos.y, a_Pos.z); } void SetRot (const Vector3f & a_Rot); // OBSOLETE, use individual SetYaw(), SetPitch(), SetRoll() components - void SetYaw (double a_Yaw); - void SetPitch (double a_Pitch); - void SetRoll (double a_Roll); + void SetYaw (double a_Yaw); // In degrees, normalizes to [-180, +180) + void SetPitch (double a_Pitch); // In degrees, normalizes to [-180, +180) + void SetRoll (double a_Roll); // In degrees, normalizes to [-180, +180) void SetSpeed (double a_SpeedX, double a_SpeedY, double a_SpeedZ); void SetSpeed (const Vector3d & a_Speed) { SetSpeed(a_Speed.x, a_Speed.y, a_Speed.z); } void SetSpeedX (double a_SpeedX); -- cgit v1.2.3 From e2fb507be2157194dc435e30c856ffb4e6ad4ed6 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 3 Apr 2014 21:52:50 +0200 Subject: APIDump: Added angular specifics. --- MCServer/Plugins/APIDump/APIDesc.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index b0086d740..b3b7dd11c 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -777,7 +777,7 @@ end GetMass = { Params = "", Return = "number", Notes = "Returns the mass of the entity. Currently unused." }, GetMaxHealth = { Params = "", Return = "number", Notes = "Returns the maximum number of hitpoints this entity is allowed to have." }, GetParentClass = { Params = "", Return = "string", Notes = "Returns the name of the direct parent class for this entity" }, - GetPitch = { Params = "", Return = "number", Notes = "Returns the pitch (nose-down rotation) of the entity. Measured in degrees, values range from -90 to +90." }, + GetPitch = { Params = "", Return = "number", Notes = "Returns the pitch (nose-down rotation) of the entity. Measured in degrees, normal values range from -90 to +90. +90 means looking down, 0 means looking straight ahead, -90 means looking up." }, GetPosition = { Params = "", Return = "{{Vector3d}}", Notes = "Returns the entity's pivot position as a 3D vector" }, GetPosX = { Params = "", Return = "number", Notes = "Returns the X-coord of the entity's pivot" }, GetPosY = { Params = "", Return = "number", Notes = "Returns the Y-coord of the entity's pivot" }, @@ -792,7 +792,7 @@ end GetUniqueID = { Params = "", Return = "number", Notes = "Returns the ID that uniquely identifies the entity within the running server. Note that this ID is not persisted to the data files." }, GetWidth = { Params = "", Return = "number", Notes = "Returns the width (X and Z size) of the entity." }, GetWorld = { Params = "", Return = "{{cWorld}}", Notes = "Returns the world where the entity resides" }, - GetYaw = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity. Measured in degrees, values range from -180 to +180." }, + GetYaw = { Params = "", Return = "number", Notes = "Returns the yaw (direction) of the entity. Measured in degrees, values range from -180 to +180. 0 means ZP, 90 means XM, -180 means ZM, -90 means XP." }, Heal = { Params = "Hitpoints", Return = "", Notes = "Heals the specified number of hitpoints. Hitpoints is expected to be a positive number." }, IsA = { Params = "ClassName", Return = "bool", Notes = "Returns true if the entity class is a descendant of the specified class name, or the specified class itself" }, IsBoat = { Params = "", Return = "bool", Notes = "Returns true if the entity is a {{cBoat|boat}}." }, -- cgit v1.2.3