• Do not use Works in Progress as a way of avoiding the releases system! Works in Progress can be used for sharing early betas and for getting suggestions for improvement. Releases of finished content are not allowed in this forum! If you would like to submit a finished addon, click here for instructions on how to do so.

Yoshi's Luas (Maybe eventually SOCs...?)

Status
Not open for further replies.
This is my thread for posting things I make with SOCs and Lua. Right now, I don't have any SOCs to show, but I have Luas:

Code:
--Yoshi's Quick Stop Ability

local CanQuickStop = 1
local HasQuickStopped = 0
addHook ("ThinkFrame", 
                    for player in players.iterate
                                        if player.valid then
                                        if player.mo.skin == "yoshi" and player.mo.health >= 21 and (player.cmd.buttons & BT_USE) and player.mo.z > player.mo.floorz and CanQuickStop == 1 and HasQuickedStopped == 0 and not player.powers[pw_super] then
                                        player.mo.health = player.mo.health - 
                                        player.health - 
                                        player.mo.momx = 0
                                        player.mo.momy = 0
                                        player.mo.momz = 0
                                        CanQuickStop = 0
                                        HasQuickStopped = 1
                                        elseif player.mo.z == player.mo.floorz and CanQuickStop == 0 then
                                        CanQuickStop = 1
                                        HasQuickStopped = 0
                                        end
                                        end
                    end
end)

Code:
--Yoshi's Super Floating Script

local PlayerIsFloating = 0
addHook("ThinkFrame", do
                   for player in players.iterate
                                       if player.valid then
                                                          if player.mo.skin == "yoshi" and player.powers[pw_super] and player.mo.z > player.mo.floorz and (player.cmd.buttons & BT_USE) then
                                                                              player.mo.momz = 0 
                                                                              player.mo.state = 31 
                                                                              PlayerIsFloating = 1 
                                                          else
                                                          PlayerIsFloating = 0 
                                                          end
                                                          if PlayerIsFloating == 1 then
                                                          player.charability = 0
                                                          end
                                                          if player.mo.z == player.mo.floorz and player.mo.skin == "yoshi" then 
                                                          player.charability = 1
                                                          end
                                       end
                    end
end)

The only problems these scripts have is as a spectator in multiplayer it gives a small warning, but they work properly afterwards.

Feedback on these/ways to optimize them would be great.

Also... any ideas for something I should try to script? It doesn't matter if it's been done before, I just need something to make to get better.
 
Last edited:
You have to check if a player is not a spectator and if their mo exists and is valid so it stops throwing errors when spectating.
 
Rapidgame7 said:
You have to check if a player is not a spectator and if their mo exists and is valid so it stops throwing errors when spectating.
That makes sense. Also, as a general question, I altered the Quick Stop script so it doesn't work when Yoshi has a Whirlwind/Armageddon Shield.
Code:
(player.powers[pw_shield & SH_JUMP|SH_BOMB)
Code:
(player.powers[pw_shield] & SH_JUMP) or (player.powers[pw_shield] & SH_BOMB)

Are these interchangeable? Or does the first not work?
 
The first doesn't work, but only because you missed a ] after pw_shield. They're both equivalent, otherwise.

They're not actually doing what you want, though! SH_JUMP and SH_BOMB aren't flags, they're constants - you want to use the == operator. Specifically, I think the following is what you want to do:

Code:
(((player.powers[pw_shield] & SH_NOSTACK) == SH_JUMP) or ((player.powers[pw_shield] & SH_NOSTACK) == SH_BOMB)))
 
Well, I finally got around to spectator checking in Yoshi's floating script. I didn't update his Quick Stop script though. Rather, I deleted it since it wasn't really helping. I mean, seriously, it's supposed to help if an instant midair stop is needed (which is generaly rare), it's a pain in the ass to time it right when needed, and, well, without being disabled when having at least the whirlwind shield, 20 rings made the whirlwind shield useless.

Anyway, aside from that, I've been working on a new script lately. It works, but it's probably not done. It's a bit longer, so I put it in spoilers.

Code:
--Super Set Script
print("To override any custom character's super color's add this script after the character")
local SuperSet = "sonic"

