Changelog

From RAGE Multiplayer Wiki
Jump to: navigation, search
  • Note: Colour was replaced with Color

0.3.7

EVEN´╗┐TS

public class EventsExample : RAGE.Events.Script
{
  public EventsExample()
  {
    // this kind of events receives mp.trigger, mp.events.callLocal, but also remote events
    RAGE.Events.AddEvent("remote_triggerable_event", SomeEvent);
    
    RAGE.Events.AddDataHandler("some_data", SomeDataHandler);
    
    RAGE.Events.Tick += Tick;
    RAGE.Events.OnPlayerChat += ChatHandler;
    
    // trigger a js event
    RAGE.Events.CallLocal("eventName", 1, "someString", 1.0f);
  }
  
  public void SomeEvent(object[] args)
  {
  }
  
  public void SomeDataHandler(RAGE.Elements.Entity entity, object value)
  {
  }
  
  public void ChatHandler(string text, RAGE.Events.CancelEventArgs cancel)
  {
    if(text == "cancelme")
    {
    	cancel.Cancel = true;
    }
  }
  
  // known as "render" in JS
  public void Tick(System.Collections.Generic.List<RAGE.Events.TickNametagData> nametags)
  {
  }
}

GAME INTERACTION

// trivial game stuff
int interior = RAGE.Game.Interior.GetInteriorFromCollision(0.0f, 0.0f, 0.0f);

// player interaction
RAGE.Elements.Entities.Players.GetAtRemote(1).ClearDecorations();

// player interaction using a game entity handle
RAGE.Game.Ped.ClearPedDecorations(RAGE.Elements.Player.LocalPlayer.Handle);

// ped creation
uint freeroamHash = RAGE.Game.Misc.GetHashKey("mp_m_freemode_01");
RAGE.Elements.Ped ped = new RAGE.Elements.Ped(freeroamHash, new RAGE.Vector3(0.0f, 0.0f, 0.0f), dimension: 5);


CEF

...
  
public void OurEventHandler(object[] args)
{
  RAGE.Chat.Output("Got actually called! {0}", (string)args[0]);
}
  
public void TriggerMe()
{
  	RAGE.Events.Add("eventExample", OurEventHandler);
  
	RAGE.Ui.HtmlWindow wnd = new RAGE.Ui.HtmlWindow("package://index.html");
 	wnd.ExecuteJs("mp.trigger('eventExample', 'yep')");
  
  	// "mp.gui.execute"
  	RAGE.Ui.DefaultWindow.ExecuteJs("test()");
}

BUILT-IN NATIVEUI

using System;
using System.Collections.Generic;

using RAGE.NUI;

