Author Topic: Restricted items during PvP  (Read 777 times)

Legacy_r8_

  • Newbie
  • *
  • Posts: 47
  • Karma: +0/-0
Restricted items during PvP
« on: August 20, 2012, 08:31:08 pm »


               I'm trying to disable potions, healing kits, and spell scrolls during PvP. In non-PvP combat the items should work as usual

I haven't found any scripts that trigger specifically when a player uses any of these three item types.

Any advice?
               
               

               
            

Legacy_ehye_khandee

  • Hero Member
  • *****
  • Posts: 1415
  • Karma: +0/-0
Restricted items during PvP
« Reply #1 on: August 20, 2012, 08:38:09 pm »


               put a routine at the top of your module's OnActivateItem script that does the following:

Test for item used by TYPE, if type is matched, then check to see if the user is in combat, if in combat, check to see if the last creature they hit was a PC, if so, exit the item script totally. This is about as close as I can come to your desired outcome, there is nothing to check for who is involved in the combat beyond this that I am aware of - best of luck on this.

Be well. Game on.
GM_ODA
               
               

               
            

Legacy_MagicalMaster

  • Hero Member
  • *****
  • Posts: 2712
  • Karma: +0/-0
Restricted items during PvP
« Reply #2 on: August 20, 2012, 08:47:33 pm »


               If the PvP combat is in a specific area like an arena, that can be used as well.

Also, you could check to see if there are any PCs within 40 yards or whatever that are hostile.  That might work.
               
               

               
            

Legacy_r8_

  • Newbie
  • *
  • Posts: 47
  • Karma: +0/-0
Restricted items during PvP
« Reply #3 on: August 20, 2012, 09:19:06 pm »


               Thanks for the quick responses

I was sure that OnActivateItem is only triggered by Unique Power (or similar) item properties. To test it, I added this to my OnActivateItem event:

void main()
{
    object oItem = GetItemActivated();
    object oPC = GetItemActivator();

    if (GetBaseItemType(oItem) == BASE_ITEM_POTIONS)
    {
       SendMessageToPC(oPC, "you've activated a potion");
    }
}

On drinking a potion, this doesn't seem to work. This is going to be module-wide, so it's not area specific. Testing to see if the player is in PVP is the easy part. I just need to know where the items trigger from when they're used
               
               

               


                     Modifié par r8_, 20 août 2012 - 08:19 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Restricted items during PvP
« Reply #4 on: August 20, 2012, 11:40:02 pm »


               Most of the potions and scrolls impact scripts have code in them for the SpellHook,  Just set the name for the Hook in your module load script.   You will then be able to use that script to hook your potions and scrolls.
 #include "x2_inc_switches"
...
void main()
{
...
    SetModuleOverrideSpellscript("HookSpell");
...
}

If something dose not already have code for the spell hook,  You will have to add it to the impact script for what you want to hook. 

As far as heal kits go, They  are 100% hard coded.  The best thing to do with them, is to just remove them from your module.     
               
               

               
            

Legacy_ffbj

  • Hero Member
  • *****
  • Posts: 1097
  • Karma: +0/-0
Restricted items during PvP
« Reply #5 on: August 21, 2012, 01:28:52 am »


               Yeah healing kits are the worst. I have them in my campaign only as medium high treasure.
I replaced with Leomist healing bandages which cannot be used in combat, and have a lesser chance to cure disease or poison, though they can if you are a good enough healer.
               
               

               


                     Modifié par ffbj, 21 août 2012 - 12:32 .
                     
                  


            

Legacy_r8_

  • Newbie
  • *
  • Posts: 47
  • Karma: +0/-0
Restricted items during PvP
« Reply #6 on: August 24, 2012, 08:07:45 pm »


               Thanks Lightfoot8

I got spell hooking to work using SetModuleOverrideSpellScriptFinished to block spell casting which is surprisingly simple. I made a conditional using GetBaseItemType to test for scrolls & potions

What I'm having trouble with is detecting if a PC is attacking (or being attacked by) another player, which works only in some instances. It's more complex than I anticipated. The spell canceling will sometimes remain active even after PVP combat. I'm using two clients connected to a test server, and then restarting/rejoining after each PVP test. Very time consuming

I'm using combinations of GetIsPC, GetLastHostileActor, and GetAttackTarget for detecting PvP
               
               

               


                     Modifié par r8_, 24 août 2012 - 07:13 .
                     
                  


            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Restricted items during PvP
« Reply #7 on: August 24, 2012, 09:36:37 pm »


               Is there a method to catch the event of one PC setting another to "dislike"?
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Restricted items during PvP
« Reply #8 on: August 25, 2012, 04:44:55 pm »


               Sounds like you are trying to get a little to complex in your checking. 

I think I would just check for two conditions.

1 Is the PC in combat.
2 Is there a Hostile PC in the same area.

I Simply figure that if there is a Hostile PC in the area, It is a PvP Situation.

With  that line of thinking you end up with something like this:

#include "x2_inc_spellhook"
const int FIRST = 1;

