/****************************************************************************** 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; icast_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 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; iclient->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; iclient->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