COM_AddCommand("SuperSet", function(player, SuperSetColor)
	if SuperSetColor == none or string.lower(SuperSetColor) == "help" then
		print("Usage: 'SuperSet <Sonic/Tails/Knuckles>")
	elseif string.lower(SuperSetColor) == "tails" then
		SuperSet = "tails"
		print("Super Color Set is now set to Tails")
	elseif string.lower(SuperSetColor) == "knuckles" then
		SuperSet = "knuckles"
		print("Super Color Set is now set to Knuckles")
	elseif string.lower(SuperSetColor) == "sonic" then
		SuperSet = "sonic"
		print("Super Color Set is now set to Sonic")
	else
		print()
		print("The Super Color Set you specified is not an available Super Set")
		print()
		print("Type 'superset' or 'superset help' for further info.")
	end
end)
addHook("ThinkFrame", do
	for player in players.iterate
		if SuperSet == "tails" and player.powers[pw_super] then
			if player.mo.color == SKINCOLOR_SUPER1 then
				player.mo.color = SKINCOLOR_TSUPER1
			elseif player.mo.color == SKINCOLOR_SUPER2 then
				player.mo.color = SKINCOLOR_TSUPER2
			elseif player.mo.color == SKINCOLOR_SUPER3 then
				player.mo.color = SKINCOLOR_TSUPER3
			elseif player.mo.color == SKINCOLOR_SUPER4 then
				player.mo.color = SKINCOLOR_TSUPER4
			elseif player.mo.color == SKINCOLOR_SUPER5
				player.mo.color = SKINCOLOR_TSUPER5
			end
		elseif SuperSet == "sonic" and player.powers[pw_super] then
			if player.mo.color == SKINCOLOR_SUPER1 then
				player.mo.color = SKINCOLOR_SUPER1
			elseif player.mo.color == SKINCOLOR_SUPER2 then
				player.mo.color = SKINCOLOR_SUPER2
			elseif player.mo.color == SKINCOLOR_SUPER3 then
				player.mo.color = SKINCOLOR_SUPER3
			elseif player.mo.color == SKINCOLOR_SUPER4 then
				player.mo.color = SKINCOLOR_SUPER4
			elseif player.mo.color == SKINCOLOR_SUPER5 then
				player.mo.color = SKINCOLOR_SUPER5
			end
		elseif SuperSet == "knuckles" and player.powers[pw_super] then
			if player.mo.color == SKINCOLOR_SUPER1 then
				player.mo.color = SKINCOLOR_KSUPER1
			elseif player.mo.color == SKINCOLOR_SUPER2 then
				player.mo.color = SKINCOLOR_KSUPER2
			elseif player.mo.color == SKINCOLOR_SUPER3 then
				player.mo.color = SKINCOLOR_KSUPER3
			elseif player.mo.color == SKINCOLOR_SUPER4 then
				player.mo.color = SKINCOLOR_KSUPER4
			elseif player.mo.color == SKINCOLOR_SUPER5 then
				player.mo.color = SKINCOLOR_KSUPER5
			end
		end
	end
end)

Basically, you specify a "Super Set", which is used to determine what colors are used when super. Currently, the sets are "Sonic", "Tails", and "Knuckles". ...and yes, I know that I'm pointlessly checking SKINCOLOR_SUPER# and then setting that exact color. (For the "Sonic" set, it checks for SKINCOLOR_SUPER1, and if the player's color matches, it sets their color to it, even though it was already that color. Does that for each color in the "Sonic" set.) I know it's not necessary, but I like keeping each part of my script consistent with other parts. I'm thinking of adding a few other sets, though. Might try for a release if I can get a few more sets.
 
This is very much like a script I made in the past which lets players change their super color to a variety of preset options, like red, blue, or even brown! This is the method my version used to use, but there are a few things I'd like to address in yours.

First of all—it doesn't matter how much you like to have consistent parts in your script, it's always bad practice to include code that is redundant or unnecessary. Think about it—your code is checking every frame to see if the player has the "sonic" SuperSet and is super, and if those conditions are true, it'll set the player's color to... the very same color. It's not like that small block of code is going to completely lag a server down, but why put any extra stress on the game at all? Coding is all about efficiency and if you're anything like me you'll continue to discover new ways to make your scripts shorter and faster every day. The earlier you start to learn that, the better. With that said, you can still make that block of code useful! How about detecting whether the player is using TSUPER or KSUPER supercolors, so that Tails and Knuckles can use Sonic's SuperSet? ;)

The second issue is one that you'll actually need to fix for this to be practical in netgames. It's a hard concept to understand when you're starting out so don't worry if this confuses you, but Lua scripts are actually loaded client-side, meaning each player's game runs the code separately from every other person in the netgame. The game thankfully keeps track of variables stored in players, objects, etc.—but not any local variables outside of your hooks. This means your SuperSet variable is automatically set to "sonic" for every client, but when it's changed via your console variable, it ONLY changes that variable for the client, and not for all the other people connected to the server. This is what causes desynchs in netgames, as not all the players' games are exactly the same anymore. Whether you understand that or not, the fix is simple—make the variable a player variable (i.e. "player.SuperSet"). The game will synchronize the variable among all clients, and it'll allow you to give different SuperSets to each player, which I assume is what you were going for in the first place! c:
 
Ah, thanks. Also, and this is something I've thought about but haven't attempted, but I should be able to use variables to basically make the number of super colors in a set four instead of five, right? Trying to come up with sets for red, blue, and black/white, but I can only come up with four colors. I have however made three other sets, rainbow, orange, and violet.
 
