Jump to content
    1. Welcome to GTAForums!

    1. GTANet.com

    1. GTA Online

      1. The Criminal Enterprises
      2. Updates
      3. Find Lobbies & Players
      4. Guides & Strategies
      5. Vehicles
      6. Content Creator
      7. Help & Support
    2. Red Dead Online

      1. Blood Money
      2. Frontier Pursuits
      3. Find Lobbies & Outlaws
      4. Help & Support
    3. Crews

    1. Grand Theft Auto Series

      1. Bugs*
      2. St. Andrews Cathedral
    2. GTA VI

    3. GTA V

      1. Guides & Strategies
      2. Help & Support
    4. GTA IV

      1. The Lost and Damned
      2. The Ballad of Gay Tony
      3. Guides & Strategies
      4. Help & Support
    5. GTA San Andreas

      1. Classic GTA SA
      2. Guides & Strategies
      3. Help & Support
    6. GTA Vice City

      1. Classic GTA VC
      2. Guides & Strategies
      3. Help & Support
    7. GTA III

      1. Classic GTA III
      2. Guides & Strategies
      3. Help & Support
    8. Portable Games

      1. GTA Chinatown Wars
      2. GTA Vice City Stories
      3. GTA Liberty City Stories
    9. Top-Down Games

      1. GTA Advance
      2. GTA 2
      3. GTA
    1. Red Dead Redemption 2

      1. PC
      2. Help & Support
    2. Red Dead Redemption

    1. GTA Mods

      1. GTA V
      2. GTA IV
      3. GTA III, VC & SA
      4. Tutorials
    2. Red Dead Mods

      1. Documentation
    3. Mod Showroom

      1. Scripts & Plugins
      2. Maps
      3. Total Conversions
      4. Vehicles
      5. Textures
      6. Characters
      7. Tools
      8. Other
      9. Workshop
    4. Featured Mods

      1. Design Your Own Mission
      2. OpenIV
      3. GTA: Underground
      4. GTA: Liberty City
      5. GTA: State of Liberty
    1. Rockstar Games

    2. Rockstar Collectors

    1. Off-Topic

      1. General Chat
      2. Gaming
      3. Technology
      4. Movies & TV
      5. Music
      6. Sports
      7. Vehicles
    2. Expression

      1. Graphics / Visual Arts
      2. GFX Requests & Tutorials
      3. Writers' Discussion
      4. Debates & Discussion
    1. Announcements

    2. Support

    3. Suggestions

Instant Gang Wars Triggering/Attack (Wave) For Specific Times.. Is It Possible???


ArmanCan
 Share

Recommended Posts

ArmanCan

Normally we have to kill 3 Ballas or Vagos in order to trigger a "Gang Wars Attack" and sometimes it is difficult to find a 3 enemy gang together.. especially in some weak territories such as Playa Del Sevilla... Off course in some cases the player triggers the unwanted territory..😧

 

So why don't we stand in a specific territory, push a buttorn or type a cheat and let the script activates/deactivates this for us? By the way.. "Specific Times" means this script will be only usable between these missions.. Doberman/Green Sabre - Home Coming/End of the Line  😉 

Link to comment
Share on other sites

OrionSR

I guess this counts as unfinished business. I wanted to do this long before I knew how to figure it out.

 

There are no standard or added opcodes to perform this function, so the best bet is to search through DK22pac's SDK Plug-in reference for clues that might help out. Here are some highlights from the CGangWar files.

 

//https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_sa/game_sa/CGangWars.ccp
int &CGangWars::Gang1 = *reinterpret_cast<int *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB84, 0, 0, 0, 0, 0));
int &CGangWars::Gang2 = *reinterpret_cast<int *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB50, 0, 0, 0, 0, 0));

int addrof(CGangWars::SetSpecificZoneToTriggerGangWar) = ADDRESS_BY_VERSION(0x444010, 0, 0, 0, 0, 0);
int gaddrof(CGangWars::SetSpecificZoneToTriggerGangWar) = GLOBAL_ADDRESS_BY_VERSION(0x444010, 0, 0, 0, 0, 0);

void CGangWars::SetSpecificZoneToTriggerGangWar(int zoneId) {
    plugin::CallDynGlobal<int>(gaddrof(CGangWars::SetSpecificZoneToTriggerGangWar), zoneId);
}

int addrof(CGangWars::StartOffensiveGangWar) = ADDRESS_BY_VERSION(0x446050, 0, 0, 0, 0, 0);
int gaddrof(CGangWars::StartOffensiveGangWar) = GLOBAL_ADDRESS_BY_VERSION(0x446050, 0, 0, 0, 0, 0);

void CGangWars::StartOffensiveGangWar() {
    plugin::CallDynGlobal(gaddrof(CGangWars::StartOffensiveGangWar));
}

//https://github.com/DK22Pac/plugin-sdk/blob/master/plugin_sa/game_sa/CGangWars.h
SUPPORTED_10US static void SetSpecificZoneToTriggerGangWar(int zoneId);
SUPPORTED_10US static void StartOffensiveGangWar();

 

This info needs to be converted to cleo using available references and code snippets. Are you ready to go down this rabbit hole?

 

//opcode.txt
0AA5: call_function $hPROC num_params 1 pop 1 $param
0AA6: call_method $Destroy struct $CarStruct num_params 0 pop 0
0AA7: call_function_return 0x569660 num_params 2 pop 2 $COORD_Y $COORD_X $GROUND
0AA8: call_method_return 0x4048E0 struct 0xB74494 num_params 1 pop 0 $MyCar [email protected]

//cleo examples
const
  WorkOutPolicePresence = 0x5625F0
  civil = 14.0
  in_range = 18.0
  criminal = 30.0
  federal = 60.0
  x_pos = 505.0
  y_pos = 14.0
  
  x_float = [email protected]
  y_float = [email protected]
  z_float = [email protected]
  num_cops = [email protected]
end
0AA7: WorkOutPolicePresence num_params 4 pop 4 civil z_float y_float x_float num_cops

0AA5: call 0x49CB10  num_params 0 pop 0  // delete all unique jumps stuff 

//https://gtaforums.com/topic/494026-safunction-memory-adresses/?do=findComment&comment=1060901693
0AA5: call 0x005DD3B0 _readPlantsDat num_params 1 pop 1 filename "PLANTS.DAT"
0AA6: call_method 0x5BD830 _CHandlingData__readHandlingCfg struct 0xC2B9C8 num_params 0 pop 0
0AA7: call_function 0x008263C0 _strcmp num_params 2 pop 2 STRING1 [email protected] STRING2 [email protected] RESULT_TO [email protected]

//https://gtaforums.com/topic/983954-coordinates-to-offsets-sa/
const
    _operator_minus_CVector_CVector = 0x0040FE60 // CVector __cdecl operator-(const CVector &left, const CVector &right)
    _Multiply3x3 = 0x0059C810 // CVector __cdecl Multiply3x3(const CVector &vec, const CMatrix &mat)
end
0AA5: call_function_no_result _operator_minus_CVector_CVector push 3 pop 3 right [email protected] left [email protected] out [email protected]
0AA5: call_function_no_result _Multiply3x3 push 3 pop 3 mat [email protected] vec [email protected] out [email protected]

//maybe
0AA5: StartOffensiveGangWar 0x446050 push 0 pop 0 

 

Seems to be working as expected.

 

{$CLEO .cs}
//StartGangWar.txt

const
  //int &CGangWars::Gang1 = *reinterpret_cast<int *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB84, 0, 0, 0, 0, 0));
  //int &CGangWars::Gang2 = *reinterpret_cast<int *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB50, 0, 0, 0, 0, 0));
  CGangWars__Gang1 = 0x96AB84
  CGangWars__Gang2 = 0x96AB50
  //int addrof(CGangWars::StartOffensiveGangWar) = ADDRESS_BY_VERSION(0x446050, 0, 0, 0, 0, 0);
  StartOffensiveGangWar = 0x446050
  DaNang = 4
  Aztecas = 7
end

0000:
wait 2000
0879: enable_gang_wars 1
wait 20000  // extra long for new game start

//SUPPORTED_10US static void StartOffensiveGangWar();
0AA5: call StartOffensiveGangWar push 0 pop 0
wait 10
// Old trick from PS2 and Master mind's territory glitch 
0A8C: write_memory CGangWars__Gang1 size 4 value DaNang virtual_protect 0
0A8C: write_memory CGangWars__Gang2 size 4 value Aztecas virtual_protect 0

wait 2000
0A93: terminate_this_custom_script

 

An old topic with interesting details from gang war experiments: Master Mind's Territory Glitch

Link to comment
Share on other sites

ArmanCan
Posted (edited)
6 hours ago, OrionSR said:

I guess this counts as unfinished business. I wanted to do this long before I knew how to figure it out.

 

 

Ohh really?? 🙂

 

6 hours ago, OrionSR said:

There are no standard or added opcodes to perform this function, so the best bet is to search through DK22pac's SDK Plug-in reference for clues that might help out. Here are some highlights from the CGangWar files.

 

 

Yes.. I've searched on the "main.scm" but i didn't find an useful opcode for this but i've found some zone names and i'm copying them right now.. DK22pac and you can speak this language but i'm not and off course i can't translate too 😀

 

6 hours ago, OrionSR said:

This info needs to be converted to cleo using available references and code snippets. Are you ready to go down this rabbit hole?

 

I'm always NOT ready but at least i can try to some certain point.. If you feel yourself ready we can try to create it 😉 

 

6 hours ago, OrionSR said:

