Aller au contenu

Photo

Activate item on certain location


  • Veuillez vous connecter pour répondre
18 réponses à ce sujet

#1
andysks

andysks
  • Members
  • 1 650 messages
Hi all. I got an item, which I want to be only available for activation on a certain location. Being the noob scripter that I am, I try Lilacs, but it only takes me as far as  just an area.

From what I understand, this means an area... anywhere. Just acivate on the ground.
Do I need to change this line to something like, get area by tag? Or I don't know... something similar ?

Thanks a lot in advance.

#2
Guest_Iveforgotmypassword_*

Guest_Iveforgotmypassword_*
  • Guests
You could set a conversation on a placeable on the ground ( could be a magic rock, arcane circle or anything that matches what the item does ) that will check using the default gc_check_item script to see if the party's got it when they arrive and click the placeable. If they have then carry on with whatever it does via the conversation.

#3
andysks

andysks
  • Members
  • 1 650 messages
Seems possible. Much simpler. This way I don't need a tag based script, everything will be handled through the convo.

#4
Tchos

Tchos
  • Members
  • 5 054 messages
For reference, there is no GetAreaByTag(), but an area is an object, so you can use GetObjectByTag() to get the area. There's also GetArea(oObject), which returns the area where the specified object is located, which you can use if the area has no tag (and in other circumstances).

#5
Guest_Iveforgotmypassword_*

Guest_Iveforgotmypassword_*
  • Guests
I did it with a rock before just set the placeable to usable, give it a conversation and in the on used script part add the generic gp_talk object script and it will start the conversation. Don't forget to make it plot too so it wont be destroyed in battle.

#6
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages
You can also a set a waypoint, and then check the user's distance from the waypoint. This allows you to limit it to a particular part of an area, as well as making it useful in multiple areas (anywhere with the waypoint).

You could also do it with a trigger, with the trigger setting a variable on the item itself as the PC enters and exits the trigger. You could also throw out a VFX at the same time, so the player knows they're in the right place to use the item.

#7
Claudius33

Claudius33
  • Members
  • 258 messages
Once you get a more experienced scripter :

If you name a script i_<Item Tag>_ac where <Item Tag> is the tag of an object, for instance i_myobject_ac, the script will be fired automatically each time the object is activated.It must be a campaign script if you are building a multi modules campaign. As campaign scripts are dynamic you can update your script at anytime, for instance when you set a new area.
In the script, test the area as mentionned above (testing the tag of an area), for instance :

object oPC = GetFirstPC();
string sArea = GetTag(GetArea(oPC));      / / tag of the area where the PC is
if  ((sArea == "area_1") || (sArea == "area_2") || ... || (sArea == "area_n") ) //  PC is is in one the possible areas
{
.... do something ...
}  
Hope it helps 

Modifié par Claudius33, 04 juillet 2013 - 09:57 .


#8
andysks

andysks
  • Members
  • 1 650 messages
All this is good, and helpful. To wrap things up, I can go with a conversation, say on an arcane circle (That's the easy way), not bad but it doesn't add much mystery.
The other way, is set a trigger that adds a variable on the item, or even the module( does it matter?), and then the script will have an if statement that the item will only be activated if the variable is 1.
Am I getting all things right ? :D

#9
MasterChanger

MasterChanger
  • Members
  • 686 messages
When you say activated, do you mean that you can only click on it in your quickbar when it's within that area, or that it will only have an effect when it's in the area? Because you can easily put a check in your activate script to check if it's in the right area as Tchos and Lugaid describe. If it's not, you can just send a message to the user: "<item name> had no effect."

#10
andysks

andysks
  • Members
  • 1 650 messages
Yes, I want it to be activated from the inventory by right clicking it, but will only have its effects if you are on a certain room. Let me paste the script that Lilacs is giving me ,if it's any help.


void OnActivate(object oEventItem, object oActTarget, location lActTarget, object oActivator)
{
object oTarget;
object oSpawn;
effect eVFX;
object oPC = oActivator;

// This item cannot be used in combat.
if ( GetIsInCombat(oActivator) )
{
SendMessageToPC(oActivator, "Item has no effect here.");
return;
}

// This item must target a location (not an object).
if ( GetIsObjectValid(oActTarget) )
{
SendMessageToPC(oActivator, "Item has no effect here.");
return;
}

// Spawn "c_fiend".
eVFX = EffectVisualEffect(VFX_FNF_FIREBALL);
oTarget = GetWaypointByTag("sp_fiend");
oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "c_fiend", GetLocation(oTarget));
AssignCommand(oSpawn, ActionStartConversation(oPC));
DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oSpawn));
}

P.S : I have named the script i_itemtag_ac

