Page 1 of 2

Race Mode .lua coding (Now working!)

Posted: Thu Jul 26, 2007 2:51 pm
by Maveritchell
Honestly, I know this is lazy. And please forgive me for doing this, Zerted, Ace_Azzameen, or anyone else that chooses to answer.

But. I'm trying to figure out a way to code race mode, and I think I've got a decent solution. I already know how to force racers in a certain path, that's not a problem. What I need to do is set up a code in the .lua that does this:

I'm assuming that there are two regions, here. I need region 1 to start a timer when a certain player enters it (keeping in mind other people may enter this region in the interim between this being triggered and region 2 being triggered), and region 2 to end that timer. Then what I need is a certain amount of points awarded based on the time, something like 1 (or whatever positive int)/time.

Also, I assume I could set up an assault mode to work, based on the assumption that a certain amount of points gathered by one team ends the match. It'd be sort've a Tour de France deal, with teams competing, but with individual standings present as well.

Anyway, I'm not sure how to code the first (and I don't even know if it's possible to start multiple instances of the timer while it's still running for one person), and I'm not completely sure it would work in assault mode. Any input would be most appreciated.

Posted: Thu Jul 26, 2007 3:21 pm
by Ace_Azzameen_5
All I did for my race mode was animate a starting gate that opens after a timer elapses, and then made another region that acts as teh finsih line. The game simple announces if someone has won. It should be a simple matter to use that system to assign points to the player whose name is captured by the string 'player' in on enter region. But I don't know how to assign points, just mass search the asset scripts to find out.

region1 = OnEnterRegion(
function(region, player)
if IsCharacterHuman then --optional, will only assign points to human players
addpoints(player, 5) --not actually real points function, I'm guessing.
else
print("AI's don't deserve points. Hmph")
end
end,
"FinishLineRegion"
)

In fact, I'm going to look into that as soon as I can make a region that kills people via luascript. While we're all here:

Code: Select all

----KillRegion
ActivateRegion("KillRegion")--activate now, for testing
region2 = OnEnterRegion(
function(region, player)
if IsCharacterHuman(player) then
print("You may live...")
else
print("Time to respawn...")
KillObject(player)
end
end,
"KillRegion"
)
That outputs the second print message but I don't see any dead AI. This will probably break my above example too, so...yeah.

Posted: Thu Jul 26, 2007 3:27 pm
by Maveritchell
The problem is that I'm trying to make a circuit track, not a simple A-to-B race. That I could do by just simply modifying CTF mode.

Also, my (feasible or not, I do not know) concept allows for second, third, etc. places, instead of just a "Racer X" wins.

EDIT: You say you don't see any dead AI, but it looks like your "Kill Region" is only targeting human players. Maybe that's why it's not working?

Posted: Thu Jul 26, 2007 3:37 pm
by Ace_Azzameen_5
*EDIT*
The If/else statement kills them if they are anything else but human.

Yeah, my race mode is actually currently attempting to be multi-lap, with multiple routes, and is slightly different than my example.

I've learned somewhat since I last worked on it though.

What if we had a region soon after the start line with code like this:

Code: Select all

RacerCount = 0
region1 = OnEnterRegion(
function(region, player)
if RacerCount == 0 then
player = "racer1"
RacerCount = RacerCount +1

elseif RacerCount == 1 then
player = "racer2"
RacerCount = RacerCount +1

elseif RacerCount == 2 then
player = "racer3"
RacerCount = RacerCount +1
end
--and so on for as many racers their could reasonably be.
end,
"StartLineRegion"
)
Wait, does LUA have arrays? (Like I know from JAVA)

And then for every time a player crosses the finish line region we up the value that we can somehow associate with their name string. I'm still thinking on this.

Code: Select all

racer1laps = 0
racer2laps = 0
racer3laps = 0

region1 = OnEnterRegion(
function(region, player)
if player == "racer1" then
racer1laps = racer1laps + 1

elseif player == "racer2" then
player = "racer2"
racer2laps = racer2laps + 1

elseif player == "racer3" then
racer3laps = racer3laps + 1
end
end,
"FinishLineRegion"
)

