public void RoomTalkBroadcast(int sourceX, int sourceY, string chat, int roomUser) { Logging.LogEvent("Chatting to room " + mRoomID.ToString() + ": " + chat, Logging.LogLevel.Debug); foreach (int sessionId in mMemberSessions.Keys) { if (mRoomUsers.ContainsKey(sessionId)) { string currentChat = chat; int xDistance = Math.Abs(sourceX - mRoomUsers[sessionId].CurrentX); int yDistance = Math.Abs(sourceY - mRoomUsers[sessionId].CurrentY); if (xDistance >= 6 || yDistance >= 6) //Garble text { for (int i = 0; i < chat.Length; i++) { if (SpecialMath.RandomNumber(0, 10) > 5 && chat[i] != ' ') { currentChat = currentChat.Replace(chat[i], '.'); } } } if (xDistance < 9 && yDistance < 9) // User can at least partially hear { mMessage.Init(24); //@X mMessage.appendString(ArgumentEncoding.encodeInt(roomUser)); mMessage.appendString(currentChat); mMessage.appendChar(2); InstanceManager.Sessions.GetSession(sessionId).SendMessage(mMessage.ToString(), false); } } } }
private void HandlePoolCamera() { if (DateTime.Now.TimeOfDay.TotalSeconds > mCameraNext || mCameraDay != DateTime.Now.DayOfYear) { if (SpecialMath.RandomNumber(0, 10) > 5) { int randomTarget = mRoomInstance.mRoomUserIDs[SpecialMath.RandomNumber(0, mRoomInstance.mRoomUserIDs.Count - 1)]; int targetCamera = 1; if (SpecialMath.RandomNumber(0, 10) > 5) { targetCamera = 2; } SendCameraPacket("setcamera " + targetCamera.ToString()); string transition = "fade"; if (SpecialMath.RandomNumber(0, 10) > 5) { transition = "cameraPan"; } SendCameraPacket("transition " + transition); SendCameraPacket("targetcamera " + randomTarget.ToString()); } mCameraNext = DateTime.Now.TimeOfDay.TotalSeconds + 5; mCameraDay = DateTime.Now.DayOfYear; } }
// Поворот ствола к цели void AimGun(Vector3 target) { float angle = SpecialMath.CalculateAngleToHitTarget(target, gunEndTransform.position, velocity); gunPivotTransform.localEulerAngles = new Vector3(360f - angle, 0f, 0f); transform.LookAt(target); transform.eulerAngles = new Vector3(0f, transform.rotation.eulerAngles.y, 0f); }
public Neuron(int weightCount, byte v) { weights = new byte[weightCount]; for (int i = 0; i < weightCount; i++) { weights[i] = SpecialMath.FloatToByte(Extra.NextFloat()); } value = v; }
public NN(int thinkingneurons, int workingneurons) { Random random = new Random(); neuronCount = thinkingneurons + workingneurons; neurons = new Neuron[neuronCount]; for (int i = 0; i < neuronCount; i++) { neurons[i] = new Neuron(neuronCount - 1, SpecialMath.FloatToByte((float)(random.NextDouble() * 2) - 1)); } }
public void Iterate(byte[] neurons) // bad iterate lol { float total = 0; for (int i = 0; i < weights.Length; i++) { float a = SpecialMath.ByteToFloat(neurons[i]); a *= weights[i]; total += a; } futurevalue = SpecialMath.FloatToByte(SpecialMath.Sigmoid(total)); }
public void Iterate(Neuron[] neurons, Neuron neuron) { float total = 0; for (int i = 0; i < weights.Length; i++) { if (neuron != neurons[i]) { float a = SpecialMath.ByteToFloat(neurons[i].value); a *= weights[i]; total += a; } } futurevalue = SpecialMath.FloatToByte(SpecialMath.Sigmoid(total)); }
private void doPlayerUpdate(RoomUser user, PathFinderNode nextNode) { user.NextX = nextNode.X; user.NextY = nextNode.Y; user.NextZ = mHeightMap[user.NextX, user.NextY]; user.Path.Remove(nextNode); mPlayerMap[user.CurrentX, user.CurrentY] = false; mPlayerMap[user.NextX, user.NextY] = true; int newDirection = SpecialMath.WorkDirection(user.CurrentX, user.CurrentY, user.NextX, user.NextY); user.HeadDirection = newDirection; user.BodyDirection = newDirection; mRoomInstance.AnnounceUserStatus(user.SessionID, true); user.CurrentX = user.NextX; user.CurrentY = user.NextY; user.CurrentZ = user.NextZ; }
public void AimTo(Vector3 toVec) { // если смотрим в бесконечность if (float.IsInfinity(toVec.x)) { SetAim((int)AimState.INACTIVE); } else { SetAim((int)AimState.ACTIVE); // если смотрим на цель, но она дальше максимальной дальности // потенциальный допил - автоподстройка дальности, но тогда теряется смысл в анимации ствола и реальной баллистике if (SpecialMath.CalculateAngleToHitTarget(toVec, gunController.gunEndTransform.position, gunController.velocity) <= 45f) { SetAim((int)AimState.SEMIACTIVE); } } }
//79 - "LOOKTO": "AO" public void Listener79() { RoomUser user = mRoomInstance.GetUser(mSessionID); string[] part = mPacketBody.Split(' '); int x, y; if (!user.IsMoving) { if (part.Length == 2) { if (int.TryParse(part[0], out x) && int.TryParse(part[1], out y)) { int newDir = SpecialMath.WorkDirection(user.CurrentX, user.CurrentY, x, y); bool updateBody = !(newDir == user.BodyDirection + 1 || newDir == user.BodyDirection - 1 || newDir == user.BodyDirection - 7 || newDir == user.BodyDirection + 7); if (!user.SpecialStates.ContainsKey("lay") && !user.SpecialStates.ContainsKey("sit")) { user.HeadDirection = newDir; if (updateBody) { user.BodyDirection = newDir; } mRoomInstance.AnnounceUserStatus(mSessionID, true); } else { if (!updateBody) { user.HeadDirection = newDir; } mRoomInstance.AnnounceUserStatus(mSessionID, true); } } } } }
void RenderTrajectory() { // Начало дуги Vector3 currentVel = gunPivotTransform.forward * velocity; Vector3 currentPos = gunEndTransform.position; Vector3 newPos = Vector3.zero; Vector3 newVel = Vector3.zero; List <Vector3> futurePositions = new List <Vector3>(); // Начало списка всех возможных будущих позиций снаряда на этой траектории futurePositions.Add(currentPos); // Защита от эджкейса с прицелом в бесконечность int maxIterations = 10000; for (int i = 0; i < maxIterations; i++) { // Делаем шаг, интерполируя положение снаряда в будущее SpecialMath.PositionStepInterpolate(Time.fixedDeltaTime, currentPos, currentVel, out newPos, out newVel); currentPos = newPos; currentVel = newVel; futurePositions.Add(currentPos); // Примем, что земли ниже чем 0 по Y не бывает if (currentPos.y < 0f) { break; } } lineRenderer.positionCount = futurePositions.Count; lineRenderer.SetPositions(futurePositions.ToArray()); }
static void GenerateMap() { mapBar = new ProgressBar("Generating Map... ", MapWidth, 20, 0, 1); Screen.DisplayScreen(); map = new byte[MapWidth, MapHeight, MapLength]; for (int x = 0; x < MapWidth; x++) { for (int y = 0; y < MapHeight; y++) { for (int z = 0; z < MapLength; z++) { // FUTURE TODO make map generate using perlin noise #region BasicMapGeneration if (y < 4) // stone // 1.5% metal 98.5% stone { if (Extra.Chance(1.5f)) { map[x, y, z] = (byte)Blocks.Block.Metal; } else { map[x, y, z] = (byte)Blocks.Block.Stone; } } else if (y == 4) // dirt(surface) // 2.5% pond 2.5% farmland 95% dirt { if (map[x, y, z] == 0) // if its empty { if (Extra.Chance(5f)) { if (Extra.Chance(50f)) { // pond center map[x, y, z] = (byte)Blocks.Block.Water; // pond outsides map[x, y, SpecialMath.Modulus(z + 1, MapLength)] = (byte)Blocks.Block.Water; map[x, y, SpecialMath.Modulus(z - 1, MapLength)] = (byte)Blocks.Block.Water; map[SpecialMath.Modulus(x + 1, MapWidth), y, z] = (byte)Blocks.Block.Water; map[SpecialMath.Modulus(x - 1, MapWidth), y, z] = (byte)Blocks.Block.Water; } else { map[x, y, z] = (byte)Blocks.Block.FarmLand; // TODO add to farmLands } } else { map[x, y, z] = (byte)Blocks.Block.Dirt; } } } else if (y == 5) // trees // 2.5% trees 97.5% air { if (Extra.Chance(2.5f)) { // tree D: map[x, y, z] = (byte)Blocks.Block.Tree; // trunk 1 map[x, y + 1, z] = (byte)Blocks.Block.Tree; // trunk 2 // leaf algo. :D !!! for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 3; k++) { map[SpecialMath.Modulus(x + i, MapWidth), y + j, SpecialMath.Modulus(z + k, MapLength)] = (byte)Blocks.Block.Tree; } } } } } #endregion } } mapBar.QuickUpdate(); Screen.DisplayScreen(); } }
// Tim's working neurons' order: ear, 64*(4)eyes, 6*(4)hairs, turn_left, turn_right, turn_up, turn_down, arm1/arm2, attack/interact, operand, mouth, move forward, move backward, move left, move right, jump. public void CalculateState() { // BIG BAD TODO make all update happen in UpdateState() int nPtr = 0; //*sensing: ear, 64*(4)eyes, 6*(4)hairs // TODO ear // vvv OPTIMIZE vvv still has TODO #region Hairs byte[] blockNeurons; blockNeurons = SpecialMath.NibbleToNeurons(Game.map[SpecialMath.Modulus(x + 1, Game.MapWidth), y, z]); // TODO add index of player with offset (TODO implement dir) for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { nn.neurons[nPtr + j].value = blockNeurons[j]; } nPtr += 4; } blockNeurons = SpecialMath.NibbleToNeurons(Game.map[SpecialMath.Modulus(x - 1, Game.MapWidth), y, z]); // TODO add index of player with offset for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { nn.neurons[nPtr + j].value = blockNeurons[j]; } nPtr += 4; } blockNeurons = SpecialMath.NibbleToNeurons(Game.map[x, SpecialMath.Modulus(y + 1, Game.MapHeight), z]); // TODO add index of player with offset for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { nn.neurons[nPtr + j].value = blockNeurons[j]; } nPtr += 4; } blockNeurons = SpecialMath.NibbleToNeurons(Game.map[x, SpecialMath.Modulus(y - 1, Game.MapHeight), z]); // TODO add index of player with offset for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { nn.neurons[nPtr + j].value = blockNeurons[j]; } nPtr += 4; } blockNeurons = SpecialMath.NibbleToNeurons(Game.map[x, y, SpecialMath.Modulus(z + 1, Game.MapLength)]); // TODO add index of player with offset for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { nn.neurons[nPtr + j].value = blockNeurons[j]; } nPtr += 4; } blockNeurons = SpecialMath.NibbleToNeurons(Game.map[x, y, SpecialMath.Modulus(z - 1, Game.MapLength)]); // TODO add index of player with offset for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { nn.neurons[nPtr + j].value = blockNeurons[j]; } nPtr += 4; } #endregion // vvv TODO #region Eyes #endregion //*nn iteration (lol ez) nn.Iterate(); //*interaction: turn_LR, turn_UD, arm1/arm2, attack/interact, operand, mouth #region Directions float turn_LR = nn.neurons[nPtr].value; nPtr++; float turn_UD = nn.neurons[nPtr].value; nPtr++; dir = Extra.DirectionCycle(dir, true && turn_LR >= 0); subdir = Extra.SubDirectionCycle(subdir, true && turn_UD >= 0); #endregion // TODO dropping / special grabbing #region Interaction // evaluate coord int[] coord = Extra.DirectionToCoordinate(dir, subdir); int[] timcoord = new int[] { x, y, z }; int[] limits = new int[] { Game.MapWidth, Game.MapHeight, Game.MapLength }; int[] targetcoord = new int[] { 0, 0, 0 }; for (int i = 0; i < 3; i++) { targetcoord[i] = SpecialMath.Modulus(coord[i] + timcoord[i], limits[i]); } // big switch part bool ARM = false; // if right arm or left arm float fARM = nn.neurons[nPtr].value; nPtr++; bool AI = false; // attack or interact float fAI = nn.neurons[nPtr].value; nPtr++; Items.Item armItem; // evaluate ARM, AI and armItem ARM = true && fARM >= 0; AI = true && fAI >= 0; armItem = ARM ? right : left; // switch statement switch (AI) { case true: // attack // still has TODO switch (Game.map[targetcoord[0], targetcoord[1], targetcoord[2]]) { case (byte)Blocks.Block.Air: // TODO attack player break; case (byte)Blocks.Block.Stone: if (armItem.item == Items.ItemEnum.WoodPickaxe || armItem.item == Items.ItemEnum.MetalPickaxe) { Drop(new Items.Item(Items.ItemEnum.Stone, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); Game.map[targetcoord[0], targetcoord[1], targetcoord[2]] = (byte)Blocks.Block.Air; } break; case (byte)Blocks.Block.Dirt: Drop(new Items.Item(Items.ItemEnum.Dirt, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); Game.map[targetcoord[0], targetcoord[1], targetcoord[2]] = (byte)Blocks.Block.Air; break; case (byte)Blocks.Block.Tree: Drop(new Items.Item(Items.ItemEnum.Tree, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); Game.map[targetcoord[0], targetcoord[1], targetcoord[2]] = (byte)Blocks.Block.Air; break; case (byte)Blocks.Block.Metal: if (armItem.item == Items.ItemEnum.WoodPickaxe || armItem.item == Items.ItemEnum.MetalPickaxe) { Drop(new Items.Item(Items.ItemEnum.Metal, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); Game.map[targetcoord[0], targetcoord[1], targetcoord[2]] = (byte)Blocks.Block.Air; } break; case (byte)Blocks.Block.Table: Drop(new Items.Item(Items.ItemEnum.Table, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); Game.map[targetcoord[0], targetcoord[1], targetcoord[2]] = (byte)Blocks.Block.Air; break; case (byte)Blocks.Block.Stack: Drop(new Items.Item(Items.ItemEnum.Stack, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); int index = Items.Stack.FindIndex(Game.stacks, targetcoord[0], targetcoord[1], targetcoord[2]); if (Game.stacks[index].items.Count > 0) { for (int i = 0; i < Game.stacks[index].items.Count; i++) { Drop(Game.stacks[index].items[i], targetcoord[0], targetcoord[1], targetcoord[2]); } } Game.map[targetcoord[0], targetcoord[1], targetcoord[2]] = (byte)Blocks.Block.Air; Game.stacks.RemoveAt(index); break; case (byte)Blocks.Block.Water: // useless lol break; case (byte)Blocks.Block.FarmLand: Drop(new Items.Item(Items.ItemEnum.FarmLand, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); Game.map[targetcoord[0], targetcoord[1], targetcoord[2]] = (byte)Blocks.Block.Air; Game.farmLands.RemoveAt(Items.FarmLand.FindIndex(Game.farmLands, targetcoord[0], targetcoord[1], targetcoord[2])); break; case (byte)Blocks.Block.Planks: Drop(new Items.Item(Items.ItemEnum.Planks, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); Game.map[targetcoord[0], targetcoord[1], targetcoord[2]] = (byte)Blocks.Block.Air; break; } break; case false: // interact // evaluate operand byte operand = 0; operand = SpecialMath.FloatToByte(new float[4] { nn.neurons[nPtr].value, nn.neurons[nPtr + 1].value, nn.neurons[nPtr + 2].value, nn.neurons[nPtr + 3].value }); nPtr += 4; switch (Game.map[targetcoord[0], targetcoord[1], targetcoord[2]]) { case (byte)Blocks.Block.Air: // place block // check if block is supported bool supported = false; byte[] blocks = new byte[6]; blocks[0] = Game.map[SpecialMath.Modulus(targetcoord[0] + 1, Game.MapWidth), targetcoord[1], targetcoord[2]]; blocks[1] = Game.map[SpecialMath.Modulus(targetcoord[0] - 1, Game.MapWidth), targetcoord[1], targetcoord[2]]; blocks[2] = Game.map[targetcoord[0], SpecialMath.Modulus(targetcoord[1] + 1, Game.MapHeight), targetcoord[2]]; blocks[3] = Game.map[targetcoord[0], SpecialMath.Modulus(targetcoord[1] - 1, Game.MapHeight), targetcoord[2]]; blocks[4] = Game.map[targetcoord[0], targetcoord[1], SpecialMath.Modulus(targetcoord[2] + 1, Game.MapLength)]; blocks[5] = Game.map[targetcoord[0], targetcoord[1], SpecialMath.Modulus(targetcoord[2] - 1, Game.MapLength)]; for (int i = 0; i < 6; i++) { if (blocks[i] != 0 && blocks[i] != 5) { supported = true; break; } } // place block if (supported == true && (byte)armItem.item <= 9) { Game.map[targetcoord[0], targetcoord[1], targetcoord[2]] = (byte)armItem.item; switch ((byte)armItem.item) // handle stack and farmLand { case 6: // stack Game.stacks.Add(new Items.Stack(new List <Items.Item>(), targetcoord[0], targetcoord[1], targetcoord[2])); break; case 8: // farmland Game.farmLands.Add(new Items.FarmLand(targetcoord[0], targetcoord[1], targetcoord[2])); break; } Use(ARM, 1); // use 1 item } break; case (byte)Blocks.Block.Stone: // useless lol break; case (byte)Blocks.Block.Dirt: // try plant tree with FarmFood if (armItem.item == Items.ItemEnum.FarmFood) { // plant tree if (Game.map[targetcoord[0], SpecialMath.Modulus(targetcoord[1] + 1, Game.MapHeight), targetcoord[2]] == 0) { Game.map[targetcoord[0], SpecialMath.Modulus(targetcoord[1] + 1, Game.MapHeight), targetcoord[2]] = (byte)Blocks.Block.Tree; // trunk 1 } if (Game.map[targetcoord[0], SpecialMath.Modulus(targetcoord[1] + 2, Game.MapHeight), targetcoord[2]] == 0) { Game.map[targetcoord[0], SpecialMath.Modulus(targetcoord[1] + 2, Game.MapHeight), targetcoord[2]] = (byte)Blocks.Block.Tree; // trunk 2 } // leaf algo (:D) for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 3; k++) { if (Game.map[SpecialMath.Modulus(targetcoord[0] + i, Game.MapWidth), SpecialMath.Modulus(targetcoord[1] + j + 1, Game.MapHeight), SpecialMath.Modulus(targetcoord[2] + k, Game.MapLength)] == 0) { Game.map[SpecialMath.Modulus(targetcoord[0] + i, Game.MapWidth), SpecialMath.Modulus(targetcoord[1] + j + 1, Game.MapHeight), SpecialMath.Modulus(targetcoord[2] + k, Game.MapLength)] = (byte)Blocks.Block.Tree; } } } } Use(ARM, 1); // use 1 FarmFood } break; case (byte)Blocks.Block.Tree: // useless lol break; case (byte)Blocks.Block.Table: // crafting with operand switch (operand) { case 9: // Planks if (armItem.item == Items.ItemEnum.Tree && armItem.count >= 1) { Use(ARM, 1); Drop(new Items.Item(Items.ItemEnum.Planks, 4, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); } break; case 10: // WoodPickaxe if (armItem.item == Items.ItemEnum.Planks && armItem.count >= 2) { Use(ARM, 2); Drop(new Items.Item(Items.ItemEnum.WoodPickaxe, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); } break; case 12: // MetalPickaxe if (armItem.item == Items.ItemEnum.Metal && armItem.count >= 2) { Use(ARM, 2); Drop(new Items.Item(Items.ItemEnum.MetalPickaxe, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); } break; case 13: // WoodWeapon if (armItem.item == Items.ItemEnum.Planks && armItem.count >= 1) { Use(ARM, 1); Drop(new Items.Item(Items.ItemEnum.WoodWeapon, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); } break; case 14: // MetalWeapon if (armItem.item == Items.ItemEnum.Metal && armItem.count >= 1) { Use(ARM, 1); Drop(new Items.Item(Items.ItemEnum.MetalWeapon, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); } break; } break; case (byte)Blocks.Block.Stack: // grabbing/inserting Items.Stack stack = Items.Stack.Find(Game.stacks, targetcoord[0], targetcoord[1], targetcoord[2]); if (operand < 8) { // grab Drop(stack.Grab(), x, y, z); PickUp(); } else { // insert stack.Insert(armItem); Use(ARM, armItem.count); } break; case (byte)Blocks.Block.Water: // useless lol break; case (byte)Blocks.Block.FarmLand: // give FarmFood if grown Items.FarmLand farmLand = Items.FarmLand.Find(Game.farmLands, targetcoord[0], targetcoord[1], targetcoord[2]); if (farmLand.grown == true) { Drop(new Items.Item(Items.ItemEnum.FarmFood, 1, targetcoord[0], targetcoord[1], targetcoord[2]), targetcoord[0], targetcoord[1], targetcoord[2]); Game.farmLands[Items.FarmLand.FindIndex(Game.farmLands, targetcoord[0], targetcoord[1], targetcoord[2])].Reset(); } break; case (byte)Blocks.Block.Planks: // useless lol break; } break; } #endregion // TODO Mouth //*movement: move_left, move_right, move_forward, move_backward, jump #region Movement // evaluate moveLeft, moveRight, moveFoward, moveBackward and jump float moveLeft = nn.neurons[nPtr].value; nPtr++; float moveRight = nn.neurons[nPtr].value; nPtr++; float moveForward = nn.neurons[nPtr].value; nPtr++; float moveBackward = nn.neurons[nPtr].value; nPtr++; float jump = nn.neurons[nPtr].value; bool bJump = true && jump >= 0; bool moveSide = true && moveLeft > moveRight; bool moveStraight = true && moveForward > moveBackward; bool bMoveSide = (true && moveLeft >= 0) ^ (true && moveRight >= 0); bool bMoveStraight = (true && moveForward >= 0) ^ (true && moveBackward >= 0); // TODO jumping if (bJump) // jump { if (Game.map[x, SpecialMath.Modulus(y + 1, Game.MapHeight), z] == (byte)Blocks.Block.Air) // atleast level 1 { if (Game.map[x, SpecialMath.Modulus(y + 2, Game.MapHeight), z] == (byte)Blocks.Block.Air) { y = SpecialMath.Modulus(y + 2, Game.MapHeight); // level 2 } else { y = SpecialMath.Modulus(y + 1, Game.MapHeight); // level 1 } } } // horizontal movement DIR movementDir = dir; if (bMoveStraight && !moveStraight) // alpha flip (0) { switch (movementDir) { case DIR.NORTH: movementDir = DIR.SOUTH; break; case DIR.SOUTH: movementDir = DIR.NORTH; break; case DIR.EAST: movementDir = DIR.WEST; break; case DIR.WEST: movementDir = DIR.EAST; break; } } int[] alpha = new int[] { 0, 0, 0 }; // no offset if (bMoveStraight) { alpha = Extra.MovementDirectionToCoordinate(movementDir); // alpha coordinate (1) } if (bMoveSide) { movementDir = Extra.DirectionCycle(movementDir, moveSide); // beta cycle (2) } int[] beta = new int[] { 0, 0, 0 }; // no offset if (bMoveSide) { beta = Extra.MovementDirectionToCoordinate(movementDir); // beta coordinate (3) } int[] final = new int[] { 0, 0, 0 }; // initializing for (int i = 0; i < 3; i++) { final[i] = alpha[i] + beta[i]; // final result (unofficial 4) } if (Game.map[final[0], final[1], final[2]] != 0) // can move { x = final[0]; z = final[2]; } #endregion //*extra #region Gravity if (Game.map[x, SpecialMath.Modulus(y - 1, Game.MapHeight), z] == (byte)Blocks.Block.Air) // can fall { y = SpecialMath.Modulus(y - 1, Game.MapHeight); // fall fall++; falling = true; } else // on ground { if (falling) // just landed { falling = false; hp -= fall > 2 ? fall - 2 : 0; } } #endregion #region DeathCheck if (hp <= 0) // died { dead = true; // remove from tims Game.tims.Remove(this); } #endregion }
private void GenerateMaps() { //Get information about the default heightmap string[] lines = mDefaultHeightmap.Split(Convert.ToChar(13)); int y = lines.Length; int x = lines[0].Length; //Client heightmap string[,] theMap = new string[x, y]; string[,] theOldMap = new string[x, y]; //Pathfinding info byte[,] theMatrix = new byte[SpecialMath.NearestSuperiorPowerOfTwo(x), SpecialMath.NearestSuperiorPowerOfTwo(y)]; //Heightmap float[,] hMap = new float[x, y]; //Redirect map for beds Point[,] redirectMap = new Point[x, y]; //Rollers bool enableRollers = false; //Translate the default map into data thor can understand for (int line = 0; line < y; line++) { for (int chr = 0; chr < x; chr++) { float tileZ = 0; string tileValue = lines[line].Substring(chr, 1); theMap[chr, line] = tileValue; if (float.TryParse(tileValue, out tileZ)) { theMatrix[chr, line] = 1; hMap[chr, line] = tileZ; } else { theMatrix[chr, line] = 0; } redirectMap[chr, line] = new Point(chr, line); } } theOldMap = theMap; //Loop over the furniture and update heightmap and pathfinder foreach (FurniInfo info in mFloorFurni) { //If this is the highest item on the tile, set the heightmap if (info.TotalHeight > hMap[info.PosX, info.PosY]) { hMap[info.PosX, info.PosY] = info.TotalHeight; } //If the item isn't pathable, block the tile if (!info.Flags.CanPath) { theMatrix[info.PosX, info.PosY] = 0; } //If the item isn't stackable or interactable, we should tell the client if (!info.Flags.CanStackOn && !info.PublicFurni && !info.Flags.CanSit && !info.Flags.CanLay && !info.Flags.CanStand) { if (hMap[info.PosX, info.PosY] == 0) { theMap[info.PosX, info.PosY] = "A"; } } //If the item is a roller, set the weight higher so users avoid walking on them if (info.Flags.IsRoller && theMatrix[info.PosX, info.PosY] != 0) { theMatrix[info.PosX, info.PosY] = 5; } //Get a list of tiles this furniture currently resides on Dictionary <int, AffectedTile> pointList = GetAffectedTiles(info); //Loop over the affected tiles and essentially do what we did above foreach (AffectedTile point in pointList.Values) { //If this is the highest item on the tile, set the heightmap if (info.TotalHeight > hMap[point.X, point.X]) { hMap[point.X, point.Y] = info.TotalHeight; } //If the item isn't pathable, block the tile if (!info.Flags.CanPath) { theMatrix[point.X, point.Y] = 0; } //If the item isn't stackable or interactable, we should tell the client if (!info.Flags.CanStackOn && !info.PublicFurni && !info.Flags.CanSit && !info.Flags.CanLay && !info.Flags.CanStand) { if (hMap[point.X, point.Y] == 0) { theMap[point.X, point.Y] = "A"; } } //If this is a bed, we need to redirect the tile to the top if (info.Flags.TopRow) { if (info.PosRotation == 0 || info.PosRotation == 4) { redirectMap[point.X, point.Y].Y = info.PosY; } if (info.PosRotation == 2 || info.PosRotation == 6) { redirectMap[point.X, point.Y].X = info.PosX; } } } } //Second loop, to handle special exceptions and client heightmap generation foreach (FurniInfo info in mFloorFurni) { //Is this furniture at the top of the tile? if (info.TotalHeight == hMap[info.PosX, info.PosY]) { //Can we stack on it? If so, the client tile height should be equal to it if (info.Flags.CanStackOn) { theMap[info.PosX, info.PosY] = ((int)Math.Round(info.TotalHeight)).ToString(); } } //Get a list of tiles this furniture currently resides on Dictionary <int, AffectedTile> pointList = GetAffectedTiles(info); //Loop over the affected tiles and essentially do what we did above foreach (AffectedTile point in pointList.Values) { //Is this furniture at the top of the tile? if (info.TotalHeight == hMap[point.X, point.Y]) { //Can we stack on it? If so, the client tile height should be equal to it if (info.Flags.CanStackOn) { theMap[point.X, point.Y] = ((int)Math.Round(info.TotalHeight)).ToString(); } } } //Is it a door divder? If it is, update the pathfinder with the correct value if (info.VarType == FurniInfo.VarTypes.DoorDivider) { theMatrix[info.PosX, info.PosY] = 0; //Open ? if (info.FurniVar == "O") { theMatrix[info.PosX, info.PosY] = 1; } } //Is it a chair? If it is, drop the tile to the lowest possible if (info.Flags.CanSit && !info.PublicFurni) { hMap[info.PosX, info.PosY] = int.Parse(theOldMap[info.PosX, info.PosY]); //Get a list of tiles this furniture currently resides on pointList = GetAffectedTiles(info); //Loop over the affected tiles and essentially do what we did above foreach (AffectedTile point in pointList.Values) { hMap[point.X, point.Y] = int.Parse(theOldMap[info.PosX, info.PosY]); } } } //Do one final loop to handle rollers foreach (FurniInfo info in mFloorFurni) { //Roller ? if (info.Flags.IsRoller) { enableRollers = true; theMap[info.PosX, info.PosY] = theOldMap[info.PosX, info.PosY]; } } //Update the real maps! mClientMap = theMap; mMatrix = theMatrix; mHeightMap = hMap; mRedirectMap = redirectMap; mHasRollers = enableRollers; }
public void RequestSetStuffDataFloorItem(int itemId, string data, RoomUser user, FurniInfo.VarTypes overrideType) { FurniInfo item = GetFurniObject(itemId); ClientMessage mMessage = new ClientMessage(); if (item != null) { if (overrideType != 0) { item.VarType = overrideType; } switch (item.VarType) { case FurniInfo.VarTypes.TempOpen: if (TilesTouching(item.PosX, item.PosY, user.CurrentX, user.CurrentY)) { InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, "FALSE"); if (data == "TRUE") { NotifyClientSetStuffTempOpen(itemId); } } break; case FurniInfo.VarTypes.TrueFalse: if (TilesTouching(item.PosX, item.PosY, user.CurrentX, user.CurrentY)) { if ((data == "TRUE" || data == "FALSE")) { InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, data); NotifyClientSetStuffChange(itemId, data); } } break; case FurniInfo.VarTypes.DoorDivider: if (user.HasAdmin || user.HasRights) { if (data == "O" || data == "C") { if (!PlayerCheck(item.PosX, item.PosY)) { InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, data); NotifyClientSetStuffChange(itemId, data); mFloorFurni = InstanceManager.Game.Furni.GetRoomFloorFurni(mRoomInstance.RoomInfo.RoomID); GenerateMaps(); } } } break; case FurniInfo.VarTypes.Dice: if (TilesTouching(item.PosX, item.PosY, user.CurrentX, user.CurrentY)) { if (data == "dice_roll" || data == "dice_off") { int newVal = 0; if (data == "dice_roll") { newVal = SpecialMath.RandomNumber(1, 6); } bool isRoll = newVal > 0; int rollVal = (item.FurniID * 38) + newVal; InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, newVal.ToString()); NotifyClientDiceRoll(item.FurniID, rollVal, isRoll); } } break; case FurniInfo.VarTypes.Bottle: if (data == "dice_roll") { int newVal = SpecialMath.RandomNumber(0, 7); bool isRoll = newVal > 0; int rollVal = (item.FurniID * 38) + newVal; InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, newVal.ToString()); NotifyClientDiceRoll(item.FurniID, rollVal, isRoll); } break; case FurniInfo.VarTypes.OnOff: if (data == "ON" || data == "OFF") { InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, data); NotifyClientSetStuffChange(itemId, data); } break; case FurniInfo.VarTypes.OpenOrClosed: if (data == "O" || data == "C") { InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, data); NotifyClientSetStuffChange(itemId, data); } break; case FurniInfo.VarTypes.NumericalOff: int tmpNum = -1; if (int.TryParse(data, out tmpNum) || data == "OFF") { if (tmpNum >= -1 && tmpNum < 10 && !(tmpNum == -1 && data == "-1")) { InstanceManager.Game.Furni.SetStuffDataFloorItem(itemId, data); NotifyClientSetStuffChange(itemId, data); } } break; } } }