An old topic with interesting details from gang war experiments: Master Mind's Territory Glitch

 

There were some similar things in this topic but it was pretty long to read 😀

 

I think these are the zones that i'm looking for

 

Spoiler
076C: set_zone 'SUN1' gang 0 density_to 30 
076C: set_zone 'SUN1' gang 0 density_to 30 
076C: set_zone 'SUN3A' gang 0 density_to 30 
076C: set_zone 'SUN3B' gang 0 density_to 30 
076C: set_zone 'SUN3C' gang 0 density_to 30 
076C: set_zone 'SUN4' gang 0 density_to 30 
076C: set_zone 'CHC1A' gang 2 density_to 40 
076C: set_zone 'CHC1B' gang 2 density_to 40 
076C: set_zone 'CHC2A' gang 2 density_to 40 
076C: set_zone 'CHC2B' gang 2 density_to 40 
076C: set_zone 'CHC3' gang 2 density_to 40 
076C: set_zone 'CHC4A' gang 2 density_to 40 
076C: set_zone 'CHC4B' gang 2 density_to 40 
076C: set_zone 'EBE1' gang 2 density_to 30 
076C: set_zone 'EBE2A' gang 2 density_to 30 
076C: set_zone 'EBE2B' gang 2 density_to 30 
076C: set_zone 'EBE3C' gang 2 density_to 30 
076C: set_zone 'ELCO1' gang 7 density_to 40 
076C: set_zone 'ELCO2' gang 7 density_to 40 
076C: set_zone 'GAN1' gang 0 density_to 10 
076C: set_zone 'GAN2' gang 0 density_to 25 
076C: set_zone 'GLN1' gang 0 density_to 40 
076C: set_zone 'GLN2A' gang 0 density_to 40 
076C: set_zone 'LIND1A' gang 0 density_to 20 
076C: set_zone 'LIND1B' gang 0 density_to 20 
076C: set_zone 'LIND2A' gang 0 density_to 20 
076C: set_zone 'LIND2B' gang 0 density_to 20 
076C: set_zone 'LIND3' gang 0 density_to 20 
076C: set_zone 'IWD1' gang 0 density_to 20 
076C: set_zone 'IWD2' gang 0 density_to 20 
076C: set_zone 'IWD3A' gang 0 density_to 20 
076C: set_zone 'IWD3B' gang 0 density_to 20 
076C: set_zone 'IWD4' gang 0 density_to 10 
076C: set_zone 'IWD5' gang 0 density_to 20 
076C: set_zone 'JEF1A' gang 0 density_to 40 
076C: set_zone 'JEF1B' gang 0 density_to 40 
076C: set_zone 'JEF2' gang 0 density_to 40 
076C: set_zone 'JEF3B' gang 0 density_to 40 
076C: set_zone 'JEF3C' gang 0 density_to 40 
076C: set_zone 'LFL1A' gang 2 density_to 40 
076C: set_zone 'LFL1B' gang 2 density_to 40 
076C: set_zone 'LMEX1A' gang 7 density_to 30 
076C: set_zone 'LMEX1B' gang 7 density_to 30 
076C: set_zone 'ELS1A' gang 0 density_to 30 
076C: set_zone 'ELS1B' gang 0 density_to 30 
076C: set_zone 'ELS2' gang 0 density_to 30 
076C: set_zone 'ELS3A' gang 0 density_to 30 
076C: set_zone 'ELS3B' gang 0 density_to 30 
076C: set_zone 'ELS4' gang 0 density_to 30 
076C: set_zone 'PLS' gang 0 density_to 10  // Playa del Seville
076C: set_zone 'SMB1' gang 0 density_to 10 
076C: set_zone 'SMB2' gang 0 density_to 10 
076C: set_zone 'VIN2' gang 0 density_to 10 
076C: set_zone 'VERO1' gang 0 density_to 10 
076C: set_zone 'VERO2' gang 0 density_to 10 
076C: set_zone 'VERO3' gang 0 density_to 10 
076C: set_zone 'VERO4A' gang 0 density_to 10 
076C: set_zone 'VERO4B' gang 0 density_to 10 

 

 

And i've found a map with explanations.. thank you Rhans 😉

 

spacer.png

Edited by ArmanCan
Link to comment
Share on other sites

OrionSR
22 hours ago, ArmanCan said:

Ohh really?? 🙂

Well..., sort of. When I did all the gang war testing back in the day, I didn't know how to trigger a gang war without killing 3 Ballas or Vagos. That's the only part that's unfinished business. However, I played around with my test script a bit more and set up some other examples you might want to use when you create your script, like how to detect if gang wars are currently active.

 

Note: Some of these codes are using SCR  style keywords in the opcodes because it's often easier to align the official commands with the internal structure, but this script is still intended for the normal SA edit mode.

{$CLEO .cs}
//TestWar.txt

const
  //float &CGangWars::TimeTillNextAttack = *reinterpret_cast<float *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB48, 0, 0, 0, 0, 0));
  CGangWars__TimeTillNextAttack = 0x96AB48
  TimeTillNextAttack = [email protected]
  //CRadar *&CGangWars::RadarBlip = *reinterpret_cast<CRadar **>(GLOBAL_ADDRESS_BY_VERSION(0x96AB98, 0, 0, 0, 0, 0));
  CGangWars__RadarBlip = 0x96AB98
  RadarBlip = [email protected]
  //int &CGangWars::Gang1 = *reinterpret_cast<int *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB84, 0, 0, 0, 0, 0));
  CGangWars__Gang1 = 0x96AB84
  //int &CGangWars::Gang2 = *reinterpret_cast<int *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB50, 0, 0, 0, 0, 0));
  CGangWars__Gang2 = 0x96AB50
  //int addrof(CGangWars::StartOffensiveGangWar) = ADDRESS_BY_VERSION(0x446050, 0, 0, 0, 0, 0);
  StartOffensiveGangWar = 0x446050
  //int addrof(CGangWars::StartDefensiveGangWar) = ADDRESS_BY_VERSION(0x444300, 0, 0, 0, 0, 0);
  CGangWars__StartDefensiveGangWar = 0x444300
  //int addrof(CGangWars::EndGangWar) = ADDRESS_BY_VERSION(0x4464C0, 0, 0, 0, 0, 0);
  CGangWars__EndGangWar = 0x4464C0
  //bool &CGangWars::bGangWarsActive = *reinterpret_cast<bool *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB90, 0, 0, 0, 0, 0));
  CGangWars__bGangWarsActive = 0x96AB90
  bGangWarsActive = [email protected]
  Grove = 1
  DaNang = 4
  Aztecas = 7
end

03A4: script_name 'TestWar'

wait 10000
090D: clear_specific_zones_to_trigger_gang_war  // Enables turf wars to be provoked in all zones
076C: set_zone_gang_strength zone_id 'JEF3A' gang_id Grove density 40  // Jefferson Hospital - new game attack
//0879: set_gang_wars_active false

wait 10000
//SUPPORTED_10US static bool &bGangWarsActive;
0A8D: bGangWarsActive = read_memory CGangWars__bGangWarsActive size 1 virtual_protect 0
if
  bGangWarsActive == false
then 
  0879: set_gang_wars_active true
  0629: set_int_stat 337 to 1 // toggles the "territories under control" stat
  090D: clear_specific_zones_to_trigger_gang_war 
  0ACE: print_help_formatted "Gang Wars Activated"
  0330: set_player $2 infinite_run true
  01F7: set_player $2 ignored_by_cops true
  03BF: set_player $2 ignored_by_everyone true
else
  0ACE: print_help_formatted "Gang Wars are Already Active"
end

wait 10000
//SUPPORTED_10US static float &TimeTillNextAttack;
0A8D: TimeTillNextAttack = read_memory CGangWars__TimeTillNextAttack size 4 virtual_protect 0
TimeTillNextAttack /= 60000.0 
0ACE: print_help_formatted "TimeTillNextAttack = %.2f minutes" TimeTillNextAttack

wait 10000
//SUPPORTED_10US static void StartOffensiveGangWar();
0AA5: call StartOffensiveGangWar push 0 pop 0

// Change gangID of each attack group 
//SUPPORTED_10US static int &Gang1;
0A8C: write_memory CGangWars__Gang1 size 4 value DaNang virtual_protect 0
//SUPPORTED_10US static int &Gang2;
0A8C: write_memory CGangWars__Gang2 size 4 value Aztecas virtual_protect 0

wait 20000
//SUPPORTED_10US static void EndGangWar(bool bEnd);
0AA5: call CGangWars__EndGangWar push 1 pop 1 true

wait 10000
//SUPPORTED_10US static void StartDefensiveGangWar();
0AA5: call CGangWars__StartDefensiveGangWar push 0 pop 0

wait 10000
// Restore original state
//SUPPORTED_10US static void EndGangWar(bool bEnd);
0AA5: call CGangWars__EndGangWar push 1 pop 1 true
if
  bGangWarsActive == false
then 
  //SUPPORTED_10US static CRadar *&RadarBlip;
  0A8D: RadarBlip = read_memory CGangWars__RadarBlip size 4 virtual_protect 0
  0164: remove_blip RadarBlip
  0879: set_gang_wars_active bGangWarsActive
  0629: set_int_stat 337 to 0 // toggles the "territories under control" stat
  076C: set_zone_gang_strength zone_id 'JEF3A' gang_id Grove density 0  // Jefferson Hospital
  0330: set_player $2 infinite_run false
  01F7: set_player $2 ignored_by_cops false
  03BF: set_player $2 ignored_by_everyone false
