local safecom= {tell=1,say=1,sayto=1,whisper=1,whisperto=1,yell=1,emote=1,leave=1,follow=1,wear=1,remove=1,get=1,drop=1,put=1,push=1,pull=1,open=1,close=1,lock=1,unlock=1,tie=1,untie=1,kick=1,kill=1,swing=1,clean=1,dig=1,fill=1,empty=1,move=1,throw=1,eat=1,inject=1,give=1,mount=1,dismount=1,sit=1,stand=1,sleep=1,swim=1,surface=1,dive=1,fly=1,land=1,jump=1,trap=1,file_plan=1} local atab={ state="!state", cash="$cash", balance="$balance" } local argc=getn(arg) local tobj=nil local congeal=function(start) local s="" if %argc<start or start>getn(%arg) then return "" end if %argc==start then return %arg[start] end for i=start,%argc-1 do s=s..%arg[i].." " end s=s..%arg[%argc] return s end local str=function(tn) return %congeal(3),nil end local strt=function(tn,rs) if rs[tn] then return tn,nil else return nil,"Value ^W"..tn.."^n not found in legal value list." end end local strlt=function(tn,rs) local t=tn local s=nil local i=strfind(t,",",1,1) while i do s=strsub(t,1,i-1) t=strsub(t,i+1,-1) if !rs[s] then return nil,"Value ^W"..s.."^n not found in legal value list." end i=strfind(t,",",1,1) end if !rs[t] then return nil,"Value ^W"..t.."^n not found in legal value list." end return tn,nil end local strp=function(tn) if strfind(tn,"[^%l]") then return nil,"String must only contain lowercase letters." end return tn,nil end local strr=function(tn) if %safecom[tn] or actionverb(tn) then return %congeal(3) end return nil,"Use of unsafe command forbidden, or command not recognised." end local int=function(tn) local v=tonumber(tn) if v then return v,nil end return nil,"Value ^W"..tn.."^n is not an integer." end local intm=function(tn,rs) local v=tonumber(tn) if !v then return nil,"Value ^W"..tn.."^n is not an integer." end if v<rs then return nil,"Value ^W"..tn.."^n is below lower limit ^W"..rs.."^n." end return v,nil end local intr=function(tn,rs) local v=tonumber(tn) if !v then return nil,"Value is not an integer." end if v<rs[1] then return nil,"Value ^W"..tn.."^n is below lower limit ^W"..rs[1].."^n." end if v>rs[2] then return nil,"Value ^W"..tn.."^n is above upper limit ^W"..rs[2].."^n." end return v,nil end local obj=function(tn) if get(tn) then return tn,nil else return nil,"Value must be an object." end end local odash=function(tn) if get(tn) or tn=="-" then return tn,nil else return nil,"Value must be an object or -." end end local mdash=function(tn) if (get(tn) and getflag(tn, flag.Mobile)) or tn=="-" then return tn, nil else return nil,"Value must be an mobile or -." end end local intp=function(tn,rs) local v=tonumber(tn) if !v then return nil,"Value must be an integer" end if v<0 then return nil,"Value must be 0 or greater." end return v,nil end local ibin=function(tn,rs) local v=tonumber(tn) if !v then return nil,"Value must be an integer" end if v~=0 and v~=1 then return nil,"Value must be 0 or 1." end return v,nil end local worn=function(tn,rs) local wlv=getint(rs,"wornlevel") local won=getstr(rs,"wornon") if won and wlv>0 and (tn=="1" or tn=="true" or tn=="yes") then return 1,nil elseif won and wlv>0 and (tn=="0" or tn=="false" or tn=="no") then return 0,nil elseif won and wlv>0 then return nil,"Value must be 1 or 0." else return nil,"Object is not wearable." end end local weap=function(tn,rs) local dam=getint(rs,"damage") if dam>0 and (tn=="1" or tn=="true" or tn=="yes") then return 1,nil elseif dam>0 and (tn=="0" or tn=="false" or tn=="no") then return 0,nil elseif dam>0 then return nil,"Value must be 1 or 0." else return nil,"Object is not a weapon." end end local seat=function(tn,rs) local seat=getflag(rs,flag.CanSitOn) local sitter=get(tn) if seat and sitter and getflag(sitter,flag.Mobile) then return tn,nil elseif seat and sitter then return nil,"Only mobiles can be made to sit on things." elseif seat and !sitter then return nil,"Value must be a mobile ID." else return nil,"Object is not a seat." end end local oref=function(tn,rs,tgt) local suff=strfind(arg[2],"%.%l+$") if !suff then return nil,"Malformed attribute." end suff=strsub(arg[2],suff) local mpos=strfind(arg[2],suff,1,1) if !mpos then return nil,"Malformed attribute." end local orfs=strsub(arg[2],1,mpos-1) if !orfs then return nil,"Malformed attribute." end local orf=getobj(tgt,orfs) if !orf then return nil,"Missing or invalid object reference ^W"..orfs.."^n." end if rs then return rs(tn,orf) else return tn,nil end end local aref=function(tn,rs,tgt) local suff=strfind(arg[2],"%.%l+$") if !suff then return nil,"Malformed attribute." end suff=strsub(arg[2],suff) local mpos=strfind(arg[2],suff,1,1) if !mpos then return nil,"Malformed attribute." end local orfs=strsub(arg[2],1,mpos-1) if !orfs then return nil,"Malformed attribute." end local orf=getstr(tgt,orfs) if !orf then return nil,"Missing array reference ^W"..orfs.."^n." end if rs then return rs(tn,orf) else return tn,nil end end local wtype=function(tn) if tn=="1" or tn=="bashing" or tn=="impact" or tn=="bash" then return 1,nil end if tn=="2" or tn=="slashing" or tn=="cutting" or tn=="cut" or tn=="slash" then return 2,nil end if tn=="3" or tn=="energy" or tn=="laser" or tn=="plasma" then return 3,nil end if tn=="4" or tn=="stunning" or tn=="stun" then return 4,nil end if tn=="5" or tn=="stabbing" or tn=="piercing" or tn=="stab" or tn=="pierce" then return 5,nil end return nil,"Value must be a legal weapon type." end local zobj=function(tn) local z=get(tn.."_zone") if !z then return nil,"Zone ^W"..tn.."^n does not exist." end return tn,nil end local flg=function(tn,rs) local o=get(tn) if !o then return nil,"Cannot find object ^W"..tn.."^n." end if !getflag(o,rs) then return nil,"Object ^W"..tn.."^n is of the wrong type." end return tn,nil end local pers=function(tn,rs) local po=get(tn) if !po then return nil,"Cannot find object ^W"..tn.."^n." end if !person(po) then return nil,"Object ^W"..tn.."^n is not a person." end return tn,nil end local omob=function(tn,rs) local po=get(tn) if !po then return nil,"Cannot find object ^W"..tn.."^n." end if player(po) then return nil,"Object ^W"..tn.."^n is not an object or mobile." end return tn,nil end local iobj=function(tn,rs) local po=get(tn) if !po then return nil,"Cannot find object ^W"..tn.."^n." end if person(po) then return nil,"Object ^W"..tn.."^n is a person." end return tn,nil end --type / restrictions value --int integer --intp integer>=0 --intm min integer with minimum value restriction --intr {min,max} integer with min/max range restriction --str string --strt {"a","b"} one of the strings in the table --strlt {"a","b"} one or more of the strings in the table, separated by commas --strr resistricted string. tell, say, sayto, whisper, yell, trap, emote, get, drop, <action>, file_plan --pstr plain string- lowercase characters only --obj any object --odash any object or '-' --iobj inanimate (non-person) object --zobj checks for existence of <arg>_zone object --weap object with damage attribute >=1 --worn object with wornlevel int and wornon str attributes --flg flag.<Flag> object with specified flag --omob non-player --pers mobile or player --oref <function> given <string>.<int>.<string> attempts to get(<string>.<int>), and will pass it as a parameter to <function> --wtype 1-5, also accepts names for weapon types -- attr on values type values lev pfl local ptab={ { "service", pers, nil, intr, {0,5}, 0, 0 }, { "abv", iobj, nil, intr, {0,10000}, 0, 0 }, { "aggr", flg, flag.Mobile, intr, {0,100}, 0, 0 }, { "armour", omob, nil, intm, 0, 0, 0 }, { "damage", omob, nil, intm, 0, 0, 0 }, { "maxload", obj, nil, intm, 0, 0, 0 }, { "bankmob", flg, flag.Room, flg, flag.Mobile, 0, 0 }, { "body", pers, nil, strt, {insect=1,droid=1,avian=1,larva=1,snake=1,tetrapod=1,plant=1,tree=1,vehicle=1,lamidav=1,vehicle=1,human=1}, 0, 0 }, { "$cash", pers, nil, intr, {0,1000000}, 0, 0 }, { "$balance", pers, nil, int, nil, 0, 0 }, { "cost", omob, nil, intm, 0, 0, 0 }, { "discover", omob, nil, omob, nil, 0, 0 }, { "empty", iobj, nil, iobj, nil, 0, 0 }, { "door", iobj, nil, iobj, nil, 0, 0 }, { "food", omob, nil, int, nil, 0, 0 }, { "gender", pers, nil, strt, {m=1,f=1,n=1,a=1}, 0, 0 }, { "key", iobj, nil, obj, nil, 0, 0 }, { "link", iobj, nil, obj, nil, 0, 0 }, { "lock", iobj, nil, obj, nil, 0, 0 }, { "name", obj, nil, str, nil, 0, 0 }, { "nation", obj, nil, strp, nil, 0, 0 }, { "mass", obj, nil, intm, 0, 0, 0 }, { "short", obj, nil, strp, nil, 0, 0 }, { "altshort", obj, nil, strp, nil, 0, 0 }, { "short_desc.%i", omob, nil, str, nil, 0, 0 }, { "short_desc", omob, nil, str, nil, 0, 0 }, { "desc.%i", omob, nil, str, nil, 0, 0 }, { "desc", obj, nil, str, nil, 0, 0 }, { "shopmob", flg, flag.Room, flg, flag.Mobile, 0, 0 }, { "other", iobj, nil, obj, nil, 0, 0 }, { "start", obj, nil, obj, nil, 0, 0 }, { "maxstrength", pers, nil, intm, 1, 0, 0 }, { "wornon", iobj, nil, strlt, {hands=1,feet=1,hand=1,foot=1,arm=1,arms=1,leg=1,legs=1,finger=1,limb=1,body=1,neck=1,head=1,lapel=1,face=1,eyes=1,eye=1}, 0, 0 }, { "wornlevel", iobj, nil, intr, {0,5}, 0, 0 }, { "ovolume", iobj, nil, intm, 0, 0, 0 }, { "volume", iobj, nil, intm, 0, 0, 0 }, { "tell.%s", flg, flag.Mobile, strr, nil, 0, 0 }, { "tell.%s.%i", flg, flag.Mobile, strr, nil, 0, 0 }, { "tell.%s.%s", flg, flag.Mobile, strr, nil, 0, 0 }, { "tell.%s.%s.%i", flg, flag.Mobile, strr, nil, 0, 0 }, { "telldefault", flg, flag.Mobile, strr, nil, 0, 0 }, { "rant.%i", omob, nil, strr, nil, 0, 0 }, { "rant.count", omob, nil, intm, 0, 0, 0 }, { "rantspeed", omob, nil, intm, 1, 0, 0 }, { "skill.combat", pers, nil, intr, {0,150}, 0, 0 }, { "stype", omob, nil, stpr, nil, 0, 0 }, { "shop.ripoff", omob, nil, intr, {1,500}, 0, 0 }, { "shop.offer", omob, nil, intr, {1,500}, 0, 0 }, { "shop.count", omob, nil, intm, 1, 0, 0 }, { "shop.%i", omob, nil, obj, nil, 0, 0 }, { "shop.%i.istock", omob, nil, oref, intp, 0, 0 }, { "shop.%i.atonce", omob, nil, oref, intp, 0, 0 }, { "auto.%i", omob, nil, obj, nil, 0, 0 }, { "auto.%i.worn", omob, nil, oref, worn, 0, 0 }, { "auto.%i.wield", omob, nil, oref, weap, 0, 0 }, { "auto.%i.count", omob, nil, oref, intp, 0, 0 }, { "auto.count", omob, nil, intm, 1, 0, 0 }, { "auto.%i.seatfor", omob, nil, oref, seat, 0, 0 }, { "tele.%i", flg, flag.Room, obj, nil, 0, 0 }, { "tele.%i.count", flg, flag.Room, oref, intp, 0, 0 }, { "tele.%i.vis", flg, flag.Room, oref, ibin, 0, 0 }, { "tele.count", flg, flag.Room, intm, 1, 0, 0 }, { "fwd", iobj, nil, obj, nil, 0, 0 }, { "planet", iobj, nil, str, nil, 0, 0 }, { "coproom", iobj, nil, flg, flag.Room, 0, 0 }, { "interview", iobj, nil, flg, flag.Room, 0, 0 }, { "hospital", iobj, nil, flg, flag.Room, 0, 0 }, { "floor", iobj, nil, odash, nil, 0, 0 }, { "wornfrom", flg, flag.Mobile, mdash, nil, 0, 0 }, { "wtype", iobj, nil, wtype, nil, 0, 0 }, { "barwhy", flg, flag.Mobile, strr, nil, 0, 0 }, { "name.plural", omob, nil, str, nil, 0, 0 }, { "long", omob, nil, str, nil, 0, 0 }, { "long.plural", omob, nil, str, nil, 0, 0 }, { "initstate", omob, nil, intm, 0, 0, 0 }, { "!state", omob, nil, intm, 0, 0, 0 }, { "zone", any, nil, zobj, nil, 0, 0 }, { "contains", iobj, nil, obj, nil, 0, 0 }, { "pockets", obj, nil, intm, 0, 0, 0 }, { "att.%s", flg, flag.Mobile, intr, {1,50}, 0, 0 }, { "substance", iobj, nil, obj, nil, 0, 0 }, { "serving", iobj, nil, intm, 1, 0, 0 }, { "key", iobj, nil, obj, nil, 0, 0 }, { "lock", iobj, nil, obj, nil, 0, 0 }, { "quest", iobj, nil, flg, flag.Quest, 0, 0 }, { "candig", iobj, nil, intr, {0,1}, 0, 0 }, { "climbto", iobj, nil, flg, flag.Room, 0, 0 }, { "dir", iobj, nil, strp, nil, 0, 0 }, { "fount", iobj, nil, obj, nil, 0, 0 }, { "nth", iobj, nil, str, nil, 0, 0 }, { "office", iobj, nil, str, nil, 0, 0 }, { "home", iobj, nil, flg, flag.Room, 0, 0 }, { "mname", iobj, nil, str, nil, 0, 0 }, { "mzone", iobj, nil, zobj, nil, 0, 0 }, { "reward", iobj, nil, intm, 0, 0, 0 }, { "minitag", iobj, nil, strp, nil, 0, 0 }, { "board", iobj, nil, obj, nil, 0, 0 }, { "questpoints", iobj, nil, intm, 0, 0, 0 }, { "short_brief", iobj, nil, str, nil, 0, 0 }, { "quest_needed", flg, flag.Quest, flg, flag.Quest, 0, 0 }, { "mutex", flg, flag.Quest, flg, flag.Quest, 0, 0 }, { "siton.start", flg, flag.Mobile, flg, flag.CanSitOn, 0, 0 }, { "wander.time", obj, nil, intm, 1, 0, 0 }, { "allowpast", flg, flag.Mobile, str, nil, 0, 0 }, { "riding_verb", omob, nil, str, nil, 0, 0 }, { "motionverb", omob, nil, str, nil, 0, 0 }, { "stepon_p", omob, nil, str, nil, 0, 0 }, { "stepon_s", omob, nil, str, nil, 0, 0 }, { "stepoff_p", omob, nil, str, nil, 0, 0 }, { "stepoff_s", omob, nil, str, nil, 0, 0 }, { "saddelof", omob, nil, str, nil, 0, 0 }, { "room_name", flg, flag.Room, str, nil, 0, 0 }, { "building", flg, flag.Room, str, nil, 0, 0 }, { "enpara", flg, flag.Room, intr, {0,1}, 0, 0 }, { "ship_class", iobj, nil, str, nil, 0, 0 }, { "room.%i", iobj, nil, flg, flag.Room, 0, 0 }, { "room.count", iobj, nil, intm, 1, 0, 0 }, { "ship", iobj, nil, obj, nil, 0, 0 }, { "holoid", iobj, nil, int, nil, 0, 0 }, { "entry_room", iobj, nil, flg, flag.Room, 0, 0 }, { "panel", iobj, nil, obj, nil, 0, 0 }, { "dock.name", iobj, nil, str, nil, 0, 0 }, { "dock.head", iobj, nil, str, nil, 0, 0 }, { "dock.code", iobj, nil, str, nil, 0, 0 }, { "dock.info", iobj, nil, str, nil, 0, 0 }, { "dock.city", iobj, nil, str, nil, 0, 0 }, { "dock.planet", iobj, nil, str, nil, 0, 0 }, { "dock.star", iobj, nil, str, nil, 0, 0 }, { "dock.%i", iobj, nil, flg, flag.Room, 0, 0 }, { "dock.count", iobj, nil, intm, 1, 0, 0 }, { "port.name", flg, flag.Room, str, nil, 0, 0 }, { "dock", flg, flag.Room, obj, nil, 0, 0 }, { "on_examine", iobj, nil, strt, {dslist=1}, 0, 0 }, { "height", iobj, nil, intm, 0, 0, 0 }, { "daylen", iobj, nil, intm, 0, 0, 0 }, { "timezone", iobj, nil, intr, {0,23}, 0, 0 }, { "stop.%i", iobj, nil, flg, flag.Room, 0, 0 }, { "stop.count", iobj, nil, intm, 1, 0, 0 }, { "stop.route", iobj, nil, intr, {0,1}, 0, 0 }, { "stop.circle", iobj, nil, intr, {0,1}, 0, 0 }, { "$record.%i", pers, nil, aref, str, 0, 0 }, { "$record.%i.fine", pers, nil, aref, intp, 0, 0 }, { "$record.%i.when", pers, nil, aref, intp, 0, 0 }, { "$record.count", pers, nil, intm, 1, 0, 0 }, { "crim.convict", pers, nil, intm, 0, 0, 0 }, { "crim.fine", pers, nil, intm, 0, 0, 0 } } local getreq=function(fun,dat) local req="" if fun==%obj then return "any object" elseif fun==%str then return "any string" elseif fun==%int then return "any integer" elseif fun==%omob then return "non-players" elseif fun==%odash then return "an object or -" elseif fun==%mdash then return "a mobile or -" elseif fun==%iobj then return "non-persons" elseif fun==%strt then return "a restricted string" elseif fun==%strr then return "a safe command string" elseif fun==%strlt then return "a list of restricted strings" elseif fun==%intm then return "an integer above "..dat elseif fun==%intr then return "an integer between "..dat[1].." and "..dat[2] elseif fun==%strp then return "a lowercase word" elseif fun==%zobj then return "a zone" elseif fun==%pers then return "persons" elseif fun==%flg then if dat==flag.Room then return "a room" end if dat==flag.Mobile then return "a mobile" end if dat==flag.CanSitOn then return "a seat" end if dat==flag.Quest then return "a mission object" end elseif fun==%oref then if dat==%intp then return "an integer >=0" end if dat==%worn then return "1 or 0, where reference is wearable" end if dat==%weap then return "1 or 0, where reference is weapon" end if dat==%seat then return "1 or 0, where reference is a seat" end if dat==%ibin then return "1 or 0" end elseif fun==%aref then if dat==%intp then return "an integer >=0" end if dat==%str then return "any string" end else return "unknown" end end if arg[1]=="list" then local clin="" local areq="" local treq="" startpager(pl) send(pl,"Set can affect the following attributes...") send(pl,format("%-16s %-16s %-16s","Attribute name","Allowed Target","Allowed Values")) for i,v in ptab do treq=getreq(v[2],v[3]) areq=getreq(v[4],v[5]) clin=format("%-16s %-16s %-16s",v[1],treq,areq) if clin then send(pl," "..clin) end end return end if argc<3 then send(pl,"Expected: ^Wset ^b<^Bobject^b> <^Battribute^b> <^Bvalue^b>^n") return end --step 1: can they touch this object? local prv=privs(pl) if getflag(pl,flag.Mobile) then prv=19 end if prv<19 then send(pl,"Only Captain+ can use set.") return end if arg[1]=="here" then tobj=owner(pl) end if !tobj then tobj=matchplayer(pl,arg[1]) end if !tobj then tobj=match(pl,{arg[1]}) tobj=tobj[1] end if !tobj then tobj=get(arg[1]) end if !tobj then send(pl,"Cannot find ^W"..arg[1].."^n.") return end local zstr=getstr(tobj,"zone") local mstr=getstr(pl,"zone") if zstr and zstr~="@auto" and !getpriv(pl,priv.EditAll) and (!mstr or mstr~=zstr) then local zone=get(zstr.."_zone") if zone then local auths=getstr(zone,"author") if auths and !inlist(pl,auths) then send(pl,"You do not have permission to make any changes to that zone.") return end end end if prv<9993 then --capt privs if player(tobj) and obj~=pl then send(pl,"You cannot set properties on other players.") return end end if prv<privs(tobj) then --comm privs if person(tobj) then send(pl,"You do not have sufficient rank to change anything about them.") else send(pl,"You do not have sufficient rank to change anything about that.") end return end local val=arg[3] local att=atab[arg[2]] if !att then att=arg[2] end for i, v in ptab do local m=nil if !strfind(v[1],"%%%l") and v[1]==att then m=1 else local pat=gsub(v[1],"%%s","%%l+") local pat=gsub(pat,"%%i","%%d+") local pat=gsub(pat,"%.","%%.") pat="^"..pat.."$" if strfind(arg[2],pat) then m=1 end end if m then if prv<v[6] then send(pl,"You do not have sufficient rank to alter that attribute.") return end local sv,err = v[2](getstr(tobj,"id"),v[3]) if !sv then send(pl,"You cannot change that attribute on that target: "..err) return end sv,err = v[4](arg[3],v[5],tobj) if !sv then send(pl,"That is not a legal value for that attribute: "..err) return end set(tobj,att,sv) send(pl,"Done.") return end end send(pl,"You cannot use set to alter that attribute.")