• New Horizons on Maelstrom
    Maelstrom New Horizons


    Visit our website www.piratehorizons.com to quickly find download links for the newest versions of our New Horizons mods Beyond New Horizons and Maelstrom New Horizons!

melee!

mark

Landlubber
I'm really interested in changing the fencing in the game. I'm mainly interested in adding some delays to things and such. I have an idea of what to change to make it more fun. I would also like the delays to depend on your melee skill.

My questions
1) what files do I need to modify? I'm pretty much lost in the forest of folders and files.

2) do "#include <time.h>" and the accompanying functions work in potc?

3) what is the syntax for getting the value of the melee skill?

4) With the right guidance I very well may be able to figure it out, but I am very welcome to any suggestions or tips on how I might go about adding time delays and such.
 
I don't know nothing about what files to look for as I was thinking of importing the fencing from AOP as the combat is way different and requires a bit more strategy.
 
1) Most likely you need the files in PROGRAM\Loc_ai. Most notably LAi_fightparams.c and LAi_events.c.
2) That works fine. Leave out the <> though.
3) sti(pchar.skill.fencing)
4) What kind of delays would you want to add? I once had the idea of only making blocks effective for a short period of time. After that time, the block becomes ineffective. This to counter the ability to just keep blocking forever with no penalty. There already IS a penalty added now: You do get some damage when being hit while blocking now in the latest game versions.

This might also be interesting. My attempted "health scales sworddamage mod". Doesn't seem to work yet though.<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->#define HEALTH_SCALES_SWORDDAMAGE    1
    // 1: The damage done when swordfighting is scaled by your health/max health
    // 0: Stock game behaviour<!--c2--></div><!--ec2-->
From PROGRAM\Loc_ai\LAi_fightparams.c:<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->    if(isBlocked)
    {
        damage = damage*0.3;
    }
    // TIH --> do not show XP messages for other characters, its annoying! Aug24'06
    bool resetshowXP = false;
    if(sti(attack.index) != GetMainCharacterIndex())
    {
        attack.donotshowXP = true;
        resetshowXP = true;
    }
    // TIH <--
    // if(!LAi_IsFightMode(enemy) && attack.equip.blade=="blade5") {damage = damage*(rand(5)+sti(attack.skill.Sneak)+5);}    // ccc sneakmod backstab

    //Íàíîñèì ïîâðåæäåíèå
    // PB: Health scales sworddamage -->
    damage = MakeInt(ApplyArmor(enemy, attack, damage + critical, true) + 0.5); // Original damage
    if(HEALTH_SCALES_SWORDDAMAGE && CheckAttribute(attack, "hp" ) && CheckAttribute(attack, "hp_max" ))
    {damage = damage * sti(attack.hp) / sti(attack.hp_max);} // Health scalar added
    LAi_ApplyCharacterDamage(enemy, damage); // GreatZen-NK
    // PB: Health scales sworddamage <--
    //Ïðîâåðèì íà ñìåðòü
    LAi_CheckKillCharacter(enemy);
    //Åñòü ëè îðóæèå ó öåëè
    bool isSetBalde = (SendMessage(enemy, "ls", MSG_CHARACTER_EX_MSG, "IsSetBalde") != 0);
    //Íà÷èñëÿåì îïûòà
    float exp = LAi_BladeCalcExperience(attack, enemy, dmg);
    if(LAi_IsDead(enemy))
    {
        //Íà÷èñëèì çà óáèéñòâî
        exp = exp + LAi_CalcDeadExp(attack, enemy);
        if(!isSetBalde)
        {
            // ccc mar05 REPLOSS tweak added
            if(enemy.chr_ai.group != LAi_monsters_group) LAi_ChangeReputation(attack, - REPLOSS*3); // NK tempfix for un-drawn blades 04-17
        }
    }
    if(!isSetBalde)
    {
        // ccc mar05 REPLOSS tweak added
        if(enemy.chr_ai.group != LAi_monsters_group) LAi_ChangeReputation(attack, - REPLOSS); // NK tempfix for un-drawn blades 04-17
        exp = 0.0;
    }

    if(!noExp) AddCharacterExp(attack, MakeInt(exp*0.5 + 0.5));
    if ( resetshowXP ) { DeleteAttribute(attack,"donotshowXP"); } // TIH do not show other characters XP increases<!--c2--></div><!--ec2-->
 