I suppose each time someone passes  the finish line, you could check how high their laps interger is. If its equal to the amount of laps intended, they win.

Posted: Thu Jul 26, 2007 3:44 pm
by Maveritchell
I'm not sure whose concept we're still working with here, or if it's some strange amalgam of the two, but I think even if we used an array to define a "name" for each player entering the region (at least in my idea), you'd still need multiple regions to trigger a timer (and trigger the finish) for each defined racer (e.g. racer1start, racer2start, etc.) That wouldn't be impossible, but it'd certainly be messy. Not that I mind it too much.

However, I'm still unsure how to work the timer and assign points based on that. (racer1start starts timer for racer1, racer1end ends timer, and points = x/timervalue)

Posted: Thu Jul 26, 2007 3:51 pm
by Ace_Azzameen_5
Well, the first person to win a lap, they get points, and the 2nd less, etc. Same with the end lap. I suppose you haven't read my whole edited post yet.

Posted: Thu Jul 26, 2007 8:50 pm
by [RDH]Zerted
Teancum and I where working on a race mode a while back. It was never finished as we both sort of stopped modding SWBF2 after all the mode's specs got defined. If you want it, I can dig around for the mode's requirements.

A quick overview:

Team 1: Racers
Team 2: Watchers
Team 3: Pit crew
All 3 teams are human playable. Another way to setup the teams would be to have 3 selectable classes per the standard 2 teams per section ( 3 clasess for racer, 3 for watcher, 3 for pit crew).

The racers had no damaging weapons, but had weapons like shrink or slow-down (not sure if this can be done anymore, might crash-to-desktop). When a racer takes damage, he slows down a bit. Racers could not leave the track. Racers could not die. If they somehow did, they would respawn at their last check point. When a racer spawns, he is forced into the vehicle type linked to his unit class. The first few racers to past a checkpoint get the most points. A racer has to pass the checkpoints inorder. The track ends after the first racer passes a given amount of checkpoints (the checkpoints could be looped).

The watchers are there to bother the racers, but could not enter the track. They attempt to damage the racers, which in turns slows them down. Watchers could teleport to the track inorder become part of the pit crew.

The pit crew was supposed to run around healing racers. If they leave the track, they turn into watchers.

Coding wise, tracking the player's progress isn't too hard. You just have to have a counter for how many checkpoints they passed and the name of the next checkpoint they need to pass. I hadn't thought of it, but it can be easily expanded to support multiple checkpoint paths. This mode and coding style does scale from small to large amounts of players.

