Jump to content

CTV


RA

Recommended Posts

Intro:

Well, I wrote my first mtama mod, called "Capture the Vehicle" for a LAN party that I helped host. This is a GTA3-only mod (not Vice City). However, it could be very easily converted to GTAVC by changing the target vehicles in the two functions (ctvGetVehId & ctvGetVehName) and the locations (in function ctvCheck). This mod is geard towards a group of gamers who had little experience with GTA and even less experience with multiplayer GTA.

Summary:

The mod itself involves finding and staying in a certain set of vehicles (all on the west side of the map). Once you accumulate 2 minutes of "target vehicle" time, you get 20 points. You also get 5 points per person that you kill (anytime), and you loose 1 point for dying. Also, players in the current target vehicle must stay on the west map or get slapped. This was done to keep everyone near a certain spot on the map.

Coding the mod (obligatory rant):

When I started writing this mod, I figured it would be fairly easy to do certain things. However, it became painfully obvious that there is almost nothing that I can do to make this mod much better. The most important thing I wanted was to have a dot over the target vehicle on the minimap. Alas, neither this, nor rewarding cash or weapons (the second most important thing) was possible. Also, why in the world do vehicles respawn with damage?

Constructive criticism for other scripters:

One other thing I noticed when trying to get inspiration from other mtama mods was that people were constantly using ini files to store variables. Why not just use a standard mirc global variable instead? When naming variables, try to use descriptive names instead of the cryptic single-letters that I often saw. Finally, try to comment your code a bit. All of these problems combined makes the script hard to read and maintain.

Fun:

Taking everything into consideration, I still had a good time. In our LAN party setting with everyone in the same room (and fairly trustworthy), this mod served its purpose and will probably be used in the future.

To run:

First save the code below to a .mrc mIRC script file. Be sure you have mtama set up in mIRC and load the script into MTA. To start CTV, run !ctv on as admin, or any user can start it the first time by typing !begin. During CTV gameplay, players can type !help for the current target vehicle or !score for their score. After 60 minutes, the game ends. You can also set up one player as ctv-admin (currently its IP 127.0.0.1 for testing) and that person can do a few extra things like change the target vehicle (using !next).

CTV 1.04.mrc

; Triggered when a admin says something. $1 = Server, $2- = Text 
alias mta.admin { 
  if ($2 == !ctv) { 
     ctv $1 $3-  
  }
  else if ($2 == !cmd) {
     mta.command $1 $3 $4-
  }
}

; Triggered to start ctv mode. $1 = Server, $2 = on/off 
alias ctv { 
  if ( $2 == on ) {
     if ( $mta.admin+($1) ) {               
        echo Starting CTV v1.04 by Aaron ([email protected]) - server $1
        mta.say $1 CTV - Head West to find the action!
        unset %CTV $+ [ $1 ] $+ *
;        Set IP of admin 
        set %CTV $+ [ $1 ] $+ ADMINIP 127.0.0.1
        .timerctv $+ $1 1 3600 ctv $1 off
        .timercheck $+ $1 1 10 ctvNextVehicle $1
     } 
     else {  
        mta.say $1 No admin+ connection! 
     }
  } 
  else if ($2 == off) {
     var %id = $ctvGetHighScoreId($1)
     mta.say $1 Capture the Vehicle game over.
     if ( %id != $null ) {
        mta.say $1 $mta.name($1,%id) won with %CTV [ $+ [ $1 ] $+ ID $+ [ %id ] $+ SCORE ]         
     } 
     else {
        mta.say $1 No winner: Everyone sucks!
     }

     unset %CTV $+ [ $1 ] $+ *
     .timerctv $+ $1 off
     .timercheck $+ $1 off
  }
}

