[Newton] Physik Tür

Posted By: Anonymous

[Newton] Physik Tür - 03/10/07 14:58

Hi ich hab mal eine frage,
Wie mache ich mit newton eine Tür die man mit einer taste öffnen kann aber auf äußere physik einflüsse reagiert.(z.b. wenn eine kiste vor der tür steht geht die tür nicht auf)

Danke im Vorraus
Posted By: Anonymous

Re: [Newton] Physik Tür - 03/13/07 19:33

weiß niemand etwas.Vermutungen würden auch helfen.
Posted By: RedPhoenix

Re: [Newton] Physik Tür - 03/13/07 21:22

Die Tür muss ein Newton Physikobjekt sein, das mit dem Tastendruck geht dann genau wie bei den normalen doors nur das du zum Drehen nicht die Gstudiobefehle benutzt sondern Newtonbodyaddtorque oder so. Es gibt dabei aber einige Probleme über die man vorher nachdenken sollte:
1: Ich weiß nicht genau inwiefern Newton die Push-Parameter von Entities beeinflusst. Wenn dein PLayer also nicht auch ein Newtonobjekt ist (was durchaus möglich aber nicht ganz einfach zu machen ist) stellt die Tür für ihn möglicherweise kein Hindernis mehr da.

2: Wenn die Tür blockiert ist müsste das Newton script die drehung ja beenden. Solange die Tür blockiert ist, ginge sie natürlich nicht auf oder zu, aber wenn das Hindernis dann irgendwannmal weg ist, würde die Drehfunction ja weiterlaufen. Die beendung der Drehung ginge aber nicht per Kollisionsevents, die funktionieren mit Newton (soweit ich weiß) nicht.
Posted By: Anonymous

Re: [Newton] Physik Tür - 03/14/07 16:29

also ich hab das so gemacht das der player auf phsikobjekte reagiert.

kannst du mir den genauen befehl sagen um die tür zu drehen?

also aber bis dahin hat es sehr geholfen vielen dank!!!
Posted By: RedPhoenix

Re: [Newton] Physik Tür - 03/16/07 23:30

Wenn du deine Tür zu einem Newtonphysikobjekt machst, darfst du sie nicht mehr anhand ihre x,Y,Z Werte bewegen oder anhand ihrer Winkel drehen. Dazu musst du nun die Newton eigenen Dll-Functionen verwnden. In der Door_swing (die Aktion die deine Tür bisher gedreht hat), musst du alle ent_move Befehle durch
NewtonBodyAddForce (Body, temp.X, temp.Y, temp.z); ersetzen, wobei temp.X,y,Z relative (durch vec_rotate auf die Türwinkel ausgerichtete) Werte sein müssen. Body muss durch body = NewtonGetBody (my); am Beginn der Function zugewiesen werden. Dazu muss vorher body als lokale Variable definiert sein.
Außerdem sollte zu Beginn der Function und nach allen Wait Befehlen sichergestellt sein, dass dll_handle auf dem Newtonhandle steht.

Alle Drehungen in der door_swing Function müssen durch
NewtonBodyAddTorque (Body, temp.x, temp.y, temp.z);
ersetzt werden wobei der Z parameter Pan Drehungen entspricht.

Um zu verhinden, dass die Tür aus den Angeln kippt müssen außerdem die anderen Winkel erhalten werden durch:
NewtonBodySetOmega (Body, temp);
wobei hier die X und Y werte größer 0 und Z 0 sein sollte.

Welche Werte für dich sinnvoll sind, weiß ich nicht das musst du einfach ausprobieren (und das kann durchaus länger dauern). Benutze aber nicht zu kleine Werte, orientier dich an der voreingestellten Variable Newtongravity, welche die Anziehungskraft angibt.
Posted By: Anonymous

Re: [Newton] Physik Tür - 03/17/07 21:07

ah ich hab nur die hälfte kapiert.kannst du so was für mich schreiben?
Posted By: RedPhoenix

Re: [Newton] Physik Tür - 03/19/07 18:17

Ich versuch mich dran, ist aber nicht ganz einfach könnte also noch eine Weile dauern.

Außerdem noch eine Frage: Nur für normale Türen oder auch für Klappen und/oder Gates (die hoch und runterfahren statt zu drehen) oder Schiebetüren.
Eine Function für alle Türarten zu machen ist nämlich noch komplizierter, deshalb wärs gut, wenn ich weiß, was ich weglassen kann.
Posted By: Anonymous

Re: [Newton] Physik Tür - 03/19/07 18:21

nur eine normale tür. Vielen dank RedPhoenix
Posted By: RedPhoenix

Re: [Newton] Physik Tür - 03/29/07 15:17

So die Türenaktion nimmt so langsam Formen an, ich hatte leider in den letzten Tagen nur wenig Zeit, deshalb hat's länger gedauert. Ein paar Fehler muss ich noch beseitigen.
Eine Tür muss sich möglichst exakt um 90 Grad drehen, das durch eine Berechnung zu erreichen ist ziemlich knifflig. Ich habe allerdings einen kleinen Trickk entdeckt, der das vereinfachen könnte indem man die Tür UNGEFÄHR 90 Grad dreht und dann auf eine exakte Winkelposition transformiert. Das gebe vielleicht einen kleinen Ruck, ich hoffe aber das macht nichts.

Zwei Fragen hätte ich auch noch:
1: Die Tür soll man wahrscheinlich per Mausklick öffnen können. Soll sie aber auch noch durch "eindrücken" durch z.B. Explosionen oder eine dagegen rennende Person aufgehen? Dann müsste ich der Tür eine große Masse geben um zu verhindern, das sie einfach so aufgeht. Das würde dazu führen, dass die Tür wahrscheinlich alle Objekte aus dem Weg fegen wird.
2: Soll die Aktion gestoppt werden wenn die Tür blockiert ist, oder solange versuchen die Tür zu öffnen, bis keine Blockade mehr da ist?
Posted By: Anonymous

Re: [Newton] Physik Tür - 03/29/07 15:45

zu 1.Es wäre gut wenn sie auch durch eindrücken und explosionen aufgegen würde.

zu 2.Am besten wäre es wenn das was hinter der tür hat eine größere asse wie die tür hat stoppt sie wenn nicht dann geht sie solange auf bis das objekt weg ist

Vielen dank das du das machst
Posted By: RedPhoenix

Re: [Newton] Physik Tür - 03/29/07 15:58

Ach ja noch was: Nutzt du die doors.wdl aus den (mittlerweile schon etwas älteren Templates)? Dann könnte ich mir ein paar Sachen sparen.
Posted By: Anonymous

Re: [Newton] Physik Tür - 03/29/07 16:40

Nein ich nehme keine templates.Aber ich könnte sie verwenden wenns für dich einfacher wäre
Posted By: Anonymous

Re: [Newton] Physik Tür - 04/05/07 20:34

hi wie weit bist mit dem script für die tür?
Posted By: RedPhoenix

Re: [Newton] Physik Tür - 04/06/07 21:41