end

0ACE: print_help_formatted "End Test" 
0A93: terminate_this_custom_script

 

Link to comment
Share on other sites

ArmanCan

@OrionSR yes.. the "Triggering" isn't available in Sanny Builder and it seems you progressed A LOT.. WOW.. 😉 but i have some suggestions for you...

 

- Well it's also about players so we should add these checks.. "$ONMISSION=0" "Player.Defined" "Player.Controllable"

- Normally gang wars is activated by either Doberman or Home Coming so why don't we add some extra checks in order to prevent crashing or corruption? For example "if $DOBERMAN_MISSION_COMPLETED=1 then..."

 

If i understood/saw it correctly "pressing button" opcodes are missing or you just wrote a mindblowing function to trigger it 😀

 

According to your previous comments i'm recognizing that this idea and the progress is yours..so.. how can i help you? 🙂 

 

 

Link to comment
Share on other sites

OrionSR

Oh no. This is your idea, and reasonably well defined too.

On 7/21/2022 at 12:57 PM, ArmanCan said:

So why don't we stand in a specific territory, push a buttorn or type a cheat and let the script activates/deactivates this for us? By the way.. "Specific Times" means this script will be only usable between these missions.. Doberman/Green Sabre - Home Coming/End of the Line  😉 

  • "So why don't we stand in a specific territory," - so... a looping script
  • "push a buttorn or type a cheat" - you know how to code this
  • "and let the script activates" - examples include StartOffensiveGangWar
  • "/deactivates this for us?" - recent additions include EndGangWar
  • "means this script will be only usable between these missions" - an alternative to mission progress is to check if bGangWarsActive is TRUE (=1).

Limited testing suggests that if gang wars aren't active then StartOffensiveGangWar won't do anything other than display a message that a war was been provoked, but only if CJ enters an attackable zone. So you could just let the script run; worry about that message after you find a problem.

 

Another note from testing: Deactivating a defensive war/gang attack before arriving at the zone often resulted in the blinking blip remaining after EndGangWar was called, so I added some codes to get rid of it. This data is saved, so it could be that the next gang attack would clear up the stray blip, even when reloading. 

 

These standard opcodes might help. It shouldn't be possible to trigger a war while on a mission unless set True by this opcode.

08A3: can_trigger_gang_war_when_on_a_mission state [bool]
087A:   is_gang_war_going_on
0A03:   is_gang_war_fighting_going_on

 

And more tidbits from the plug-in references;

bool &CGangWars::bCanTriggerGangWarWhenOnAMission = *reinterpret_cast<bool *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB93, 0, 0, 0, 0, 0));
SUPPORTED_10US static bool &bCanTriggerGangWarWhenOnAMission;

int addrof(CGangWars::CanPlayerStartAGangWarHere) = ADDRESS_BY_VERSION(0x443F80, 0, 0, 0, 0, 0);
SUPPORTED_10US static bool CanPlayerStartAGangWarHere(CZoneInfo *zoneInfo);

 

You should be able to implement bCanTriggerGangWarWhenOnAMission using the same format as bGangWarsActive. The comments from the plug-in are probably making your eyes bleed, but they are intended to be a Rosetta Stone for translating between the plug-in and cleo. 

 

CanPlayerStartAGangWarHere is a bit trickier. All of the other gang war call function examples have been "void" - they don't return any information. so 0AA5 is the appropriate opcode. CanPlayerStartAGangWarHere needs to return a bool (true or false, 1 or 0) so 0AA7 is needed. Something like;

0AA7: call CGangWars__CanPlayerStartAGangWarHere push 1 pop 1 zoneInfo and_return CanPlayerStartAGangWarHere

The zoneInfo field is probably the zoneInfo index, rather than the zone key text or pointer to the struct. I'm not sure how to get from the player's coords to the zoneInfo index; something to worry about only if the function is needed.

 

Anyway, I think the best way I can help is to... push you off the end of the dock to see if you sink or swim. You know everything you need to know; you just need to get past this mental barrier and you'll be swimming like a fish. Besides, the water is only chest-deep. You can just walk away at any time, so there's no risk in making the attempt. Encouragement instead, since pushing isn't an option.

 

Come on in. The water's fine.

Edited by OrionSR
Link to comment
Share on other sites

ArmanCan
Posted (edited)

Ok let's get to it but i have some questions before i do anything.. 

 

It seems the script you've posted is a template for us so i'm gonna ask some of my questions on this script..

 

Spoiler
{$CLEO .cs}
//TestWar.txt

const
  //float &CGangWars::TimeTillNextAttack = *reinterpret_cast<float *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB48, 0, 0, 0, 0, 0));
  CGangWars__TimeTillNextAttack = 0x96AB48
  TimeTillNextAttack = [email protected]
  //CRadar *&CGangWars::RadarBlip = *reinterpret_cast<CRadar **>(GLOBAL_ADDRESS_BY_VERSION(0x96AB98, 0, 0, 0, 0, 0));
  CGangWars__RadarBlip = 0x96AB98
  RadarBlip = [email protected]
  //int &CGangWars::Gang1 = *reinterpret_cast<int *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB84, 0, 0, 0, 0, 0));
  CGangWars__Gang1 = 0x96AB84
  //int &CGangWars::Gang2 = *reinterpret_cast<int *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB50, 0, 0, 0, 0, 0));
  CGangWars__Gang2 = 0x96AB50
  //int addrof(CGangWars::StartOffensiveGangWar) = ADDRESS_BY_VERSION(0x446050, 0, 0, 0, 0, 0);
  StartOffensiveGangWar = 0x446050
  //int addrof(CGangWars::StartDefensiveGangWar) = ADDRESS_BY_VERSION(0x444300, 0, 0, 0, 0, 0);
  CGangWars__StartDefensiveGangWar = 0x444300
  //int addrof(CGangWars::EndGangWar) = ADDRESS_BY_VERSION(0x4464C0, 0, 0, 0, 0, 0);
  CGangWars__EndGangWar = 0x4464C0
  //bool &CGangWars::bGangWarsActive = *reinterpret_cast<bool *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB90, 0, 0, 0, 0, 0));
  CGangWars__bGangWarsActive = 0x96AB90
  bGangWarsActive = [email protected]
  Grove = 1
  DaNang = 4
  Aztecas = 7
end

03A4: script_name 'TestWar'

wait 10000
090D: clear_specific_zones_to_trigger_gang_war  // Enables turf wars to be provoked in all zones
076C: set_zone_gang_strength zone_id 'JEF3A' gang_id Grove density 40  // Jefferson Hospital - new game attack
>>>>>>>>>>I HAVE TO ADD ALL THE ZONES WITH GANG DENSITY TO HERE..RIGHT? BECAUSE YOU SAID IT WAS A LIMITED TESTING AND I ASSUME THAT YOU'VE ONLY TESTED THIS ZONE..    
//0879: set_gang_wars_active false

wait 10000
//SUPPORTED_10US static bool &bGangWarsActive;
0A8D: bGangWarsActive = read_memory CGangWars__bGangWarsActive size 1 virtual_protect 0
if
  bGangWarsActive == false
then 
  0879: set_gang_wars_active true
  0629: set_int_stat 337 to 1 // toggles the "territories under control" stat
  090D: clear_specific_zones_to_trigger_gang_war 
  0ACE: print_help_formatted "Gang Wars Activated"
  0330: set_player $2 infinite_run true
  01F7: set_player $2 ignored_by_cops true
  03BF: set_player $2 ignored_by_everyone true
else
  0ACE: print_help_formatted "Gang Wars are Already Active"
end

>>>>>>>>>> IT SEEMS I GOTTA ADD "PRESS KEY" OR "TYPE CHEAT" OPCODES TO HERE AND OFF COURSE I HAVE TO ADD 2 KEYS FOR ACTIVATION/CANCELLING...   
    
wait 10000
//SUPPORTED_10US static float &TimeTillNextAttack;
0A8D: TimeTillNextAttack = read_memory CGangWars__TimeTillNextAttack size 4 virtual_protect 0
TimeTillNextAttack /= 60000.0 
0ACE: print_help_formatted "TimeTillNextAttack = %.2f minutes" TimeTillNextAttack

wait 10000
//SUPPORTED_10US static void StartOffensiveGangWar();
0AA5: call StartOffensiveGangWar push 0 pop 0

// Change gangID of each attack group 
//SUPPORTED_10US static int &Gang1;
0A8C: write_memory CGangWars__Gang1 size 4 value DaNang virtual_protect 0
//SUPPORTED_10US static int &Gang2;
0A8C: write_memory CGangWars__Gang2 size 4 value Aztecas virtual_protect 0

wait 20000
//SUPPORTED_10US static void EndGangWar(bool bEnd);
0AA5: call CGangWars__EndGangWar push 1 pop 1 true

wait 10000
//SUPPORTED_10US static void StartDefensiveGangWar();
0AA5: call CGangWars__StartDefensiveGangWar push 0 pop 0

wait 10000
// Restore original state
//SUPPORTED_10US static void EndGangWar(bool bEnd);
0AA5: call CGangWars__EndGangWar push 1 pop 1 true
if
  bGangWarsActive == false
then 
  //SUPPORTED_10US static CRadar *&RadarBlip;
  0A8D: RadarBlip = read_memory CGangWars__RadarBlip size 4 virtual_protect 0
  0164: remove_blip RadarBlip
  0879: set_gang_wars_active bGangWarsActive
  0629: set_int_stat 337 to 0 // toggles the "territories under control" stat
  076C: set_zone_gang_strength zone_id 'JEF3A' gang_id Grove density 0  // Jefferson Hospital
  0330: set_player $2 infinite_run false
  01F7: set_player $2 ignored_by_cops false
  03BF: set_player $2 ignored_by_everyone false
