
// implements some editing commands


//////// Entity Editing ///////////////

// the entity type of current selection
et = [ at (entget) 0 ]

// access the given attribute of selected ent
ea = [ at (entget) (+ $arg1 1) ]

// clear ents of given type
clearents = [ 
  if $editing [
    entcancel
    entselect [ strcmp (et) $arg1 ]; 
    echo Deleted (enthavesel) $arg1 entities; 
    delent
  ] 
]

// replace all ents that match current selection
// with the values given
replaceents = [
  if $editing [
    entfind @(entget)
    entset @arg1 @arg2 @arg3 @arg4 @arg5
    echo Replaced (enthavesel) entities  
  ]
]

selentedit      = [ "saycommand" ( concatword "/entset " (entget) ) ] 
selreplaceents  = [ "saycommand" ( concatword "/replaceents " (entget) ) ]  
selentfindall   = [ do [ @( concatword "entfind " (entget) ) ] ]

// modify given attribute of ent by a given amount
// arg1 attribute
// arg2 value
entproperty = [
  entloop [
    a0 = (ea 0)
    a1 = (ea 1)
    a2 = (ea 2)
    a3 = (ea 3)
    do [a@arg1 = (+ (ea @arg1) @arg2)]
    entset (et) $a0 $a1 $a2 $a3
  ]
]

enttypelist = [ 
  light mapmodel playerstart envmap particles sound
  shells bullets rockets riflerounds grenades cartridges
  health healthboost greenarmour yellowarmour quaddamage
  teleport teledest
  monster carrot jumppad
  base respawnpoint
  spotlight 
  box barrel platform elevator
  ""
]

enttypelength = (listlen $enttypelist)

listindex = [
  s = 0
  n = (listlen $arg1)
  loop i $n [
    if (strcmp $arg2 (at $arg1 $i)) [
      s = $i
    ]
  ]
  result $s
]

enttypeselect = [     
  n = $enttypelength
  next = (+ (listindex $enttypelist (et)) $arg1)
  if (< $next 0)  [ next = (- $n 1) ]
  if (= $next $n) [ next = 0 ]
  next = (at $enttypelist $next)
  entset $next (ea 0) (ea 1) (ea 2) (ea 3) 
]

////// Entity primary actions /////////

ent_action_base           = [ entproperty 0 ( * $arg1 1 ) ]
ent_action_carrot         = [ entproperty 0 ( * $arg1 1 ) ]
ent_action_teleport       = [ entproperty 0 ( * $arg1 1 ) ]
ent_action_teledest       = [ entproperty 1 ( * $arg1 1 ) ]
ent_action_monster        = [ entproperty 1 ( * $arg1 1 ) ]
ent_action_mapmodel       = [ entproperty 1 ( * $arg1 1 ) ]
ent_action_spotlight      = [ entproperty 0 ( * $arg1 5 ) ]
ent_action_light          = [ entproperty 0 ( * $arg1 5 ) ]
ent_action_jumppad        = [ entproperty 0 ( * $arg1 5 ) ]
ent_action_respawnpoint   = [ entproperty 0 ( * $arg1 15 ) ]
ent_action_playerstart    = [ entproperty 0 ( * $arg1 15 ) ]
ent_action_envmap         = [ entproperty 0 ( * $arg1 5 ) ]
ent_action_particles      = [ entproperty 0 ( * $arg1 1 ) ]
ent_action_sound          = [ entproperty 0 ( * $arg1 1 ) ]
ent_action_cycle          = [ entset ( if ( > $arg1 -1 ) [ result $arg2 ] [ result $arg3 ] ) ]
ent_action_shells         = [ ent_action_cycle $arg1 bullets quaddamage ]
ent_action_bullets        = [ ent_action_cycle $arg1 rockets shells ]
ent_action_rockets        = [ ent_action_cycle $arg1 riflerounds bullets ]
ent_action_riflerounds    = [ ent_action_cycle $arg1 grenades rockets ]
ent_action_grenades       = [ ent_action_cycle $arg1 cartridges riflerounds ]
ent_action_cartridges     = [ ent_action_cycle $arg1 quaddamage grenades ]
ent_action_quaddamage     = [ ent_action_cycle $arg1 shells cartridges ]
ent_action_health         = [ ent_action_cycle $arg1 healthboost yellowarmour ]
ent_action_healthboost    = [ ent_action_cycle $arg1 greenarmour health ]
ent_action_greenarmour    = [ ent_action_cycle $arg1 yellowarmour healthboost ]
ent_action_yellowarmour   = [ ent_action_cycle $arg1 health greenarmour ]
ent_action_box            = [ entproperty 1 ( * $arg1 1 ) ]
ent_action_barrel         = [ entproperty 1 ( * $arg1 1 ) ]
ent_action_platform       = [ entproperty 1 ( * $arg1 1 ) ]
ent_action_elevator       = [ entproperty 1 ( * $arg1 1 ) ]

//////// Copy and Paste //////////////

// 3 types of copying and pasting
// 1. select only cubes      -> paste only cubes
// 2. select cubes and ents  -> paste cubes and ents. same relative positions
// 3. select only ents       -> paste last selected ent. if ents are selected, replace attrs as paste

opaquepaste = 1
entcopybuf = ""

entreplace   = [ 
  do [
    if (enthavesel) [] [ newent @entcopybuf ]
    entset @entcopybuf 
  ]
]

