Aller au contenu

A timer?


13 réponses à ce sujet

#1
Guest_dewkl_*

Guest_dewkl_*
  • Guests
Is there a way to create a timer? To have a script or something run after (e.g) 30 seconds (of some action)? 

#2
DavidSims

DavidSims
  • BioWare Employees
  • 196 messages
You can delay an event with a given time. The time however is not exact, particularly if sent to an object far away from the player and when there is a lot of activity happening such as battle. The proccessing of the delayed event is an AI update, and the game gets around to those when it has time. Using the area as the target object helps minimize this.

The code looks something like this:

//I like to declare my event types as constants. Keeps it easy to read. Using the custom event type
//prevents conflicts with other events. Idealy, this should be done in an include file.
const int EVENT_TYPE_MY_DELAYED_EVENT = EVENT_TYPE_CUSTOM_EVENT_1;

...
float fDelay = 5.0;//delay in seconds
event evNew = Event(EVENT_TYPE_MY_DELAYED_EVENT);
object oTarget = GetArea(GetHero());//Could be any target object.
DelayEvent(fDelay, oTarget, evNew);

If you want to pass more detail along with the event, you can set any number of paramaters on the event:

float fDelay = 5.0;//delay in seconds
event evNew = Event(EVENT_TYPE_MY_DELAYED_EVENT);
evNew = SetEventInteger(evNew, 0, 100);//Adding value 100 to index 0
object oTarget = GetArea(GetHero());//Could be any target object.
DelayEvent(fDelay, oTarget, evNew);

Within the taget objects script, you'll need to catch that event and do something with it:

const int EVENT_TYPE_MY_DELAYED_EVENT = EVENT_TYPE_CUSTOM_EVENT_1;

void main()
{
event ev = GetCurrentEvent();
int nEventType = GetEventType(ev);
int nEventHandled = FALSE;

switch(nEventType)
{
case EVENT_TYPE_MY_DELAYED_EVENT:
{
int nValue = GetEventInteger(ev,0);//nValue will be 100, the number we passed in.
//do stuff
break;
}

}
if (!nEventHandled)
{
HandleEvent(ev, RESOURCE_SCRIPT_AREA_CORE);
}
}

If you want a heartbeat, you can delay the same event back to OBJECT_SELF within that script.

Modifié par DavidSims, 23 avril 2010 - 09:40 .


#3
Guest_dewkl_*

Guest_dewkl_*
  • Guests
How do I declare my own constants/event type? I'm just getting "Invalid value assigned to constant".

#4
DavidSims

DavidSims
  • BioWare Employees
  • 196 messages
Outside of a script, use const datatype variablename = value;



in this case, I had:

const int EVENT_TYPE_MY_DELAYED_EVENT = EVENT_TYPE_CUSTOM_EVENT_1;



My best guess is you don't have any include files above that line, so the custom event 1 constant isn't defined. Try including utility_h at the top and try compiling again.

#5
Guest_dewkl_*

Guest_dewkl_*
  • Guests
I tried including utility_h earlier but I get the same error. EVENT_TYPE_CUSTOM_EVENT_1 is a value defined there? I couldn't find anything.

Modifié par dewkl, 26 avril 2010 - 05:22 .


#6
_L_o_B_o_

_L_o_B_o_
  • Members
  • 117 messages
Try EVENT_TYPE_CUSTOM_EVENT_01 ;)

#7
DavidSims

DavidSims
  • BioWare Employees
  • 196 messages
It's in events_h, which is included by utility_h.



Could you post the code? My guess is you're doing something else wrong.

#8
Guest_dewkl_*

Guest_dewkl_*
  • Guests

_L_o_B_o_ wrote...

Try EVENT_TYPE_CUSTOM_EVENT_01 ;)

This works. Thanks for the replies.

#9
Guest_dewkl_*

Guest_dewkl_*
  • Guests
Everything compiles but I don't think I've got it right. I added the case to my module script which I also use to pick up an EVENT_TYPE_CAMPAIGN_ITEM_ACQUIRED-event for some other script.

I have created a case in the module script: http://pastebin.org/182832 (Cropped out the other module script stuff for viewing purposes)
Firing this script that should send a delayed event that the module script picks up (?): http://pastebin.org/182839

NB: "cs_include" is the include that holds the constant. It should say "PING", "PONG", but it just says "PING" unfortunately.

Modifié par dewkl, 26 avril 2010 - 11:37 .


#10
Guest_dewkl_*

Guest_dewkl_*
  • Guests
It works! I just had to specify which script in the DelayEvent.

#11
Craig Graff

Craig Graff
  • Members
  • 608 messages
The reason your script didn't work until you specified the script is that you are delaying the event on the player, but trying to get the module to pick up the event. Using the player as the object means the event will get routed to player_core.nss unless you specify an override script. It also means that OBJECT_SELF will be the player in the module script when that event runs, which might cause some weirdness if you aren't careful.

Modifié par Craig Graff, 29 avril 2010 - 02:56 .


#12
Guest_dewkl_*

Guest_dewkl_*
  • Guests
Bump.
I'm attempting to create a somewhat custom AI for one creature. The idea is that it's supposed to automatically switch between states like this. Performing events Idle->Fire->Help and back to Idle again automatically. If damage is detected it's supposed to fire the Retaliate-event.

Right now I had considered just sending a DelayEvent to the next after every (custom) event. This way I can also adjust enough time for the actions in the states to properly finish (animations and such). Will this get messy/unpredictable? Are there better ways to go about doing this? Any reason this would not work?

note: I just noticed an error in the picture. It doesn't have to be in idle-state to transition to retaliate, ignore the red arrow.

Modifié par dewkl, 26 juin 2010 - 10:20 .


#13
Craig Graff

Craig Graff
  • Members
  • 608 messages
It would generally be beter to use a combination of EVENT_TYPE_HANDLE_CUSTOM_AI and EVENT_TYPE_DAMAGED to do what you are attempting.
Make sure to #include "cai_h" and then call CAI_SetCustomAI to something like CAI_DAMAGED under EVENT_TYPE_DAMAGED. Then under CAI_DAMAGED add the retaliate command and  call CAI_SetCustomAI with CAI_IDLE.

#14
Guest_dewkl_*

Guest_dewkl_*
  • Guests
(Thanks) I'm attempting to use custom AI, but I can't get the states/events/cases to perform their contents, despite being in the correct state. This is definitely due to some silly mistake I've done, I hope someone can do a better job than me at pointing it out. I have enabled AI_CUSTOM_AI_ACTIVE.

The log prints:
Script GetCustomAI: 1 
Script GetCustomAI: 1001

The first is spawn I guess and the second is my custom state called "CAI_USER_DEFINED_FIRE_CONE". When in that state it's supposed to: PrintToLog("CAI_USER_DEFINED_FIRE_CONE"); 

Edit: Seems it has to be in combat to work.

For some reason it doesn't. Here's the code if that helps. (short, it's not supposed to leave the command queue open) 

Modifié par dewkl, 30 juin 2010 - 01:21 .