Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First Person Rendering without OpenGL #2141

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -37,4 +37,12 @@ public interface MutableComponentContainer extends ComponentContainer {
* @param component
*/
void saveComponent(Component component);

default void addOrSaveComponent(Component component) {
if (hasComponent(component.getClass())) {
saveComponent(component);
} else {
addComponent(component);
}
}
}
Expand Up @@ -19,35 +19,24 @@
import org.terasology.entitySystem.entity.lifecycleEvents.BeforeDeactivateComponent;
import org.terasology.entitySystem.event.ReceiveEvent;
import org.terasology.entitySystem.systems.BaseComponentSystem;
import org.terasology.entitySystem.systems.RegisterMode;
import org.terasology.entitySystem.systems.RegisterSystem;
import org.terasology.entitySystem.systems.UpdateSubscriberSystem;
import org.terasology.logic.characters.events.ChangeHeldItemRequest;
import org.terasology.logic.characters.events.HeldItemChangedEvent;
import org.terasology.logic.players.LocalPlayer;
import org.terasology.registry.In;
import org.terasology.rendering.logic.LightComponent;
import org.terasology.rendering.logic.LightFadeComponent;
import org.terasology.world.block.items.BlockItemComponent;

@RegisterSystem
public class CharacterHeldItemSystem extends BaseComponentSystem implements UpdateSubscriberSystem {
@In
private LocalPlayer localPlayer;
@RegisterSystem(RegisterMode.AUTHORITY)
public class CharacterHeldItemAuthoritySystem extends BaseComponentSystem {

@ReceiveEvent
public void onChangeHeldItemRequest(ChangeHeldItemRequest event, EntityRef character,
CharacterHeldItemComponent characterHeldItemComponent) {
EntityRef oldItem = characterHeldItemComponent.selectedItem;
characterHeldItemComponent.selectedItem = event.getItem();
character.saveComponent(characterHeldItemComponent);
character.send(new HeldItemChangedEvent(oldItem, event.getItem()));
updateLightFromItem(character, oldItem, event.getItem());
}

@ReceiveEvent(components = CharacterComponent.class)
public void onHeldItemChanged(HeldItemChangedEvent event, EntityRef entity) {
updateLightFromItem(entity, event.getOldItem(), event.getNewItem());
}

@ReceiveEvent
public void onBlockItemDestroyedRemoveLight(BeforeDeactivateComponent event, EntityRef item, BlockItemComponent blockItemComponent) {
if (blockItemComponent.blockFamily == null || blockItemComponent.blockFamily.getArchetypeBlock().getLuminance() == 0) {
Expand Down Expand Up @@ -119,18 +108,4 @@ private byte getLuminance(EntityRef item) {
}
return 0;
}


@Override
public void update(float delta) {
if (!localPlayer.isValid()) {
return;
}

EntityRef characterEntity = localPlayer.getCharacterEntity();

// Hand animation update
CharacterHeldItemComponent characterHeldItemComponent = characterEntity.getComponent(CharacterHeldItemComponent.class);
characterHeldItemComponent.handAnimation = Math.max(0, characterHeldItemComponent.handAnimation - 2.5f * delta);
}
}
Expand Up @@ -24,5 +24,9 @@ public class CharacterHeldItemComponent implements Component {
@Replicate
public EntityRef selectedItem = EntityRef.NULL;

public float handAnimation;
@Replicate
public long lastItemUsedTime;

@Replicate
public long nextItemUseTime;
}
Expand Up @@ -20,6 +20,7 @@
import org.terasology.entitySystem.entity.EntityRef;
import org.terasology.entitySystem.event.ReceiveEvent;
import org.terasology.entitySystem.systems.BaseComponentSystem;
import org.terasology.entitySystem.systems.RegisterMode;
import org.terasology.entitySystem.systems.RegisterSystem;
import org.terasology.input.binds.interaction.AttackButton;
import org.terasology.input.binds.inventory.DropItemButton;
Expand Down Expand Up @@ -56,15 +57,15 @@ public class CharacterInventorySystem extends BaseComponentSystem {
private long lastInteraction;
private long lastTimeThrowInteraction;

@ReceiveEvent
@ReceiveEvent(netFilter = RegisterMode.AUTHORITY)
public void syncSelectedSlotWithHeldItem(InventorySlotChangedEvent event, EntityRef entityRef,
SelectedInventorySlotComponent selectedInventorySlotComponent) {
if (selectedInventorySlotComponent.slot == event.getSlot()) {
entityRef.send(new ChangeHeldItemRequest(event.getNewItem()));
}
}

@ReceiveEvent
@ReceiveEvent(netFilter = RegisterMode.AUTHORITY)
public void onChangeSelectedInventorySlotRequested(ChangeSelectedInventorySlotRequest request, EntityRef character, SelectedInventorySlotComponent selectedInventorySlotComponent) {
if (request.getSlot() >= 0 && request.getSlot() < 10 && request.getSlot() != selectedInventorySlotComponent.slot) {
EntityRef newItem = InventoryUtils.getItemAt(character, request.getSlot());
Expand All @@ -74,45 +75,53 @@ public void onChangeSelectedInventorySlotRequested(ChangeSelectedInventorySlotRe
}
}

@ReceiveEvent(components = {CharacterComponent.class})
@ReceiveEvent(components = {CharacterComponent.class}, netFilter = RegisterMode.CLIENT)
public void onNextItem(ToolbarNextButton event, EntityRef entity, SelectedInventorySlotComponent selectedInventorySlotComponent) {
int nextSlot = (selectedInventorySlotComponent.slot + 1) % 10;
localPlayer.getCharacterEntity().send(new ChangeSelectedInventorySlotRequest(nextSlot));
event.consume();
}

@ReceiveEvent(components = {CharacterComponent.class})
@ReceiveEvent(components = {CharacterComponent.class}, netFilter = RegisterMode.CLIENT)
public void onPrevItem(ToolbarPrevButton event, EntityRef entity, SelectedInventorySlotComponent selectedInventorySlotComponent) {
int prevSlot = (selectedInventorySlotComponent.slot + 9) % 10;
localPlayer.getCharacterEntity().send(new ChangeSelectedInventorySlotRequest(prevSlot));
event.consume();
}

@ReceiveEvent(components = {CharacterComponent.class})
@ReceiveEvent(components = {CharacterComponent.class}, netFilter = RegisterMode.CLIENT)
public void onSlotButton(ToolbarSlotButton event, EntityRef entity) {
localPlayer.getCharacterEntity().send(new ChangeSelectedInventorySlotRequest(event.getSlot()));
event.consume();
}


@ReceiveEvent(components = {CharacterComponent.class, InventoryComponent.class})
public void onAttackRequest(AttackButton event, EntityRef entity) {
if (!event.isDown() || time.getGameTimeInMs() - lastInteraction < 200) {
@ReceiveEvent(components = {CharacterComponent.class, InventoryComponent.class}, netFilter = RegisterMode.CLIENT)
public void onAttackRequest(AttackButton event, EntityRef entity, CharacterHeldItemComponent characterHeldItemComponent) {
if (!event.isDown() || time.getGameTimeInMs() < characterHeldItemComponent.nextItemUseTime) {
return;
}

CharacterHeldItemComponent characterHeldItemComponent = entity.getComponent(CharacterHeldItemComponent.class);
EntityRef selectedItemEntity = characterHeldItemComponent.selectedItem;

entity.send(new AttackRequest(selectedItemEntity));

lastInteraction = time.getGameTimeInMs();
characterHeldItemComponent.handAnimation = 0.5f;
long currentTime = time.getGameTimeInMs();
// TODO: send this data back to the server so that other players can visualize this attack
// TODO: extract this into an event someplace so that this code does not have to exist both here and in LocalPlayerSystem
characterHeldItemComponent.lastItemUsedTime = currentTime;
characterHeldItemComponent.nextItemUseTime = currentTime;
ItemComponent itemComponent = selectedItemEntity.getComponent(ItemComponent.class);
if (itemComponent != null) {
characterHeldItemComponent.nextItemUseTime += itemComponent.cooldownTime;
} else {
characterHeldItemComponent.nextItemUseTime += 200;
}
entity.saveComponent(characterHeldItemComponent);
event.consume();
}

@ReceiveEvent(components = {CharacterComponent.class, InventoryComponent.class})
@ReceiveEvent(components = {CharacterComponent.class, InventoryComponent.class}, netFilter = RegisterMode.CLIENT)
public void onDropItemRequest(DropItemButton event, EntityRef entity) {
CharacterHeldItemComponent characterHeldItemComponent = entity.getComponent(CharacterHeldItemComponent.class);
EntityRef selectedItemEntity = characterHeldItemComponent.selectedItem;
Expand Down Expand Up @@ -155,15 +164,13 @@ public void onDropItemRequest(DropItemButton event, EntityRef entity) {
impulseVector,
newPosition));

characterHeldItemComponent.handAnimation = 0.5f;
characterHeldItemComponent.lastItemUsedTime = time.getGameTimeInMs();
entity.saveComponent(characterHeldItemComponent);

resetDropMark();
}

entity.saveComponent(characterHeldItemComponent);
event.consume();


}

public void resetDropMark() {
Expand Down
@@ -0,0 +1,126 @@
/*
* Copyright 2013 MovingBlocks
*
* 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 org.terasology.logic.inventory;

import org.terasology.asset.Assets;
import org.terasology.entitySystem.MutableComponentContainer;
import org.terasology.entitySystem.entity.EntityRef;
import org.terasology.entitySystem.entity.lifecycleEvents.OnActivatedComponent;
import org.terasology.entitySystem.entity.lifecycleEvents.OnChangedComponent;
import org.terasology.entitySystem.event.EventPriority;
import org.terasology.entitySystem.event.ReceiveEvent;
import org.terasology.entitySystem.systems.BaseComponentSystem;
import org.terasology.entitySystem.systems.RegisterMode;
import org.terasology.entitySystem.systems.RegisterSystem;
import org.terasology.logic.common.ActivateEvent;
import org.terasology.math.geom.Vector3f;
import org.terasology.registry.In;
import org.terasology.rendering.iconmesh.IconMeshFactory;
import org.terasology.rendering.logic.LightComponent;
import org.terasology.rendering.logic.MeshComponent;
import org.terasology.utilities.random.FastRandom;
import org.terasology.utilities.random.Random;
import org.terasology.world.block.family.BlockFamily;
import org.terasology.world.block.items.BlockItemComponent;

@RegisterSystem(RegisterMode.AUTHORITY)
public class ItemAuthoritySystem extends BaseComponentSystem {
@In
private InventoryManager inventoryManager;

private static Random rand = new FastRandom();

@ReceiveEvent(components = ItemComponent.class, priority = EventPriority.PRIORITY_TRIVIAL)
public void usedItem(ActivateEvent event, EntityRef item) {
ItemComponent itemComp = item.getComponent(ItemComponent.class);
if (itemComp.consumedOnUse) {
int slot = InventoryUtils.getSlotWithItem(event.getInstigator(), item);
inventoryManager.removeItem(event.getInstigator(), event.getInstigator(), slot, true, 1);
}
}

@ReceiveEvent
public void onRenderItemIconMeshActivated(OnActivatedComponent event, EntityRef item, RenderItemIconMeshComponent renderItemIconMeshComponent, ItemComponent itemComponent) {
addOrUpdateItemMeshComponent(itemComponent, item);
}

@ReceiveEvent
public void onRenderItemIconMeshChanged(OnChangedComponent event, EntityRef item, RenderItemIconMeshComponent renderItemIconMeshComponent, ItemComponent itemComponent) {
addOrUpdateItemMeshComponent(itemComponent, item);
}

@ReceiveEvent
public void onRenderItemBlockMeshActivated(OnActivatedComponent event, EntityRef item,
RenderItemBlockMeshComponent renderItemBlockMeshComponent,
BlockItemComponent blockItemComponent,
ItemComponent itemComponent) {
addOrUpdateBlockMeshComponent(blockItemComponent, item);
}

@ReceiveEvent
public void onRenderItemBlockMeshChanged(OnChangedComponent event, EntityRef item,
RenderItemBlockMeshComponent renderItemBlockMeshComponent,
BlockItemComponent blockItemComponent,
ItemComponent itemComponent) {
addOrUpdateBlockMeshComponent(blockItemComponent, item);
}

public static void addOrUpdateItemMeshComponent(ItemComponent itemComponent, MutableComponentContainer entity) {
if (itemComponent != null) {
MeshComponent meshComponent = null;
if (entity.hasComponent(MeshComponent.class)) {
meshComponent = entity.getComponent(MeshComponent.class);
} else {
meshComponent = new MeshComponent();
}
meshComponent.material = Assets.getMaterial("engine:droppedItem").get();
if (itemComponent.icon != null) {
meshComponent.mesh = IconMeshFactory.getIconMesh(itemComponent.icon);
}
entity.addOrSaveComponent(meshComponent);
}
}

public static void addOrUpdateBlockMeshComponent(BlockItemComponent blockItemComponent, MutableComponentContainer entity) {
if (blockItemComponent != null) {
MeshComponent meshComponent = null;
if (entity.hasComponent(MeshComponent.class)) {
meshComponent = entity.getComponent(MeshComponent.class);
} else {
meshComponent = new MeshComponent();
}
BlockFamily blockFamily = blockItemComponent.blockFamily;

if (blockFamily == null) {
return;
}

meshComponent.mesh = blockFamily.getArchetypeBlock().getMeshGenerator().getStandaloneMesh();
meshComponent.material = Assets.getMaterial("engine:terrain").get();

if (blockFamily.getArchetypeBlock().getLuminance() > 0 && !entity.hasComponent(LightComponent.class)) {
LightComponent lightComponent = entity.addComponent(new LightComponent());

Vector3f randColor = new Vector3f(rand.nextFloat(), rand.nextFloat(), rand.nextFloat());
lightComponent.lightColorDiffuse.set(randColor);
lightComponent.lightColorAmbient.set(randColor);
}

entity.addOrSaveComponent(meshComponent);
}
}
}
Expand Up @@ -27,12 +27,6 @@
*
*/
public final class ItemComponent implements Component {
/**
* Should this item be rendered? Some items have an inventory icon but no "held" representation
*/
@Replicate(value = FieldReplicateType.SERVER_TO_CLIENT, initialOnly = true)
public boolean renderWithIcon;

/**
* Name of the icon this item should be rendered with
*/
Expand Down Expand Up @@ -85,4 +79,5 @@ public enum UsageType {

public Prefab pickupPrefab;

public int cooldownTime = 200;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prevents prefabs that do not specify a cooldown to get a better value than "machine gun"

}