public class MenuExample
        : RAGE.Events.Script
{
    private bool ketchup = false;
    private string dish = "Banana";
    private MenuPool _menuPool;

    public void AddMenuKetchup(UIMenu menu)
    {
        var newitem = new UIMenuCheckboxItem("Add ketchup?", ketchup, "Do you wish to add ketchup?");
        menu.AddItem(newitem);
        menu.OnCheckboxChange += (sender, item, checked_) =>
        {
            if (item == newitem)
            {
                ketchup = checked_;
                Notify("~r~Ketchup status: ~b~" + ketchup);
            }
        };
    }

    public void AddMenuFoods(UIMenu menu)
    {
        var foods = new List<dynamic>
        {
            "Banana",
            "Apple",
            "Pizza",
            "Quartilicious",
            0xF00D, // Dynamic!
        };
        var newitem = new UIMenuListItem("Food", foods, 0);
        menu.AddItem(newitem);
        menu.OnListChange += (sender, item, index) =>
        {
            if (item == newitem)
            {
                dish = item.IndexToItem(index).ToString();
                Notify("Preparing ~b~" + dish + "~w~...");
            }

        };
    }

    public void AddMenuCook(UIMenu menu)
    {
        var newitem = new UIMenuItem("Cook!", "Cook the dish with the appropiate ingredients and ketchup.");
        newitem.SetLeftBadge(UIMenuItem.BadgeStyle.Star);
        newitem.SetRightBadge(UIMenuItem.BadgeStyle.Tick);
        menu.AddItem(newitem);
        menu.OnItemSelect += (sender, item, index) =>
        {
            if (item == newitem)
            {
                string output = ketchup ? "You have ordered ~b~{0}~w~ ~r~with~w~ ketchup." : "You have ordered ~b~{0}~w~ ~r~without~w~ ketchup.";
                Notify(String.Format(output, dish));
            }
        };
        menu.OnIndexChange += (sender, index) =>
        {
            if (sender.MenuItems[index] == newitem)
                newitem.SetLeftBadge(UIMenuItem.BadgeStyle.None);
        };
    }

    public void AddMenuAnotherMenu(UIMenu menu)
    {
        var submenu = _menuPool.AddSubMenu(menu, "Another Menu");
        for (int i = 0; i < 20; i++)
            submenu.AddItem(new UIMenuItem("PageFiller", "Sample description that takes more than one line. Moreso, it takes way more than two lines since it's so long. Wow, check out this length!"));
    }

    public void DrawMenu(System.Collections.Generic.List<RAGE.Events.TickNametagData> nametags)
    {
        _menuPool.ProcessMenus();
    }

    public MenuExample()
    {
        _menuPool = new MenuPool();
        var mainMenu = new UIMenu("Native UI", "~b~NATIVEUI SHOWCASE");
      
      	// original NativeUI replicates GTA V "interaction menu", 
      	//changing FreezeAllInput to true makes the player completely frozen
      	// while the menu is active
        mainMenu.FreezeAllInput = true;
      
        _menuPool.Add(mainMenu);
        AddMenuKetchup(mainMenu);
        AddMenuFoods(mainMenu);
        AddMenuCook(mainMenu);
        AddMenuAnotherMenu(mainMenu);
        _menuPool.RefreshIndex();

        RAGE.Events.Tick += DrawMenu;

        mainMenu.Visible = true;
    }

    public static void Notify(string text)
    {
        RAGE.Game.Ui.SetNotificationTextEntry("STRING");
        RAGE.Game.Ui.AddTextComponentSubstringPlayerName(text);
        RAGE.Game.Ui.DrawNotification(false, false);
    }
}
  • JS: "entityDataChange" event has been replaced with "mp.events.addDataHandler(key, handler)"
  • JS: added mp.events.callLocal
  • Improvements on initial server loading
  • Fix voice chat not getting cleared properly after setting "voice3d" to false
  • Improve voice chat playback thread synchronization mechanism, so it doesn't affect anything else
  • Fix reported voice chat crashes
  • 0.4's game interaction performance improvements backport
  • Fix in-game UI not saving "latest IP connected to" correctly
  • DataStorage UTF-8 support fixes
  • Added a smoother voice chat packet loss handling
  • Fixed reported voice chat stability issues
  • Fixed some specific remote player tasks stuck after finished
  • Added "experimental web platform features" flag to the in-game CEF
  • Fixed key binding issues with isDown param = false

0.3.6

General changes

  • Added: server-based voice chat (server config option to enable: `voice-chat`: true)
  • Updated: Scripting stability improvements ("undefined" errors should be fixed now, needs to be confirmed)
  • Updated: V8 (a separate vanilla one is used client-side now, not the one bundled with NodeJS)
  • Updated: Security enhancements
  • Added: Grand Theft Auto V's 1.45 patch support
  • Reimplemented "construction zone crash" fix
  • Vehicle model limit adjustment (it's not an actual 0.4 backport since it uses another method that doesn't rely on 0.4 features)
  • Updated NodeJS
  • Backported native fool proofing
  • Added "allow-voice-chat-input" option (only available via registry at the moment); default value: 1
  • Updated: CEF (Chromium 70.0.3538.77)
  • Fixed: potential aiming synchronization data corruption
  • Added: more game limits have been adjusted so more global conversion mods are compatible now
  • Fixed: custom dlc packs conflicting with certain game dlc pack
  • Fixed: dlc packs not working correctly with FQDN
  • Miscellaneous fixes

Scripting

  • Added: mp.voiceChat.muted (client-side)
  • Added: mp.voiceChat.getPreprocessingParam(param) (client-side)
  • Added: mp.voiceChat.setPreprocessingParam(param, value) (client-side)
  • Added: player.voiceVolume (client-side)
  • Added: player.voice3d (client-side)
  • Added: player.voiceAutoVolume (client-side)
  • Added: player.isVoiceActive (client-side)
  • Added: event: playerStartTalking (client-side)
  • Added: event: playerStopTalking (client-side)
  • Added: player.enableVoiceTo(target) (server-side)
  • Added: player.disableVoiceTo(target) (server-side)
  • Added: player.voiceListeners (server-side)
  • Added: mp.voiceChat.isAllowed (read-only) (client-side)
  • Added: player.clearDecorations() (server-side)
  • Added: player.getVoiceAttribute(attribute) (client-side)
  • Added: player.setVoiceAttribute(attribute, value) (client-side)
  • Fixed: vehicle.getOccupant
  • Updated: C# enums
  • Fixed: C# UTF-8 support improvements