; Called periodically to check the target 
alias ctvCheck { 
  var %time = $ctvGetTargetTime($1)
  var %goal = 120
  inc %CTV [ $+ [ $1 ] $+ UPDATE ]
;  Nobody is in target vehicle 
  if ( %time == 0 ) { 
     if ( %CTV [ $+ [ $1 ] $+ UPDATE ] > %CTV [ $+ [ $1 ] $+ LOST ] ) {
;        mta.say $1 Target vehicle lost. Choosing new vehicle...
        $ctvNextVehicle($1)
     }
  } 
;  Someone is in target vehicle
  else { 
     var %id = %CTV [ $+ [ $1 ] $+ TARGET ]
     var %loc = $mta.area($1,%id)       

     var %safeloc = 0
     if ( [ %loc ] == Hepburn-Hights Portland ) { inc %safeloc }
     if ( ( %safeloc == 0 ) && ( [ %loc ] == Red-Light-District Portland ) ) { inc %safeloc }
     if ( ( %safeloc == 0 ) && ( [ %loc ] == Chinatown Portland ) ) { inc %safeloc }
     if ( ( %safeloc == 0 ) && ( [ %loc ] == Callahan-Bridge Portland ) ) { inc %safeloc }
     if ( ( %safeloc == 0 ) && ( [ %loc ] == Callahan-Point Portland ) ) { inc %safeloc }
     if ( ( %safeloc == 0 ) && ( [ %loc ] == Chinatown Portland ) ) { inc %safeloc }
     if ( ( %safeloc == 0 ) && ( [ %loc ] == Portland ) ) { inc %safeloc }
;     Target player is in bounds   
     if ( %safeloc > 0 ) { 
;        Player has reached time goal in target
        if ( %time > %goal ) { 
           inc %CTV [ $+ [ $1 ] $+ ID $+ [ %id ] $+ SCORE ] 20
           mta.say $1 $mta.name($1,%id) has won a round! Score: %CTV [ $+ [ $1 ] $+ ID $+ [ %id ] $+ SCORE ]
           unset %CTV [ $+ [ $1 ] $+ ID $+ [ %id ] $+ TIME ]     
           unset %CTV [ $+ [ $1 ] $+ TARGET ]
           .timercheck $+ $1 1 10 ctvNextVehicle $1 
        } 
        else if ( 6 // %CTV [ $+ [ $1 ] $+ UPDATE ] ) {
           mta.say $1 $mta.name($1,%id) has $calc( %goal - %time ) sec left at %loc
        } 
     } 
;     Target player is out of bounds 
     else { 
        if ( 2 // %CTV [ $+ [ $1 ] $+ UPDATE ] ) {
           set %CTV [ $+ [ $1 ] $+ TICKS ] $ticks
           if ( %time > 30 ) {              
              set %CTV [ $+ [ $1 ] $+ ID $+ [ %id ] $+ TIME ] $calc( ( %time - 30 ) * 1000 )               
           }
           inc -u99 %CTV [ $+ [ $1 ] $+ ID $+ [ %id ] $+ TOAST ]
           if ( %CTV [ $+ [ $1 ] $+ ID $+ [ %id ] $+ TOAST ] > 2 ) {               
              unset %CTV [ $+ [ $1 ] $+ ID $+ [ %id ] $+ TIME ]
              mta.say $1 /slap $mta.name($1,%id) 
              mta.say $1 /slap $mta.name($1,%id)                
              if ( %CTV [ $+ [ $1 ] $+ ID $+ [ %id ] $+ TOAST ] > 5 ) {
                 unset %CTV [ $+ [ $1 ] $+ TARGET ]
                 ctvNextVehicle $1
              }

           }
           else {
              mta.say $1 $mta.name($1,%id) is AWOL at %loc
           }
        }
     }

  }
}

; Called when a new target vehicle needs to be chosen 
alias ctvNextVehicle { 
  var %vehnum = $calc( ( $ticks % 7 ) + 1 ) 
  var %lastvehicle = %CTV [ $+ [ $1 ] $+ VEH ]

;  Use this part to try to get an empty vehicle
  var %tries = 0
  while ( %tries < 7 ) {
     inc %tries
     inc %vehnum
     if ( %vehnum == %lastvehicle ) {
        inc %vehnum         
     }   
     if ( %vehnum > 7 ) %vehnum = 1
     set %CTV [ $+ [ $1 ] $+ VEH ] %vehnum
     if ( $mta.vehicle($1,$ctvGetVehId($1)).list == -1 ) {
        set %tries 10
     }      
  }

  set %CTV [ $+ [ $1 ] $+ UPDATE ] 0
  set %CTV [ $+ [ $1 ] $+ LOST ] 60

  echo Next vehicle: $ctvGetVehName($1)
  mta.say $1 Capture $ctvGetVehName($1) 
  .timercheck $+ $1 0 2 ctvCheck $1
}

; Get the MTAMA ID of the target vehicle 
alias ctvGetVehId { 
  var %vehnum = %CTV [ $+ [ $1 ] $+ VEH ]
  if      ( %vehnum == 1 ) { return 59 }
  else if ( %vehnum == 2 ) { return 33 }
  else if ( %vehnum == 3 ) { return 58 }
  else if ( %vehnum == 4 ) { return 8  }
  else if ( %vehnum == 5 ) { return 35 }
  else if ( %vehnum == 6 ) { return 56 }
  else if ( %vehnum == 7 ) { return 57 }
  else                     { return zz }
}

; Get the name of the target vehicle 

