// MorgenGrauen MUDlib
//
// living/comm.c -- communiction module for livings
//
// $Id$

#pragma strong_types,save_types
#pragma no_clone
#pragma range_check

inherit "/std/living/comm_structs";

#include <defines.h>
#include <thing/language.h>
#define NEED_PROTOTYPES
#include <living/comm.h>
#undef NEED_PROTOTYPES

void create_super()
{
  set_next_reset(-1);
}

protected string comm_guess_action() {
  string cmd;
  string action = query_verb();
  // Die Aktionen sind intern in der Regel nach den haeufigsten Kommandoverben
  // dieser Aktion benannt. Bei einigen Aktionen sind mehrere Kommandoverben
  // ueblich, die sollen hier noch abgehandelt werden.
  switch(action) {
    case "nehme":
      // MA_TAKE == nimm
      action = MA_TAKE;
      break;

    case "gebe":
      // MA_GIVE == "gib"
      action = MA_GIVE;
      break;
    
    case "norden":
    case "nordosten":
    case "osten":
    case "suedosten":
    case "sueden":
    case "suedwesten":
    case "westen":
    case "nordwesten":
    case "oben":
    case "unten":
    case "betrete":
    case "verlasse":
    case "teleport":
    case "teleportiere":
      action = MA_MOVE;
      break;

    case "unt":
      action = MA_LOOK;
      break;

    case "wirf":
      if (strstr(query_command(), " weg") > -1)
        action = MA_PUT;
      break;

    case "stecke":
      cmd = query_command();
      if (strstr(cmd, " weg") > -1)
        action = MA_UNWIELD;
      else if (strstr(cmd," in ") > -1)
        action = MA_PUT;
      break;

    case "ziehe":
      cmd = query_command();
      if (strstr(cmd, " an") > -1)
        action = MA_WEAR;
      else if (strstr(cmd, " aus") > -1)
        action = MA_UNWEAR;
      break;

    case "esse":
    case "friss":
      action = MA_EAT;
      break;

    case "saufe":
      action = MA_DRINK;
      break;

    case "hoere":
      //MA_LISTEN == lausche
      action = MA_LISTEN;
      break;
    case "lese":
      action = MA_READ;
      break;

    case ":":
    case ";":
      action = MA_EMOTE;
      break;

    case "zerbreche":
    case "zerstoere":
    case "verbrenne":
    case "entsorge":
      action = MA_REMOVE;
      break;
  }
  return action;
}

protected int comm_guess_message_type(string action, mixed origin) {
  // everything not mentioned in the switch becomes MT_LOOK.
  switch(action) {
    case MA_FIGHT:
      // Kampf kann man meisten sowohl sehen als auch hoeren.
      return MT_LOOK | MT_LISTEN;
    case MA_LISTEN:
    case MA_SAY:
      return MT_LISTEN;
    case MA_FEEL:
      return MT_FEEL;
    case MA_SMELL:
      return MT_SMELL;
    case MA_CHANNEL:
      return MT_COMM | MT_FAR;
    case MA_EMOTE:
      if (objectp(origin)
          && environment(origin) == environment())
        return MT_COMM;
      else
        return MT_COMM | MT_FAR;
    case MA_SHOUT:
      return MT_LISTEN | MT_FAR;
  }
  // die meisten Aktionen sind zumindest sichtbar...
  return MT_LOOK;
}

// Wrapper fuer ReceiveMsg()
public int* ReceiveSay(string msg, string prefix = 0,
  struct msg_s* sense_blocked =
    ({(<msg_s> 
      msg: "@WER1 bewegt die Lippen, Du hoerst jedoch nichts.",
      type: MT_LOOK)}))
{
  int* res = ({0, -1});

  if(!prefix)
  {
    prefix = previous_object().Name(WER, 1) + " sagt: ";
  }

  res[0] = ReceiveMsg(
    replace_personal(msg, ({previous_object(), this_player()}) - ({0}), 1),
    MT_LISTEN | MSG_BS_LEAVE_LFS,
    MA_SAY,
    prefix);

  if(res[0] == MSG_SENSE_BLOCK)
  {
    // Um eine Nummer zurueckzugeben, ist hier leider eine for-Schleife noetig.
    for(int i = 0; i < sizeof(sense_blocked); ++i)
    {
      res[0] = ReceiveMsg(
        replace_personal(sense_blocked[i].msg, ({previous_object(),
                         this_player()}) - ({0}), 1),
        sense_blocked[i].type | MSG_BS_LEAVE_LFS,
        MA_SAY,
        sense_blocked[i].prefix);
      if(res[0] != MSG_SENSE_BLOCK)
      {
        res[1] = i;
        break;
      }
    }
  }
  return res;
}

public int ReceiveNotify(string msg, string action)
{
  // Da MT_NOTIFICATION immer zugestellt wird, ist keine Fehlerbehandlung
  // notwendig.
  return ReceiveMsg(
    msg,
    // MSG_DONT_IGNORE waere wegen MT_NOTIFICATION inhaltlich nicht noetig,
    // spart aber ein paar Ticks.
    MT_NOTIFICATION | MSG_BS_LEAVE_LFS | MSG_DONT_IGNORE,
    action);
}

public int ReceiveTeilemit(string msg)
{
  // Blockierte Sinne sind hier kein Problem, ergo keine Fehlerbehandlung.
  return ReceiveMsg(
    replace_personal(msg, ({previous_object(), this_player()}) - ({0}), 1),
    MT_COMM | MT_FAR | MSG_BS_LEAVE_LFS | MSG_DONT_STORE,
    MA_TELL,
    previous_object().Name(WER, 1) + "teilt Dir mit: ");
}

public int* ReceiveMultisense(struct msg_s* msgs,
    string action = 0, int commontypes = 0)
{
  int* res = ({0, -1});

  // Um eine Nummer zurueckzugeben, ist hier leider eine for-Schleife noetig.
  for(int i = 0; i < sizeof(msgs); ++i)
  {
    res[0] = ReceiveMsg(
      replace_personal(msgs[i].msg, ({previous_object(), this_player()}), 1),
      msgs[i].type | MSG_BS_LEAVE_LFS | commontypes,
      action,
      msgs[i].prefix);
    if(res[0] == MSG_DELIVERED)
    {
      res[1] = i;
      break;
    }
  }
  return res;
}
