• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Physics & Voting Dialogue & WASD Movement & Terrain Generation & Other Scripts

Status
Not open for further replies.
Download my Scripts Test Map & Try it Out!


Alright so here's that map I've been talking about. Right now I'm really trying to work on the physics and need help with that. If you could please download the map and try it out for yourself I would appreciate that.

The voting dialogue system is complete. It features random vote selection for when one or more votes are tied, a title + subtitle, automatic scaling to fit the number of options, vote switching before the vote is up / everyone has voted, and a timer label that shows how many seconds you have left to cast your vote. The only things I might add (that aren't really neccessary) are:

• a boolean option to set up a vote that waits for the timer to expire even if everyone has already voted
• an area that displays more text for when you select an option that tells you additional details about it (if there are additional details set). This wouldn't neccessarily have to be a part of my voting dialogue system though, it could just be an add-on
• A parameter for minimal votes required option; that way when voting on kicking a player it could require the participation of most of the people in the party to vote so for example if nobody but one or two people vote those people can't force the player to be kicked.
• A configurable vote delay; so trolls can't annoy everyone in the game by forcing people to constantly vote on something. e.g. Wait 90 seconds until voting on (x vote menu or just any vote in general) again.
• I should make some even more function examples of use then what I currently have. The kick player thing is the best example of use but the others aren't really doing anything. This does not pertain to the vote system itself though.​

This is the function for calling a vote btw:
JASS:
void gf_callVote (string lp_votingOn, fixed lp_timeToVote, string lp_title, string lp_subtitle, int lp_voteOptionsCount)

Right now the commands to show the different dialogue configures I made are:
1. -rm (shows game modes to pick from, currently I don't have it do anything)
2. -kick (shows all the player names + one option for "Don't kick anybody"
2. -many options (shows like 30 options, currently for testing purposes whichever button you click up to option 16 will spawn a roach at a random location in the map for the player whose ID is the option # - 1, did this for the lulz)

Here are all my folders + scripts. Note that EVERYTHING in my map is contained within scripts because doing everything in .galaxy is WINNING. The parts in black are folders, the parts in green are scripts, the parts in red are disabled scripts (used as notes or just kept around to review or fix later).
Code:
Variables
[COLOR="Lime"]    Map Constants
    Map Variables
    Trigger Globals[/COLOR]
Blue Library
[COLOR="Lime"]    Debug Msg
    Index Unit
    Custom Value
    Projectile Create[/COLOR]
    Vote System
        Variables
[COLOR="Lime"]            Vote Variables[/COLOR]
        Vote Functions
[COLOR="Lime"]            Call Vote
            On Vote
            Vote Configures
            Vote Cast[/COLOR]
        Vote Dialog
[COLOR="Lime"]            Vote Dialog Create[/COLOR]
    Physics
[COLOR="Red"]        Vectors[/COLOR]
[COLOR="Lime"]        Gravity[/COLOR]
    WASD Blue
        Notes
[COLOR="Red"]            Notes[/COLOR]
        Movement
[COLOR="Lime"]            WASD Globals
            Jump Unit
            Move Unit
            Key Press
            Key Release
            Key Events[/COLOR]
    Terrain System
[COLOR="Lime"]        Terrain Generator[/COLOR]
Triggers
[COLOR="Lime"]    on Message
    on Button Press
    Fire Weapon
    on Order
    on Damage[/COLOR]
Map Load
[COLOR="Lime"]    Map Load[/COLOR]
Recycle Bin
[COLOR="Red"]    Jump
    Tower Income[/COLOR]
Do you like my organization of scripts, variables, and notes? I try to keep it very orderly and also to make each system as modular as possible so you can just copy one of them out and paste it another map as you need em' without too much confusion... you'll want to really take a look through the scripts first before you do that though so you know what's what.

The WASD movement system uses the WASD keys to move in 8 directions, space to jump (uses my gravity physics, hold shift before jumping to jump even higher), and camera follow although I commented that out as apparently it locks camera input while the cam is moving making the camera scroll (which adjusts camera height) not work. You can just remove the // if you want that on again. I also had it adjust camera height for when I was doing super jumps but that code isn't in the map (or recycle bin) anymore.

There's a projectiles system in there too. I currently have the projectile unit set to ignore terrain height. This is fine for them but not so well for my units which I want to have jumping around n' stuff since they adjust height with the terrain and I don't know how to properly compensate for that so that the unit doesn't suddenly go way up or down when jumping from a high area to a low area (or the reverse).

I need help with figuring out how I should add friction, 3D collision, knockback, and sliding (so if they're on a steep slope they end up sliding down it). I also don't know how to adjust the speed and zvelocity on my projectiles to make for example an arrow or a glob or a nade or whatever moving in an arc go exactly towards the point they clicked. Right now it would just overshoot the spot >.<. Please give help with these issues.

The terrain generator I haven't really worked on much. Right now it's just creating x number of trees at random all over the map. I'll attend to it sooon though, it's just not as high a priority as for example my physics script.

I have a damage system in there that works really well. On one of my older maps (Impossible Odds) which somehow has magically corrupted data (probably because I started the map long before some of the recent updates) things don't work so well for unknown reasons... I also am not sure if damage < 1.0 can be applied, it seems not, but I have yet to test it in the map I have here uploaded which isn't a messy mess due to Blizzard updates.

One more thing I should mention is I have a projectiles function in there which lets me create and customize many aspects of a projectile including its art and such. Eventually I'll add even more things to it to allow myself to customize projectiles even more by making physics apply differently to different projectiles, having on damage / on projectile death effects, sounds, (if I get that working properly, seems like sounds generated by map script can't be heard if ones generated by data are playing which drown it out) and so on.
 

Attachments

  • BlueBerryWizard - Voting System.SC2Map
    1.5 MB · Views: 106
  • Blue Physics 2.SC2Map
    638.2 KB · Views: 64
  • Blue Physics 1.0.SC2Map
    672.9 KB · Views: 58
Last edited:
Current Gravity Physics Script

JASS:
//---------- Configurable Constants ----------
const fixed  c_gravityTimerInterval = 0.1;
const fixed  c_gravity              = 9.8;
const string c_gravityBehavior      = "Jump";
//--------------------------------------------
trigger     gt_gravity              = TriggerCreate("gt_Gravity_Func");
timer       gv_gravityTimer         = TimerCreate();
bool gt_Gravity_Func (bool testConds, bool runActions) {
    int     lv_i = 1;
    unit    lv_u = UnitGroupUnit(gv_gravityUG, lv_i);
    int     lv_cv;
    point   lv_pt;
    // Gravity Variables
    fixed   lv_z;  // velocity
    fixed   lv_zw; // terrain-height displacement
    fixed   lv_za; // acceleration
    fixed   lv_zg; // gravity
    // Sliding Variables
    //fixed   lv_x;
    //fixed   lv_y;
    
    while(lv_u != null) {
        lv_u  = UnitGroupUnit(gv_gravityUG, lv_i);
        if (UnitHasBehavior(lv_u, c_gravityBehavior)) {
            lv_cv = FixedToInt(UnitGetCustomValue(lv_u, c_uIndex));
            lv_pt = UnitGetPosition(lv_u);
            lv_z  = UnitGetHeight(lv_u);
            lv_zw = WorldHeight(c_heightMapGround, lv_pt);
            lv_za = (gv_zBoost[lv_cv]*c_gravityTimerInterval);
            lv_zg = (c_gravity*c_gravityTimerInterval);
            
            lv_z  = lv_z + lv_za - lv_zg - (c_gravity*c_gravityTimerInterval);
            //lv_zw = lv_zw; gv_zDisplacement[lv_cv]
            
            // Unit is at ground level
            if (lv_z <= 0) {
                lv_z = 0;
                // UnitGroupRemove(gv_jumpingUnit, lv_u);
                UnitBehaviorRemove(lv_u, c_gravityBehavior, 1);
            }
            if (UnitGetType(lv_u) == c_projectile) {
                if (lv_zw >= lv_z) {
                    //UnitCreateEffectUnit(lv_u, "VolatileBurst", lv_u);
                    gf_ProjectileExplosion (1, 1, lv_pt);
                    gv_zBoost[lv_cv] += (9.8 + (lv_zw - lv_z));
                    lv_z = lv_zw;
                    //UnitKill(lv_u);
                }
            }
            
            //DebugMsg("Height: " + FixedToString(lv_z, 2));
            UnitSetHeight(lv_u, lv_z, c_gravityTimerInterval);
            gv_zBoost[lv_cv] += -lv_za;
            
            //gv_zDisplacement[lv_cv] = gv_zDisplacement[lv_cv] - lv_zw + lv_z;
            //if (UnitGetOwner(lv_u) == 1) {
                //CameraSetValue(1, c_cameraValueHeightOffset, lv_z, 0.2, -1, 10);
                //CameraSetValue(1, c_cameraValueYaw, UnitGetFacing(lv_u), 0.2, -1, 10);
            //}
            
            //DebugMsg("Z Offset Current: " + FixedToString(lv_zw, 2));
            //DebugMsg("Z Height Initial: " + FixedToString(gv_zDisplacement[lv_cv], 2));
        }
        lv_i += 1;
    }
    
    return true;
}
// Register Physics Timer Event
void gt_Gravity_Init () {
    TimerStart(gv_gravityTimer, c_gravityTimerInterval/2, true, c_timeReal);
    TriggerAddEventTimer(gt_gravity, gv_gravityTimer);
}
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,195
I have no idea why you find simple physics difficult...

What you are currently doing is...
next unit height = unit height + boost * t + 2 * gravity accelation * t
boost = boost + gravity acceleration * t

Why are you adding 2 * gravity accelation * t to the height?!

As I told you dozens of times before, it is...
next unit height = unit height + velocity * t + (1/2) * gravity accelation * t^2
velocity = velocity + gravity accelation * t

This formula is obtained by double intergrating acceleration with respects to time. You in theory do not even need the "(1/2) * gravity accelation * t^2" for a close approximation but that is there to apply corrections due to constant acceleration.
 
I have no idea why you find simple physics difficult...

What you are currently doing is...
next unit height = unit height + boost * t + 2 * gravity accelation * t
boost = boost + gravity acceleration * t

Why are you adding 2 * gravity accelation * t to the height?!

As I told you dozens of times before, it is...
next unit height = unit height + velocity * t + (1/2) * gravity accelation * t^2
velocity = velocity + gravity accelation * t

This formula is obtained by double intergrating acceleration with respects to time. You in theory do not even need the "(1/2) * gravity accelation * t^2" for a close approximation but that is there to apply corrections due to constant acceleration.
Tell me if I have this right, been thinking about it for the last few hours:

Position is the current position of the unit (obviously).
Velocity is like offset or direction; they are values you add to the position to get the new position?
Acceleration is a value you add to velocity to increase or decrease the amount the position changes due to velocity each interval?
Gravity is subtracted from acceleration on the z (height) axis reducing the speed at which the object moves upwards and even reversing it after awhile?
Friction is subtracted (or add if the values are negative) from x and y acceleration slowing down the rate at which the unit slides along terrain?
Sliding along slopes is done (when the unit is on the ground not in the air) by checking the height difference between say the position xy of the unit and the same position offset by the radius or the unit or ummm just 1.0 then applying that height difference to the acceleration on the x and y axis?
Bouncing is done when an object hits the terrain (height is same as or less than that of the terrain) and involves mass and energy or something? I really don't know what to do here.
Moving a unit along x and y axis would mean adding to its acceleration but limiting it to make sure the acceleration doesn't go above the maximum the unit speed?

Is this all right?
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,195
Velocity is like offset or direction; they are values you add to the position to get the new position?
Velocity is the vector form of speed. When you drive a car you have to follow a certain speed limit. If your car is driving at 50 mph for an hour it means you will have traveled 50 miles.

Acceleration is a value you add to velocity to increase or decrease the amount the position changes due to velocity each interval?
Kind of.

Gravity is subtracted from acceleration on the z (height) axis reducing the speed at which the object moves upwards and even reversing it after awhile?
Yes. However in reality gravity varies with displacement from the surface of an object so if you were on the moon the gravity from earth will be much less than the gravity from the moon although you will be affected by both at any time and will ven jump further when between the earth and the moon (same applies on earth but virtually unnoticable).

Friction is subtracted (or add if the values are negative) from x and y acceleration slowing down the rate at which the unit slides along terrain?
Depends on friction source. You must remember that drag applies to the unit's combined velocity vector (XYZ) and not just XY and is proportional to the distance traveled. I think the real model is that air drag is an acceleration that is a function of velocity. No idea how ebrasive friction works but I am guessing it must have some constant element to it.

Sliding along slopes is done (when the unit is on the ground not in the air) by checking the height difference between say the position xy of the unit and the same position offset by the radius or the unit or ummm just 1.0 then applying that height difference to the acceleration on the x and y axis?
It is an acceleration that is a function of gravity, gradient and traction. I advise reading up about this kind of physics as I have not specalized on it.

Bouncing is done when an object hits the terrain (height is same as or less than that of the terrain) and involves mass and energy or something? I really don't know what to do here.
Moving a unit along x and y axis would mean adding to its acceleration but limiting it to make sure the acceleration doesn't go above the maximum the unit speed?
Bouncing is done by reflecting a fraction (the ridgedness of the object and terrain) of the momentum of the object around the collided surface normal. As terrain has an infinite mass you can assume that a fraction of the velocity is reflected from the terrain normal due to the mass canceling out (momentum only plays a part in collisions with movable objects and determines how they bounce off each other).

The problem with velocity and acceleration is they are often not constant. This means that differential equations are needed to solve the system.
 
Bouncing is done by reflecting a fraction (the ridgedness of the object and terrain) of the momentum of the object around the collided surface normal. As terrain has an infinite mass you can assume that a fraction of the velocity is reflected from the terrain normal due to the mass canceling out (momentum only plays a part in collisions with movable objects and determines how they bounce off each other).

How do I handle the xy part of bouncing and what else might I need that's not in here? This is my current script.

JASS:
bool gt_Physics_Func (bool testConds, bool runActions) {
    int     lv_i = 1;
    unit    lv_u = UnitGroupUnit(gv_physicsUG, lv_i);
    int     lv_cv;
    point   lv_pt;
    // Gravity Variables
    fixed   lv_zw; // terrain-height displacement
    
    while(lv_u != null) {
        lv_cv = FixedToInt(UnitGetCustomValue(lv_u, c_uIndex));
        // Add gravity to acceleration
        if (gv_useGravity[lv_cv]) {
            gv_accelZ[lv_cv] += -(c_gravity*c_physicsTimerInterval);
        }
        // Add acceleration to velocity
        gv_velX[lv_cv] += (gv_accelX[lv_cv]*c_physicsTimerInterval);
        gv_velY[lv_cv] += (gv_accelY[lv_cv]*c_physicsTimerInterval);
        gv_velZ[lv_cv] += (gv_accelZ[lv_cv]*c_physicsTimerInterval);
        // Add velocity to position coordinates
        gv_posX[lv_cv] += (gv_velX[lv_cv]*c_physicsTimerInterval);
        gv_posY[lv_cv] += (gv_velY[lv_cv]*c_physicsTimerInterval);
        gv_posZ[lv_cv] += (gv_velZ[lv_cv]*c_physicsTimerInterval);
        // Set the position
        lv_pt = Point(gv_posX[lv_cv], gv_posY[lv_cv]);
        // Check world height
        lv_zw = WorldHeight(c_heightMapGround, lv_pt);
        // On terrain-collide
        if (gv_posZ[lv_cv] <= lv_zw && gv_useBounce[lv_cv]) {
            // Bounce
            gv_posZ[lv_cv] = lv_zw;
            gv_accelZ[lv_cv] = (gv_accelZ[lv_cv]*0.5);
            gv_velZ[lv_cv] = -(gv_velZ[lv_cv]*0.5);
            gv_velZ[lv_cv] += (gv_accelZ[lv_cv]*c_physicsTimerInterval);
            gv_posZ[lv_cv] += (gv_velZ[lv_cv]*c_physicsTimerInterval);
        }
        if (gv_posZ[lv_cv] <= lv_zw + 0.1) {
            // Sliding & Friction
            gv_velX[lv_cv] = gv_velX[lv_cv]*c_friction;
            gv_velY[lv_cv] = gv_velY[lv_cv]*c_friction;
            // Kill if sliding no more
            if (gv_velX[lv_cv] < 0.1 && gv_velX[lv_cv] > -0.1 && gv_velY[lv_cv] < 0.1 && gv_velY[lv_cv] > -0.1 && gv_slideEndDie[lv_cv]) {
                UnitKill(lv_u);
            // Kill if very weak bounce
            } else if (gv_bounceEndDie[lv_cv]) {
                UnitKill(lv_u);
            }
        }
        
        UnitSetPosition(lv_u, lv_pt, true);
        // Subtract terrain height so the unit ignores terrain height during its movement
        UnitSetHeight(lv_u, gv_posZ[lv_cv] - lv_zw, c_physicsTimerInterval);
        
        lv_i += 1;
        lv_u  = UnitGroupUnit(gv_physicsUG, lv_i);
    }
    
    return true;
}
// Register Physics Timer Event
void gt_Physics_Init () {
    TimerStart(gv_physicsTimer, 0.0, true, c_timeReal);
    TriggerAddEventTimer(gt_physics, gv_physicsTimer);
}

I basically have 3 things left to do (or so I think). XY part of bounce, sliding, and making balls and stuff bounce when hitting each other. I guess I also need to add in mass and make use of the mass value, but I don't know how mass factors into physics. Maybe I need some other things too...

Edit 2: I also need to add a value to weapons for maximum throw height which applies to any parabolic weapon and is to be used with things thrown by hand or launchers or whatever; for bullets and rockets and such it'll be just be a big number so there isn't a much of a limitation there (even with bullets I would want a scenario where the z velocity is so damned strong it changes height at a ridiculous rate to fire up a really steep cliff or at a unit way up in the air such that the projectile is going at a ridiculous speed upwards). I wonder if I can/should just use the maximum speed for the projectile to limit this... z should probably have a different maximum though. I dunno. Maybe speed should limit what is added on to the initial z velocity and I can still have stuff get thrown really high that moves at a slow speed on xy.
 

Attachments

  • SCII Custom Games Invites.png
    SCII Custom Games Invites.png
    332.7 KB · Views: 644
Last edited:
Status
Not open for further replies.
Top