alias ctvGetVehName { 
  var %vehnum = %CTV [ $+ [ $1 ] $+ VEH ]
  if      ( %vehnum == 1 ) { return Linerunner the semi-truck }
  else if ( %vehnum == 2 ) { return Rumpo the black van }
  else if ( %vehnum == 3 ) { return Mr. Whopee the ice cream truck }
  else if ( %vehnum == 4 ) { return Mule the fish truck }
  else if ( %vehnum == 5 ) { return DoDo the airplane }
  else if ( %vehnum == 6 ) { return Infernus the Lamborghini }
  else if ( %vehnum == 7 ) { return Idaho the boat car }
  else                     { return BugBear! }
}

; Get the total time the target player has
alias ctvGetTargetTime { 
  var %target = %CTV [ $+ [ $1 ] $+ TARGET ]  
  if ( %target != $null ) {      
     var %oldtime = %CTV [ $+ [ $1 ] $+ ID $+ [ %target ] $+ TIME ]
     if ( %oldtime == $null ) {
        %oldtime = 0
     }
     var %time = $calc( %oldtime + $ticks - %CTV [ $+ [ $1 ] $+ TICKS ] )
     if ( %time == $null ) { 
        %time = 0
     }
     %time = $floor($calc(%time / 1000))

     return %time
  } 
  else {
     return 0
  }
}

; Get the player ID with the highest score 
alias ctvGetHighScoreId { 
  var %playerindex = 0   
  var %playerscore = 0

  var %highscore = 0
  var %highplayerindex = $null
  while ( %playerindex < 32 ) {
     var %playerscore = %CTV [ $+ [ $1 ] $+ ID $+ [ %playerindex ] $+ SCORE ]
     if ( %playerscore > %highscore ) {
        %highplayerindex = %playerindex
     }
     %playerindex = %playerindex + 1
  }
  return %highplayerindex      
}

; Send message to server. $1 = Server
; This is due to a bug in mtama
alias ctvSay {
}

; Triggered when a player joins the game. $1 = Server, $2 = PlayerID 
alias mta.join { 
  if ($timer(ctv $+ $1)) {
     unset %CTV [ $+ [ $1 ] $+ ID $+ [ $2 ] $+ TIME ]
     unset %CTV [ $+ [ $1 ] $+ ID $+ [ $2 ] $+ SCORE ]
  }
}

; Triggered when a player is killed or died. $1 = Server, $2 = PlayerID, $3 = KillerID, [$4 = WeaponID] 
alias mta.kill { 
  echo Player $2 $mta.name($1,$2) killed by $3 $mta.name($1,$3) with $4 $mta.weapon($1,$4)
  inc %CTV [ $+ [ $1 ] $+ ID $+ [ $3 ] $+ SCORE ] 5
  dec %CTV [ $+ [ $1 ] $+ ID $+ [ $2 ] $+ SCORE ] 1
}

; Triggered when a player gets out of a vehicle. $1 = Server, $2 = PlayerID, $3 = VehicleID 
alias mta.exit { 
  if ($timer(ctv $+ $1)) {
;     Player is getting out of the target vehicle
     if ( %CTV [ $+ [ $1 ] $+ TARGET ] == [ $2 ] ) { 
        $ctvCheck($1)
        if ( %CTV [ $+ [ $1 ] $+ TARGET ] != $null ) {
           var %time
           mta.say $1 Capture $ctvGetVehName($1) at $mta.area($1,$2)
           %time = $calc( %CTV [ $+ [ $1 ] $+ ID $+ [ $2 ] $+ TIME ] + $ticks - %CTV [ $+ [ $1 ] $+ TICKS ] )
           set %CTV [ $+ [ $1 ] $+ ID $+ [ $2 ] $+ TIME ] %time
           unset %CTV [ $+ [ $1 ] $+ TARGET ]
           set %CTV [ $+ [ $1 ] $+ LOST ] $calc( %CTV [ $+ [ $1 ] $+ UPDATE ] + 60 )
        }
     }
  }
}

; Triggered when a player gets in a vehicle. $1 = Server, $2 = PlayerID, $3 = VehicleID
alias mta.enter { 
  if ($timer(ctv $+ $1)) {
;     echo $1 $mta.name($1,$2) in $mta.vehicle($1,$2)
     if ($3 == $ctvGetVehId($1) ) {
        mta.say $1 $mta.name($1,$2) has $ctvGetVehName($1) at $mta.area($1,$2) !
;        Remember which player is in the target vehicle 
        set %CTV [ $+ [ $1 ] $+ TARGET ] [ $2 ] 
;        Remember the tick count for later 
        set %CTV [ $+ [ $1 ] $+ TICKS [ $ticks ] ]
     }
  }
}