-------
To give a player points, look at the assualt maps.
You need to kill the player's unit, not the player itself. Or use ScriptCB_PlayerSuicide(player) which would also knock off a point
Lua does not have arrays (at least I don't think so), but it does have tables which can be used in the exact same way.

Posted: Thu Jul 26, 2007 9:24 pm
by Maveritchell
Thanks, guys. I realize and appreciate that both of you have-worked/are-working on race gamemodes, and I realize that they may both be more glamourous than the one I suggested. However, your personal race mode ideas aside, I'd love it if you could help me implement the one I wrote about in the first post. Not to be too-to-the-point or rude, but basically I was asking for the blocks of code that would:

a) define a region that starts a timer
b) define a region that ends the same timer
c) use the timer (i'm assuming this is some kind of 'double' variable) variable and assign points based on that

I really appreciate all the help, but a bit of a personal aside - I've taken a couple years of programming classes, and honestly, it's not my bag. I'll figure it out myself if there's really no other way, but I wanted to basically see if I could be spoonfed the information first, because it'd just be less fun if I do the legwork. Appreciate all the help so far!

Posted: Fri Jul 27, 2007 2:49 am
by lieutenantcoda
OFF TOPIC: so you all are making a racing circuit, what are they gonna be,

podracers or swoops(KOTOR era)

Posted: Fri Jul 27, 2007 8:41 am
by Ace_Azzameen_5
off topic:Swoops(CW-GCW era) - and by that, I mean skinned speeder bikes.
KOTOR era swoops are large vehicles, but SW Swoops first appeared in some GCW EU, or in the background of Ep 4. They are racing speeder bikes.

@Maveritchel, I thought my info was pretty applicable to your idea. Just paste into script post load and start stiching it together and changing it. Shouldn't be to hard even if programming isn't your bag.

I don't know what you mean by assigning points based one a timer. Unfortunately, the only thing Battlefront II reports about timers is that they have ended - the TimerElapse event.

However, you could have a system of two timers. One is one second long; and when it elapses, it is reset to 1 and restarted again. Another timer could serve as a time limit or something that stops the 1 second timer when the longer timer elapses.

For points, you could add a number variable that increases each time the the 1 second timer elapses - the old time = time +1 stuff as seen above*.
When each player ends the race, (enters the finish region), the time it took is noted (player1time = time) and then points are awarded some thing like this
if player1time <30 then
add a jillion points
elseif player1time >30 and <45
add half a jillion points
end
like that.
I'll see if I can code that sometime soon, but first I want get a somewhat enjoyable beta release of my map out, so I'm off to the animated props thread to make me a clone commander to brief you.

*@Zerted Is there some kinda of interger++ thing?

OffTopic:

P.S.
Zerted, can you link me to your holo source? I need to see how you
[RDH]Zerted wrote: -learned to edit a single unit's stats instead of an entire class' stats (think droppable kits like BF2)
I thought the player returned by some of the events was a spawned unit, but apparently there most be some kind of GetPlayerCharacter or Unit. TYIA. Parrantly the AI players are non-entities refered to as numbers.
Message Severity: 2
C:\Battlefront2\main\Battlefront2\Source\LuaCallbacks_Mission.cpp(635)
Entity "34" not found
*edit*Sucide doesn't seem to work on AI, but it does know to look for players and not entities (no above message)

Posted: Fri Jul 27, 2007 4:02 pm
by Maveritchell
Ace_Azzameen_5 wrote: I don't know what you mean by assigning points based one a timer. Unfortunately, the only thing Battlefront II reports about timers is that they have ended - the TimerElapse event.
That's sort've what I was wondering. That is to say, then that you can't set the value of a timer at a certain time (something like getValue(timer) that would output whatever # of time units remaining)? I understand, too, the concept of your 1-second-timer within a larger timer, but can one nest timers like that?

---

EDIT: I think I figured out how to do the whole race setup without a timer, but I'll need someone to proof the idea to make sure it doesn't have any holes before I code it, since it's a monster block of code:

1) Assign variables racer (=1, =2, etc. to define the racer), r1lap (r2lap, etc.) (=1-5, for the lap a specific racer is on), and trigger (basically a binary variable, to decide whether the lapcount goes up - this is just here to prevent people entering a region, backing up, and reentering to boost their lapcount.)

-In this example, I'm assuming there are 5 laps

2) Make 3 regions (one right in front of the other) in front of the starting line.
a) First one sets the base variable values (racer = x, rxlap = 0, and trigger = 0), then kills itself.
b) Second one adds 1 to rxlap then sets trigger = 0, if "trigger" = 1 (its base value is 0)
c) Third one checks to see if r1lap + r2lap +.... rxlap == 5*x, and if rxlap == 5

3) Make a region at the end of the track (inaccessible when going backwards, i.e. on top of a dropoff) that sets trigger = 1.

4) Assign points based on how many racers have finished 5 laps. If rxlap == 5, then it'll figure out what the total (r1lap + r2lap +.... rxlap = everyoneslaptotal) is (some multiple of 5), and can assign points based on the inverse of that (e.g. 5*x/everyoneslaptotal).

---
EDIT2: I typed it up, minus the parts I'm currently unsure about, and if you want you can look at it here (I've still got to change some stuff, e.g. all the OnEnterRegions referring to region1)

racemode.txt

Posted: Sat Jul 28, 2007 6:41 pm
by Ace_Azzameen_5
I'm looking at it, I'll edit with updates.

