PortalMark - Recall Tutorial + Some Questions

Post » Mon Nov 19, 2012 1:42 am

So I'm having a few problems getting my portals to work exactly like the Valve game, and I'm going to see if its possible here. Hopefully you guys have some suggestions. First though, I need to explain how my Portals work.

Basically you have a scripted spell. Suprisingly, you don't actually need a script for this spell at all. That's right, completely bare bones. What you need instead is a Projectile. This Projectile then has an explosion. This explosion then has a placed object.
This placed object does most of the work. It has a NullTextureSet, and has the following script (it is a MiscItem). By the way for everything I talk about in here there needs to be one copy for one color portal, and another for the other portal. So, two spell projectiles, spells, magic effects, miscItems, etc. All the scripts are identical, you just need to set the properties differently.

Scriptname PCKP_ScriptPortalMover extends ObjectReferenceObjectReference Property Portal autoObjectReference Property PortalProjTrigger  AutoObjectReference Property PortalTrigger autoevent OnLoad()Portal.MoveTo(self)Utility.Wait(0.10)PortalTrigger.MoveTo(Portal)PortalProjTrigger.MoveTo(Portal)self.Disable()Utility.Wait(1)self.delete()endEvent

Now, to explain the properties. Portal is the Art, it just looks like a portal. Doesn't actually do anything. They are located in a room that is a duplicate of the CTest room, but you could store them anywhere. PortalTrigger is an activator that when stepped into shoots stuff out the other portal. PortalProjTrigger has the exact same script as PortalTrigger, but the activator acts on L_PROJECTILEZONE rather than L_ACTORZONE.
The script on the portal triggers is thus:

Scriptname PCKP_PortalScript extends ObjectReferenceObjectReference Property OtherPortal  AutoGlobalVariable Property JustPorted autoevent OnTriggerEnter(ObjectReference akActionRef)if JustPorted.GetValue() as int ==0  JustPorted.SetValue(1)  akActionRef.MoveTo(OtherPortal,0,0,0,false)endIfendEventevent OnTriggerLeave(ObjectReference akActionRef)Utility.Wait(1.0)JustPorted.SetValue(0)endEvent

and that's it!

QUESTIONS FOR FUTURE DEVELOPMENT:
1) The most glaring flaw of these portals is that they do not rotate such that the direction they are facing is perpendicular to the surface that they are cast on. If I could do that, I could probably figure out a workaround for the other problems.
2) MoveTo does not conserve momentum at all, meaning even if I did manage to figure out what direction to face the darn things I would need another function to determine the velocity and angle of the entrant, then give a Force Push command on the other side in the adjusted direction. Even this seems...problematic.
3) I can't think of a way to make surfaces upon which the portal cannot be cast. The only idea I've got is to make a custom wall or something, add it to a list, and use a FindClosestRefOFAnyTypeInList combined with a getdistance function, and if its really small then to not move the portal.

Potential solution to problem 1:

Have the spawned object create six X markers with placeatme functions in directions above, below, left right forward and backward of it. Then it fires spells at these XMarkers. They all spawn objects that OnLoad get their own XYZ coordinates and set a DoNotAcceptNewInput Global to 1 for a few seconds (basically making it so that the other spells don't override the first one to hit's data). Then the XYZ coordinates are matched to the Portal's XYZ coordinates, and a vector is generated. The portal is then rotated to face in the negative of this vector.

The problem I see with this is that it would be enormously computationally complex. Anyone see a better solution?

EDIT: Tried my solution to problem two, doesn't work. I dunno why. Is there a problem with this script?

Scriptname PCKP_ScriptPortalMover extends ObjectReference ObjectReference Property Portal autoObjectReference Property PortalTrigger autoFormList Property BlackList autoevent OnLoad()ObjectReference DarkWood = Game.FindClosestReferenceOfAnyTypeInListFromRef(BlackList, self, 50.0)if DarkWood==NONE  Portal.MoveTo(self)  Utility.Wait(0.10)  PortalTrigger.MoveTo(Portal)  PortalProjTrigger.MoveTo(Portal)endIfself.Disable()Utility.Wait(1)self.delete()endEventObjectReference Property PortalProjTrigger  Auto 
User avatar
Silvia Gil
 
Posts: 3433
Joined: Mon Nov 20, 2006 9:31 pm

Post » Mon Nov 19, 2012 2:36 am

2) This seems a LOT easier to solve than the other problems. It seems pretty easy to just have the entry portal calculate the velocity of all moving objects within a short distance of itself, and if one of them it triggered, it sends that information to the exit portal and determine which way and how hard to push it from that. It doesn't seem too bad to me... if you can check their positions every few frames, calculating velocity should not be that hard. The problem is: What if someone drops 100 misc items near the portal? I guess you can have a maximum number of objects that can be checked on each update (like 10 or something), but it would likely cause buggy behavior. But how often is anyone ever going to drop 100 items in front of the portal and try to go through it, unless they're just trying to screw it up intentionally? Anyway, let me know if you want help with the math. I guess you'll have to solve 1 first.

I have no idea about the others though, sorry. ):
User avatar
NeverStopThe
 
Posts: 3405
Joined: Tue Mar 27, 2007 11:25 pm

Post » Sun Nov 18, 2012 3:57 pm

Fortunately, only people and projectiles can go through portals, not miscitems.

I'd hate to be a bother, but would you mind showing me a code workflow of what you have in mind? If not, that's cool, I'm sure I can figure it out :tongue:

EDIT: As the only reason to make the speed thing is for falling objects (as projectiles conserve momentum as is):
I guess I can make a bigger activator around the portal one that does a
float firstposition = akActionRef.GetPositionZ()
Utility.Wait(0.05)
float secondpos = akActionRef.GetPositionZ()
float DeltaZ = secondpos +- firstpos
if DeltaZ * 20 >= somenumber that seems like a good threshold value
ForceGlobal.SetValue(DeltaZ * 20)
Utility.Wait(1.0)
ForceGlobal.SetValue(0)

and then the portal has a script that says, if ForceGlobal.GetValue()>0
Portal.PushActorAway(akActionRef, ForceGlobal.GetValue() as float)

Does that make sense?

EDIT: Apprently it made a lot of sense. Works fantastically.
User avatar
Kristina Campbell
 
Posts: 3512
Joined: Sun Oct 15, 2006 7:08 am

Post » Sun Nov 18, 2012 12:51 pm

Wait, does using +- work?

And oh, I thought you wanted the direction in every axis, but yeah, if it only matters for falling actors, it's easier.
User avatar
Dean
 
Posts: 3438
Joined: Fri Jul 27, 2007 4:58 pm

Post » Mon Nov 19, 2012 2:19 am

+- does indeed work.
User avatar
Alexis Acevedo
 
Posts: 3330
Joined: Sat Oct 27, 2007 8:58 pm

Post » Sun Nov 18, 2012 8:51 pm

Okay, I need to set up an activator that disable/deletes projectiles exclusively from my Portal spells, to make it so there are things you can't attach portals to for puzzling purposes.

Problem is, if I use an OnTriggerEnter event, it can delete any projectile that comes its way. But I need it to only delete the portal spells. So, scratch that.
OnHit events even detect projectiles. Problem is, you can't cast disable or delete on projectiles, as they have no member functions. Projectiles have a tick box that says "can be disabled" but I've not the slightest idea what that does, as you still can't script them to be disabled.

Ideas?
User avatar
Wayland Neace
 
Posts: 3430
Joined: Sat Aug 11, 2007 9:01 am


Return to V - Skyrim