0.3.4

  • Added: player.getDecoration(collection)
  • Added: player.setDecoration(collection, overlay)
  • Updated: player.setHeadOverlay(overlayId, [index, opacity, color, secondaryColor])
  • Updated: player.getHeadOverlay
  • Updated: mp.game.graphics.screen2dToWorld3d(x, y[, collisionTest])
  • Updated: click event args are (x, y, state, mouseKey, relativeX, relativeY, 3dpos, entityHandle) now
  • Fixed: text label rendering issues
  • Fixed: shared variables not reseting for local player clientside after reconnecting
  • Fixed: invalid password issue
  • Fixed: playerWeaponShot not triggering when there's no any target entity

RC-2

  • Updated: all remote trigger arguments should be passed as an array now, e.g. player.call("eventName", [1, 2, 3]). It was updated only for server-side API as for RC-2.
  • Added: vehicle.quaternion
  • Added: vehicle.heading
  • Added: "this" to events. It includes "cancel" and "handler" properties. Setting "this.cancel = true" would stop triggering futher events this call.

RC-1

  • Added: Vehicle.movable (get)
  • Updated: mp.environment is mp.world now
  • Added: mp.world.requireIpl
  • Added: mp.world.removeIpl
  • Added: mp.world.trafficLights.locked (get / set)
  • Added: mp.world.trafficLights.state (get / set)
  • Added Player.removeObject

Client-side updates

  • Added: mp.gui.cursor.show(visibility, freezeControls)
  • Added: Entity.getVariable
  • Added: Entity.setVariable
  • Added: mp.vehicles.new
  • Added: mp.objects.new
  • Added: mp.pickups.new
  • Added: mp.markers.new
  • Added: mp.blips.new
  • Added: mp.checkpoints.new
  • Added: mp.labels.new
  • Updated: mp.game.graphics.drawText(text, position[, additionalArgs])
  • Added: Vehicle.setHandling(name, value)
  • Added: mp.discord.update(detailedStatus, state)
  • Added: mp.game.cam.getGameplayCamRelativeHeading
  • Added: Entity.remoteId
  • Added: pool.atRemoteId

Events updates

  • Added: Events.getAllOf(eventName)
  • Added: Events.remove(eventName[, hander])
  • Added: Events.reset()

Player updates

  • Added: Player.weapons (documented below)
  • Added: Player.removeWeapon(weapon)
  • Added: Player.removeAllWeapons()
  • Added: Player.weapon (get / set)
  • Added: Player.weaponAmmo (get / set)
  • Added: Player.getWeaponAmmo(weapon)
  • Added: Player.setWeaponAmmo(weapon, ammo)
  • Added: Player.allWeapons (get)
  • Added: Player.getHeadOverlay(id)
  • Added: Player.setHeadOverlay(id, [overlayId, opacity])
  • Added: Player.socialClub (get)
  • Added: Player.isStreamed(player)
  • Added: Player.streamedPlayers (get)
  • Added: Player.isReloading (get)
  • Added: Player.isOnLadder (get)
  • Added: Player.isInMelee (get)
  • Added: Player.packetLoss (get)

Blip updates

  • Added: Blip.shortRange (get / set)
  • Added: Blip.drawDistance (get / set)
  • Added: Blip.rotation (get / set)
  • Updated: Blip.colour => Blip.color (get / set)
  • Removed: mp.blips.newStreamed // use .new() with drawDistance ( see below )

TextLabel updates (includes entity methods)

  • Added: TextLabel.color (get / set)
  • Added: TextLabel.drawDistance (get / set)
  • Added: TextLabel.los (get / set)
  • Added: TextLabel.text (get / set)