end

0ACE: print_help_formatted "End Test" 
0A93: terminate_this_custom_script

 

On 7/24/2022 at 12:56 AM, OrionSR said:

The zoneInfo field is probably the zoneInfo index, rather than the zone key text or pointer to the struct. I'm not sure how to get from the player's coords to the zoneInfo index; something to worry about only if the function is needed.

 

 

- Yeah.. this is also another problem.. Normally Sanny Builder takes the districts and shows on the screen like Wesser's zone name script..Before the triggering opcodes this problem needs to be fixed.. OR.. i 've another idea which has low possibility to code.. 

 

If it's too difficult to pinpoint player's actual coordinate and trigger to there.. than.. we can create a CLEO MENU, choose the zones to be triggered and we can either use this script as a reference or create an INI file 😉

Edited by ArmanCan
Link to comment
Share on other sites

OrionSR

Fail. I've been playing with the gang war and zone functions, gathering information I might use to make a RTSM for gang wars, and yesterday's tests were full of crashes and useless data. How's your project going?

 

On 7/24/2022 at 7:02 AM, ArmanCan said:

It seems the script you've posted is a template

No, not really. This script is intended more as sample code. The idea is to pull in working examples of what you need for a specific task. Maybe a slightly commented example of decompiled code will provide a useful example. You can add in your own constants when you're ready. The only alterations are; I converted the decimal addresses to hex using SB's Ctrl-H hotkey, and included the descriptive constants as comments.

 

// This file was decompiled using SASCM.ini published on 2021-07-05
{$CLEO .cs}

03A4: script_name 'TestWar' 
0879: enable_gang_wars 0 
0001: wait 10000 ms 
090D: highlight_all_inactive_gang_zones_as_available_for_gangwars 
076C: set_zone 'JEF3A' gang 1 density_to 40 
0001: wait 10000 ms 
0A8D: [email protected] = read_memory 0x96AB90 size 1 virtual_protect 0  // CGangWars__bGangWarsActive
00D6: if 
0039:   [email protected] == 0 
004D: jump_if_false @TestWar_139 
0879: enable_gang_wars 1 
0629: change_integer_stat 337 to 1 
090D: highlight_all_inactive_gang_zones_as_available_for_gangwars 
0ACE: show_formatted_text_box "Gang Wars Activated" 
0330: set_player $player_char infinite_run 1 
01F7: set_player $player_char ignored_by_cops 1 
03BF: set_player $player_char ignored_by_everyone 1 
0002: jump @TestWar_172 

:TestWar_139
0ACE: show_formatted_text_box "Gang Wars are Already Active" 

:TestWar_172
0001: wait 10000 ms 
0A8D: [email protected] = read_memory 0x96AB48 size 4 virtual_protect 0  // CGangWars__TimeTillNextAttack
0017: [email protected] /= 60000.0 
0ACE: show_formatted_text_box "TimeTillNextAttack = %.2f minutes" [email protected] 
0001: wait 10000 ms 
0AA5: call_function 0x446050 num_params 0 pop 0  // CGangWars__StartOffensiveGangWar
0A8C: write_memory 0x96AB84 size 4 value 4 virtual_protect 0  // CGangWars__Gang1
0A8C: write_memory 0x96AB50 size 4 value 7 virtual_protect 0  // CGangWars__Gang2
0001: wait 20000 ms 
0AA5: call_function 0x4464C0 num_params 1 pop 1 1  // CGangWars__EndGangWar
0001: wait 10000 ms 
0AA5: call_function 0x444300 num_params 0 pop 0  // CGangWars__StartDefensiveGangWar
0001: wait 10000 ms 
0AA5: call_function 0x4464C0 num_params 1 pop 1 1  // CGangWars__EndGangWar
00D6: if 
0039:   [email protected] == 0 
004D: jump_if_false @TestWar_425 
0A8D: [email protected] = read_memory 0x96AB98 size 4 virtual_protect 0  // CGangWars__RadarBlip
0164: disable_marker [email protected] 
0879: enable_gang_wars [email protected] 
0629: change_integer_stat 337 to 0 
076C: set_zone 'JEF3A' gang 1 density_to 0 
0330: set_player $player_char infinite_run 0 
01F7: set_player $player_char ignored_by_cops 0 
03BF: set_player $player_char ignored_by_everyone 0 

:TestWar_425
0ACE: show_formatted_text_box "End Test" 
0A93: terminate_this_custom_script 

 

Start small. All your first test script needs to do is loop until triggered by key presses or cheat string, then start a war. Test that script in different save game environments before worrying about managing exceptions. 

 

Next add a way to end the war, because that was part of the original plan. Take note of how gang density changes when a war is interrupted by using a function compared to traditional methods like toggling an R3 mission or simply flipping $OnMission on and off.

 

Link to comment
Share on other sites

OrionSR
On 7/24/2022 at 7:02 AM, ArmanCan said:

It seems the script you've posted is a template

Speaking of templates, I've been experimenting with Sanny's template feature and have a couple of example templates to offer.

 

The most basic SB template is the New CLEO Script option from the File menu, which creates a new file like this;

{$CLEO .cs}
0000:



0A93: terminate_this_custom_script

 

Basics: There are a number of standard templates for common procedures available from the Ctrl-J menu. Alternatively, you can type the name of the template and press F2 to insert the code. Most of these are for inserting high-level constructs like IF..THEN..ELSE..END.

 

It's also possible to add custom templates by selecting the code segment and using the Add New Template option from the Tools menu. If you think these templates might be useful, you can add them to your custom templates for the current edit mode. These templates should work on any PC version of III, VC and SA with Cleo installed, but won't work for Cleo for Android, so a global template isn't a good option.

 

test_cheat

while true
  wait 0
  if  
    test_cheat "MYCHEAT" 
  then
  //=== Start custom code ===\\



  //==== End custom code ====\\
  end
end

 

key_pressed

while true
  wait 0
  if and
    is_key_pressed 220  // "\"
    is_key_pressed 74  // "J"
  then
    while true
      if and
        is_key_pressed 220  // "\"
        is_key_pressed 74  // "J"
      then
        wait 0
      else
        Break
      end
    end
//-------------- Codes Start Here --------------------------    
    

 
//---------------- Codes End Here --------------------------
  end

 

So the idea is, you can start with the File, New CLEO Script template, then insert the preferred trigger template, tweak the keys or cheat string, and jump straight into coding.

Link to comment
Share on other sites

ArmanCan

I would like to continue but there are too many memory adresses in this plugin reference and i don't know which one will be suitable for me..🙂

Link to comment
Share on other sites

OrionSR

Start with the New CLEO Script template from the File menu.

Insert the text_cheat template suggested above.

Insert this line between the code start/end comments

0AA5: call_function 0x446050 num_params 0 pop 0  // CGangWars__StartOffensiveGangWar

Compile and Copy

Test in game

 

When the cheat string is entered a gang war should be triggered if gang wars are active and CJ is in a turf controlled by Ballas or Vagos.

 

I'm expecting the war to trigger; the more interesting tests are for inappropriate situations like;

  • Gang war is already in progress
  • Gang attack is in progress
  • Gang wars not active
  • Turfs controlled by Grove and Azteca
  • Non-gang turfs

The simple wait 10000 structure of my test script didn't give me much control of the tests, but I got the impression that if the StartOffensiveGangWar function was called in a non-gang turf, the gang war still triggered when CJ arrived at an attackable turf a short time later - maybe.

 

Keep track of the Provoked War message and when it is displayed inappropriately.

Edited by OrionSR
Link to comment
Share on other sites

ArmanCan
1 hour ago, OrionSR said:

When the cheat string is entered a gang war should be triggered if gang wars are active and CJ is in a turf controlled by Ballas or Vagos.

 

 

{$CLEO .cs}
0000: NOP

while true
  wait 0
  if  
    test_cheat "GANG" 
  then
0AA5: call_function 0x446050 num_params 0 pop 0  // CGangWars__StartOffensiveGangWar
  end
end

 

well i couldn't believe but this tiny ass script worked BUT this one ONLY works if the gang wars is ACTIVE..

 

- I've started to test on my "Home Coming" savegame.. Everything worked but with an exception.. When i entered this Aztecas are also started to get hostile on me..I've realized that on Discotech/Club turf near Unity Station. Other than that it was enough to go to the target territory and type a cheat. Talking about territories i went to any Rifas or Da Nang Boys territory and typed the cheat there but it didn't work. Additional to these territories you can not start a gang war again on your turf..

 

- Than i tested it again on our chain game savefile (It was Doberman) because i wanted to test it on different nonstandart terrritories like Las Venturas turfs.. I've triggered it and even left it during second wave.. It became Mixed territory as usual.. Offcourse the whole process worked like a charm but with issues that i explained above..

 

- My final test was the new game and the problems began from here.. I've directly started on Jefferson and typed it. I've seen the usual message "You've provoked a gang war" and all the nearby ballas started to shoot me but i couldn't see the ballas and the "blinking blip" on my radar/map. Off course this caused another problem.. all the civilians/police including traffic cars vanished from the whole map but i brought back by starting a side mission like taxi or vigilante..I've used this to my advantage and drove through Las Venturas.. I've received 4 Stars but noone including SAM Site missiles bothered me.. It was like a ghost town 😀  You can start the mission "Big Smoke" and suprisingly you can also trigger this weird gang war DURING this mission.. All the effects will be same.. 

 

