Skip to content

EffectDamage();

I can't figure out why I'm not being damaged 1 HP of cold damage in this script???
void main()
{
   object oPC = GetNearestCreature
   (CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, OBJECT_SELF);

   if (!GetIsPC(oPC)) return;

   /*int DoOnce = GetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF));

   if (DoOnce==TRUE)
        {
           return;
        }
        SetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF), TRUE);*/


   int nDie = d20();
   if (nDie>=10)
    {

       effect eCold = EffectVisualEffect(VFX_IMP_HEAD_COLD);
       ApplyEffectToObject(DURATION_TYPE_INSTANT, eCold, oPC);
       effect eDamage = EffectDamage(1, DAMAGE_TYPE_COLD, DAMAGE_POWER_NORMAL);
       ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC);
       ApplyEffectToObject(DURATION_TYPE_INSTANT, eCold, oPC);
    }

}
\

Any help would be greatly appreciated. :)

Comments

  • KamirynKamiryn Member Posts: 74
    edited October 2021
    "Bad" luck? There's 45% chance to not get damaged after all.

    I would add some debug messages (name of oPC, nDie,...).

    You apply the visual effect eCold twice btw.
  • ZephiriusZephirius Member Posts: 411
    It's being used on the OnHeratbeat handler, so in theory nDie should roll a 20 sided die every six seconds or so...
  • ZephiriusZephirius Member Posts: 411
    I don't know how to debug. An example would be awesome... :wink:
  • KamirynKamiryn Member Posts: 74
    edited October 2021
    Add something like
    SendMessageToPC(GetFirstPC(), "GetNearestCreature(): "+GetName(oPC));
    ...
    SendMessageToPC(GetFirstPC(), "nDie="+IntToString(nDie));
    
    to write the name of oPC and the die roll to the chat window.

    [edit]Your script works fine for me btw. Which object runs the heartbeat script? A placeable I guess?[/edit]
  • ProlericProleric Member Posts: 1,281
    If this is the module heartbeat, GetNearestCreature won't return a PC because the module has no location.

    Not sure what that /* is doing.

    The simplest way to debug is to insert SendMessageToPC() calls to display data values at key points, such as PC name after the GetNearestCreature call.
  • ZephiriusZephirius Member Posts: 411
    it's an area heartbeat, not module...
  • KamirynKamiryn Member Posts: 74
    edited October 2021
    An area has no location as well. So GetNearest...() won't work.

    Why not put a placeable in that area and let the placeable run the script?
  • ZephiriusZephirius Member Posts: 411
    I had to draw a generic trigger around my entire map and use the triggers OnHeartbeat handler that way. Works just fine now...
  • TerrorbleTerrorble Member Posts: 169
    For what it's worth, GetFirstPC() and GetNextPC() could work since it's only PCs you want. I didn't test but this loop should work in the area's heartbeat event.
    	object oPC = GetFirstPC();
    
    
    	//OBJECT_SELF would be the area if put in the area's HB event
     	while( GetIsObjectValid(oPC) && GetArea(oPC) == OBJECT_SELF )
    	{
    		//do cold damage and VFX
    	oPC = GetNextPC();
    	}
    

    This loop will find all the PCs in the area, whereas yours just finds whichever is deemed closest to the trigger.

    The DoOnce part of the script seems odd to pair with a heartbeat event. The script would potentially do damage once to the player a few seconds after they enter the area, then continue to run every 6 seconds but exit out every time after that. Seems like it should be run once in the OnEnter of the area with the damage and VFX done thru something like: DelayCommand(GetRandomDelay(4.0,15.0),DoColdandVFX());
  • ForSeriousForSerious Member Posts: 446
    edited October 2021
    Terrorble wrote: »

    The DoOnce part of the script seems odd to pair with a heartbeat event. The script would potentially do damage once to the player a few seconds after they enter the area, then continue to run every 6 seconds but exit out every time after that.
    I totally agree. I suppose it is commented out. It just doesn't make any sense with how script is hopped to work.
    Post edited by ForSerious on
  • meaglynmeaglyn Member Posts: 149
    edited October 2021
    What Terrorble wrote is right and likely a better way to do it... It will use fewer resources. Also might consider combining it with a check for there being any PC in the area at all. Isn't there a new function that helps with that or am I confusing nwnxee?

    Anyway, glad you got it working.
    Post edited by meaglyn on
  • BuddywarriorBuddywarrior Member Posts: 62
    A bit of a side bar. But I'm
    Zephirius wrote: »
    I don't know how to debug. An example would be awesome... :wink:

    90% of my time is debugging. My favorite way to narrow things down is to just add a SendMessageToPC to help narrow down where something is working how I would like. for example.
    void main()
    {
       object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, OBJECT_SELF);
       SendMessageToPC(oPC, "Step 1. we see the PC ");
    	
       if (!GetIsPC(oPC)) return;
    
       /*int DoOnce = GetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF));
        SendMessageToPC(oPC, "Step 2. Is DoOnce doing what we think it should?  " + IntToString(DoOnce));	
       if (DoOnce==TRUE)
            {
               return;
            }
            SetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF), TRUE);*/
    
    
       int nDie = d20();
       SendMessageToPC(oPC, "Step 3. What did it roll?  " + IntToString(nDie));	
       
        if (nDie>=10)
        {
           SendMessageToPC(oPC, "Step 4. Sweet! Lets hurt something! ");	
    
           effect eCold = EffectVisualEffect(VFX_IMP_HEAD_COLD);
           ApplyEffectToObject(DURATION_TYPE_INSTANT, eCold, oPC);
           effect eDamage = EffectDamage(1, DAMAGE_TYPE_COLD, DAMAGE_POWER_NORMAL);
           ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC);
           ApplyEffectToObject(DURATION_TYPE_INSTANT, eCold, oPC);
        }
    
    }
    
Sign In or Register to comment.