#11
kevL

kevL
  • Members
  • 4 061 messages
I like Lugaid's idea of a trigger ... ( barring the trigger bug )

put something like this in the onEnter & onExit of a trigger that fills the room where Activation is allowed:

// sets a boolean that allows an item to activate or not, depending
// on whether the item possessor has entered or exited the trigger
void main()
{
  object oPC = GetItemPossessor(GetObjectByTag("rod_of_fiend"));
  if (GetEnteringObject() == oPC)
  {
    SetLocalInt(GetArea(OBJECT_SELF), "bCallFiend", TRUE);
  }
  else if (GetExitingObject() == oPC)
  {
    DeleteLocalInt(GetArea(OBJECT_SELF), "bCallFiend");
  }
}

... assumes there is only one such object with the tag "rod_of_fiend" and sort of assumes there is only one room where the fiend may be called



Then for the item_activation script:

// 'i_rod_of_fiend_ac'
void CallFiend(object oWp, object oPC)
{
  location lWp = GetLocation(oWp);
  object oFiend = CreateObject(OBJECT_TYPE_CREATURE, "c_fiend", lWp);

  DelayCommand(0.3f, AssignCommand(oFiend, ActionStartConversation(oPC)));
}


void main()
{
  object oPC = GetItemActivator();
  int bFiend = GetLocalInt(GetArea(oPC), "bCallFiend");
  if (bFiend)
  {
    object oWp = GetWaypointByTag("sp_fiend");
    effect eVis = EffectVisualEffect(VFX_FNF_FIREBALL);
    DelayCommand(0.2f, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oWp));

    DelayCommand(0.4f, CallFiend(oWp, oPC));
  }
  else SendMessageToPC(oPC, "Item has no effect here.");
}



uhm, aren't default Fiends kinda hostile? It might not want to .. conversate .... like that.


And what follows is an activation script (only), if you'd rather do it this way.
note: it's currently set at 5m from the waypoint


// 'i_rod_of_fiend_ac'
void CallFiend(object oWp, object oPC)
{
  location lWp = GetLocation(oWp);
  object oFiend = CreateObject(OBJECT_TYPE_CREATURE, "c_fiend", lWp);

  DelayCommand(0.3f, AssignCommand(oFiend, ActionStartConversation(oPC)));
}


void main()
{
  object oPC = GetItemActivator();
  object oWp = GetWaypointByTag("sp_fiend");
  if (GetDistanceBetween(oPC, oWp) < 5.f)
  {
    effect eVis = EffectVisualEffect(VFX_FNF_FIREBALL);
    DelayCommand(0.2f, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oWp));

    DelayCommand(0.4f, CallFiend(oWp, oPC));
  }
  else SendMessageToPC(oPC, "Item has no effect here.");
}


Ps. both setups compile but neither is tested.

Modifié par kevL, 06 juillet 2013 - 05:35 .


#12
andysks

andysks
  • Members
  • 1 650 messages
Thank a lot, that is very comprehensive KevL. I'm not home right now, but I'll test it later and see what happens.

#13
kevL

kevL
  • Members
  • 4 061 messages
ok... the check for combat should probably be put back in ... or handled in some way.

#14
Darin

Darin
  • Members
  • 282 messages
kevL's got the right idea; I generally go with a local int on the creature, then delete it or set it to 0 on an exit, then check the creature in the OnActivate script for the item; if the variable is 1, fire, if not, do nothing.

You could also, if you wanted it to be really interesting, have two versions of the item; one is a useless item with no powers, the other has the OnActivate Cast spell unique power and the script attached....then you write an OnEnter and OnExit that check the entering object for useless item, if they have it, switch it for the useful one...and the onexit does the opposite. Only issue is they could hand off the item and it would work everywhere...but if you combine it with the local int trick it could be okay.

#15
andysks

andysks
  • Members
  • 1 650 messages
KevL, it works like a charm :D ! I just had to copy the blueprint of the hostile fiend and make the duplicate a friendly faction,then summon this. Thanks a lot, I could never figure this on my own.

#16
kevL

kevL
  • Members
  • 4 061 messages
which one did you go with - the trigger, or the GetDistance method?

#17
andysks

andysks
  • Members
  • 1 650 messages
I went with the trigger. I added also a script on the onexit of the area, that the creature will be destroyed, so that when you enter again you need to summon again.

#18
kevL

kevL
  • Members
  • 4 061 messages
sounds neat :)

#19
andysks

andysks
  • Members
  • 1 650 messages
Hah, yeah it is. I've gotten so much help from this forum that my credits will be a huge list :D.
Seriously, my campaign was nothing before I started asking stuff here.