According to these results..

 

- We can easily ignore/eliminate the pinpointing coordinates concerns because the provocation begins in your current territory right after you type the cheat..

 

- We should definitely add your check " if bGangWarsActive is TRUE (=1)."  for starting a gang war...😉

Link to comment
Share on other sites

OrionSR
On 7/27/2022 at 1:42 PM, ArmanCan said:

We should definitely add your check " if bGangWarsActive is TRUE (=1)."  for starting a gang war.

Yeah, you should. Making any progress?

 

I suggest replacing the single StartOffensiveGangWar line with an IF..THEN..ELSE..END construct.

 

First read the status of bGangWarsActive, then use this basic construct.

if
  //condition to check
then
  //do this if condition is true
else
  //do this if false (display a help box?)
end

 

 

Edited by OrionSR
Link to comment
Share on other sites

ArmanCan
Posted (edited)
On 7/28/2022 at 11:34 PM, OrionSR said:

Making any progress?

 

Yes.. i've progressed.. normally making it simple is actually making it harder but it seems the game itself conducting the GANGWAR progress really well and because of that i don't need more constants or some additional opcodes but the bitch ass Sanny gives me an error.. 😠 here is my weirdo script..

 

Spoiler
{$CLEO .cs}

thread 'GANGWARS'

wait 0

const
0A8D: [email protected] = read_memory 0x443AA0 size 4 virtual_protect 0 // int addrof(CGangWars::GangWarGoingOn) = ADDRESS_BY_VERSION(0x443AA0, 0, 0, 0, 0, 0)
0A8D: [email protected] = read_memory 0x96AB90 size 4 virtual_protect 0 // bool &CGangWars::bGangWarsActive = *reinterpret_cast<bool *>(GLOBAL_ADDRESS_BY_VERSION(0x96AB90, 0, 0, 0, 0, 0))
0A8D: [email protected] = read_memory 0x96AB98 size 4 virtual_protect 0  // CGangWars__RadarBlip
end

:MISSION_CHECK_BEFORE_CODING
wait 0
if and
    $ONMISSION == 0
then
jump @GANG_WARS_INITIATING_CANNCELLING 

:GANG_WARS_INITIATING_CANNCELLING
while true
    wait 10000 // For a New Game
        if and
            Player.Defined($PLAYER_CHAR)
            [email protected] = true
            0AB0: key_pressed 106 // Numpad "*"
        then
            0AA5: call_function 0x446050 num_params 0 pop 0  // CGangWars__StartOffensiveGangWar
            0ACE: show_formatted_text_box "Gang Attack Has Been Started"
        end
        if  or
            Player.Defined($PLAYER_CHAR)
            [email protected] = true
            0AB0: key_pressed 111 // Numpad "/"
        then
            0AA5: call_function 0x4464C0 num_params 0 pop 0 $param // int addrof(CGangWars::EndGangWar) = ADDRESS_BY_VERSION(0x4464C0, 0, 0, 0, 0, 0);
            0ACE: show_formatted_text_box "Gang Attack Has Been Cancelled"
        end
        
:DEFENSIVE_GANG_WARS
    wait 10000 
        0AA5: call_function 0x444300 num_params 0 pop 0  // CGangWars__StartDefensiveGangWar
    wait 10000 
        0AA5: call_function 0x4464C0 num_params 1 pop 1 1  // CGangWars__EndGangWar
        if 
            0039: [email protected] == 0 
        then
            0164: disable_marker [email protected] 
            0879: enable_gang_wars [email protected] 
            0629: change_integer_stat 337 to 0
        end                     

 

Edited by ArmanCan
Link to comment
Share on other sites

OrionSR
6 hours ago, ArmanCan said:

normally making it simple is actually making it harder

Does this mean that you want the constants back? If so, let's get the script to a stable and working condition before making the transition.

 

Your const..end construct was not applied correctly; I'm going to leave it out for my next set of comments but I'll explain now in case you want to work ahead.

The format of each line is;

  • optional_indent
  • name_of_constant
  • equals char "="
  • number, (string=unk_err?) or variable that will replace name_of_constant when compiled
  • // optional comment

The const..end construct does not work on things like opcodes, keywords, multiple words or reserved commands like end, or Break. It's a very common substitution routine that allows values that never change to be named without using a variable. SB also allows variables to be named using the same format.

 

8 hours ago, ArmanCan said:
CGangWars__GangWarGoingOn = 0x443AA0

(edited to fit const..end format)

 

Nice find, but wasn't used, and isn't needed in this form. This isn't an address you can read or write to; note the relatively small hex values. 0x4xxxxx addresses are in a range I associate with in-game functions; something that will perform an action, or return a result. This function could probably be implemented with 0AA7, but GangWarGoingOn, and GangWarFightingGoingOn, have been assigned to an official opcodes, which are much easier to work with.

087A:   is_gang_war_going_on
0A03:   is_gang_war_fighting_going_on

Save this bit for later. Better to back up a bit and get things working.

 

I like your script, btw. This is very helpful. Give me some time to consider modifications.

Link to comment
Share on other sites

ArmanCan
42 minutes ago, OrionSR said:

I like your script, btw. This is very helpful. Give me some time to consider modifications.

 

Thank you so much but i don't want these eye bleeding constants back 😀 

 

Ok.. all the times are yours 😉

Link to comment
Share on other sites

OrionSR
2 hours ago, ArmanCan said:

Thank you so much but i don't want these eye bleeding constants back 😀 

Well... No. but I won't complicate the addresses for now. I need to reintroduce the constants for the key_press numbers because they need to be changed in two places. And as the script develops they can become lost in the body of the script. It's much better to have the key presses assigned in one place in the header at the top of the script.

 

A few examples: First an annotated map of how I organize my script structures. Too many comments don't make the script easier to read at this point; use this as imaginary reference while reading a more basic script.

{Header}                            // Notes and compiler directives
{$CLEO .cs}
//  nothing.txt
//  Edit mode=SA

/*
    This script does nothing.
*/

const
  //nothing
end//const


{Initialize}                        // run once codes to get ready
03A4: script_name 'nothing'         // short string, 7 chars + null
wait 10000                          // let game load before doing nothing


{Main Body}
while true
  wait 50                           // heartbeat of the main loop                           
  0000: NOP                         // commands indented within construct
end//while                          // end of and same indent level as the main while loop 
0A93: terminate_this_custom_script  // safety valve in case of Break in loop


{Sub-Routines}
{Cleo Functions}                    // see 0AB1: cleo_call
{String Labels}                     // common for Android

 

Same thing with all the extra comments removed. However, I kept the comments after end statements because that was an issue in your script. The IF..THEN..END construct for $OnMission wasn't ended, and there was no end for the main while loop.  Alignment within constructs was a bit wonky. More on that as the script develops.

{$CLEO .cs}
//  nothin.txt
//  Edit mode=SA

03A4: script_name 'nothin'
wait 10000


while true
  wait 50         
  0000: NOP
end//while
0A93: terminate_this_custom_script

So... yeah, worth using a little imagination to simplify the text. The part that will be developed next replaces the no operation (0000: NOP) command.

 

Key Press Spam: Do you want the command to be issued once per press (and release) or to execute while the button is held? The addcash script illustrates the difference. Make a prediction of what the script will do and test in game for the best option for your script.

 

{$CLEO .cs}
//  addcash.txt
//  Edit mode=SA

03A4: script_name 'addcash'
wait 10000


while true
  wait 0         

  if
    is_key_pressed 106   // Numpad "*"
  then
    0109: player $2 money += 1
  end//if

  if
    is_key_pressed 111  // Numpad "/"
  then
    while is_key_pressed 111  // Numpad "/"
      wait 0
    end//while
    0109: player $2 money += 1000
  end//if

end//while main loop
0A93: terminate_this_custom_script

 

I've got a Google Sheet with a lot of San Andreas Constants set up for use in cleo scripts. I need to revisit this idea in light of some of SB's new features, but the easy way to use the reference is to copy and paste the constants you want to use and into your script.

 

Key_Constants

Spoiler
[KEY]
Key_Backspace=8
Key_Tab=9
Key_Enter=13
Key_Shift=16
Key_Ctrl=17
Key_Pause=19
Key_Caps_Lock=20
Key_Esc=27
Key_Spacebar=32
Key_PgUp=33
Key_PgDn=34
Key_End=35
Key_Home=36
Key_Left_Arrow=37
Key_Up_Arrow=38
Key_Right_Arrow=39
Key_Down_Arrow=40
Key_Insert=45
Key_Delete=46
Key_0=48
Key_1=49
Key_2=50
Key_3=51
Key_4=52
Key_5=53
Key_6=54
Key_7=55
Key_8=56
Key_9=57
Key_A=65
Key_B=66
Key_C=67
Key_D=68
Key_E=69
Key_F=70
Key_G=71
Key_H=72
Key_I=73
Key_J=74
Key_K=75
Key_L=76
Key_M=77
Key_N=78
Key_O=79
Key_P=80
Key_Q=81
Key_R=82
Key_S=83
Key_T=84
Key_U=85
Key_V=86
Key_W=87
Key_X=88
Key_Y=89
Key_Z=90
Key_Left_Win=91
Key_Right_Win=92
Key_Function=93
Key_Num_0=96
Key_Num_1=97
Key_Num_2=98
Key_Num_3=99
Key_Num_4=100
Key_Num_5=101
Key_Num_6=102
Key_Num_7=103
Key_Num_8=104
Key_Num_9=105
Key_Num_Asterisk=106
Key_Num_Plus=107
Key_Num_Minus=109
Key_Num_Period=110
Key_Num_Slash=111
Key_F1=112
Key_F2=113
Key_F3=114
Key_F4=115
Key_F5=116
Key_F6=117
Key_F7=118
Key_F8=119
Key_F9=120
Key_F10=121
Key_F11=122
Key_F12=123
Key_Num_Lock=144
Key_Scroll_Lock=145
Key_Semicolon=186
Key_Equal=187
Key_Comma=188
Key_Hyphen=189
Key_Period=190
Key_Slash=191
Key_Backtick=192
Key_Open_Bracket=219
Key_Backslash=220
Key_Close_Bracket=221
Key_Apostrophe=222

 

 

