1. Dismiss Notice
  2. GOG.com logo

    Thanks to YOUR votes, GOG.com now sells:
    - Sea Dogs - Sea Dogs: Caribbean Tales
    - Sea Dogs: City of Abandoned Ships

    Vote now to add Pirates of the Caribbean to the list!

    Dismiss Notice
  3. Under the Crossbones Podcast

    A Pirate Podcast with Interviews
    Music, Comedy and all things Pirate!

    - Episode Guide - About - Subscribe -
    - Twitter - Facebook - iTunes - Android -
    - Youtube - Fill the Coffers -

    Dismiss Notice
  4. New Horizons logo

    Quick links for PotC: New Horizons
    - Download latest version
    - Wiki - FAQ - Report bugs here
    - ModDB profile

  5. GOF logo

    Quick links for AoP2: Gentlemen of Fortune 2
    - Downloads and info
    - Historical Immersion Supermod
    - ModDB Profile

Dismiss Notice
New to the forum?
Please take a moment to read our Welcome Message and Forum Rules.

Included in Build Looting Uniforms from Soldiers

Discussion in 'Features Archive' started by Pieter Boelen, Apr 5, 2016.

  1. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    Got it! The code you're looking for is in PROGRAM\Loc_ai\LAi_groups.c:
    Code:
    //------------------------------------------------------------------------------------------
    //The response to requests
    //------------------------------------------------------------------------------------------
    
    //Update the alarm, called on every frame
    #event_handler("CharacterGroup_UpdateAlarm", "LAi_group_UpdateAlarm");
    void LAi_group_UpdateAlarm()
    {
       ref mchr = GetMainCharacter(); // KK
       LAi_grp_playeralarm = GetEventData();
       LAi_grp_alarmactive = GetEventData();
       if(!bSeaActive)
       {
         // PB -->
         if(!LAi_grp_alarmactive && CheckAttribute(mchr, "locationLock"))
         {
           EndQuestMovie();
           DeleteAttribute(mchr,"locationLock");
         }
         // PB <--
    
    :doff
     
  2. Grey Roger

    Grey Roger Sea Dog Staff Member Storm Modder

    Joined:
    Feb 12, 2007
    Messages:
    6,383
    That seems a bit too general, appearing to cancel "locationLock" for whatever reason it was imposed. Perhaps put the reward outfit in 'SoldierReinforcements' after all. Technically you'll receive it too soon, but either you'll survive the battle in which case it won't much matter exactly when you got the outfit, or you won't survive the battle in which case it really won't matter exactly when you got the outfit! Putting away your weapon so you can press F2 and admire your new outfit prematurely will increase the chances of the latter result. :D
     
    Pieter Boelen likes this.
  3. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    Yep, that's exactly what it is meant to do. It no longer "knows" anything about the reason for it, so it would be hard to add extra specific stuff to it.
    Not impossible though, but probably not worth the trouble either.

    I'm probably a bit stupid here (damn my lack of time to pay proper attention to everything! :whipa ), but.... what reward did we want to add here again?
    Some sort of "get player-character specific soldier outfit" when it happens? There aren't all that many of those; mainly just a few Nathaniel Hawk and Jack Sparrow variations.
    But those are also already assigned when being promoted as "Naval Officer Nathaniel Hawk" and are used as appropriate during the Hoist the Colours storyline.

    Also, 'SoldierReinforcements' only gets triggered if you deliberately kill a generic town guard.
    While it is totally possible to do that, I'd be inclined to not recommend players to do that.
    There tends to be a good chance of not surviving it.... :wp
     
  4. Grey Roger

    Grey Roger Sea Dog Staff Member Storm Modder

    Joined:
    Feb 12, 2007
    Messages:
    6,383
    That's the point. The chances of surviving the attack on the town guard and all the consequences are low. So if you succeed, you could get a free army uniform from the relevant nation. Maybe a special uniform not available from the tailor, though that would mean one special uniform per nation per time period; or maybe remove army officer uniforms from tailors, so you only get them by defeating the whole town guard.

    But there's something wrong if it's easier to defeat the entire town's army by attacking the fort than to defeat the local guard after attacking one of them - where were these guard supermen when the town itself was being attacked? :confused:
     
  5. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    Automatically handing out a random guard uniform or the general nation-specific soldier officer one should be relatively easy.
    There is a function call you can use to find whichever uniform that happens to be for that nation and time period.

    At the moment you can buy soldier uniforms from the tailors ONLY if you are a Privateer/Naval Officer have have the required promotions.
    Your suggestion sounds like a viable way of getting them if you are not in a position to buy them.

    Though I do wonder: Why would you want them if you're not a Privateer or Naval Officer?
    Most people I know like to use those uniforms for their officers and/or crew.
    It would become more relevant if they would serve as a disguise of sorts. But right now that is not a feature that exists.

    Town Capture is handled by the ship boarding code. It is completely independent of walking around towns while ashore.
    I do agree with you that it is quite weird this way.

    We do still have a Planned Feature to tweak the strength of boarding crews and bring some more logic and balancing into it.
    When get to tackling that one, it should be quite doable to have the "extra strength town guard code" apply to soldiers during Town Capture as well. (Excluding the "reinforcements", of course)
    This might make Town Capture excessively difficult though, because there are a lot more soldiers at one time when you do that as opposed to when you're randomly walking around.

    How "super" they are depends heavily on difficulty, by the way.
    It is a feature I added quite a while ago, because the town guards were far too easy targets.
    They have brilliantly good weapons and you could easily steal those right in the early game.

    We could also disable the "extra strength Town Guards" though, because we now have the "Soldier Reinforcements" feature that serves a very similar purpose.
     
  6. Grey Roger

    Grey Roger Sea Dog Staff Member Storm Modder

    Joined:
    Feb 12, 2007
    Messages:
    6,383
    Partly as a form of trophy for having defeated the guards. And partly as another preparation in case disguising does come into play later. (There's already a perk, "Disguiser", which doesn't do much disguising due to there not being any disguising. :D)

    And, since this thread specifically mentions Nathaniel and the main quest, it is a good time to point out that making town capture significantly harder is going to cause Nathaniel problems when it comes to that part of the story where he captures Bridgetown. The super guards already fouled up that story, leading to the need for an excuse to weaken them again for the early mission. (Which, by the way, won't be needed if you restore regular guards to their original strength and rely on the reinforcements to dissuade players from random thuggery. Maybe use the offset to make the reinforcements a bit tougher so it's still really dangerous to get into a fight with the guards.)
     
  7. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    Would just the "officer outfit" suffice for that? Or would you need to get all the individual soldier variations as well?

    You are quite right. It is also not actually related to the original point of this thread, so I made a new one instead:
    Discussion - Regarding Town Guard/Soldier Strength | PiratesAhoy!
    I'd welcome your thoughts on it there. :doff
     
  8. Grey Roger

    Grey Roger Sea Dog Staff Member Storm Modder

    Joined:
    Feb 12, 2007
    Messages:
    6,383
    The relevant officer outfit for the nation and period would do - you've wiped out the whole unit, so if you're helping yourself to someone's uniform as a trophy, it may as well be the commander's. Or a random uniform for nation and period, as you pick the one which has least holes in it. Collecting the whole set would be more complicated - from the player's point of view as he needs to keep attacking guards to get the lot, from the programmer's point of view as the code would need to check which outfits the player already has and pick a random one not currently owned. For something that's just a little bonus for a player who actually managed to take on the guards and win, I'd recommend keeping it simple. :D
     
  9. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    I think adding this line would do the trick:
    Code:
    GiveModel2Player(GetRandomModelForTypeExSubCheck(true, "Land_Officers", "man", GetCurrentLocationNation() ), false);
    
    You could add an extra LogIt message to indicate that this happened.

    For that, use "Soldiers" instead of "Land_Officers".

    Indeed I cannot think of any simple way of accomplishing that from the programming side.
    The simplest version I could think of is:
    Code:
    if (frnd() < 0.2) GiveModel2Player(GetRandomModelForTypeExSubCheck(true, "Land_Officers", "man", GetCurrentLocationNation() ), false); // 20% chance of an officer
    else GiveModel2Player(GetRandomModelForTypeExSubCheck(true, "Soldiers", "man", GetCurrentLocationNation() ), false); // 80% chance of a regular soldier
    
    There is no guarantee then that you'll get an outfit that you didn't already have, but it should at least do more than nothing.

    Since this feature is your idea, I'll leave the final implementation up to you.
    I think you should have enough details to play around with for now. :doff
     
  10. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    @Grey Roger: I made this a separate feature request here so we won't forget about it. Should be easy enough to do it.

    I myself have plenty of other things still to be done, so it won't be me who makes this happen.
    But I'll help whoever does (you?) if necessary. :cheers
     
  11. Grey Roger

    Grey Roger Sea Dog Staff Member Storm Modder

    Joined:
    Feb 12, 2007
    Messages:
    6,383
    'SoldierReinforcements' seems to be called separately for each pair of reinforcement soldiers. That happens for each soldier you kill, starting with the one you originally attacked and also for every other guard in the area that joins in. Is there a way to check whether you've been given the reward outfit so you only get one? Otherwise, if it's picking a random uniform each time, you are likely to end up with the whole lot, along with a 'logit' message every time a new reinforcement is summoned.
     
  12. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    Not for those, no. Only for the actual guards; not for the reinforcements.

    You cannot have more than one of each outfit that exists (they don't work the same as items do).
    You don't need more of them anyway, because you can assign the same outfit to as many characters as you want once you have it.

    This is what the function I suggested does:
    Code:
    void GiveModel2Player(string model, bool assign)
    {
       Characters[GetMainCharacterIndex()].clothes.(model) = true;
       if(assign) SetModelfromArray(GetMainCharacter(), GetModelIndex(model));
    }
    
    There is no harm in calling that multiple times with the same outfit IF you use "assign = false".
    With true, you override the player model every time and I don't think you want that.
    But with false, you'd just end up adding a character attribute that was already there anyway.

    If you do want to avoid it, you can use something like:
    Code:
    string model = "Jack";
    if (!CheckAttribute(PChar, "clothes." + model))
    {
    LogIt("Received Model: " + model);
    GiveModel2Player(model, true);
    }
    
    I think that should work. It would even possible to add a default LogIt message IN the GiveModel2Player function, along with that check.
    Then you just need to call the function and not need to worry anymore about the rest.

    If you want to ensure that every time you get an outfit, you get a NEW one, then it becomes complicated.
    It then needs to become something like this (in UNTESTED code!):
    Code:
    string model = "";
    int i = 0;
    while (model == "" || CheckAttribute(PChar, "clothes." + model) )
    {
    model = GetRandomModelForTypeExSubCheck(true, "Soldiers", "man", GetCurrentLocationNation() );
    if (!CheckAttribute(PChar, "clothes." + model)) GiveModel2Player(model, true);
    else
    {
    i++
    if (i > 20) return;
    }
    }
    
    Not impossible. But you may want to avoid that level of complexity as it is probably not needed. :cheeky
     
  13. Grey Roger

    Grey Roger Sea Dog Staff Member Storm Modder

    Joined:
    Feb 12, 2007
    Messages:
    6,383
    Which is why I said "for every other guard in the area that joins in", not "for every "soldier". ;)

    True, but 'GiveModel2Player(GetRandomModelForTypeExSubCheck(true, "Land_Officers", "man", GetCurrentLocationNation() ), false);' will assign a random uniform. If there are more than one eligible uniform then each time you kill a guard, 'SoldierReinforcements' will be called and potentially give you a different one. Whereas I'd only like to award one uniform for the whole battle.

    Quite the reverse. I want to ensure that, within one battle, you only get one. Getting the same one repeatedly is not a problem as you pointed out, so if it's possible to pick a random uniform at the beginning of the battle and assign that each time, it would work. But that also involves setting something at the start of the battle and remembering it throughout. On the other hand, if you kill a guard in Havana and survive the consequences, earning one Spanish uniform, and then kill a guard in Santiago and do the same, you should have the chance of getting a different one, so I don't want to merely skip the reward if you already have any uniform of the guards' nationality. (It doesn't need to keep going until it finds a uniform which you don't already have. If it picks one which you already have, tough, you're not getting another one this time. That way it won't get stuck if you have already collected the full set when you kill the next guard.)
     
  14. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    Ah, OK. The words "that joins in" threw me off there.

    Technically, no it doesn't. Simply because virtually all nations have only a single model assigned to "Land_Officers".
    For the random ones, it is the "Soldiers" group you need. Refer to post #9 above.

    Two things you could do:
    1. Work it into LAi_group_UpdateAlarm after all.
    or
    2. Change the SoldierReinforcements function so that instead of 1-2 showing up for every guard you kill, a WHOLE BUNCH show up, but only for the FIRST guard you kill.
    That should be simple enough; just requires checking if the "locationLock" attribute is already set and, if so, don't bother with the reinforcements.

    The second one relates very much to Discussion - Regarding Town Guard/Soldier Strength | PiratesAhoy!, of course.

    Then try this in SoldierReinforcements:
    Code:
    if (!CheckAttribute(pchar, "receivemodel") pchar.receivemodel = GetRandomModelForTypeExSubCheck(true, "Soldiers", "man", GetCurrentLocationNation() );
    
    And this in LAi_group_UpdateAlarm:
    Code:
    if (CheckAttribute(mchr, "receivemodel"))
    {
    GiveModel2Player(mchr.receivemodel, false);
    DeleteAttribute(mchr, "receivemodel")
    }
    
    Or something like that.

    That may do the trick. Add the post #9 officer chance in that SoldierReinforcements section if you like that.
     
  15. Grey Roger

    Grey Roger Sea Dog Staff Member Storm Modder

    Joined:
    Feb 12, 2007
    Messages:
    6,383
    In that case, never mind the repeated rewards for hitting the same nation again. You get the officer uniform and if you survive the battle then you get to wear it. Getting the same uniform again doesn't cause trouble so I don't need to check for it. Which means all that is needed is 'GiveModel2Player(GetRandomModelForTypeExSubCheck(true, "Land_Officers", "man", GetCurrentLocationNation() ), false);' added to "CCCFunctions.c". See attached.

    'LAi_group_UpdateAlarm' seems to be too general, I don't want to hand out uniforms for other events. And I don't want to mess with a basic mechanism just for a little bonus item. So an officer uniform for the nation whose guards you're fighting, and if you want more rewards then go and challenge someone else's army. xD
     

    Attached Files:

  16. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    Does sound like the simplest possible solution. :onya

    My last suggestion does cover that. It ONLY gives a model IF the "receivemodel" attribute is set.
    And that is set ONLY when Soldier Reinforcements are generated (and the location is locked).

    LAi_group_UpdateAlarm then MUST unlock the location (otherwise you remain stuck) and when it does,
    you both get the model AND the attribute gets removed so you won't get it again.

    So I think that solution would do exactly what you described in post #13.
    That being said, if you're also happy with the simpler solution, then a more complicated seems a bit superfluous. :cheeky
     
  17. Grey Roger

    Grey Roger Sea Dog Staff Member Storm Modder

    Joined:
    Feb 12, 2007
    Messages:
    6,383
    That would indeed seem to be better, partly because it allows for extra different uniforms after attacking guards of the same nation again, but mainly because it only gives the reward uniform when the fight is actually over. Try these...
     

    Attached Files:

  18. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    Getting there! :cheers

    Three suggestions:

    1. Use this so you can get the officer uniform too:
    Code:
         // GR: Stealing Soldier Uniforms -->
         if (!CheckAttribute(pchar, "receivemodel"))
         {
           if (frnd() < 0.2) pchar.receivemodel = GetRandomModelForTypeExSubCheck(true, "Land_Officers", "man", GetCurrentLocationNation() ); // 20% chance of an officer
           else pchar.receivemodel = GetRandomModelForTypeExSubCheck(true, "Soldiers", "man", GetCurrentLocationNation() ); // otherwise a random soldier
         }
         // GR: Stealing Soldier Uniforms <--
    
    2. And this to prevent seeing that LogIt message if you already got that particular model:
    Code:
           // GR: Stealing Soldier Uniforms -->
           if (CheckAttribute(mchr, "receivemodel") && !CheckAttribute(mchr, "clothes." + mchr.receivemodel))
           {
             GiveModel2Player(mchr.receivemodel, false);   // if you have just defeated a group of soldiers and reinforcements,
             DeleteAttribute(mchr, "receivemodel");     // get a free uniform as set by SoldierReinforcements in CCCFunctions.c
             LogIt("You take a uniform from one of the dead soldiers.");
           }
           // GR: Stealing Soldier Uniforms <--
    
    But since in theory someone may end up using "receivemodel" for non-soldiers too,
    it may be better to not specify the "soldier" business in the LogIt message. Therefore:

    3. OPTIONAL, rewrite GiveModel2Player in PROGRAM\NK.c to automatically take care of the LogIt message instead:
    Code:
    void GiveModel2Player(string model, bool assign)
    {
       if(assign)
       {
         SetModelfromArray(GetMainCharacter(), GetModelIndex(model));
       }
       else
       {
         if (!CheckAttribute(GetMainCharacter(), "clothes." + model))   LogIt("You got the " + model + " outfit: " + Models[GetModelIndex(model)].description);
       }
       Characters[GetMainCharacterIndex()].clothes.(model) = true;
    }
    
     
  19. Grey Roger

    Grey Roger Sea Dog Staff Member Storm Modder

    Joined:
    Feb 12, 2007
    Messages:
    6,383
    Having 'GiveModel2Player' issue a 'logit' whenever you get a new outfit might not be a good idea as it would generate potentially annoying messages whenever quests assign you a new model. "Bartolomeu" with the various pirate outfits and "Hornblower" with the various rank uniforms, not to mention any free-play naval officer who gets new rank uniforms as promotion rewards, would be affected.

    For the message as part of 'LAi_group_UpdateAlarm', perhaps make it conditional:
    Code:
    if(!HasSubStr(mchr.receivemodel, "soldier")) LogIt("You take a uniform from one of the dead soldiers.");
    Or use the same general 'logit' in 'LAi_group_UpdateAlarm' as you proposed for 'GiveModel2Player', so it doesn't say anything about soldiers, it just tells you that you got a new model.
     
  20. Pieter Boelen

    Pieter Boelen (Not So) Old Seadog Staff Member Administrator Storm Modder Hearts of Oak Donator

    Joined:
    Nov 11, 2004
    Messages:
    66,575
    Gender:
    Male
    Occupation:
    Maritime Research: Project Engineer (Analysis)
    Location:
    Wageningen, The Netherlands
    That is why in my suggestion, the log message shows up only if it is a NEW model you got.

    And if the model is being directly assigned, the message is skipped too.
    After all, you don't need to be told you got something then because you can see that yourself too.
    Note that the LogIt line is in the 'else' section of the 'if(assign)'.

    This second case is what happens mostly in the various storylines and for naval officer promotions too.
    Model is directly assigned, so no on-screen message. I think that should be OK, no?
     

Share This Page