scummvm/sword2/events.cpp

358 lines
7.4 KiB
C++
Raw Normal View History

2003-07-28 01:44:38 +00:00
/* Copyright (C) 1994-2003 Revolution Software Ltd
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*/
#include <stdio.h>
2003-07-28 03:12:49 +00:00
#include "stdafx.h"
2003-07-28 01:44:38 +00:00
//#include "src\driver96.h"
#include "console.h"
#include "debug.h"
#include "defs.h"
#include "events.h"
#include "interpreter.h"
#include "logic.h"
#include "memory.h"
#include "object.h"
#include "sync.h"
_event_unit event_list[MAX_events];
2003-07-28 01:44:38 +00:00
void Init_event_system(void) { //Tony4Dec96
2003-07-28 01:44:38 +00:00
uint32 j;
for (j = 0; j < MAX_events; j++) {
//denotes free slot
event_list[j].id = 0;
}
2003-07-28 01:44:38 +00:00
}
uint32 CountEvents(void) {
uint32 j;
uint32 count = 0;
for (j = 0; j < MAX_events; j++) {
2003-07-28 01:44:38 +00:00
if (event_list[j].id)
count++;
}
return count;
2003-07-28 01:44:38 +00:00
}
int32 FN_request_speech(int32 *params) { //Tony13Nov96
//change current script - must be followed by a TERMINATE script
// directive
//param 0 id of target to catch the event and startup speech servicing
2003-07-28 01:44:38 +00:00
uint32 j = 0;
2003-07-28 01:44:38 +00:00
while(1) {
if (event_list[j].id == (uint32) params[0])
2003-07-28 01:44:38 +00:00
break;
if (!event_list[j].id)
2003-07-28 01:44:38 +00:00
break;
j++;
}
if (j == MAX_events)
2003-07-28 01:44:38 +00:00
Con_fatal_error("FN_set_event out of event slots (%s line %u)", __FILE__, __LINE__);
//found that slot
2003-07-28 01:44:38 +00:00
//id of person to stop
event_list[j].id = params[0];
//full script id to interact with - megas run their own 7th script
event_list[j].interact_id = (params[0] * 65536) + 6;
2003-07-28 01:44:38 +00:00
return IR_CONT;
2003-07-28 01:44:38 +00:00
}
void Set_player_action_event(uint32 id, uint32 interact_id) { //Tony4Dec96
uint32 j = 0;
2003-07-28 01:44:38 +00:00
// if (event_list[j].id != id && event_list[j].id)
// // zip along until we find a free slot
// while (event_list[j].id!=id || event_list[j].id) {
// j++;
// }
2003-07-28 01:44:38 +00:00
while (1) {
if (event_list[j].id == id)
2003-07-28 01:44:38 +00:00
break;
if (!event_list[j].id)
2003-07-28 01:44:38 +00:00
break;
j++;
}
if (j == MAX_events)
2003-07-28 01:44:38 +00:00
Con_fatal_error("Set_event out of event slots");
// found that slot
2003-07-28 01:44:38 +00:00
//id of person to stop
event_list[j].id = id;
//full script id of action script number 2
event_list[j].interact_id = (interact_id * 65536) + 2;
2003-07-28 01:44:38 +00:00
}
int32 FN_set_player_action_event(int32 *params) { //Tony10Feb97
// we want to intercept the player character and have him interact
// with an object - from script this code is the same as the mouse
// engine calls when you click on an object - here, a third party
// does the clicking IYSWIM
2003-07-28 01:44:38 +00:00
// note - this routine used CUR_PLAYER_ID as the target
2003-07-28 01:44:38 +00:00
// params
// 0 id to interact with
2003-07-28 01:44:38 +00:00
uint32 j = 0;
2003-07-28 01:44:38 +00:00
// search for an existing event or a slot
2003-07-28 01:44:38 +00:00
while(1) {
if (event_list[j].id == CUR_PLAYER_ID)
2003-07-28 01:44:38 +00:00
break;
if (!event_list[j].id)
2003-07-28 01:44:38 +00:00
break;
j++;
}
if (j == MAX_events)
2003-07-28 01:44:38 +00:00
Con_fatal_error("Set_event out of event slots");
// found that slot
2003-07-28 01:44:38 +00:00
// id of person to stop
event_list[j].id = CUR_PLAYER_ID;
// full script id of action script number 2
event_list[j].interact_id = (params[0] * 65536) + 2;
2003-07-28 01:44:38 +00:00
return IR_CONT;
2003-07-28 01:44:38 +00:00
}
int32 FN_send_event(int32 *params) { //Tony28Feb97
// we want to intercept the player character and have him interact
// with an object - from script
2003-07-28 01:44:38 +00:00
// params
// 0 id to recieve event
// 1 script to run
2003-07-28 01:44:38 +00:00
uint32 j = 0;
2003-07-28 01:44:38 +00:00
// Zdebug("*+*+* %d %d", params[0], params[1]);
2003-07-28 01:44:38 +00:00
// search for an existing event or a slot
2003-07-28 01:44:38 +00:00
while(1) {
if (event_list[j].id == (uint32) params[0])
2003-07-28 01:44:38 +00:00
break;
if (!event_list[j].id)
2003-07-28 01:44:38 +00:00
break;
j++;
}
if (j == MAX_events)
2003-07-28 01:44:38 +00:00
Con_fatal_error("fn_send_event out of event slots");
// found that slot
2003-07-28 01:44:38 +00:00
// id of person to stop
event_list[j].id = params[0];
//full script id
event_list[j].interact_id = params[1];
2003-07-28 01:44:38 +00:00
return IR_CONT;
2003-07-28 01:44:38 +00:00
}
int32 FN_check_event_waiting(int32 *params) { //Tony4Dec96
// returns yes/no in RESULT
2003-07-28 01:44:38 +00:00
// no params
2003-07-28 01:44:38 +00:00
uint32 j;
2003-07-28 01:44:38 +00:00
RESULT = 0;
2003-07-28 01:44:38 +00:00
for (j = 0; j < MAX_events; j++) {
if (event_list[j].id == ID) {
RESULT = 1;
2003-07-28 01:44:38 +00:00
break;
}
}
return IR_CONT;
2003-07-28 01:44:38 +00:00
}
// like FN_check_event_waiting, but starts the event rather than setting
// RESULT to 1
int32 FN_check_for_event(int32 *params) { // James (04mar97)
2003-07-28 01:44:38 +00:00
// no params
uint32 j;
for (j = 0; j < MAX_events; j++) {
if (event_list[j].id == ID) {
2003-07-28 01:44:38 +00:00
// start the event
// run 3rd script of target object on level 1
LLogic.Logic_one(event_list[j].interact_id);
// clear the event slot
event_list[j].id = 0;
return IR_TERMINATE;
2003-07-28 01:44:38 +00:00
}
}
return IR_CONT;
2003-07-28 01:44:38 +00:00
}
2003-07-28 01:44:38 +00:00
// combination of FN_pause & FN_check_for_event
// - ie. does a pause, but also checks for event each cycle
int32 FN_pause_for_event(int32 *params) { // James (04mar97)
2003-07-28 01:44:38 +00:00
// returns yes/no in RESULT
// params
// 0 pointer to object's logic structure
// 1 number of game-cycles to pause
2003-07-28 01:44:38 +00:00
Object_logic *ob_logic = (Object_logic *)params[0];
uint32 j;
// first, check for an event
for (j = 0; j < MAX_events; j++) {
if (event_list[j].id == ID) {
// reset the 'looping' flag
ob_logic->looping = 0;
2003-07-28 01:44:38 +00:00
// start the event
// run 3rd script of target object on level 1
LLogic.Logic_one(event_list[j].interact_id);
// clear the event slot
event_list[j].id = 0;
return IR_TERMINATE;
2003-07-28 01:44:38 +00:00
}
}
// no event, so do the FN_pause bit
// start the pause
if (ob_logic->looping == 0) {
2003-07-28 01:44:38 +00:00
ob_logic->looping = 1;
// no. of game cycles
ob_logic->pause = params[1];
2003-07-28 01:44:38 +00:00
}
// if non-zero
if (ob_logic->pause) {
// decrement the pause count
ob_logic->pause--;
// drop out of script, but call this again next cycle
return IR_REPEAT;
} else {
// pause count is zerp
2003-07-28 01:44:38 +00:00
ob_logic->looping = 0;
// continue script
return IR_CONT;
2003-07-28 01:44:38 +00:00
}
}
uint32 Check_event_waiting(void) { //Tony4Dec96
// returns yes/no
2003-07-28 01:44:38 +00:00
uint32 j;
for (j = 0; j < MAX_events; j++)
if (event_list[j].id == ID)
return 1;
2003-07-28 01:44:38 +00:00
return 0;
2003-07-28 01:44:38 +00:00
}
int32 FN_clear_event(int32 *params) { //Tony11Mar97
2003-07-28 01:44:38 +00:00
// no params
// no return vaule
uint32 j;
for (j = 0; j < MAX_events; j++)
if (event_list[j].id == ID) {
//clear the slot
event_list[j].id = 0;
return IR_CONT;
2003-07-28 01:44:38 +00:00
}
return IR_CONT;
2003-07-28 01:44:38 +00:00
}
void Start_event(void) { //Tony4Dec96
// call this from stuff like fn_walk
// you must follow with a return IR_TERMINATE
2003-07-28 01:44:38 +00:00
uint32 j;
2003-07-28 01:44:38 +00:00
for (j = 0; j < MAX_events; j++)
if (event_list[j].id == ID) {
// run 3rd script of target object on level 1
LLogic.Logic_one( event_list[j].interact_id);
//clear the slot
event_list[j].id = 0;
2003-07-28 01:44:38 +00:00
return;
}
// oh dear - stop the system
2003-07-28 01:44:38 +00:00
Con_fatal_error("Start_event can't find event for id %d", ID);
}
int32 FN_start_event(int32 *params) { //Tony4Dec96
uint32 j;
2003-07-28 01:44:38 +00:00
for (j = 0; j < MAX_events; j++)
if (event_list[j].id == ID) {
// run 3rd script of target object on level 1
LLogic.Logic_one(event_list[j].interact_id);
// clear the slot
event_list[j].id = 0;
return IR_TERMINATE;
2003-07-28 01:44:38 +00:00
}
//oh dear - stop the system
2003-07-28 01:44:38 +00:00
Con_fatal_error("FN_start_event can't find event for id %d", ID);
return 0; //never called - but lets stop them bloody errors
2003-07-28 01:44:38 +00:00
}
void Kill_all_ids_events(uint32 id) { //Tony18Dec96
uint32 j;
2003-07-28 01:44:38 +00:00
for (j = 0; j < MAX_events; j++)
if (event_list[j].id == id) {
// clear the slot
event_list[j].id = 0;
}
2003-07-28 01:44:38 +00:00
}