• 0

    posted a message on [Trigger] How to Target with Mouselook (Tracelines)

    @Kanaru: Go

    Turn on both mouselook flags, make a tiny region at your unit and set your camera's unit bounds to that region every 0.0 seconds.

    Posted in: Tutorials
  • 0

    posted a message on [Trigger] How to Target with Mouselook (Tracelines)

    @sherardt: Go

    Well the traceline will tell you what is in front of you right now, that's the point. So you don't need to take into account "What if the unit moves?" because you should be dealing damage to the unit you get from the traceline instantly. If you wanted to apply the same logic to projectiles, you could do the same thing except change the loop to take one step every 0.0 game seconds and update the position of a projectile with each iteration. That way, you actually have a moving projectile that will check for collision at every step.

    However, if you're coding a physics library this wouldn't be the way to go. You will want to treat a missile like any other object. Give it a starting location of the user's viewpoint and a 0 vector: [0, 0, 0]. Then, apply a force of great magnitude to the object in the direction the unit is facing, which should change the object's directional vector to something like [1.0, 1.0, 0.0] meaning it moves +1.0 east, +1.0 north per iteration (Every 0.0 game seconds). At every iteration you should also apply the forces of gravity, wind resistance and friction to slow the projectile down and create the arc that brings every object that goes up back to the ground.

    Posted in: Tutorials
  • 0

    posted a message on [Trigger] How to Target with Mouselook (Tracelines)

    Thanks for the positive feedback, guys. :)

    Quote from doos101: Go

    I honestly don't know how to impement this.

    Can you enlighten me about how to implement this? I'm trying to make it so that effect spawns on the position where my mouse clicks...

    Refer to the map...

    The traceline function is really only necessary for aiming at the middle of a player's camera view. As OneTwoSC said, you can achieve what you're trying to do much more simply by checking for "Point Clicked" events.

    Quote from malu05: Go

    Hey, great tut... Though' A thing about Camera position and camera height.

    How on earth are you going to the XY an Z position of the camera if you are not attached to a unit? When i do it i do it pased on the Pitch and camera distance, but since camera-distance is relative in this game it usually screw up my function.

    I'm not exactly sure because I haven't run into that scenario myself. The pitch and yaw would remain the same, but you'd have to calculate the position and height of the camera. I'd play with CameraGetTarget() and CameraInfoGetValue(x, c_cameraValueHeightOffset ).

    Quote from doos101: Go

    @OneTwoSC: Go

    K, I tried that it works, in fact I don't need the traceline. So what exactly is the point of the traceline?

    The traceline function is used for 3D aiming, like you'd see in a First Person Shooter. Since you can't just click on the ground you have to calculate what the player is aiming at in the middle of his screen, where the crosshairs are.

    Posted in: Tutorials
  • 0

    posted a message on Add XP via trigger

    @m0rte: Go

    Create a "grant experience" ability that grants the amount of XP you want. Then, cast that ability on unit from player with a trigger.

    Posted in: Miscellaneous Development
  • 0

    posted a message on 8 Way Movement
    Quote from BrotherLaz: Go

    rrowland: wow, and there I thought I was the first to implement the bitfield solution. Mine is followed by a switch statement though, not nested ifs.

    Really? I tried implementing a switch and the editor told me they weren't supported...

    Posted in: Miscellaneous Development
  • 0

    posted a message on [Trigger] How to Target with Mouselook (Tracelines)
    Quote from iWaNN: Go

    Traceline Camera Position: traceline_currentTargetPoint Index 1: 1 Camera Height: 2.0 Player: 1

    This looks like:

    Traceline (Camera Position: traceline_currentTargetPoint[1],
    Camera Height: 2.0,
    Player: 1)
    

    Is that correct? If so, the problem is you're plugging in the point of the current target, "traceline_currentTargetPoint", instead of the point of your camera. If your camera is following your main unit, then your function call should look like this:

    Traceline (Camera Position: Position of Unit ( mainUnit ),
    Camera Height: Unit Height ( mainUnit ) + 2.0,
    Player: 1)
    

    This is assuming that your camera is set to follow your unit and that your camera is set at a 2.0 height offset. If your camera is not set at a 2.0 offset you should replace 2.0 with the actual offset of your camera.

    Posted in: Tutorials
  • 0

    posted a message on Naval Units

    You could create a trigger that looks for any units casting the unload ability at stage Generic2 - Queue. Then compare the worldheight at the location they've selected with the height of the water and cancel the unload order (and possibly throw a custom error message) if the target location is under water.

    Posted in: Miscellaneous Development
  • 0

    posted a message on Naval Units

    Make a unit group and add all of your naval units to it. Create a trigger that goes off whenever a naval unit moves. In that trigger, check the World Height (the height of the actual walkable terrain) against the height of the water. If the terrain at the place they're trying to move is higher than the water, don't let them move there.

    Posted in: Miscellaneous Development
  • 0

    posted a message on How to move unit behind the camera?

    What's the difference?

    Posted in: Miscellaneous Development
  • 0

    posted a message on 8 Way Movement

    Well that trigger is a huge mess! Hunting through that mess is enough to give anybody a headache :) A suggestion I would make for clarity in the future is to use the "If Then Else Multiple" option instead of nesting all those if statements. "If Then Else Multiple" is kind of confusing, but I figured it out earlier today (After getting fed up with nested if statements!)

    Basically, create the if-then-else-multiple statement. Then, right click "If Then Else" and click "New Element" or just hit Ctrl+W. Do this for each "else if" you want to add, including the first "if". Much easier to read and keep track of, and no nesting!

    As for your problem, that is a very complex set of variables you're keeping and checking. I know you're concerned about performance, but having a recurring timer that checks a single int variable every 0.0 or 0.5 or etc seconds is not going to make a difference in performance at all. The only time it would do more than check the single variable at all is when a button is pressed down, and in that case your trigger does the same amount of work at that point anyway.

    I'll show you what I used for the WASD system in Reaper Madness, which has the same control system you want to set up. Note how simple it is to read:

    Key Down (Any):

    if          (EventKeyPressed() == c_keyW) {
    	WASDstate |= 0x0001;
    } else if (EventKeyPressed() == c_keyA) {
    	WASDstate |= 0x0010;
    } else if (EventKeyPressed() == c_keyS) {
    	WASDstate |= 0x0100;
    } else if (EventKeyPressed() == c_keyD) {
    	WASDstate |= 0x1000;
    }
    

    Key Up (Any):

    if          (EventKeyPressed() == c_keyW) {
    	WASDstate ^= 0x0001;
    } else if (EventKeyPressed() == c_keyA) {
    	WASDstate ^= 0x0010;
    } else if (EventKeyPressed() == c_keyS) {
    	WASDstate ^= 0x0100;
    } else if (EventKeyPressed() == c_keyD) {
    	WASDstate ^= 0x1000;
    }
    

    The actual function, getWASDangle(), that translates the buttons being pressed into an angle we can use:

    int lv_TempBits = WASDstate & 0x0001;
    if(lv_TempBits == 0x0001) {
    	lv_TempBits = gv_players[pv_player].WASDstate&0x1010;
    	if(lv_TempBits == 0x0000)      { return 0.0; }   // W
    	else if(lv_TempBits == 0x1000) { return 315.0; } // W+D
    	else                           { return 45.0; }  // W+A or W+A+D
    } else {
    	lv_TempBits = gv_players[pv_player].WASDstate&0x1110;
    	if(lv_TempBits == 0x0100)      { return 180.0; } // S
    	else if(lv_TempBits == 0x1100) { return 225.0; } // S+D
    	else if(lv_TempBits == 0x1000) { return 270.0; } // D
    	else if(lv_TempBits == 0x0010) { return 90.0; }  // A
    	else if(lv_TempBits == 0x1010) { return 90.0; }  // A + D
    	else if(lv_TempBits == 0x0000) { return 0.0; }  // None
    	else                           { return 135.0; } // S+A or S+A+D
    }
    

    The trigger that runs every 0.0 seconds:

    if(WASDstate != 0x0000) {
    Unit - Move Unit instantly to ((Position of Unit) offset by 0.1 towards getWASDangle() degrees) (Blend)
    Unit - Make Unit face getWASDangle() over 0.1 seconds
    }
    

    The |= 0x0000 stuff may look confusing, but it's simple. When I run |= 0x0100 I'm setting the second digit (of the 4) to a 1, just as it appears. When I run ^= 0x0100 I am setting the second digit to a zero. This way, the 4 digits represent, in order: My D, S, A and W keys. 1 means they're pressed, 0 means they are not pressed.

    I would say this is probably one of the most elegant and best performing methods.

    Posted in: Miscellaneous Development
  • 0

    posted a message on Missing functionality: player names

    Looking into this.

    Wow I guess that's true. Maybe it's an intended limitation. I can see why it would be, although I wouldn't agree that it's too important to remove functionality to prevent players from cheating in their own games.

    Posted in: Galaxy Editor Bugs and Feedback
  • 0

    posted a message on [Trigger] How to Target with Mouselook (Tracelines)

    Introduction

    Hello all, I've been hanging out for a while using SC2Mapster's resources and sharing the progress of one of my maps with the community. One of the questions I get asked the most is how to detect where the player is looking via MouseLook. The answer is: I use a custom-made traceline function. I want to take the time to explain to the community what a traceline is and how to make one. Please note that although I wrote my code for Reaper Madness in pure script (no triggers via galaxy editor) this tutorial will be explaining how to set it up in Galaxy Editor.

    Setting Up Variables and Triggers

    First, because Galaxy does not support bulk copy or pointers, and because Galaxy Editor does not support structs, we will need to set up the values that our traceline function calculates as global variables. We want to calculate the three following variables:

    1. Current Target - We will want our function to return which unit is currently targeted.
    2. Current Targeted Point - We will want our function to return the point the player is targeting, whether it is a unit or terrain. We will use this point to position our impact effects.
    3. Current Targeted Height - When our player is targeting a unit, we want to know the height at which the traceline intersected the unit. We will use this point to position our impact effects.

    We also need to set them up as arrays because we will need a different set of value for each player. As a lesson in good development practices, I would like to show you how to set up Constant variables, however Galaxy doesn't support setting array lengths by anything except raw numbers so we'll have to do it the hard way.

    Make a new folder called "Traceline" so we can separate this function from the rest of your project. Inside the new folder, create another folder named "Variables". Inside the variables folder, make our three variables: traceline_currentTarget (unit), traceline_currentTargetPoint (point) and traceline_currentTargetHeight (real). Turn them into an array by checking the array box. Set the size to the maximum amount of players who can play your game (We'll use 8 as the example): Picture 1

    Now we need a function to write our traceline into. Right click on the "Traceline" folder, hover over "New" and click "New Action Definition". Name it "Traceline": Picture 2

    Our function will need to be passed certain variables as parameters to perform its function, so let's set the parameters up. Our function needs to know:

    1. Camera Position - The position of the camera (XY).
    2. Camera Height - The height of the camera (Z).
    3. Player - The player we're calculating a traceline for.

    To create a new parameter, right click on "Parameters", hover over "New" and click "New Parameter". We want to add three: "Camera Position" (point), "Camera Height" (real) and "Player" (integer): Picture 3

    We will also be using Custom Script, so add a new Action of type "Custom Script": Picture 4

    Now we get to the meat of our function. Click on the new custom script action to be greeted with a nice empty box, ready to be filled with juicy target-finding script. While following the tutorial, keep in mind that the editor will change the name of your parameters behind-the-scenes. For instance, the variable "Camera Height" will be renamed "lp_cameraHeight" when referred to in Galaxy Script. The lp_ stands for "Local Parameter", the first letter of our variable is shifted to lowercase and all spaces are removed.

    Explanation of Traceline Function

    A short intermission to explain what our traceline function will do: Our traceline function is, surprise, going to trace an imaginary line. The beginning of the line is the camera's position and height, the end of the line is 50.0 units in the direction the player is facing. To "trace" the line, we will be checking the position of each point in the line in small increments. For example, if you're at 0,0 at height 0 [0, 0, 0] and you're looking straight east the end of the imaginary line would be at 50, 0 at height 0 [50, 0, 0]. Every 1.0 unit of the line, we will check to see if we've hit anything. This means we run a loop 50 times: First we check [1,0,0], if we find nothing we check at [2,0,0] etc until we hit something.

    Inside Our Function

    First we need to get the angles of the players camera: The pitch and yaw. First we'll need to create two variables (real) to hold the angles, so create two variables inside the function and call them "Pitch" and "Yaw". For pitch, set the initial value to Camera Pitch of Player (Player) and for yaw set the initial value to Camera Yaw of Player (Player), where the "Player" inside the parenthesis refers to our parameter named "Player": Picture 5

    Last thing before we dive into code: We'll need to set our main unit to a global variable so that we don't end up targeting it in our traceline. Create a variable ON THE LEFT in our trigger list, OUTSIDE of our function named "Main Unit" (unit). In a multiplayer game this variable will need to be an array, as all players will have a different main unit. However, for this example I will only be using 1 main unit.

    Next we'll want to start in on our code. As explained earlier, we will be checking each point in small intervals in a loop. So, we need to set up the loop. Create a variable named "Trace Distance" (real) and set its initial value to 0.0. This variable will keep track of how far along the imaginary line we are. Now we'll set up our loop:

    while(lv_traceDistance < 50.0) { // While Trace Distance is under our max range, 50, we want to run everything between the squiggly brackets: {}
        // This is where all of our future code is going to go.
        lv_traceDistance += 0.5; // At the end of the loop we increment our distance from the camera by 0.5 units. Since the maximum distance is 50.0, this loop will run up to 100 times.
    }
    

    The first things we'll need to do inside our loop is calculate the height and position of our current "step" in the trace. Create a variable called "Trace Height" (real). Inside our loop, we'll calculate the height of the current "step":

    if(lv_pitch < 90){
    	lv_traceHeight = Tan(lv_pitch) * lv_traceDistance * (-1);
    } else if(lv_pitch > 270) {
    	lv_traceHeight = Tan(360 - lv_pitch) * lv_traceDistance;
    }
    

    It's not so important that you understand what's going on in the last code segment, but we're finding the Tangent of the angle of lv_Pitch which returns a value between 0 and 1. We multiply that number by the distance we travel every step. For example if we're looking directly toward the sky (90 degree angle) and our trace distance is 0.5 units, the resulting tangent will be 1, and the relative height will be 1 * 0.5 = 0.5, meaning the height at this step in our traceline is 0.5 units higher than the camera's height. As another example, if we're looking forward and up equally (45 degree angle), the resulting tangent will be 0.5 and the relative height will be 0.5 * 0.5 = 0.25, meaning the height at this step in our traceline is 0.25 units higher than the camera's height. If you don't understand all that, it's fine, just continue reading.

    Next we need to get the point (XY) where our current step will be located. This one is less complex because Blizzard gave us a function to do the dirty work for us. Create a variable named "Trace Point" (point). We'll get the trace point by calculating it as a polar offset of the camera position. A polar offset means it is a certain distance (offset) away from a point at a given angle (polar). Here's how we call it:

    lv_tracePoint = PointWithOffsetPolar(lp_cameraPosition, lv_traceDistance, lv_yaw);
    

    We will need the World Height at the current position of our traceline step, so create a variable named "Trace World Height" (real). This is how we get the height of the world at the current step position:

    lv_traceWorldHeight = WorldHeight(c_heightMapGround, lv_tracePoint);
    

    Now that we have the exact information about the current point in our imaginary line, we're going to do a few things to determine if a unit is in our way:

    1. Create a small region with a radius of 1.5 at the current traceline point
    2. Grab the closest unit to the center of that region, that is within the region
    3. Create a region at the unit we found, the size of the unit
    4. Get the world height at the position of the unit

    So create four variables: "Trace Region" (region), "Closest Unit" (unit), "Unit Region" (region) and "Unit World Height" (real). We are going to use the unit's default radius as the size of the unit, however you can replace it with a custom size if you want. We are also going to assume that the unit is a ground unit and therefore uses the c_heightMapGround heightmap, and that the bottom of their "hitbox" is the worldheight (which means where the terrain they're standing on is):

    lv_traceRegion = RegionCircle(lv_tracePoint, 1.5);
    lv_closestUnit = libNtve_gf_ClosestUnitToPoint(lv_tracePoint, UnitGroup(null, 15, lv_traceRegion, UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0));
    lv_unitRegion = RegionCircle(UnitGetPosition(lv_closestUnit), UnitGetPropertyFixed(lv_closestUnit, c_unitPropRadius, true));
    lv_unitWorldHeight = WorldHeight(c_heightMapGround, UnitGetPosition(lv_closestUnit));
    

    Now we have all the information we need to decide whether we're: Looking at a unit, looking at terrain or aren't looking at anything (yet). So, we're going to test which of those 3 is the case. First we're going to check if it's a unit. We will make sure:

    1. The unit is not null (A unit was actually selected)
    2. The unit is not the player's main hero
    3. The traceline point's location (XY) is inside the unit's hitbox
    4. The traceline point's height (Z) is above the bottom of the unit (We're using 0 because we assume it's ground)
    5. The traceline point's height (Z) is below the top of the unit (We're going to use the radius of the unit as a baseline, however this can be VERY inaccurate on many units and should be replaced with CUSTOM values on a unit-by-unit basis.

    And those checks will look like this:

    if(lv_closestUnit != null && 
    lv_closestUnit != gv_mainUnit && 
    RegionContainsPoint(lv_unitRegion, lv_tracePoint) && 
    lp_cameraHeight + lv_traceHeight - lv_unitWorldHeight >= 0.0 && 
    lp_cameraHeight + lv_traceHeight - lv_unitWorldHeight <= UnitGetPropertyFixed(lv_closestUnit, c_unitPropRadius, true)) {
    // This is where our response will go if all of the conditions are met.
    // If all of the conditions are met, it means we are looking at the unit stored in lv_closestUnit.
    }
    

    If those conditions are met, which means we're looking at a unit, we want to set those three variables we created earlier to the unit's info and then exit our traceline function (This goes inside the brackets {} of the if statement):

    gv_traceline_currentTarget[lp_player] = lv_closestUnit;
    gv_traceline_currentTargetPoint[lp_player] = lv_tracePoint;
    gv_traceline_currentTargetHeight[lp_player] = lp_cameraHeight + lv_traceHeight;
    		
    return;
    

    However, if those conditions aren't met, then we aren't looking at a unit (at this step in the traceline) so we need to check whether we're looking at terrain or still haven't collided with anything yet. The way to check if we've hit terrain is very simple, just check if the current height of the traceline step is under the height of the terrain:

    if(lp_cameraHeight + lv_traceHeight <= lv_traceWorldHeight) {
        gv_traceline_currentTarget[lp_player] = null;
        gv_traceline_currentTargetPoint[lp_player] = lv_tracePoint;
        gv_traceline_currentTargetHeight[lp_player] = lp_cameraHeight + lv_traceHeight;
    
        return;
    }
    

    So now if we've hit either a unit or terrain, our function has ended and we have the information of the unit and/or terrain that the player is looking at. This is the end of our loop, so if it runs this test and finds neither a unit nor terrain then it will run again, 0.5 units further down the imaginary line. If it runs 100 times and finds nothing, it will exit the loop and continue through the function. Since it's important that we know when it intersects with NOTHING (Say they're looking up at the sky) we're going to add the following AFTER the loop. To reiterate, this goes OUTSIDE of the while(){} statement that we have been putting our code in:

    gv_traceline_currentTarget[lp_player] = null;
    gv_traceline_currentTargetPoint[lp_player] = null;
    gv_traceline_currentTargetHeight[lp_player] = 0.0;
    

    This just clears out all of the values if we're not looking at anything to make sure that if we're not looking at anything we don't use old, outdated values. As for the traceline, that's it! Any time you want to see what the user is looking at, just call the action using the trigger editor like any other action, it's under the "- General" tab: Picture 6

    We're Done!

    Two places you can put this function are:

    1. In a recurring function (Every 0.0 seconds, etc). This is useful if you want to use the current target information to display info to the player about the unit they're looking at. You can see an example of this in my Reaper Madness videos. You can then use the SAME information (You don't have to run the traceline twice) to determine which unit or piece of terrain to shoot when the player hits the attack key (such as left mouse click).
    2. In a trigger responding to left mouse click, or any other attack key. Just run the traceline() function to populate the three variables (Current target, current target position and current target height) and use those variables to process your attack. For instance, you could run traceline, deal 10.0 damage to traceline_currentTarget and spawn a blood splatter effect at position traceline_currentTargetPosition and height traceline_currentTargetHeight.

    Tips:

    1. After running the traceline function, you can check if the unit is targeting a unit by checking whether or not traceline_currentTarget is null. If it's null, there's no target. If it's not null, then it holds the unit info of the target.
    2. After running the traceline function, you can check if the unit is targeting terrain by checking whether or not traceline_currentTarget is null AND whether or not traceline_currentTargetPosition is null. If both are null, then the player isn't looking at a unit nor is he looking at terrain.
    3. You can change the values within the traceline such as our max distance, 50.0, to better suit your needs. For example, if the player is holding a sniper rifle you will probably want him to shoot further than 50.0, so just change the 50.0 to however far you want them to see. On the biggest map, 250.0 should be long enough to target anybody on the entire map. Remember that the bigger this number is the more work needs to be processed and it could end up slowing down your game.

    Check Your Work!

    Lastly, here's a picture of how your trigger editor should look if you followed my tutorial exactly: Picture 7

    And here's how your code should look if you followed my tutorial exactly:

    while(lv_traceDistance < 50.0) {
        if(lv_pitch < 90){
            lv_traceHeight = Tan(lv_pitch) * lv_traceDistance * (-1);
        } else if(lv_pitch > 270) {
            lv_traceHeight = Tan(360 - lv_pitch) * lv_traceDistance;
        }
        lv_tracePoint = PointWithOffsetPolar(lp_cameraPosition, lv_traceDistance, lv_yaw);
        lv_traceWorldHeight = WorldHeight(c_heightMapGround, lv_tracePoint);
    
        lv_traceRegion = RegionCircle(lv_tracePoint, 1.5);
        lv_closestUnit = libNtve_gf_ClosestUnitToPoint(lv_tracePoint, UnitGroup(null, 15, lv_traceRegion, UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0));
        lv_unitRegion = RegionCircle(UnitGetPosition(lv_closestUnit), UnitGetPropertyFixed(lv_closestUnit, c_unitPropRadius, true));
        lv_unitWorldHeight = WorldHeight(c_heightMapGround, UnitGetPosition(lv_closestUnit));
    
        if(lv_closestUnit != null && 
        lv_closestUnit != gv_mainUnit && 
        RegionContainsPoint(lv_unitRegion, lv_tracePoint) && 
        lp_cameraHeight + lv_traceHeight - lv_unitWorldHeight >= 0.0 && 
        lp_cameraHeight + lv_traceHeight - lv_unitWorldHeight <= UnitGetPropertyFixed(lv_closestUnit, c_unitPropRadius, true)) {
            gv_traceline_currentTarget[lp_player] = lv_closestUnit;
            gv_traceline_currentTargetPoint[lp_player] = lv_tracePoint;
            gv_traceline_currentTargetHeight[lp_player] = lp_cameraHeight + lv_traceHeight;
            		
            return;
        }
    
        if(lp_cameraHeight + lv_traceHeight <= lv_traceWorldHeight) {
            gv_traceline_currentTarget[lp_player] = null;
            gv_traceline_currentTargetPoint[lp_player] = lv_tracePoint;
            gv_traceline_currentTargetHeight[lp_player] = lp_cameraHeight + lv_traceHeight;
    
            return;
        }
    
        lv_traceDistance += 0.5;
    }
    
    gv_traceline_currentTarget[lp_player] = null;
    gv_traceline_currentTargetPoint[lp_player] = null;
    gv_traceline_currentTargetHeight[lp_player] = 0.0;
    

    Thanks for Reading!

    Thanks for reading everybody! I know it's a bit advanced and a lot of people probably won't get it, but I tried to explain it as best as possible! Feel free to leave your feedback and/or questions and I'll do my best to answer them.

    Posted in: Tutorials
  • 0

    posted a message on Reaper Madness (Showcase 2: Physics)
    Quote from netisopl: Go

    Can I ask how about you went creating that physics engine more specifically how fluidly those banelings bounce off of the walls.?

    Lots of time spent in notepad.

    Quote from TDarkC: Go

    Make the camera so it does not change the hight when moveing it on to a cliff.

    Thanks for the insight... Even though I listed that both here and on the youtube video itself as one of the unfixable bugs. The cliff level is not the problem, it's the invisible ramp.

    Posted in: Project Workplace
  • 0

    posted a message on Map Editor MATH calculation INCORRECTLY

    The editor doesn't use floating point (floats) it uses fixed points (reals). Floating points are much more precise and are a requirement for working with precise numbers. Reals are trash. They're good for saving memory, I guess. They're bad for anything that actually relies on a precise number. It may be "working as intended" but it's also wrong.

    Floats need to be implemented into Galaxy ASAP. Pointers or bulk copy also need to be supported. Lastly, structs are available in the Galaxy script but they are not supported in the Trigger Editor, which should also be changed ASAP.

    Posted in: Miscellaneous Development
  • 0

    posted a message on "Empty Face" in Container Item

    Nobody? This seemed like such a cool feature, it's a shame it doesn't work, lol.

    Posted in: Miscellaneous Development
  • To post a comment, please or register a new account.