First of all, you've got all those variables being set to 0 when this first person enters the region. Whats the point? You can just get rid of the event and let the integers be set to 0 when the map loads.

Another thing, the 'region1 =' might cause problems. I think you have to make it a different name for each OnEnterRegion. As I understand, 'region'1 is being made into a custom event. For some reason, enter region won't work with out sakdj =, for me.

I understand and like your trigger idea. Players have to go all the way around to the top of the cliff to get points.

Posted: Sat Jul 28, 2007 7:49 pm
by Maveritchell
Yeah, "region1=" is just a placeholder. I copied and pasted a lot; that was just a concept script. Your "assigning a string to each unit" I thought was pretty good, and I have it in there. The one thing I'm not sure about, though, is how to assign points with the .lua. I've looked through the stock scripts, and I don't see anything (not that I think I would, as I don't remember any event explicitly giving the player points).

And ah, I didn't realize that the variables were initially set at zero. I was going more in the java mindset, where you have to define a variable with a number before you can start operating on it.

Posted: Sat Jul 28, 2007 9:52 pm
by Ace_Azzameen_5
Check some the of Objective Scripts in data_ayb/common/scripts.

Posted: Sat Jul 28, 2007 10:22 pm
by Maveritchell
Lol, right as I started to post that I hadn't found anything, I opened up ObjectiveAssault again and found this:

AddAssaultDestroyPoints(killer)

I'm pretty sure that'll work for what I want.

Also, I actually did find a gettimer function, and I almost had the name right in my guess: it's GetTimerValue(timer). Turns out that the race mode could be done with a timer should one want to.

Posted: Sat Jul 28, 2007 10:46 pm
by Ace_Azzameen_5
Cool. That should help me make some of my code more efficient. Saving nanoseconds! :oops: I hope thats not right in the docs.

Posted: Sat Jul 28, 2007 10:51 pm
by Maveritchell
I'm still trying to figure out if there's any way to manipulate that add points call, though. In fact, I can't even figure out a way to assign multiples of whatever-point-value-that-is without just writing it repeatedly. Which is messy. Ugh.

EDIT: Argh. I "finished" my racemode script, which I just copied-and-pasted into a tdm .lua. It doesn't cause any errors, but something's preventing it from doing what I want it to do (which is mostly described in my last post, the only difference is this one has the points-adding function). Someone care to proofcheck it?

racemode.txt

Posted: Sun Jul 29, 2007 9:09 am
by Ace_Azzameen_5
AddAssaultDestroyPoints(killer) should be AddAssaultDestroyPoints(player) for one thing.

Killer is just a string (killer = "[GT]Cmndr_Fusion" or AI killer = "35") asinged by the engine to be whoever killed someone when you use OnCharacterDeath or other such things.

Player is the same but for the player that enters the region. So yeah. Try it then. Also, your BF2 log shows nothing?

Posted: Sun Jul 29, 2007 2:26 pm
by Maveritchell
Whoops. I knew I needed to replace "killer," but I never did. Also, thanks for the heads up on it being "player," I was going to sub in the strings for each player, as I assumed that "killer" was a string assigned to a player, not a string that had its own definition.

Yeah, no problems in BF2log. I've not tested it since fixing it, but all I really tested initially was to see whether I would get points on finishing 5 laps. (I woulda had a hard time testing to see whether I could get the game to end when all 10 racers finished, since I haven't set up the AI completely.) I also think I'm going to add a timer that kills the game after "X" minutes, since it would be no fun to have to wait for the last dumb AI to finish, or whatever.

EDIT: Even after I fixed that, it still doesn't show any points gain for finishing 5 laps. Also, there's still nothing pertinent in the BF2log.

Posted: Sun Jul 29, 2007 4:52 pm
by Ace_Azzameen_5
A simple tip courtesy of Zerted:
print("") will output stuff into the bf2log.
So, for example, inside each region event, you could put "xxx region triggered"

Also, ShowMessageText(LOCALIZATION.KEY.HERE, REP) {[ , TEAM] is optional} will print stuff in game. You could always leave it blanl to make <null> come up.