mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-12-25 07:14:50 +01:00
181 lines
5.2 KiB
C++
181 lines
5.2 KiB
C++
/* Copyright (c) 2002-2012 Croteam Ltd.
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of version 2 of the GNU General Public License as published by
|
|
the Free Software Foundation
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
|
|
|
702
|
|
%{
|
|
#include "StdH.h"
|
|
%}
|
|
|
|
class CWatchPlayers: CRationalEntity {
|
|
name "Watch Players";
|
|
thumbnail "Thumbnails\\WatchPlayers.tbn";
|
|
features "HasName", "IsTargetable";
|
|
|
|
properties:
|
|
1 CEntityPointer m_penOwner "Owner/Target" 'O' COLOR(C_dBROWN|0xFF), // entity which owns it / target
|
|
10 CEntityPointer m_penFar "Far Target" 'F' COLOR(C_BLACK|0xFF), // entity which owns it / target
|
|
2 FLOAT m_fWaitTime "Wait time" 'W' = 0.1f, // watch time
|
|
3 RANGE m_fDistance "Watch distance" 'D' = 100.0f, // distance when player is seen
|
|
4 BOOL m_bRangeWatcher "Range watcher" 'R' = TRUE, // range watcher
|
|
5 enum EventEType m_eetEventClose "Close Event type" 'T' = EET_TRIGGER, // type of event to send
|
|
6 enum EventEType m_eetEventFar "Far Event type" 'Y' = EET_ENVIRONMENTSTOP, // type of event to send
|
|
7 CEntityPointer m_penCurrentWatch,
|
|
8 BOOL m_bActive "Active" 'A' = TRUE,
|
|
9 CTString m_strName "Name" 'N' = "",
|
|
|
|
components:
|
|
1 model MODEL_WATCHPLAYERS "Models\\Editor\\WatchPlayers.mdl",
|
|
2 texture TEXTURE_WATCHPLAYERS "Models\\Editor\\WatchPlayers.tex"
|
|
|
|
functions:
|
|
/************************************************************
|
|
* USER FUNCTIONS *
|
|
************************************************************/
|
|
// check if any player is close
|
|
BOOL IsAnyPlayerClose(void) {
|
|
// far enough to not move at all
|
|
FLOAT fClosest = 100000.0f;
|
|
FLOAT fDistance;
|
|
|
|
m_penCurrentWatch = NULL;
|
|
// for all players
|
|
for (INDEX iPlayer=0; iPlayer<GetMaxPlayers(); iPlayer++) {
|
|
CEntity *penPlayer = GetPlayerEntity(iPlayer);
|
|
// if player is alive and visible
|
|
if (penPlayer!=NULL && penPlayer->GetFlags()&ENF_ALIVE && !(penPlayer->GetFlags()&ENF_INVISIBLE)) {
|
|
fDistance = 100000.0f;
|
|
if (m_bRangeWatcher) {
|
|
// calculate distance to player from wathcer
|
|
fDistance = (penPlayer->GetPlacement().pl_PositionVector-
|
|
GetPlacement().pl_PositionVector).Length();
|
|
} else {
|
|
if (m_penOwner!=NULL) {
|
|
// calculate distance to player from owner
|
|
fDistance = (penPlayer->GetPlacement().pl_PositionVector-
|
|
m_penOwner->GetPlacement().pl_PositionVector).Length();
|
|
}
|
|
}
|
|
if (fDistance<fClosest) {
|
|
fClosest = fDistance;
|
|
m_penCurrentWatch = penPlayer;
|
|
}
|
|
}
|
|
}
|
|
// if close enough start moving
|
|
return (fClosest < m_fDistance);
|
|
};
|
|
|
|
// send close event
|
|
void SendCloseEvent(void) {
|
|
// send range event
|
|
if (m_bRangeWatcher && m_penOwner==NULL) {
|
|
// SendInRange(this, m_eetEventClose, FLOATaabbox3D(GetPlacement().pl_PositionVector, m_fDistance));
|
|
// send to owner
|
|
} else {
|
|
SendToTarget(m_penOwner, m_eetEventClose, m_penCurrentWatch);
|
|
}
|
|
};
|
|
|
|
// send far event
|
|
void SendFarEvent(void) {
|
|
// send range event
|
|
if (m_bRangeWatcher && m_penOwner==NULL) {
|
|
// SendInRange(this, m_eetEventFar, FLOATaabbox3D(GetPlacement().pl_PositionVector, m_fDistance));
|
|
// send to owner
|
|
} else {
|
|
if (m_penFar!=NULL) {
|
|
SendToTarget(m_penFar, m_eetEventFar);
|
|
} else {
|
|
SendToTarget(m_penOwner, m_eetEventFar);
|
|
}
|
|
}
|
|
};
|
|
|
|
procedures:
|
|
// main (initialization)
|
|
Main(EVoid) {
|
|
// init as nothing
|
|
InitAsEditorModel();
|
|
SetPhysicsFlags(EPF_MODEL_IMMATERIAL);
|
|
SetCollisionFlags(ECF_IMMATERIAL);
|
|
|
|
// set appearance
|
|
SetModel(MODEL_WATCHPLAYERS);
|
|
SetModelMainTexture(TEXTURE_WATCHPLAYERS);
|
|
|
|
if (m_fWaitTime<0.1f) {
|
|
m_fWaitTime=0.1f;
|
|
}
|
|
|
|
if (m_bActive) {
|
|
jump Active();
|
|
} else {
|
|
jump Inactive();
|
|
}
|
|
};
|
|
|
|
Active()
|
|
{
|
|
autocall FarWatch() EDeactivate;
|
|
jump Inactive();
|
|
}
|
|
|
|
Inactive()
|
|
{
|
|
wait() {
|
|
on (EActivate) : {
|
|
stop;
|
|
};
|
|
otherwise() : {
|
|
resume;
|
|
};
|
|
}
|
|
jump Active();
|
|
}
|
|
|
|
// player is close
|
|
CloseWatch(EVoid) {
|
|
while (TRUE) {
|
|
wait(m_fWaitTime) {
|
|
on (EBegin) : {
|
|
if (!IsAnyPlayerClose()) {
|
|
// notify for player off range
|
|
SendFarEvent();
|
|
jump FarWatch();
|
|
}
|
|
resume;
|
|
}
|
|
on (ETimer) : { stop; }
|
|
}
|
|
}
|
|
};
|
|
|
|
// player is far
|
|
FarWatch(EVoid) {
|
|
while (TRUE) {
|
|
wait(m_fWaitTime) {
|
|
on (EBegin) : {
|
|
if (IsAnyPlayerClose()) {
|
|
// notify for player in range
|
|
SendCloseEvent();
|
|
jump CloseWatch();
|
|
}
|
|
resume;
|
|
}
|
|
on (ETimer) : { stop; }
|
|
}
|
|
}
|
|
};
|
|
}; |