; Triggered when a player does a !-command. $1 = Server, $2 = PlayerID, $3 = !-command, $4- = !-command parameters 
alias mta.command { 
  var %admin
  if ( %CTV [ $+ [ $1 ] $+ ADMINIP ] == $mta.ip($1,$2) ) {
     %admin = 1
  }
  else {
     %admin = 0
  }
  if ( $3 == !myinfo ) {
     mta.say $1 Player $2 ; $mta.name($1,$2) ; $mta.ip($1,$2)
  }
  else if ( $3 == !loc ) {
     mta.say $1 Location: $mta.location($1,$2)
  }
  else if ($timer(ctv $+ $1)) {      
     if ($3 == !highscore ) {
        var %id = $ctvGetHighScoreId($1)
        if ( %id == $null ) {
           mta.say $1 Everyone is loosing!
        } else {
           mta.say $1 $mta.name($1,%id) is leading with a score of %CTV [ $+ [ $1 ] $+ ID $+ [ %id ] $+ SCORE ]
        }
     } 
     else if ( $3 == !score ) {
        var %score = %CTV [ $+ [ $1 ] $+ ID $+ [ $2 ] $+ SCORE ]
        if ( %score == $null ) {
           %score = 0
        }
        mta.say $1 $mta.name($1,$2) score: %score
     }

     else if ( $3 == !help ) {
        mta.say $1 Target vehicle: $ctvGetVehName($1)
     }
     else if ( $3 == !kill ) {
        mta.say $1 /slap $mta.name($1,$2) 
        mta.say $1 /slap $mta.name($1,$2) 
        mta.say $1 /slap $mta.name($1,$2) 
        mta.say $1 /slap $mta.name($1,$2)
        mta.say $1 /slap $mta.name($1,$2) 
        mta.say $1 /slap $mta.name($1,$2)
     }      
     else if ( ( $3 == !next ) && ( %admin > 0 ) ) {
        .timercheck $+ $1 1 3 ctvNextVehicle $1
     } 
     else if ( ( $3 == !end ) && ( %admin > 0 ) ) {
        mta.say $1 Ending game...
        .timerctv $+ $1 1 1 ctv $1 off
     }      
  } 
  else if ( $3 == !begin ) {
     .timerctv $+ $1 off
     .timercheck $+ $1 1 1 ctv $1 on
  } 

}

P.S. I look forward to BLUE!

Link to comment
Constructive criticism for other scripters:

One other thing I noticed when trying to get inspiration from other mtama mods was that people were constantly using ini files to store variables. Why not just use a standard mirc global variable instead? When naming variables, try to use descriptive names instead of the cryptic single-letters that I often saw. Finally, try to comment your code a bit. All of these problems combined makes the script hard to read and maintain.

This is because of the speed of mIRC handling loads of variables. The way mIRC stores all the information is quite stupid. Longer variables cause a longer parsing time of the script. With ini-files, all data is stored in a seperate file, and can be used after mIRC had restarted.

Commenting code is an other thing. I remember all the old code i had to work with in the days I was still scripting. And everyone who was (ab)using my scripts because they were quite documented and easy-editable.

Your script looks quite nice, cant test it though. I'm certain some other people will. Great work!

Link to comment

about the constructive criticism:

1) INI Files:

These are not only an better way of storage as harry said, but they are also much easier to get things working on ALL MTA:mA Servers at once as you can write player data directly to their ini path on the server ini file. This saves the need to have long comlicated and useless variable names... which slows down mIRC's already slow script parsing.

2) Comments:

I personally don't comment my script because A its a waste of my time which could be used to firther improve the script im working on and B it shows an abuser how to modify it... take MTA:mA:GRS for example.. if i commented it, people would easily be able to remove the CRC check in place. As is it people have trouble with it because i made the code hard to decipher.

I have looked through your script and its not bad, but it could be vastly improved. If you like i can go through it when i get home.

Nice to see other people coming out with scripts though.. good job :)

Link to comment

I'd be happy to take any suggestions as to how to beef up my code.

I have little experience with mirc scripting, but just thought I'd comment that I find it hard to believe that using a file is faster than using a global variable (since disk I/O is an order of magnitude slower than RAM access). Since all of the variables are created when necessary, there is no need for me to store them in a file for later use. I see the point of long variable names, but I think that in the era of Ghz computers, the difference is so insignificant that it is a non-issue. I, of course, could be wrong in this assumption.

P.S. I have had cases when a badly damaged, respawned vehicle spontaneously caught on fire and blew up. This kept happening until I restarted the server. Maybe it was just a glitch.

Link to comment

Nice job on that script, good to see some new gamemodes (although this idea has been used a bit)

P.S. I have had cases when a badly damaged, respawned vehicle spontaneously caught on fire and blew up. This kept happening until I restarted the server. Maybe it was just a glitch.

Thats no glitch, lag and synch makes it look like you've blowed up the vehicle on your screen. But the other player has a less damaged vehicle simply because not all your shots hit them.

Link to comment
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...