Edited by OrionSR
Link to comment
Share on other sites

OrionSR

Progressing the Script - nesting IF constructs

 

Picking up where we left off with the addcash script, this script is pretty much the same thing with a few modifications.

  • I included constants for the key presses.
  • All key press triggers only activate upon release.
  • There is a placeholder for gang attacks/defensive wars, but it's been block commented out until the gang war tests are complete.
  • 0000: NOP is being used as a placeholder for the next iteration of development.
{$CLEO .cs}
//  TestWar4.txt
//  Edit mode=SA

const
  War_Key = 106     //  Key_Num_Asterisk=106
  Attack_Key = 111  //  Key_Num_Slash=111
end // const

03A4: script_name 'TestWar'
wait 10000


while true // main loop
  wait 50

  if
    is_key_pressed War_Key
  then
    while is_key_pressed War_Key
      wait 0
    end//while
    0000: NOP
  end//if War_Key pressed

/*
  if
    is_key_pressed Attack_Key
  then
    while is_key_pressed Attack_Key
      wait 0
    end//while
    0000: NOP
  end//if Attack_Key pressed
*/

end//while main loop
0A93: terminate_this_custom_script

It's a good idea to test major changes one step at a time. For testing, you could replace NOP with the actual command or display a message so you know that part is working as expected.

 

Part of the design decision is to start with the key press check. I don't want the script to be constantly hammering away at memory or performing complex operations 20 times a second during the main loop. So, key press first, then perform other checks if it passes.

 

The current NOP is suppose to trigger the war, but first I want to check if gang wars are active. So the next "show your work" iteration is to replace the NOP above with;

    0A8D: [email protected] = read_memory 0x96AB90 size 1 virtual_protect false  // CGangWars__bGangWarsActive
    if
      [email protected] == true
    then
      0000: NOP
    end//if bGangWarsActive

 

The next iteration is to check if a gang war or attack is already active. If either is true, then NOP, else finally trigger the war.

      if or
        087A: is_gang_war_going_on
        0A03: is_gang_war_fighting_going_on
      then
        0000: NOP
      else
        0AA5: call_function 0x446050 num_params 0 pop 0  // CGangWars__StartOffensiveGangWar
        0ACE: print_help_formatted "Gang War Has Been Started"     
      end//if gang wars going on

 

The last iteration for this script is to end the war or attack if active. This toggle style use helps conserve on the number of keys required. Single key scripts and tools are common and can lead to conflicts, so best to use as few as possible.

        0AA5: call_function 0x4464C0 num_params 1 pop 1 1  // CGangWars__EndGangWar
        0A8D: [email protected] = read_memory 0x96AB98 size 4 virtual_protect 0  // CGangWars__RadarBlip
        if
          075C: does_blip_exist [email protected]
        then
          0164: remove_blip [email protected]
        end//if attack blip exist
        0ACE: print_help_formatted "Gang War Has Been Cancelled"     

No more NOPs. You're almost done. Once the gang war section has passed the test it should be relatively easy to adapt it to gang attacks.

 

The current script does not manage the case of being OnMission. I'm not really sure what the conflict is. Some missions issue a command that allows gang wars to be started during the mission, most do not. It is possible to manage both conditions, but I'm not sure what problem to avoid.

 

Edited by OrionSR
Link to comment
Share on other sites

ArmanCan

@OrionSR holly molly.. you wrote so much stuff again 🙂 here is my summary from what you said..

 

- Key Codes can be lost during the body of this script so it needs to be assigned in constants..

- "0x4xxxxxx"  these kind of adresses can not be written or added to constants..

- First key pressing.. and than checks checks and another checks until you go crazy 😀

 

I've also tried to combine these in a logical way but it seems there is still a problem with compiling..

 

Spoiler
{$CLEO .cs}
//  InstantGangWar.txt
//  Edit mode=SA

const
  War_Key = 106     //  Key_Num_Asterisk=106 "*"
  Attack_Key = 111  //  Key_Num_Slash=111    "/"
end // const

03A4: script_name 'InstantGangWar'
wait 10000


while true // main loop
  wait 50

  if
    is_key_pressed War_Key
  then
    while is_key_pressed War_Key
      wait 0
    end
    while true
    0A8D: [email protected] = read_memory 0x96AB90 size 1 virtual_protect false  // CGangWars__bGangWarsActive
    if
      [email protected] == true
    then
      0000: NOP
    end//if bGangWarsActive
    if or
        087A: is_gang_war_going_on
        0A03: is_gang_war_fighting_going_on
    then
        0000: NOP
    else
        0AA5: call_function 0x446050 num_params 0 pop 0  // CGangWars__StartOffensiveGangWar
        0ACE: print_help_formatted "Gang War Has Been Started"     
    end//if gang wars going on    
  end//if War_Key pressed


  if
    is_key_pressed Attack_Key
  then
    while is_key_pressed Attack_Key
      wait 0
    end
    while true
        0AA5: call_function 0x4464C0 num_params 1 pop 1 1  // CGangWars__EndGangWar
        0A8D: [email protected] = read_memory 0x96AB98 size 4 virtual_protect 0  // CGangWars__RadarBlip
        if
          075C: does_blip_exist [email protected]
        then
          0164: remove_blip [email protected]
        end//if attack blip exist
        0ACE: print_help_formatted "Gang War Has Been Cancelled"  
  end//if Attack_Key pressed

end//while main loop
0A93: terminate_this_custom_script

 

 

Link to comment
Share on other sites

OrionSR

Hm... I was worried that I had made it too easy. I'll try again with another version of the script that adds another level of complexity - subroutines. And I'll wait for confirmation that everything is working as expected before adding the next iteration. You can speed up this process considerably by trying again to assemble the previously posted version.

 

To explain again; all you need to do is assemble the pieces of the script puzzle and you should have a magic spell that will trigger gang wars. Copy the next part of the puzzle, and overwrite the 0000: NOP in the previous part. But I'm really hoping your goal is to understand these magic spells as logic puzzles.

 

Try again. Please don't uncomment the Attack section unless the War section is working properly. Test each iteration one step at a time. Feel free to add a popup message after the 0000: NOP line so you can tell the key presses are working properly.

 

Psuedo-code for the primary goal - triggering the war. We're starting with a basic looping script that looks for key presses. What you are working on now is what happens after the key is released (currently NOP). 

 

/*
// pseudo-code - if war_key is released, then this happens
//start a gang war // not yet, check if gang wars are active first
if 
  gang wars are active
then
  //start a gang war // not yet, check if gang war or attack is going on first
  if or
    a gang war is going on
    gang fighting is going on
  then
    cancel the war or attack
  else
    trigger a gang war
  end
end
*/

 

You keep using the attack key to cancel the war, which is really confusing. For clarification, Offensive gang wars have traditionally been called simply Gang Wars (War). Defensive gang wars have been called Gang Attacks (Attack). Ending a gang war was usually referred to a Canceling. In the end I don't think a cancel key is needed, but for now, please choose a Cancel_Key (Key_Num_Minus=109?).

 

In the meanwhile, I'll rework the script again and make another post.

Link to comment
Share on other sites

OrionSR

WarKeys - Basic

 

This is very much the same looping script with key press checks as before. The main differences are the addition of a third key check for cancelling an on going war or attack. The attack key is active this time too. It'll start an attack but doesn't do any safety checks, which leads to a glitch. If an attack is started while an attack is going on then the blip from the first attack can get lost as a stray blip.

 

And sub-routines have been added. Sub-routines are a normal part of most languages, and built into SCM opcodes. This isn't some Sanny compiler wizardry like high level constructs (while..end, if..then..else..end, etc). The idea here is that instead of complicating the key check routines with nested IF constructs, it's possible to "goto a subroutine" (gosub) which will execute a set of commands and then "return" to the next command following the gosub.

 

WarKeys1.txt

Spoiler
{$CLEO .cs}
//  warkeys.txt
//  Edit mode=SA

const
  War_Key = 106     // Key_Num_Asterisk=106
  Attack_Key = 111  // Key_Num_Slash=111
  Cancel_Key = 109  // Key_Num_Minus=109
end // const

script_name 'warkeys'
wait 10000

{Main Loop}
while true // main loop
  wait 50

  if
    is_key_pressed War_Key
  then
    while is_key_pressed War_Key
      wait 0
    end//while
    gosub @Start_Offensive_Gang_War
  end//if War_Key pressed

  if
    is_key_pressed Attack_Key
  then
    while is_key_pressed Attack_Key
      wait 0
    end//while
    gosub @Start_Defensive_Gang_War
  end//if Attack_Key pressed

  if
    is_key_pressed Cancel_Key
  then
    while is_key_pressed Cancel_Key
      wait 0
    end//while
    gosub @End_Gang_War
  end//if Cancel_Key pressed

