sof-sdk/Source/Game/gamecpp/g_iraq.cpp
2000-06-15 00:00:00 +00:00

1082 lines
31 KiB
C++

/******************************************************
* Objects between Iraq and a hard place (if you think about it, it really is funny) *
******************************************************/
#include "g_local.h"
#include "g_obj.h"
#include "callback.h"
#define FRUITSTAND_MELONS 4
#define FRUITSTAND_ORANGES 8
#define FRUITSTAND_NOFRUIT 16
#define HLTH_IRAQ_BASKET 50
#define HLTH_IRAQ_CART_CAMEL 300
#define HLTH_IRAQ_FLATBED 500
#define HLTH_IRAQ_FLATBED_WHEEL 500
#define HLTH_IRAQ_FRUIT_MELON 50
#define HLTH_IRAQ_FRUIT_ORANGE 10
#define HLTH_IRAQ_FRUIT_STAND 125
#define HLTH_IRAQ_PARTITION 400
#define HLTH_IRAQ_POTTERY 25
#define HLTH_IRAQ_SPRINKLER 500
#define HLTH_IRAQ_STEALTH 5000
#define HLTH_IRAQ_TREE_PALM 1000
#define HLTH_IRAQ_VALVE 300
#define FLATBED_TRIGGERED 4
#define FLATBED_LIGHTS 8
#define FLATBED_WHEELS_ONLY 16
#define FLATBED_BRAKE_FACTOR 3
#define VALVE_PORTCULLIS (1<<7)
extern void debug_drawbox(edict_t* self,vec3_t vOrigin, vec3_t vMins, vec3_t vMaxs, int nColor);
extern void drawthink(edict_t *ent);
// misc_iraq...
void SP_misc_iraq_basket (edict_t *ent);
void SP_misc_iraq_cart_camel (edict_t *ent);
void SP_misc_iraq_flatbed (edict_t *ent);
void SP_misc_iraq_fruit_melon (edict_t *ent);
void SP_misc_iraq_fruit_orange (edict_t *ent);
void SP_misc_iraq_fruit_stand (edict_t *ent);
void SP_misc_iraq_partition (edict_t *ent);
void SP_misc_iraq_pottery (edict_t *ent);
void SP_misc_iraq_sprinkler (edict_t *ent);
void SP_misc_iraq_stealth (edict_t *ent);
void SP_misc_iraq_tree_palm (edict_t *ent);
void SP_misc_iraq_valve (edict_t *ent);
spawn_t iraqSpawns[] =
{
// misc_iraq...
{"misc_iraq_basket", SP_misc_iraq_basket},
{"misc_iraq_cart_camel", SP_misc_iraq_cart_camel},
{"misc_iraq_flatbed", SP_misc_iraq_flatbed},
{"misc_iraq_fruit_melon", SP_misc_iraq_fruit_melon},
{"misc_iraq_fruit_orange", SP_misc_iraq_fruit_orange},
{"misc_iraq_fruit_stand", SP_misc_iraq_fruit_stand},
{"misc_iraq_partition", SP_misc_iraq_partition},
{"misc_iraq_pottery", SP_misc_iraq_pottery},
{"misc_iraq_sprinkler", SP_misc_iraq_sprinkler},
{"misc_iraq_stealth", SP_misc_iraq_stealth},
{"misc_iraq_tree_palm", SP_misc_iraq_tree_palm},
{"misc_iraq_valve", SP_misc_iraq_valve},
{NULL, NULL},
};
typedef enum
{
OBJ_BASKET = 0,
OBJ_CART_CAMEL,
OBJ_FLATBED_OFF,
OBJ_FLATBED_WHEEL,
OBJ_FLATBED_ON,
OBJ_FRUIT_MELON,
OBJ_FRUIT_ORANGE,
OBJ_FRUIT_STAND,
OBJ_LIGHT_BEAM,
OBJ_PARTITION,
OBJ_POTTERY,
OBJ_SPRINKLER,
OBJ_STEALTH,
OBJ_TREE_PALM,
OBJ_VALVE,
MAX_OBJS
};
modelSpawnData_t iraqModelData[MD_IRAQ_SIZE] =
{
// dir file surfaceType material health solid material file cnt scale
"objects/iraq/basket", "basket", SURF_WOOD_DBROWN, MAT_WOOD_DBROWN, HLTH_IRAQ_BASKET, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_BASKET
"objects/iraq/cart_camel", "cart", SURF_WOOD_DBROWN, MAT_WOOD_DBROWN, HLTH_IRAQ_CART_CAMEL, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_CART_CAMEL
"objects/iraq/flatbed", "off", SURF_METAL, MAT_METAL_LGREY, HLTH_IRAQ_FLATBED, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_FLATBED_OFF
"objects/iraq/flatbed", "tire", SURF_METAL, MAT_METAL_LGREY, HLTH_IRAQ_FLATBED_WHEEL, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_FLATBED_WHEEL
"objects/iraq/flatbed", "on", SURF_METAL, MAT_METAL_LGREY, HLTH_IRAQ_FLATBED, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_FLATBED_ON
"objects/iraq/fruit_melon", "melon", SURF_LIQUID_RED, MAT_DEFAULT, HLTH_IRAQ_FRUIT_MELON, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_FRUIT_MELON
"objects/iraq/fruit_orange", "orange", SURF_LIQUID_ORANGE, MAT_DEFAULT, HLTH_IRAQ_FRUIT_MELON, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_FRUIT_ORANGE
"objects/iraq/fruit_stand", "fruit_stand", SURF_WOOD_DBROWN, MAT_WOOD_DBROWN, HLTH_IRAQ_FRUIT_STAND, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_FRUIT_STAND
"objects/generic/beam", "beam", SURF_NONE, MAT_NONE, 0, SOLID_NOT, NULL, 0, 0.0, NULL, // OBJ_LIGHT_BEAM
"objects/iraq/partition", "partition", SURF_NONE, MAT_DEFAULT, HLTH_IRAQ_PARTITION, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_PARTITION
"objects/iraq/pottery", "pottery", SURF_SAND_LBROWN, MAT_DEFAULT, HLTH_IRAQ_POTTERY, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_POTTERY
"objects/iraq/sprinklers", "sprinklers", SURF_METAL, MAT_METAL_LGREY, HLTH_IRAQ_SPRINKLER, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_SPRINKLER
"objects/iraq/stealth", "stealth", SURF_METAL, MAT_METAL_LGREY, HLTH_IRAQ_STEALTH, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_STEALTH
"objects/iraq/tree_palm", "tree", SURF_WOOD_DBROWN, MAT_WOOD_DBROWN, HLTH_IRAQ_TREE_PALM, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_TREE_PALM
"objects/iraq/valve", "valve", SURF_METAL, MAT_METAL_LGREY, HLTH_IRAQ_VALVE, SOLID_BBOX, NULL, 0, 0.0, NULL, // OBJ_VALVE
};
void EntToWorldMatrix(vec3_t org, vec3_t angles, Matrix4 &m);
/*QUAKED misc_iraq_basket (1 .5 0) (-6 -7 -18) (7 6 15) INVULNERABLE NOPUSH x x x x FLUFF
A tall thin wicker basket
------ SPAWNFLAGS ------
INVULNERABLE - can't be damaged.
NOPUSH - can't be pushed
FLUFF - won't show if gl_pictip is set
*/
void SP_misc_iraq_basket (edict_t *ent)
{
VectorSet (ent->mins, -6, -7, -18);
VectorSet (ent->maxs, 7, 6, 15);
SimpleModelInit2(ent,&iraqModelData[OBJ_BASKET],NULL,NULL);
}
/*QUAKED misc_iraq_cart_camel (1 .5 0) (-20 -48 -24) (20 48 24) INVULNERABLE NOPUSH x x x x FLUFF
A large two wheeled wooden cart
------ SPAWNFLAGS ------
INVULNERABLE - can't be damaged.
NOPUSH - can't be pushed
FLUFF - won't show if gl_pictip is set
*/
void SP_misc_iraq_cart_camel (edict_t *ent)
{
VectorSet (ent->mins, -20, -48, -24);
VectorSet (ent->maxs, 20, 48, 24);
SimpleModelInit2(ent,&iraqModelData[OBJ_CART_CAMEL],NULL,NULL);
}
void flatbed_stop (edict_t *self)
{
GrabStuffOnTop (self);
VectorClear(self->velocity);
self->movetype = MOVETYPE_NONE;
self->s.sound = 0;
self->nextthink = -1;
}
void flatbed_deccel (edict_t *self)
{
float distanceLeft;
float thisDist;
float curSpeed;
vec3_t newVel;
float xDiff, yDiff;
GrabStuffOnTop (self);
xDiff = self->s.origin[0] - self->volume;
yDiff = self->s.origin[1] - self->attenuation;
distanceLeft = sqrt(xDiff*xDiff + yDiff*yDiff);
curSpeed = sqrt(self->velocity[0]*self->velocity[0] + self->velocity[1]*self->velocity[1]);
thisDist = curSpeed * .1;
if (curSpeed < 5)
{
newVel[0] = self->velocity[0] * (distanceLeft/thisDist);
newVel[1] = self->velocity[1] * (distanceLeft/thisDist);
newVel[2] = 0;
VectorCopy(newVel, self->velocity);
self->think = flatbed_stop;
self->nextthink = level.time + .1;
return;
}
newVel[0] = self->velocity[0] * (distanceLeft/((FLATBED_BRAKE_FACTOR+1)*thisDist));
newVel[1] = self->velocity[1] * (distanceLeft/((FLATBED_BRAKE_FACTOR+1)*thisDist));
newVel[2] = 0;
VectorCopy(newVel, self->velocity);
self->nextthink = level.time + .1;
}
qboolean FlatbedEndofLineCheck (edict_t *self)
{
float distanceLeft;
float thisDist;
float curSpeed;
float xDiff, yDiff;
xDiff = self->s.origin[0] - self->volume;
yDiff = self->s.origin[1] - self->attenuation;
distanceLeft = sqrt(xDiff*xDiff + yDiff*yDiff);
curSpeed = sqrt(self->velocity[0]*self->velocity[0] + self->velocity[1]*self->velocity[1]);
thisDist = curSpeed * .1;
if (VectorCompare(vec3_origin, self->velocity))
{
return true;
}
// if (self->spawnflags & TRAIN_DECCELERATE)
{
if (distanceLeft < (FLATBED_BRAKE_FACTOR*thisDist))
{
vec3_t newVel;
//adjust velocity then stop
newVel[0] = self->velocity[0] * (distanceLeft/((FLATBED_BRAKE_FACTOR+1)*thisDist));
newVel[1] = self->velocity[1] * (distanceLeft/((FLATBED_BRAKE_FACTOR+1)*thisDist));
newVel[2] = 0;
VectorCopy(newVel, self->velocity);
self->think = flatbed_deccel;
self->nextthink = level.time + .1;
return false;
}
else
{
return true;
}
}
}
void flatbed_WheelSpin (edict_t *self)
{
ggBinstC *wheel1,*wheel2,*wheel3,*wheel4;
vec3_t angVel = {0,0,0};
eft_rotate_t *rotInfo = NULL;
int tire_circ;
float speed,turns,radians;
tire_circ = (30 * M_PI);
speed = self->speed;
turns = speed / tire_circ;
radians = DEGTORAD * turns;
radians = M_PI * turns;
wheel1 = SimpleModelFindBolt(self, iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY01");
wheel2 = SimpleModelFindBolt(self, iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY02");
wheel3 = SimpleModelFindBolt(self, iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY03");
wheel4 = SimpleModelFindBolt(self, iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY04");
if (wheel1)
{
if (rotInfo = FXA_GetRotate(self))
{
// adding to an existing rotation
rotInfo->xRot = radians*512;//512 accounts for the shift induced by FXA_SetRotate()
}
else
{
// need to create a rotating effect
angVel[PITCH] = radians;
FXA_SetRotate(self, angVel,
wheel1->GetInstPtr(),wheel2->GetInstPtr(),
wheel3->GetInstPtr(),wheel4->GetInstPtr());
}
}
}
void flatbed_linecheck (edict_t *self)
{
GrabStuffOnTop (self);
FlatbedEndofLineCheck(self);
self->nextthink = level.time + .1;
flatbed_WheelSpin (self);
}
void flatbed_accel (edict_t *self)
{
int chance;
GrabStuffOnTop (self);
if ((double)(self->velocity[0]*self->velocity[0] + self->velocity[1]*self->velocity[1]) < (self->speed*self->speed)) //speed is max speed
{
self->velocity[1] += (-1 * self->accel * sin(self->s.angles[1] * DEGTORAD));
self->velocity[0] += (self->accel * cos(self->s.angles[1] * DEGTORAD));
self->nextthink = level.time + .1;
}
else
{
self->think = flatbed_linecheck;
self->nextthink = level.time + .1;
}
chance = gi.irand(0,5);
FlatbedEndofLineCheck(self);
flatbed_WheelSpin (self);
}
void flatbed_go (edict_t *self, edict_t *other, edict_t *activator)
{
// flatbeds with facing 0 are "pointing" east (pos x)
self->movetype = MOVETYPE_DAN;
GrabStuffOnTop (self);
self->velocity[1] = -1 * self->accel * sin(self->s.angles[1] * DEGTORAD);
self->velocity[0] = self->accel * cos(self->s.angles[1] * DEGTORAD);
self->friction = 0;
self->gravity = 0;
self->nextthink = level.time + .1;
self->think = flatbed_accel;
self->use = NULL;
self->plUse = NULL;
// self->s.sound = gi.soundindex("Ambient/Locs/Subway/Train/Move.wav");
FlatbedEndofLineCheck(self);
}
void flatbedwheels_stop (edict_t *self)
{
FXA_RemoveRotate(self);
}
void flatbedwheels_roll (edict_t *self)
{
ggBinstC *wheel1,*wheel2,*wheel3,*wheel4;
vec3_t angVel = {0,0,0};
eft_rotate_t *rotInfo = NULL;
int tire_circ;
float speed,turns,radians;
tire_circ = (30 * M_PI);
speed = self->speed;
turns = speed / tire_circ;
radians = DEGTORAD * turns;
radians = M_PI * turns;
wheel1 = SimpleModelFindBolt(self, iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY01");
wheel2 = SimpleModelFindBolt(self, iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY02");
wheel3 = SimpleModelFindBolt(self, iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY03");
wheel4 = SimpleModelFindBolt(self, iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY04");
if (wheel1)
{
if (rotInfo = FXA_GetRotate(self))
{
// adding to an existing rotation
rotInfo->xRot = radians*512;//512 accounts for the shift induced by FXA_SetRotate()
}
else
{
// need to create a rotating effect
angVel[PITCH] = radians;
FXA_SetRotate(self, angVel,
wheel1->GetInstPtr(),wheel2->GetInstPtr(),
wheel3->GetInstPtr(),wheel4->GetInstPtr());
}
}
// self->think = flatbedwheels_roll;
// self->nextthink = level.time + .2;
}
void flatbedwheels_use (edict_t *self, edict_t *other, edict_t *activator)
{
if (!self->count)
{
self->count = 1; // Let 'em know we're moving
flatbedwheels_roll(self);
}
else
{
self->count = 0; // Let 'em know we're not moving
flatbedwheels_stop(self);
}
}
void flatbed_remove(edict_t *self)
{
IGhoulObj *obj = NULL;
GhoulID idEngine = 0;
float xattenuation = ATTN_NORM, xvolume = 1.0;
if (self->ghoulInst && (obj = self->ghoulInst->GetGhoulObject()))
{
if (idEngine = obj->FindPart("ENGINE"))
{
fxRunner.stopContinualEffect("environ/normalsmoke", self, idEngine);
}
}
}
void flatbed_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
IGhoulObj *obj = NULL;
GhoulID idEngine = 0;
float xattenuation = ATTN_NORM, xvolume = 1.0;
if (self->ghoulInst && (obj = self->ghoulInst->GetGhoulObject()))
{
if (idEngine = obj->FindPart("ENGINE"))
{
fxRunner.execContinualEffect("environ/normalsmoke", self, idEngine);
gi.positioned_sound (self->s.origin, g_edicts, 0, gi.soundindex("impact/explosion/med.wav"), xvolume, xattenuation, 0);
self->think = flatbed_remove;
self->nextthink = level.time + 5;
self->die = NULL;
if (self->spawnflags & FLATBED_LIGHTS)
{ // turn off headlights
SimpleModelTurnOnOff(SimpleModelGetBolt(self,1),false);
SimpleModelTurnOnOff(SimpleModelGetBolt(self,2), false);
SimpleModelRemoveObject(self, "HEADLIGHT1");
SimpleModelRemoveObject(self, "HEADLIGHT2");
}
}
}
}
/*QUAKED misc_iraq_flatbed (1 .5 0) (-95 -40 -42) (95 40 45) INVULNERABLE NOPUSH TRIGGERED LIGHTS WHEELS_ONLY x FLUFF
A flatbed truck that can have a tank on the back
------ KEYS ------
Style :
0 - no tank - just a flatbed (default)
1 - has a tank on the back
Distance - distance the truck will move when triggered
Speed - max speed (default 200)
------ SPAWNFLAGS ------
INVULNERABLE - can't be damaged.
NOPUSH - can't be pushed
TRIGGERED - trigger will cause the truck to move forward a specified amount
LIGHTS - the headlights are on
WHEELS_ONLY - wheels turn when used, stop turning when used again.
FLUFF - won't show if gl_pictip is set
------ SPECIALS ------
- moves forward or backward
- wheels turn as it moves
*/
void SP_misc_iraq_flatbed (edict_t *ent)
{
VectorSet (ent->mins, -95, -40, -42);
VectorSet (ent->maxs, 95, 40, 45);
gi.effectindex("environ/normalsmoke");
gi.soundindex("impact/explosion/med.wav");
SimpleModelInit2(ent,&iraqModelData[OBJ_FLATBED_ON],NULL,NULL);
if (ent->style==0) // No tank
{
SimpleModelRemoveObject(ent,"OILTANK");
}
if (ent->spawnflags & FLATBED_LIGHTS)
{
SimpleModelAddBolt(ent,*ent->objSpawnData,"headlight1",
iraqModelData[OBJ_LIGHT_BEAM],"to_headlight",NULL);
SimpleModelAddBolt(ent,*ent->objSpawnData,"headlight2",
iraqModelData[OBJ_LIGHT_BEAM],"to_headlight",NULL);
SimpleModelAddObject(ent, "top1");
SimpleModelAddObject(ent, "top2");
SimpleModelAddObject(ent, "back1");
SimpleModelAddObject(ent, "back2");
SimpleModelAddObject(ent, "frt1");
SimpleModelAddObject(ent, "frt2");
SimpleModelAddObject(ent, "frt3");
SimpleModelAddObject(ent, "frt4");
}
else
{
SimpleModelRemoveObject(ent, "top1");
SimpleModelRemoveObject(ent, "top2");
SimpleModelRemoveObject(ent, "back1");
SimpleModelRemoveObject(ent, "back2");
SimpleModelRemoveObject(ent, "frt1");
SimpleModelRemoveObject(ent, "frt2");
SimpleModelRemoveObject(ent, "frt3");
SimpleModelRemoveObject(ent, "frt4");
}
SimpleModelAddBolt(ent,*ent->objSpawnData,"DUMMY01",
iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY05",NULL);
SimpleModelAddBolt(ent,*ent->objSpawnData,"DUMMY02",
iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY05",NULL);
SimpleModelAddBolt(ent,*ent->objSpawnData,"DUMMY03",
iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY05",NULL);
SimpleModelAddBolt(ent,*ent->objSpawnData,"DUMMY04",
iraqModelData[OBJ_FLATBED_WHEEL],"DUMMY05",NULL);
// Turn wheels without moving it?
if (ent->spawnflags & FLATBED_WHEELS_ONLY)
{
ent->count = 0; // Let 'em know we're not moving
ent->use = flatbedwheels_use;
if (!ent->speed)
{
ent->speed = 200;
}
}
// Turn wheels and apply velocity
else if (ent->spawnflags & FLATBED_TRIGGERED)
{
ent->use = flatbed_go;
ent->s.origin[2] += 1; // hack to avoid the sliding into floor brushes problem
// ent->touch = flatbed_smush; mcnutt said he won't need this
ent->elasticity = -1;
ent->flags |= FL_NO_KNOCKBACK;
if (!ent->speed)
{
ent->speed = 200;
}
ent->accel = 30;
// using volume and attenuation for storage of finishing position
ent->volume = ent->s.origin[0] + st.distance * cos(ent->s.angles[1] * DEGTORAD);
ent->attenuation = ent->s.origin[1] + st.distance * sin(ent->s.angles[1] * DEGTORAD);
}
ent->die = flatbed_die;
}
/*QUAK-ED misc_iraq_fruit_melon (1 .5 0) (-8 -4 -4) (8 4 4) INVULNERABLE NOPUSH x x x x FLUFF
Nice melons
------ SPAWNFLAGS ------
INVULNERABLE - can't be damaged.
NOPUSH - can't be pushed
FLUFF - won't show if gl_pictip is set
*/
void SP_misc_iraq_fruit_melon (edict_t *ent)
{
VectorSet (ent->mins, -8, -4, -4);
VectorSet (ent->maxs, 8, 4, 4);
SimpleModelInit2(ent,&iraqModelData[OBJ_FRUIT_MELON],NULL,NULL);
}
/*QUAK-ED misc_iraq_fruit_orange (1 .5 0) (-2 -2 -2) (2 2 2) INVULNERABLE NOPUSH x x x x FLUFF
Nice oranges
------ SPAWNFLAGS ------
INVULNERABLE - can't be damaged.
NOPUSH - can't be pushed
FLUFF - won't show if gl_pictip is set
*/
void SP_misc_iraq_fruit_orange (edict_t *ent)
{
VectorSet (ent->mins, -2, -2, -2);
VectorSet (ent->maxs, 2, 2, 2);
SimpleModelInit2(ent,&iraqModelData[OBJ_FRUIT_ORANGE],NULL,NULL);
}
void SimpleModelSetOriginRelative(edict_t *original,edict_t *dupe,float addforward,float addright,float addup);
void iraq_fruit_stand_throw(edict_t *self)
{
self->velocity[0] = gi.flrand(-100,100);
self->velocity[1] = gi.flrand(-100,100);
self->velocity[2] = gi.flrand(200,500);
self->avelocity[2]= gi.flrand(-100,100);
self->die = BecomeDebris;
}
// Have fruit thrown before stand dies.
void iraq_fruit_stand_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
edict_t *enemy[10],*holdent;
int i,total;
if (self->goalentity == NULL) // No fruit on table, kill it.
{
BecomeDebris(self,inflictor,attacker,damage,point);
return;
}
if ((self->spawnflags & FRUITSTAND_MELONS) && (self->spawnflags & FRUITSTAND_ORANGES))
total = 10;
else
total = 5;
holdent = self->goalentity;
for (i=0;i<total;++i)
{
enemy[i] = holdent;
holdent = holdent->goalentity;
enemy[i]->teammaster = NULL; // So they know they've been thrown
}
if (total == 10)
{
iraq_fruit_stand_throw(enemy[9]);
iraq_fruit_stand_throw(enemy[8]);
iraq_fruit_stand_throw(enemy[7]);
iraq_fruit_stand_throw(enemy[6]);
iraq_fruit_stand_throw(enemy[5]);
}
iraq_fruit_stand_throw(enemy[4]);
iraq_fruit_stand_throw(enemy[3]);
enemy[2]->think = iraq_fruit_stand_throw;
enemy[2]->nextthink = level.time + FRAMETIME;
enemy[1]->think = iraq_fruit_stand_throw;
enemy[1]->nextthink = level.time + FRAMETIME;
enemy[0]->think = iraq_fruit_stand_throw;
enemy[0]->nextthink = level.time + FRAMETIME;
BecomeDebris(self,inflictor,attacker,damage,point);
}
// One fruit dies, all fruit dies.
void iraq_fruit_stand_fruit_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
{
edict_t *table,*holdent,*holdent2;
int i,total;
if (!self->teammaster) // table's dead. Leave other fruit alone.
return;
table = self->teammaster;
holdent = table->goalentity;
table->goalentity = NULL;
if ((table->spawnflags & FRUITSTAND_MELONS) && (table->spawnflags & FRUITSTAND_ORANGES))
total = 10;
else
total = 5;
// Kill all fruit from table
for (i=0;i<total;++i)
{
holdent2 = holdent->goalentity;
BecomeDebris(holdent,inflictor,attacker,999,point);
holdent = holdent2;
}
}
/*QUAKED misc_iraq_fruit_stand (1 .5 0) (-8 -16 -16) (8 16 16) INVULNERABLE NOPUSH MELONS ORANGES NOFRUIT x FLUFF
Nice fruit stand. If none of the spawnflags are used, the table will have both types of fruit.
------ SPAWNFLAGS ------
INVULNERABLE - can't be damaged.
NOPUSH - can't be pushed
MELONS - only melons on table
ORANGES - only oranges
NOFRUIT - no fruit on table
FLUFF - won't show if gl_pictip is set
------ SPECIALS ------
- fruti is thrown when table is shot
*/
void SP_misc_iraq_fruit_stand (edict_t *ent)
{
edict_t *melon,*melon2,*melon3,*melon4,*melon5;
edict_t *orange,*orange2,*orange3,*orange4,*orange5;
VectorSet (ent->mins, -8, -16, -16);
VectorSet (ent->maxs, 8, 16, 16);
SimpleModelInit2(ent,&iraqModelData[OBJ_FRUIT_STAND],NULL,NULL);
if (ent->spawnflags & FRUITSTAND_NOFRUIT) // No fruit??
return;
// Didn't choose either so they must want both.
if (!(ent->spawnflags & FRUITSTAND_MELONS) && !(ent->spawnflags & FRUITSTAND_ORANGES))
{
ent->spawnflags |= FRUITSTAND_MELONS | FRUITSTAND_ORANGES;
}
// Melons on table??
if (ent->spawnflags & FRUITSTAND_MELONS)
{
// Melon1
melon = G_Spawn();
melon->s.angles[1] = ent->s.angle_diff;
SP_misc_iraq_fruit_melon(melon);
melon->die = iraq_fruit_stand_fruit_die;
SimpleModelSetOriginRelative(ent,melon,0,0,20);
// Melon2
melon2 = G_Spawn();
melon2->s.angles[1] = ent->s.angle_diff;
SP_misc_iraq_fruit_melon(melon2);
melon2->die = iraq_fruit_stand_fruit_die;
SimpleModelSetOriginRelative(ent,melon2,0,-8,20);
// Melon3
melon3 = G_Spawn();
melon3->s.angles[1] = ent->s.angle_diff;
SP_misc_iraq_fruit_melon(melon3);
melon3->die = iraq_fruit_stand_fruit_die;
SimpleModelSetOriginRelative(ent,melon3,0,-16,20);
// Melon4
melon4 = G_Spawn();
melon4->s.angles[1] = ent->s.angle_diff;
SP_misc_iraq_fruit_melon(melon4);
melon4->die = iraq_fruit_stand_fruit_die;
SimpleModelSetOriginRelative(ent,melon4,0,-4,27);
// Melon5
melon5 = G_Spawn();
melon5->s.angles[1] = ent->s.angle_diff;
SP_misc_iraq_fruit_melon(melon5);
melon5->die = iraq_fruit_stand_fruit_die;
// If there are no oranges, but a melon where the orangs go
if (ent->spawnflags & FRUITSTAND_ORANGES) // There are oranges
SimpleModelSetOriginRelative(ent,melon5,0,-12,27);
else
{
SimpleModelSetOriginRelative(ent,melon5,0,12,20);
melon5->s.angle_diff += 25;
}
}
// Oranges on table???
if (ent->spawnflags & FRUITSTAND_ORANGES)
{
orange = G_Spawn();
orange->s.angles[1] = ent->s.angle_diff;
SP_misc_iraq_fruit_orange(orange);
orange->die = iraq_fruit_stand_fruit_die;
SimpleModelSetOriginRelative(ent,orange,2,8,18);
// Orange2
orange2 = G_Spawn();
orange2->s.angles[1] = ent->s.angle_diff;
SP_misc_iraq_fruit_orange(orange2);
orange2->die = iraq_fruit_stand_fruit_die;
SimpleModelSetOriginRelative(ent,orange2,-2,8,18);
// Orange3
orange3 = G_Spawn();
orange3->s.angles[1] = ent->s.angle_diff;
SP_misc_iraq_fruit_orange(orange3);
orange3->die = iraq_fruit_stand_fruit_die;
SimpleModelSetOriginRelative(ent,orange3,0,12,18);
// Orange4
orange4 = G_Spawn();
orange4->s.angles[1] = ent->s.angle_diff;
SP_misc_iraq_fruit_orange(orange4);
orange4->die = iraq_fruit_stand_fruit_die;
SimpleModelSetOriginRelative(ent,orange4,4,12,18);
// Orange5
orange5 = G_Spawn();
orange5->s.angles[1] = ent->s.angle_diff;
SP_misc_iraq_fruit_orange(orange5);
orange5->die = iraq_fruit_stand_fruit_die;
SimpleModelSetOriginRelative(ent,orange5,-8,18,18);
}
ent->die = iraq_fruit_stand_die;
// Setup fruit and table to point to each other in case of death or dismemberment.
if ((ent->spawnflags & FRUITSTAND_MELONS) && (ent->spawnflags & FRUITSTAND_ORANGES))
{
ent->goalentity = melon;
melon->goalentity = melon2;
melon2->goalentity = melon3;
melon3->goalentity = melon4;
melon4->goalentity = melon5;
// Point fruit back to table so if a single fruit dies, all fruit dies.
melon->teammaster = ent;
melon2->teammaster = ent;
melon3->teammaster = ent;
melon4->teammaster = ent;
melon5->teammaster = ent;
melon5->goalentity = orange;
orange->goalentity = orange2;
orange2->goalentity = orange3;
orange3->goalentity = orange4;
orange4->goalentity = orange5;
// Point fruit back to table so if a single fruit dies, all fruit dies.
orange->teammaster = ent;
orange2->teammaster = ent;
orange3->teammaster = ent;
orange4->teammaster = ent;
orange5->teammaster = ent;
}
else if (ent->spawnflags & FRUITSTAND_MELONS) // Just melons
{
ent->goalentity = melon;
melon->goalentity = melon2;
melon2->goalentity = melon3;
melon3->goalentity = melon4;
melon4->goalentity = melon5;
// Point fruit back to table so if one fruit dies, all fruit dies.
melon->teammaster = ent;
melon2->teammaster = ent;
melon3->teammaster = ent;
melon4->teammaster = ent;
melon5->teammaster = ent;
}
else if (ent->spawnflags & FRUITSTAND_ORANGES) // Just oranges
{
ent->goalentity = orange;
orange->goalentity = orange2;
orange2->goalentity = orange3;
orange3->goalentity = orange4;
orange4->goalentity = orange5;
// Point fruit back to table so if a single fruit dies, all fruit dies.
orange->teammaster = ent;
orange2->teammaster = ent;
orange3->teammaster = ent;
orange4->teammaster = ent;
orange5->teammaster = ent;
}
}
/*QUAKED misc_iraq_partition (1 .5 0) (-63 -1 0) (62 2 35) INVULNERABLE NOPUSH x x x x FLUFF
Chrome pole with a felt line. Used by movie theaters use to keep people in line.
------ SPAWNFLAGS ------
INVULNERABLE - can't be damaged.
NOPUSH - can't be pushed
FLUFF - won't show if gl_pictip is set
*/
void SP_misc_iraq_partition (edict_t *ent)
{
VectorSet (ent->mins, -63, -1, 0);
VectorSet (ent->maxs, 62, 2, 35);
SimpleModelInit2(ent,&iraqModelData[OBJ_PARTITION],NULL,NULL);
}
/*QUAKED misc_iraq_pottery (1 .5 0) (-8 -8 -9) (8 8 9) INVULNERABLE NOPUSH x x x x FLUFF
A knee high pot for storing dates and figs and such.
------ SPAWNFLAGS ------
INVULNERABLE - can't be damaged.
NOPUSH - can't be pushed
FLUFF - won't show if gl_pictip is set
*/
void SP_misc_iraq_pottery (edict_t *ent)
{
VectorSet (ent->mins, -8, -8, -9);
VectorSet (ent->maxs, 8, 8, 9);
SimpleModelInit2(ent,&iraqModelData[OBJ_POTTERY],NULL,NULL);
}
/*QUAKED misc_iraq_sprinkler (1 .5 0) (-7 -63 -2) (6 64 2) INVULNERABLE NOPUSH x x x x FLUFF
A six headed cattle sprinkler.
------ SPAWNFLAGS ------
INVULNERABLE - can't be damaged.
NOPUSH - N/A can't be pushed
FLUFF - won't show if gl_pictip is set
*/
void SP_misc_iraq_sprinkler (edict_t *ent)
{
VectorSet (ent->mins, -7, -63, -2);
VectorSet (ent->maxs, 6, 64, 2);
ent->spawnflags |= SF_NOPUSH; // Can't ever be pushed
SimpleModelInit2(ent,&iraqModelData[OBJ_SPRINKLER],NULL,NULL);
}
// kef 10/21/99 -- jersey needs the bbox smaller so Hawk can stand near it
//
// was (-285 -177 -54) (285 177 53)
//
/*QUAKED misc_iraq_stealth (1 .5 0) (-32 -32 -54) (32 32 53) INVULNERABLE NOPUSH x x x x FLUFF
A big stealth plane
------ SPAWNFLAGS ------
INVULNERABLE - N/A can't be damaged.
NOPUSH - N/A can't be pushed
FLUFF - won't show if gl_pictip is set
*/
void SP_misc_iraq_stealth (edict_t *ent)
{
VectorSet (ent->mins, -32, -32, -54);
VectorSet (ent->maxs, 32, 32, 53);
ent->spawnflags |= SF_INVULNERABLE;
ent->s.angles[YAW] = 270;
SimpleModelInit2(ent,&iraqModelData[OBJ_STEALTH],NULL,NULL);
}
/*QUAKED misc_iraq_tree_palm (1 .5 0) (-30 -9 -67) (-6 23 67) INVULNERABLE NOPUSH x x x x FLUFF
A tall palm tree
------ SPAWNFLAGS ------
INVULNERABLE - can't be damaged.
NOPUSH - N/A, can't ever be pushed
FLUFF - won't show if gl_pictip is set
hey, designers! you need to put a clip brush around this joker cuz it defies physics. tree is non-solid, too.
*/
void SP_misc_iraq_tree_palm (edict_t *ent)
{
// VectorSet (ent->mins, -65, -47, -67);
// VectorSet (ent->maxs, 18, 69, 67);
VectorSet (ent->mins, -30, -9, -67);
VectorSet (ent->maxs, -6, 23, 67);
ent->spawnflags |= SF_NOPUSH; // Can't ever be pushed
SimpleModelInit2(ent,&iraqModelData[OBJ_TREE_PALM],NULL,NULL);
ent->solid = SOLID_NOT;
// ent->think = drawthink;
// ent->nextthink = level.time + .1;
}
/*QUAKED misc_generic_sprinkler (1 .5 0) (-4 -4 -4) (4 4 4) INVULNERABLE NOPUSH x x x x FLUFF
A ceiling water sprinkler
DO NOT USE YET!
*/
void SP_misc_generic_sprinkler (edict_t *ent)
{
VectorSet (ent->mins, -4, -4, -4);
VectorSet (ent->maxs, 4, 4, 4);
ent->surfaceType = SURF_STONE_WHITE;
ent->health = 10;
ent->spawnflags |= SF_NOPUSH;
game_ghoul.SetSimpleGhoulModel (ent,"objects/generic/urn","urn");
SimpleModelInit(ent,SOLID_BBOX);
fxRunner.execContinualEffect("environ/sprinkler", ent);
}
valveCallback theValveCallback;
bool valveCallback::Execute(IGhoulInst *me,void *ent,float time,const void *matrix)
{
edict_t* self = (edict_t*)ent;
self->ghoulInst->Pause(level.time);
self->s.sound = 0;
return true;
}
// sadly, I just copied these from g_func.cpp rather than take the 20 or 30 hours
//to figure out how to #include them in a header somewhere
#define STATE_TOP 0
#define STATE_BOTTOM 1
#define STATE_UP 2
#define STATE_DOWN 3
void valve_use_portcullis (edict_t *ent, edict_t *other, edict_t *activator)
{
// based on the moveinfo.state of 'other', either turn the valve clockwise, ccw, or stop its turning
switch(other->moveinfo.state)
{
case STATE_TOP:
case STATE_BOTTOM: // stop
ent->avelocity[0] = 0.0;
break;
case STATE_UP: // cw
ent->avelocity[0] = 40.0;
break;
case STATE_DOWN: // ccw
ent->avelocity[0] = -40.0;
break;
default: // stop
ent->avelocity[0] = 0.0;
break;
}
gi.linkentity(ent);
}
void iraq_valve_use (edict_t *ent, edict_t *other, edict_t *activator)
{
ggObjC *simpObj;
GhoulID simpSeq;
ggOinstC* myInstance;
GhoulID tempNote=0;
if (!ent->ghoulInst)
{
return;
}
if (ent->spawnflags & VALVE_PORTCULLIS)
{
valve_use_portcullis(ent, other, activator);
return;
}
else
{
gi.sound(ent, CHAN_VOICE, gi.soundindex("Ambient/Models/Valve/ValveTurn.wav"), .6, ATTN_NORM, 0);
}
simpObj = game_ghoul.FindObject(ent->ghoulInst->GetGhoulObject());
if (!simpObj)
{
return;
}
//changed this to false, can't cache new seqs in after instances are created --ss
simpSeq = simpObj->FindSequence(iraqModelData[OBJ_VALVE].file);
if (!simpSeq)
{
return;
}
myInstance = simpObj->FindOInst(ent->ghoulInst);
if (!myInstance)
{
return;
}
// Play turning sequence
myInstance->PlaySequence(simpSeq, level.time);
// Setup stop frame when done playing sequence
tempNote = simpObj->GetMyObject()->FindNoteToken("EOS");
if (tempNote)
{
ent->ghoulInst->AddNoteCallBack(&theValveCallback,tempNote);
}
}
/*QUAKED misc_iraq_valve (1 .5 0) (-12 -3 -10) (12 1 11) INVULNERABLE NOPUSH x x x x FLUFF PORTCULLIS
A circular valve that will spin when used.
------ SPAWNFLAGS ------
INVULNERABLE - N/A, can't ever be damaged.
NOPUSH - N/A, can't ever be pushed
FLUFF - won't show if gl_pictip is set
PORTCULLIS - used by a func_door_portcullis
*/
void SP_misc_iraq_valve (edict_t *ent)
{
VectorSet (ent->mins, -12, -3, -10);
VectorSet (ent->maxs, 12, 1, 11);
ent->spawnflags |= SF_INVULNERABLE;
ent->spawnflags |= SF_NOPUSH; // Can't ever be pushed
SimpleModelInit2(ent,&iraqModelData[OBJ_VALVE],NULL,NULL);
ent->ghoulInst->Pause(level.time);
ent->movetype = MOVETYPE_DAN;
ent->gravity = 0.0;
ent->use = iraq_valve_use;
gi.soundindex("Ambient/Models/Valve/ValveTurn.wav");
}