Yeah. One of the things I was wanting to do was put a limit to how long the block could be held. To make it more like real fencing, the amount of time the block would be held would actually be quite short, maybe for a fourth of a second. Of course the higher your melee skill, the longer the block lasts, maybe up to a second for a melee skill of 10. Perhaps there would be a pretty small delay after blocking (also scalable by melee skill) so you couldn't just rapidly click the block button and would have to use the retreat more often. I also want to shorten the retreat distance to make it more realistic and useful (retreat and attack). The other delay I was considering is delaying the time after you attacked before you could block. This time would of course be scaled by your melee skill. I would still like to be able to cancel an attack with the block button so as to feint the opponent into blocking and then attacking after his block. I don't know if the last thing is possible, but it would be nice. Plus the higher the skill, the quicker you can block and attack again and have quicker attacks. I think it would be interesting. At least the time factor on the block would be good plus a somewhat shorter retreat. The third thing makes it harder to attack, but with the small damage to blocking opponents, the more agressive fencer would be rewarded.

<img src="style_emoticons/<#EMO_DIR#>/duel_pa.gif" style="vertical-align:middle" emoid=":ixi" border="0" alt="duel_pa.gif" />

and thanks for pointing me at the right files <img src="style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />
 
sorry for double posting, but I wanted to mention what looks to be a usefull function from the LAi_events.c file:

LAi_Character_EndAction()

Now I'm not totally sure if this is what I think it is, but if we could check how long a block has been held, then would we possibly use this function to stop it? or do we use LAi_CharacterEndTask()? I think the question is, "How do we check how long somebody is blocking?" We first have to know whether the player is blocking or not (would LAi_CheckCharacter() possibly have anything to do with this, or GetEventData()?). If the player is blocking, we can start a timer. If the timer reaches the time limit, we could then call one the "end" functions. Which one I don't know. I also don't know where we would put this code.

And where might the file be to change the distance of the retreat? Or is it possible?
 
would you still be able to fight three at a time? it happens quite often that you're surrounded by three. two is very common, i think it happens more often than fighting a single person.
 
Please note that I don't know all the answers to everything. But I'll try to come up with something. <img src="style_emoticons/<#EMO_DIR#>/smile.gif" style="vertical-align:middle" emoid=":)" border="0" alt="smile.gif" />

The only usable delay function that I am aware of is postevent. See here for some simple usage and explanation of this function:<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->// this block allows you to regain control of pchar after a delay. Useful in testing AI funcs on pchar,
// and then getting control back to reset the situation.
// call it with postevent("resetpchar_event", msec); where msec is the delay in ms.
#event_handler("resetpchar_event", "resetpchar");
void resetpchar()
{
    LAi_SetPlayerType(GetMainCharacter());
}<!--c2--></div><!--ec2-->
I have no idea what <i>LAi_Character_EndAction()</i> does. You can try to put it into <i>PROGRAM\console.c</i> and see what happens when you press F12. Make sure to define <i>ref chr</i> before calling that action. Same goes for <i>LAi_CharacterEndTask()</i>, only here you also need to define <i>string endTask</i> beforehand. Not sure how to use that. <img src="style_emoticons/<#EMO_DIR#>/unsure.gif" style="vertical-align:middle" emoid=":?" border="0" alt="unsure.gif" />

I think the "easiest" thing to do would be to add a postevent that is called as soon as the player presses the block key. After the set delay, a "player can block" variable is changed. You can then add some code to <i>void LAi_ApplyCharacterBladeDamage(aref attack, aref enemy, float attackDmg, float hitDmg, bool isBlocked)</i> in PROGRAM\Loc_ai\LAi_fightparams.c that sets isBlocked = false when this "player can block" variable has been changed. So that way the block would become ineffective after the set delay. That wouldn't actually stop the "block animation" though.
 