end//while main loop
terminate_this_custom_script

{Sub-routunes}
:Start_Offensive_Gang_War
0AA5: call_function 0x446050 num_params 0 pop 0  // CGangWars__StartOffensiveGangWar
0ACE: print_help_formatted "Gang War Has Been Started"     
return

:Start_Defensive_Gang_War
0AA5: call_function 0x444300 num_params 0 pop 0  // CGangWars__StartDefensiveGangWar
0ACE: print_help_formatted "Gang Attack Has Been Started"     
return

:End_Gang_War
0AA5: call_function 0x4464C0 num_params 1 pop 1 1  // CGangWars__EndGangWar
0A8D: [email protected] = read_memory 0x96AB98 size 4 virtual_protect 0  // CGangWars__RadarBlip
if
  075C: does_blip_exist [email protected]
then
  0164: remove_blip [email protected]
end//if attack blip exist
0ACE: print_help_formatted "Gang War Has Been Cancelled"     
return

 

 

Please test this script as written, make sure it works before moving on.

Remove previous scripts that are likely to conflict.

 

Notice that the main loop and key press checks are back to the simple form, nice and organized. This section of the script doesn't need to be changed, for now. The sub-routines at the end are what need to be enhanced with safety checks for gang wars active, and gang wars/fighting going on. 

 

The :End_Gang_War routine is complete, and does not need to be modified. The glitch with the stray blip will be fixed another way. 

 

Add a safety check only for Gang Wars Active to the :Start_Offensive_Gang_War routine. There are examples in previous posts to work with. The pseudo-code is fairly straight forward.

//pseudo code
/*
:Start_Offensive_Gang_War
read status of are gang wars active?
if
  gang wars are active
then
  start an offensive gang war
end
return
*/

Test this modification. If it works in game then make the same modification to the :Start_Defensive_Gang_War sub-routine and test again.

 

Will update with the Gang War Going On modifications shortly. 

Link to comment
Share on other sites

ArmanCan
2 hours ago, OrionSR said:

But I'm really hoping your goal is to understand these magic spells as logic puzzles.

 

Yes.. i'm clever enough to understand your magic spells 😀

 

11 minutes ago, OrionSR said:

Please test this script as written, make sure it works before moving on.

 

 

Will do but it's late right now. I'll test it tomorrow and write the results..

 

It seems the script is getting strong and whole.. Can we say that we should ignore our previous attempts and focus on your last comment/script?🙂

Link to comment
Share on other sites

OrionSR
51 minutes ago, ArmanCan said:

It seems the script is getting strong and whole.

I'm glad you think so. I was worried that the sub-routines might confuse the issue more than clarify. Yes, focus on the new warkeys scripts, but don't ignore the previous versions completely. If you can get the previous version working it'll make this part a lot easier. The WarKeys version is nearly identical to the previous version other than a slight reorganization to sort things into sub-routines. You can still use previous versions as reference in this script fairly directly. Mostly, the indents will change, but also, the final check for gang wars going on is managed a bit differently. So...

 

WarKeys1 is the script I posted above for you to develop. You should be working on your version of WarKeys2, which is WarKeys1 plus checks for Gang Wars Active. This snippet is for WarKeys3. The difference in this segment compared to previous versions is that instead of executing a set of commands to cancel a war that's going on, it'll call :End_Gang_War as a sub-subroutine. The :End_Gang_War subroutine is the same for Gang Wars and Gang Attacks, so any edits to this subroutine will apply to both, and it helps keep the script shorter by sharing a common routine. 

 

Review:

From WarKeys1:

:Start_Offensive_Gang_War
0AA5: call_function 0x446050 num_params 0 pop 0  // CGangWars__StartOffensiveGangWar
0ACE: print_help_formatted "Gang War Has Been Started"     
return

 

And you're supposed to be coding something like this for WarKey2;

//pseudo code
/*
:Start_Offensive_Gang_War
read status of are gang wars active?
if
  gang wars are active
then
  0AA5: call_function 0x446050 num_params 0 pop 0  // CGangWars__StartOffensiveGangWar
  0ACE: print_help_formatted "Gang War Has Been Started"     
end
return
*/

 

This snippet is intended to replace the lines for 0AA5 and 0ACE between then and end when updating to WarKeys3.

   if or
    087A: is_gang_war_going_on
    0A03: is_gang_war_fighting_going_on
  then
    gosub @End_Gang_War
  else
    0AA5: call_function 0x446050 num_params 0 pop 0  // CGangWars__StartOffensiveGangWar
    0ACE: print_help_formatted "Gang War Has Been Started"     
  end//if gang wars going on

 

A similar modification for defensive wars will prevent the stray blip glitch from starting an attack while an attack is in progress.

 

WarKeys4 would remove the key press check and constant for cancelling a war or attack because that trigger is no longer needed. Pressing either of the other gang keys will cancel an ongoing war or attack.

 

 

Link to comment
Share on other sites

ArmanCan
Posted (edited)

@OrionSR i have a question for you.. 

 

Do you have any special concerns? Because i did these tests again and that's how i imagined..i mean PERFECT.. but we have still a tiny problem..

 

Your script is really working nicely and i can start/cancel an offensive or defensive war anytime. If you don't have special concerns we can continue from this script. With the confident  of your script i decided to mix it up which we shouldn't do this in a normal way..

 

- I've started offensive gang war on Jefferson. After first wave i've started defensive gang war. This time game gave the priority to defensive war and told me to "get back into the warzone". (Defensive gangwar started in Grove Street) This is just an attempt and it's irrelevant. I'm just writing here in order to inform you.. 🙂

- I've stayed near the Grove Street, started a defensive gangwar and i defended my turf. After that i got out from my turf and started the defensive war again. When i got back to my turf i realised that the game spawned another roadblock on previous roadblocks which should removed after first defensive attack..This one may need some additional opcodes 😀

Edited by ArmanCan
Link to comment
Share on other sites

OrionSR
8 hours ago, ArmanCan said:

Do you have any special concerns?

A primary concern is that our scripts don't quite match. How far did you make in the transitions between WarKeys1, 2, 3 and 4?

 

8 hours ago, ArmanCan said:

game spawned another roadblock on previous roadblocks which should removed after first defensive attack.

Maybe. I suspect the previous roadblocks are "random" trash leftover from the attack, and it would go away if you left the area and returned. If the roadblocks persist, like what you'd expect from "mission controlled" vehicles, then that can be a major concern. Please test and report.

 

8 hours ago, ArmanCan said:

roadblocks which should removed after first defensive attack..This one may need some additional opcodes

Assuming the roadblocks are just random trash, they should be easy enough to clean up as part of the end gang war subroutine.

 

From DK's plugin for CGangWars.cpp

CVector &CGangWars::PointOfAttack = *reinterpret_cast<CVector *>(GLOBAL_ADDRESS_BY_VERSION(0x96ABC8, 0, 0, 0, 0, 0));

 

CVector defines 3D coordinates: Relative to 0x96ABC8; X= +0x0, Y= +0x4 and Z= +0x8.

 

IIRC from old tests on PS2, these coordinates mark the center of the zone, and most likely match the location of the attack blip. A clear area command could be issued with these coordinates but,... I think the actual spawn location for point of attack is closer to something like, the nearest vehicle node to the PointOfAttack. So, it might be necessary to issue a very large clear area radius to scoop up all the trash when cancelling a war or attack.

 

Or, maybe we could recreate the process of finding the nearest node and use a smaller radius. Clear area is common in standard scripts and missions. There are side effects; It can look weird when everything disappears if CJ is near. Player controlled vehicles within the radius are impounded, something that can be exploited to collect special vehicles. A large clear area radius is more likely to impound random vehicles which CJ has never driven - a glitch prevented by the SilentPatch, btw.

 

With that context in mind, please repeat your experiments and try to verify my old observations. Consider developing a new script to test your ideas or to display the point of attack rather than tamper with the larger warkeys script until we work the bugs out of the system. 

 

Meanwhile, I've been playing around with some of those gang wars and zone functions that were giving me trouble and have been celebrating a lot more Wins than Fails or Crashes. I don't have any particular scripting purpose in mind for these functions; I'm mostly frustrated that I have so much trouble figuring them out, and thought if I worked on enough of them then I might discover the logic hidden in the magic.

 

Link to comment
Share on other sites

ArmanCan
13 hours ago, OrionSR said:

How far did you make in the transitions between WarKeys1, 2, 3 and 4?

 

Actually i've only tested Warkeys1 because you've asked me in the first place. To be honest i don't feel a need to modify this Warkeys1 because everything is running smoothly except this roadblock problem.

 

13 hours ago, OrionSR said:

Maybe. I suspect the previous roadblocks are "random" trash leftover from the attack, and it would go away if you left the area and returned. If the roadblocks persist, like what you'd expect from "mission controlled" vehicles, then that can be a major concern. Please test and report.

 

I've defended my turf, left the area but i've started another defensive gangwar in the neighbour turf (I was close to gym). I think as a result of "Draw Distance" previous roadblock couldn't delete itself. I'm gonna try to find a solution and add some modifications.. After that i'm gonna test it on some other savefiles..🙂

 

14 hours ago, OrionSR said:

A primary concern is that our scripts don't quite match.

 

Well it seems you don't have a special concern so i'm gonna do these modifications, tests and than finalize the script 😉

Link to comment
Share on other sites

OrionSR

