kingpin-sdk/gamesrc/ep_skidrow.c

2944 lines
75 KiB
C
Raw Permalink Normal View History

2000-03-27 00:00:00 +00:00
/******************************************************************************
SKIDROW - Episode specific code
*******************************************************************************/
#include "g_local.h"
#include "voice_punk.h"
#include "voice_bitch.h"
void Pull_Alarm_Think (edict_t *ent);
qboolean EP_Skidrow_ProcessMagicJ( edict_t *self, edict_t *other, cast_memory_t *mem );
qboolean ProcessMomo (edict_t *self, edict_t *other);
void EP_skidrow_radio_on (edict_t *self);
void Resp_Lenny (edict_t *self, edict_t *other, response_t response);
//............................................................................
// This gets called whenever a character (player or AI) is sighted by an AI character
// in the Skidrow episode
// Returns TRUE if no further processing should take place in AI_RecordSighting()
qboolean EP_Skidrow_CastSight ( edict_t *self, edict_t *other, cast_memory_t *mem )
{
// Jesus (SR4 boss), if player gets battery, go into Psycho mode
if (self->name_index == NAME_JESUS && other->client && !(self->cast_info.aiflags & AI_NO_TAKE_COVER))
{
static int battery_index;
if (!battery_index)
battery_index = 1 + ITEM_INDEX(FindItem("Battery"));
if (other->client->pers.inventory[battery_index - 1])
{ // go into Psycho mode
self->cast_info.aiflags |= AI_NO_TAKE_COVER;
// gi.dprintf( "SOUND TODO: Leave that battery alone muthafucka!!\n" );
Voice_Specific (self, other, sr_jesus, 16);
// release if currently hiding
self->combat_goalent = NULL;
self->cast_info.aiflags &= ~AI_TAKE_COVER;
self->dont_takecover_time = 99999;
}
return false;
}
if (self->name_index == NAME_RUMMY || self->name_index == NAME_NICK || self->name_index == NAME_ED)
{
if (self->name_index == NAME_RUMMY && other->client)
{
other->episode_flags &= ~EP_SKIDROW_RUMMY_ASKED_WINE;
}
if (other->client && (mem->memory_type == MEMORY_TYPE_ENEMY) && !(other->client->pers.weapon))
{ // give them a chance to make friends if they holster
self->enemy = NULL;
// make them a neutral instead of enemy
AI_RemoveFromMemory( self, mem );
AI_AddToMemory( self, mem, MEMORY_TYPE_NEUTRAL );
mem->flags &= ~MEMORY_HOSTILE_ENEMY;
}
// ignore them
return true;
}
// Ridah, 5-8-99, added this so Momo asks you for the money if he hasn't seen you for a while
if (self->name_index == NAME_MOMO && other->client)
{
if (mem->timestamp < (level.time - 8))
{ // haven't seen them for a while
other->episode_flags &= ~EP_SKIDROW_MOMO_ASKED_MONEY;
// mem->flags &= ~MEMORY_LASTWARNING;
}
if ((mem->memory_type == MEMORY_TYPE_ENEMY) /*&& !other->client->pers.weapon*/)
{ // give them a chance to make friends if they holster
self->enemy = NULL;
// make them a neutral instead of enemy
AI_RemoveFromMemory( self, mem );
AI_AddToMemory( self, mem, MEMORY_TYPE_NEUTRAL );
mem->flags &= ~MEMORY_HOSTILE_ENEMY;
}
return true;
}
// Hack, don't let Mona talk, or it'll probably sound too "feminin"
if (self->name_index == NAME_MONA)
{
self->cast_info.aiflags |= AI_NO_TALK;
}
// Ridah, if listening to the radio, ignore player unless he's really close
if ( ( (self->name_index == NAME_BERNIE)
|| (self->name_index == NAME_ARNOLD))
&& (other->client)
&& (self->goal_ent && self->goal_ent->think == EP_skidrow_radio_on))
{
if (self->enemy)
{
self->goal_ent = NULL;
return false;
}
if (other->current_territory != self->cast_group || VectorDistance(self->s.origin, other->s.origin) > AI_NOT_HOLSTERED_RANGE_2)
{
// Ignore them
return true;
}
else
{
if (VectorDistance (self->s.origin, other->s.origin) > AI_NOT_HOLSTERED_RANGE_1)
{
// Dont get mad yet
return true;
}
else
{
// too close waist em
AI_MakeEnemy( self, other, 0 );
AI_StartAttack( self, other );
self->goal_ent = NULL;
return false;
}
}
}
if (self->name_index == NAME_LAMONT)
{
float dist;
if (self->enemy) // currently attacking
{
self->cast_info.aiflags |= AI_NO_TALK;
return false;
}
else
{
self->cast_info.aiflags &= ~AI_NO_TALK;
}
dist = VectorDistance(self->s.origin, other->s.origin);
self->cast_info.aiflags |= AI_FASTWALK;
// check if player has entered range 1
if (other->client)
{
if (dist < AI_NOT_HOLSTERED_RANGE_1)
{
if (mem->inc < 10)
{ // we've come from outside the range
if (mem->inc < 4)
mem->inc++;
mem->inc += 10; // signify that we are now inside the range
}
}
else
{
if (mem->inc >= 10)
{ // just left the range 1
mem->inc -= 10;
}
}
}
else if (VectorDistance( self->s.origin, g_edicts[1].s.origin ) < AI_NOT_HOLSTERED_RANGE_1)
{ // talk to the player since they're close by
return false;
}
// now talk if we're standing around
if ( (self->last_talk_time < (level.time - 3))
&& ( (self->cast_info.currentmove->frame->aifunc == ai_stand)
|| (other->client && dist < AI_NOT_HOLSTERED_RANGE_1/2)))
{ // Lamont's a nut case..
if (dist < AI_NOT_HOLSTERED_RANGE_1/2)
self->cast_info.pausetime = level.time + 2;
if (other->client && (dist < AI_NOT_HOLSTERED_RANGE_1)) // talk shit to player
{
// client is close, act hostile
if (mem->inc%10 >= 4)
{ // attack
AI_MakeEnemy( self, other, 0 );
Voice_Specific( self, other, lamont_random, 14 );
}
if ( (lamont_random[10 + mem->inc%10].last_played < (level.time - 10))
|| (lamont_random[10 + mem->inc%10].last_played > level.time))
{
Voice_Specific( self, other, lamont_random, 10 + mem->inc%10 );
}
else // randomly abuse player, and go on about Lenny
{
Voice_Random( self, other, &lamont_random[6], 7 );
}
}
else if (!(other->client))
{
Voice_Random( self, other, lamont_random, 6 );
}
else // they are a client, but a good distance away
{
Voice_Random( self, other, &lamont_random[0], 9 );
}
if ((dist < AI_NOT_HOLSTERED_RANGE_1) && !directly_infront( self, other))
self->cast_info.avoid( self, other, true );
else
self->cast_info.talk( self );
// pick a random path_corner to go to next
if (self->goal_ent && self->goal_ent->target)
{
edict_t *trav=NULL;
int i;
i = rand()%4;
while (i-- && self->goal_ent->target && (trav = G_PickTarget(self->goal_ent->target)))
{
self->goal_ent = trav;
}
self->goal_ent->wait = 1 + rand()%4;
}
}
if (self->goal_ent && !self->goal_ent->wait)
self->goal_ent->wait = 1 + rand()%4;
return false;
}
// Ridah, play Beth's special "backoff"
if ( self->name_index == NAME_BETH && other->client && (self->last_talk_time < (level.time - 3)) )
{
if ( (!(other->client->pers.holsteredweapon))
&& (other->client->pers.weapon)
&& (!(mem->flags & MEMORY_WARNED_BACKOFF)))
{
float dist;
dist = VectorDistance( self->s.origin, other->s.origin );
if (dist < AI_NOT_HOLSTERED_RANGE_2)
{
mem->flags |= MEMORY_WARNED_BACKOFF;
Voice_Random(self, other, &beth_specific[7], 2);
}
}
}
if ( self->name_index == NAME_MAGICJ && other->client)
{
if ( !(other->client->pers.holsteredweapon) )
{
mem->flags |= MEMORY_AFRAID;
}
else
{
self->cast_info.aiflags &= ~AI_NO_TALK;
mem->flags &= ~MEMORY_AFRAID;
}
return EP_Skidrow_ProcessMagicJ (self, other, mem);
}
if ( self->cast_group == GANG_RATGANG )
{
cast_memory_t *mem;
mem = level.global_cast_memory[ self->character_index ][ other->character_index ];
if (other->client && !(other->episode_flags & EP_SKIDROW_RATS_PISSED))
{
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_RATS_PISSED);
}
if (mem->flags & MEMORY_TAUNT && last_client_talk > level.time)
{
mem->flags &= ~MEMORY_TAUNT;
Voice_Random(self, self->cast_info.talk_ent, profanity_level2, NUM_PROFANITY_LEVEL2);
last_client_talk = level.time + 3 + rand()%10;
self->cast_info.currentmove = self->cast_info.move_stand;
}
}
return false;
}
//............................................................................
// EP_Skidrow_CastUse
// Called when ever a character is "used" (like when someone dies)
qboolean EP_Skidrow_CastUse (edict_t *self, edict_t *other, edict_t *activator)
{
if ((other->name_index == NAME_LOUIE) && (other->health <= 0))
{ // Louie has been killed, so walk to him
self->goal_ent = other;
self->target = NULL;
other->cast_info.aiflags |= AI_GOAL_RUN; // Run to him
// gi.dprintf( "Louie has been killed, sending Al in to investigate\n" );
return true;
}
return false;
}
//............................................................................
// EP_Skidrow_EventSpeech
// Called on speech occasions (including flashlight hitting player)
//
// Return TRUE so that the normal speech routines don't say something as well
qboolean EP_Skidrow_EventSpeech (edict_t *self, edict_t *other, int saywhat)
{
cast_memory_t *mem;
mem = level.global_cast_memory[ self->character_index ][ other->character_index ];
//............................................................................
// LAMONT
if ( self->name_index == NAME_LAMONT )
{ // Lamont speech done in EP_CastSight()
return true;
}
// Hack, record that we've been to the Bar
if (other->client && level.bar_lvl)
{
// other->client->pers.episode_flags = other->episode_flags |= EP_BAR_FIRST_TIME;
EP_Skidrow_Register_EPFLAG (other, EP_BAR_FIRST_TIME);
}
switch (saywhat)
{
case say_neutral:
if (self->name_index == NAME_RUMMY && other->client)
{
if (other->episode_flags & EP_SKIDROW_RUMMY_GAVE_WINE)
{
Voice_Random (self, other, &rummy[14], 2);
return true;
}
if (!(other->episode_flags & EP_SKIDROW_TALKED_TO_RUMMY) && !(self->episode_flags & EP_SKIDROW_RUMMY_GAVE_WINE))
{
mem = level.global_cast_memory[ self->character_index ][ other->character_index ];
Voice_Random (self, other, &rummy[8], 2);
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_TALKED_TO_RUMMY);
mem->response = Resp_Rummy_GotWine;
return true;
}
else if (!(other->episode_flags & EP_SKIDROW_RUMMY_ASKED_WINE) && !(self->episode_flags & EP_SKIDROW_RUMMY_GAVE_WINE))
{
if (mem = level.global_cast_memory[ self->character_index ][ other->character_index ])
{
Voice_Random (self, other, &rummy[8], 2);
// other->episode_flags |= EP_SKIDROW_RUMMY_ASKED_WINE;
// other->client->pers.episode_flags |= EP_SKIDROW_RUMMY_ASKED_WINE;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_RUMMY_ASKED_WINE);
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_TALKED_TO_RUMMY);
mem->response = Resp_Rummy_GotWine;
return true;
}
}
// have they responded yet?
else if ( (other->response_ent == self)
&& (other->last_response_time > (level.time - 5)))
{
if (other->last_response == resp_yes)
{
int index;
gitem_t *item;
Voice_Random ( self, other, &rummy[4], 2 );
// gi.dprintf ("Rummy: the combination is 36 26 36 ... \n");
item = FindItem ("Whiskey");
index = ITEM_INDEX (item);
other->client->pers.inventory[ index ] = 0;
// show icon and name on status bar
other->client->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(item->icon);
other->client->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS+index;
other->client->pickup_msg_time = level.time + 5.5;
// other->episode_flags |= EP_SKIDROW_RUMMY_GAVE_WINE;
// other->client->pers.episode_flags |= EP_SKIDROW_RUMMY_GAVE_WINE;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_RUMMY_GAVE_WINE);
{
edict_t *e;
int i;
for (i=1, e=g_edicts+i ; i < globals.num_edicts ; i++,e++)
{
if ((e->targetname) && (!strcmp(e->targetname, "safedoor_sr")))
{
// Unlock target door
if (e->key == -1)
{
e->key = 0;
e->targetname = NULL;
}
}
}
}
}
else
{
Voice_Random (self, other, &rummy[10], 2);
mem->response = Resp_Rummy_GotWine;
}
if (mem = level.global_cast_memory[ self->character_index ][ other->character_index ])
mem->response = NULL;
other->response_ent = NULL;
return true;
}
// ask for wine
else if ( (specific[4].last_played < (level.time - 3))
&& (specific[9].last_played < (level.time - 4)))
{
Voice_Random ( self, other, &rummy[8], 2 );
if (mem = level.global_cast_memory[ self->character_index ][ other->character_index ])
mem->response = Resp_Rummy_GotWine;
return true;
}
else
{
Voice_Random ( self, other, &rummy[12], 2);
return true;
}
return true;
}
if (self->name_index == NAME_NICK && other->client)
{
if (!(other->episode_flags & EP_SKIDROW_NICK_TOLD_BIKE))
{
Voice_Specific (self, other, nick, 6);
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_NICK_TOLD_BIKE);
return true;
}
if (!(other->episode_flags & EP_SKIDROW_NICK_WARNING_1))
{
Voice_Specific (self, other, nick, 0);
// other->client->pers.episode_flags = other->episode_flags |= EP_SKIDROW_JOSEPH_WARNING_1;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_NICK_WARNING_1);
}
else if (!(other->episode_flags & EP_SKIDROW_NICK_WARNING_2))
{
Voice_Random (self, other, &nick[1], 2);
// other->client->pers.episode_flags = other->episode_flags |= EP_SKIDROW_JOSEPH_WARNING_2;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_NICK_WARNING_2);
}
else if (!(other->episode_flags & EP_SKIDROW_NICK_WARNING_3))
{
Voice_Random (self, other, &nick[3], 2);
// other->client->pers.episode_flags = other->episode_flags |= EP_SKIDROW_JOSEPH_WARNING_3;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_NICK_WARNING_3);
}
else
{
Voice_Specific( self, other, nick, 5 );
other->client->pers.episode_flags = other->episode_flags &= ~EP_SKIDROW_NICK_WARNING_1;
other->client->pers.episode_flags = other->episode_flags &= ~EP_SKIDROW_NICK_WARNING_2;
other->client->pers.episode_flags = other->episode_flags &= ~EP_SKIDROW_NICK_WARNING_3;
}
return true;
}
if (self->name_index == NAME_ED && other->client)
{
Voice_Random (self, other, rummy, 4);
return true;
}
if (self->name_index == NAME_LENNY && other->client)
{
self->cast_info.aiflags |= AI_REPEAT_TALK_JESTURE;
// Have they got the watch?
if ((other->client->pers.inventory[ITEM_INDEX(FindItem("Watch"))]) ||
(other->episode_flags & EP_SKIDROW_LENNY_TOOK_WATCH))
{ // got the watch..
if (!(other->client->pers.inventory[ITEM_INDEX(FindItem("StoreRoomKey"))]))
{ // Lenny hasn't given the key yet..
if (mem->inc != 199) // we haven't praised them yet
{
if (other->client->pers.episode_flags & EP_TALKED_TO_LENNY)
{
Voice_Specific( self, other, lenny_table, 1 ); // that's great!
self->last_talk_time -= TALK_SELF_DELAY - 1.5; // only wait 1.5 before we speak again, regardless of whether they respond or not
other->last_talk_time = self->last_talk_time - 1; // must have this so we don't think they've said something after us as a result of the above hack
}
else
{
Voice_Specific( self, other, lenny_table, 0 ); // christ, that's great!
self->last_talk_time -= TALK_SELF_DELAY - 4.5; // wait 4.5 seconds
other->last_talk_time = self->last_talk_time - 1; // must have this so we don't think they've said something after us as a result of the above hack
}
mem->inc = 199;
}
else // give them the watch
{
int index;
gitem_t *item;
// Lenny takes the watch
item = FindItem ("Watch");
index = ITEM_INDEX (item);
other->client->pers.inventory[ index ] = 0;
// other->episode_flags |= EP_SKIDROW_LENNY_TOOK_WATCH;
// other->client->pers.episode_flags |= EP_SKIDROW_LENNY_TOOK_WATCH;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_LENNY_TOOK_WATCH);
// Lenny gives player the key
Voice_Specific( self, other, lenny_table, 2 ); // here's the key
item = FindItem ("StoreRoomKey");
index = ITEM_INDEX (item);
other->client->pers.inventory[ index ]++;
// show icon and name on status bar
other->client->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(item->icon);
other->client->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS+index;
other->client->pickup_msg_time = level.time + 5.5;
mem->inc = 0;
}
}
else // given them the watch, just chat
{
if (!mem->inc)
{
Voice_Specific( self, other, lenny_table, 14 );
mem->inc = 1;
}
else if (mem->inc == 1)
{ // thanks again
Voice_Random( self, other, &lenny_table[14], 2 );
mem->inc = 2;
}
else if (mem->inc == 2)
{ // you'd better leave now
Voice_Specific( self, other, lenny_table, 13 );
self->last_talk_time += 5; // this is a long one, give us more time to say it all
mem->inc = 3;
}
else // random stuff
{
Voice_Random( self, other, &lenny_table[10], 3 );
if (mem->inc++ > 4)
mem->inc = 1; /// thank them again
}
}
mem->response = Resp_Lenny;
return true;
}
// if we've cussed him, act hostile back
else if (other->response_ent == self && other->last_response == resp_no)
{
Voice_Random( self, other, &lenny_table[17], 3 );
other->response_ent = NULL; // get over it
}
// talked to them yet?
else if (other->client->pers.episode_flags & EP_TALKED_TO_LENNY)
{
// random chat, we've already asked them about Lamont
if (self->last_talk_time < (level.time - 15)) // haven't spoken for a while, they must have left and come back
{
Voice_Random( self, other, &lenny_table[22], 3 );
}
else if (mem->inc > 4)
{ // been here too long
Voice_Specific( self, other, lenny_table, 13 );
self->last_talk_time += 3; // this is a long one, give us more time to say it all
mem->inc = 0;
}
else
{
Voice_Random( self, other, &lenny_table[4], 9 );
mem->inc++;
}
mem->response = Resp_Lenny;
return true;
}
// first greeting
else
{
if (mem->inc == 0)
{ // hey you're that dude
Voice_Specific( self, other, lenny_table, 3 );
self->last_talk_time -= TALK_SELF_DELAY - 5;
other->last_talk_time = self->last_talk_time - 1; // must have this so we don't think they've said something after us as a result of the above hack
mem->inc++;
}
else if (mem->inc == 1)
{ // jesus
Voice_Specific( self, other, lenny_table, 17 );
self->last_talk_time -= TALK_SELF_DELAY - 2;
other->last_talk_time = self->last_talk_time - 1; // must have this so we don't think they've said something after us as a result of the above hack
mem->inc++;
}
else
{
Voice_Specific( self, other, lenny_table, 4 ); // go kill lamont for me
// other->client->pers.episode_flags = other->episode_flags |= EP_TALKED_TO_LENNY;
self->last_talk_time -= TALK_SELF_DELAY - 3;
other->last_talk_time = self->last_talk_time - 1; // must have this so we don't think they've said something after us as a result of the above hack
mem->inc = 0;
EP_Skidrow_Register_EPFLAG (other, EP_TALKED_TO_LENNY);
}
mem->response = Resp_Lenny;
return true;
}
}
//............................................................................
// LISA
// note to self:
// this will ensure that she keeps the same tone of voice
if ( self->name_index == NAME_LISA && other->client)/* && !other->client->pers.inventory[ITEM_INDEX(FindItem("Pistol"))])*/
{
int index;
// int rval;
edict_t *Igmo;
index = ITEM_INDEX (FindItem ("Pistol"));
Igmo = EP_GetCharacter( NAME_IGMO );
// check to see if the player has a pistol
if (!Igmo)
{
// gi.dprintf ("SOUND TODO: Shit... your one bad ass Dude!\n");
Voice_Specific (self, other, mona_specific, 13);
}
else if (other->client->pers.inventory [index])
{
Voice_Random (self, other, &lisa_specific[5], 3); // Ridah, NOTE! new method of playing specific sounds, without repeating one's self
}
else if (other->client->pers.episode_flags & EP_PAWNOMATIC_FIRST_TIME)
{
Voice_Random (self, other, &lisa_specific[2], 6);
}
else
Voice_Random(self, other, lisa_specific, 8);
return true;
}
//............................................................................
// BETH
else if ( self->name_index == NAME_BETH && other->client)
{
if (other->client->pers.episode_flags & EP_SKIDROW_GOT_COIL)
{
Voice_Random (self, other, &beth_specific[4] , 3);
}
else
{
Voice_Random(self, other, beth_specific, 6);
}
return true;
}
//............................................................................
// MONA
// JOSEPH 19-MAR-99
else if ( self->name_index == NAME_MONA && other->client)
{
edict_t *Lamont;
Lamont = EP_GetCharacter( NAME_LAMONT );
self->cast_info.aiflags &= ~AI_NO_TALK;
if (Lamont && !(other->episode_flags & EP_SKIDROW_MONA_FIRST_TIME))
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_MONA_FIRST_TIME);
// If the player has killed Lamont
if ((!Lamont || Lamont->health <= 0))
{
if (!(other->client->pers.episode_flags & EP_TALKED_TO_LENNY) && rand()%2)
Voice_Random (self, other, &mona_specific[0], 4); // make sure they know about Lenny in the bar
else
Voice_Random (self, other, &mona_specific[13], 2); // you're one bad ass mofo
}
// If the player hasn't visited the bar
else if (!(other->client->pers.episode_flags & EP_BAR_FIRST_TIME))
{
Voice_Random (self, other, &mona_specific[0], 8);
}
// If the player hasn't talked to lenny
else if (!(other->client->pers.episode_flags & EP_TALKED_TO_LENNY))
{
Voice_Random (self, other, &mona_specific[10], 3);
}
else
{
Voice_Random (self, other, &mona_specific[4], 6);
}
self->cast_info.aiflags |= AI_NO_TALK;
return true;
}
// END JOSEPH
//............................................................................
// MAGICJ
if ( (self->name_index == NAME_MAGICJ)
&& (other->client))
{
if (other->episode_flags & EP_SKIDROW_MAGICJ_GAVE_DOLLAR)
{
Voice_Random ( self, other, mj_random, 4);
return true;
}
if (!(other->episode_flags & EP_SKIDROW_MAGICJ_ASKED_DOLLAR))
{
if (mem = level.global_cast_memory[ self->character_index ][ other->character_index ])
{
Voice_Specific( self, other, specific, 4 );
// other->episode_flags |= EP_SKIDROW_MAGICJ_ASKED_DOLLAR;
// other->client->pers.episode_flags |= EP_SKIDROW_MAGICJ_ASKED_DOLLAR;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_MAGICJ_ASKED_DOLLAR);
mem->response = Resp_MagicJ_GotDollar;
return true;
}
}
// have they responded yet?
else if ( (other->response_ent == self)
&& (other->last_response_time > (level.time - 5)))
{
if (other->last_response == resp_yes)
{ // give the crow bar to the player
int index;
gitem_t *item;
Voice_Specific( self, other, specific, 7 );
item = FindItem ("Crowbar");
index = ITEM_INDEX (item);
other->client->pers.inventory[ index ]++;
// show icon and name on status bar
other->client->ps.stats[STAT_PICKUP_ICON] = gi.imageindex(item->icon);
other->client->ps.stats[STAT_PICKUP_STRING] = CS_ITEMS+index;
other->client->pickup_msg_time = level.time + 5.5;
// other->episode_flags |= EP_SKIDROW_MAGICJ_GAVE_DOLLAR;
// other->client->pers.episode_flags |= EP_SKIDROW_MAGICJ_GAVE_DOLLAR;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_MAGICJ_GAVE_DOLLAR);
}
else
{
Voice_Specific( self, other, specific, 8 );
}
if (mem = level.global_cast_memory[ self->character_index ][ other->character_index ])
mem->response = NULL;
other->response_ent = NULL;
return true;
}
// randomly ask them about the iron bar
else if ( (specific[4].last_played < (level.time - 30))
&& (specific[9].last_played < (level.time - 40)))
{
Voice_Specific( self, other, specific, 9 );
if (mem = level.global_cast_memory[ self->character_index ][ other->character_index ])
mem->response = Resp_MagicJ_GotDollar;
return true;
}
else
{
Voice_Random ( self, other, mj_random, 4);
return true;
}
}
// END JOSEPH
//............................................................................
// LEROY -> BETTY
if ( (self->name_index == NAME_LEROY)
&& (other->name_index == NAME_BETTY))
{
Voice_Random(self, self->cast_info.talk_ent, neutral_converse_to_female, NUM_NEUTRAL_CONVERSE_TO_FEMALE);
return true;
}
//............................................................................
// BUSTER -> JED (doors.bsp scripting test)
if ( (self->name_index == NAME_BUSTER)
&& (other->name_index == NAME_JED))
{
mem = level.global_cast_memory[self->character_index][other->character_index];
if (mem->inc++ > 2)
{ // time to bury them
Voice_Specific(self, other, profanity_level2, 14 );
AI_MakeEnemy( self, other, 0 );
return true;
}
if (mem->inc == 1)
Voice_Specific(self, other, profanity_level2, 7 );
else if (mem->inc == 2)
Voice_Specific(self, other, profanity_level2, 17 );
else if (mem->inc == 3)
Voice_Specific(self, other, profanity_level2, 11 );
// pretend he's going to respond soon, so we don't wait so long
other->last_talk_time = level.time + 2;
return true;
}
// JOSEPH 13-FEB-99
//............................................................................
// MOMO
if ( (self->name_index == NAME_MOMO)
&& (other->client))
{
return (ProcessMomo (self, other));
}
// END JOSEPH
break;
case say_hostile:
if (self->name_index == NAME_ED && other->client)
{
Voice_Random (self, other, rummy, 4);
return true;
}
if ( self->name_index == NAME_BETH && other->client)
{
// Rafael: we need more negative sounds
if (rand()%100 > 75)
Voice_Random (self, other, &f_fightsounds[0],3);
else
Voice_Specific (self, other, beth_specific, 7);
return true;
}
//............................................................................
// MONA
// JOSEPH 19-MAR-99
if ( self->name_index == NAME_MONA && other->client)
{
{
edict_t *Lamont;
Lamont = EP_GetCharacter( NAME_LAMONT );
if (Lamont && !(other->episode_flags & EP_SKIDROW_MONA_FIRST_TIME))
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_MONA_FIRST_TIME);
}
self->cast_info.aiflags &= ~AI_NO_TALK;
if (other->client->ps.stats[STAT_HUD_SELF_TALK] == TT_POSITIVE)
{
mem = level.global_cast_memory [self->character_index][other->character_index];
mem->flags &= ~MEMORY_ASSHOLE;
Voice_Random (self, other, &mona_specific[0], 8);
return true;
}
else
{
Voice_Random (self, other, &mona_specific[15], 5);
}
self->cast_info.aiflags |= AI_NO_TALK;
return true;
}
// END JOSEPH
if ( (self->name_index == NAME_MAGICJ)
&& (other->client))
{
if (other->client->ps.stats[STAT_HUD_SELF_TALK] == TT_POSITIVE)
{
mem = level.global_cast_memory [self->character_index][other->character_index];
mem->flags &= ~MEMORY_ASSHOLE;
Voice_Random ( self, other, mj_random, 4);
return true;
}
else
{
if ((rand()%10) < 4)
Voice_Specific (self, other, specific, 29);
else
Voice_Random ( self, other, &specific[23], 2);
return true;
}
}
if ( (self->name_index == NAME_RUMMY || self->name_index == NAME_NICK)
&& (other->client))
{
if (other->client->ps.stats[STAT_HUD_SELF_TALK] == TT_POSITIVE)
{
mem = level.global_cast_memory [self->character_index][other->character_index];
mem->flags &= ~MEMORY_ASSHOLE;
if (self->name_index == NAME_RUMMY)
Voice_Random (self, other, &rummy[12], 2);
else
{
if (!(other->episode_flags & EP_SKIDROW_NICK_TOLD_BIKE))
{
Voice_Specific (self, other, nick, 6);
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_NICK_TOLD_BIKE);
}
else
Voice_Random ( self, other, rummy, 3);
}
return true;
}
else
{
if (self->name_index == NAME_RUMMY)
Voice_Random (self, other, &rummy[12], 2);
else
{
if (!(other->episode_flags & EP_SKIDROW_NICK_TOLD_BIKE))
{
Voice_Specific (self, other, nick, 6);
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_NICK_TOLD_BIKE);
}
else
Voice_Random ( self, other, rummy, 3);
}
return true;
}
}
// JOSEPH 13-FEB-99
if (self->name_index == NAME_MOMO && other->client)
{
return (ProcessMomo (self, other));
}
// END JOSEPH
if ( ((self->name_index == NAME_BETTY) || (self->name_index == NAME_LEROY))
&& other->client)
{
edict_t *betty;
betty = EP_GetCharacter (NAME_BETTY);
if (!betty || betty->health < 0)
return false;
self->last_talk_time = level.time;
{
edict_t *leroy;
leroy = EP_GetCharacter (NAME_LEROY);
if (leroy && leroy->health > 0)
{
// return true; // never speak to player if leroy is there
float time_offset;
time_offset = 0.0;
mem = level.global_cast_memory[ leroy->character_index ][ other->character_index ];
if (mem->flags & MEMORY_LASTWARNING && directly_infront(other, self)) // they're looking at her
{
Voice_Random ( leroy, self->cast_info.talk_ent, &specific[16], 2);
// Voice_Specific(leroy, self->cast_info.talk_ent, specific, 16 + rand()%2); // die
AI_MakeEnemy(leroy, self->cast_info.talk_ent, 0);
}
else if (mem->flags & MEMORY_UPSET)
{
mem->flags |= MEMORY_LASTWARNING;
if (!specific[15].last_played || specific[15].last_played > level.time)
Voice_Specific ( leroy, other, specific, 15); // step off
else
Voice_Random ( leroy, other, &specific[12], 3);
time_offset = 10.0;
}
else if (mem->flags & MEMORY_ASSHOLE)
{
Voice_Random ( leroy, other, &specific[12], 3);
mem->flags |= MEMORY_UPSET;
time_offset = 3.0;
}
else
{
Voice_Random ( leroy, other, &specific[12], 3);
mem->flags |= MEMORY_ASSHOLE;
}
last_client_talk = level.time + 3 + time_offset;
// Ridah, turn to face them, or make a gesture
if (!infront( leroy, other ))
{
leroy->cast_info.avoid( leroy, other, true );
}
else
{
// make talking gesture if we're just standing around
if (leroy->cast_info.currentmove == leroy->cast_info.move_stand)
leroy->cast_info.talk(leroy);
}
}
else
{
return false;
}
}
return true;
}
// Ridah, not used anymore
/*
if (self->name_index == NAME_LEROY && other->client)
{
{
edict_t *betty;
static int rnd;
float time_offset;
time_offset = 0.0;
mem = level.global_cast_memory[ self->character_index ][ other->character_index ];
betty = EP_GetCharacter (NAME_BETTY);
if (betty && betty->health > 0)
{
if (VectorDistance( self->s.origin, betty->s.origin ) < 256)
{ // don't say anything just yet
// self->last_talk_time = level.time;
return true;
}
else
{
return false;
}
}
else
{
// is not on the map anymore
return false;
}
return true;
}
}
*/
break;
case say_flashlight:
// We put it in here so it only occurs if we aren't already angry at them
if (self->enemy != other)
{
cast_memory_t *mem, *premem;
// get the memory of this "other" character before we record the sighting
premem = level.global_cast_memory[self->character_index][other->character_index];
AI_RecordSighting(self, other, VectorDistance(self->s.origin, other->s.origin));
// get the post sighting memory
mem = level.global_cast_memory[self->character_index][other->character_index];
// if we recorded a new sighting (or hadn't seen them in a while), and they are hostile..
if ( (!premem || (premem->timestamp < (level.time - 10)))
&& (mem->flags & MEMORY_HOSTILE_ENEMY))
{
//gi.dprintf ("%s: there he is!\n", self->name); // Rafael: make sure you call the Voice routines, so they don't talk again for a bit
return true;
}
}
break;
// Ridah, this is a mess, we should just scan for names, and go from there
/*
case say_alisthatyou:
AI_RecordSighting(self, other, VectorDistance(self->s.origin, other->s.origin));
gi.dprintf ("%s: Al is that you?\n", self->classname);
break;
case say_behindthebarrel: break;
case say_forabuck: break;
case say_talktobetty:
if (self->name_index == NAME_LEROY)
{
Voice_Random(self, self->cast_info.talk_ent, neutral_converse_to_female, NUM_NEUTRAL_CONVERSE_TO_FEMALE);
return true;
}
break;
*/
}
return false;
}
//............................................................................
// EP_Skidrow_ItemPickup
// Called whenever an item is picked up
void EP_Skidrow_ItemPickup ( edict_t *self, edict_t *other )
{
if (!Q_strcasecmp( self->classname, "item_coil" ))
{
// other->client->pers.episode_flags |= EP_SKIDROW_GOT_COIL;
// other->episode_flags |= EP_SKIDROW_GOT_COIL;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_GOT_COIL);
}
// note to self
// for now they should just listen to the radio or wake up if they see the player
#if 0
edict_t /* *Al,*/ *Bernie, *Arnold, *radio ;
if (!Q_strcasecmp( self->classname, "item_coil" ))
{
other->episode_flags |= EP_SKIDROW_GOT_COIL;
//Al = EP_GetCharacter( NAME_AL );
Bernie = EP_GetCharacter( NAME_BERNIE );
if (/*Al &&*/ Bernie)
{
Bernie->cast_info.aiflags |= AI_GOAL_RUN; // So we run back to him
// send him to Bernie
//Al->goal_ent = Bernie; // this will make him walk to Bernie
// we then use the sight handler (above) to stop him
// when he gets close, and send them all to the 2nd door
}
else
{
//Al = EP_GetCharacter( NAME_AL );
Bernie = EP_GetCharacter( NAME_BERNIE );
Arnold = EP_GetCharacter( NAME_ARNOLD );
//if (Al)
// AI_MakeEnemy(Al, other, 0);
if (Bernie)
AI_MakeEnemy(Bernie, other, 0);
if (Arnold)
AI_MakeEnemy(Arnold, other, 0);
// gi.dprintf ("CHEATER: AL, Arnold, and Bernie made hostile\n");
}
// kill the radio
radio = G_Find( NULL, FOFS(classname), "misc_skidrow_radio" );
if (!radio)
{
gi.dprintf( "EP_Skidrow_CastSight: Can't find radio to turn off!!\n");
}
else
{
radio->think = NULL;
radio->nextthink = -1;
}
}
#endif
}
//............................................................................
// Special event-driven scripting. Usually called when a character reaches a
// path_corner_cast with the "scriptname" field set.
void EP_Skidrow_Script( edict_t *ent, char *scriptname )
{
edict_t *other;
//gi.dprintf( "Script '%s' called by %s\n", scriptname, ent->classname );
switch (ent->name_index)
{
//================================================================================================
// Test script using doors.bsp
case NAME_JED:
if (!strcmp( scriptname, "jed_script" ))
{
// Tell Jed to start evading Buster
ent->enemy = EP_GetCharacter( NAME_BUSTER );
AI_RecordSighting( ent, ent->enemy, VectorDistance( ent->s.origin, ent->enemy->s.origin ) );
ent->cast_info.currentmove = ent->cast_info.move_evade;
}
break;
case NAME_BUSTER:
if (!strcmp( scriptname, "buster_script" ))
{
// Stand here looking at Jed
other = EP_GetCharacter( NAME_JED );
AI_RecordSighting( ent, other, VectorDistance( ent->s.origin, other->s.origin ) );
ent->cast_info.avoid( ent, other, true );
ent->cast_info.talk_ent = other;
// find our mates and tell them to look at Jed also, but don't talk
{
int i;
for (i=0; i<level.num_characters; i++)
{
if (!level.characters[i])
continue;
if ( (level.characters[i] != ent)
&& (level.characters[i]->cast_group == ent->cast_group)
&& (VectorDistance( level.characters[i]->s.origin, ent->s.origin ) < 256))
{
AI_RecordSighting( level.characters[i], other, VectorDistance( level.characters[i]->s.origin, other->s.origin ) );
level.global_cast_memory[level.characters[i]->character_index][other->character_index]->flags |= MEMORY_NO_TALK;
level.characters[i]->cast_info.talk_ent = other;
level.characters[i]->cast_info.avoid( level.characters[i], other, true );
}
}
}
}
break;
#define SR1_INTRO 1
#if SR1_INTRO // out for demo
//================================================================================================
// SR1 intro
case NAME_TOUGHGUY1:
if (!strcmp( scriptname, "intro_script1" ))
{ // say something, do talking motion
ent->last_talk_time = level.time + 2;
ent->cast_info.talk( ent );
ent->cast_info.pausetime = level.time + 7;
}
else if (!strcmp( scriptname, "intro_script2" ))
{ // tell the other guy to come with us
ent->yaw_speed = 40;
other = EP_GetCharacter( NAME_TOUGHGUY2 );
other->last_talk_time = level.time + 2;
other->cast_info.talk( ent );
other->yaw_speed = 40;
other->leader = ent;
// ent->cast_info.aiflags |= AI_GOALENT_MANUAL_CLEAR;
other->cast_info.pausetime = level.time + 2;
}
break;
default:
if (!strcmp( scriptname, "intro_player_script1" ))
{ // go into death frame
static mframe_t frames[] = {
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
NULL, 0, NULL,
};
static mmove_t move = {725, 755, frames, NULL};
other = EP_GetCharacter( NAME_INTROGUY1 );
other->yaw_speed = 5;
other->s.frame = move.firstframe;
other->cast_info.currentmove = &move;
other->s.model_parts[PART_GUN].invisible_objects = 0xFF;
if (!(cl_parental_lock->value && !cl_parental_override->value))
{
// set pain skins
other->s.model_parts[PART_HEAD].skinnum[0] = other->s.model_parts[PART_HEAD].baseskin + 1;
other->s.model_parts[PART_BODY].skinnum[0] = other->s.model_parts[PART_BODY].baseskin + 1;
}
}
else if (!strcmp( scriptname, "intro_camera3" ))
{
void intro_player_standup( edict_t *self );
edict_t *thinker;
thinker = G_Spawn();
thinker->nextthink = level.time + 0.5;
thinker->think = intro_player_standup;
}
else if (!strcmp( scriptname, "intro_player_script1a" ))
{
// delete the tough guys
other = EP_GetCharacter( NAME_TOUGHGUY1 );
G_FreeEdict( other );
other = EP_GetCharacter( NAME_TOUGHGUY2 );
G_FreeEdict( other );
}
else if (!strcmp( scriptname, "intro_player_script2" ))
{ // we're at the corner, crouch down and grab the pipe
void intro_player_pickup_pipe( edict_t *self );
static mframe_t frames[] =
{
NULL, 0.000, NULL, // frame 0
NULL, 0.000, NULL, // frame 1
NULL, 0.000, NULL, // frame 2
NULL, 0.000, NULL, // frame 3
};
static mmove_t move = {570, 573, frames, intro_player_pickup_pipe};
ent->yaw_speed = 40;
// crouch down
ent->cast_info.currentmove = &move;
ent->s.frame = ent->cast_info.currentmove->firstframe;
ent->maxs[2] = DUCKING_MAX_Z;
// release the player from the camera
other = NULL;
while (other = G_Find( other, FOFS(classname), "misc_cutscene_trigger" ))
{
if (other->nextthink >= level.time && other->think)
{
other->wait = 2/FRAMETIME;
}
}
}
else if (!strcmp( scriptname, "intro_end" ))
{ // end of intro
other = EP_GetCharacter( NAME_INTROGUY1 );
G_FreeEdict( other );
}
break;
#endif
}
// Alarm
if (!strcmp( scriptname, "alarm" ))
{
// We need some assistance!
edict_t *marker;
// find the 2nd door ambush marker, tell all 3 guys to move to it
marker = G_Find( NULL, FOFS(classname), "misc_skidrow_ambush" );
if (!marker)
{
gi.dprintf( "EP_Skidrow_Script: Can't find ambush marker!!\n");
}
else
{
edict_t *plyr;
if (plyr = EP_GetCharacter( NAME_BERNIE ))
{
plyr->goal_ent = plyr->start_ent = marker;
plyr->guard_ent = NULL;
plyr->target = NULL; // stop guarding the radio area/patrolling
}
// if (plyr = EP_GetCharacter( NAME_AL ))
// plyr->goal_ent = marker;
if (plyr = EP_GetCharacter( NAME_ARNOLD ))
{
plyr->goal_ent = marker;
plyr->guard_ent = NULL;
plyr->target = NULL; // stop guarding the radio area/patrolling
}
}
// kill the radio
marker = G_Find( NULL, FOFS(classname), "misc_skidrow_radio" );
if (marker)
{
G_FreeEdict( marker );
}
}
}
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#if SR1_INTRO // out for demo
void intro_player_standup( edict_t *self )
{ // stand up
edict_t *trav, *other;
trav = G_Find( NULL, FOFS(targetname), "intro_player_corner1a" );
other = EP_GetCharacter( NAME_INTROGUY1 );
other->cast_info.currentmove = other->cast_info.move_stand_up;
other->s.frame = other->cast_info.currentmove->firstframe;
other->maxs[2] = other->cast_info.standing_max_z;
other->last_talk_time = level.time; // make talking jesture when standing
// head for the corner in a few seconds
other->goal_ent = trav;
other->cast_info.goal_ent_pausetime = level.time + 2.5; // pause for a bit
// other->maxs[2] = DUCKING_MAX_Z;
}
void intro_player_turnaround( edict_t *self )
{
edict_t *other;
//self->owner->cast_info.currentmove = self->owner->cast_info.move_stand_up;
//self->owner->maxs[2] = self->owner->cast_info.standing_max_z;
// turn to face alley
other = NULL;
while (other = G_Find( other, FOFS(targetname), "intro_corner1" ))
{
// if (VectorDistance(self->owner->s.origin, other->s.origin) < 384)
{
self->owner->goal_ent = other;
// self->owner->cast_info.goal_ent_pausetime = level.time + 0.5;
self->owner->goal_ent->cast_info.aiflags |= AI_GOALENT_MANUAL_CLEAR;
break;
}
}
G_FreeEdict( self );
}
void intro_player_pickup_pipe( edict_t *self )
{
edict_t *think;
// show the pipe
self->s.model_parts[PART_GUN].invisible_objects = 0x0;
// self->cast_info.currentmove = self->cast_info.move_crstand;
self->cast_info.currentmove = self->cast_info.move_stand_up;
self->maxs[2] = self->cast_info.standing_max_z;
think = G_Spawn();
think->nextthink = level.time + 0.7;
think->think = intro_player_turnaround;
think->owner = self;
}
#endif
qboolean EP_Skidrow_ProcessMagicJ( edict_t *self, edict_t *other, cast_memory_t *mem )
{
if ( (other->client)
&& (!(other->client->pers.holsteredweapon))
&& (mem->flags & MEMORY_AFRAID )
&& (other->client->pers.weapon) )
{
float dist;
dist = VectorDistance( self->s.origin, other->s.origin );
// if running, don't say or do anything
if (self->cast_info.currentmove->frame->aifunc == ai_run)
return true;
if ( (dist < AI_NOT_HOLSTERED_RANGE_1)
&& !(mem->flags & MEMORY_HOSTILE_ENEMY))
{
#define MAXCHOICES 8
edict_t *ent = NULL;
int num_choices = 0;
edict_t *choice[MAXCHOICES];
int rval;
float dist[MAXCHOICES];
while(1)
{
ent = G_Find (ent, FOFS(classname), "misc_skidrow_afraid");
if (!ent)
break;
if ((dist[num_choices] = VectorDistance( ent->s.origin, self->s.origin )) > 384)
choice[num_choices++] = ent;
if (num_choices == MAXCHOICES)
break;
}
if (!num_choices)
{
// gi.dprintf( "AI: can't find a misc_skidrow_afraid\n");
mem->flags &= ~MEMORY_AFRAID;
}
else if (self->groundentity)
{
// gi.dprintf( "AI: Going to misc_skidrow_afraid\n");
// rval = rand() % num_choices;
{
int i;
float olddist = 0;
for (i=0; i<num_choices; i++)
{
if (dist[i] > olddist)
{
rval = i;
olddist = dist[i];
}
}
}
if (!(choice[rval]->cast_info.aiflags & AI_GOAL_RUN))
// gi.sound(ent, CHAN_VOICE, gi.soundindex("actors/skidrow/magicj/fuckthat.wav"), 1, ATTN_NORM, 0);
Voice_Specific( self, other, specific, 25 );
choice[rval]->cast_info.aiflags |= AI_GOAL_RUN;
self->cast_info.aiflags |= AI_RUN_LIKE_HELL;
self->goal_ent = choice[rval];
self->cast_info.aiflags |= AI_GOAL_IGNOREENEMY;
self->cast_info.currentmove = self->cast_info.move_run;
}
}
else if (dist < AI_NOT_HOLSTERED_RANGE_2)
{
#define TIME_TO_COMPLY_OR_I_RUN 5.0
if (!(mem->flags & MEMORY_HOSTILE_ENEMY))
{
if ( (level.time > mem->not_holstered_attack_time)
&& (level.time < (mem->not_holstered_attack_time+5)))
{
// gi.dprintf ("stay away I'll fuck you up\n");
if (!(self->cast_info.aiflags & AI_NO_TALK))
{
self->cast_info.aiflags |= AI_NO_TALK;
if (rand()%3 == 0)
Voice_Specific( self, other, specific, 23 ); // fuck you up
else //if (rand()%3 == 1)
Voice_Specific( self, other, specific, 24 ); // fuck that
// else
// Voice_Specific( self, other, specific, 25 ); // be back
}
// Ridah, not sure what this was for, but it causes behavoural problem
// if (self->groundentity)
// self->cast_info.currentmove = self->cast_info.move_avoid_walk;
if (ai_debug_memory->value)
{
gi.dprintf("AI_RecordSighting: is cowering!\n");
}
}
else if (level.time > mem->not_holstered_attack_time)
{
if (!(other->client->pers.weapon->ammo))
Voice_Specific( self, other, specific, 22 ); // put that pipe down
else
Voice_Random( self, other, m_backoff, NUM_BACKOFF );
// give them some "time to comply"
mem->not_holstered_attack_time = level.time + TIME_TO_COMPLY_OR_I_RUN;
if (ai_debug_memory->value)
{
gi.dprintf("AI_RecordSighting: i'm about to run in %d seconds\n", (int) TIME_TO_COMPLY_OR_I_RUN);
}
// if we're standing around, turn to face them
if ( (self->cast_info.currentmove->frame->aifunc == ai_stand)
&& (self->cast_info.move_avoid_walk && self->cast_info.move_avoid_crwalk))
{
self->cast_info.avoid( self, other, true );
}
}
}
// if we're standing around, turn to face them
if (self->cast_info.currentmove->frame->aifunc == ai_stand)
{
vec3_t vec;
VectorSubtract( other->s.origin, self->s.origin, vec );
VectorNormalize( vec );
self->ideal_yaw = vectoyaw( vec );
M_ChangeYaw( self );
}
// evade?
if (self->cast_info.currentmove->frame->aifunc == ai_stand && self->cast_info.move_stand_evade && (self->moral < MORAL_AGGRESSIVE))
{
self->cast_info.currentmove = self->cast_info.move_stand_evade;
self->last_stand_evade = level.time;
}
}
/*
else if (dist < AI_NOT_HOLSTERED_RANGE_3)
{ // if walking, ignore, if running, turn to face them, ready for attack if they get within range
if (VectorLength( other->velocity ) > 210)
{ // running
// if we're standing around, turn to face them
if (self->cast_info.currentmove->frame->aifunc == ai_stand)
{
vec3_t vec;
VectorSubtract( other->s.origin, self->s.origin, vec );
VectorNormalize( vec );
self->ideal_yaw = vectoyaw( vec );
M_ChangeYaw( self );
}
}
}
*/
return true;
}
return false;
}
//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//
// Special Skidrow entities
//................................................
// Radio
/*QUAKED misc_skidrow_radio (.5 .5 1) (-16 -16 -24) (16 16 48)
Bernie and the guys will listen to this. After the radio has stopped,
they'll discuss the game for some time.
"delay" time to wait between starting to listen to the radio
"wait" time spent listening to the radio each time
"speed" time spent discussing the game afterwards
*/
/*QUAKED misc_skidrow_radio_repeater (.5 .5 1) (-16 -16 -24) (16 16 48)
Use to tag the speaker inside the warehouse
*/
void EP_Radio_On_First_Time (edict_t *self);
void radio_snd_think (edict_t *self)
{
self->count++;
if (self->count == 1)
{
gi.sound ( self, CHAN_VOICE, gi.soundindex ("world/cheerup.wav"), 1, ATTN_NORM, 0);
self->nextthink = level.time + 1.0;
}
else if (self->count == 2 || self->count == 3)
{
gi.sound ( self, CHAN_VOICE, gi.soundindex ("world/cheerhigh.wav"), 1, ATTN_NORM, 0);
self->nextthink = level.time + 6.0;
}
else if (self->count == 4)
{
gi.sound ( self, CHAN_VOICE, gi.soundindex ("world/cheerdown.wav"), 1, ATTN_NORM, 0);
self->nextthink = level.time + 2.0;
}
else
self->think = G_FreeEdict;
}
void Skidrow_Radio_Sound (edict_t *self)
{
edict_t *radio_snd;
radio_snd = G_Spawn ();
radio_snd->think = radio_snd_think;
radio_snd->nextthink = level.time + 0.1;
radio_snd->count = 0;
}
void radio_loop_think (edict_t *self)
{
gi.sound ( self, CHAN_VOICE, gi.soundindex ("world/cheerlow.wav"), 1, ATTN_NORM, 0);
self->nextthink = level.time + 1.0;
}
void Skidrow_Radio_Loop (edict_t *self)
{
edict_t *radio_loop;
radio_loop = G_Spawn ();
radio_loop->think = radio_loop_think;
radio_loop->nextthink = level.time + 1.0;
}
void EP_skidrow_radio_stop_discuss (edict_t *self)
{
// self->think = EP_skidrow_radio_on;
self->think = EP_Radio_On_First_Time;
self->nextthink = level.time + self->delay;
self->timestamp = self->nextthink + self->wait; // set the time to stop playing
}
void EP_skidrow_radio_off (edict_t *self)
{
edict_t *Bernie/*, *Al*/, *Arnold;
Bernie = EP_GetCharacter( NAME_BERNIE );
// Al = EP_GetCharacter( NAME_AL );
Arnold = EP_GetCharacter( NAME_ARNOLD );
// Ridah 5-8-99, modified this to prevent courtyard wierdness after touching reset
if (Bernie)
{
if (Bernie->goal_ent == self)
{
Bernie->goal_ent = NULL;
if (!Bernie->enemy)
Bernie->cast_info.pausetime = level.time + self->speed; // stick around for a bit
}
Bernie->cast_info.aiflags |= AI_TALK;
}
/*
if (Al && (Al->goal_ent == self))
{
Al->goal_ent = NULL;
if (!Al->enemy)
Al->cast_info.pausetime = level.time + self->speed; // stick around for a bit
Al->cast_info.aiflags |= AI_TALK;
}
*/
if (Arnold)
{
if (Arnold->goal_ent == self)
{
Arnold->goal_ent = NULL;
if (!Arnold->enemy)
Arnold->cast_info.pausetime = level.time + self->speed; // stick around for a bit
}
Arnold->cast_info.aiflags |= AI_TALK;
}
self->think = EP_skidrow_radio_stop_discuss;
self->nextthink = level.time + self->speed;
}
void EP_skidrow_radio_on (edict_t *self)
{
edict_t *Bernie/*, *Al*/, *Arnold;
Bernie = EP_GetCharacter( NAME_BERNIE );
// Al = EP_GetCharacter( NAME_AL );
Arnold = EP_GetCharacter( NAME_ARNOLD );
if ( (Bernie)
&& !Bernie->enemy
&& (!Bernie->goal_ent || (Bernie->goal_ent->touch == path_corner_cast_touch))
&& (VectorDistance( Bernie->s.origin, self->s.origin ) < 1024))
{
Bernie->goal_ent = self;
Bernie->cast_info.aiflags &= ~AI_TALK; // don't talk while at radio
// Ridah, 5-8-99, we shouldn't need this anymore
}
/*
if ( (Al)
&& !Al->enemy
&& (!Al->goal_ent || (Al->goal_ent->touch == path_corner_cast_touch))
&& (VectorDistance( Al->s.origin, self->s.origin ) < 1024))
{
Al->goal_ent = self;
Al->cast_info.aiflags &= ~AI_TALK; // don't talk while at radio
}
*/
if ( (Arnold)
&& !Arnold->enemy
&& (!Arnold->goal_ent || (Arnold->goal_ent->touch == path_corner_cast_touch))
&& (VectorDistance( Arnold->s.origin, self->s.origin ) < 1024))
{
Arnold->goal_ent = self;
Arnold->cast_info.aiflags &= ~AI_TALK; // don't talk while at radio
// Ridah, 5-8-99, we shouldn't need this anymore
}
if (level.time > self->timestamp)
{ // turn the radio off
self->think = EP_skidrow_radio_off;
self->nextthink = level.time + 0.1;
return;
}
self->nextthink = level.time + 3;
/*
Skidrow_Radio_Sound (self);
{
edict_t *repeater;
repeater = G_Find ( self, FOFS(classname), "misc_skidrow_radio_repeater");
if (repeater)
Skidrow_Radio_Sound (repeater);
}
*/
}
void EP_Radio_On_First_Time (edict_t *self)
{
Skidrow_Radio_Sound (self);
/*
{
edict_t *repeater;
repeater = G_Find ( self, FOFS(classname), "misc_skidrow_radio_repeater");
if (repeater)
Skidrow_Radio_Sound (repeater);
}
*/
EP_skidrow_radio_on (self);
self->think = EP_skidrow_radio_on;
}
void SP_misc_skidrow_radio_repeater (edict_t *self)
{
self->movetype = MOVETYPE_NONE;
self->solid = SOLID_NOT;
gi.linkentity (self);
}
void SP_misc_skidrow_radio (edict_t *self)
{
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
self->movetype = MOVETYPE_NONE;
self->solid = SOLID_NOT;
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, 48);
// self->think = EP_skidrow_radio_on;
self->think = EP_Radio_On_First_Time;
self->nextthink = level.time + self->delay;
self->timestamp = self->nextthink + self->wait; // set the time to stop playing
self->cast_info.aiflags |= AI_GOALENT_MANUAL_CLEAR; // don't clear it out when we get there
self->cast_info.aiflags |= AI_GOAL_RUN; // run to us
// just for testing we need a constant background sound for the radio
// self->s.sound = gi.soundindex ("world/baseball.wav");
AI_Ent_droptofloor( self );
Skidrow_Radio_Loop (self);
}
/*QUAKED misc_skidrow_ambush (.5 .5 1) (-16 -16 -24) (16 16 48)
Used to set ambush location for the 3 guards when the
player goes into the 2nd door.
*/
void SP_misc_skidrow_ambush (edict_t *self)
{
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
self->movetype = MOVETYPE_NONE;
self->solid = SOLID_NOT;
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, 48);
AI_Ent_droptofloor( self );
}
//==========================================================================================
//
// RESPONSES
// JOSEPH 23-MAR-99
void Resp_Lenny (edict_t *self, edict_t *other, response_t response)
{
if (response == resp_yes)
{
Voice_Specific( self, other, player_answer, 1 );
//Voice_Random( self, other, m_response, NUM_RESPONSE );
Voice_Player_Specific (self, TT_POSITIVE);
}
else
{
Voice_Random( self, other, player_profanity_level1, NUM_PROFANITY_LEVEL1 );
Voice_Player_Specific(self, TT_NEGATIVE);
}
self->response_ent = other;
self->last_response_time = level.time;
self->last_response = response;
}
// END JOSEPH
void Resp_MagicJ_GotDollar( edict_t *self, edict_t *other, response_t response )
{
if (response == resp_yes)
{
Voice_Player_Specific(self, TT_YES);
if (!(other->episode_flags & EP_SKIDROW_MAGICJ_GAVE_DOLLAR))
{
// have we really got a dollar to give?
if (self->client->pers.currentcash >= 1)
{
Voice_Specific( self, other, specific, 5 );
// give him the dollar
self->client->pers.currentcash -= 1;
other->currentcash += 1;
other->episode_flags |= EP_SKIDROW_MAGICJ_GAVE_DOLLAR;
// EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_MAGICJ_GAVE_DOLLAR);
}
else
{
Voice_Specific( self, other, specific, 6 );
// gi.cprintf( self, PRINT_HIGH, "You don't have a dollar to give.\n" );
response = resp_no;
}
}
}
else if (response == resp_no)
{
Voice_Specific( self, other, specific, 6 );
Voice_Player_Specific(self, TT_NO);
}
self->response_ent = other;
self->last_response_time = level.time;
self->last_response = response;
}
void Resp_Rummy_GotWine ( edict_t *self, edict_t *other, response_t response )
{
int index;
gitem_t *item;
item = FindItem ("Whiskey");
index = ITEM_INDEX (item);
if (response == resp_yes)
{
Voice_Player_Specific(self, TT_YES);
if (!(self->episode_flags & EP_SKIDROW_RUMMY_GAVE_WINE))
{
if (self->client->pers.inventory[index])
{
// gi.dprintf ("FIXME: heres your wine\n");
Voice_Specific( self, other, player_whiskey, 0 );
other->episode_flags |= EP_SKIDROW_RUMMY_GAVE_WINE;
// EP_Skidrow_Register_EPFLAG (self, EP_SKIDROW_RUMMY_GAVE_WINE);
}
else
{
// gi.cprintf( self, PRINT_HIGH, "FIXME: You don't have any wine to give.\n" );
Voice_Specific( self, other, player_whiskey, 1 );
response = resp_no;
}
}
else
{
// gi.cprintf( self, PRINT_HIGH, "FIXME: You don't have any wine to give.\n" );
Voice_Specific( self, other, player_whiskey, 1 );
response = resp_no;
}
}
else if (response == resp_no)
{
//gi.cprintf( self, PRINT_HIGH, "FIXME: I aint go any drink to give.\n" );
Voice_Specific( self, other, player_whiskey, 1 );
Voice_Player_Specific(self, TT_NO);
}
// hack to get rummy to work
other->cast_info.talk_ent = self;
self->response_ent = other;
self->last_response_time = level.time;
self->last_response = response;
}
/*QUAKED misc_skidrow_afraid (.5 .5 1) (-16 -16 -24) (16 16 48)
used by actors to pick location where it is safer to run away from the player
*/
void SP_misc_skidrow_afraid (edict_t *self)
{
if (deathmatch->value)
{
G_FreeEdict(self);
return;
}
self->movetype = MOVETYPE_NONE;
self->solid = SOLID_NOT;
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, 48);
self->cast_info.aiflags |= AI_RUN_LIKE_HELL;
AI_Ent_droptofloor( self );
}
// Pull Alarm routines
void Pull_Alarm_Ring (edict_t *ent)
{
edict_t *Louie;
Louie = EP_GetCharacter( NAME_LOUIE );
if ( Louie && ent->owner == Louie )
{
{
edict_t *entity = NULL;
edict_t *alarm = NULL;
while(1)
{
entity = G_Find (NULL, FOFS(classname), "misc_alarm");
if (!entity)
break;
if (VectorDistance( entity->s.origin, Louie->s.origin ) < 64)
{
alarm = entity;
break;
}
}
if (!alarm)
{
ent->nextthink = level.time + 0.1;
}
else
{
Louie->cast_info.aiflags &= ~AI_GOAL_IGNOREENEMY;
// Louie->cast_info.aiflags &= ~AI_GOAL_PULL_ALARM;
alarm->use (alarm, Louie, Louie);
G_FreeEdict(ent);
}
}
}
}
void Pull_Alarm_Think (edict_t *ent)
{
edict_t *Louie;
cast_memory_t *mem;
Louie = EP_GetCharacter( NAME_LOUIE );
if ( Louie && ent->owner == Louie )
{
mem = level.global_cast_memory[ Louie->character_index ][ ent->enemy->character_index ];
Louie->goal_ent = ent;
ent->cast_info.aiflags |= AI_GOAL_RUN;
ent->nextthink = level.time + 0.1;
ent->think = Pull_Alarm_Ring;
return;
}
// the user must be dead so free it up
G_FreeEdict (ent);
}
/*
edict_t *FindCastOrigin (edict_t *self)
{
edict_t *ent = NULL;
while(1)
{
ent = G_Find (ent, FOFS(classname), "cast_origin");
if (!ent)
break;
if (ent->owner != self)
continue;
else
return ent;
}
return NULL;
}
*/
void EP_Skidrow_Reset( edict_t *self, edict_t *other )
{
extern void AI_CreateCharacterMemory(edict_t *src, edict_t *dest);
extern void AI_ReleaseCastMemory(edict_t *self, cast_memory_t *cast_memory);
edict_t *Arnold, *Bernie;
cast_memory_t *mem;
edict_t *Cast_Origin;
if (!(other->client))
return;
Arnold = EP_GetCharacter( NAME_ARNOLD );
Bernie = EP_GetCharacter( NAME_BERNIE );
if (other->client && (other->client->pers.episode_flags & EP_SKIDROW_GOT_COIL))
return;
// both are still alive
if (Arnold && Bernie)
{
// TBD:
// actors need to go back to their start location
if (Arnold && (mem = level.global_cast_memory[ Arnold->character_index ][ other->character_index ]))
{
// Ridah, 5-8-99, some modifications for courtyard problems..
if (mem->memory_type == MEMORY_TYPE_ENEMY)
{
AI_ReleaseCastMemory( Arnold, Arnold->cast_info.enemy_memory );
Arnold->cast_info.enemy_memory = NULL;
}
// Ridah, 5-8-99, make it so we don't even remember the player
// AI_CreateCharacterMemory (Arnold, other);
// Ridah, DEMO: if they're currently in Louie's office, just spawn them back at the start pos
if (ValidBoxAtLoc( Arnold->start_ent->s.origin, Arnold->mins, Arnold->maxs, Arnold, MASK_PLAYERSOLID ))
VectorCopy( Arnold->start_ent->s.origin, Arnold->s.origin );
else // just run back there
Arnold->start_ent->cast_info.aiflags |= AI_GOAL_RUN;
Arnold->enemy = NULL;
Cast_Origin = Arnold->start_ent;
Arnold->goal_ent = Cast_Origin;
Arnold->cast_info.currentmove = Arnold->cast_info.move_stand;
}
if (Bernie && (mem = level.global_cast_memory[ Bernie->character_index ][ other->character_index ]))
{
// Ridah, 5-8-99, some modifications for courtyard problems..
if (mem->memory_type == MEMORY_TYPE_ENEMY)
{
AI_ReleaseCastMemory( Bernie, Bernie->cast_info.enemy_memory );
Bernie->cast_info.enemy_memory = NULL;
}
// Ridah, 5-8-99, make it so we don't even remember the player
// AI_CreateCharacterMemory (Bernie, other);
// Ridah, DEMO: if they're currently in Louie's office, just spawn them back at the start pos
if (ValidBoxAtLoc( Bernie->start_ent->s.origin, Bernie->mins, Bernie->maxs, Bernie, MASK_PLAYERSOLID ))
VectorCopy( Bernie->start_ent->s.origin, Bernie->s.origin );
else // just run back there
Bernie->start_ent->cast_info.aiflags |= AI_GOAL_RUN;
Bernie->enemy = NULL;
Cast_Origin = Bernie->start_ent;
Bernie->goal_ent = Cast_Origin;
Bernie->cast_info.currentmove = Bernie->cast_info.move_stand;
}
}
}
// JOSEPH 17-MAR-99
int EP_skidrow_touch_motorcycle_that_needs_battery_to_start (edict_t *self, edict_t *trigger)
{
// If the don't have the battery, then we don't get to go
if (!(self->client->pers.inventory[ITEM_INDEX(FindItem("Battery"))]))
{
if (!(self->episode_flags & EP_SKIDROW_FOUND_BIKE))
{
gi.sound(self, CHAN_VOICE, gi.soundindex("scenaric/bikenobattery.wav"), 1, ATTN_NORM, 0);
EP_Skidrow_Register_EPFLAG (self, EP_SKIDROW_FOUND_BIKE);
}
return 0;
}
// JOSEPH 5-JUN-99
self->client->pers.inventory[ITEM_INDEX(FindItem("Battery"))] = 0;
// END JOSEPH
// Trigger triggered
G_UseTargets (trigger, self);
// Delete old bike
{
edict_t *e;
int i;
for (i=1, e=g_edicts+i ; i < globals.num_edicts ; i++,e++)
{
if ((e->classname) && (!strcmp(e->classname, "props_motorcycle")))
{
G_FreeEdict(e);
}
}
}
// New bike
{
edict_t *moto = NULL;
extern void SP_props_motorcycle_run (edict_t *self);
moto = G_Spawn();
if (!moto)
return 1;
SP_props_motorcycle_run(moto);
}
// Do camera cut
// Delete trigger brush
return 1;
}
// END JOSEPH
void Resp_Momo_GotMoney ( edict_t *self, edict_t *other, response_t response )
{
cast_memory_t *mem;
if (self->episode_flags & EP_SKIDROW_MOMO_TOOK_MONEY)
return;
mem = level.global_cast_memory[ other->character_index ][ self->character_index ];
if (response == resp_yes)
{
Voice_Player_Specific(self, TT_YES);
Voice_Random (self, other, player_money_yes, NUM_PLAYER_MONEY_YES); // yes
}
else if (response == resp_no)
{
Voice_Player_Specific (self, TT_NO);
Voice_Random (self, other, player_money_no, NUM_PLAYER_MONEY_NO); // no
}
self->response_ent = other;
self->last_response_time = level.time;
self->last_response = response;
}
// generic process for hostile or neutral momo
qboolean ProcessMomo (edict_t *self, edict_t *other)
{
cast_memory_t *mem;
mem = level.global_cast_memory[ self->character_index ][ other->character_index ];
if (mem->flags & MEMORY_LASTWARNING)
{
Voice_Random ( self, other, &momo_specific[13], 2); // get the fuck out of my foyer
return true;
}
if (other->episode_flags & EP_SKIDROW_MOMO_TOOK_MONEY)
{
// Ridah, 5-8-99, we've already taken their money, so say one of the following..
if (!(mem->flags & MEMORY_ASSHOLE))
Voice_Random ( self, other, &momo_specific[12], 2); // so what's it gonna be... in or out?
else // they've cussed us, don't act all happy to see them
Voice_Random ( self, other, &momo_specific[13], 2); // get the fuck out of my foyer
return true;
}
if (!(other->episode_flags & EP_SKIDROW_MOMO_FIRST_TIME))
{
Voice_Specific (self, other, momo_specific, 0); // welcome.wav
// mem->inc = 1;
// other->episode_flags = other->client->pers.episode_flags |= EP_SKIDROW_MOMO_ASKED_MONEY;
// mem->response = Resp_Momo_GotMoney;
// other->episode_flags = other->client->pers.episode_flags |= EP_SKIDROW_MOMO_FIRST_TIME;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_MOMO_FIRST_TIME);
return true;
}
// Ridah, 5-8-99, I changed this so it clears this flag in EP_CastSight() if Momo sees you after not having seen you for a while
if (!(other->episode_flags & EP_SKIDROW_MOMO_ASKED_MONEY))
{
// note to Rafael: you can use "inc" for anything.. usually used to count events
if (!mem->inc)
{
if (!( mem->flags & MEMORY_ASSHOLE))
{
Voice_Random (self, other, &momo_specific[1], 3); // 10 dollar cover charge
mem->inc = 1;
}
else
{
Voice_Specific (self, other, momo_specific, 5); // now it's 20 bucks!
mem->inc = 2;
}
}
else
{
Voice_Specific (self, other, momo_specific, 9); // your back
}
// other->episode_flags = other->client->pers.episode_flags |= EP_SKIDROW_MOMO_ASKED_MONEY;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_MOMO_ASKED_MONEY);
mem->response = Resp_Momo_GotMoney;
return true;
}
// have they responded yet?
else if ( (other->response_ent == self)
&& (other->last_response_time > (level.time - 5)))
{
if (other->last_response == resp_yes)
{
edict_t *door = NULL;
int cost;
if ( mem->flags & MEMORY_ASSHOLE)
{
if (mem->inc < 3)
cost = 20;
else
cost = 30;
}
else
{
cost = 10;
}
// have we really have money to give?
if (other->client->pers.currentcash >= cost)
{
other->client->pers.currentcash -= cost;
self->currentcash += cost;
// other->episode_flags = other->client->pers.episode_flags |= EP_SKIDROW_MOMO_TOOK_MONEY;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_MOMO_TOOK_MONEY);
// TBD: at this point need to have momo walk away to a path corner cast
Voice_Specific( self, other, &momo_specific[0], 10 ); // go on in
// JOSEPH 9-MAR-99
// in case there's more than one door
{ // unlock the door for player
// Find target door
edict_t *e;
int i;
for (i=1, e=g_edicts+i ; i < globals.num_edicts ; i++,e++)
{
if ((e->targetname) && (!strcmp(e->targetname, "bardoor_sr")))
{
// Unlock target door
if (e->key == -1)
{
e->key = 0;
e->targetname = NULL;
}
}
}
// other->episode_flags |= EP_SKIDROW_MOMO_TOOK_MONEY;
// other->client->pers.episode_flags |= EP_SKIDROW_MOMO_TOOK_MONEY;
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_MOMO_TOOK_MONEY);
}
// END JOSEPH
}
else
{
// don't have money to give
Voice_Random( self, other, &momo_specific[7], 2 ); // see me later when you got the money
}
}
else // they said no
{
Voice_Random( self, other, &momo_specific[13], 3 );
}
other->last_response_time = 0; // so we don't process this response again
mem->response = NULL;
other->response_ent = NULL;
return true;
}
else
{
if (mem->flags & MEMORY_ASSHOLE)
{
if (!(mem->flags & MEMORY_UPSET))
{
mem->flags |= MEMORY_UPSET;
if (mem->inc < 3)
{
Voice_Specific (self, other, momo_specific, 5);
}
else // 30 bucks for you now!
{
Voice_Specific (self, other, momo_specific, 6);
}
}
else
{
Voice_Random (self, other, &momo_specific[12], 4);
// This needs to be here, or Momo will never take the money when mad
if (momo_specific[12].last_played == level.time)
{ // we just asked them if they wanna come in, so let them respond
mem->response = Resp_Momo_GotMoney;
}
}
}
else
{
Voice_Random (self, other, &momo_specific[12], 5);
if (momo_specific[12].last_played == level.time)
{ // we just asked them if they wanna come in, so let them respond
mem->response = Resp_Momo_GotMoney;
}
}
}
return true;
}
void EP_SkidrowFlags (edict_t *self)
{
if (self->name_index == NAME_MOMO)
{
self->cast_info.aiflags |= AI_IMMORTAL;
self->s.model_parts[PART_GUN].invisible_objects = (1<<0 | 1<<1);
self->s.model_parts[PART_GUN2].invisible_objects = (1<<0 | 1<<1);
}
}
/*UAKED immortal_hostility (.5 .5 1) (-16 -16 -24) (16 16 48)
This is an entity that will let an immortal check for player
hostility and take corresponding actions
health = the distance to check for ei a health of 64 would have a 128 diameter
*/
#if 0
void immortal_hostile_think (edict_t *self)
{
edict_t *player;
vec3_t vec;
float dist;
player = &g_edicts[1];
if (player->client->gun_noise)
{
VectorSubtract (self->s.origin, player->s.origin, vec);
dist = VectorLength (vec);
if (dist < self->health)
{
edict_t *dude;
cast_memory_t *mem;
{
dude = G_PickTarget(self->target);
if (dude)
{
mem = level.global_cast_memory[ dude->character_index ][ player->character_index ];
mem->flags |= MEMORY_LASTWARNING;
// gi.dprintf ("%s heard the shot\n", dude->name);
}
else
gi.dprintf ("player made gun noise in my detect zone!\n");
}
}
}
self->nextthink = level.time + 0.1;
}
void SP_immortal_hostility (edict_t *self)
{
self->movetype = MOVETYPE_NONE;
self->solid = SOLID_NOT;
VectorSet (self->mins, -16, -16, -24);
VectorSet (self->maxs, 16, 16, 48);
if (!(self->health))
{
gi.dprintf ("setting default radius of 128\n");
self->health = 128;
}
self->think = immortal_hostile_think;
self->nextthink = level.time + 0.1;
AI_Ent_droptofloor( self );
}
#endif
/*QUAKED ep_skidrow_flag (.5 .5 0) ?
marks where the player can no longer fire his gun
*/
void ep_skidrow_flag_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{
if (!(other->client))
return;
if (!(other->episode_flags & EP_SKIDROW_RATS_FIND))
{
EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_RATS_FIND);
// EP_Skidrow_Register_EPFLAG (other, EP_SKIDROW_CUT_SCENE_TWO);
}
}
void SP_ep_skidrow_flag ( edict_t *ent )
{
if (deathmatch->value)
{
G_FreeEdict(ent);
return;
}
ent->solid = SOLID_TRIGGER;
ent->touch = ep_skidrow_flag_touch;
ent->svflags |= SVF_NOCLIENT;
gi.setmodel (ent, ent->model);
gi.linkentity (ent);
}
/*
// Skidrow flags
#define EP_SKIDROW_MAGICJ_ASKED_DOLLAR 0x00000001 //1
#define EP_SKIDROW_BETH_GIVES_HINT 0x00000002 //2
#define EP_SKIDROW_AL_SAW_DEAD_LOUIE 0x00000004 //3
#define EP_PAWNOMATIC_FIRST_TIME 0x00000008 //4
#define EP_SKIDROW_GOT_COIL 0x00000010 //5
#define EP_SKIDROW_MAGICJ_GAVE_DOLLAR 0x00000020 //6
#define EP_SKIDROW_MOMO_ASKED_MONEY 0x00000040 //7
#define EP_SKIDROW_MOMO_TOOK_MONEY 0x00000080 //8
#define EP_SKIDROW_MOMO_FIRST_TIME 0x00000100 //9
#define EP_TALKED_TO_LENNY 0x00000200 //10
#define EP_SKIDROW_MOMO_GAVE_MONEY 0x00000800 //11
#define EP_BAR_FIRST_TIME 0x00001000 //12
#define EP_SKIDROW_LENNY_TOOK_WATCH 0x00002000 //13
#define EP_SKIDROW_JOSEPH_WARNING_1 0x00004000 //16
#define EP_SKIDROW_JOSEPH_WARNING_2 0x00080000 //15
#define EP_SKIDROW_JOSEPH_WARNING_3 0x00100000 //16
#define EP_SKIDROW_RUMMY_GAVE_WINE 0x00200000 //17
#define EP_SKIDROW_RUMMY_ASKED_WINE 0x00400000 //18
#define EP_SKIDROW_RATS_PISSED 0x00800000 //19
*/
#include "ep_log.h"
int the_log_page = 0;
void EP_Skidrow_Player_Log (edict_t *self, int page)
{
int len;
int i;
int cnt = 0;
int select = 0;
len = 0;
Com_sprintf (game.helpmessage1, sizeof(game.helpmessage1), "");
Com_sprintf (game.helpmessage2, sizeof(game.helpmessage2), "");
the_log_page += page;
if (the_log_page < 0)
the_log_page = 0;
else if (the_log_page >= NUM_SKIDROW_PLAYER_LOG)
the_log_page = 0;
for (i=1; i<NUM_SKIDROW_PLAYER_LOG; i++)
{
if (self->client->pers.episode_flags & ep_skidrow_player_log[i].ep_flag)
cnt++;
if (cnt == the_log_page)
{
select = i;
break;
}
}
if (!page || !the_log_page)
for (i=0; i<NUM_SKIDROW_PLAYER_LOG; i++)
{
if (ep_skidrow_player_log[i].new_clue == true)
{
select = i;
break;
}
}
if (cnt == 0)
{
the_log_page = 0;
strcpy (game.helpmessage1, " ");
if (ep_skidrow_player_log[select].new_clue)
strcat (game.helpmessage1, "new entry");
strcpy (game.helpmessage2, ep_skidrow_player_log[0].ep_text);
}
else
{
if (select == 0)
the_log_page = 0;
strcpy (game.helpmessage1, " ");
if (ep_skidrow_player_log[select].new_clue)
strcat (game.helpmessage1, "new entry");
strcat (game.helpmessage2, ep_skidrow_player_log[select].ep_text);
if (page)
gi.sound(self, CHAN_VOICE, gi.soundindex("world/pageturn.wav"), 1, ATTN_NONE, 0);
}
}
void EP_Skidrow_Register_EPFLAG (edict_t *self, int ep_flag)
{
if (self->client->pers.episode_flags & ep_flag)
return;
self->episode_flags = self->client->pers.episode_flags |= ep_flag;
EP_Flash_Newflag (self, ep_flag);
}
void EP_Skidrow_CheckMomo (edict_t *ent, cast_memory_t *mem)
{
if (ent->episode_flags & EP_SKIDROW_MOMO_ASKED_MONEY)
mem->inc++;
}
qboolean EP_Skidrow_Flash_Newflag (edict_t *self, int ep_flag)
{
int i;
qboolean gotone = false;
for (i=0; i<NUM_SKIDROW_PLAYER_LOG; i++)
{
if (ep_skidrow_player_log[i].ep_flag == ep_flag)
{
ep_skidrow_player_log[i].new_clue = true;
gotone = true;
}
else
ep_skidrow_player_log[i].new_clue = false;
}
return (gotone);
}