Nvm, I think I've got it. For "player.SuperSet", to I just do "player.SuperSet = "Sonic"" since local "player.SuperSet = "Sonic"" doesn't work? Or am I completely wrong on that?

I did manage variables for black and white, but it's only run occasionally since it isn't finished yet, but I shouldn't have anymore problems now that I've figured it out.

Actually, in terms of lua scripting in srb2 as a whole, how difficult is lessening the super colors from five to four? I'm working on doing so, but I'm just wondering if it's actually something that should be challenging, or if the fact I find it somewhat difficult is just my lack of experience with lua.
 
That is correct, there is no need to put "local" in front of player.SuperSet. The variable is stored in the player's set of instance variables—it acts just like the value stored in player.mo.color or the table stored in player.powers!

You can set your own number of skin colors to switch between by using a timer. You don't even need to set one up yourself; player.powers[pw_super] is itself a timer! It counts up by 1 every tic that the player is super, starting from the transformation phase. The best way to work from here is to use the modulus operation. The modulus operation is the % sign, and it returns the remainder of the first number divided by the second number. For instance, 10 % 5 is equal to 0, because 10 evenly divides into 5 in sets of 2. 10 % 3 is equal to 1, because 10 can divide into 3 in sets of 3, but there's a remainder of 1. Knowing this, you can set up a timer such that the remainder changes as the timer counts up. For example, pretend you perform "timer % 3" where timer starts at 0:
Code:
0 % 3 yields 0
1 % 3 yields 1
2 % 3 yields 2
3 % 3 yields 0
4 % 3 yields 1
5 % 3 yields 2
6 % 3 yields 0
7 % 3 yields 1
8 % 3 yields 2
9 % 3 yields 0
10 % 3 yields 1

...and so on. You'll notice that the numbers start to repeat themselves as the timer increases! This is how we can get skin colors to repeat as player.powers[pw_super] goes up. So, let's say we want to switch between 4 skin colors for a black/white super color—white, silver, grey and black. We'll calculate player.powers[pw_super] % 4, because that will repeat digits 0 - 3!
Code:
local timer = player.powers[pw_super] % 4
		
if timer == 0 then mo.color = SKINCOLOR_WHITE
elseif timer == 1 then mo.color = SKINCOLOR_SILVER
elseif timer == 2 then mo.color = SKINCOLOR_GREY
elseif timer == 3 then mo.color = SKINCOLOR_BLACK
end
This works just fine—but it's also repeating every 4 tics, so it'll flash really fast. Let's say we want each color to last 7 tics. We can divide player.powers[pw_super] by 7 to get a timer value that only changes every 7 tics:
Code:
local timer = (player.powers[pw_super]/[b]7[/b]) % 4
		
if timer == 0 then mo.color = SKINCOLOR_WHITE
elseif timer == 1 then mo.color = SKINCOLOR_SILVER
elseif timer == 2 then mo.color = SKINCOLOR_GREY
elseif timer == 3 then mo.color = SKINCOLOR_BLACK
end
That looks a lot smoother! But... what if we wanted it to fade from black back to white instead of switching directly from black to white? We can just add more possible values to the remainder!
Code:
local timer = (player.powers[pw_super]/7) % [b]7[/b]
		
if timer == 0 then mo.color = SKINCOLOR_WHITE
elseif timer == 1 or timer == 6 then mo.color = SKINCOLOR_SILVER
elseif timer == 2 or timer == 5 then mo.color = SKINCOLOR_GREY
else mo.color = SKINCOLOR_BLACK
end

There's a lot of freedom with what you can do with division and remainders. Just within that one line, you can change the duration of each color and how many colors it cycles through! If you study hard in your math classes you'll get really good at figuring out cool ways to use math in your programming. Hopefully that crash course is enough to get you started. c:
 
Umm... my head hurts now? I'm just gonna stick with my custom variable timers... They're so much easier to understand. In case you're wondering what it is:

Code:
if CurrentColor == 1 then
        player.mo.color = SKINCOLOR_WHITE
        if CountDown == 0 then
                  CountDown = 1 * TICRATE / 12
                  CurrentColor = 2
        else
                  CountDown = CountDown - 1
        end
 
I've now finished black and white, and added the red and blue sets. So now, the available sets are "Sonic", "Tails", "Knuckles", "Red", "Blue", "Orange", "Violet", "BlackAndWhite", and "Rainbow".
 
New script!!!!!!

While I'm waiting for SuperColors.lua in submissions, I've started a new script. You may have seen me talk about it slightly in Editing Help, but here's what I've got so far: (There's no menu, and you can't do upgrades yet)