Also ich geb dir hier mal eine erste Version von dem Code, funktioniert aber noch nicht so sicher, wie er sollte.

Function door_physic(Body)
{
// Balance...
temp.x = 0;
temp.y = 0;
temp.z = MY.SKILL46;
vec_scale(temp, 4);
//vec_rotate(temp, my.pan);
NewtonBodySetOmega (Body, temp);
//NewtonbodySetvelocity(body,nullvector);
}

function _door_swing_newton()
{ //Das ist eine Template dooraktion,
//die einfach die Bewegungsbefehle an die Newtonfunktion übergibt
var body;
var saved_pan;
MY.__MOVING = ON;
MY.SKILL46 = 0;

// check whether to open or to close
if(MY._CURRENTPOS < MY._ENDPOS)
{
saved_pan = MY.PAN;
if(MY.__SILENT == OFF) { ent_PLAYSOUND (ME,open_snd,66); }
while(MY._CURRENTPOS < MY._ENDPOS)
{
MY.SKILL46 = -MY._FORCE*TIME;
MY._CURRENTPOS = abs(saved_pan-my.pan);
wait(1);
}
//Dieser Codeteil funktioniert auf meinem ystem noch nicht richtig!
//MY.PAN += MY._CURRENTPOS-MY._ENDPOS; // Das ergibt einen kleinen Sprung
//body = NewtonGetBody (MY);//Damit die Tür auch exakt richtig steht
//NewtonBodySetTransform (body); // Das verändern der Winkel muss für Newton gültig gemacht werden
MY._CURRENTPOS = MY._ENDPOS;
saved_pan = MY.PAN;
}
else // MY._CURRENTPOS >= MY._ENDPOS
{
if(MY.__SILENT == OFF) { ent_playsound(ME,close_snd,66); }
while(MY._CURRENTPOS > 0)
{
MY.SKILL46 = MY._FORCE*TIME;
MY._CURRENTPOS = 90-abs(saved_pan-my.pan);
wait(1);
}
// MY.PAN += MY._CURRENTPOS; //Hier dasselbe
//body = NewtonGetBody (MY);
//NewtonBodySetTransform (body); //Damit die Tür auch exakt richtig steht
MY._CURRENTPOS = 0;
}
MY.__MOVING = OFF;
My.SKILL46 = 0;
}


function newtondoor_event()
{
_doorevent_check();
if(RESULT) { BRANCH _door_swing_newton; }
}


ACTION newtondoor
{
MY.MASS = 10000; // Wert auf die Massen anderer Levelgegenstände anpassen
MY.SKILL46 = 0;
//c_setminmax(MY);
newtoncreatedoorentity();
IF (MY.EVENT == NULL) { MY.EVENT = newtondoor_event; }
_doorevent_init();
if(MY._FORCE == 0) { MY._FORCE = 20; } //Höher wenn Masse kleiner!
if(MY._ENDPOS == 0) { MY._ENDPOS = 90; } //Drehwinkel
}

function NewtoncreatedoorEntity ()
{
var collisionType;
var body;
dll_handle = newtonHandle;

// if entity is not destructible. Set health very heigth

// check for collision type
collisionType = 0;

body = NewtonAddMapEntity (my, collisionType);
NewtonSetBodyMass (body, MY.MASS);
NewtonSetBodyLinearDamp (body, 0.1);
NewtonSetBodyAngularDamp (body, 0.1, 0.1, 0.1);
NewtonSetBodyMaterial (body, wood_material);
NewtonSetBodyAutoActiveState (Body, 0);
NewtonSetBodyActiveState (Body, 1);
NewtonSetBodyForceAndTorque (Body, door_physic);

}

Bei mir gibt das sehr unterschiedliche Resultate... Bei der hälfte meiner Engine Starts funktioniert der Code richtig, bei der anderen Hälfte spielt er total verrückt. Ich weiß zwar wo das Problem liegt, aber ich weiß noch nicht genau, wie ichs korrigieren kann. Ich benutze hier Newtonbodysetomega anstatt newtonbodyaddtorque für die Drehbewegung, das tut die Engine aber scheinbar nicht so gerne. Das werde ich noch verändern. Außerdem hat die Tür kein Schlossprinzip, das heißt sie geht immer gleich schwer auf, nicht einmal mit hohem Wiederstand und dann mit geringerem. Das werde ich auch noch verbessern.

Noch ein Hinweis zum Einbau: Die Tür muss als eine Levelgruppe mit folgendem Aufbau platziert werden:

