[Fix] Major issue in how hooks worked, now hackishly sane!

This commit is contained in:
Allanis 2013-04-09 00:19:08 +01:00
parent 3df258229c
commit 6a320a27b1
5 changed files with 68 additions and 23 deletions

View File

@ -3,7 +3,7 @@ if lang == "es" then
-- Not translated. -- Not translated.
else -- Default English. else -- Default English.
misn_title = "Empire Recruitment" misn_title = "Empire Recruitment"
misn_reward = "3000 credits" misn_reward = "%d Scred"
misn_desc = "Deliver some parcels for the Empire to %s." misn_desc = "Deliver some parcels for the Empire to %s."
title = {} title = {}
title[1] = "Spaceport Bar" title[1] = "Spaceport Bar"
@ -27,8 +27,9 @@ function create()
dest = space.getPlanet("Empire"); dest = space.getPlanet("Empire");
-- Mission details. -- Mission details.
reward = 3000
misn.setTitle(misn_title) misn.setTitle(misn_title)
misn.setReward(misn_credits) misn.setReward(string.format(misn_reward, reward))
misn.setDesc(string.format(misn_desc, dest)) misn.setDesc(string.format(misn_desc, dest))
tk.msg(title[2], string.format(text[3], dest)) tk.msg(title[2], string.format(text[3], dest))
@ -42,7 +43,7 @@ end
function land() function land()
if space.landName() == dest then if space.landName() == dest then
if player.rmCargo(parcels) then if player.rmCargo(parcels) then
player.pay(3000) player.pay(reward)
-- More flavour text :) -- More flavour text :)
tk.msg(title[3], string.format(text[4], dest)) tk.msg(title[3], string.format(text[4], dest))
misn.finish() misn.finish()

View File

@ -7,10 +7,12 @@
// The hook. // The hook.
typedef struct Hook_ { typedef struct Hook_ {
int id; int id; // Unique id.
Mission* misn; unsigned int parent; // Mission it's connected to.
char* func; char* func; // Function returned.
char* stack; char* stack; // Stack it's a part of.
int delete; // Indicates it should be deleted when possible.
} Hook; } Hook;
// The stack. // The stack.
@ -18,12 +20,28 @@ static unsigned int hook_id = 0; // Unique hook id.
static Hook* hook_stack = NULL; static Hook* hook_stack = NULL;
static int hook_mstack = 0; static int hook_mstack = 0;
static int hook_nstack = 0; static int hook_nstack = 0;
static int hook_runningstack = 0; // Check if stack is running.
// Extern. // Extern.
extern int misn_run(Mission* misn, char* func); extern int misn_run(Mission* misn, char* func);
int hook_run(Hook* hook) { int hook_run(Hook* hook) {
if(misn_run(hook->misn, hook->func)) int i;
Mission* misn;
if(hook->delete) return 0; // Hook should be deleted not run.
// Locate the mission.
for(i = 0; i < MISSION_MAX; i++)
if(player_missions[i].id == hook->parent)
break;
if(i >= MISSION_MAX) {
WARN("Trying to run hook with parent not in player mission stack!");
return -1;
}
misn = &player_missions[i];
if(misn_run(misn, hook->func))
// Error has accured. // Error has accured.
WARN("Hook [%s] '%d' -> '%s' failed", hook->stack, WARN("Hook [%s] '%d' -> '%s' failed", hook->stack,
hook->id, hook->func); hook->id, hook->func);
@ -32,21 +50,22 @@ int hook_run(Hook* hook) {
} }
// Add/Remove hooks. // Add/Remove hooks.
int hook_add(Mission* misn, char* func, char* stack) { int hook_add(unsigned int parent, char* func, char* stack) {
Hook* new_hook; Hook* new_hook;
// If the memory must grow. // If the memory must grow.
if(hook_nstack+1 > hook_mstack) { if(hook_nstack+1 > hook_mstack) {
hook_stack = realloc(hook_stack, (hook_mstack+5)*sizeof(Hook));
hook_mstack += 5; hook_mstack += 5;
hook_stack = realloc(hook_stack, hook_mstack*sizeof(Hook));
} }
// Create the new hook. // Create the new hook.
new_hook = &hook_stack[hook_nstack]; new_hook = &hook_stack[hook_nstack];
new_hook->id = ++hook_id; new_hook->id = ++hook_id;
new_hook->misn = misn; new_hook->parent = parent;
new_hook->func = func; new_hook->func = func;
new_hook->stack = stack; new_hook->stack = stack;
new_hook->delete = 0;
hook_nstack++; hook_nstack++;
@ -65,31 +84,47 @@ void hook_rm(int id) {
else break; else break;
} }
if(hook_runningstack) {
hook_stack[m].delete = 1;
return;
}
// Last hook, just clip the stack.
if(m == (hook_nstack-1)) { if(m == (hook_nstack-1)) {
hook_nstack--; hook_nstack--;
return; return;
} }
// Move it! // Move it!
memmove(&hook_stack[m+1], &hook_stack[m+2], sizeof(Hook)*(hook_nstack-(m+2))); memmove(&hook_stack[m], &hook_stack[m], sizeof(Hook)*(hook_nstack-(m+1)));
hook_nstack--; hook_nstack--;
} }
void hook_rmParent(unsigned int parent) { void hook_rmParent(unsigned int parent) {
int i; int i;
for(i = 0; i < hook_nstack; i++) for(i = 0; i < hook_nstack; i++)
if(parent == hook_stack[i].misn->id) { if(parent == hook_stack[i].parent) {
hook_rm(hook_stack[i].id); hook_rm(hook_stack[i].id);
i--; if(!hook_runningstack) i--;
} }
} }
// Run all hooks off the stack. // Run all hooks off the stack.
int hooks_run(char* stack) { int hooks_run(char* stack) {
int i; int i;
hook_runningstack = 1; // Running hooks.
for(i = 0; i < hook_nstack; i++) for(i = 0; i < hook_nstack; i++)
if(strcmp(stack, hook_stack[i].stack)==0) if((strcmp(stack, hook_stack[i].stack)==0) && !hook_stack[i].delete) {
hook_run(&hook_stack[i]); hook_run(&hook_stack[i]);
}
hook_runningstack = 0; // Not running hooks anymore.
for(i = 0; i < hook_nstack; i++)
if((strcmp(stack, hook_stack[i].stack)==0) && hook_stack[i].delete) {
hook_rm(hook_stack[i].id);
i--;
}
return 0; return 0;
} }

