private void setRoomUnitTileState(roomUnit pUnit) { pUnit.removeStatus("sit"); pUnit.removeStatus("lay"); List <floorItem> tileItems = this.getFloorItems(pUnit.X, pUnit.Y); foreach (Items.floorItem lItem in tileItems) { if (lItem.Definition.Behaviour.canSitOnTop) { pUnit.Z = lItem.Z; pUnit.rotationHead = lItem.Rotation; pUnit.rotationBody = lItem.Rotation; pUnit.removeStatus("dance"); pUnit.addStatus("sit", "sit", stringFunctions.formatFloatForClient(lItem.Definition.topHeight), 0, null, 0, 0); } else if (lItem.Definition.Behaviour.canLayOnTop) { //pUnit.X = lItem.X; //pUnit.Y = lItem.Y; pUnit.Z = lItem.Z; pUnit.rotationBody = lItem.Rotation; pUnit.rotationHead = lItem.Rotation; pUnit.removeStatus("dance"); pUnit.removeStatus("handitem"); pUnit.addStatus("lay", "lay", stringFunctions.formatFloatForClient(lItem.Definition.topHeight) + " null", 0, null, 0, 0); } } }
private void shortenRoomUnitPath(roomUnit pUnit) { if (pUnit.Path.Count > 1) { blisterMoleNode pNode = pUnit.Path[1]; if (!(Math.Abs(pUnit.X - pNode.X) > 1 || Math.Abs(pUnit.Y - pNode.Y) > 1)) { if (tileFree(pNode.X, pNode.Y)) { int X1 = 0; int X2 = 0; if (pNode.X > pUnit.X) { X1 = -1; X2 = 1; } else { X1 = 1; X2 = -1; } if (tileFree((byte)(pNode.X + X1), pNode.Y) && tileFree((byte)(pUnit.X + X2), pUnit.Y)) // Valid shortcut { pUnit.Path.RemoveAt(0); } } } } }
public void refreshRoomUnitOnTile(byte X, byte Y) { roomUnit pUnit = this.getRoomUnitOnTile(X, Y); if (pUnit != null) { setRoomUnitTileState(pUnit); this.sendMessage("@b" + pUnit.ToStatusString() + (char)1); } }
private void unsetRoomUnitTileState(roomUnit pUnit) { if (this.gridState[pUnit.X, pUnit.Y] == roomTileState.Interactive) { List <floorItem> Items = this.getFloorItems(pUnit.X, pUnit.Y); foreach (floorItem lItem in Items) { if (lItem.Definition.Behaviour.canSitOnTop) // User was seated, remove sit animation and reset height { pUnit.removeStatus("sit"); pUnit.Z = this.gridHeight[pUnit.X, pUnit.Y]; } } } }
private void moveRoomUnitToTile(roomUnit pUnit, ref blisterMoleNode nextTile) { // Set next step pUnit.nextX = nextTile.X; pUnit.nextY = nextTile.Y; pUnit.nextZ = this.gridHeight[nextTile.X, nextTile.Y]; pUnit.Path.Remove(nextTile); // Set unit map this.gridUnit[pUnit.X, pUnit.Y] = false; this.gridUnit[pUnit.nextX, pUnit.nextY] = true; // Calculate new rotation pUnit.rotationHead = rotationCalculator.calculateHumanMoveDirection(pUnit.X, pUnit.Y, pUnit.nextX, pUnit.nextY); pUnit.rotationBody = pUnit.rotationHead; pUnit.requiresUpdate = true; }
private void moveRoomUnit(roomUnit pUnit) { if (pUnit.Path.Count > 0) { shortenRoomUnitPath(pUnit); // Cut corners etc blisterMoleNode nextTile = pUnit.Path[0]; bool nextTileNoRoomUnit = !this.gridUnit[nextTile.X, nextTile.Y]; bool nextTileExists = this.tileExists(nextTile.X, nextTile.Y); if (pUnit.allowOverideNextTile || (nextTileNoRoomUnit && nextTileExists && this.gridState[nextTile.X, nextTile.Y] == roomTileState.Free)) { moveRoomUnitToTile(pUnit, ref nextTile); pUnit.allowOverideNextTile = false; return; } else { bool workInteractiveTile = false; if (this.gridState[pUnit.goalX, pUnit.goalY] == roomTileState.Interactive) { if (!this.gridUnit[pUnit.goalX, pUnit.goalY]) { this.gridState[pUnit.goalX, pUnit.goalY] = roomTileState.Free; workInteractiveTile = true; } } List <blisterMoleNode> Path = this.findShortestPath(pUnit.X, pUnit.Y, pUnit.goalX, pUnit.goalY); if (workInteractiveTile) { this.gridState[pUnit.goalX, pUnit.goalY] = roomTileState.Interactive; } if (Path.Count > 0) { nextTile = Path[0]; if (!this.gridUnit[nextTile.X, nextTile.Y] && tileExists(nextTile.X, nextTile.Y)) { pUnit.Path = Path; moveRoomUnitToTile(pUnit, ref nextTile); return; } } } } else { bool workInteractiveTile = false; if (this.gridState[pUnit.goalX, pUnit.goalY] == roomTileState.Interactive) { if (!this.gridUnit[pUnit.goalX, pUnit.goalY]) { this.gridState[pUnit.goalX, pUnit.goalY] = roomTileState.Free; workInteractiveTile = true; } } List <blisterMoleNode> Path = this.findShortestPath(pUnit.X, pUnit.Y, pUnit.goalX, pUnit.goalY); if (workInteractiveTile) { this.gridState[pUnit.goalX, pUnit.goalY] = roomTileState.Interactive; } if (Path.Count > 0) { pUnit.Path = Path; unsetRoomUnitTileState(pUnit); moveRoomUnit(pUnit); return; } setRoomUnitTileState(pUnit); } // Stop moving pUnit.Moves = false; pUnit.nextX = 0; pUnit.nextY = 0; pUnit.nextZ = 0; pUnit.requiresUpdate = false; }
public void animateTalkingUnit(roomUnit pUnit, ref string Text, bool applyEmotes) { string[] Words = Text.Split(' '); string Gesture = null; if (applyEmotes) { foreach (string Word in Words) { if (Gesture != null) { break; } switch (Word.ToLower()) { case ":)": case ":-)": case ":d": case ":-d": case ":p": case ":-p": case ";)": case ";-)": Gesture = "sml"; break; case ":o": Gesture = "srp"; break; case ":s": case ":-s": case ":(": case ":-(": case ":'(": case ":'-(": Gesture = "sad"; break; case ":@": case ">:(": case ">:-(": Gesture = "agr"; break; } } } int wordAmount = Words.Length; if (Gesture != null) { pUnit.addStatus("gest", "gest", Gesture, 5, null, 0, 0); if (wordAmount == 1) // Only word is the gesture emote { return; } } int speakSecs = 1; if (wordAmount > 1) { speakSecs = wordAmount / 2; } else if (wordAmount > 5) { speakSecs = 5; } pUnit.addStatus("talk", "talk", null, speakSecs, null, 0, 0); }
private void runRollers() { if (mRollerTimer > DateTime.Now.TimeOfDay.TotalSeconds && mRollerDay == DateTime.Today.DayOfYear) { return; } StringBuilder Updates = new StringBuilder(); List <int> movedRoomUnitIDs = new List <int>(); List <int> movedItemIDs = new List <int>(); try { foreach (floorItem lRoller in this.floorItems) { if (!lRoller.Definition.Behaviour.isRoller) { continue; // Not a roller item } #region General // Workout direction for roller byte nextX = lRoller.X; byte nextY = lRoller.Y; if (lRoller.Rotation == 0) { nextY--; } else if (lRoller.Rotation == 2) { nextX++; } else if (lRoller.Rotation == 4) { nextY++; } else if (lRoller.Rotation == 6) { nextX--; } if (!tileExists(nextX, nextY) || tileBlockedByRoomUnit(nextX, nextY)) { continue; // Can't roll off room map / on room unit } #endregion #region Get objects on current tile and verify roomUnit pUnit = this.getRoomUnitOnTile(lRoller.X, lRoller.Y); // Get room unit on this roller List <floorItem> pItems = new List <floorItem>(); foreach (floorItem lItem in this.getFloorItems(lRoller.X, lRoller.Y)) { if (!lItem.Definition.Behaviour.isRoller && !movedItemIDs.Contains(lItem.ID)) { pItems.Add(lItem); } } if (pUnit != null && (pUnit.Moves || movedRoomUnitIDs.Contains(pUnit.ID))) { pUnit = null; // Invalid room unit } if (pUnit == null && pItems.Count == 0) { continue; // No items on roller and no room unit aswell } #endregion // Get items on next tile and perform some checks bool nextTileIsRoller = false; bool canMoveItems = (this.gridState[nextX, nextY] == roomTileState.Free); bool canMoveUnit = canMoveItems; bool nextTileUnitInteractiveStance = false; foreach (floorItem lItem in this.getFloorItems(nextX, nextY)) { if (lItem.Definition.Behaviour.isRoller) { nextTileIsRoller = true; continue; } if (lItem.Definition.Behaviour.isSolid) { canMoveItems = false; canMoveUnit = false; if (lItem.Definition.Behaviour.isDoor) { if (lItem.customData == "O") // Door is open { canMoveUnit = true; // Can move unit in door } } } else if (pUnit != null && lItem.Definition.isInteractiveStance) { nextTileUnitInteractiveStance = true; if (!nextTileIsRoller) { canMoveUnit = true; } } } if (!canMoveItems) // Can't move items { if (!canMoveUnit) // Can't move unit aswell { continue; // Can't run this roller } pItems.Clear(); // Clear items to move } #region Generate notification and move objects serverMessage eventNotification = new serverMessage(230); // "Cf" eventNotification.appendWired(lRoller.X); eventNotification.appendWired(lRoller.Y); eventNotification.appendWired(nextX); eventNotification.appendWired(nextY); eventNotification.appendWired(pItems.Count); foreach (floorItem lItem in pItems) { float nextZ = lItem.Z; if (!nextTileIsRoller) { nextZ -= lRoller.Definition.topHeight; } eventNotification.appendWired(lItem.ID); eventNotification.appendClosedValue(stringFunctions.formatFloatForClient(lItem.Z)); eventNotification.appendClosedValue(stringFunctions.formatFloatForClient(nextZ)); lItem.X = nextX; lItem.Y = nextY; lItem.Z = nextZ; lItem.requiresUpdate = true; movedItemIDs.Add(lItem.ID); generateFloorMap(); } eventNotification.appendWired(lRoller.ID); if (pUnit != null) // Room unit lifting with roller { float nextZ = pUnit.Z; if (!nextTileIsRoller) { nextZ -= lRoller.Definition.topHeight; } pUnit.X = nextX; pUnit.Y = nextY; pUnit.Z = nextZ; pUnit.requiresUpdate = true; if (!nextTileIsRoller || nextTileUnitInteractiveStance) { this.setRoomUnitTileState(pUnit); } this.gridUnit[lRoller.X, lRoller.Y] = false; this.gridUnit[pUnit.X, pUnit.Y] = true; eventNotification.appendWired(2); eventNotification.appendWired(pUnit.ID); eventNotification.appendClosedValue(stringFunctions.formatFloatForClient(pUnit.Z)); eventNotification.appendClosedValue(stringFunctions.formatFloatForClient(nextZ)); movedRoomUnitIDs.Add(pUnit.ID); } #endregion Updates.Append(eventNotification.ToString()); } if (Updates.Length > 0) { this.sendMessage(Updates.ToString()); } this.mRollerTimer = DateTime.Now.TimeOfDay.TotalSeconds + rollerDelaySeconds; this.mRollerDay = DateTime.Today.DayOfYear; } catch (Exception ex) { Core.Logging.Log("Rollers in room instance of room " + this.roomID + " crashed, exception: " + ex.Message); this.hasRollers = false; } }