새로운 엔티티(Entity)를 만들게 되면 Attribute를 다루게 됩니다. Attribute는 최대 체럭, 공격력, 이동 속도와 같은 엔티티(Entity)의 능력치를 말합니다. Attribute가 정확히 무엇인가하는 더욱 자세한 설명은 마인크래프트 위키에 잘 나와있습니다. http://minecraft.gamepedia.com/Attribute

 

이 강의에서는 기존의 Attribute를 다루고, 직접 새로운 Attribute를 정의하고 더 나아가서 코드로 그 값들을 수정하는 법을 배울 것입니다.

 

Attribute 만들기

1단계

새로운 Attribute를 만들기 위해 가장 먼저 해야 할 일은 IAttribute 객체를 만드는 것입니다. 인터페이스(Interface) 객체를 만들어야 한다고 해서 IAttribute를 상속하는 클래스(Class)를 만들 필요는 없습니다. 이미 마인크래프트(Minecraft)에서 기존의 모든 Attribute에 적용되고 있는 RangedAttribute라는 클래스(Class)를 제공하기 때문입니다. 생성자는 다음과 같은 인자를 가지고 있습니다.

 

RangedAttribute(IAttribute p_i45891_1_, String p_i45891_2_, double p_i45891_3_, double p_i45891_5_, double p_i45891_7_)

IAttribute
p_i45891_1 :
정확한
기능을 파악할 없습니다. 모든 Attribute에서 "(IAttribute)null" 지정합니다.
String p_i45891_2_ : Attribute
이름입니다. 이름은 같은 Attribute 같은 엔티티(Entity)에게 2 이상 지정하지 못합니다. 그렇기 때문에 모드 아이디(Mod ID) 이용해서 구분하는 것이 바람직합니다. SoundBody.MOD_ID + ".digspeed"」와 같은 형식입니다.
double p_i45891_3_ : Attribute의 기본값입니다. 엔티티(Entity)가 처음 생성될 때, 기본 값으로 이 Attribute에 대입됩니다. 최소값, 최대값의 범위를 벗어날 수 없습니다. 만약 벗어난다면 IllegalArgumentException을 발생시킵니다.
double p_i45891_5_ : Attribute의 최소값입니다. 대부분 0.0D의 값을 가지고 있습니다. 최소값이기 때문에 실제 Attribute 값은 이 이하로 내려가지 않습니다. 이 값 자체가 최대값보다 커진다면 IllegalArgumentException을 발생시킵니다.
double p_i45891_7_ : Attribute의 최대값입니다. 대부분 Double.MAX_VALUE의 값을 가지고 있습니다. 최대값이기 때문에 실제 Attribute 값은 이보다 커질 수 없습니다. 이 값 자체가 최소값보다 작아진다면 IllegalArgumentException을 발생시킵니다.

 

Attribute를 만드는 것은 크게 어렵지 않습니다.

public static IAttribute digspeedFactor = new RangedAttribute((IAttribute)null, Strings.attribute_digspeedfactor_name, 1.0, 0.0, Double.MAX_VALUE);

 

하지만 이게 끝은 아닙니다. 만약 Attribute가 클라이언트(Client)와 동기화가 되어야 한다면 setShouldWatch()를 true로 설정해야만 합니다. false로 한다면 당연히 동기화 기능을 끌 수 있습니다. 이 함수는 값이 변경된 객체를 다시 반환하기 때문에 다음과 같이 코드를 작성할 수 있습니다.

public static IAttribute digspeedFactor = new RangedAttribute((IAttribute)null, Strings.attribute_digspeedfactor_name, 1.0, 0.0, Double.MAX_VALUE).setShouldWatch(true);

 

 

2단계

열심히 Attribute를 만들었지만 사실 엔티티(Entity)는 그런 Attribute가 있다는 사실조차 알지 못합니다. 그렇기 때문에 Attribute를 반드시 등록해야 합니다. 등록하는 시기는 엔티티(Entity) 클래스(Class)에서 applyEntityAttributes() 함수가 호출될 때입니다. 간단히 override하시면 됩니다. 그리고 this.getAttributeMap().registerAttribute(MY_OWN_ATTRIBUTE)을 호출하세요. 물론 「MY_OWN_ATTRIBUTE」는 그저 예시일 뿐입니다. 1단계에서 만든 Attribute를 등록하시면 될 겁니다.

@Override

protected void applyEntityAttributes() {

super.applyEntityAttributes(); // 상위 함수를 호출하지 않으면 체력이나 이동속도와 같은 기본적인 Attribute가 등록되지 않을 것입니다.

this.getAttributeMap().registerAttribute(TurretAttributes.MAX_AMMO_CAPACITY);

}

 

 

3단계

Attribute를 만들고 등록까지 마쳤지만 아직 쓰임은 없습니다. 이 값을 가져오기는 상당히 간단합니다. this.getEntityAttribute(MY_OWN_ATTRIBUTE).getAttributeValue()를 호출하시면 값을 가져올 수 있습니다.

 

 

 

