001/* 002 * Trident - A Multithreaded Server Alternative 003 * Copyright 2014 The TridentSDK Team 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package net.tridentsdk.server.data.block; 018 019import net.tridentsdk.base.Block; 020import net.tridentsdk.base.Position; 021import net.tridentsdk.base.Substance; 022import net.tridentsdk.entity.living.Player; 023import net.tridentsdk.entity.types.EntityType; 024import net.tridentsdk.meta.block.SignMeta; 025import net.tridentsdk.meta.block.Tile; 026import net.tridentsdk.meta.component.Meta; 027import net.tridentsdk.meta.component.MetaCollection; 028import net.tridentsdk.plugin.cmd.PlatformColor; 029import net.tridentsdk.server.packets.play.out.PacketPlayOutSignEditorOpen; 030import net.tridentsdk.server.packets.play.out.PacketPlayOutUpdateSign; 031import net.tridentsdk.server.player.TridentPlayer; 032import net.tridentsdk.server.util.OwnedTridentBlock; 033import net.tridentsdk.server.world.TridentWorld; 034 035import java.util.concurrent.atomic.AtomicReferenceArray; 036 037/** 038 * Implements sign meta 039 * 040 * @author The TridentSDK Team 041 */ 042public class SignMetaImpl implements SignMeta, Tile { 043 private volatile byte orientation; 044 private volatile Position position; 045 private final AtomicReferenceArray<String> stringAtomicReferenceArray = new AtomicReferenceArray<>(4); 046 047 @Override 048 public String textAt(int index) { 049 return stringAtomicReferenceArray.get(index); 050 } 051 052 @Override 053 public void setTextAt(int index, String text) { 054 stringAtomicReferenceArray.set(index, text); 055 position.world().entities().stream().filter(e -> e.type() == EntityType.PLAYER).forEach(p -> update((Player) p)); 056 } 057 058 private String[] toArray() { 059 String[] strings = new String[4]; 060 for (int i = 0; i < 4; i++) { 061 String s = stringAtomicReferenceArray.get(i); 062 if (s == null) { 063 setTextAt(i, s = PlatformColor.EMPTY); 064 } 065 066 strings[i] = s; 067 } 068 069 return strings; 070 } 071 072 @Override 073 public byte encode() { 074 // TODO handle illegal meta 075 ((TridentWorld) position.world()).tilesInternal().add(this); 076 return orientation; 077 } 078 079 @Override 080 public Meta<Block> decode(Block instance, float yaw, byte direction, byte cx, byte cy, byte cz, short damageValue) { 081 byte data = 0x00; 082 083 yaw = (yaw + 180.0f + 45.0f) % 360.0f; // +180 puts north at 360/0 - +45 puts north/west to 0 084 int orientation = (int)(yaw / 90.0f); 085 086 switch(orientation) { 087 case 0: 088 data |= 3; 089 break; 090 case 1: 091 data |= 4; 092 break; 093 case 2: 094 data |= 2; 095 break; 096 case 3: 097 data |= 5; 098 break; 099 } 100 101 instance.setSubstanceAndMeta(Substance.SIGN_POST, data); 102 103 orientation = data; 104 position = instance.position(); 105 ((OwnedTridentBlock) instance).player().connection().sendPacket(new PacketPlayOutSignEditorOpen().set("loc", position)); 106 return this; 107 } 108 109 @Override 110 public Meta<Block> make() { 111 return new SignMetaImpl(); 112 } 113 114 @Override 115 public Substance[] applyTo(MetaCollection collection) { 116 collection.put(SignMeta.class, this); 117 return new Substance[] {Substance.SIGN}; // TODO wall signs 118 } 119 120 @Override 121 public void update(Player player) { 122 ((TridentPlayer) player).connection().sendPacket(new PacketPlayOutUpdateSign().set("loc", position).set("messages", toArray())); 123 } 124}