/* * Copyright 2010, Maarten Billemont * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.lyndir.omicron.api; import com.lyndir.lhunath.opal.system.util.MetaObject; import java.util.Objects; import java.util.stream.Stream; import javax.annotation.Nonnull; import javax.annotation.Nullable; /** * @author lhunath, 2013-08-02 */ public abstract class PublicModuleType<M extends IModule> extends MetaObject { /** * Makes a unit destructible and gives it the ability to observe its surroundings. */ public static final PublicModuleType<IBaseModule> BASE = // new PublicModuleType<IBaseModule>( IBaseModule.class, ResourceCost.immutableOf( ResourceType.METALS, 1 ) ) {}; /** * Gives the unit the ability to move around. */ public static final PublicModuleType<IMobilityModule> MOBILITY = // new PublicModuleType<IMobilityModule>( IMobilityModule.class, ResourceCost.immutableOf( ResourceType.METALS, 1 ) ) {}; /** * Provides the unit with resource storage. */ public static final PublicModuleType<IContainerModule> CONTAINER = // new PublicModuleType<IContainerModule>( IContainerModule.class, ResourceCost.immutableOf( ResourceType.METALS, 1 ) ) {}; /** * Adds the provisions for extracting resources to the unit. */ public static final PublicModuleType<IExtractorModule> EXTRACTOR = // new PublicModuleType<IExtractorModule>( IExtractorModule.class, ResourceCost.immutableOf( ResourceType.METALS, 1 ) ) {}; /** * Teaches the unit how to construct other units. */ public static final PublicModuleType<IConstructorModule> CONSTRUCTOR = // new PublicModuleType<IConstructorModule>( IConstructorModule.class, ResourceCost.immutableOf( ResourceType.METALS, 2 ) ) {}; /** * Installs a weapon system on the unit, allowing it to inflict damage onto other units. */ public static final PublicModuleType<IWeaponModule> WEAPON = // new PublicModuleType<IWeaponModule>( IWeaponModule.class, ResourceCost.immutableOf( ResourceType.METALS, 2 ) ) {}; private final Class<M> moduleType; private final ImmutableResourceCost standardCost; PublicModuleType(@Nonnull final Class<M> moduleType, @Nonnull final ImmutableResourceCost standardCost) { this.moduleType = moduleType; this.standardCost = standardCost; } @Nonnull public Class<M> getModuleType() { return moduleType; } @Nonnull public ImmutableResourceCost getStandardCost() { return standardCost; } @Override public int hashCode() { Class<?> moduleTypeInterface; if (moduleType.isInterface()) moduleTypeInterface = moduleType; else moduleTypeInterface = Stream.of(moduleType.getInterfaces()).filter( IModule.class::isAssignableFrom ).findFirst().get(); return Objects.hash( moduleTypeInterface, standardCost ); } @Override public boolean equals(@Nullable final Object obj) { if (this == obj) return true; if (!(obj instanceof PublicModuleType)) return false; PublicModuleType<?> o = (PublicModuleType<?>) obj; return moduleType.isAssignableFrom( o.moduleType ) || o.moduleType.isAssignableFrom( moduleType ) && standardCost.equals( o.standardCost ); } }