Modifier 만들기

이제 Attribute 값을 수정만 하면 필요한 기능을 구현할 수 있을 것입니다.

1. 기본값 변경하기

이 방법은 직접적으로 값을 변경하기 때문에 간단합니다. 최대 체력을 직접 지정해주거나 할 때 많이 사용되는 방법입니다. 다음의 코드를 참고하세요.

this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(40.0D); // 엔티티(Entity)의 최대 체력을 40(하트 반 칸)으로 지정합니다.

이 방법은 클라이언트(Client)와 자동으로 동기화되지 않습니다. 동기화 하려면 수동적으로 패킷(Packet)을 보내서 하셔야 합니다.

 

 

2. Attribute에 Modifier 추가하기

이 방법은 Attribute를 바꾸고 나서 언제든지 원래 값으로 되돌릴 수 있는 '가역적'인 방법입니다. 우리가 추가하려는 것은 기본적으로 Attribute Modifier이고 역시 위키에 잘 설명되어 있습니다. http://minecraft.gamepedia.com/Attribute#Modifiers

Attribute랑 비슷하게 객체를 만들어야 합니다. 이 경우에도 이미 AttributeModifier 클래스(Class)가 정의되어 있어 편리합니다. 생성자의 인자는 다음과 같습니다.

 

public AttributeModifier(UUID p_i1606_1_, String p_i1606_2_, double p_i1606_3_, int p_i1606_5_)

 

UUID p_i1606_1_ : UUID입니다. 그렇기 때문에 Modifier마다 유일해야 합니다. Attribute에서 이름(name)에 해당하는 값인 것이죠. https://www.uuidgenerator.net/ 에서 UUID를 생성할 수 있습니다. 그냥 이렇게 생성해도 겹칠 일은 거의 없습니다. 이게 UUID 클래스(Class) 의 편리함입니다. UUID.fromString()를 이용하면 사전에 생성 해 놓은 문자열로부터 UUID를 얻을 수 있습니다. UUID.fromString("e6107045-134f-4c54-a645-75c3ae5c7a27")」이런 식 입니다.
String p_i1606_2_ : Modifier 이름에 해당하는 인자입니다. 빈 문자열만 아니면 문제가 없습니다. 심지어 겹쳐도 됩니다. 어차피 식별에 사용되는 인자는 UUID이기 때문입니다.
double p_i1606_3_ : 얼마나 값을 변경할 것인지에 해당하는 인자입니다. Modifier를 통해서도 Attribute의 기본적인 최소, 최대값은 넘을 수 없으니 유의하셔야 합니다.
int p_i1606_5_ : Modifier의 연산자(Operation)입니다. 위키 내용을 참고하세요. 간단하게 설명하면 연산자(Operation)는 어떻게 값이 변경되는지를 결정하는 요소입니다. Attribute에 값을 더할 건지, 곱할 건지를 지정하는 것입니다.

연산자(Operation) 0: X를 만큼 더합니다. 연산자(Operation) 1: Y가 "X*"만큼 증가합니다. 연산자(Operation) 2: Y=Y*(1+). 처음 "X=기본값"으로 대입됩니다. 그 후 연산자(Operation) 0이 실행이 되고 "Y=X"로 대입됩니다. 이후 연산자(Operation) 1이, 마지막으로 연산자(Operation) 2가 적용됩니다.

 

이제 모든 인자를 알아보았으니 객체를 생성해 보겠습니다.

MY_CUSTOM_MODIFIER = new AttributeModifier(UUID.fromString("e6107045-134f-4c54-a645-75c3ae5c7a27"), "myCustomModifier420BlazeIt", 0.360D, EnumAttrModifierOperation.ADD_PERC_VAL_TO_SUM.ordinal());

이제 객체도 만들었으니 어떻게 적용하고 해제하는지 확인 해보겠습니다.

entity.getEntityAttribute(MY_ATTRIBUTE_INSTANCE).applyModifier(MY_CUSTOM_MODIFIER);
entity.getEntityAttribute(MY_ATTRIBUTE_INSTANCE).removeModifier(MY_CUSTOM_MODIFIER);

 

 

 

Attribute는 자동으로 저장되고 불러와집니다. 따라서 수동적으로 해당 작업을 해주실 필요는 없습니다. 다만 클라이언트(Client)와 동기화만 조금 신경 써 주시면 됩니다.

 

 

 

 

참고자료:

http://www.minecraftforge.net/forum/index.php/topic,30137.msg156378.html

위의 자료에서 강의 구성, 샘플 코드 등을 참고 했습니다. 사실상 거의 번역본입니다.

'마인크래프트 모딩 > 강의' 카테고리의 다른 글

아이템 스택(Item Stack)  (2) 2015.10.05
[모딩] 포션 추가  (0) 2015.08.15
5. AI  (5) 2015.02.06
4. 포션 추가(번역)  (0) 2015.02.05
3.동물을 추가해보자 (EntityAnimal)  (0) 2015.02.05

+ Recent posts