| CODE |
| Begin MWE_TelekinesisMain ;Globals for this mod will have the prefix TELE_ ;G Float DestructorCode;gamehour - used in terminating outstanding scripts ;G Short TimeComplete;allows the object to fly towards the player Short TelekinesisActive;this tells if the spell is active Short TelekinesisUsed;this tells if the spell is in use Short TypeValidator;used to validate if the object can be picked up Short TypeApproved;object type can be picked up Short PreventNewActivation;prevents you from using telekinesis on multiple items Short ObjectFlying ;Flag for MWE_TelekinesisObject Float ActivateDistance;the distance at which an object is activated Float TimeNeeded ;minimum 1 - time needed to obtain the object Float TimePassed ;amount of time passed when using telekinesis if ( TELE_DestructorCode != -1 ) Set TELE_DestructorCode to -1 endif if ( TELE_PreventNewActivation == 1 ) return endif if ( player -> GetEffect, 59 );If the player is using telekinesis Set TelekinesisActive to 1 Set MWE_Vars02 to 0 Set MWE_Vars01 to 50000 ToggleLoadFade;Target Function - Append Infix if ( OnActivate == 1 ) Set TELE_DestructorCode to GameHour Set MWE_Vars02 to 0 Set MWE_Vars01 to 50000 ToggleLoadFade;Target Function - Append Infix Set ActivateDistance to ( GetDistance, "Player" ) Set TypeValidator to MWE_Vars03 if ( ActivateDistance <= 192 );If the object is in pick up range Set TimeNeeded to 1 Set TimePassed to 0 Set TelekinesisUsed to 0 Set MWE_Vars02 to 0 Set MWE_Vars01 to 50000 ToggleLoadFade;Target Function - Append Infix Activate ;this is essentially 'ObjectID -> Activate' else;if outside pickup range if ( TypeValidator == 4 );LIGH Set TypeApproved to 0;LIGH entries cannot all be carried elseif ( TypeValidator == 8 );INGR Set TypeApproved to 1 elseif ( TypeValidator == 9 );WEAP Set TypeApproved to 1 elseif ( TypeValidator == 10 );ARMO Set TypeApproved to 1 elseif ( TypeValidator == 11 );AMMO Set TypeApproved to 1 elseif ( TypeValidator == 12 );CLOT Set TypeApproved to 1 elseif ( TypeValidator == 13 );APPA Set TypeApproved to 1 elseif ( TypeValidator == 14 );BOOK Set TypeApproved to 1 elseif ( TypeValidator == 15 );LOCK Set TypeApproved to 1 elseif ( TypeValidator == 16 );PROB Set TypeApproved to 1 elseif ( TypeValidator == 17 );REPA Set TypeApproved to 1 elseif ( TypeValidator == 18 );MISC Set TypeApproved to 1 elseif ( TypeValidator == 19 );ALCH Set TypeApproved to 1 else Set TypeApproved to 0 endif if ( TypeApproved == 1 ) ;if there are any sorts of base time cost calculations, they ;should be done in the line below Set TimeNeeded to ( 1 + GetSecondsPassed ) Set TimePassed to 0 Set TelekinesisUsed to 1 Set MWE_Vars02 to 0 Set MWE_Vars01 to 50000 ToggleLoadFade;Target Function - Append Infix Startscript "MWE_TelekinesisObject";start the object's script else Set TimeNeeded to 0 Set TimePassed to 0 Set TelekinesisUsed to 0 endif endif endif else Set TelekinesisActive to 0 endif if ( TelekinesisUsed == 1 ) ;Modifiers to time costs should be added below Set TimeNeeded to ( TimeNeeded - GetSecondsPassed ) if ( TimeNeeded <= 0 ) Set TelekinesisUsed to 0 Set TELE_PreventNewActivation to 1 Set TELE_ObjectFlying to 1 endif endif if ( TelekinesisActive != 1 ) Set TELE_DestructorCode to GameHour endif End |
| CODE |
| Begin MWE_TelekinesisObject ;Globals for this mod will have the prefix TELE_ ;G Float DestructorCode;gamehour - used in terminating outstanding scripts ;G Short TimeComplete;allows the object to fly towards the player Float DestructorCode Short DestructorCodeInit Float ObjX Float ObjY Float ObjZ Float DistToPlayer Float ZeroPoint Float Sin Float Cos Float Tan Float PlayerRelativeX Float PlayerRelativeY Float PlayerRelativeZ Short ObjectPhase;phase 1 for lift, phase 2 for flying Float FlightTime Float FlightSpeed if ( DestructorCodeInit == 0 );Initializes the destructor code and base data Set DestructorCodeInit to 1 Set DestructorCode to TELE_DestructorCode Set ObjX to GetPos x Set ObjY to GetPos y Set ObjZ to GetPos z Set ZeroPoint to ObjZ Set ObjectPhase to 1 Set FlightTime to 0 Set FlightSpeed to 500 endif if ( TELE_DestructorCode != -1 );if the destructor isn't the default if ( DestructorCode != TELE_DestructorCode ) stopscript MWE_TelekinesisObject;destory the object's script return endif endif ;OBJECT MOVEMENT SCRIPTING BELOW *INCOMPLETE* if ( ObjectPhase == 1 ) Set FlightTime to ( FlightTime + GetSecondsPassed ) Set ObjX to GetPos x Set ObjY to GetPos y Set ObjZ to GetPos z Set PlayerRelativeX to ( Player -> GetPos, X ) Set PlayerRelativeY to ( Player -> GetPos, Y ) Set PlayerRelativeZ to ( Player -> GetPos, Z ) if ( ObjX > PlayerRelativeX ) Set PlayerRelativeX to 1 else Set PlayerRelativeX to -1 endif if ( ObjY > PlayerRelativeY ) Set PlayerRelativeY to 1 else Set PlayerRelativeY to -1 endif if ( ObjZ > PlayerRelativeZ ) Set PlayerRelativeZ to 1 else Set PlayerRelativeZ to -1 endif endif End |
| QUOTE |
| We're lucky, the player is always facing the object enough to have it targetted - so we can think of the trig. in 2d terms |
| QUOTE |
| note: in game where exactly on the player model are the x,y,z coordinates from the getx, gety & getz functions? are they at the center of the player's bounding box? that's going to cause the functions to be a bit weird, things will fly to the center of the player rather than eye level. I guess this is more realistic as well, you don't want your new treasure flying at your eyes. Guiding your loot to your hands sounds better. |
| QUOTE |
| I'm not sure how object->getdistance, player works, does it return the true point to point distance in 3-space between the player and an object? Or does it return a straight-line distance from the xy coordinates of each object (ie: straight-line distance between two points on a map)? The trig calculations are different depending on how that function works. |
| QUOTE (Cid88 @ Mar 30 2005, 04:26 PM) |
| If you want, you could add collision detection by putting an invis creature or npc around the object. This is how fishing mods have collision detection. |
| CODE |
;;pseudocode follows: set xdiff to object->getxpos - player->getxpos set ydiff to object->getypos - player->getypos set zdiff to object->getzpos - player->getzpos ;; topographical distance to player set dist2D to sqrt ( ( xdiff * xdiff ) + ( ydiff * ydiff ) ) ;; distance in 3-space set dist3D to sqrt ( ( zdiff * zdiff ) + ( dist2D * dist2D ) ) |
| QUOTE (tonto_101 @ Mar 30 2005, 05:04 PM) |
| Nah, I don't think it'd be a good idea - not in this case. That would mean dropping an invisible creature on every meaningful object in a cell. That, and I would need to change the object into an activator...so on, so on. Sounds slow, hard-to-do, and I doubt that I'd have the scripting ability to make such a feature 'improve' the look and feel of the mod. |
| QUOTE (halo112358 @ Mar 30 2005, 05:31 PM) |
| You might want to ask aerelorn for an efficient getDistance function in MWE. Otherwise you're making a slew of calculations every frame and I'm not sure how efficient MW is at math. A getdistance rewrite would be useful for stock game scripts as well, you could probably save a few frames in balmora by replacing the stock game calls on all the sign scripts, etc. Now if I had to guess, I'd say the sqrt function they use probably sucks and that's what's making getDistance so slow - the rest of this is just multiplication (which should be fast). So maybe an efficient sqrt call is another prime request. |
| QUOTE (Cid88 @ Mar 30 2005, 08:11 PM) |
| Good point. Just was throwing it out there in case you really felt the need for such a thing. |
| QUOTE |
| the object script doesn't terminate when telekinesis terminates - perhaps terminate the effect and call ->fall on the object when the spell wears off? I had a bit of fun triggering objects and trying to outrun them. |
| QUOTE |
| I noticed strange behavior if I activated a corpse while telekinesis was in effect. Once the spell had worn off I could no longer activate that corpse until I cast telekinesis again. As soon as the new spell took effect the corpse's inventory window would appear. I didn't have multiple corpses around when I noticed this, I'll investigate this a bit more later |
| QUOTE |
| Slick so far, this looks like it has the potential to be a lot of fun. If you don't get to it first maybe I'll write a little patch to give objects the curved initial motion you originally asked for. |