Select Ped (or Vehicle) to Spawn from Picture Preview - LemonUI
-
Awhile back I added a function to a LemonUI menu to preview peds - not as a tiny thumbnail, something bigger, and also customized exactly the way it was supposed to spawn - hair, outfit, etc.
Now i added the code to spawn the selection. This was relatively easy to do in LemonUI and C#. It's a shame this isn't a feature in LemonUI.
In this demo the pictures are the size of a trading card - but you could make them as large or as small as you want. You could also spawn vehicles this way as well.
-
@JohnFromGWN said in Select Ped (or Vehicle) to Spawn from Picture Preview - LemonUI:
Now i added the code to spawn the selection. This was relatively easy to do in LemonUI and C#. It's a shame this isn't a feature in LemonUI.
Is not a feature, but I asked Lemon and she said it can be done from 1.8 by overriding the process function. Of course, you still have to draw all the stuff yourself, but at least can benefit from other LemonUI features
-
@JustDancePC I did have a problem here that I couldn't resolve but I'll try first with some conditional statements.
The issue is because Lemonui treats functions from lists differently from menus.
One has object sender, the other doesn't. So calling the functions requires different syntax.
Have no idea how to do this a priori.
This code could be fully automated even though the spawn codes, specifically the component variations, are different for each ped.
Conceptually I was thinking of an array or lookup table if that's possible that would match sprite number to ped function, without renaming the 300 or so existing ped spawn functions I have. Again each one is different and of course since modders don't follow standards the legs of one could be the glasses of another.
-
@JohnFromGWN I have to run some tests myself for the overriding part, I have some ideas but haven't tried anything yet.
Also, do you mean you have 300 different functions? One for each specific ped? Damn, lol. You should only have one and use conditional statements for each ped component you want to skip during creation. Also, all your custom peds could be saved into a file, then you can create the menu programmatically from the file contents, take for example what I did in the Music Menu script, specifically, the playlists section.
Your peds file could look something like this
-
@JustDancePC said in Select Ped (or Vehicle) to Spawn from Picture Preview - LemonUI:
One for each specific ped? Damn, lol.
Nah. Not that retarded. Keep in mind when I started I knew nothing at all beyond the basics of programming learned from VBA. And when I started, i spawned peds and cars NativeListItem<String> and then switched to full menu style.
Also I only use 4 or 5 component variations. And they all share a common function called EquipCurrentPed.
public void SpawnAdaStream() { Ped AdaT = World.CreatePed("AdaStream", Game.Player.Character.GetOffsetPosition(new Vector3(2, 1, 0))); //Long Hair and striped, white dress options Function.Call(Hash.SET_PED_DEFAULT_COMPONENT_VARIATION, AdaT); CurrentPed = AdaT; { EquipCurrentPed(); } }
The only time I used face features and overlays was when i did the MP Male/Female tranny. This was quite a learning because the order of the code is important, not sure why, but it took me several hours of back and forth to finally get him/her to look the way i did and about 20 lines of code or more.
When I change the character I also use a generic function
Game.Player.ChangeModel(CurrentPed.Model); Function.Call(Hash.CHANGE_PLAYER_PED, Game.Player.Character, CurrentPed, true, true); //var Int1 = Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 3); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 0, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 0), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 0, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 1, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 1), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 1, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 2, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 2), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 2, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 3, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 3), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 3, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 4, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 4), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 4, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 5, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 5), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 5, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 6, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 6), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 6, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 7, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 7), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 7, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 8, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 8), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 8, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 9, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 9), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 9, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 10, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 10), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 10, 2)); Function.Call(Hash.SET_PED_COMPONENT_VARIATION, Game.Player.Character, 11, Function.Call<int>(Hash.GET_PED_DRAWABLE_VARIATION, CurrentPed, 11), Function.Call<int>(Hash.GET_PED_TEXTURE_VARIATION, CurrentPed, 11, 2)); //props, you can increase if needed. Ear Pieces 2, watches 3, bangles 4 Function.Call(Hash.SET_PED_PROP_INDEX, Game.Player.Character, 0, Function.Call<int>(Hash.GET_PED_PROP_INDEX, CurrentPed, 0), Function.Call<int>(Hash.GET_PED_PROP_TEXTURE_INDEX, CurrentPed, 0, 2)); //hat Function.Call(Hash.SET_PED_PROP_INDEX, Game.Player.Character, 1, Function.Call<int>(Hash.GET_PED_PROP_INDEX, CurrentPed, 1), Function.Call<int>(Hash.GET_PED_PROP_TEXTURE_INDEX, CurrentPed, 1, 2)); //glasses Game.Player.Character.IsInvincible = true; Game.Player.Character.Weapons.Give(WeaponHash.CombatPistol, 5000, true, true); //true has to belcase Game.Player.Character.Weapons.Give(WeaponHash.Unarmed, 1, false, true); }
Anyway no aspirations to ever be a programmer, but since I started I've done everything I wanted to do in this game, not elegantly, not efficiently, but everything works.
And you've been a great help, but honestly very few people here have ever helped me. @Jitnaught for scripts and @a63nt-5m1th for anything related to GTA5 files and data. Anything OS or Windows related I have tons of experience with, including assembling my own PCs from scratch.
-
P.S. I'm sure you will laugh because there are far better ways to do this, I'm sure, but this is how I spawned my peds.
if (e.KeyCode == Keys.NumPad9) { { if (spriteNum == 1) { SpawnRoninBrown(); } } { if (spriteNum == 2) { SpawnLaraWhite(); } } { if (spriteNum == 3) { SpawnLaraBlack(); } } { if (spriteNum == 4) { SpawnAdaAS(); } } { if (spriteNum == 5) {SpawnTifaA(null, new EventArgs()); } } { if (spriteNum == 6) { SpawnMaiCasual3(null, new EventArgs()); } } { if (spriteNum == 7) { SpawnLana9(null, new EventArgs()); } } }
-
Why not just use one function, e.g
SpawnPed(Model model)
, and use that function for all of your spawns instead of individual functions for each model? Example:public void SpawnPed(Model model) { Ped ped = World.CreatePed(model, Game.Player.Character.GetOffsetPosition(new Vector3(2, 1, 0))); Function.Call(Hash.SET_PED_DEFAULT_COMPONENT_VARIATION, ped); CurrentPed = ped; EquipCurrentPed(); } if (e.KeyCode == Keys.NumPad9) { if (spriteNum == 1) SpawnPed("RoninBrownModel"); else if (spriteNum == 2) SpawnPed("LaraWhiteModel"); else if (spriteNum == 3) SpawnPed("LaraBlack"); else if ... ... }
Another improvement would be to use an array of models then use the spriteNum to get the model from the array.
public void SpawnPed(Model model) { Ped ped = World.CreatePed(model, Game.Player.Character.GetOffsetPosition(new Vector3(2, 1, 0))); Function.Call(Hash.SET_PED_DEFAULT_COMPONENT_VARIATION, ped); CurrentPed = ped; EquipCurrentPed(); } Model[] pedModels = { "model1", "model2", "model3" }; if (e.KeyCode == Keys.NumPad9) { SpawnPed(pedModels[spriteNum]); }
Keep in mind though that arrays are zero-indexed, meaning that to get the first item you have to use the number 0 (e.g.
pedModels[0]
), so you would have to make sure spriteNum is zero-indexed as well, or just subtract 1 from it.
-
@Jitnaught
Each ped has its own component variations further compounded by the fact that modders don't or for mysterious reasons can't follow standards. The legs of one model might be the glasses for another.The function SpawnPed("LaraBlack") is not the ped model, it is a set of 4,5,6, or more specific components, specific for that 3d model and based on available hair, torso, legs, etc.
Another issue I have to deal with is each ped is given a unique ID in case I want to interact with them in a script.
So I could have Lara5 and Ronin3 etc.
But I will definitely look at your code and will certainly use your else statements as they are more "acceptable", as would be using case statements I guess.
One big advantage of creating my own lemonui menus is to spawn with component variations rather than Menyoo outfits, while at the same time making them companions, persistent, invincible, and armed with weapons. All in one function, shared with every single ped, called EquipCurrentPed()
The issue is with individual customization. Of course this only an issue for peds that allow for variations.
Edit. I only use
Function.Call(Hash.SET_PED_DEFAULT_COMPONENT_VARIATION, ped)
as a reminder for those peds which don't have any component variations.
-
@Jitnaught I guess I could I have one function, with all 12 component variations, and pass the relevant ones to that function for each ped. In that case it wouldn't matter if the glasses were 4, normally legs, as long as it was properly coded.
The components not in use, would be set to their defaults.
Still this would require 2 variables per component, int drawableId, int textureId, so 24 variables.
-
@Jitnaught I should have given an example of how my ped spawns look. This one is exceptional due to its complexity, not the code, but the possible variations.
public void SpawnTranny() { Ped Ped1 = World.CreatePed(PedHash.FreemodeFemale01, Game.Player.Character.GetOffsetPosition(new Vector3(0, 1, 0))); CurrentPed = Ped1; { EquipCurrentPed(); } //PedComps -Component Variation Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 0, 39, 0, 2); //'FACE Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 1, 0, 0, 2); //'BEARD OR MASK Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 2, 10, 0, 2); //'HAIR Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 3, 45, 0, 2); //'SHIRT/TORSO Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 4, 15, 0, 2); //'LEGS/PANTS Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 5, 0, 0, 2); //'HANDS GLOVES Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 6, 0, 0, 2); //'SHOES Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 7, 23, 0, 2); //'BOWTIE/SCARVES Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 8, 10, 0, 2); //'ACCESSORIES Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 9, 0, 0, 2); //'TASKS OR IS IT REALLY MASKS?? Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 10, 6, 0, 2); //'TEXTURES Function.Call(Hash.SET_PED_COMPONENT_VARIATION, CurrentPed, 11, 15, 0, 2); //'TORSO2 //PedProps (Accessories in Menyoo) Function.Call(Hash.SET_PED_PROP_INDEX, CurrentPed, 2, 18, 0, 1); // ear pieces Function.Call(Hash.SET_PED_PROP_INDEX, CurrentPed, 6, 2, 0, 1); // watches //FacialFeatures, 0-19, values float between -1 and 1, default is 0 Function.Call(Hash._SET_PED_FACE_FEATURE, CurrentPed, 0, -0.4); // nose width Function.Call(Hash._SET_PED_FACE_FEATURE, CurrentPed, 6, 0.6); // Function.Call(Hash._SET_PED_FACE_FEATURE, CurrentPed, 18, 1); // Function.Call(Hash._SET_PED_FACE_FEATURE, CurrentPed, 19, 1); // //Blend Data Function.Call(Hash.SET_PED_HEAD_BLEND_DATA, CurrentPed, 28, 23, 0, 26, 27, 0, 0.0455F, 1.009F, 0.0F, true); Function.Call((Hash)0x48F44967FA05CC1E, CurrentPed, 1, 5, 0.8); //beard Function.Call((Hash)0x497BF74A7B9CB952, CurrentPed, 1, 1, 0, 0); //beard colour Function.Call(Hash.SET_PED_HEAD_OVERLAY, CurrentPed, 8, 0, 0.63); //lipstick Function.Call(Hash._SET_PED_HEAD_OVERLAY_COLOR, CurrentPed, 8, 2, 0, 0); //mandatory, 2 for lip colortype (not the specific color, just the parameter) Function.Call((Hash)0x48F44967FA05CC1E, CurrentPed, 10, 8, 0.7); //chest hair Function.Call((Hash)0x497BF74A7B9CB952, CurrentPed, 10, 1, 0, 0); //mandatory Function.Call(Hash.SET_PED_HEAD_OVERLAY, CurrentPed, 11, 0, .8);//body blemish Function.Call(Hash._SET_PED_HEAD_OVERLAY_COLOR, CurrentPed, 11, 1, 0, 0); //mandatory //this code has to come later, if put higher will not run Function.Call(Hash._SET_PED_HAIR_COLOR, CurrentPed, 7, 0); //'Additional Hair Function.Call(Hash._SET_PED_EYE_COLOR, CurrentPed, 4, 0); //'Additional Eye }