I've got a proof of concept script for you to play with. If you CJ get close enough to a gang attack for the cars and gang to spawn and then press Key_Num_Plus then it'll place weapon pickups with colored blip markers above the 5 car nodes nearest to the PointOfAttack. If you were strongly motivated to take out the trash, this script could be adapted to clear a small radius at the spawn point of vehicles only if they were spawned.

 

An odd quirk of the script was that the game failed to find the proper nodes if CJ wasn't in the general area. I suspect that the game can't find nodes in distant areas that aren't fully loaded so it finds the closest it can instead.

 

The blips were attached to pickups because collecting the weapon makes the blip go away.

 

Spoiler
{$CLEO .cs}
{EditMode=SA}
// WarNode.txt

const
 Key_Num_Plus=107
end

Script_Name 'WarNode'

while true
  wait 0
  if
    is_key_pressed Key_Num_Plus
  then
    while is_key_pressed Key_Num_Plus
      wait 0
    end
    Cleanup_Attack_Vehicles()
  end
end

0A93: terminate_this_custom_script


:Cleanup_Attack_Vehicles
0A8D: [email protected] = read_memory 0x96AB4C size 4 virtual_protect 0 // CGangWars__State2=0x96AB4C
if
  [email protected] == 0x2
then
  0ace: "Player Came to Defensive War"

  0A8D: [email protected] = read_memory 0x96ABC8 size 4 virtual_protect 0 // CGangwar__PointOfAttack X
  0A8D: [email protected] = read_memory 0x96ABCC size 4 virtual_protect 0 // CGangwar__PointOfAttack Y
  0A8D: [email protected] = read_memory 0x96ABD0 size 4 virtual_protect 0 // CGangwar__PointOfAttack Z
                                                                                                                                                                                                                                                                                  
  // Relative spawn point for gang peds and pickup 
  04D3: get_nearest_car_path_coords_from [email protected] [email protected] [email protected] type 1 store_to [email protected] [email protected] [email protected]                                                              
  [email protected] +=1.0                                                                                                                               
  032B: [email protected] = create_weapon_pickup #M4 group 3 ammo 1000 at [email protected] [email protected] [email protected]                                                                      
  03DC: [email protected] = add_blip_for_pickup pickup [email protected]                                                                                               
  0165: set_marker [email protected] color_to 0xffffffff  // white                                                                                      
                                                                                                                                         
  // Spawn point for blockade vehicle
  04D3: get_nearest_car_path_coords_from [email protected] [email protected] [email protected] type 2 store_to [email protected] [email protected] [email protected]                                                              
  [email protected] +=1.0                                                                                                                               
  032B: [email protected] = create_weapon_pickup #MINIGUN group 3 ammo 1000 at [email protected] [email protected] [email protected]                                                                 
  03DC: [email protected] = add_blip_for_pickup pickup [email protected]                                                                                               
  0165: set_marker [email protected] color_to 0xff0000ff // red                                                                                         
                                                                                                                                         
  // Spawn point for blockade vehicle
  04D3: get_nearest_car_path_coords_from [email protected] [email protected] [email protected] type 3 store_to [email protected] [email protected] [email protected]                                                              
  [email protected] +=1.0                                                                                                                               
  032B: [email protected] = create_weapon_pickup #KATANA group 3 ammo 1000 at [email protected] [email protected] [email protected]                                                                  
  03DC: [email protected] = add_blip_for_pickup pickup [email protected]                                                                                               
  0165: set_marker [email protected] color_to 0x00ff00ff // green                                                                                       
                                                                                                                                         
  // Spawn point for blockade vehicle
  04D3: get_nearest_car_path_coords_from [email protected] [email protected] [email protected] type 4 store_to [email protected] [email protected] [email protected]                                                              
  [email protected] +=1.0                                                                                                                               
  032B: [email protected] = create_weapon_pickup #SNIPER group 3 ammo 1000 at [email protected] [email protected] [email protected]                                                                  
  03DC: [email protected] = add_blip_for_pickup pickup [email protected]                                                                                               
  0165: set_marker [email protected] color_to 0x0000ffff // blue                                                                                        
                                                                                                                                         
  // Next nearest car node, but nothing from the attack has spawned here yet
  04D3: get_nearest_car_path_coords_from [email protected] [email protected] [email protected] type 5 store_to [email protected] [email protected] [email protected]                                                              
  [email protected] +=1.0                                                                                                                               
  032B: [email protected] = create_weapon_pickup #SHOTGSPA group 3 ammo 1000 at [email protected] [email protected] [email protected]                                                                
  03DC: [email protected] = add_blip_for_pickup pickup [email protected]                                                                                               
  0165: set_marker [email protected] color_to 0xffff00ff // yellow                                                                                      

end
Return

 

 

Link to comment
Share on other sites

ArmanCan
Posted (edited)
11 hours ago, OrionSR said:

I've got a proof of concept script for you to play with

 

well.. great.. 😀 it seems i gotta adapt this to our Warkey and test it 😉

 

Edit: I have small questions for you..

 

    Cleanup_Attack_Vehicles()

 

- Is it same as "gosub @Cleanup_Attack_Vehicles" ?

- When it's simply yes.. than do i have to type "True" or something like that to activate it? Because it seems pressing key doesn't clear the roadblocks or i'm doing something wrong 🤔

Edited by ArmanCan
Link to comment
Share on other sites

OrionSR
4 hours ago, ArmanCan said:

well.. great.. 😀 it seems i gotta adapt this to our Warkey and test it 😉

No, this is an independent script for testing purposes.

 

4 hours ago, ArmanCan said:

- Is it same as "gosub @Cleanup_Attack_Vehicles"

Yes, I've been experimenting with some of the new SB features. I got ahead of myself with the label name. Right now it only marks the 5 nearest nodes with pickups and blips.

 

4 hours ago, ArmanCan said:

- When it's simply yes.. than do i have to type "True" or something like that to activate it?

Nope, the hotkey is Key_Num_Plus. Nothing will happen if CJ isn't close enough to the attack for the vehicles to spawn. Also, I wouldn't expect it to do anything if the gang attack has already been cancelled.

 

Edited by OrionSR
Link to comment
Share on other sites

ArmanCan
Posted (edited)
19 hours ago, OrionSR said:

Nope, the hotkey is Key_Num_Plus. Nothing will happen if CJ isn't close enough to the attack for the vehicles to spawn. Also, I wouldn't expect it to do anything if the gang attack has already been cancelled.

 

 

Yep.. i was doing it wrong 😀 it seems our last tiny problem has been fixed 😉 OrionSR... two scripts are allright but it would be little bit awkward so why don't we combine this into one script and finalize the work? 🙂

 

By the way.. i have another little request from you and a little question..

 

- I'm gonna start with this question.. Can i disable/delete or stomp an external side mission Cesar's Courier Call "External script 2 (BCESAR2)" ? Because it is annoying and messing up my progress..

 

- I've actually asked this from you but i have still problem with this script below.. I've edited and compiled but the game is crashing while loading a save file or starting a new game.. Can you just take a look at it and tell me how can i fix this? 🙏

 

Spoiler
{$CLEO .cs}

thread "Wardrobe"
wait 0

//RBR/CG37: ------------------ All Clothes in Wardrobe ------------------------

:CG_AllClothes
// Flags for owned clothes are at mem addresses 0xa9734c to 0xa97442 - set 1 to own
// These 247 flags are presumably: 249  total clothes items (without the specials)
//                                -  3  default skins (default torso, legs, shoes)
//                                +  1  ski mask (listed as special; not available through wardrobe)

// these three lines by OrionSR surely beat my lengthy code

// [email protected] = 0xa9734c to 0xa97442 step 1
// wait 0 
// OSR/CG37: causing lag 
// 0A8C: write_memory [email protected] size 1 value 1 virtual_protect 0
// end

//RBR/CG37: slightly reworked for better readability
//OSR/CG37: reworked to avoid waits in a for/end loop
0006: [email protected] = 0xA9734C  // start of shopping clothes data
:CG_AllClothes_SetFlags
00D6: if
002B:   0xA97442 >= [email protected] // end of shopping clothes data
004D: jump_if_false @CG_AllClothes_Specials
0A8C: write_memory [email protected] size 1 value 1 virtual_protect 0
000A: [email protected] += 1
0002: jump @CG_AllClothes_SetFlags

:CG_AllClothes_Specials
// Make all specials available
// Setting these globals seems to be enough. Ski Mask is not accessible through wardrobe.
0004: $Gimp_Suit_Available = 1
0004: $Valet_Uniform_Available = 1
0004: $Rural_Clothes_Available = 1
0004: $Croupier_Uniform_Available = 1
0004: $Cop_Uniform_Available = 1
0004: $Pimp_Suit_Available = 1
0004: $Racing_Suit_Available = 1
0004: $Medic_Uniform_Available = 1

// Make all stores selectable in wardrobe
0004: $2549 = 1   // Binco
0004: $2550 = 1   // Pro-Laps
0004: $2551 = 1   // Sub Urban
0004: $2552 = 1   // Zip
0004: $2553 = 1   // Victim
0004: $2554 = 1   // Didier Sachs

//RBR/CG37: PDE's budget - keep for reference
062A: change_float_stat 14 to 108039.0  // fashion budget (approx)
062A: change_float_stat 62 to 108039.0  // total shopping budget

:CG_AllClothes_End
0051: return

 

 

Thank you 🙂

Edited by ArmanCan
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • 1 User Currently Viewing
    0 members, 0 Anonymous, 1 Guest

×
×
  • Create New...

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.