package electrosphere.menu; import java.util.LinkedList; import java.util.List; import org.joml.Quaternionf; import org.joml.Vector3f; import electrosphere.engine.Globals; import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.entity.types.creature.CreatureTemplate; import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.visualattribute.AttributeVariant; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.net.parser.net.message.CharacterMessage; import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorStaticMorph; import electrosphere.renderer.actor.ActorUtils; import electrosphere.renderer.actor.ActorStaticMorph.StaticMorphTransforms; import electrosphere.renderer.anim.Animation; import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.ClickableElement; import electrosphere.renderer.ui.Element; import electrosphere.renderer.ui.ValueElement.ValueChangeEventCallback; import electrosphere.renderer.ui.elements.ActorPanel; import electrosphere.renderer.ui.elements.Button; import electrosphere.renderer.ui.elements.ImagePanel; import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.ScrollableContainer; import electrosphere.renderer.ui.elements.Slider; import electrosphere.renderer.ui.elements.StringCarousel; import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.ValueChangeEvent; import electrosphere.renderer.ui.form.FormElement; import electrosphere.util.Utilities; public class MenuGeneratorsMultiplayer { public static Element createMultiplayerCharacterSelectionWindow(){ FormElement rVal = new FormElement(); // int screenTop = Globals.WINDOW_HEIGHT - 150; int verticalPosition = 125; //button (create) Button createButton = new Button(); Label createLabel = new Label(100,125 + verticalPosition + 200,1.0f); createLabel.setText("Create Character"); createButton.addChild(createLabel); rVal.addChild(createButton); createButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldCreationMenu()); return false; }}); return rVal; } static String selectedRace = ""; public static Element createMultiplayerCharacterCreationWindow(){ FormElement rVal = new FormElement(); // int screenTop = Globals.WINDOW_HEIGHT - 150; int verticalPosition = 125; //select race StringCarousel raceCarousel = new StringCarousel(100, 125, 1.0f); raceCarousel.setOnValueChangeCallback(new ValueChangeEventCallback() {public void execute(ValueChangeEvent event){ selectedRace = event.getAsString(); }}); for(String raceName : Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces()){ raceCarousel.addOption(raceName); } rVal.addChild(raceCarousel); //button (create) Button createButton = new Button(); Label createLabel = new Label(100,275,1.0f); createLabel.setText("Select Race"); createButton.addChild(createLabel); rVal.addChild(createButton); createButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ WindowUtils.replaceMainMenuContents(MenuGeneratorsMultiplayer.createMultiplayerCharacterCreationTweakWindow(selectedRace)); return false; }}); return rVal; } public static Element createMultiplayerCharacterCreationTweakWindow(String race){ // int screenTop = Globals.WINDOW_HEIGHT - 150; int verticalPosition = 125; int horizontalPosition = 300; //figure out race data CreatureType selectedRaceType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(race); //spawn camera so renderer doesn't crash (once render pipeline is modularized this shouldn't be necessary) Globals.playerCamera = CameraEntityUtils.spawnBasicCameraEntity(new Vector3f(0,0,0), new Vector3f(0,0.3f,1).normalize()); Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera); // CameraEntityUtils.setCameraEye(Globals.playerCamera, new Vector3f(-1,3f,0).normalize()); // CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f(0,0,0)); //create actor panel Actor characterActor = ActorUtils.createActorFromModelPath(selectedRaceType.getModelPath()); ActorPanel actorPanel = new ActorPanel(1200, 100, 500, 500, characterActor); actorPanel.setAnimation(Animation.ANIMATION_IDLE_1); actorPanel.setPosition(new Vector3f(0,-0.5f,-0.6f)); // actorPanel.setRotation(new Quaternionf().rotateLocalY(0)); actorPanel.setScale(new Vector3f(1.0f)); //have to build static morph while looping through attributes ActorStaticMorph staticMorph = new ActorStaticMorph(); //create creature template CreatureTemplate template = new CreatureTemplate(race); List controlsToAdd = new LinkedList(); //create edit controls here for(VisualAttribute attribute : selectedRaceType.getVisualAttributes()){ if(attribute.getType().equals(VisualAttribute.TYPE_BONE)){ //add label for slider Label sliderName = new Label(20, verticalPosition, 0.6f); sliderName.setText(attribute.getAttributeId()); controlsToAdd.add(sliderName); //add a slider Slider boneSlider = new Slider(horizontalPosition, verticalPosition + 10, 500, 20, new Vector3f(0.1f,0.1f,0.1f), new Vector3f(1,1,1)); float min = attribute.getMinValue(); float max = attribute.getMaxValue(); float defaultValue = min + (max - min)/2.0f; boneSlider.setMinimum(min); boneSlider.setMaximum(max); boneSlider.setValue(defaultValue); controlsToAdd.add(boneSlider); //actually add attributes to static morph if(attribute.getPrimaryBone() != null && staticMorph.getBoneTransforms(attribute.getPrimaryBone()) == null){ staticMorph.initBoneTransforms(attribute.getPrimaryBone()); } if(attribute.getMirrorBone() != null && staticMorph.getBoneTransforms(attribute.getMirrorBone()) == null){ staticMorph.initBoneTransforms(attribute.getMirrorBone()); } //add attribute to creature template template.putValue(attribute.getAttributeId(), defaultValue); //set callback for when we change the slider value to update the static morph boneSlider.setOnValueChangeCallback(new ValueChangeEventCallback() {public void execute(ValueChangeEvent event) { if(characterActor.getStaticMorph() != null){ ActorStaticMorph staticMorph = characterActor.getStaticMorph(); staticMorph.updateValue(attribute.getSubtype(), attribute.getPrimaryBone(), event.getAsFloat()); if(attribute.getMirrorBone() != null){ staticMorph.updateValue(attribute.getSubtype(), attribute.getMirrorBone(), event.getAsFloat()); } template.getValue(attribute.getAttributeId()).setValue(event.getAsFloat()); } }}); } else if(attribute.getType().equals(VisualAttribute.TYPE_REMESH)){ //add label for carousel Label sliderName = new Label(20, verticalPosition, 0.6f); sliderName.setText(attribute.getAttributeId()); controlsToAdd.add(sliderName); //for adding the value to the creature template boolean hasAddedValue = false; //add a carousel StringCarousel variantCarousel = new StringCarousel(horizontalPosition, verticalPosition, 1.0f); for(AttributeVariant variant : attribute.getVariants()){ variantCarousel.addOption(variant.getId()); //if we haven't already added a value, add a value to the creature template if(!hasAddedValue){ hasAddedValue = true; //add attribute to template template.putValue(attribute.getAttributeId(), variant.getId()); } } //callback for updating remesh variantCarousel.setOnValueChangeCallback(new ValueChangeEventCallback(){public void execute(ValueChangeEvent event) { //TODO: implement updating visuals template.getValue(attribute.getAttributeId()).setVariantId(event.getAsString()); AttributeVariant variant = null; for(AttributeVariant variantCurrent : attribute.getVariants()){ if(variantCurrent.getId().equals(event.getAsString())){ variant = variantCurrent; break; } } if(variant != null){ Globals.assetManager.addModelPathToQueue(variant.getModel()); for(String mesh : variant.getMeshes()){ characterActor.getMeshMask().queueMesh(variant.getModel(), mesh); } } }}); controlsToAdd.add(variantCarousel); } verticalPosition = verticalPosition + 100; } //finally set static morph characterActor.setActorStaticMorph(staticMorph); //add button to actually create the character Button createCharacterButton = new Button(); Label createCharacterLabel = new Label(horizontalPosition,verticalPosition,1.0f); createCharacterLabel.setText("Create"); createCharacterButton.addChild(createCharacterLabel); controlsToAdd.add(createCharacterButton); createCharacterButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestCreateCharacterMessage(Utilities.stringify(template))); return false; }}); int width = 1800; int height = verticalPosition + 300; ScrollableContainer scrollable = new ScrollableContainer(0, 0, width, height); for(Element newControl : controlsToAdd){ scrollable.addChild(newControl); } scrollable.addChild(actorPanel); // rVal.addChild(scrollable); // Label testLabel = new Label(100,215,1.0f); // testLabel.setText("Aaaaaaa"); // rVal.addChild(testLabel); // //black texture background // ImagePanel imagePanel = new ImagePanel(0,0,width,height + 1000,Globals.blackTexture); // scrollable.addChild(imagePanel); return scrollable; } }