i've just come up with something: if this is implemented in the game, and corpses would be impassible, this would work really well. you'd mostly fight one at a time if you're lucky, still have the occasional 2 vs. 1 fight, the location where you'd fight would be much more important (retreating to a better position would be more common) and you can fully concentrate on the fight! i think it would give a way better experience if this was combined with impassible corpses.
 
If this is implemented, it would apply to the enemies as well as the player. Therefore the game would remain balanced: Just tougher for all parties. And a toggle would be required in any case. <img src="style_emoticons/<#EMO_DIR#>/yes.gif" style="vertical-align:middle" emoid=":yes" border="0" alt="yes.gif" />
 
I can see what you're saying. That sounds like a good way to do it. Would I call the postevent() from <i>void LAi_CharacterBlock()</i> in LAi_events? Sorry, I am quite unlearned in the ways of potc coding. Would I actually need to create another function that modifies a universal variable "playerCanBlock"? In <i>void LAi_ApplyCharacterBladeDamage(aref attack, aref enemy, float attackDmg, float hitDmg, bool isBlocked)</i> you could write the code:

if(!playerCanBlock)
isBlocked=false;

if the variable was universal. Honestly I'm just wandering around a dense forest trying to tell one tree from another. Perhaps you could tell more about the postevent() function (or someone else can too). Thanks for your help so far.

And I think the impassible corpses would make it quite fun too. And with the danger of fighting multiple opponents, people would be encouraged to use grenades and musketoons more (I personally don't use them very often at all. I probably should)
 
I never used that function, so don't really know anything about it other than that it can be used for delays. You'd need to write a postevent that would make playerCanBlock = false after the set delay. A universal variable would work. One thing that always worried me with this idea was what would happen when the player would press the block key several times. I suppose you'll just need to experiment a bit. That's the way I do my modding: Messing around, trying to guess the right way to do things. And when I am in search of the code I want to change, I try to remember some code, often a BuildSettings.h toggle, that has some relevance to it, then search the PROGRAM folder for that code.

In the Build 14 Alpha, corpses are no longer impassable and I think that is a major improvement. I wouldn't want to return to the obstructing corpses anymore. <img src="style_emoticons/<#EMO_DIR#>/unsure.gif" style="vertical-align:middle" emoid=":?" border="0" alt="unsure.gif" />
 
I mainly just don't know where to make the postevent() function and where to call it; maybe in void LAi_CharacterBlock() in LAi_events? And I'm still pretty new to C programming, so I don't know how to the make the variable universal.

Also, another thing to consider is the fact that once "playerCanBlock" is false, there probably needs to be another postevent() that turns "playerCanBlock" to true after a greater delay.

And don't be discouraged either about not knowing stuff. I think I'm learning stuff just by talking to you. I think I'm really starting to see how the postevent() would work, I just need to know where to put the coding with #eventhandler... that you had in your example and what function should call the postevent(). And I need to know how to make the variable universal, pass it to void LAi_ApplyCharacterBladeDamage(aref attack, aref enemy, float attackDmg, float hitDmg, bool isBlocked), or to call the variable from the applycharacterbladedamage.
 
i'm not talking about the foes blocking, but you having to be octopus to survive three foes slashing at you at different times. <img src="style_emoticons/<#EMO_DIR#>/wacko.gif" style="vertical-align:middle" emoid=":wacko:" border="0" alt="wacko.gif" /> i think it'd result in the one with the most hp winning, because you just try to hack at each other as often as you can in as little time as possible before you get killed by the other two! <img src="style_emoticons/<#EMO_DIR#>/wacko.gif" style="vertical-align:middle" emoid=":wacko:" border="0" alt="wacko.gif" /> anyway, i always turn impassible corpses back on. it makes swashbuckler difficulty doable.
 
You should try and figure out what function is called when the player pressed the block key. Then add the postevent call into that function somewhere.
 
Back
Top