#pragma strict_types
#pragma no_clone
#pragma no_shadow
#pragma no_inherit
#pragma verbose_errors
#pragma combine_strings
//#pragma pedantic
//#pragma range_check
#pragma warn_deprecated

#define NEED_PROTOTYPES
#include <thing/properties.h>
#include <properties.h>
#include <wizlevels.h>
#include <new_skills.h>
#include <events.h>

string *valid_guilds = ({});

void create() {
  seteuid(getuid(this_object()));
  restore_object(GUILD_SAVEFILE);
  if (!pointerp(valid_guilds)) 
    valid_guilds=({});
}

//noetig, da nun valid_guilds eine Variable ist
public mixed QueryProp( string name )
{
  if (name==P_VALID_GUILDS) 
      return copy(valid_guilds);
  return 0;
}

nomask int beitreten() {
  object pl = this_player();
  object gilde = previous_object();

  if (!objectp(pl) || !objectp(gilde))
      return 0;

  // Gilden sind Blueprints.
  string gname = object_name(gilde);
  string ogname = ({string})pl->QueryProp(P_GUILD);

  if (GUILD_DIR+ogname == gname) {
    write("Du bist schon in dieser Gilde.\n");
    return -4;
  }

  if (ogname &&
      (ogname!=((({string})pl->QueryProp(P_DEFAULT_GUILD)) || DEFAULT_GUILD))) {
    write("Du bist noch in einer anderen Gilde.\n");
    return -1;
  }
  if (gname[0..7]!=GUILD_DIR ||
        member(valid_guilds,(gname=gname[8..]))<0) {
      write("Diese Gilde ist leider nicht zugelassen.\n"+
              "Bitte verstaendige einen Erzmagier.\n");
      return -2;
  }
  ({string})pl->SetProp(P_GUILD,gname);
  // Event Gildenwechsel triggern
  ({int})EVENTD->TriggerEvent(EVT_GUILD_CHANGE, ([
      E_OBJECT: pl, E_PLNAME: getuid(pl),
      E_ENVIRONMENT: environment(pl),
      E_GUILDNAME: gname,
      E_LAST_GUILDNAME: ogname ]) );

  return 1;
}

static nomask void loose_ability(mixed key, mixed dat, int loss) {
  mixed val;

  val=mappingp(dat)?dat[SI_SKILLABILITY]:dat;
  if (!intp(val) || val<=0) return;
  val-=(val*loss)/100;if (val<=0) val=1;
  if (mappingp(dat))
      dat[SI_SKILLABILITY]=val;
  else
      dat=val;
}

varargs nomask int austreten(int loss) {
  object pl,gilde;
  string gname;
  mapping skills;

  if (!(pl=this_player()) || !(gilde=previous_object()))
      return 0;
  // Gilden muessen Blueprints sein, so. ;-)
  gname=object_name(gilde);
  if (gname[0..7]!=GUILD_DIR ||
      (({string})pl->QueryProp(P_GUILD))!=gname[8..]) {
      write("Du kannst hier nicht aus einer anderen Gilde austreten.\n");
      return -1;
  }
  if (gname[8..]==(({string})pl->QueryProp(P_DEFAULT_GUILD)||DEFAULT_GUILD))
  {
        write("Aus dieser Gilde kannst Du nicht austreten.\n");
        return -1;
  }
  if (loss<=0) loss=20;
  skills=({mapping})pl->QueryProp(P_NEWSKILLS);
  walk_mapping(skills,"loose_ability",this_object(),loss);
  ({mapping})pl->SetProp(P_NEWSKILLS,skills);
  ({string})pl->SetProp(P_GUILD,0);
  // Event Gildenwechsel triggern
  ({int})EVENTD->TriggerEvent(EVT_GUILD_CHANGE, ([
      E_OBJECT: pl, E_PLNAME: getuid(pl),
      E_ENVIRONMENT: environment(pl),
      E_GUILDNAME: ({string})pl->QueryProp(P_GUILD),
      E_LAST_GUILDNAME: gname ]) );

  // Defaultgilde ggf. neuen Titel setzen lassen.
  gname = ({string})pl->QueryProp(P_GUILD);
  ({void})(GUILD_DIR+"/"+gname)->adjust_title(pl);

  return 1;
}

nomask static int security_check()
{
  if (previous_object() && geteuid(previous_object())==ROOTID)
    return 1;
  if (!process_call() && previous_object() && ARCH_SECURITY)
    return 1;
  return 0;
}

nomask int AddGuild(string gildob) {
  if (!stringp(gildob) || !sizeof(gildob) || !security_check() 
      || file_size(GUILD_DIR+gildob+".c")<0)
      return 0;
  if (member(valid_guilds, gildob) != -1)
      return 0;
  valid_guilds+=({gildob});
  save_object(GUILD_SAVEFILE);
  return 1;
}

nomask int RemoveGuild(string gildob) {
  if (!stringp(gildob) || !sizeof(gildob) 
      || !security_check())
      return 0;
  if (member(valid_guilds, gildob) == -1)
      return 0;
  valid_guilds-=({gildob});
  
  save_object(GUILD_SAVEFILE);
  return 1;
}

nomask int ValidGuild(string gildenob) {
  if (!stringp(gildenob)) 
      return 0;

  return (member(valid_guilds,gildenob)>=0);
}

nomask string *_query_valid_guilds() {return copy(valid_guilds); }