void main()
{
  if (GetIsInCombat() &&
      GetNearestCreature
      (
         CREATURE_TYPE_PLAYER_CHAR,
         PLAYER_CHAR_IS_PC,
         OBJECT_SELF,
         FIRST,
         CREATURE_TYPE_REPUTATION,
         REPUTATION_TYPE_ENEMY
      ) != OBJECT_INVALID
     )//END if Condition clause
   {
     if ( /*Checks For Dissalowed Spells in PVP */)
       SetModuleOverrideSpellScriptFinished ();
   }
}
               
               

               
            

Legacy_r8_

  • Newbie
  • *
  • Posts: 47
  • Karma: +0/-0
Restricted items during PvP
« Reply #9 on: August 25, 2012, 06:09:27 pm »


               Thanks again, it works!

Now I'm looking for a way to set a PvP target to hostile automatically using SetPCDislike when combat begins. The GetNearestCreature conditional will only work when the opposing PC is red (hostile).

I know on some servers they make it so PvP is only possible if you set your opponent to "Dislike" in the player list
               
               

               
            

Legacy_ffbj

  • Hero Member
  • *****
  • Posts: 1097
  • Karma: +0/-0
Restricted items during PvP
« Reply #10 on: August 26, 2012, 07:36:17 pm »


               So it's solved. That's good. It reminded me of something I did a while back, which might be of some interest:

       void main()
    {
        // Loop through PCs.
        object oPC = GetFirstPC();
        while (oPC != OBJECT_INVALID)
        {
            // See if oPC's last attacker is a PC and both are in combat (not necessarily with each other).
            object oAttacker = GetNearestCreature (CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
            if (GetIsEnemy(oPC, oAttacker) && GetIsInCombat(oAttacker)  &&  GetIsInCombat(oPC)
            && GetArea(oPC) == GetArea(oAttacker))
            {
                // Construct the message to send to DMs.
                string sArea = GetName(GetArea(oPC));
                string sPC = GetName(oPC);
                string sAttacker = GetName(oAttacker);
                string sMessage = (sPC + " was attacked by " + sAttacker + " in " + sArea + ".");
                // Send the message.
                SendMessageToAllDMs(sMessage);
                FloatingTextStringOnCreature(sMessage, oPC, TRUE);//comment out if not wanted.
            }
            oPC = GetNextPC();
        }
}
It's sort of fuzzy logic attempting to realize the specific from the general.
I never really tested it thoroughly.  It would have to be executed out of a hb.
The original idea was to get the first attacker, sort of to answer the oft asked query:
"Who started it"? 

Or maybe something more like this:
    void main()
    {
        // Loop through PCs.
        object oPC = GetFirstPC();
        while (oPC != OBJECT_INVALID)
        {
            // See if oPC's last attack target is a PC.
            object oTarget = GetAttackTarget(oPC);
            object oAttacker = GetLastAttacker(oTarget);
            if (GetIsPC(oAttacker) && GetIsPC(oTarget))
            {
                SetPCDislike(oAttacker, oTarget);
                // Construct the message to send to DMs.
                string sArea = GetName(GetArea(oTarget));
                string sPC = GetName(oTarget);
                string sAttacker = GetName(oAttacker);
                string sMessage = (sPC + " was attacked by " + sAttacker + " in " + sArea + ".");
                // Send the message.
                SendMessageToAllDMs(sMessage);
                FloatingTextStringOnCreature(sMessage, oPC, TRUE);
                //comment out if not wanted. Left in for testing purposes.
            }
            oPC = GetNextPC();
        }
}
So just using last attacker and no need for an area check and then set them to dislike, though I think when you attack someone it automatically sets them to dislike eachother.  Maybe get last attack attempted target would work.
               
               

               


                     Modifié par ffbj, 26 août 2012 - 07:42 .
                     
                  


            

Legacy_r8_

  • Newbie
  • *
  • Posts: 47
  • Karma: +0/-0
Restricted items during PvP
« Reply #11 on: August 28, 2012, 04:35:41 pm »


               I tried your code ffbj. It works, though the PvP item restriction has a few nuances that make it more complex than it should be. This is with the heartbeat SetPCDislike, and Lightfoot8's GetNearestCreature:

problem 1:
PvP begins
Opponent turns red after 6 seconds (heartbeat)
Player sets opponent to "like" in the player list
Player drinks potion in between heartbeats, healed
Opponent turns red after 6 seconds
repeat

problem 2:
A hostile player is nearby
Potions and scrolls are disabled when attacking a monster

problem 3:
Drinking potion(s) right before combat (heartbeat creates a delay)
Casting scrolls(s) at another PC right before combat

problem 4:
Someone turns everyone in the server hostile
When in the same area as other players, all of the other players now have potions/scrolls disabled

I might just give up and disable potions/scrolls during all combat, using GetIsInCombat.
I tried my original idea of using GetIsPC, GetLastAttacker etc. for detecting PvP, and it's even buggier


spell hook code:


#include "x2_inc_switches"

const int FIRST = 1;

void main()
{

object oSpellTarget = GetSpellTargetObject();
int oSpellItem = GetBaseItemType(GetSpellCastItem());


    if (GetIsInCombat() &&
          GetNearestCreature
          (
             CREATURE_TYPE_PLAYER_CHAR,
             PLAYER_CHAR_IS_PC,
             OBJECT_SELF,
             FIRST,
             CREATURE_TYPE_REPUTATION,
             REPUTATION_TYPE_ENEMY
          ) != OBJECT_INVALID
         )
    {

     //is your spell a potion or scroll?
    if (oSpellItem == BASE_ITEM_POTIONS ||
        oSpellItem == BASE_ITEM_ENCHANTED_POTION ||
        oSpellItem == BASE_ITEM_SPELLSCROLL ||
        oSpellItem == BASE_ITEM_ENCHANTED_SCROLL ||
        oSpellItem == BASE_ITEM_ENCHANTED_WAND
             )
        {

            SetModuleOverrideSpellScriptFinished ();
            SendMessageToPC(OBJECT_SELF, "Potions and scrolls during PvP combat have been disabled");

        }
    }
}



heartbeat code:


void main()
    {
        // Loop through PCs.
        object oPC = GetFirstPC();
        while (oPC != OBJECT_INVALID)
        {
            // See if oPC's last attack target is a PC.
            object oTarget = GetAttackTarget(oPC);
            object oAttacker = GetLastAttacker(oTarget);
            if (GetIsPC(oAttacker) && GetIsPC(oTarget))
            {
                SetPCDislike(oAttacker, oTarget);
            }
            oPC = GetNextPC();
        }
}


Alternate spell hook PvP detection without using GetNearestCreature:
see comments for bugs

#include "x2_inc_switches"

void main()
{

object oSpellTarget = GetSpellTargetObject();
object oAttackTarget = GetAttackTarget();
object oLastAttacker = GetLastAttacker();
int oSpellItem = GetBaseItemType(GetSpellCastItem());


    if (GetIsInCombat() &&
        oSpellItem == BASE_ITEM_POTIONS ||
        oSpellItem == BASE_ITEM_ENCHANTED_POTION ||
        oSpellItem == BASE_ITEM_SPELLSCROLL ||
        oSpellItem == BASE_ITEM_ENCHANTED_SCROLL ||
        oSpellItem == BASE_ITEM_ENCHANTED_WAND
        )

    {

        // potions refuse to work when using this, permanently disabled even outside of PvP
        // also, oLastAttacker will disable scrolls/potions indefinitely until PC is attacked by a monster
        if (GetIsPC(oSpellTarget) || GetIsPC(oAttackTarget) || GetIsPC(oLastAttacker))
        {

            SetModuleOverrideSpellScriptFinished ();
            SendMessageToPC(OBJECT_SELF, "Potions and scrolls during PvP combat have been disabled");
        }
    }
}

In order to test this, I have to start a server and join with two clients, and restarting/rejoining for every test. It's very tedious compared to just hitting F9

Thanks for your help so far
               
               

               


                     Modifié par r8_, 28 août 2012 - 03:43 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Restricted items during PvP
« Reply #12 on: September 03, 2012, 12:33:51 am »


               To me the main problem here is that you are not clearly defining what you concider PvP.

r8_ wrote...

problem 1:
PvP begins
Opponent turns red after 6 seconds (heartbeat)
Player sets opponent to "like" in the player list
Player drinks potion in between heartbeats, healed
Opponent turns red after 6 seconds
repeat

I would guess that is a problem in my code.   The GetNearest function is returning the nearest PC that the caster dislikes, When what we really want is the nearest PC that dislikes the Caster.  I also do not like the Idea of having the AI turn the PC hostile to other PC's, It should be the PC's choice.    That way friendly fire does not start kicking PC's from partys and accidents lets the PC decide if they are offended or not. 
 

problem 2:
A hostile player is nearby
Potions and scrolls are disabled when attacking a monster

As it should be.   Too me if a hostile PC is near by it is a PvP situation, But that is my opinion, it does not have to be yours.   I can see many times when one PC can use other monsters, summons  or hostiles as part of there PvP.   Making it any other way would cause a situation just like 1 above.   PC attacks PC,  PC Attacks monster , Drinks potion and goes back to attacking to PC.  

Again the problem is that you need to define better what PvP is in your world.   If not we are just shooting in the dark on how to adjust the script.  

 

problem 3:
Drinking potion(s) right before combat (heartbeat creates a delay)
Casting scrolls(s) at another PC right before combat


Well again Why can a player not cast a scroll at a PC is he is friendly and no PvP is going on.   reguardless of if the Pv is starting a PvP or not.  

problem 4:
Someone turns everyone in the server hostile
When in the same area as other players, all of the other players now have potions/scrolls disabled


Again need a better definition of what PvP is in your world.   Also the rules players are to Play by in reguards to PvP.  To me the only time a Player should turn themselves hostile to another player, is if they are planning to attack or want to be attacked,   Again My Opinion.  

...

I also really see no reason to treat PvP different then Player vs hostile. (opinion again)
I would say that if there was combat going on and there was a hostile within x feet the, the potion/scroll should have a x% chance of failure. 

What is the most detailed description, that you can give, of what PvP is on your world.  Also, when they should be disabled within that Time frame.