public BlockValue(bool transparent, string name = "", string packName = "") { this.name = name; if (allBlocks == null) { allBlocks = new BlockValue[initialSize]; nameToBlockId = new Dictionary <string, int>(); largestIdMag = 2; } largestIdMag += 1; if (transparent) { AddNewBlockDelayed(-largestIdMag, name, packName); } else { AddNewBlockDelayed(largestIdMag, name, packName); } }
public static int StringToBlockId(string blockName) { return(BlockValue.BlockNameToId(blockName)); }
public static string BlockIdToString(int blockId) { return(BlockValue.IdToBlockName(blockId)); }
public static void SetupAirAndWildcard() { Air = new BlockValue(0, "Air"); Wildcard = new BlockValue(-1, "Wildcard"); }
public static void LoadIdConfigFromJsonString(string idConfig) { // remove any previous blocks BlockValue[] prevBlocks = allBlocks; Dictionary <string, BlockValue> allPrevBlocks = new Dictionary <string, BlockValue>(); for (int i = 0; i < prevBlocks.Length; i++) { if (prevBlocks[i] != null && prevBlocks[i].name != "") { allPrevBlocks[prevBlocks[i].packName + ":" + prevBlocks[i].name] = prevBlocks[i]; } } allBlocks = null; nameToBlockId = null; allBlocksTexture = null; largestIdMag = 0; Air = new BlockValue(0, "Air"); Wildcard = new BlockValue(-1, "Wildcard"); SavedBlockValues blockValues = JsonConvert.DeserializeObject <SavedBlockValues>(idConfig); for (int i = 0; i < blockValues.blockIds.Length; i++) { int blockId = blockValues.blockIds[i]; string blockName = blockValues.blockNames[i]; string blockPack = blockValues.blockPacks[i]; BlockValue block; // we already took care of this above if (blockName == "Air") { block = Air; } // we already took care of this above else if (blockName == "Wildcard") { block = Wildcard; } // create the block and force the block id // note that if the texture doesn't exist anymore, this will force a cross pink rgb(255,0,255) texture to be used instead which should be fairly noticable else { block = new BlockValue(blockId, blockName, blockPack); } string packBlockKey = block.packName + ":" + block.name; // update the id of the reference and no longer worry about it (since it is updated) if (allPrevBlocks.ContainsKey(packBlockKey)) { BlockValue prevBlock = allPrevBlocks[packBlockKey]; prevBlock._id = blockId; allPrevBlocks.Remove(packBlockKey); } } // for all of the old things we haven't assigned to new ids yet, create them foreach (KeyValuePair <string, BlockValue> blockNotInSave in allPrevBlocks) { string blockName = blockNotInSave.Key; BlockValue block = blockNotInSave.Value; BlockValue newBlock = new BlockValue(block.id < 0, block.name, block.packName); block._id = newBlock.id; } }
void AddNewBlock(int id, string name, string packName = "") { this.name = name; this.packName = packName; string texturePath = ""; if (packName != "") { texturePath = GetBlockTexturePath(packName, name); } if (allBlocks == null) { allBlocks = new BlockValue[initialSize]; nameToBlockId = new Dictionary <string, int>(); largestIdMag = 2; SetupTexture(); } if (allBlocksTexture == null) { SetupTexture(); } nameToBlockId[name] = id; int uid = System.Math.Abs(id); // increase number of blocks until we have enough while (allBlocks.Length <= uid) { BlockValue[] newAllBlocks = new BlockValue[allBlocks.Length * 2]; for (int i = 0; i < allBlocks.Length; i++) { newAllBlocks[i] = allBlocks[i]; } allBlocks = newAllBlocks; // if we are done doubling the size, create the texture if (allBlocks.Length > uid) { SetupTexture(); } } if (allBlocks[uid] != null) { UnityEngine.Debug.LogWarning("warning: multiple blocks have id" + uid + "(technically " + id + " with transparency flag)"); } allBlocks[uid] = this; _id = id; largestIdMag = System.Math.Max(largestIdMag, uid); Debug.Log(name + " has id " + id); string modelPath = ""; if (packName != "") { modelPath = GetBlockModelPath(packName, name); } if (modelPath != "" && File.Exists(modelPath)) { BlockModel model = BlockModel.FromJSONFilePath(modelPath); Texture2D[] textures = model.GetTextures(); for (int i = 0; i < textures.Length; i++) { Color[] pixels = textures[i].GetPixels(); allBlocksTexture.SetPixels(i * 32, (uid - 1) * 16 * 3, 16 * 2, 16 * 3, pixels); } allBlocksTexture.Apply(); File.WriteAllBytes("res.png", allBlocksTexture.EncodeToPNG()); if (id > 0) { _id = -uid; Debug.LogWarning("warning: detected custom model for block " + name + " with updated id " + id + " but we were told it does not have a custom model, set it to custom model anyway"); } customModels[_id] = model; } else if (texturePath != "") { if (File.Exists(texturePath)) { byte[] imageData = File.ReadAllBytes(texturePath); Texture2D blockTexture = new Texture2D(2, 2); blockTexture.LoadImage(imageData); // (will automatically resize as needed) blockTexture.Apply(); // convert to argb32 Texture2D argbTexture = new Texture2D(blockTexture.width, blockTexture.height, TextureFormat.ARGB32, false, true); argbTexture.SetPixels(blockTexture.GetPixels()); argbTexture.Apply(); Color32[] argbColors = argbTexture.GetPixels32(); // check for transparency bool isTransparent = false; for (int j = 0; j < argbColors.Length; j++) { if (argbColors[j].a < 240) // if it is only 240/255 or higher it isn't noticable enough to actually use the transparency { isTransparent = true; break; } } // sign of id should match transparency, fix if not if (isTransparent) { if (id > 0) { _id = -uid; Debug.LogWarning("warning: detected transparent texture for block " + name + " with updated id " + id + " and texture path " + texturePath + " but we were told it is not transparent, set it to transparent anyway"); } } else { if (id < 0) { _id = uid; Debug.LogWarning("warning: detected not transparent texture for block " + name + " with updated id " + id + " and texture path " + texturePath + " but we were told it is transparent, set it to not transparent anyway"); } } if (argbTexture.width != 16 * 2 || argbTexture.height != 16 * 3) { Debug.Log("rescaling texture of block " + name + " with id " + id + " and texture path " + texturePath); TextureScale.Bilinear(argbTexture, 16 * 2, 16 * 3); } argbTexture.Apply(); Color[] pixels = argbTexture.GetPixels(); for (int k = 0; k < animFrames; k++) { allBlocksTexture.SetPixels(k * 32, (uid - 1) * 16 * 3, 16 * 2, 16 * 3, pixels); } allBlocksTexture.Apply(); File.WriteAllBytes("res.png", allBlocksTexture.EncodeToPNG()); } else { //bool animated = false; // test if animated for (int i = 0; i < 32; i++) { string frameITexture = texturePath.Substring(0, texturePath.Length - ".png".Length) + i + ".png"; if (File.Exists(frameITexture)) { //animated = true; byte[] imageData = File.ReadAllBytes(frameITexture); Texture2D blockTexture = new Texture2D(2, 2); blockTexture.LoadImage(imageData); // (will automatically resize as needed) blockTexture.Apply(); // convert to argb32 Texture2D argbTexture = new Texture2D(blockTexture.width, blockTexture.height, TextureFormat.ARGB32, false, true); argbTexture.SetPixels(blockTexture.GetPixels()); argbTexture.Apply(); Color32[] argbColors = argbTexture.GetPixels32(); // check for transparency bool isTransparent = false; for (int j = 0; j < argbColors.Length; j++) { if (argbColors[j].a < 240) // if it is only 240/255 or higher it isn't noticable enough to actually use the transparency { isTransparent = true; break; } } // sign of id should match transparency, fix if not if (isTransparent) { if (id > 0) { _id = -uid; Debug.LogWarning("warning: detected transparent texture for block " + name + " with updated id " + id + " and texture path " + texturePath + " but we were told it is not transparent, set it to transparent anyway"); } } else { if (id < 0) { _id = uid; Debug.LogWarning("warning: detected not transparent texture for block " + name + " with updated id " + id + " and texture path " + texturePath + " but we were told it is transparent, set it to not transparent anyway"); } } if (argbTexture.width != 16 * 2 || argbTexture.height != 16 * 3) { Debug.Log("rescaling texture of block " + name + " with id " + id + " and texture path " + texturePath); TextureScale.Bilinear(argbTexture, 16 * 2, 16 * 3); } argbTexture.Apply(); Color[] pixels = argbTexture.GetPixels(); // offset x by frame count allBlocksTexture.SetPixels(i * 16 * 2, (uid - 1) * 16 * 3, 16 * 2, 16 * 3, pixels); allBlocksTexture.Apply(); } } Debug.LogWarning("warning: texture " + texturePath + " for block " + name + " with id " + id + " does not exist"); } } }
public bool Equals(BlockValue other) { return(this.id == other.id); }
public abstract void OnSearchForFood(out bool lookForBlock, out BlockValue lookForBlockValue);
public void UpdatePathing() { ////// new temp stuff MovingEntity body = GetComponent <MovingEntity>(); //pathingTarget = LVector3.FromUnityVector3(FindObjectOfType<BlocksPlayer>().transform.position); /* * // find position on ground below player and path to that instead * int goDownAmount = 10; // don't get into infinite loop, give up eventually * while (pathingTarget.BlockV == BlockValue.Air && goDownAmount > 0) * { * pathingTarget = pathingTarget - new LVector3(0, 1, 0); * goDownAmount--; * } * pathingTarget += new LVector3(0, 2, 0); */ ////// pathingTarget = LVector3.Invalid; if (thingDoing != null) { if (thingDoing.target != null) { if (thingDoing.target.entity != null) { pathingTarget = LVector3.FromUnityVector3(thingDoing.target.entity.transform.position); iNeedToPathfindAgain = true; } else if (thingDoing.target.block != LVector3.Invalid) { pathingTarget = thingDoing.target.block; //Debug.Log("going to pathing target with block in thing doing of " + pathingTarget); } } } if (curPath == null) { iNeedToPathfindAgain = true; } if (pathingTarget == LVector3.Invalid) { body.desiredMove = Vector3.zero; } if (PhysicsUtils.millis() - lastPathfind > 1000.0 / pathfindsPerSecond && frameUpdatedLast != Time.frameCount && iNeedToPathfindAgain) // offset so everyone isn't aligned on the same frame { LVector3 myPos = LVector3.FromUnityVector3(transform.position); LVector3 foundThing; /* * if (Search(out foundThing)) * { * // found it, is it closer? * if (pathingTarget == LVector3.Invalid || LVector3.CityBlockDistance(foundThing, myPos) < LVector3.CityBlockDistance(pathingTarget, myPos)) * { * // if so, go to it instead * ThingDoing newThingDoing = new ThingDoing(thingDoing.typeOfThing, new ThingDoingTarget(foundThing)); * // copy over valid blocks for future reference * if (thingDoing != null && thingDoing.target != null) * { * newThingDoing.target.validBlocks = thingDoing.target.validBlocks; * } * thingDoing = newThingDoing; * pathingTarget = foundThing; * } * //Debug.Log("found thing when looking"); * } * else * { * // did not find * //Debug.Log("did not find thing when looking"); * //Debug.Log("did not find thing in " + steps + " steps"); * } */ frameUpdatedLast = Time.frameCount; //Debug.Log("updating pathing"); RaycastResults blockStandingOn; bool lookingForBlocks = false; if (thingDoing != null && thingDoing.target != null && thingDoing.target.entity == null && thingDoing.target.block == LVector3.Invalid && thingDoing.target.validBlocks != null) { lookingForBlocks = true; } if (pathingTarget != LVector3.Invalid || lookingForBlocks) { if (PhysicsUtils.RayCastAlsoHitWater(body.transform.position, -Vector3.up, 20.0f, out blockStandingOn)) { // if we are using shift and standing over an empty block, but our feet are on a neighboring block, use that neighboring block for pathfinding instead if (blockStandingOn != LVector3.Invalid) { myPos = blockStandingOn.hitBlock + new LVector3(0, blocksHeight, 0); } //LVector3 playerPos = LVector3.FromUnityVector3(pathingTarget.transform.position); bool iShouldJump; if (thingDoing.typeOfThing == TypeOfThingDoing.RunningAway) { PhysicsUtils.PathfindAway(blocksHeight, ref curPath, out iShouldJump, myPos, pathingTarget, 100); } else { //// new stuff bool pathingSuccess = false; PathingRegionPos resPath = null; if (lookingForBlocks) { resPath = PathingChunk.PathindToResource(World.mainWorld, myPos, GetComponent <MovingEntity>().reachRange, thingDoing.target.validBlocks, new MobilityCriteria(1, 1, blocksHeight, 1), out pathingSuccess, out blockWeCanSeeOnceWeGetThere, verbose: world.blocksWorld.verbosePathing); if (resPath != null) { pathingTarget = new LVector3(resPath.wx, resPath.wy, resPath.wz); thingDoing = new ThingDoing(thingDoing.typeOfThing, new ThingDoingTarget(pathingTarget, thingDoing.target.validBlocks)); } } else { resPath = BlocksPathing.Pathfind(World.mainWorld, myPos, pathingTarget, 1, 1, blocksHeight, 1, out pathingSuccess, verbose: false); } iShouldJump = false; if (resPath != null) { curPath = (new PathingResult(resPath)).GetPathNode(); iNeedToPathfindAgain = false; //Debug.Log("got path with next pos " + curPath.pos + " also, my pos is " + myPos + " and pathing target is " + pathingTarget); if (curPath.nextNode != null && curPath.nextNode.pos.y > curPath.pos.y) { iShouldJump = true; } if (curPath.nextNode != null) { //curPath = curPath.nextNode; } } else { curPath = null; iNeedToPathfindAgain = true; } ///// /// // old thing: //PhysicsUtils.Pathfind(blocksHeight, ref curPath, out iShouldJump, myPos, pathingTarget+new LVector3(0,1,0), 100); } if (curPath != null) { if (curPath.nextNode == null) { //Debug.Log("curPath = " + curPath.pos + " myPos = " + myPos + " next null"); } else { //Debug.Log("curPath = " + curPath.pos + " myPos = " + myPos + " nextPath = " + curPath.nextNode.pos); } } if (iShouldJump) { body.jumping = true; } } else { //Debug.Log("falling far, cannot pathfind"); } } lastPathfind = PhysicsUtils.millis(); } if (pathingTarget == LVector3.Invalid) { //Debug.Log("has invalid pathing target?"); iNeedToPathfindAgain = true; } body.desiredMove = Vector3.zero; Vector3 targetPos = transform.position; if (curPath != null && pathingTarget != LVector3.Invalid) { /* // dani commented this out recently * LVector3 myPos = LVector3.FromUnityVector3(transform.position); * RaycastResults blockStandingOn; * if (PhysicsUtils.RayCastAlsoHitWater(body.transform.position, -Vector3.up, 20.0f, out blockStandingOn)) * { * // if we are using shift and standing over an empty block, but our feet are on a neighboring block, use that neighboring block for pathfinding instead * myPos = blockStandingOn.hitBlock + new LVector3(0, blocksHeight, 0); * } * LVector3 myPosBeforeJump = myPos - new LVector3(0, 1, 0); * LVector3 myPosBeforeFall = myPos + new LVector3(0, 1, 0); */ //if (curPath.prevNode != null && (myPos == curPath.prevNode.pos || myPosBeforeJump == curPath.prevNode.pos)) //{ //} //else /* * PathNode closest = curPath; * float closestDist = LVector3.EuclideanDistance(closest.pos, myPos); * PathNode curTmp = closest; * while(curTmp.prevNode != null) * { * curTmp = curTmp.prevNode; * float tmpDist = LVector3.EuclideanDistance(curTmp.pos, myPos); * if (tmpDist < closestDist) * { * closest = curTmp; * closestDist = tmpDist; * } * } * curTmp = curPath; * while (curTmp.nextNode != null) * { * curTmp = curTmp.nextNode; * float tmpDist = LVector3.EuclideanDistance(curTmp.pos, myPos); * if (tmpDist < closestDist) * { * closest = curTmp; * closestDist = tmpDist; * } * } * * if (closest.pos == myPos) * { * if (closest.nextNode == null) * { * Debug.Log("reached end of path"); * } * else * { * curPath = closest.nextNode; * } * } * else * { * curPath = closest; * }*/ /* // dani commented this out recently * if (curPath.nextNode != null && (myPos == curPath.nextNode.pos || myPosBeforeJump == curPath.nextNode.pos || myPosBeforeFall == curPath.nextNode.pos)) * { * curPath = curPath.nextNode; * } * else if (myPos == curPath.pos || myPosBeforeJump == curPath.pos || myPosBeforeFall == curPath.pos) * { * if (curPath.nextNode != null) * { * curPath = curPath.nextNode; * } * } * * * LVector3 targetBlock = curPath.pos; * if (targetBlock.y == LVector3.FromUnityVector3(transform.position).y) * { * //body.usingShift = true; * body.usingShift = false; * } * else * { * body.usingShift = false; * } * if (targetBlock.y > myPos.y) * { * body.jumping = true; * } * else * { * body.jumping = false; * } * targetPos = targetBlock.BlockCentertoUnityVector3(); * body.SetAbsoluteDesiredMove((targetPos - transform.position).normalized); */ Vector3 dirToMove; bool pushedOffPath; curPath = curPath.GetCurNode(transform.position, out body.jumping, out dirToMove, out pushedOffPath); body.SetAbsoluteDesiredMove(dirToMove); if (pushedOffPath) { //Debug.Log("pushed off path"); //iNeedToPathfindAgain = true; } if (curPath.nextNode != null) { //Debug.Log("got cur path " + curPath.pos + " with jumping " + body.jumping + " and dir to move " + dirToMove + " and next " + curPath.nextNode.pos + " and pushed off path " + pushedOffPath); } else { //Debug.Log("got cur path " + curPath.pos + " with jumping " + body.jumping + " and dir to move " + dirToMove + " and no next and pushed off path " + pushedOffPath); } BlockValue blockWeAreGoingTo = blockWeCanSeeOnceWeGetThere.BlockV; if (!DesiredBlock(blockWeAreGoingTo) && thingDoing != null && thingDoing.target != null && thingDoing.target.entity == null) { Debug.Log("rip someone took my block , my block is now " + World.BlockToString(blockWeAreGoingTo)); curPath = null; pathingTarget = LVector3.Invalid; } else { float myDist = LVector3.CityBlockDistance(LVector3.FromUnityVector3(transform.position), pathingTarget); // found it, eat it if (myDist <= 2) { //Debug.Log("got to desired block"); if (thingDoing != null && thingDoing.typeOfThing == TypeOfThingDoing.GettingFood) { OnReachFoodBlock(blockWeCanSeeOnceWeGetThere); } else if (thingDoing != null && thingDoing.typeOfThing == TypeOfThingDoing.Gathering) { OnReachBlockToGather(blockWeCanSeeOnceWeGetThere); } /* * DidEatObject(pathingTarget, 1.0f); * world[pathingTarget] = (int)Example.Flower; */ //this.thingDoing = new ThingDoing(TypeOfThingDoing.GettingFood, null); if (thingDoing != null && thingDoing.target != null) { this.thingDoing = new ThingDoing(thingDoing.typeOfThing, new ThingDoingTarget(thingDoing.target.validBlocks)); } else if (thingDoing != null) { this.thingDoing = new ThingDoing(thingDoing.typeOfThing, null); } curPath = null; pathingTarget = LVector3.Invalid; body.jumping = false; iNeedToPathfindAgain = true; } // still pathing to it else { } } } }
public bool InventoryMatchesRecipe(Inventory inventory, int nRows, int maxBlocks, bool useResources) { if (maxBlocks == -1) { maxBlocks = inventory.capacity; } if (maxBlocks > inventory.capacity) { maxBlocks = inventory.capacity; } if (maxBlocks % nRows != 0) { Debug.LogError("maxBlocks size of " + maxBlocks + " is not a multiple of given nRows=" + nRows); return(false); } if (unordered) { int numMatchesNeeded = unorderedRecipe.Length; int numMatches = 0; int[] matches = new int[unorderedRecipe.Length]; for (int i = 0; i < matches.Length; i++) { matches[i] = -1; } for (int i = 0; i < maxBlocks; i++) { if (!IsEmptyBlockStack(inventory.blocks[i])) { bool foundMatch = false; for (int j = 0; j < unorderedRecipe.Length; j++) { if (matches[j] == -1 && unorderedRecipe[j] == inventory.blocks[i].Block) { matches[j] = i; foundMatch = true; numMatches += 1; break; } } if (!foundMatch) { return(false); } } } if (numMatches == numMatchesNeeded) { if (useResources) { for (int i = 0; i < matches.Length; i++) { inventory.blocks[matches[i]].count -= 1; if (inventory.blocks[matches[i]].count <= 0) { inventory.blocks[matches[i]] = new BlockStack(BlockValue.Air, 0); } } } return(true); } return(false); } else { int nColumns = maxBlocks / nRows; int numMatchesNeeded = recipe.GetLength(0) * recipe.GetLength(1); for (int topLeftX = 0; topLeftX < nColumns; topLeftX++) { for (int topLeftY = 0; topLeftY < nRows; topLeftY++) { int numMatches = 0; for (int i = 0; i < recipe.GetLength(1); i++) { for (int j = 0; j < recipe.GetLength(0); j++) { int x = topLeftX + i; int y = topLeftY + j; if (x < nColumns && y < nRows) { int index = x + y * nColumns; BlockStack cur = inventory.blocks[index]; BlockValue recipeCur = recipe[recipe.GetLength(0) - j - 1, i]; if (IsEmptyBlockStack(cur)) { if (recipeCur == BlockValue.Air) { //Debug.Log(x + " " + y + "inventory empty here and recipe is too, recipeCur=" + World.BlockToString((int)recipeCur)); numMatches += 1; } else { //Debug.Log(x + " " + y + "inventory empty here and recipe is not, recipeCur=" + World.BlockToString((int)recipeCur)); } } else if (!IsEmptyBlockStack(cur)) { if (cur.block == recipeCur) { //Debug.Log(x + " " + y + "same: inventory is " + World.BlockToString(cur.block) + " and recipe is " + World.BlockToString((int)recipeCur)); numMatches += 1; } else { //Debug.Log(x + " " + y + "different: inventory is " + World.BlockToString(cur.block) + " and recipe is " + World.BlockToString((int)recipeCur)); } } } } } //Debug.Log("got num matches " + numMatches + " with top left x=" + topLeftX + " and topLeftY=" + topLeftY); if (numMatches == numMatchesNeeded) { bool hasExtraStuff = false; for (int x = 0; x < topLeftX; x++) { for (int y = 0; y < nRows; y++) { int index = x + y * nColumns; if (!IsEmptyBlockStack(inventory.blocks[index])) { hasExtraStuff = true; break; } } if (hasExtraStuff) { break; } } for (int x = topLeftX; x < nColumns; x++) { for (int y = 0; y < topLeftY; y++) { int index = x + y * nColumns; if (!IsEmptyBlockStack(inventory.blocks[index])) { hasExtraStuff = true; break; } } if (hasExtraStuff) { break; } } if (hasExtraStuff) { //Debug.Log("matches recipe but has extra stuff"); return(false); } else { //Debug.Log("matches recipe completely"); if (useResources) { for (int i = 0; i < recipe.GetLength(1); i++) { for (int j = 0; j < recipe.GetLength(0); j++) { int x = topLeftX + i; int y = topLeftY + j; int index = x + y * nColumns; if (!IsEmptyBlockStack(inventory.blocks[index])) { inventory.blocks[index].count -= 1; if (inventory.blocks[index].count <= 0) { inventory.blocks[index] = new BlockStack(BlockValue.Air, 0); } } } } } return(true); } } else if (numMatches > numMatchesNeeded) { Debug.LogWarning("numMatches = " + numMatches + " but maximum num matches is " + numMatchesNeeded + " this is invalid how u do this"); } } } return(false); } }