editcopy   = [
  if (|| havesel [! (enthavesel)]) [
    entcopybuf = ""
    entcopy
    copy
  ] [
    entcopybuf = (entget)
  ]
]

editpaste  = [ 
  cancelpaste = (! (|| enthavesel havesel));
  if (strcmp "" $entcopybuf) [
    pastehilite
    reorient // temp; real fix will be in octaedit
    onrelease [ 
      if (opaquepaste) delcube 
      paste
      entpaste
      if ($cancelpaste) [ cancelsel ] 
    ] 
  ] [
    entreplace
    if ($cancelpaste) [ cancelsel ] 
  ] 
]

/////// Selection ///////////////

equaltype  = [
  if (strcmp * $arg1) [ result 1 ] [
    result (strcmp (et) $arg1)
  ]
]

equalattr  = [
  if (strcmp * $arg2) [ result 1 ] [
    result (= (ea $arg1) $arg2)
  ]
]

// select ents with given properties
// '*' is wildcard
entfind    = [ 
  if (= ($numargs) 1) [
    entselect     [ equaltype @@arg1 ]     
  ] [ if (= ($numargs) 2) [
    entselect [ && (equaltype @@arg1)         [equalattr 0 @@arg2] ]
  ] [ if (= ($numargs) 3) [
    entselect [ && (equaltype @@arg1) (&&     [equalattr 0 @@arg2] [equalattr 1 @@arg3]) ]
  ] [ if (= ($numargs) 4) [
    entselect [ && (equaltype @@arg1) (&& (&& [equalattr 0 @@arg2] [equalattr 1 @@arg3])     [equalattr 2 @@arg4]) ]
  ] [
    entselect [ && (equaltype @@arg1) (&& (&& [equalattr 0 @@arg2] [equalattr 1 @@arg3]) (&& [equalattr 2 @@arg4] [equalattr 3 @@arg5])) ]
  ]]]]
]

lse        = [
  line = ""
  count = 0
  entloop [
    line  = ( concatword $line (entget) "		" )
    count = ( + $count 1 )
    if (> $count 4) [
      echo $line
      line = ""
      count = 0
    ]
  ]
  if (> $count 0 ) [ echo $line ]
  echo (enthavesel) entities selected
]

enttoggle  = [ entmoving 1; entmoving 0; ]
entaddmove = [ entmoving 2 ]

grabbing = 0

hmapctrl   = [ hmapedit $arg1; passthrough $arg1]
drag       = [ dragging 1; onrelease [ dragging 0 ] ]
corners    = [ selectcorners 1; dragging 1; onrelease [ selectcorners 0; dragging 0 ] ]
entadd     = [ entaddmove; entmoving 0; ]
editmove   = [ moving 1; onrelease [ moving 0 ]; result $moving ]
entdrag    = [ entaddmove; onrelease [entmoving 0]; result $entmoving ] 
editdrag   = [ cancelsel; || (entdrag) [ drag ] ]
selcorners = [ if ($hmapedit) [ hmapselect ] [ cancelsel; || (entdrag) [ corners ] ] ]
editextend = [ || entdrag [ selextend; reorient; editmove ] ]

editmovewith    = [
  if (havesel) [
    || (editmove) [ @arg1 ]
    onrelease [ moving 0; dragging 0 ]
  ] [
    @arg1
  ]
]

editmovecorner = [ editmovewith selcorners ]
editmovedrag   = [ editmovewith editdrag ]

////// Other Editing commands /////////

editfacewentpush = [ 
  
  if (|| [havesel] [! (enthavesel)] ) [
    if ($moving) [ 
      pushsel $arg1 
    ] [ 
      entcancel
      editface $arg1 $arg2
    ] 
  ] [
      if ($entmoving) [ entpush $arg1 ] [ ent_action_@(et) ]
  ]
]

entswithdirection = "playerstart teledest mapmodel monster box barrel platform elevator"

inlist = [
  r = 0
  n = ( listlen $arg2 )
  loop i $n [
    if (strcmp $arg1 (at $arg2 $i)) [
      r = 1 
    ]
  ]
  result $r
]

entdirection = [
  if ( && (enthavesel) [ = (havesel) 0 ] ) [
    if (inlist (et) $entswithdirection) [
      if (> $arg1 0) [
        entproperty 0 @@arg2
        if (> (ea 0) 360) [ entproperty 0 -360 ]          
      ] [
        entproperty 0 -@@arg2
        if (< (ea 0) 0) [ entproperty 0 360 ]
      ]
    ]
    result 1
  ] [
    result 0
  ]
]

editdel    = [ delcube; delent ]
editflip   = [ flip; entflip ]

editrotate = [ 
  || [ entdirection $arg1 15 ] [ 
      rotate $arg1
      entrotate $arg1 
    ] 
]

editcut    = [  
  hadselection = (havesel)
  moving 1
  if ($moving) [
    copy;     entcopy
    delcube;  delent
    onrelease [ 
      moving 0
      paste
      entpaste
      if ( ! $hadselection ) [ cancelsel ]
    ]
  ]
]

passthrough = [ 
  passthroughsel $arg1; 
  if ($arg1) [
    passthroughcube_bak = $passthroughcube
    passthroughcube 1
  ] [
    passthroughcube $passthroughcube_bak
  ]
  entcancel 
  if ( setting_entediting ) [ entediting ( ! $arg1 ) ]
  
]

edithud = [
    if (enthavesel) [concatword (entget) " : " (enthavesel) " selected"]
]