Gruppe1
---Ein Dummyobjekt mit Invisibleflag und Newtonwoodentity als Funktiojn ohne Parameter
---Gruppe2 (in Gruppe1
---Eine Newtonhingeobjekt (aus dem Newtonordner oder einem Beispielordner)mit der Funktion: Newtonhingeconst und skill1 auf 0.3 skill2 u 3 auf 90.
---Gruppe3 (in Gruppe2)
---Die Tür mit der Funktion Newtondoor

Außerdem solltest du die doors.wdl includen (aus den alten Templates) wenn du die nicht hast:

// Template file v4.23a (02/09/01) @020901a
////////////////////////////////////////////////////////////////////////
// File: doors.wdl
// WDL prefabs for doors, platforms, gates, switchs, etc
////////////////////////////////////////////////////////////////////////
// 6/20/00 Doug Poston
// Added doorswitches
// Version 4.20
////////////////////////////////////////////////////////////////////////
// ACTIONS:
//
// FUNCTIONS:
//
// Mod Date: 7/5/00 DCP
// Changed to 4.19 format
//
// Mod Date: 8/30/00 DCP
// Changed __GATE from FLAG7 to FLAG5 (to avoid __LID conflict)
// Changed gate ACTION to behave more like a door
// Mod Date: 9/1/00 DCP
// Modified gate ACTION
// Enabled __SILENT flag (play sound only if OFF)
// Mod Date: 10/31/00 DCP
// Changed to 4.30 format
//
////////////////////////////////////////////////////////////////////////

IFNDEF DOORS_DEF;
SOUND gate_snd <gate.wav>; // elevators
SOUND open_snd <door_op.wav>;
SOUND close_snd <door_cl.wav>;
SOUND key_fetch <beamer.wav>;
SOUND trigger_snd <click.wav>;
ENDIF;

IFNDEF DOORS_DEF2;
SOUND teleport_snd <beamer.wav>;
ENDIF;
////////////////////////////////////////////////////////////////////////
// Strings for needing and picking up keys; can be redefined
STRING need_key1_str "Red key required";
STRING need_key2_str "Green key required";
STRING need_key3_str "Blue key required";
STRING need_key4_str "Silver key required";
STRING need_key5_str "Golden key required";
STRING need_key6_str "Black key required";
STRING need_key7_str "White key required";
STRING need_key8_str "Yet another key required";
STRING got_key1_str "Found a red key!";
STRING got_key2_str "Found a green key!";
STRING got_key3_str "Found a blue key!";
STRING got_key4_str "Found a silver key!";
STRING got_key5_str "Found a golden key!";
STRING got_key6_str "Found a black key!";
STRING got_key7_str "Found a white key!";
STRING got_key8_str "Found a yet another key!";

// These skills may not only be set by keys, but can also be set by
// dedicated actions, dialogues in adventures, and so on.
// If a key skill is set to 1, the door or elevator will work.
var key1 = 0;
var key2 = 0;
var key3 = 0;
var key4 = 0;
var key5 = 0;
var key6 = 0;
var key7 = 0;
var key8 = 0;


var temp_dist = 0; // temp store a distance (used in range trigger)
var temp_dist2 = 0; // temp store a distance (used in range trigger)
entity* temp_elevator; // store the current elevator (dcp - changed from temp_ent because of name conflict in movement.wdl)

///////////////////////////////////////////////////////////////////////
DEFINE _ENDPOS_X,SKILL1; // target position for elevator
DEFINE _ENDPOS_Y,SKILL2;
DEFINE _ENDPOS_Z,SKILL3; // target height for elevator
DEFINE _ENDPOS,SKILL3; // opening angle for doors
DEFINE _KEY,SKILL4; // key number, 0 = no key needed
DEFINE _KEYTYPE,SKILL4; // legacy
DEFINE _PAUSE,SKILL6; // wait time at end positions
DEFINE _TRIGGER_RANGE,SKILL7; // door/elevator may be triggered
DEFINE _SWITCH,SKILL8; // remote switch number for operating

DEFINE _CURRENTPOS,SKILL9;
DEFINE _TRIGGERFRAME,SKILL10; // Frame number of the last received trigger
DEFINE _STARTPOS_X,SKILL27; // start position for elevator
DEFINE _STARTPOS_Y,SKILL28;
DEFINE _STARTPOS_Z,SKILL29; // start height for elevator

DEFINE __ROTATE,FLAG1; // key item rotates
DEFINE __SILENT,FLAG2; // no message
DEFINE __GATE,FLAG5; // elevator is a gate (DCP: changed from 7 to 5)
DEFINE __REMOTE,FLAG6; // platform can be remote started from the target position
DEFINE __LID,FLAG7; // door is a lid (opens vertically)

DEFINE __MOVING,FLAG8; // set during movement


//////////////////////////////////////////////////////////////////////////////////////////////////
var doorswitch_states = 0; // the states of each door switch (0-off, 1-on)


// Desc: the door switch event
// if the _doorevent_check returns a valid value, set/reset (XOR)
// the doorswitch_states value using the switch's _SWITCH value
//
// Date: 6/20/00
function doorswitch_event()
{
_doorevent_check();
if(RESULT) { doorswitch_states ^= MY._SWITCH; } // set/reset door switch
}

// Desc: action attached to door switch
// can be used to active both doors and/or elevators
//
// Date: 6/20/00
ACTION doorswitch
{
MY.EVENT = doorswitch_event;
_doorevent_init();

if(MY._SWITCH == 0) { MY._SWITCH = 1; } // default to switch 1

}

// Desc: Reset all the door switches
//
// Date: 6/20/00
function _doorswitch_reset_all()
{
doorswitch_states = 0;
}


// Desc: check the switch once every 24 ticks
// if it's state has changed, activate
//
// Date: 6/20/00
function _elevator_use_switch()
{
while(1)
{
if((MY._SWITCH & doorswitch_states) != 0)
{
// state has changed (0->1), activate
elevator_move();

while((MY._SWITCH & doorswitch_states) != 0)
{
waitt(24);
}
// state has changed (1->0), activate
elevator_move();

}
waitt(24);

}
}

// Desc: check the switch once every 16 ticks
// if it's state has changed, activate
//
// Date: 6/20/00
function _door_use_switch()
{
while(1)
{
// assert(MY._SWITCH & doorswitch_states == 0)

if((MY._SWITCH & doorswitch_states) != 0)
{
// state has changed (0->1), activate
_door_swing();

while((MY._SWITCH & doorswitch_states) != 0)
{
// assert(MY._SWITCH & doorswitch_states != 0)
waitt(16);
}
// state has changed (1->0), activate
_door_swing();

}
waitt(16);
}
}


////////////////////////////////////////////////////////////////////////


// Desc: Rotates an entity as long as it is visible and stays at the same place
ACTION ent_rotate
{
// by default, rotate horizontally
if((MY.SKILL1 == 0) && (MY.SKILL2 == 0) && (MY.SKILL3 == 0))
{
MY.SKILL1 = 3;
}

//store the current position
MY._STARTPOS_X = MY.X;
MY._STARTPOS_Y = MY.Y;
MY._STARTPOS_Z = MY.Z;

// rotate it as long as it isn't picked up
while(MY.INVISIBLE == OFF
&& MY._STARTPOS_X == MY.X
&& MY._STARTPOS_Y == MY.Y
&& MY._STARTPOS_Z == MY.Z)
{
MY.PAN += MY.SKILL1*TIME;
MY.TILT += MY.SKILL2*TIME;
MY.ROLL += MY.SKILL3*TIME;
wait(1);
}
}

////////////////////////////////////////////////////////////////////////
// Key actions.

// Desc: rotate an item horizontally
ACTION item_rotate
{
//store the current position
MY._STARTPOS_X = MY.X;
MY._STARTPOS_Y = MY.Y;
MY._STARTPOS_Z = MY.Z;

// rotate it als long as it isn't picked up
while(MY.INVISIBLE == OFF
&& MY._STARTPOS_X == MY.X
&& MY._STARTPOS_Y == MY.Y
&& MY._STARTPOS_Z == MY.Z)
{
MY.PAN += 3*TIME;
wait(1);
}
}

// Desc: action to enable an entity to be picked up
ACTION item_pickup
{
MY.PUSH = -1;
MY.ENABLE_SCAN = ON; // pick up pressing SPACE..
MY.ENABLE_CLICK = ON; // clicking with the mouse...
MY.ENABLE_PUSH = ON; // or touching the item

if(MY.__ROTATE == ON) { item_rotate(); }
}

// Desc: called when a "key" receives an EVENT
// set corisponding key value to 1, display string, play sound, and remove key
//
// Mod Date: 7/5/00 DCP
// Changed to function
function _key_pickup()
{
if(EVENT_TYPE == EVENT_SCAN && indicator != _HANDLE) { return; }
if((EVENT_TYPE == EVENT_PUSH) && ((YOU != player) || (YOU != player2))) { return; }

if(MY._KEY == 1) { key1 = 1; msg.STRING = got_key1_str; }
if(MY._KEY == 2) { key2 = 1; msg.STRING = got_key2_str; }
if(MY._KEY == 3) { key3 = 1; msg.STRING = got_key3_str; }
if(MY._KEY == 4) { key4 = 1; msg.STRING = got_key4_str; }
if(MY._KEY == 5) { key5 = 1; msg.STRING = got_key5_str; }
if(MY._KEY == 6) { key6 = 1; msg.STRING = got_key6_str; }
if(MY._KEY == 7) { key7 = 1; msg.STRING = got_key7_str; }
if(MY._KEY == 8) { key8 = 1; msg.STRING = got_key8_str; }
if(MY.__SILENT != ON) { show_message(); }
snd_play(key_fetch,50,0);
ent_remove(ME);
}

// Desc: This entity must not look like a key at all...
ACTION key
{
if(MY._KEY == 0) { MY._KEY = 1; }
MY.EVENT = _key_pickup;
item_pickup();
}


// Desc: reset key values to zero
//
// Mod Date: 7/5/00 DCP
// Changed to function
function key_init()
{
key1 = 0;
key2 = 0;
key3 = 0;
key4 = 0;
key5 = 0;
key6 = 0;
key7 = 0;
key8 = 0;
}

////////////////////////////////////////////////////////////////////////

// Desc: handle "teleporter" events
//
// Mod Date: 7/5/00 DCP
// Changed to function
function _tele_event()
{
handle_touch(); // show mouse touch text, if any

// entity walked over it while performing SONAR, or touched it
if( EVENT_TYPE == EVENT_SONAR
|| EVENT_TYPE == EVENT_IMPACT)
{
wait(1); // the entity was already moving, so this must be finished before displacing it

YOUR.X = MY.SKILL1; // displace the entity
YOUR.Y = MY.SKILL2;
YOUR.Z = MY.SKILL3;
YOUR.PAN = MY.SKILL5;
CAMERA.AMBIENT += 30; // a short flash
CAMERA2.AMBIENT += 30; // a short flash
snd_play (teleport_snd,50,0);
waitt(2);

CAMERA.AMBIENT -= 20;
CAMERA2.AMBIENT -= 20;
waitt(2);

CAMERA.AMBIENT -= 10;
CAMERA2.AMBIENT -= 10;

}
}

// Desc: Teleporter action. Transports an entity to the SKILL1,2,3 position
// it touched. SKILL5 gives an angle.
ACTION teleporter
{
MY.EVENT = _tele_event;
MY.ENABLE_IMPACT = ON;

// enable operating on stepping onto (for platform teleporters)
if(MY._TRIGGER_RANGE == 1) { MY.ENABLE_SONAR = ON; }

// enable mouse text
if(MY.STRING1 != NULL) { MY.ENABLE_TOUCH = ON; }
}


////////////////////////////////////////////////////////////////////////

// Desc: handle door events. Opens if a SCAN instruction was performed.
function door_event()
{
_doorevent_check();
if(RESULT) { BRANCH _door_swing; }
}


// Desc: set __LID flag to on, continue as a door
ACTION lid
{
MY.__LID = ON;
BRANCH door;
}

//Desc: a door.
ACTION door
{
IF (MY.EVENT == NULL) { MY.EVENT = door_event; }
_doorevent_init();
if(MY._FORCE == 0) { MY._FORCE = 5; }
if(MY._ENDPOS == 0) { MY._ENDPOS = 90; }
}

/*
ACTION trigger_beep {
MY.EVENT = signal;
MY.ENABLE_TRIGGER = 1;
MY.TRIGGER_RANGE = 10;
MY.PASSABLE = 1;
}
*/

// closes the door again if no trigger was received within the last 4 framesa second
function _doorevent_close()
{
wait(4);

// close door of no trigger received again, and yet open and not moving
if((TOTAL_FRAMES > MY._TRIGGERFRAME + 3)
&& (MY._CURRENTPOS == MY._ENDPOS)
&& (MY.__MOVING == OFF))
{
BRANCH _door_swing;
}
}


function _move_to_target()
{
wait(1);
}

// Desc: active the door
//
// Mod 8/30/00 DCP
// Added code to check and handle gates
// Mod 9/1/00 DCP
// Enabled __SILENT flag (sound only if OFF)
function _door_swing()
{
MY.__MOVING = ON;

if(MY.__GATE == ON)
{
if(MY.__SILENT == OFF) { ent_playsound (ME,open_snd,66); }

// open gate
while(MY.__MOVING == ON)
{

wait(1); // DcP - moved wait to the start of this block, before the __MOVING flag is set to OFF

// calculate the 3D direction to move to
MY._SPEED_X = MY._TARGET_X - MY.X;
MY._SPEED_Y = MY._TARGET_Y - MY.Y;
MY._SPEED_Z = MY._TARGET_Z - MY.Z;

// check the distance to the target position, using pythagoras
temp = MY._SPEED_X*MY._SPEED_X + MY._SPEED_Y*MY._SPEED_Y + MY._SPEED_Z*MY._SPEED_Z;

// we have now the square of the distance to the target,
// and must compare it with the square of the distance to move
if(temp > MY._FORCE * TIME * MY._FORCE * TIME)
{
// if far, move with normal speed
temp = MY._FORCE * TIME;
vec_normalize(MY._SPEED,temp); // adjust the speed vector's length
}
else
{ // if near, stop after moving the rest distance
MY.__MOVING = OFF;
}

move(ME,NULLSKILL,MY._SPEED); // move in that direction

// check to see if the door is stuck
if(RESULT == 0)
{
// stop trying to move the gate
break;
}

MY._SPEED_X = MY_SPEED.X; // set the speed to the real distance covered
MY._SPEED_Y = MY_SPEED.Y; // for moving the player with the platform
MY._SPEED_Z = MY_SPEED.Z;
}

MY._SPEED_X = 0;
MY._SPEED_Y = 0;
MY._SPEED_Z = 0;

MY.__MOVING = OFF;

// at end position, reverse the direction
if( (MY._TARGET_X == MY._ENDPOS_X)
&&(MY._TARGET_Y == MY._ENDPOS_Y)
&&(MY._TARGET_Z == MY._ENDPOS_Z))
{
MY._TARGET_X = MY._STARTPOS_X;
MY._TARGET_Y = MY._STARTPOS_Y;
MY._TARGET_Z = MY._STARTPOS_Z;

// check to see if it closes automagically
if(MY._PAUSE > 0)
{
waitt(MY._PAUSE);
BRANCH _door_swing; // do it again
}

}
else
{
MY._TARGET_X = MY._ENDPOS_X;
MY._TARGET_Y = MY._ENDPOS_Y;
MY._TARGET_Z = MY._ENDPOS_Z;
}

return; // END GATE movement
}

// check whether to open or to close
if(MY._CURRENTPOS < MY._ENDPOS)
{
if(MY.__SILENT == OFF) { ent_PLAYSOUND (ME,open_snd,66); }
while(MY._CURRENTPOS < MY._ENDPOS)
{
if(MY.__LID == ON)
{
MY.ROLL += MY._FORCE*TIME;
}
else
{
MY.PAN -= MY._FORCE*TIME;
}
MY._CURRENTPOS += ABS(MY._FORCE)*TIME;
wait(1);
}
if(MY.__LID == ON)
{
MY.ROLL -= MY._CURRENTPOS-MY._ENDPOS;
}
else
{
MY.PAN += MY._CURRENTPOS-MY._ENDPOS;
}
MY._CURRENTPOS = MY._ENDPOS;
if(MY.__LID == ON)
{
MY.PASSABLE = ON; // otherwise the player won't fit through
}
}
else // MY._CURRENTPOS >= MY._ENDPOS
{
if(MY.__SILENT == OFF) { ent_playsound(ME,close_snd,66); }
while(MY._CURRENTPOS > 0)
{
if(MY.__LID == ON)
{
MY.ROLL -= MY._FORCE*TIME;
}
else
{
MY.PAN += MY._FORCE*TIME;
}
MY._CURRENTPOS -= abs(MY._FORCE)*TIME;
wait(1);
}
if(MY.__LID == ON)
{
MY.ROLL -= MY._CURRENTPOS;
}
else
{
MY.PAN += MY._CURRENTPOS;
}
MY._CURRENTPOS = 0;
if(MY.__LID == ON)
{
MY.PASSABLE = 0;
}
}
MY.__MOVING = OFF;
}

////////////////////////////////////////////////////////////////////////
function _elevator_target;
// Desc: handle elevator events
function elevator_event()
{
_doorevent_check();
if(RESULT) { branch elevator_move; }
}

// Desc: set up the elevator
//
//
// DCP - added ranged trigger (3/22/00)
//
// DCP - changed recall trigger (3/27/00)
//
// DCP - added _elevatorevent_init to resolve conflict in _doorevent_init (4/4/00)
ACTION elevator
{
if(MY._FORCE == 0) { MY._FORCE = 5; }
if(MY._ENDPOS_X == 0) { MY._ENDPOS_X = MY.X; }
if(MY._ENDPOS_Y == 0) { MY._ENDPOS_Y = MY.Y; }
if(MY._ENDPOS_Z == 0) { MY._ENDPOS_Z = MY.Z; }


MY._TYPE = _TYPE_ELEVATOR;
MY.EVENT = elevator_event;
_elevatorevent_init(); // DCP - changed from _doorevent_init


// initialize the movement parameters of the elevator
MY._STARTPOS_X = MY.X;
MY._STARTPOS_Y = MY.Y;
MY._STARTPOS_Z = MY.Z;

MY._TARGET_X = MY._ENDPOS_X;
MY._TARGET_Y = MY._ENDPOS_Y;
MY._TARGET_Z = MY._ENDPOS_Z;


if((MY._TRIGGER_RANGE > 1) || (MY.__REMOTE == ON))
{
// create a remote trigger to recall elevator
ent_create("arrow.pcx",MY._TARGET_X,_elevator_target);
}


MY.__MOVING = OFF;


// if it's a paternoster, start its movement action
if((MY.__GATE == OFF) && (MY._PAUSE > 0))
{
waitt(MY._PAUSE);
elevator_move();
}

}

ACTION elevator_2
{
if(MY._FORCE == 0) { MY._FORCE = 5; }
if(MY._ENDPOS_X == 0) { MY._ENDPOS_X = MY.X; }
if(MY._ENDPOS_Y == 0) { MY._ENDPOS_Y = MY.Y; }
if(MY._ENDPOS_Z == 0) { MY._ENDPOS_Z = MY.Z; }


MY._TYPE = _TYPE_ELEVATOR;


// initialize the movement parameters of the elevator
MY._STARTPOS_X = MY.X;
MY._STARTPOS_Y = MY.Y;
MY._STARTPOS_Z = MY.Z;

MY._TARGET_X = MY._ENDPOS_X;
MY._TARGET_Y = MY._ENDPOS_Y;
MY._TARGET_Z = MY._ENDPOS_Z;




MY.__MOVING = OFF;


// if it's a paternoster, start its movement action
if((MY.__GATE == OFF) && (MY._PAUSE > 0))
{
waitt(MY._PAUSE);
elevator_move();
}
elevator_move();


}


/* old gate action
// will open and close a gate vertically
ACTION gate
{
MY.__GATE = ON; // define a gate - very similar to an elevator
MY._ENDPOS_Z = MY.Z + 0.9*(MY.MAX_Z - MY.MIN_Z);
elevator();
}
*/

// Desc: will open and close a gate
//
//_ENDPOS_X (SKILL1): percent of entity's width the door will travel in the X direction (default 0)
//_ENDPOS_Y (SKILL2): percent of entity's depth the door will travel in the Y direction (default 0)
//_ENDPOS_Z (SKILL3): percent of entity's width the door will travel in the Z direction (default 0)
//
//_KEYTYPE (SKILL4): key number (1..4) needed to open gate (default 0).
//
//_FORCE (SKILL5): gives the gate speed in quants per tick (default 5).
//
//_PAUSE (SKILL6): amount of time gate will remain open (default 0). If value
//is 0, gate will stay open until it is activated again.
//
//_TRIGGER_RANGE (SKILL7): range, in quants, within which an entity must be to
//automatically open the gate (default 0). If value is 0, the door will not
//open automatically.
//
//_SWITCH (SKILL8): remote switch number for operating (default 0). If a
//switch value is changed all matching gates with the same number will be
//activated.
//
//__SILENT (FLAG2): if ON gate makes no noise (default OFF).
//
//
// Mod Date: 8/30/00 DCP
// Changed to behave more like doors
// Mod Date: 9/1/00 DCP
// Modified gate ACTION (clean and debug)
// Enabled __SILENT flag (play sound only if OFF)
ACTION gate
{
MY.__GATE = ON; // define this entity as a gate

// give the gate a default speed (if it doesn't already have one)
if(MY._FORCE == 0) { MY._FORCE = 5; }

// Set _ENDPOS_[X,Y,Z] values
if((MY._ENDPOS_X == 0) && (MY._ENDPOS_Y == 0) && (MY._ENDPOS_Z == 0) )
{
// set default values
MY._ENDPOS_X = MY.X;
MY._ENDPOS_Y = MY.Y;
MY._ENDPOS_Z = MY.Z + (0.9*(MY.MAX_Z - MY.MIN_Z));
}
else
{
// check individulal endpos
if(MY._ENDPOS_X == 0) { MY._ENDPOS_X = MY.X; }
else { MY._ENDPOS_X = MY.X + ((MY._ENDPOS_X/100)*(MY.MAX_X - MY.MIN_X)); }

if(MY._ENDPOS_Y == 0) { MY._ENDPOS_Y = MY.Y; }
else { MY._ENDPOS_Y = MY.Y + ((MY._ENDPOS_Y/100)*(MY.MAX_Y - MY.MIN_Y)); }

if(MY._ENDPOS_Z == 0) { MY._ENDPOS_Z = MY.Z; }
else { MY._ENDPOS_Z = MY.Z + ((MY._ENDPOS_Z/100)*(MY.MAX_Z - MY.MIN_Z)); }
}


MY.EVENT = door_event;
_doorevent_init();

// initialize the movement parameters of the gate
MY._STARTPOS_X = MY.X;
MY._STARTPOS_Y = MY.Y;
MY._STARTPOS_Z = MY.Z;

MY._TARGET_X = MY._ENDPOS_X;
MY._TARGET_Y = MY._ENDPOS_Y;
MY._TARGET_Z = MY._ENDPOS_Z;


MY.__MOVING = OFF;
}




// Desc: handle ranged trigger events
function _elevator_target_event()
{
// entity performed SCAN nearby (by pressing SPACE)
if((EVENT_TYPE == EVENT_SCAN) && (indicator == _HANDLE))
{
MY = MY.ENTITY1; // pretend that I'm the elevator
branch elevator_event; // and received a SCAN myself
}


// if we receive a trigger event...
// DcP - NOTE: EVENT_CLICK ADDED TO TEST RECALL CODE (4/4/00)
if((EVENT_TYPE == EVENT_TRIGGER) || (EVENT_TYPE == EVENT_CLICK))
{
// check to see if the player is closer to the elevator or this trigger
// calculate the distance squared to the trigger (You = player, me = trigger)
temp.X = YOUR.X - MY.X;
temp.Y = YOUR.Y - MY.Y;
temp.Z = YOUR.Z - MY.Z;

vec_to_angle(temp_dist, temp);
// DcP- replaced with vec_to_angle()
//temp_dist.Z = (temp.X * temp.X) + (temp.Y * temp.Y) + (temp.Z * temp.Z);

ME = MY.ENTITY1; // become the elevator

// calculate the distance squared to the elevator (You = player, me = elevator)
temp.X = YOUR.X - MY.X;
temp.Y = YOUR.Y - MY.Y;
temp.Z = YOUR.Z - MY.Z;
vec_to_angle(temp_dist2, temp);

// if(temp_dist < ((temp.X * temp.X) + (temp.Y * temp.Y) + (temp.Z * temp.Z)))

// DcP - NOTE: These lines commented out to test trigger without compairing it to the elevator pos.
if(temp_dist.Z < temp_dist2.Z)
{
branch elevator_event; // activate the elevator
}
}
}


// Desc: invisible target entity action to remote call the elevator
//
// this entity is linked to the calling entity through its ENTITY1 skill
// this entity uses the calling entity's _RECALL_TRIGGER_RANGE value
function _elevator_target()
{
MY.INVISIBLE = ON;
MY.PASSABLE = ON;
MY.ENTITY1 = YOU; // store the adept_elevator synonym

// ranged trigger is set here
if(YOUR._TRIGGER_RANGE > 1)
{
MY.TRIGGER_RANGE = YOUR._TRIGGER_RANGE;
MY.ENABLE_TRIGGER = ON;
// DcP - NOTE: EVENT_CLICK ADDED TO TEST RECALL CODE (4/4/00)
MY.ENABLE_CLICK = ON;
}

// here the REMOTE must also be considered
if(YOUR.__REMOTE == ON)
{
MY.ENABLE_SCAN = ON;
}

MY.EVENT = _elevator_target_event;
YOUR.ENTITY1 = ME; // link the calling entity (elevator) to this target
}



// Action - elevator_move
//
// DCP- added code to move 'triggers' to the opposite ends from the elevator (3//22/00)
//
// Mod 9/1/00 DCP
// Enabled __SILENT flag (play sound only if OFF)
function elevator_move()
{
again:
// start moving the elevator
MY.__MOVING = ON;
if(MY.__SILENT == OFF) { ent_playsound(ME,gate_snd,66); }
//if(MY.__SILENT == ON) { play_entsound(ME,gate_snd,66); }



// DCP - if we're using a remote trigger
if((MY._TRIGGER_RANGE > 1) || (MY.__REMOTE == ON))
{
temp_elevator = MY.ENTITY1; // the ranged target
temp_elevator.ENABLE_SCAN = OFF; // disable scan on this trigger
temp_elevator.ENABLE_TRIGGER = OFF; // disable range on this trigger
}


while(MY.__MOVING == ON)
{

wait(1); // DcP - moved wait to the start of this block, before the __MOVING flag is set to OFF

// calculate the 3D direction to move to
MY._SPEED_X = MY._TARGET_X - MY.X;
MY._SPEED_Y = MY._TARGET_Y - MY.Y;
MY._SPEED_Z = MY._TARGET_Z - MY.Z;

// check the distance to the target position, using pythagoras
temp = MY._SPEED_X*MY._SPEED_X + MY._SPEED_Y*MY._SPEED_Y + MY._SPEED_Z*MY._SPEED_Z;

// we have now the square of the distance to the target,
// and must compare it with the square of the distance to move
if(temp > MY._FORCE * TIME * MY._FORCE * TIME)
{
// if far, move with normal speed
temp = MY._FORCE * TIME;
vec_normalize(MY._SPEED,temp); // adjust the speed vector's length
}
else
{ // if near, stop after moving the rest distance
MY.__MOVING = OFF;
}

move(ME,NULLSKILL,MY._SPEED); // move into that direction

MY._SPEED_X = MY_SPEED.X; // set the speed to the real distance covered
MY._SPEED_Y = MY_SPEED.Y; // for moving the player with the platform
MY._SPEED_Z = MY_SPEED.Z;
}

MY._SPEED_X = 0;
MY._SPEED_Y = 0;
MY._SPEED_Z = 0;
IF (herauskommen == 10) { herauskommen = 1; }
IF (herauskommen == 11) { herauskommen = 0; }

// at end position, reverse the direction
if(MY._TARGET_X == MY._ENDPOS_X
&& MY._TARGET_Y == MY._ENDPOS_Y
&& MY._TARGET_Z == MY._ENDPOS_Z )
{
MY._TARGET_X = MY._STARTPOS_X;
MY._TARGET_Y = MY._STARTPOS_Y;
MY._TARGET_Z = MY._STARTPOS_Z;
}
else
{
MY._TARGET_X = MY._ENDPOS_X;
MY._TARGET_Y = MY._ENDPOS_Y;
MY._TARGET_Z = MY._ENDPOS_Z;
}


// DCP - if a ranged trigger is used,
if((MY._TRIGGER_RANGE > 1) || (MY.__REMOTE == ON))
{
temp_elevator = MY.ENTITY1; // the ranged target

temp_elevator.X = MY._TARGET_X; // move the ranged target to the elevator's target point
temp_elevator.Y = MY._TARGET_Y;
temp_elevator.Z = MY._TARGET_Z;

if(MY.__REMOTE == ON)
{
temp_elevator.ENABLE_SCAN = ON; // re-activate the scan event
}

// ranged trigger is set here
if(MY._TRIGGER_RANGE > 1)
{
temp_elevator.ENABLE_TRIGGER = ON; // re-activate the trigger event
}
}


// DcP - reset the elevator's _TRIGGERFRAME to the current TOTAL_FRAMES (4/7/00)
//
// _TRIGGERFRAME is used in _doorevent_check to allow the user time
// to step off the lift before accepting new SONAR events
MY._TRIGGERFRAME = TOTAL_FRAMES;


// if a gate or paternoster, close it or restart
if(((MY.__GATE == ON) && (MY._PAUSE > 0) && (MY.Z > MY._STARTPOS_Z))
// close gate again
|| ((MY.__GATE == OFF) && (MY._PAUSE > 0)))
{
// start paternoster in reverse direction
waitt(MY._PAUSE);
goto(again);
}
}






////////////////////////////////////////////////////////////////////////
// helper actions for the events

// Desc: init the elevator
//
// DCP - Added this action because _doorevent_init caused conflicts with
// remote trigger code (4/4/00)
//
// Mod: 6/20/00 Doug Poston
// added switch activation
function _elevatorevent_init()
{
MY.ENABLE_SCAN = ON;
MY.ENABLE_CLICK = ON;

// enable operating on stepping onto (for elevators)
if(MY._TRIGGER_RANGE > 0)
{
MY.ENABLE_SONAR = ON;
}

// enable mouse text
if(MY.STRING1 != NULL)
{
MY.ENABLE_TOUCH = ON;
}

MY._TRIGGERFRAME = 0;
MY.PUSH = 10; // move through the level blocks

// if it is switch activated...
if(MY._SWITCH != 0)
{
_elevator_use_switch();
}

}


// Mod: 6/20/00 Doug Poston
// added switch activation
//
function _doorevent_init()
{
MY.ENABLE_SCAN = ON;
MY.ENABLE_CLICK = ON;

// enable triggering
if(MY._TRIGGER_RANGE >= 2)
{
MY.ENABLE_TRIGGER = ON;
MY.TRIGGER_RANGE = MY._TRIGGER_RANGE;
}

// enable operating on stepping onto (for elevators)
if(MY._TRIGGER_RANGE == 1)
{
MY.ENABLE_SONAR = ON;
}

// enable mouse text
if(MY.STRING1 != NULL)
{
MY.ENABLE_TOUCH = ON;
}

MY._TRIGGERFRAME = 0;
MY.PUSH = 10; // move through the level blocks

// if it is switch activated...
if(MY._SWITCH != 0)
{
_door_use_switch();
}
}

// Desc: action checks whether an event can operate the door or platform
//
// Mod 9/1/00 DCP
// Enabled __SILENT flag (play sound only if OFF)
function _doorevent_check()
{
handle_touch(); // show mouse touch text, if any

if(MY.__MOVING == ON) { goto(ignore); } // don't handle a moving door


// entity performed SCAN nearby (by pressing SPACE)
if((EVENT_TYPE == EVENT_SCAN) && (indicator == _HANDLE))
|| (EVENT_TYPE == EVENT_CLICK)
{
if(MY.__SILENT == OFF) { snd_play(trigger_snd,50,0); }
goto(try_key);
}

// player or entity with TRIGGER_RANGE walked nearby.
// trigger only opens the door, closing is automatically
if(EVENT_TYPE == EVENT_TRIGGER)
{
// not already open, and no trigger since the last 2 frames ?
if((MY._CURRENTPOS != MY._ENDPOS)
&& (TOTAL_FRAMES > (MY._TRIGGERFRAME + 2)))
{
MY._TRIGGERFRAME = TOTAL_FRAMES;
goto(try_key);
}
MY._TRIGGERFRAME = TOTAL_FRAMES;
// each trigger starts an action which closes the door again
// if the triggering entity is outside range after some time
_doorevent_close();
}

// entity walked over it while performing SONAR
// sonar starts the platform
if(EVENT_TYPE == EVENT_SONAR)
{
// no sonar or trigger since the last 5 frames (this is to make sure the
// entity has walked off the platform before re-triggering)
if(TOTAL_FRAMES > (MY._TRIGGERFRAME + 5))
{
MY._TRIGGERFRAME = TOTAL_FRAMES;
goto(try_key);
}

MY._TRIGGERFRAME = TOTAL_FRAMES;
}

// no operating condition happened, so tell the door not to move
ignore:
RESULT = 0;
return(0);

try_key:
if((MY._KEY == 1)&&(key1 == 0)) { msg.STRING = need_key1_str; GOTO message; }
if((MY._KEY == 2)&&(key2 == 0)) { msg.STRING = need_key2_str; GOTO message; }
if((MY._KEY == 3)&&(key3 == 0)) { msg.STRING = need_key3_str; GOTO message; }
if((MY._KEY == 4)&&(key4 == 0)) { msg.STRING = need_key4_str; GOTO message; }
if((MY._KEY == 5)&&(key5 == 0)) { msg.STRING = need_key5_str; GOTO message; }
if((MY._KEY == 6)&&(key6 == 0)) { msg.STRING = need_key6_str; GOTO message; }
if((MY._KEY == 7)&&(key7 == 0)) { msg.STRING = need_key7_str; GOTO message; }
if((MY._KEY == 8)&&(key8 == 0)) { msg.STRING = need_key8_str; GOTO message; }

operate:
RESULT = 1;
return(1);

message: // and don't operate
if(MY.__SILENT != ON) { show_message(); }
RESULT = 0;
return(0);
}


///////////////////////////////////////////////////////////////////////
Posted By: Anonymous

Re: [Newton] Physik Tür - 04/07/07 07:55

ok vielen dank
Posted By: RedPhoenix

Re: [Newton] Physik Tür - 04/13/07 19:50

So dieser Code sollte theoretisch eigentlich funktionieren... aber!!!
1: Gibt bei mir je nach einstellung der Objekte in Wed manchmal noch sehr seltsame Resultate
2: Ist noch nicht so ausführlich getestet. Bitte versuchg dich mal dran, und berichte alle Fehler hier.

var newtonImpulseRecord[8];
DEFINE ent_id,SKILL47;
DEFINE EXPLOSION,11;
Function door_physic(Body)
{
// Balance...
temp.x = 0;
temp.y = 0;
temp.z = MY.SKILL46;
vec_scale(temp, 4000);
//vec_rotate(temp, my.pan);
IF (MY.SKILL46 != 0) {
NewtonBodyAddTorque (Body, temp.X,temp.Y,temp.Z);
}
//NewtonbodySetvelocity(body,nullvector);
}

function _door_swing_newton()
{ //Das ist eine Template dooraktion,
//die einfach die Bewegungsbefehle an die Newtonfunktion übergibt
var body;
var saved_pan;
var mom_pan;
MY.__MOVING = ON;
MY.SKILL46 = 0;
saved_pan = MY.PAN;
body = NewtonGetBody (MY);
NewtonSetBodyActiveState (Body, 1);

// check whether to open or to close
if(MY._CURRENTPOS < MY._ENDPOS)
{
if(MY.__SILENT == OFF) { ent_PLAYSOUND (ME,open_snd,66); }
while(MY._CURRENTPOS < MY._ENDPOS)
{
mom_pan = MY.PAN;
MY.SKILL46 = -MY._FORCE;
MY._CURRENTPOS = abs(saved_pan-my.pan);
wait(1);
IF (abs(mom_pan-my.pan) < 0.005 && MY._CURRENTPOS < MY._ENDPOS) { goto (do_return); }
}
//Dieser Codeteil funktioniert auf meinem ystem noch nicht richtig!
//MY.PAN += MY._CURRENTPOS-MY._ENDPOS; // Das ergibt einen kleinen Sprung
//body = NewtonGetBody (MY);//Damit die Tür auch exakt richtig steht
//NewtonBodySetTransform (body); // Das verändern der Winkel muss für Newton gültig gemacht werden
MY._CURRENTPOS = MY._ENDPOS;
saved_pan = MY.PAN;
}
else // MY._CURRENTPOS >= MY._ENDPOS
{
if(MY.__SILENT == OFF) { ent_playsound(ME,close_snd,66); }
while(MY._CURRENTPOS > 0)
{
mom_pan = MY.PAN;
MY.SKILL46 = MY._FORCE;
MY._CURRENTPOS = 90-abs(saved_pan-my.pan);
wait(1);
IF (abs(mom_pan-my.pan) < 0.005 && MY._CURRENTPOS > 0) { goto (do_return); }
}
// MY.PAN += MY._CURRENTPOS; //Hier dasselbe
//body = NewtonGetBody (MY);
//NewtonBodySetTransform (body); //Damit die Tür auch exakt richtig steht
MY._CURRENTPOS = 0;
saved_pan = MY.PAN;
body = NewtonGetBody (MY);
NewtonSetBodyActiveState (Body, 0);

}
do_return :
MY.__MOVING = OFF;
My.SKILL46 = 0;
}


function newtondoor_event()
{
_doorevent_check();
if(RESULT) { BRANCH _door_swing_newton; }
}


ACTION newtondoor
{
MY.MASS = 10000; //es muss ein statisches Newtonobjekt sein
MY.SKILL46 = 0;
//c_setminmax(MY);
newtoncreatedoorentity();
IF (MY.EVENT == NULL) { MY.EVENT = newtondoor_event; }
_doorevent_init();
if(MY._FORCE == 0) { MY._FORCE = 20; }
if(MY._ENDPOS == 0) { MY._ENDPOS = 90; }
}

function NewtoncreatedoorEntity ()
{
var collisionType;
var body;
dll_handle = newtonHandle;

// if entity is not destructible. Set health very heigth

// check for collision type
collisionType = 0;

body = NewtonAddMapEntity (my, collisionType);
NewtonSetBodyMass (body, MY.MASS);
NewtonSetBodyLinearDamp (body, 0.1);
NewtonSetBodyAngularDamp (body, 0.1, 0.1, 0.1);
NewtonSetBodyMaterial (body, wood_material);
NewtonSetBodyAutoActiveState (Body, 0);
NewtonSetBodyActiveState (Body, 0);
NewtonSetBodyForceAndTorque (Body, door_physic);

}


function _doorevent_init()
{
MY.ENABLE_SCAN = ON;
MY.ENABLE_CLICK = ON;

// enable mouse text
if(MY.STRING1 != NULL)
{
MY.ENABLE_TOUCH = ON;
}

MY._TRIGGERFRAME = 0;
//MY.PUSH = 10; // move through the level blocks
}

// Desc: action checks whether an event can operate the door or platform
//
// Mod 9/1/00 DCP
// Enabled __SILENT flag (play sound only if OFF)
function _doorevent_check()
{
handle_touch(); // show mouse touch text, if any

if(MY.__MOVING == ON) { goto(ignore); } // don't handle a moving door


// entity performed SCAN nearby (by pressing SPACE)
if((EVENT_TYPE == EVENT_SCAN) && (indicator == _HANDLE))
|| (EVENT_TYPE == EVENT_CLICK)
{
if(MY.__SILENT == OFF) { snd_play(trigger_snd,50,0); }
goto(try_key);
}
IF (EVENT_TYPE == EVENT_SCAN && YOU != NULL) {
IF (YOUR.ENT_ID == EXPLOSION) {
//Eine Explosion gegen die Tür?
BRANCH door_explo;
}
}

// no operating condition happened, so tell the door not to move
ignore:
RESULT = 0;
return(0);

try_key:
if((MY._KEY == 1)&&(key1 == 0)) { msg.STRING = need_key1_str; GOTO message; }
if((MY._KEY == 2)&&(key2 == 0)) { msg.STRING = need_key2_str; GOTO message; }
if((MY._KEY == 3)&&(key3 == 0)) { msg.STRING = need_key3_str; GOTO message; }
if((MY._KEY == 4)&&(key4 == 0)) { msg.STRING = need_key4_str; GOTO message; }
if((MY._KEY == 5)&&(key5 == 0)) { msg.STRING = need_key5_str; GOTO message; }
if((MY._KEY == 6)&&(key6 == 0)) { msg.STRING = need_key6_str; GOTO message; }
if((MY._KEY == 7)&&(key7 == 0)) { msg.STRING = need_key7_str; GOTO message; }
if((MY._KEY == 8)&&(key8 == 0)) { msg.STRING = need_key8_str; GOTO message; }

operate:
RESULT = 1;
return(1);

message: // and don't operate
if(MY.__SILENT != ON) { show_message(); }
RESULT = 0;
return(0);
}

function door_explo
{
var dx;
var dy;
var dz;
var dist2;
var body;
var volume;
dll_handle = newtonHandle;


body = NewtonGetBody (my);
if (body) {
if (EVENT_TYPE == event_SCAN) {
// decrement the health by the weapon damage (skill 4)

newtonImpulseRecord[0] = my.x;
newtonImpulseRecord[1] = my.y;
newtonImpulseRecord[2] = my.z;

// copy origin of bullet (use to determone the direction of the impulse)
newtonImpulseRecord[3] = you.x;
newtonImpulseRecord[4] = you.y;
newtonImpulseRecord[5] = you.z;

// copy the bullet mass
newtonImpulseRecord[6] = you.skill4;

// copy the bullet speed
newtonImpulseRecord[7] = you.skill5;
IF (YOU.SKILL4 > MY.MASS) { //Bedingung damit die Explosion wirkung zeigt
NewtonSetBodyActiveState (Body, 1);
NewtonBodyAddImpulse (body, newtonImpulseRecord);
}
}
wait(2);

}
}

Zum Einbau nicht vergessen:

Gruppe1 Darein, Gruppe2 und ein kleines Model außerhalb der Schwingreichweite
der Tür als Drehpunkt mit Action Newtonwoodentity und allen Parametern auf null

Gruppe2 darin Gruppe3 und Hingeobjekt mit Newtonhingeconstant und skill1 auf 0.1 skill2 auf -90 und 3 auf 90

Gruppe3 mit der Tür

Den Aufbau solltest du mal ein bisschen varieren (Abstand der einzelnen Teile voneinder und auch die Werte, die ich hier genannt habe).

Hoffe bei dir funktionierts einigermaßen

P.S. Sollte jetzt auch ohne Templates gehen, zur Sicherheit aber trotzdem noch mal reinnehmen
Posted By: Anonymous

Re: [Newton] Physik Tür - 04/13/07 19:55

ok danke werde mich mal dransetzten
© 2024 lite-C Forums