Serious-Engine/Sources/EntitiesMP/Item.es
2016-05-09 18:51:03 +02:00

325 lines
9.9 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. */
800
%{
#include "EntitiesMP/StdH/StdH.h"
#include "Models/Items/ItemHolder/ItemHolder.h"
%}
%{
// used to render certain entities only for certain players (like picked items, etc.)
extern ULONG _ulPlayerRenderingMask;
%}
class export CItem : CMovableModelEntity {
name "Item";
thumbnail "";
features "HasName", "HasDescription", "IsTargetable", "CanBePredictable";
properties:
1 CTString m_strName "Name" 'N' = "Item",
2 CTString m_strDescription = "",
// class properties
5 FLOAT m_fValue = 0.0f, // value
6 FLOAT m_fRespawnTime = 0.0f, // default respawn time
26 FLOAT m_fCustomRespawnTime "Respawn Time" = 0.0f, // custom respawn time
7 BOOL m_bRespawn "Respawn" 'R' = FALSE, // respawn item
8 CEntityPointer m_penTarget "Target" 'T' COLOR(C_dGRAY|0xFF), // target to trigger when crossed over
9 BOOL m_bPickupOnce "PickupOnce" 'P' = FALSE, // can be picked by only one player, triggers only when really picked
10 CSoundObject m_soPick, // sound channel
12 FLOAT m_fPickSoundLen = 0.0f,
14 BOOL m_bDropped = FALSE, // dropped by a player during a deathmatch game
15 INDEX m_ulPickedMask = 0, // mask for which players picked this item
16 BOOL m_bFloating "Floating" 'F' = FALSE,
components:
1 model MODEL_ITEM "Models\\Items\\ItemHolder\\ItemHolder.mdl",
functions:
virtual void AdjustDifficulty(void)
{
}
/* Adjust model mip factor if needed. */
void AdjustMipFactor(FLOAT &fMipFactor)
{
// adjust flare glow, to decrease power with how you get closer
CAttachmentModelObject *pamo = GetModelObject()->GetAttachmentModel(ITEMHOLDER_ATTACHMENT_FLARE);
if( pamo != NULL)
{
FLOAT fRatio = (Clamp( fMipFactor, 5.0f, 7.0f)-5.0f)/2.0f;
UBYTE ubRatio = UBYTE(255*fRatio);
COLOR colMutiply = RGBToColor(ubRatio,ubRatio,ubRatio)|CT_OPAQUE;
pamo->amo_moModelObject.mo_colBlendColor = colMutiply;
}
// if never picked
if (m_ulPickedMask==0) {
// don't bother testing
return;
}
//BOOL bFlare = TRUE;
// if current player has already picked this item
if (_ulPlayerRenderingMask&m_ulPickedMask) {
// if picked items are not rendered
extern INDEX plr_bRenderPicked;
if (!plr_bRenderPicked) {
// kill mip factor
fMipFactor = UpperLimit(0.0f);
}
// if picked item particles are not rendered
/*extern INDEX plr_bRenderPickedParticles;
if (!plr_bRenderPickedParticles) {
// kill flare
bFlare = FALSE; // DG: bFlare is otherwise unused!
}*/
}
// implement flare on/off ?
}
// check whether should render particles for this item
BOOL ShowItemParticles(void)
{
// if current player has already picked this item
if (_ulPlayerRenderingMask&m_ulPickedMask) {
// if picked item particles are not rendered
extern INDEX plr_bRenderPickedParticles;
if (!plr_bRenderPickedParticles) {
// don't render
return FALSE;
}
}
// otherwise, render
return TRUE;
}
// check if given player already picked this item, and mark if not
BOOL MarkPickedBy(CEntity *pen)
{
if (!IsOfClass(pen, "Player")) {
return FALSE;
}
INDEX iPlayer = ((CPlayerEntity*)pen)->GetMyPlayerIndex();
BOOL bPickedAlready = (1<<iPlayer)&m_ulPickedMask;
m_ulPickedMask |= (1<<iPlayer);
return bPickedAlready;
}
// get maximum allowed range for predicting this entity
FLOAT GetPredictionRange(void)
{
extern FLOAT cli_fPredictItemsRange;
return cli_fPredictItemsRange;
}
/* Adjust model shading parameters if needed. */
BOOL AdjustShadingParameters(FLOAT3D &vLightDirection, COLOR &colLight, COLOR &colAmbient)
{
// in DM, glares are off, so add some light to items
//if( m_bRespawn)
{
// fixed light and ambient
colLight = 0x40404040;
colAmbient = 0x60606060;
}
/*
else
{
// fixed light and ambient
colLight = 0x30303030;
colAmbient = 0x30303030;
}
*/
// light direction always from upper left corner relative to the object
vLightDirection = FLOAT3D(-1,-1,-1);
vLightDirection.Normalize();
vLightDirection*=GetRotationMatrix();
// no shadow
return FALSE;
};
/************************************************************
* INITALIZATION *
************************************************************/
void Initialize(void) {
InitAsModel();
SetFlags(GetFlags()|ENF_SEETHROUGH);
if (m_bFloating) {
SetPhysicsFlags(EPF_MODEL_FLYING);
} else {
SetPhysicsFlags(EPF_MODEL_SLIDING);
}
SetCollisionFlags(ECF_ITEM);
// make items not slide that much
en_fDeceleration = 60.0f;
// set appearance
SetModel(MODEL_ITEM);
SetDesiredTranslation(FLOAT3D(0,0,0)); // just to add to movers
};
/************************************************************
* SET MODEL AND ATTACHMENT *
************************************************************/
// Add item
void AddItem(ULONG ulIDModel, ULONG ulIDTexture,
ULONG ulIDReflectionTexture, ULONG ulIDSpecularTexture, ULONG ulIDBumpTexture) {
AddAttachmentToModel(this, *GetModelObject(), ITEMHOLDER_ATTACHMENT_ITEM, ulIDModel, ulIDTexture,
ulIDReflectionTexture, ulIDSpecularTexture, ulIDBumpTexture);
};
void AddItemSpecial(INDEX iAttachmentPos, ULONG ulIDModel, ULONG ulIDTexture,
ULONG ulIDReflectionTexture, ULONG ulIDSpecularTexture, ULONG ulIDBumpTexture) {
AddAttachmentToModel(this, *GetModelObject(), iAttachmentPos, ulIDModel, ulIDTexture,
ulIDReflectionTexture, ulIDSpecularTexture, ulIDBumpTexture);
};
// Add attachment to item
void AddItemAttachment(INDEX iAttachment, ULONG ulIDModel, ULONG ulIDTexture,
ULONG ulIDReflectionTexture, ULONG ulIDSpecularTexture, ULONG ulIDBumpTexture) {
CModelObject &mo = GetModelObject()->GetAttachmentModel(ITEMHOLDER_ATTACHMENT_ITEM)->amo_moModelObject;
AddAttachmentToModel(this, mo, iAttachment, ulIDModel, ulIDTexture,
ulIDReflectionTexture, ulIDSpecularTexture, ulIDBumpTexture);
};
// set animation of attachment
void SetItemAttachmentAnim(INDEX iAttachment, INDEX iAnim)
{
CModelObject &mo =
GetModelObject()->GetAttachmentModel(ITEMHOLDER_ATTACHMENT_ITEM)->amo_moModelObject.
GetAttachmentModel(iAttachment)->amo_moModelObject;
mo.PlayAnim(iAnim, 0);
}
// Add flare
void AddFlare(ULONG ulIDModel, ULONG ulIDTexture,
const FLOAT3D &vPos, const FLOAT3D &vStretch)
{
// add flare to items if not respawn
if( !m_bRespawn && !m_bDropped)
{
AddAttachmentToModel(this, *GetModelObject(),
ITEMHOLDER_ATTACHMENT_FLARE, ulIDModel, ulIDTexture, 0,0,0);
CAttachmentModelObject &amo = *GetModelObject()->GetAttachmentModel(ITEMHOLDER_ATTACHMENT_FLARE);
amo.amo_moModelObject.StretchModel(vStretch);
amo.amo_plRelative.pl_PositionVector = vPos;
}
};
// Stretch item
void StretchItem(const FLOAT3D &vStretch) {
CModelObject &mo = GetModelObject()->GetAttachmentModel(ITEMHOLDER_ATTACHMENT_ITEM)->amo_moModelObject;
mo.StretchModel(vStretch);
ModelChangeNotify();
};
// returns bytes of memory used by this object
SLONG GetUsedMemory(void)
{
// initial
SLONG slUsedMemory = sizeof(CItem) - sizeof(CMovableModelEntity) + CMovableModelEntity::GetUsedMemory();
// add some more
slUsedMemory += m_strDescription.Length();
slUsedMemory += m_strName.Length();
slUsedMemory += 1* sizeof(CSoundObject);
return slUsedMemory;
}
procedures:
/************************************************************
* VIRTUAL PROCEDURES THAT NEED OVERRIDE *
************************************************************/
ItemCollected(EPass epass) { return; };
/************************************************************
* I T E M L O O P *
************************************************************/
ItemLoop(EVoid)
{
m_fCustomRespawnTime = ClampDn( m_fCustomRespawnTime, 0.0f);
autowait(0.1f);
SetPredictable(TRUE);
AdjustDifficulty();
wait() {
on (EBegin) : { resume; }
on (EPass epass) : {
if (!IsOfClass(epass.penOther, "Player")) {
pass;
}
if (!(m_bPickupOnce||m_bRespawn)) {
SendToTarget(m_penTarget, EET_TRIGGER, epass.penOther);
m_penTarget = NULL;
}
call ItemCollected(epass);
}
on (EEnd) : { stop; }
}
// wait for sound to end
autowait(m_fPickSoundLen+0.5f);
// cease to exist
Destroy();
return;
};
ItemReceived(EVoid)
{
// hide yourself
SwitchToEditorModel();
if ((m_bPickupOnce||m_bRespawn)) {
SendToTarget(m_penTarget, EET_TRIGGER, NULL);
}
// respawn item
if (m_bRespawn) {
ASSERT(m_fRespawnTime>0.0f);
// wait to respawn
wait(m_fRespawnTime) {
on (EBegin) : { resume; }
on (ETimer) : { stop; }
otherwise() : { resume; }
}
// show yourself
SwitchToModel();
// cease to exist
} else {
return EEnd();
}
return;
};
};