Code:
///////////////////////////////////////////////////////////////////////////////////////////////////////
////////                               "Upgrades.lua"                               ////////
////////                                  Created By:                                 ////////
////////                                 Yoshirocks90                               ////////
////////                                     (Yoshi)                                     ////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
////////                      "Upgrades.lua" is a lua script                ////////
////////                       that was made for upgrading               ////////
////////                       various aspects of the game.              ////////
////////                              Upgrades include:                        ////////
////////                                Character Stats                          ////////
////////                                   Shield Stats                            ////////
//////////////////////////////////////////////////////////////////////////////////////////////////
////////                          Comments provided for                  ////////
////////                              your convenience                       ////////
/////////////////////////////////////////////////////////////////////////////////////////////////

addHook("ThinkFrame", do	//Add the hook for the ring bank.
	for player in players.iterate
		if player.exiting and not player.HasBanked then	//Check if the player is exiting and the player's rings have not yet been banked.
			player.RingBank = player.RingBank + (player.health - 1)	//Set the ring bank value.
			player.HasBanked = true	//This is used in the previous if statement. If this is true then rings aren't banked.
		elseif player.RingBank == none then	//If the ring bank is non-existent, set it to zero. This keeps warnings from being spammed in the console.
			player.RingBank = 0
		elseif not player.exiting then		//Check if the player is exiting. If not, then the rings are ready to be banked.
			player.HasBanked = false
		end
	end
end)

local function drawhud(v, player, cam)		//Creating the function for the custom HUD.
	v.drawString(16, 58, "Banked Rings:")	//Create the string of text for the ring bank.
	v.drawNum(130, 58, player.RingBank)	//Show the number of banked rings.
	v.drawString(16, 72, "Max Speed:")	//Create the string of text for the player's max speed
	v.drawNum(130, 72, (player.normalspeed/FRACUNIT))	//Show the player's max speed
end

hud.add(drawhud)		//Add the HUD

...I've been trying to get into putting comments in my scripts for those who look at the code. (The slashes at the end of the starting lines aren't like that in the file)

What I intend to do is eventually allow the player to upgrade their speed, jump height, and upgrade the shields, such as making the force shield last longer (increasing the number of hits it can take from 2 to 3, and so on), as well as upgrades that give the shields new abilities (this has to be experimented with before I add anything like this). There'll probably end up being more to it than this, but this is what I've got so far.
 
If you don't know them, so then it's a fake thread!
"Yoshi's SOCs and Lua"
Whatever, learning SOC should be easy, Lua is harder.
 
To further my previous six-word sentence, my first SOC and my first Lua were both edits of the wiki's tutorials. The monitor spawning script was edited to be a successful way of spawning the chaos emeralds, then spawning ring monitors once the player had them all. My first SOC, on the other hand, was much more complicated; I edited the tutorial for enemies and made a stupid Sonic bot that was spawnable with objectplace. By stupid, I don't mean it was a bad idea, but rather that he lacked any real intelligence, as he couldn't run, jump, take damage, and would annoyingly pass through the player nonstop.

Because my first Lua was more successful than my first SOC, I've always found Lua to be easier.

Now, as for my real purpose for posting...


Upgrades.lua (Currently name Upgrades-Ex.lua ("Ex" means "Experimental") has some new progress:

A menu:
attachment.php


Upgradable stats:
attachment.php


Upgradable shields:
attachment.php


That's right! You can change the menu's background color!
attachment.php


I haven't really worried too much about the positioning of text, since I've been working on the main features. The menu control is also slightly buggy. I also intend to add a command for changing the menu's text color.

Also, and this has been fixed through a work-around, but does anyone know why "player.JumpBoost = $ + (1/4)" and "player.JumpBoost = player.JumpBoost + (1/4)" both make player.JumpBoost equal zero, while "player.JumpBoost = (1/4)" works just fine?
 

Attachments

  • srb20583.jpg
    srb20583.jpg
    38.8 KB · Views: 540
  • srb20584.jpg
    srb20584.jpg
    43.9 KB · Views: 568
  • srb20585.jpg
    srb20585.jpg
    36.6 KB · Views: 534
  • srb20586.jpg
    srb20586.jpg
    34.9 KB · Views: 583
There are no decimals or fractions in SRB2 Lua; therefore, 1/4 is actually equal to 0 (the number rounds down to the nearest integer—so 11/4 is equal to 2). If you want to get a portion of a number, multiply it by the FRACUNIT constant first. For instance, FRACUNIT/4 gives you a quarter of a FRACUNIT. Assuming you're working with changing player.jumpfactor, you'll want to use FRACUNITs anyway if you want to make any substantial difference. (player.jumpfactor is measured in FRACUNITS, so a jumpfactor of 2*FRACUNIT is a jump height with twice as much power as Sonic's jump).
 
Status
Not open for further replies.

Who is viewing this thread (Total: 1, Members: 0, Guests: 1)

Back
Top