Vehicle updates

  • Added: Vehicle.mods[id] (get / set) // also available as Vehicle.get / setMod(id) since 0.3
  • Added: Vehicle.extras[id] (get / set)
  • Added: Vehicle.isStreamed(player)
  • Added: Vehicle.streamedPlayers
  • Added: Vehicle.dashboardColor (get / set)
  • Added: Vehicle.pearlescentColor (get / set)
  • Added: Vehicle.livery (get / set)
  • Added: Vehicle.numberPlateType (get / set)
  • Added: Vehicle.trimColor (get / set)
  • Added: Vehicle.windowTint (get / set)
  • Added: Vehicle.wheelColor (get / set)
  • Added: Vehicle.wheelType (get / set)
  • Added: Vehicle.getExtra(id)
  • Added: Vehicle.setExtra(id, extra)
  • Added: Vehicle.taxiLights (get / set)
  • Added: Vehicle.dashboardColor (get / set)
  • Added: Vehicle.trailer
  • Added: Vehicle.traileredBy

New events

  • Added: entityCreated (entity)
  • Added: playerReady (player)
  • Added: entityModelChange (entity, oldModel)
  • Updated: playerEnterVehicle => playerStartEnterVehicle
  • Updated: playerEnteredVehicle => playerEnterVehicle
  • Updated: playerExitVehicle => playerStartExitVehicle
  • Updated: playerLeftVehicle => playerExitVehicle
  • Added: playerDamage (player, healthLoss, armorLoss)
  • Added: playerWeaponChange (player, oldWeapon, newWeapon)
  • Added: vehicleDamage (vehicle, bodyHealthLoss, engineHealthLoss)
  • Added: vehicleSirenToggle (vehicle, state)
  • Added: vehicleHornToggle (vehicle)
  • Added: vehicleTrailerAttach (vehicle, trailer)
  • Added: playerMarkWaypoint (player, position)
  • Added: playerReachWaypoint (player)

Entity updates (for all for entitiy types)

  • Added: Entity.data.name (gets / sets synced variable just like getVariable / setVariable)
  • Added: Entity.getVariable(name)
  • Added: Entity.setVariable(name, value)

Player.weapons

  • Added: Player.weapons.all (returns an object just like Player.allWeapons)
  • Added: Player.weapons.name / Player.weapons.hash / Player.weapons.current (gets/sets ammo of specific weapon just like Player.get / setWeaponAmmo)
  • Added: Player.weapons.clear()



Events examples

// Add events
mp.events.add(
{
    playerJoin: (player) => {},
    playerChat: (player, msg) => {}
});

//
function playerJoinHandler(player)
{
}

// Add an event
mp.events.add("playerJoin", playerJoinHandler);

// Remove specified handler of specified event
mp.events.remove("playerJoin", playerJoinHandler);

// Remove handler(s) specified event(s)
mp.events.remove("playerJoin");
mp.events.remove(["playerJoin", "playerQuit"]);

// Reset whole event manager
mp.events.reset();

// Get all handlers of specified event
mp.events.getAllOf("playerJoin").forEach(_ev => _ev(null));

// 
const ev = new mp.Event("playerDeath", (player, reason, killer) =>
{
    mp.players.broadcast('First blood!');
    ev.destroy(); // this event handler will be not called anymore since it's destroyed
});

ev.destroy(); // due to this line the event is never going to be executed if we call this before it

// Per-entity (available for all of entities) event manager
mp.events.add("playerJoin", (player) =>
{
    player.events.push("playerSpawn", (player) =>
    {
        mp.players.broadcast(`hey ${player.name}, this is your first spawn!`);
        return true; // return true from the event to destroys it for the entity after execution
    });
});

New entity constructors

mp.vehicles.new(model, position,
{
    heading: heading,
    numberPlate: numberPlate,
    alpha: alpha,
    color: color,
    locked: locked,
    engine: engine,
    dimension: dimension
});
 
mp.objects.new(model, position,
{
    rotation: rotation,
    alpha: alpha,
    dimension: dimension
});

mp.blips.new(sprite, position,
{
    name: name,
    scale: scale,
    color: color,
    alpha: alpha,
    drawDistance: drawDistance,
    shortRange: shortRange,
    rotation: rotation,
    dimension: dimension,
});

mp.checkpoints.new(type, position, radius,
{
    direction: direction,
    color: color,
    visible: visible,
    dimension: dimension
});

mp.markers.new(type, position, scale,
{
    direction: direction,
    rotation: rotation,
    color: color,
    visible: visible,
    dimension: dimension
});

mp.labels.new(text, position,
{
    los: los,
    font: font,
    drawDistance: drawDistance,
    color: color,
    dimension: dimension
});