View File

@ -2,7 +2,7 @@
#include "mission.h" #include "mission.h"
// Add/Run hooks. // Add/Run hooks.
int hook_add(Mission* misn, char* func, char* stack); int hook_add(unsigned int parent, char* func, char* stack);
void hook_rm(int id); void hook_rm(int id);
void hook_rmParent(unsigned int parent); void hook_rmParent(unsigned int parent);

View File

@ -319,7 +319,7 @@ static int player_rmCargo(lua_State* L) {
mission_unlinkCargo(cur_mission, id); mission_unlinkCargo(cur_mission, id);
lua_pushboolean(L, !ret); lua_pushboolean(L, !ret);
return 0; return 1;
} }
static int player_pay(lua_State* L) { static int player_pay(lua_State* L) {
@ -410,17 +410,26 @@ static int tk_input(lua_State* L) {
// -- HOOK -- // -- HOOK --
static int hook_land(lua_State* L) { static int hook_land(lua_State* L) {
int i;
char* func; char* func;
MIN_ARGS(1); MIN_ARGS(1);
for(i = 0; i < MISSION_MAX; i++)
if(player_missions[i].id == cur_mission->id)
break;
if(i >= MISSION_MAX) {
WARN("Mission not in stack trying to hook");
return 0;
}
if(lua_isstring(L, -1)) func = (char*)lua_tostring(L, -1); if(lua_isstring(L, -1)) func = (char*)lua_tostring(L, -1);
else { else {
WARN("Mission '%s': trying to push non-valid function hook", WARN("Mission '%s': trying to push non-valid function hook",
cur_mission->data->name); cur_mission->data->name);
return 0; return 0;
} }
hook_add(cur_mission, func, "land"); hook_add(cur_mission->id, func, "land");
return 0; return 0;
} }

View File

@ -129,7 +129,7 @@ void mission_unlinkCargo(Mission* misn, unsigned int cargo_id) {
if(misn->cargo[i] == cargo_id) if(misn->cargo[i] == cargo_id)
break; break;
if(i >= misn->cargo) { if(i >= misn->ncargo) { // Not found.
DEBUG("Mission '%s' attempting to unlink in existant cargo %d.", DEBUG("Mission '%s' attempting to unlink in existant cargo %d.",
misn->title, cargo_id); misn->title, cargo_id);
return; return;