/* Ultima Offline eXperiment III (UOX3) UO Server Emulation Program Copyright 1997, 98 by Marcus Rating (Cironian) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * In addition to that license, if you are running this program or modified * * versions of it on a public system you HAVE TO make the complete source of * * the version used by you available or provide people with a location to * * download it. * You can contact the author by sending email to . */ #include "uox3.h" #include "srvkey.h" #include "debug.h" #define DBGFILE "uox3.cpp" int tempint[MAXCLIENT]; // EviLDeD - Instance of the CWorldMain Class // December 23, 1998 CWorldMain cwmWorldState; // EviLDeD - End void dostreamcode(int s) { int actByte = 0, bitByte = 0, nrBits; unsigned int value; for(int tempPos = 0; tempPos <= boutlength[s]; tempPos++) { if(tempPos == boutlength[s]) value = keyid[256]; else value = keyid[(unsigned char)outbuffer[s][tempPos]]; nrBits = value & 0xF; value >>= 4; while(nrBits) { xoutbuffer[actByte] = (char)(((unsigned int)xoutbuffer[actByte] << 1) + ((value >> (nrBits - 1)) & 0x1)); nrBits--; bitByte++; if(bitByte == 8) { bitByte = 0; actByte++; } } } if(bitByte) { while(bitByte < 8) { xoutbuffer[actByte] <<= 1; bitByte++; } actByte++; } send(client[s], xoutbuffer, actByte, 0); } #ifdef __NT__ /////////////////// HANDLE hco; CONSOLE_SCREEN_BUFFER_INFO csbi; void gotoxy(int x, int y) { COORD xy; xy.X=x; xy.Y=y; SetConsoleCursorPosition(hco, xy); } void clearscreen() { #ifdef __MINGW32__ // my compiler doesn't like long value unsigned int y; #else unsigned long int y; #endif COORD xy; xy.X=0; xy.Y=0; FillConsoleOutputCharacter(hco, ' ', 80*25, xy, &y); SetConsoleCursorPosition(hco, xy); } void constart() { hco=GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hco, &csbi); } /////////////////// #endif #ifndef __NT__ void closesocket(int s) { shutdown(s, 2); close(s); } #endif char crypt (int s, char c) { unsigned int mask[2]; mask[0] = cryptmask[s][0]; mask[1] = cryptmask[s][1]; cryptmask[s][1] = (MASTERKEY1 >> ((5 * mask[1] * mask[1]) & 0xff)) + (mask[1] * MASTERKEY1) + (mask[0] * mask[0] * MASTERKEY2) + MASTERKEY3; cryptmask[s][0] = (MASTERKEY4 >> ((3 * mask[0] * mask[0]) & 0xff)) + (mask[0] * MASTERKEY4) - (cryptmask[s][1] * cryptmask[s][1] * MASTERKEY5) + MASTERKEY6; return c ^ (char)mask[0]; } int xrecv(int s) // Better receive routine than the one currently used; not intergrated yet { int count, i; #ifdef DEBUG int x, y, j; char st[10], txt[17]; #endif count=recv(client[s], &buffer[s][binlength[s]], MAXBUFFER-binlength[s], 0); #ifdef DEBUG x=0; #endif for (i=binlength[s];i0;j--) printf("0"); printf("%s] ", st); } sprintf(st, "%X", buffer[s][i]); if (strlen(st)==2) printf("%s ", st); else printf("0%s ", st); if (!(iscntrl(buffer[s][i]))) txt[y]=buffer[s][i]; else txt[y]='.'; if (y==15) { txt[16]=0; printf("%s\n", txt); } x++; #endif } binlength[s]+=count; #ifdef DEBUG if ((y)!=15) { txt[y+1]=0; for (j=15-y;j>0;j--) printf(" "); printf("%s\n",txt); } #endif return count; } void processed(int s, int i) // To be used later together with xrecv { memcpy(buffer[s], &buffer[s][i], binlength[s]-i); binlength[s]-=i; if (binlength[s]<0) binlength[s]=0; } void flushbuffer(int s) // Sends buffered data at once { if (boutlength[s]>0) { // printf("S = %i, bout = %i, cc = %i\n", s, boutlength[s], cryptclient[s]); if (cryptclient[s]) { dostreamcode(s); } else { send(client[s], outbuffer[s], boutlength[s], 0); } boutlength[s]=0; // printf("Done\n"); } } void clearbuffers() // Sends ALL buffered data { int i; for (i=0;i ", s, length); test=test; if (boutlength[s]+length>MAXBUFFER) flushbuffer(s); memcpy(&outbuffer[s][boutlength[s]], point, length); boutlength[s]+=length; // printf("%i\n", boutlength[s]); } int str2num(char *s) // Convert string to integer { unsigned int i; int n=0; int neg=0; unsigned int length=strlen(s); for(i=0;i=65) && (s[i]<=70)) // Uppercase A-F n=n+(s[i])-65+10; if ((s[i]>=97) && (s[i]<=102)) // Lowercase A-F n=n+(s[i])-97+10; } if (s[0]=='-') n=-n; return n; } void readscript () // Read a line from the opened script file { int i, valid=0; char c; temp[0]=0; while(!valid) { i=0; if (feof(scpfile)) return; c=(char)fgetc(scpfile); while (c!=10) { if (c!=13)// && c!=0) { temp[i]=c; i++; } if (feof(scpfile)) return; c=(char)fgetc(scpfile); } temp[i]=0; valid=1; if (temp[0]=='/' && temp[1]=='/') valid=0; if (temp[0]=='{') valid=0; if (temp[0]==0) valid=0; } } void openscript (char *name) // Open script file { scpfile=fopen(name,"r"); if (scpfile==NULL) { printf("ERROR: %s not found...\n",name); error=1; keeprun=0; return; } openings++; // printf("Openings: %i\n",openings); } void closescript () { fclose(scpfile); openings--; } void read1 () // Read script line without splitting parameters { readscript(); sprintf(script1, "%s", temp); } void read2 () // Read line from script { int i; readscript(); i=0; script1[0]=0; script2[0]=0; while(temp[i]!=0 && temp[i]!=' ') { i++; } strncpy(script1, temp, i); script1[i]=0; if (script1[0]!='}' && temp[i]!=0) strcpy(script2, temp+i+1); return; } void psplit (char *pass0) // Split login password into UOX password and UO password { int i; i=0; pass1[0]=0; while (pass0[i]!='/' && pass0[i]!=0) i++; strncpy(pass1,pass0,i); pass1[i]=0; if (pass0[i]!=0) strcpy(pass2, pass0+i+1); } int inrange1 (int a, int b) // Are players from sockets a and b in visual range (Obsolete) { int c=1; int xa, xb, ya, yb, dx, dy; if (a==b) c=0; xa=chars[currchar[a]].x; ya=chars[currchar[a]].y; xb=chars[currchar[b]].x; yb=chars[currchar[b]].y; dx=abs(xa-xb); dy=abs(ya-yb); if (dx>VISRANGE) c=0; if (dy>VISRANGE) c=0; return c; } int inrange1p (int a, int b) // Are characters a and b in visual range { int c=1; int xa, xb, ya, yb, dx, dy; xa=chars[a].x; ya=chars[a].y; xb=chars[b].x; yb=chars[b].y; dx=abs(xa-xb); dy=abs(ya-yb); if (dx>VISRANGE) c=0; if (dy>VISRANGE) c=0; return c; } unsigned int chardist (int a, int b) // Distance between characters a and b { int c=1; int xa, xb, ya, yb, dx, dy; xa=chars[a].x; ya=chars[a].y; xb=chars[b].x; yb=chars[b].y; dx=abs(xa-xb); dy=abs(ya-yb); #ifdef __NT__ c=(int)(sqrt(dx*dx+dy*dy)); #else c=(int)(hypot(dx, dy)); #endif return c; } int inrange2 (int s, int i) // Is item i in visual range for player on socket s { int c=1; int xa, xb, ya, yb, dx, dy; int vr=VISRANGE; if ((items[i].id1==0x40)&&(items[i].id2>=0x7C)&&(items[i].id2<=0x7F)) vr=BUILDRANGE; xa=chars[currchar[s]].x; ya=chars[currchar[s]].y; xb=items[i].x; yb=items[i].y; dx=abs(xa-xb); dy=abs(ya-yb); if (dx>vr) c=0; if (dy>vr) c=0; return c; } int online(int c) // Is the player owning the character c online { int i, x=0; for (i=0;ib) { a=i; b=chars[p].baseskill[i]; } return a; } void loadcustomtitle() // for custom titles { int titlecount=0; char sect[512]; openscript("titles.scp"); sprintf(sect,"SKILL"); if(!titles_script.find(sect)) { closescript(); return; } do { read2(); if (script1[0]!='}') { sprintf(title[titlecount].skill,"%s", script1); titlecount++; } } while (script1[0]!='}'); closescript(); script1[0]=0; titlecount=0; openscript("titles.scp"); sprintf(sect,"PROWESS"); if(!titles_script.find(sect)) { closescript(); return; } do { read2(); if (script1[0]!='}') { sprintf(title[titlecount].prowess,"%s", script1); titlecount++; } } while (script1[0]!='}'); closescript(); script1[0]=0; titlecount=0; openscript("titles.scp"); sprintf(sect,"FAME"); if(!titles_script.find(sect)) { closescript(); return; } do { read2(); if (script1[0]!='}') { sprintf(title[titlecount].fame,"%s", script1); if (titlecount==23) { *(title[titlecount].fame)='\0'; // was sprintf(title[titlecount].fame,""); sprintf(title[++titlecount].fame,"%s", script1); } titlecount++; } } while (script1[0]!='}'); closescript(); } char *title1(int p) // Paperdoll title for character p (1) { int titlenum; int x=chars[p].baseskill[bestskill(p)]; titlenum=0; if (x>=300) titlenum=1; if (x>=410) titlenum=2; if (x>=510) titlenum=3; if (x>=610) titlenum=4; if (x>=720) titlenum=5; if (x>=820) titlenum=6; if (x>=920) titlenum=7; if (x>=1000) titlenum=8; sprintf(prowesstitle,"%s",title[titlenum].prowess); return prowesstitle; } char *title2(int p) // Paperdoll title for character p (2) { int titlenum=0; int x=bestskill(p); titlenum=x+1; sprintf(skilltitle,"%s",title[titlenum].skill); return skilltitle; } char *title3(int p) // Paperdoll title for character p (3) { char thetitle[50]; int titlenum=0; int k; unsigned int f; k=chars[p].karma; f=chars[p].fame; *thetitle='\0'; // was sprintf(thetitle,""); if (k>=10000) { titlenum=3; if (f>=1250) titlenum=2; if (f>=2500) titlenum=1; if (f>=5000) titlenum=0; } else if ((5000<=k)&&(k<9999)) { titlenum=7; if (f>=1250) titlenum=6; if (f>=2500) titlenum=5; if (f>=5000) titlenum=4; } else if ((2500<=k)&&(k<5000)) { titlenum=11; if (f>=1250) titlenum=10; if (f>=2500) titlenum=9; if (f>=5000) titlenum=8; } else if ((1250<=k)&&(k<2500)) { titlenum=15; if (f>=1250) titlenum=14; if (f>=2500) titlenum=13; if (f>=5000) titlenum=12; } else if ((625<=k)&&(k<1250)) { titlenum=19; if (f>=500) titlenum=18; if (f>=1000) titlenum=17; if (f>=5000) titlenum=16; } else if ((-625=1250) titlenum=22; if (f>=2500) titlenum=21; if (f>=5000) titlenum=20; } else if ((-1250=1250) titlenum=25; if (f>=2500) titlenum=26; if (f>=5000) titlenum=27; if (f>=10000) titlenum=28; } else if ((-2500=1250) titlenum=30; if (f>=2500) titlenum=31; if (f>=5000) titlenum=32; } else if ((-5000=1250) titlenum=34; if (f>=2500) titlenum=35; if (f>=5000) titlenum=36; if (f>=10000) titlenum=37; } else if ((-10000=1250) titlenum=39; if (f>=2500) titlenum=40; if (f>=5000) titlenum=41; } else if (k<=-10000) { titlenum=42; if (f>=1250) titlenum=43; if (f>=2500) titlenum=44; if (f>=5000) titlenum=45; } sprintf(thetitle,"%s ",title[titlenum].fame); if (titlenum==24) *thetitle='\0'; // was sprintf(thetitle,""); if (f>=10000) { if (chars[p].id2==0x91) sprintf(fametitle,"The %sLady ",thetitle); else sprintf(fametitle,"The %sLord ",thetitle); } else { if (!(strcmp(thetitle," ")==0)) sprintf(fametitle,"The %s",thetitle); else *fametitle='\0'; // was sprintf(fametitle,""); } return fametitle; } int memcharfree() { int i,k; k=-1; if (cmemcheck!=-1) { k=freecharmem[cmemcheck]; cmemcheck--; } if (k==-1) { k=charcount; if (cmemover==1) { cmemover=0; cmemcheck++; for (i=0;i0); if (rtotal>0) printf("GCOL: Removed %i items.\n",rtotal); } void deletechar (int k) // Delete character { int j; removeitem[1]=chars[k].ser1; removeitem[2]=chars[k].ser2; removeitem[3]=chars[k].ser3; removeitem[4]=chars[k].ser4; j=removefromptr(&charsp[chars[k].serial%256], k); if (chars[k].spawnserial!=-1) j=removefromptr(&cspawnsp[chars[k].spawnserial%256], k); if (chars[k].ownserial!=-1) j=removefromptr(&cownsp[chars[k].ownserial%256], k); for (j=0;jk) currchar[j]--; } chars[k].free=1; chars[k].x=20+(xcounter++); chars[k].y=50+(ycounter); chars[k].z=9; chars[k].summontimer=0; if (xcounter==40) { ycounter++; xcounter=0; } if (ycounter==80) { ycounter=0; xcounter=0; } if (cmemcheck<300) { cmemcheck++; freecharmem[cmemcheck]=k; } else cmemover=1; gcollect(); } void readwscline () // Read line from UOX3.WSC { int i, valid=0; char c; temp[0]=0; while (!valid) { i=0; if (feof(wscfile)) return; c=(char)fgetc(wscfile); while (c!=10) { if (c!=13)// && c!=0) { temp[i]=c; i++; } if (feof(wscfile)) return; c=(char)fgetc(wscfile); } temp[i]=0; valid=1; if (temp[0]=='/' && temp[1]=='/') valid=0; if (temp[0]=='{') valid=0; if (temp[0]==0) valid=0; } } void readw2 () { int i=0; readwscline(); script1[0]=0; script2[0]=0; script3[0]=0; while(temp[i]!=0 && temp[i]!=' ') i++; strncpy(script1, temp, i); script1[i]=0; if (script1[0]!='}' && temp[i]!=0) strcpy(script2, temp+i+1); return; } void readw3 () { int i=0,j; readwscline(); script1[0]=0; script2[0]=0; script3[0]=0; while(temp[i]!=0 && temp[i]!=' ') i++; strncpy(script1, temp, i); script1[i]=0; if (script1[0]=='}' || temp[i]==0) return; i++; j=i; while(temp[i]!=0 && temp[i]!=' ') i++; strncpy(script2, temp+j, i-j); script2[i-j]=0; strcpy(script3, temp+i+1); } void loadchar(int x) // Load a character from WSC { unsigned long int i; int j; x=charcount; charcount++; initchar(x); //initchar automatically adds to pointer array, remove cuz we don't know char //serial # yet. removefromptr(&charsp[chars[x].serial%256], x); chars[x].ser1=0; chars[x].ser2=0; chars[x].ser3=0; chars[x].ser4=0; chars[x].serial=0; chars[x].dir=4; chars[x].hp=chars[x].st=10; chars[x].stm=chars[x].dx=10; chars[x].mn=chars[x].in=10; for (i=0;i=1) { char time_str[80]; FILE *file; file=fopen(logfile,"a"); fprintf(file,"[%s] %s",RealTime(time_str),msg); #ifdef DEBUG printf("DEBUG: Logging to %s\n", logfile); #endif fclose(file); } } void loadnewworld () // Load world from UOX3.WSC { charcount=0; itemcount=0; charcount2=1; itemcount2=0x40000000; wscfile=fopen("uox3.wsc", "r"); if (wscfile==NULL) { printf("ERROR: UOX3.WSC not found, using blank world instead\n"); return; } printf("Loading UOX3.WSC...\n"); do { readw3(); if (!(strcmp(script1, "SECTION"))) { if (!(strcmp(script2, "CHARACTER"))) { loadchar(str2num(script3)); } if (!(strcmp(script2, "WORLDITEM"))) { loaditem(str2num(script3)); } } } while (strcmp(script1, "EOF")); fclose(wscfile); } void splitline () // For putting single words of cline into comm array { int i=0; char *s; char *d; d=" "; s=strtok(cline,d); while (s!=NULL) { comm[i]=s; i++; s=strtok(NULL,d); } tnum=i; } int makenumber (int countx) // Converts decimal string comm[count] to int { unsigned int i; int n=0; unsigned int length=strlen(comm[countx]); for(i=0;i=65) && (comm[countx][i]<=70)) // Uppercase A-F n=n+(comm[countx][i])-65+10; if ((comm[countx][i]>=97) && (comm[countx][i]<=102)) // Lowercase A-F n=n+(comm[countx][i])-97+10; } if (comm[countx][0]=='-') n=-n; return n; } int makenum2(char *s) // Converts string to integer { unsigned int i; int n=0; unsigned int length=strlen(s); for(i=0;i> 16) | (((~seed) ^ 0xabcdffff) & 0xffff0000); } char mapheight(int x, int y) // Height of MAP0.MUL at given coordinates { long int pos; int x1, x2; int y1, y2; char z; x1=x/8; // Block y1=y/8; x2=(x-(x1*8)); // Offset y2=(y-(y1*8)); pos=(x1*512*196)+(y1*196)+(y2*24)+(x2*3)+4+2; fseek(mapfile, pos, SEEK_SET); z=(char) fgetc(mapfile); return z; } char maptype(int x, int y) // Height of MAP0.MUL at given coordinates { long int pos; int x1, x2; int y1, y2; char z; x1=x/8; // Block y1=y/8; x2=(x-(x1*8)); // Offset y2=(y-(y1*8)); pos=(x1*512*196)+(y1*196)+(y2*24)+(x2*3)+4; fseek(mapfile, pos, SEEK_SET); z=(char) fgetc(mapfile); if (z!=68) return 1; z=(char) fgetc(mapfile); if (z!=2) return 1; return 0; } long int verseek(long int file, long int block) { long int vers, i; versionrecord ver; fseek(verfile, 0, SEEK_SET); fread(&vers, 4, 1, verfile); for (i=0;i=0x4000) { sprintf((*tile).name, "multi"); (*tile).flag1=0; (*tile).flag2=0; (*tile).flag3=0; (*tile).flag4=0; (*tile).weight=255; (*tile).height=0; } else { block=(tilenum/32)+1; if (!vertile(tilenum, tile)) { pos=TILEDATA_TILES+(block*4)+(sizeof(tile_st)*tilenum); fseek(tilefile, pos, SEEK_SET); fread(tile, sizeof(tile_st), 1, tilefile); } } } char verland(int landnum, land_st *land) { long int pos, block; block=(landnum/32); if (verseek(VERFILE_TILEDATA, block)==0) { // printf("No Ver\n"); return 0; } else { // printf("Ver\n"); pos=4+(sizeof(land_st)*(landnum%32)); fseek(verfile, pos, SEEK_CUR); fread(land, sizeof(land_st), 1, verfile); return 1; } } void seekland(int landnum, land_st *land) { long int pos, block; block=(landnum/32)+1; if (!verland(landnum, land)) { pos=(block*4)+(sizeof(land_st)*landnum); fseek(tilefile, pos, SEEK_SET); fread(land, sizeof(land_st), 1, tilefile); } } void seekmulti(int multinum, FILE **mfile, long int *length) { int len; st_multiidx multiidx; len=verseek(VERFILE_MULTI, multinum); if (len==0) { fseek(midxfile, multinum*sizeof(st_multiidx), SEEK_SET); fread(&multiidx, sizeof(st_multiidx), 1, midxfile); fseek(multifile, multiidx.start, SEEK_SET); *mfile=multifile; *length=multiidx.length; } else { *mfile=verfile; *length=len; } } char tileheight(int tilenum) { tile_st tile; seektile(tilenum, &tile); if (tile.flag2&4) tile.height=tile.height/2; // For Stairs+Ladders if (!(tile.flag2&2)) tile.height=0; return (tile.height); } //o-------------------------------------------------------------o //| Function : char staheight(int x,int y,int oldz); //| Date : Unknown Touched: Dec 21, 1998 //| Programmer : Unknown //o-------------------------------------------------------------o //| Purpose : Height of statics at/above given coordinates //o-------------------------------------------------------------o char staheight(int x, int y, int oldz) { long int pos, pos2, length; int x1, x2; int y1, y2; signed char z, ztemp, found; int i; staticrecord stat; // EviLDeD - Bug killing memset(&stat,0,sizeof(staticrecord)); stat.itemid=stat.itemid; stat.extra=stat.extra; z=-127; found=0; x1=x/8; // Block y1=y/8; x2=(x-(x1*8)); // Offset y2=(y-(y1*8)); pos=(x1*512*12)+(y1*12); fseek(sidxfile, pos, SEEK_SET); fread(&pos2, 4, 1, sidxfile); if (pos2!=-1) { if (feof(sidxfile)) { printf("Error: Avoiding bad read crash.\n"); return 0; } fread(&length, 4, 1, sidxfile); length=length/7; fseek(statfile, pos2, SEEK_SET); for (i=0;iz)) { z=ztemp; found=1; } } } } return z; } // Height of dynamic items at/above given coordinates char dynheight(int x, int y, int oldz) { int i; signed char z=-127, ztemp; for (i=0;iz)) { z=ztemp; } } } return z; } char height(int x, int y, int oldz) // Height of player who walked to X/Y/OLDZ { signed char mapz, staz, dynz, z; mapz=mapheight(x, y); staz=staheight(x, y, oldz); dynz=dynheight(x, y, oldz); if (staz==-127) z=mapz; else z=staz; if (dynz!=-127) z=dynz; return z; } int cgold2(int item) // Calculate total gold { char i1, i2, i3, i4; int i, total=0, serial,ci; i1=items[item].ser1; i2=items[item].ser2; i3=items[item].ser3; i4=items[item].ser4; serial=calcserial(i1,i2,i3,i4); for (ci=0;ci150) items[ci].x=150; if (items[ci].y>140) items[ci].y=140; //end fix bpitem[0]=items[ci].ser1; bpitem[1]=items[ci].ser2; bpitem[2]=items[ci].ser3; bpitem[3]=items[ci].ser4; bpitem[4]=items[ci].id1; bpitem[5]=items[ci].id2; bpitem[7]=items[ci].amount/256; bpitem[8]=items[ci].amount%256; bpitem[9]=items[ci].x/256; bpitem[10]=items[ci].x%256; bpitem[11]=items[ci].y/256; bpitem[12]=items[ci].y%256; bpitem[13]=a1; bpitem[14]=a2; bpitem[15]=a3; bpitem[16]=a4; bpitem[17]=items[ci].color1; bpitem[18]=items[ci].color2; bpitem[21]=items[ci].decaytime=0;// reseting the decaytimer in the backpack xsend(s, bpitem, 19, 0); } } // xsend(s, restart, 2, 0); } void backpack2(int s, int a1, int a2, int a3, int a4) // Send corpse stuff { int i, count=0, count2,serial,serhash,ci; char bpopen2[6]="\x3C\x00\x05\x00\x00"; char display1[8]="\x89\x00\x0D\x40\x01\x02\x03"; char display2[6]="\x01\x40\x01\x02\x03"; serial=calcserial(a1,a2,a3,a4); serhash=serial%256; for (i=0;i=0x40) { j=findbyserial(&itemsp[serial%256], serial, 0); if (j!=-1) { x = j; change=1; x1 = items[j].cont1; x2 = items[j].cont2; x3 = items[j].cont3; x4 = items[j].cont4; serial=items[j].contserial=calcserial(x1,x2,x3,x4); //error correcting code } } else { j=findbyserial(&charsp[serial%256], serial, 1); if (j!=-1) { change=1; c = j; x1 = 255; } } } while (x1!=255 && change==1); if (!change) { printf("UOX3: Sendbpitem bug. Item %i not in container.\n",serial); return; } if (((c!=-1)&&(inrange1p(currchar[s],c)))|| // if item is in a character's //pack (or subcontainer) and player is in range ((c==-1)&&(inrange2(s,x)))) // or item is in container on ground and // container is in range { xsend(s, display3, 1, 0); xsend(s, bpitem, 19, 0); } // chars[currchar[s]].weight=calcweight(s); } void senditem(int s, int i) // Send items (on ground) { int j,pack,serial; char itmput[20]="\x1A\x00\x13\x40\x01\x02\x03\x20\x42\x00\x32\x06\x06\x06\x4A\x0A\x00\x00\x00"; if (items[i].cont1!=255) { pack=1; if (items[i].cont1<0x40) { serial=items[i].contserial; j=findbyserial(&charsp[serial%256], serial, 1); if (j!=-1 && chars[j].serial==serial) pack=0; } if (pack) { sendbpitem(s,i); return; } } if ((items[i].contserial==-1) && (inrange2(s,i))) { itmput[3]=(items[i].ser1)+0x80; // Enable Piles itmput[4]=items[i].ser2; itmput[5]=items[i].ser3; itmput[6]=items[i].ser4; itmput[7]=items[i].id1; itmput[8]=items[i].id2; itmput[9]=items[i].amount/256; itmput[10]=items[i].amount%256; itmput[11]=items[i].x/256; itmput[12]=items[i].x%256; itmput[13]=(items[i].y/256)+0xC0; // Enable Dye and Move itmput[14]=items[i].y%256; itmput[15]=items[i].z; itmput[16]=items[i].color1; itmput[17]=items[i].color2; itmput[18]=0; if (items[i].visible==1) { if (chars[currchar[s]].serial!=items[i].ownserial) { itmput[18]+=0x80; } } if (items[i].visible==2) { itmput[18]+=0x80; } if (items[i].visible==3) { if ((chars[currchar[s]].id1==0x03 && chars[currchar[s]].id2==0xDB) || !chars[currchar[s]].priv&1) itmput[18]+=0x80; } if (items[i].magic==1) itmput[18]+=0x20; if (chars[currchar[s]].priv2&1) itmput[18]+=0x20; if (items[i].magic==3 && chars[currchar[s]].serial==items[i].ownserial) itmput[18]+=0x20; if (chars[currchar[s]].priv2&4) { if ((items[i].id1==0x40) && (items[i].id2<=0xFF)) { itmput[7]=0x14; itmput[8]=0xf0; } } if (items[i].dir) { itmput[19]=itmput[18]; itmput[18]=itmput[17]; itmput[17]=itmput[16]; itmput[16]=itmput[15]; itmput[15]=items[i].dir; itmput[2]=0x14; itmput[11]+=0x80; xsend(s, itmput, 20, 0); } else { itmput[2]=0x13; xsend(s, itmput, 19, 0); } if ((items[i].id1==0x20)&&(items[i].id2==0x06)) { backpack2(s, items[i].ser1, items[i].ser2, items[i].ser3, items[i].ser4); } } //chars[currchar[s]].weight=calcweight(currchar[s]); //statwindow(s, currchar[s]); } void all_items(int s) // Send ALL items to player { int i; for (i=0;i>8,(client_addr.sin_addr.s_addr&0x00ff0000)>>16,(client_addr.sin_addr.s_addr&0xff000000)>>24,&buffer[s][1]); #else sprintf(temp,"Client [%i.%i.%i.%i] connected using Account '%s'.\n",client_addr.sin_addr.S_un.S_un_b.s_b1 _ client_addr.sin_addr.S_un.S_un_b.s_b2 _ client_addr.sin_addr.S_un.S_un_b.s_b3 _ client_addr.sin_addr.S_un.S_un_b.s_b4,&buffer[s][1]); #endif savelog(temp,"server.log"); acctinuse[acctno[s]]=1; tlen=6+(servcount*40); newlist1[1]=tlen/256; newlist1[2]=tlen%256; newlist1[4]=servcount/256; newlist1[5]=servcount%256; xsend(s, newlist1, 6, 0); for (i=0;i=0) { positive=1; } ls++; } while (! ((ls==4)||(positive)) ); if (!positive) { printf("AUTH: Could not connect to loginserver\n"); if (freelogins>0) { printf("AUTH: Using offline login for player. (%i out of 4)\n", 5-freelogins); freelogins--; usedfree[s]=1; goodauth(s); } else { printf("AUTH: Out of offline logins. Disconnecting player.\n"); failauth(s); } } else { printf("AUTH: Connected to loginserver\n"); gentable(MAXCLIENT+1,0x12,0x34,0x56,0x78); // gentable(MAXCLIENT+1, 194, 195, 202, 108); send(server[s], verify1, 4, 0); verify2[0]=0x80; sprintf(&verify2[1], "%s", &buffer[s][5]); sprintf(&verify2[31], "%s", pass2); verify2[61]=0x12; for (ls2=0;ls2<62;ls2++) { verify2[ls2]=verify2[ls2]^ctable[MAXCLIENT+1][ls2]; } send(server[s], verify2, 62, 0); } #endif #endif #ifdef SINGLEONLY if (acctno[s]!=0) // This is for single-player testing releases { printf("AUTH: Only server operator is allowed to login with this version\n"); failauth(s); } #endif #ifdef NOLSERVCHECK goodauth(s); #endif } } void chardel (int s) // Deletion of character { int i, j, k, tlen; if (acctno[s]!=-1) { j=0; k=-1; for (i=0;id){ //if number of votes is higher then max then d=c; //set new max votes e=((chars[a].ser1*16777216)+(chars[a].ser2*65536)+(chars[a].ser3*256)+(chars[a].ser4)); } } } //Handle wilderness Townstones if(townname(j,3)=="the wilderness") e=0; //Set all townstones in this region to have the new mayor. c=newtime->tm_mday; //we're going to set all townstones in this region d=newtime->tm_wday; //to the most recent update time. for(a=0;atm_mday; //get real weekday c = newtime->tm_wday; //repair any messed up npcs! for(a=0;a 0;len--) s++; } else { return "the wilderness"; } return s; } char *townmayor(int j) { char *s=NULL; int a,s1,s2,s3,s4; if(items[j].morex==0) { s="unruled region"; } else { s1=((items[j].morex)/16777216); s2=((items[j].morex)/65536); s3=((items[j].morex)/256); s4=((items[j].morex)%256); for (a=0;a line--; if (line==0) sprintf(script1, "gumppic 10 50 1141"); //Mayor line--; if (line==0) sprintf(script1, "text 20 51 0 2"); line--; if (line==0) sprintf(script1, "text 120 51 0 3"); line--; if (line==0) sprintf(script1, "gumppic 10 70 1141"); //Population line--; if (line==0) sprintf(script1, "text 20 71 0 4"); line--; if (line==0) sprintf(script1, "text 120 71 0 5"); line--; if (line==0) sprintf(script1, "button 10 120 2151 2152 1 0 2"); //Leave or Join line--; if (line==0) sprintf(script1, "text 50 125 500 6"); if(type>0) { line--; if (line==0) sprintf(script1, "button 10 150 2151 2152 1 0 3"); //Toggle Town Title line--; if (line==0) sprintf(script1, "text 50 155 500 7"); if(townname(j,1)!="the wilderness") { line--; if(line==0) sprintf(script1, "button 10 180 2151 2152 1 0 4"); //Vote for Mayor line--; if(line==0) sprintf(script1, "text 50 185 500 8"); line--; if(line==0) sprintf(script1, "text 50 205 500 9"); line--; if(line==0) sprintf(script1, "text 50 225 500 10"); } } line--; if (line==0) sprintf(script1, "}"); //Terminate it } void towntext(int line, int j, char type, int s) { //type will be used for privledges by player (non, resident, mayor, etc..) //0 = nonresident, 1 = resident, 2 = mayor, 3 = town council, 4 = guard, //5 = guard captain, 6 = merchant, 7 = head merchant, 8 = clergy char town[80]; int townpop; sprintf(town,"%s",townname(j,1)); townpop=townpopulation(calcRegionFromXY(items[j].x, items[j].y)); line--; if (line==0) sprintf(script1,"Townstones Phase 1 of 7"); line--; if (line==0) sprintf(script1,"Townstone for %s", town); line--; if (line==0) sprintf(script1,"Mayor"); //line--; if (line==0) sprintf(script1,"%s", townmayor(calcRegionFromXY(items[j].x, items[j].y))); line--; if (line==0) sprintf(script1,"%s", townmayor(j)); line--; if (line==0) sprintf(script1,"Population"); if(townpop>=0) { line--; if (line==0) sprintf(script1,"%i", townpop); } else { line--; if (line==0) sprintf(script1,"unknown"); } line--; if (line==0) { if(townname(j,1)!="the wilderness") { if(type<1) { sprintf(script1, "Become a resident of %s", townname(j,1)); } else { sprintf(script1, "Leave residency of %s", townname(j,1)); } } else { if(type<1) { //Non-Residents get 1 option. sprintf(script1, "Become a resident of the wild."); } else { //Residency option #1 sprintf(script1, "Leave residency of the wild."); } } } if (type>0) { //List all options for residents. line--; if (line==0) { if(chars[currchar[s]].towntitle) { sprintf(script1, "Toggle Town Title off"); } else { sprintf(script1, "Toggle Town Title on"); } } if(townname(j,1)!="the wilderness") { line--; if (line==0) sprintf(script1, "Vote for Mayor"); line--; if (line==0) sprintf(script1, "Currently voting for:"); line--; if (line==0) sprintf(script1, "%s", townmayorvote(s)); } } line--; if (line==0) sprintf(script1,"}"); //Terminate it } void townmenu(int s, int j, int type) { char sect[512]; short int length, length2, textlines; int i; int line; int townpriv=0; //Set the townpriv dependent upon their privledges and their town vs. the //region of the stone. If they are not a member of this town or any town //they are considered a 'non-resident', which holds the value of 0, which //has been defined above. //Currently this doesnt check for all wilderness areas as one.. but.. //since wilderness people can only be a wilderness resident or toggle //their title, it doesnt mean much since if their region doesn't match, //they can change to the region of the stone they are using, and set their //title again. if((calcRegionFromXY(items[j].x,items[j].y))==(chars[currchar[s]].town)) { //They are a resident of this Townstone, set townpriv to their priv. townpriv=chars[currchar[s]].townpriv; } length=21; length2=1; line=0; do { line++; townline(line, j, townpriv, s); if (script1[0]!='}') { length+=strlen(script1)+4; length2+=strlen(script1)+4; } } while (script1[0]!='}'); length+=3; textlines=0; line=0; do { line++; towntext(line, j, townpriv, s); if (script1[0]!='}') { length+=(strlen(script1)*2)+2; textlines++; } } while (script1[0]!='}'); gump1[1]=length/256; gump1[2]=length%256; //type3 gump1[3]=items[j].ser1; gump1[4]=items[j].ser2; gump1[5]=items[j].ser3; gump1[6]=items[j].ser4; //type3 gump1[7]=0; gump1[8]=0; gump1[9]=0; gump1[10]=type; // Gump Number gump1[19]=length2/256; gump1[20]=length2%256; xsend(s, gump1, 21, 0); line=0; do { line++; townline(line, j, townpriv, s); if (script1[0]!='}') { sprintf(sect, "{ %s }", script1); xsend(s, sect, strlen(sect), 0); } } while (script1[0]!='}'); gump2[1]=textlines/256; gump2[2]=textlines%256; xsend(s, gump2, 3, 0); line=0; do { line++; towntext(line, j, townpriv, s); if (script1[0]!='}') { gump3[0]=strlen(script1)/256; gump3[1]=strlen(script1)%256; xsend(s, gump3, 2, 0); gump3[0]=0; for (i=0;i <# in order> sprintf(menuarray[linecount++], "text 20 30 300 1"); //--Command Button Page sprintf(menuarray[linecount++], "page 1"); sprintf(menuarray[linecount++], "text 20 60 300 2"); //goto text sprintf(menuarray[linecount++], "button 150 60 1209 1210 1 0 200"); //goto button sprintf(menuarray[linecount++], "text 20 80 300 3"); //gettext sprintf(menuarray[linecount++], "button 150 80 1209 1210 1 0 201"); //get button sprintf(menuarray[linecount++], "text 20 100 300 4"); //Jail text sprintf(menuarray[linecount++], "button 150 100 1209 1210 1 0 202"); //Jail button sprintf(menuarray[linecount++], "text 20 120 300 5"); //Release text sprintf(menuarray[linecount++], "button 150 120 1209 1210 1 0 203"); //Release button sprintf(menuarray[linecount++], "text 20 140 300 6"); //Kick user text sprintf(menuarray[linecount++], "button 150 140 1209 1210 1 0 204"); //kick button sprintf(menuarray[linecount++], "text 20 180 300 7"); length=21; length2=1; for(line=0;line <# in order> sprintf(menuarray[linecount++], "page %i",pagenum); //--Start User List for(i=0;i0 && (!(i%10))) { position=40; pagenum++; sprintf(menuarray[linecount++], "page %i",pagenum); } sprintf(menuarray[linecount++], "text 40 %i 300 %i",position,linenum); //usernames sprintf(menuarray[linecount++], "button 20 %i 1209 1210 1 0 %i",position,buttonnum); position+=20; linenum++; buttonnum++; } pagenum=1; //lets make some damn buttons for (i=0;i=10) sprintf(menuarray[linecount++], "button 150 300 2223 2223 0 %i",pagenum-1); //back button if ((k>10) && ((i+10)1)),pagenum+1); //forward button pagenum++; } length=21; length2=1; for(line=0;line4) return; //increase this value with each new gump added. if (type==1) //Tweaking an Item j=findbyserial(&itemsp[serial%256], serial, 0); if (type==2) //Tweaking a Character j=findbyserial(&charsp[serial%256], serial, 1); if (type==3) //Townstones j=findbyserial(&itemsp[serial%256], serial, 0); if (type==4) //wholist j=findbyserial(&itemsp[serial%256], serial, 0); if (button==1) return; if (type==1) // Item { if (button==2) // Name { entrygump(s, tser1, tser2, tser3, tser4, type, button, 50, "Enter a new name for the item. (# = default name)"); } if (button==3) // ID { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter the new ID number for the item in hex."); } if (button==4) // Hue { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter the new hue for the item in hex."); } if (button==5) // X { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter the new X coordinate for the item in decimal."); } if (button==6) // Y { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter the new Y coordinate for the item in decimal."); } if (button==7) // Z { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter the new Z coordinate for the item in decimal."); } if (button==8) // Type { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter the new type for the item in decimal."); } if (button==9) // Layer { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter the new layer for the item in decimal."); } if (button==10) // Amount { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter the new amount for the item in decimal."); } if (button==11) // More { entrygump(s, tser1, tser2, tser3, tser4, type, button, 8, "Enter the new More for the item in hex."); } if (button==12) // MoreB { entrygump(s, tser1, tser2, tser3, tser4, type, button, 8, "Enter the new MoreB for the item in hex."); } if (button==13) // Pileable { entrygump(s, tser1, tser2, tser3, tser4, type, button, 1, "Enter the new stackable toggle for the item. (0/1)"); } if (button==14) // Dye { entrygump(s, tser1, tser2, tser3, tser4, type, button, 1, "Enter the new dyeable toggle for the item. (0/1)"); } if (button==15) // Corpse { entrygump(s, tser1, tser2, tser3, tser4, type, button, 1, "Enter the new corpse toggle for the item. (0/1)"); } if (button==16) // Att { entrygump(s, tser1, tser2, tser3, tser4, type, button, 5, "Enter the new attack value for the item in decimal."); } if (button==17) // Def { entrygump(s, tser1, tser2, tser3, tser4, type, button, 5, "Enter the new defense value for the item in decimal."); } if (button==18) // Magic { entrygump(s, tser1, tser2, tser3, tser4, type, button, 1, "Enter the new magic value for the item in decimal."); } if (button==19) // Visible { entrygump(s, tser1, tser2, tser3, tser4, type, button, 1, "Enter the new visible value for the item in decimal."); } } if (type==2) // Char { if (button==2) // Name { entrygump(s, tser1, tser2, tser3, tser4, type, button, 50, "Enter a new name for the character."); } if (button==3) // Title { entrygump(s, tser1, tser2, tser3, tser4, type, button, 50, "Enter a new name for the character."); } if (button==4) // X { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter a new X coordinate for the character in decimal."); } if (button==5) // Y { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter a new Y coordinate for the character in decimal."); } if (button==6) // Z { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter a new Z coordinate for the character in decimal."); } if (button==7) // Dir { entrygump(s, tser1, tser2, tser3, tser4, type, button, 1, "Enter a new direction for the character in decimal."); } if (button==8) // Body { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter a new body type for the character in hex."); } if (button==9) // Skin { entrygump(s, tser1, tser2, tser3, tser4, type, button, 4, "Enter a new skin hue for the character in hex."); } } if (type==3) // Townstones { if (button==2) // Leave/Join { if (chars[currchar[s]].town) { //They are a resident of a region (not necessarily this one). if (chars[currchar[s]].town==calcRegionFromXY(items[j].x, items[j].y)) { //They are a resident of this region, set their .town property to 0. if(chars[currchar[s]].townpriv==2) { //They were a mayor. Find new one. chars[currchar[s]].townpriv=0; towncalcnewmayor(chars[currchar[s]].town); } chars[currchar[s]].town=0; chars[currchar[s]].townpriv=0; } else { //They are not a resident of this region, set their .town property to //the region associated with the townstone. if(chars[currchar[s]].townpriv==2) { //They were a mayor. Find new one. chars[currchar[s]].townpriv=0; towncalcnewmayor(chars[currchar[s]].town); } chars[currchar[s]].town=calcRegionFromXY(items[j].x, items[j].y); chars[currchar[s]].townpriv=1; townmenu(s, j, 3); } } else { //They are not a resident of any region, set their .town property to the //region associated with this townstone. chars[currchar[s]].town=calcRegionFromXY(items[j].x, items[j].y); chars[currchar[s]].townpriv=1; townmenu(s, j, 3); } chars[currchar[s]].townvote1=0; chars[currchar[s]].townvote2=0; chars[currchar[s]].townvote3=0; chars[currchar[s]].townvote4=0; chars[currchar[s]].towntitle=0; } if (button==3) { // Toggle Title if(chars[currchar[s]].towntitle) { chars[currchar[s]].towntitle=0; } else { chars[currchar[s]].towntitle=1; } townmenu(s, j, 3); } if (button==4) { // Vote for Mayor target(s,0,1,0,161,"Select person to vote for."); } } if (type==4)//wholist *Homey if(button<200) { button-=7; chars[currchar[s]].making=button; whocommand(s,type,button); } else { switch(button) { case 200://gochar i=chars[currchar[s]].making; chars[currchar[s]].x=chars[currchar[i]].x; chars[currchar[s]].y=chars[currchar[i]].y; chars[currchar[s]].dispz=chars[currchar[s]].z=chars[currchar[i]].z; teleport(currchar[s]); break; case 201://xtele xteleport(s, 3); break; case 202://jail char if(s==chars[currchar[s]].making) { sysmessage(s,"You cannot jail yourself!"); break; } else { for(i=0;ix2) {c=x1;x1=x2;x2=c;} if (y1>y2) {c=y1;y1=y2;y2=c;} if (addid1[s]==0x40) { switch (addid2[s]) { case 100: case 102: case 104: case 106: case 108: case 110: case 112: case 114: case 116: case 118: case 120: case 122: case 124: case 126: case 140: addtarget(s); return; } } int x,y; seektile((addid1[s]*256)+addid2[s], &tile); if (tile.flag2&0x08) pileable=1; for (x=x1;x<=x2;x++) for (y=y1;y<=y2;y++) { c=SpawnItem(s, 1, "#", pileable, addid1[s], addid2[s], NULL, NULL, 0,0); items[c].priv=0; //Make them not decay items[c].x=x; items[c].y=y; items[c].z=buffer[s][16]+tileheight(buffer[s][17]*256+buffer[s][18]); for (j=0;jx2) {c=x1;x1=x2;x2=c;} if (y1>y2) {c=y1;y1=y2;y2=c;} if (addid1[s]==1) { // addid1[s]==1 means to inverse wipe for (int i=0;i=x1 && items[i].x<=x2 && items[i].y>=y1 && items[i].y<=y2) && items[i].contserial==-1 && items[i].wipe==0) deleitem(i); } else { for (int i=0;i=x1 && items[i].x<=x2 && items[i].y>=y1 && items[i].y<=y2 && items[i].contserial==-1 && items[i].wipe==0) deleitem(i); } } void renametarget(int s) { int i,serial; serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); i=findbyserial(&itemsp[serial%256], serial, 0); if (i!=-1) { sprintf(items[i].name,xtext[s]); } i=findbyserial(&charsp[serial%256], serial, 1); if (i!=-1) { sprintf(chars[i].name,xtext[s]); } } void teletarget(int s) { int success; if (line_of_sight(s,chars[currchar[s]].x, chars[currchar[s]].y, chars[currchar[s]].dispz, (buffer[s][11]*256)+buffer[s][12], (buffer[s][13]*256)+buffer[s][14], buffer[s][16]+ tileheight(buffer[s][17]*256+buffer[s][18]), (WALLS_CHIMNEYS + DOORS + ROOFING_SLANTED))|| (chars[currchar[s]].priv&0x01)) { if (buffer[s][11]==0xFF && buffer[s][12]==0xFF && buffer[s][13]==0xFF && buffer[s][14]==0xFF) return; if (stablock((buffer[s][11]*256)+buffer[s][12],(buffer[s][13]*256)+buffer[s][14], buffer[s][16]+tileheight(buffer[s][17]*256+buffer[s][18])) && !(chars[currchar[s]].priv&0x01)) { sysmessage(calcSocketFromChar(currchar[s]),"You cannot teleport there!"); return; } if (currentSpellType[s] !=2) // not a wand cast { success=subtractmana(currchar[s], 3); // subtract mana on scroll or spell if (currentSpellType == 0) // del regs on normal spell delereagents(currchar[s], 0, 1, 0, 0, 1, 0, 0, 0); } soundeffect(s, 0x01, 0xFE); chars[currchar[s]].x=(buffer[s][11]*256)+buffer[s][12]; chars[currchar[s]].y=(buffer[s][13]*256)+buffer[s][14]; chars[currchar[s]].dispz=chars[currchar[s]].z=buffer[s][16]+tileheight(buffer[s][17]*256+buffer[s][18]); teleport(currchar[s]); staticeffect(currchar[s], 0x37, 0x2A, 0x09, 0x06); } } void removetarget(int s) { int i,serial; serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); i=findbyserial(&itemsp[serial%256], serial, 0); if (i!=-1) { sysmessage(s, "Removing item."); deleitem(i); } } void dyetarget(int s) { int i,j,k,serial; serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); if ((addid1[s]==255)&&(addid2[s]==255)) { i=findbyserial(&itemsp[serial%256], serial, 0); if (i!=-1) { dyevat[1]=items[i].ser1; dyevat[2]=items[i].ser2; dyevat[3]=items[i].ser3; dyevat[4]=items[i].ser4; dyevat[7]=items[i].id1; dyevat[8]=items[i].id2; xsend(s, dyevat, 9, 0); for (k=0;k0x03E9) ) { items[i].color1=0x03; items[i].color2=0xE9; } } for (j=0;j=0x3b)&&(chars[i].id2<=0x3d))) {nType=1;} if (!(chars[i].dead)) { for (t=0;tString! %i->%s\n",items[i].name,i); switch (items[i].morez) { case 1:dmg=items[i].morex/200;break; case 2:dmg=items[i].morex/100;break; case 3:dmg=items[i].morex/50;break; } for (c=0;c0x03E9) ) { items[i].color1=0x03; items[i].color2=0xE9; } } for (j=0;j0)&&script1[0]!='}'&&script1[0]!=0); closescript(); if (!(strcmp("}", script1))) { tips(s, 1); return; } openscript("misc.scp"); sprintf(temp, "TIP %i", str2num(script2)); if (!misc_script.find(temp)) { closescript(); return; } pos=ftell(scpfile); x=-1; y=-2; do { read1(); x++; y+=strlen(script1)+1; } while (strcmp(script1, "}")); y+=10; fseek(scpfile, pos, SEEK_SET); updscroll[1]=y/256; updscroll[2]=y%256; updscroll[3]=0; updscroll[7]=i; updscroll[8]=(y-10)/256; updscroll[9]=(y-10)%256; // xsend(s, xpause, 2, 0); xsend(s, updscroll, 10, 0); for (j=0;j0); closescript(); openscript("misc.scp"); sprintf(temp, "PAGE %s", script2); if (!misc_script.find(temp)) { closescript(); return; } pos=ftell(scpfile); x=-1; y=-2; do { read1(); x++; y+=strlen(script1)+1; } while (strcmp(script1, "}")); y+=13; fseek(scpfile, pos, SEEK_SET); bookpage[1]=y/256; bookpage[2]=y%256; bookpage[3]=items[i].ser1; bookpage[4]=items[i].ser2; bookpage[5]=items[i].ser3; bookpage[6]=items[i].ser4; bookpage[9]=p/256; bookpage[10]=p%256; bookpage[11]=x/256; bookpage[12]=x%256; // xsend(s, xpause, 2, 0); xsend(s, bookpage, 13, 0); for (j=0;j=0x0695)&&(x<0x06C5))|| // Open wooden / ratan door ((x>=0x06D5)&&(x<=0x06F4))) soundeffect3(item, 0x00, OPENWOOD); if (((x>=0x0839)&&(x<=0x0848))|| // Open gate ((x>=0x084C)&&(x<=0x085B))|| ((x>=0x0866)&&(x<=0x0875))) soundeffect3(item, 0x00, OPENGATE); if (((x>=0x0675)&&(x<0x0695))|| // Open metal ((x>=0x06C5)&&(x<0x06D5))) soundeffect3(item, 0x00, OPENSTEEL); if ((x>=0x0314)&&(x<=0x0365)) // Open secret soundeffect3(item, 0x00, OPENSECRET); } else if (y==1) // Request close door sfx { if (((x>=0x0695)&&(x<0x06C5))|| // close wooden / ratan door ((x>=0x06D5)&&(x<=0x06F4))) soundeffect3(item, 0x00, CLOSEWOOD); if (((x>=0x0839)&&(x<=0x0848))|| // close gate ((x>=0x084C)&&(x<=0x085B))|| ((x>=0x0866)&&(x<=0x0875))) soundeffect3(item, 0x00, CLOSEGATE); if (((x>=0x0675)&&(x<0x0695))|| // close metal ((x>=0x06C5)&&(x<0x06D5))) soundeffect3(item, 0x00, CLOSESTEEL); if ((x>=0x0314)&&(x<=0x0365)) // close secret soundeffect3(item, 0x00, CLOSESECRET); } } // doorsfx() END void dooruse(int s, int item) { int i, db, x, z; char changed=0; //if (items[item].type!=12) return; // Fix locked doors moving if ((iteminrange(s,item,2)==0)&& s>-1) {sysmessage(s, "You cannot reach the handle from here");return;} for (i=0;i-1) sysmessage(s, "This doesnt seem to be a valid door type. Contact a GM."); } //o---------------------------------------------------------------------------o //| Function : void gmpage(int s,char *reason) //| Date : Unknown //| Programmer : Unknown //o---------------------------------------------------------------------------o //| Purpose : Help button (Calls GM Call Menus up) //o---------------------------------------------------------------------------o void gmpage(int s, char *reason) { int i, a1, a2, a3, a4, x=0; int x2=0; a1=chars[currchar[s]].ser1; a2=chars[currchar[s]].ser2; a3=chars[currchar[s]].ser3; a4=chars[currchar[s]].ser4; for(i=1;itm_hour, local->tm_min, local->tm_sec); sprintf(temp,"%s [%d][%d][%d][%d] called at %s, %s",gmpages[i].name,a1,a2,a3,a4,gmpages[i].timeofcall,gmpages[i].reason); if(heartbeat) Writeslot(temp); chars[currchar[s]].playercallnum=i; chars[currchar[s]].pagegm=1; x2++; break; } } if (x2==0) { sysmessage(s,"The GM Queue is currently full. Contact the shard operator"); sysmessage(s,"and ask them to increase the size of the queue."); } else { if(strcmp(reason,"OTHER")) { chars[currchar[s]].pagegm=0; sprintf(temp, "Page from %s [%x %x %x %x]: %s", chars[currchar[s]].name, a1, a2, a3, a4, reason); for (i=0;itm_hour, local->tm_min, local->tm_sec); sprintf(temp,"%s [%d][%d][%d][%d] called at %s, %s",counspages[i].name,a1,a2,a3,a4,counspages[i].timeofcall,counspages[i].reason); if(heartbeat) Writeslot(temp); chars[currchar[s]].playercallnum=i; chars[currchar[s]].pagegm=2; x2++; break; } } if(x2==0) { sysmessage(s,"The Counselor Queue is currently full. Contact the shard operator"); sysmessage(s,"and ask them to increase the size of the queue."); } else { if(strcmp(reason,"OTHER")) { chars[currchar[s]].pagegm=0; sprintf(temp, "Counselor Page from %s [%x %x %x %x]: %s", chars[currchar[s]].name, a1, a2, a3, a4, reason); for (i=0;i=0x40) senditem(s, i); return; }*/ //Zippy's stealing changes x=i; if (x!=-1) if (items[x].contserial!=-1) //Find character owning item { do //Find character owning item { if (items[x].cont1<0x40) // it's a character { npc=findbyserial(&charsp[items[x].contserial%256], items[x].contserial, 1); } else //its an item { x=findbyserial(&itemsp[items[x].contserial%256], items[x].contserial, 0); if (x==-1 || items[x].corpse!=0) npc=0; } } while (npc==-1); } // if (((items[x].contserial>0)&&(npc>1))&&(!(chars[currchar[s]].priv&0x01))&& // (items[x].layer==0) && (npc!=currchar[s])) if (npc>1 && !(chars[currchar[s]].priv&0x01) && npc!=currchar[s]) { //printf("DEBUG: Contser: %i NPC: %i Char: %i",items[x].contserial,npc, currchar[s]); bounce[1]=0; xsend(s, bounce, 2, 0); return; } //End Zippy's change if (i!=-1 && items[i].corpse!=1) { packnum=packitem(currchar[s]); if (checkwhereitem(packnum, i, s)) { //additemweight(i, currchar[s]); statwindow(s,currchar[s]); //updateweight(s); not used yet } seektile((items[i].id1*256)+items[i].id2, &tile); if ((((items[i].magic==2)||((tile.weight==255)&&(items[i].magic!=1)))&&((chars[currchar[s]].priv2&1)==0)) || (items[i].magic==3 && !(items[i].ownserial==chars[currchar[s]].serial))) { bounce[1]=0; xsend(s, bounce, 2, 0); if (items[i].id1>=0x40) senditem(s, i); } else { items[i].layer=0; if (items[i].cont1!=0xff) soundeffect(s,0x00,0x57); if (items[i].amount>1) { amount=(buffer[s][5]*256)+buffer[s][6]; if (amount>items[i].amount) amount=items[i].amount; if (amountchars[k].st) { sysmessage(s,"You are not strong enough to use that."); bounce[1]=5; xsend(s, bounce, 2, 0); if(items[i].id1>=0x40) senditem(s, i); pack=packitem(currchar[s]); if (checkwhereitem(pack, i, s)) { //subtractitemweight( i, currchar[s]); statwindow(s,currchar[s]); } return; } seektile((items[i].id1*256)+items[i].id2, &tile); if ((((items[i].magic==2)||((tile.weight==255)&&(items[i].magic!=1)))&&((chars[currchar[s]].priv2&1)==0)) || (items[i].magic==3 && !(items[i].ownserial==chars[currchar[s]].serial))) { bounce[1]=5; xsend(s, bounce, 2, 0); if (items[i].id1>=0x40) senditem(s, i); return; } items[i].cont1=buffer[s][6]; items[i].cont2=buffer[s][7]; items[i].cont3=buffer[s][8]; items[i].cont4=buffer[s][9]; items[i].contserial=calcserial(items[i].cont1,items[i].cont2,items[i].cont3,items[i].cont4); if (items[i].contserial!=-1) setptr(&contsp[items[i].contserial%256], i); items[i].layer=buffer[s][5]; chars[currchar[s]].st = (chars[currchar[s]].st + items[i].st2); chars[currchar[s]].dx = (chars[currchar[s]].dx + items[i].dx2); chars[currchar[s]].in = (chars[currchar[s]].in + items[i].in2); if (showlayer) printf("Item equipped on layer %i.\n",items[i].layer); removeitem[1]=items[i].ser1; removeitem[2]=items[i].ser2; removeitem[3]=items[i].ser3; removeitem[4]=items[i].ser4; for (j=0;j=0x40) senditem(s, i); return; } seektile((items[i].id1*256)+items[i].id2, &tile); if ((((items[i].magic==2)||((tile.weight==255)&&(items[i].magic!=1)))&&((chars[currchar[s]].priv2&1)==0)) || (items[i].magic==3 && !(items[i].ownserial==chars[currchar[s]].serial))) { bounce[1]=5; xsend(s, bounce, 2, 0); if (items[i].id1>=0x40) senditem(s, i); return; } if (buffer[s][5]!='\xFF') { items[i].x=(buffer[s][5]*256)+buffer[s][6]; items[i].y=(buffer[s][7]*256)+buffer[s][8]; items[i].z=buffer[s][9]; if (items[i].contserial!=-1) removefromptr(&contsp[items[i].serial%256], i); items[i].cont1=255; items[i].cont2=255; items[i].cont3=255; items[i].cont4=255; items[i].contserial=-1; removeitem[1]=items[i].ser1; removeitem[2]=items[i].ser2; removeitem[3]=items[i].ser3; removeitem[4]=items[i].ser4; for (j=0;j=0x40) senditem(s, i); } else senditem(s, i); return; } if(chars[nChar].trainer!=chars[t].serial) { npctalk(s, t, "Thank thee kindly, but I have done nothing to warrant a gift."); bounce[1]=5; xsend(s, bounce, 2, 0); if(items[i].contserial==-1) //1==255 && items[i].cont2==255 && items[i].cont3==255 && items[i].cont4==255) { if (items[i].id1>=0x40) senditem(s, i); } else senditem(s, i); return; } else // The player is training from this NPC { // This NPC is trainging the player if(items[i].id1==0x0e && items[i].id2==0xed) { // They gave the NPC gold npctalk(s, t, "I thank thee for thy payment. That should give thee a good start on thy way. Farewell!"); int oldskill=chars[nChar].baseskill[chars[t].trainingplayerin]; chars[nChar].baseskill[chars[t].trainingplayerin]+=items[i].amount; if(chars[nChar].baseskill[chars[t].trainingplayerin]>250) chars[nChar].baseskill[chars[t].trainingplayerin]=250; updateSkillLevel(nChar, chars[t].trainingplayerin); updateskill(s,chars[t].trainingplayerin); if(items[i].amount>250) { // Paid too much items[i].amount-=250-oldskill; bounce[1]=5; xsend(s, bounce, 2, 0); if(items[i].contserial==-1) //1==255 && items[i].cont2==255 && items[i].cont3==255 && items[i].cont4==255) { if (items[i].id1>=0x40) senditem(s, i); } else senditem(s, i); } else {items[i].free=1; deleitem(i);} // Gave exact change chars[nChar].trainer=-1; chars[t].trainingplayerin=-1; return; } else // Did not give gold { npctalk(s, t, "I am sorry, but I can only accept gold."); bounce[1]=5; xsend(s, bounce, 2, 0); if(items[i].contserial==-1) //1==255 && items[i].cont2==255 && items[i].cont3==255 && items[i].cont4==255) { if (items[i].id1>=0x40) senditem(s, i); } else senditem(s, i); return; } } } else { j=tradestart(s, t); if (items[i].contserial!=-1) removefromptr(&contsp[items[i].serial%256], i); setserial(i, j, 1); items[i].x=30; items[i].y=30; items[i].z=9; removeitem[1]=items[i].ser1; removeitem[2]=items[i].ser2; removeitem[3]=items[i].ser3; removeitem[4]=items[i].ser4; for (k=0;k=0x40) senditem(s, nItem); return; } seektile((items[nItem].id1*256)+items[nItem].id2, &tile); if ((((items[nItem].magic==2)||((tile.weight==255)&&(items[nItem].magic!=1)&&(items[nCont].corpse!=1)))&&((chars[currchar[s]].priv2&1)==0)) || (items[nItem].magic==3 && !(items[nItem].ownserial==chars[currchar[s]].serial))) { bounce[1]=5; xsend(s, bounce, 2, 0); if (items[nCont].id1>=0x40) senditem(s, nCont); return; } // - Trash container if (items[nCont].type==87) { deleitem(nItem); sysmessage(s, "As you let go of the item it disappears."); return; } // - Spell Book if (items[nCont].type==9) { if (items[nItem].id1!=0x1F || items[nItem].id2<0x2D || items[nItem].id2>0x72) { bounce[1]=5; xsend(s, bounce, 2, 0); sysmessage(s, "You can only place spell scrolls in a spellbook!"); if (items[nCont].id1>=0x40) senditem(s, nCont); return; } z=packitem(currchar[s]); if ((!(items[nCont].contserial==chars[currchar[s]].serial)) && (!(items[nCont].contserial==items[z].serial)) && (!(chars[currchar[s]].priv&0x40))) { bounce[1]=5; xsend(s, bounce, 2, 0); sysmessage(s, "You cannot place spells in other peoples spellbooks."); if (items[nCont].id1>=0x40) senditem(s, nCont); return; } } if (!(((items[nCont].pileable)&&(items[nItem].pileable)&& (items[nCont].id1==items[nItem].id1)&&(items[nCont].id2==items[nItem].id2)) || ((items[nCont].type!=1)&&(items[nCont].type!=9)))) { if (items[nItem].contserial!=-1) removefromptr(&contsp[items[nItem].contserial%256], nItem); setserial(nItem, nCont, 1); if (buffer[s][5]!='\xFF') { items[nItem].x=(buffer[s][5]*256)+buffer[s][6]; items[nItem].y=(buffer[s][7]*256)+buffer[s][8]; } else { items[nItem].x=95; items[nItem].y=80; } items[nItem].z=9; removeitem[1]=items[nItem].ser1; removeitem[2]=items[nItem].ser2; removeitem[3]=items[nItem].ser3; removeitem[4]=items[nItem].ser4; for (j=0;j 65535) { items[nItem].amount -= (65535-items[nCont].amount); dupeitem(s, nCont, items[nItem].amount); items[nCont].amount = 65535; deleitem(nItem); } else { items[nCont].amount=items[nCont].amount+items[nItem].amount; deleitem(nItem); itemsfx(s, items[nItem].id1, items[nItem].id2); } for (j=0;j", PRODUCT, VER, NAME, EMAIL); #else sprintf(idname, "Ultima Offline eXperiment 3 Server Version %s Alpha [LINUX] by %s <%s>", VER, NAME, EMAIL); #endif sysmessage(s, idname); weather(s); // xsend(s, restart, 2, 0); updates(s); chars[currchar[s]].region=255; checkregion(currchar[s]); //Tauriel set packitem at login // for (i=0;i0x8422) ) { chars[c].skin1=0x83; chars[c].skin2=0xEA; } chars[c].xskin1=chars[c].skin1; chars[c].xskin2=chars[c].skin2; chars[c].priv=defaultpriv1; chars[c].priv2=defaultpriv2; if (acctno[s]==0) chars[c].priv=0xE7; chars[c].x=makenum2(start[buffer[s][0x5B]][2]); chars[c].y=makenum2(start[buffer[s][0x5B]][3]); chars[c].dispz=chars[c].z=makenum2(start[buffer[s][0x5B]][4]); chars[c].dir=4; chars[c].hp=chars[c].st=buffer[s][0x47]; if (chars[c].st>45) chars[c].st=45; // fix for hack exploit if (chars[c].st<10) chars[c].st=10; totalstats=chars[c].st; chars[c].stm=chars[c].dx=buffer[s][0x48]; if (chars[c].dx>45) chars[c].dx=45; // fix for hack exploit if (chars[c].dx<10) chars[c].dx=10; if (chars[c].dx+totalstats>65) chars[c].dx=65-totalstats; totalstats+=chars[c].dx; chars[c].mn=chars[c].in=buffer[s][0x49]; if (chars[c].in>45) chars[c].in=45; // fix for hack exploit if (chars[c].in<10) chars[c].in=10; if (chars[c].in+totalstats>65) chars[c].in=65-totalstats; if (buffer[s][0x4b]>50) buffer[s][0x4b]=50; // fixes for hack exploit totalskills=buffer[s][0x4b]; if (buffer[s][0x4d]>50) buffer[s][0x4d]=50; if (buffer[s][0x4d]+totalskills>100) buffer[s][0x4d]=100-totalskills; totalskills+=buffer[s][0x4d]; if (buffer[s][0x4f]>50) buffer[s][0x4f]=50; if (buffer[s][0x4f]+totalskills>100) buffer[s][0x4f]=100-totalskills; for (i=0;i0x04AD) ) { items[n].color1=0x04; items[n].color2=0x4E; } setserial(n, c, 4); items[n].layer=0x0B; } if ( (validbeard(buffer[s][0x56],buffer[s][0x57])) && (chars[c].id2==0x90) ) { n=SpawnItem(s,1, "#", 0, buffer[s][0x56], buffer[s][0x57], buffer[s][0x58], buffer[s][0x59],0,0); if ( ((items[n].color1*256+items[n].color2)<0x044E) || ((items[n].color1*256+items[n].color2)>0x04AD) ) { items[n].color1=0x04; items[n].color2=0x4E; } setserial(n, c, 4); items[n].layer=0x10; } // - create the backpack chars[c].packitem=n=SpawnItem(s,1, "#", 0, 0x0E, 0x75, 0, 0,0,0); setserial(n, c, 4); items[n].layer=0x15; items[n].type=1; items[n].dye=1; n=SpawnItem(s,1,"#",0,0x09,0x15,0,0,0,0); randbuf=rand()%2; if (randbuf==0) { if ((chars[c].id2=='\x90') && (chars[c].xid2=='\x90')) { items[n].id1=0x15; items[n].id2=0x39; items[n].layer=0x04; } else { items[n].id1=0x15; items[n].id2=0x16; items[n].layer=23; } } if (randbuf==1) { if ((chars[c].id2=='\x90') && (chars[c].xid2=='\x90')) { items[n].id1=0x15; items[n].id2=0x2E; items[n].layer=0x04; } else { items[n].id1=0x15; items[n].id2=0x37; items[n].layer=23; } } randbuf=rand()%6; if (randbuf==0) { items[n].color1=0x02; items[n].color2=0x84; } if (randbuf==1) { items[n].color1=0x02; items[n].color2=0x1F; } if (randbuf==2) { items[n].color1=0x03; items[n].color2=0xC3; } if (randbuf==3) { items[n].color1=0x03; items[n].color2=0xD9; } if (randbuf==4) { items[n].color1=0x02; items[n].color2=0xE8; } if (randbuf==5) { items[n].color1=0x02; items[n].color2=0xD1; } setserial(n, c, 4); items[n].type=0; items[n].dye=1; n=SpawnItem(s,1,"#",0,0x09,0x15,0,0,0,0); randbuf=rand()%2; if (randbuf==0) { items[n].id1=0x1E; items[n].id2=0xFD; } if (randbuf==1) { items[n].id1=0x15; items[n].id2=0x17; } randbuf=rand()%5; if (randbuf==0) { items[n].color1=0x01; items[n].color2=0x34; } if (randbuf==1) { items[n].color1=0x00; items[n].color2=0x28; } if (randbuf==2) { items[n].color1=0x00; items[n].color2=0x35; } if (randbuf==3) { items[n].color1=0x01; items[n].color2=0xCA; } if (randbuf==4) { items[n].color1=0x02; items[n].color2=0x1A; } setserial(n, c, 4); items[n].layer=0x05; items[n].dye=1; items[n].def=1; n=SpawnItem(s,1,"#",0,0x17,0x0F,0x02,0x87,0,0); setserial(n, c, 4); items[n].layer=0x03; items[n].dye=1; items[n].def=1; n=SpawnItem(s,1,"#",0,0x0F,0x51,0,0,0,0); setserial(n, c, 4); items[n].layer=0x01; items[n].att=5; #ifdef SPECIAL n=SpawnItem(s,1,"#",0,0x09,0x15,0,0,0,0); randbuf=rand()%7; if (randbuf==0) { items[n].id1=0x15; items[n].id2=0x4b; } if (randbuf==1) { items[n].id1=0x15; items[n].id2=0x45; } if (randbuf==2) { items[n].id1=0x15; items[n].id2=0x47; } if (randbuf==3) { items[n].id1=0x15; items[n].id2=0x49; } if (randbuf==4) { items[n].id1=0x17; items[n].id2=0x1c; } if (randbuf==5) { items[n].id1=0x1f; items[n].id2=0x0b; } if (randbuf==6) { items[n].id1=0x14; items[n].id2=0x51; } setserial(n, c, 4); items[n].layer=0x06; #endif // Give the character some gold n=SpawnItem(s,goldamount,"#",1,0x0E,0xED,0,0,1,0); setserial(n, packitem(c), 1); items[n].layer=0x01; items[n].att=5; currchar[s]=c; newbieitems(c); perm[s]=1; /* if (c==charcount) { charcount++; charcount2++; }*/ startchar(s); } void charplay (int s) // After hitting "Play Character" button { int i, j, k; if (acctno[s]>-1) { j=0; k=-1; for (i=0;i0); if (z==-128) { chars[s].x=oldx; chars[s].y=oldy; if (k!=-1) deny(k, s, sequence); return; } chars[s].dispz=dispz; chars[s].z=z; if (!( ((chars[s].id1==0x03)&&(chars[s].id2==0xDB)) || ((chars[s].id1==0x01)&&(chars[s].id2==0x92)) || ((chars[s].id1==0x01)&&(chars[s].id2==0x93)) || (chars[s].priv&0x01) || (chars[s].priv&0x80) )) for (i=0;iVISRANGE)||(abs(oldy-chars[currchar[i]].y)>VISRANGE))) || ((abs(newx-chars[currchar[i]].x)==VISRANGE)&&(abs(newy-chars[currchar[i]].y)==VISRANGE)) ) { impowncreate(i, s, 1); } else // if ((abs(newx-chars[currchar[i]].x)VISRANGE)||(abs(oldy-chars[i].y)>VISRANGE))) || ((abs(newx-chars[i].x)==VISRANGE)&&(abs(newy-chars[i].y)==VISRANGE)) ) { impowncreate(k, i, 1); } } } // }// XXX-ZIPPY // - this needs to be updated to use region pointers for (i=0;i=0x7C)&&(items[i].id2<=0x7E)) { if ((abs(newx-items[i].x)==BUILDRANGE)||(abs(newy-items[i].y)==BUILDRANGE)) { senditem(k, i); } } else { if ((abs(newx-items[i].x)==VISRANGE)||(abs(newy-items[i].y)==VISRANGE)) { senditem(k, i); } } } } if ((chars[s].x!=oldx)||(chars[s].y!=oldy)) { if (!(chars[s].dead)) objTeleporters(s); teleporters(s); } gatecollision(s); checkregion(s); } } void walking2(int s) // Only for switching to combat mode { int i; for (i=0;i=1397)&&(chars[currchar[s]].x<=1400)&& (chars[currchar[s]].y>=1622)&&(chars[currchar[s]].y<=1630)) z=28; if ((chars[currchar[s]].x>=1510)&&(chars[currchar[s]].x<=1537)&& (chars[currchar[s]].y>=1455)&&(chars[currchar[s]].y<=1456)) z=15; return z; } int unmounthorse(int s) // Get off a horse (Remove horse item and spawn new horse) { int k,c,ci,serial,serhash; serial=chars[currchar[s]].serial; serhash=serial%256; for (k=0;k1246 && main<1255) { dopotion(s, main-1246, sub, calcItemFromSer(addid1[s], addid2[s], addid3[s], addid4[s])); return; } else if (main=5256) && (main<8192)) // Tracking fix 12-30-98 { openscript("items.scp"); sprintf(sect, "ITEMMENU %i", main-256); script = &items_script; } else if(main>=ITEMMENUOFFSET && main=MAKEMENUOFFSET && main=TRACKINGMENUOFFSET+1&&(main-TRACKINGMENUOFFSET)<=TRACKINGMENUOFFSET+3) { if(!sub) return; if(!checkskill(currchar[s],TRACKING, 0, 1000)) { sysmessage(s,"You fail your attempt at tracking."); return; } tracking(s,sub-1); } openscript("tracking.scp"); sprintf(sect, "TRACKINGMENU %i", main-TRACKINGMENUOFFSET); script = &tracking_script; } if (!script->find(sect)) { closescript(); return; } read1(); i=0; do { read1(); if (script1[0]!='}') { i++; if (main>=MAKEMENUOFFSET && main1) { sprintf(xtext[s], "%s", &tbuffer[offset+7]); target(s, 0, 1, 0, 1, "Select item or character to rename."); } return; } if (!(strcmp("TITLE",comm))) { if (tnum>1) { sprintf(xtext[s], "%s", &tbuffer[offset+6]); target(s, 0, 1, 0, 47, "Select character to change the title of."); } return; } if (!(strcmp("SAVE",comm))) { //savenewworld(1); cwmWorldState.savenewworld(1); saveserverscript(1); return; } if (!(strcmp("REMOVE",comm))) { target(s, 0, 1, 0, 3, "Select item to remove."); return; } if (!(strcmp("TRAINER",comm))) { /*if (tnum==3) { i=0; script1[0]=0; while (tbuffer[offset+9+i]!=' ' && tbuffer[offset+9+i]!=0) i++; strncpy(script1,&tbuffer[offset+9],i); script1[i]=0; strupr(script1); addx[s]=-1; for (i=0;i1) { sprintf(xtext[s], "%s", &tbuffer[16]); target(s, 0, 1, 0, 203, "Select the NPC to set trigger word on."); } return; } if (!(strcmp("SETID",comm))) { if (tnum==3) { addid1[s]=hexnumber(1); addid2[s]=hexnumber(2); target(s, 0, 1, 0, 7, "Select item to polymorph."); } return; } if (!(strcmp("SETPRIV",comm))) { if (tnum==3) { addid1[s]=hexnumber(1); addid2[s]=hexnumber(2); target(s, 0, 1, 0, 9, "Select char to edit priv."); } if (tnum==2) { addid1[s]=hexnumber(1); target(s, 0, 1, 0, 89, "Select object to edit priv."); } return; } if (!(strcmp("NODECAY",comm))) { addid1[s]=0; target(s, 0, 1, 0, 89, "Select object to make permenant."); return; } #ifdef UNRELEASED if (!(strcmp("SEND",comm))) { for (i=1;i 0) && (newminutes > -1) && (newminutes <60)) { if (newhours > 12) { ampm=1; hour=newhours-12; } else { ampm=0; hour=newhours; } minute=newminutes; } } return; } if (!(strcmp("SETMORE",comm))) { if (tnum==5) { addid1[s]=hexnumber(1); addid2[s]=hexnumber(2); addid3[s]=hexnumber(3); addid4[s]=hexnumber(4); target(s, 0, 1, 0, 10, "Select item to edit 'more' value."); } return; } if (!(strcmp("SHUTDOWN",comm))) { if (tnum==2) { endtime=getclock()+(CLOCKS_PER_SEC*makenumber(1)); if (makenumber(1)==0) { endtime=0; sysbroadcast("Shutdown has been interrupted."); } else endmessage(); } return; } if (!(strcmp("MAKEGM",comm))) { target(s, 0, 1, 0, 14, "Select character to make a GM."); return; } if (!(strcmp("MAKECNS",comm))) { target(s, 0, 1, 0, 15, "Select character to make a Counselor."); return; } if (!(strcmp("KILLHAIR",comm))) { target(s, 0, 1, 0, 16, "Select character for cutting hair."); return; } if (!(strcmp("KILLBEARD",comm))) { target(s, 0, 1, 0, 17, "Select character for shaving."); return; } if (!(strcmp("KILLPACK",comm))) { target(s, 0, 1, 0, 18, "Select character to remove pack."); return; } if (!(strcmp("SETFONT",comm))) { if (tnum==2) { addid1[s]=hexnumber(1); target(s, 0, 1, 0, 19, "Select character to change font."); } return; } if (!(strcmp("WHOLIST",comm))) { whomenu(s,4); return; } if (!(strcmp("KILL",comm))) { target(s, 0, 1, 0, 20, "Select character to kill."); return; } if (!(strcmp("RESURRECT",comm))) { target(s, 0, 1, 0, 21, "Select character to resurrect."); return; } if (!(strcmp("BOLT",comm))) { target(s, 0, 1, 0, 22, "Select character to bolt."); return; } #ifdef UNRELEASED if (!(strcmp("BLT2",comm))) { if (tnum==4) { boltstring[1]=hexnumber(1); boltstring[2]=0; boltstring[3]=0; boltstring[4]=0; boltstring[5]=1; boltstring[10]=hexnumber(2); boltstring[11]=hexnumber(3); xsend(s, boltstring, 28, 0); } return; } #endif if (!(strcmp("SFX",comm))) { if (tnum==3) { soundeffect(s, hexnumber(1), hexnumber(2)); } return; } if (!(strcmp("NPCACTION",comm))) { if (tnum==2) { addid1[s]=hexnumber(1); target(s, 0, 1, 0, 53 , "Select npc to make act."); } return; } if (!(strcmp("LIGHT",comm))) { if (tnum==2) { worldfixedlevel=hexnumber(1); if (worldfixedlevel!=255) setabovelight(worldfixedlevel); else setabovelight(worldcurlevel); } return; } if (!(strcmp("SETAMOUNT",comm))) { if (tnum==2) { addx[s]=makenumber(1); target(s, 0, 1, 0, 23, "Select item to edit amount."); } return; } if (!(strcmp("SETAMOUNT2",comm))) { if (tnum==2) { addx[s]=makenumber(1); target(s, 0, 1, 0, 129, "Select item to edit amount."); } return; } #ifdef UNRELEASED if (!(strcmp("WEB",comm))) { if (tnum>1) { sprintf(xtext[s], "%s", &tbuffer[offset+4]); weblaunch(s, xtext[s]); } return; } #endif if (!(strcmp("DISCONNECT",comm))) { if (tnum==2) disconnect(makenumber(1)); } if (!(strcmp("KICK",comm))) { target(s, 0, 1, 0, 25, "Select character to kick."); return; } if (!(strcmp("TELL",comm))) { if (tnum>2) tellmessage(s, makenumber(1), &tbuffer[offset+6]); return; } if (!(strcmp("DRY",comm))) { wtype=0; for (i=0;i1) { i=0; script1[0]=0; script2[0]=0; while(tbuffer[offset+8+i]!=' ' && tbuffer[offset+8+i]!=0) i++; strncpy(script1,&tbuffer[offset+8],i); script1[i]=0; if ((script1[0]!='}')&&(c!=0)) strcpy(script2, &tbuffer[offset+8+i+1]); scriptcommand(s, script1, script2); } return; } if (!(strcmp("GCOLLECT",comm))) { gcollect(); return; } if (!(strcmp("ALLMOVEON",comm))) { chars[currchar[s]].priv2=chars[currchar[s]].priv2|0x01; teleport(currchar[s]); return; } if (!(strcmp("ALLMOVEOFF",comm))) { chars[currchar[s]].priv2=chars[currchar[s]].priv2&(0xFF-0x01); teleport(currchar[s]); return; } if (!(strcmp("SHOWHS",comm))) { chars[currchar[s]].priv2=chars[currchar[s]].priv2|0x04; teleport(currchar[s]); sysmessage(s, "House icons visible."); return; } if (!(strcmp("HIDEHS",comm))) { chars[currchar[s]].priv2=chars[currchar[s]].priv2&(0xFF-0x04); teleport(currchar[s]); sysmessage(s, "House icons hidden"); return; } if (!(strcmp("SETMOVABLE",comm))) { if (tnum==2) { addx[s]=makenumber(1); target(s, 0, 1, 0, 28, "Select item to edit mobility."); } return; } if (!(strcmp("SET",comm))) { if (tnum==3) { i=0; script1[0]=0; while (tbuffer[offset+4+i]!=' ' && tbuffer[offset+4+i]!=0) i++; strncpy(script1,&tbuffer[offset+4],i); script1[i]=0; strupr(script1); addx[s]=-1; for (i=0;i>8; talk2[2]=tl&0xFF; talk2[3]=chars[currchar[s]].ser1; talk2[4]=chars[currchar[s]].ser2; talk2[5]=chars[currchar[s]].ser3; talk2[6]=chars[currchar[s]].ser4; talk2[7]=chars[currchar[s]].id1; talk2[8]=chars[currchar[s]].id2; talk2[9]=buffer[s][3]; // Type talk2[10]=buffer[s][4]; talk2[11]=buffer[s][5]; talk2[12]=buffer[s][6]; talk2[13]=chars[currchar[s]].fonttype; talk2[14]=buffer[s][8]; talk2[15]=buffer[s][9]; talk2[16]=buffer[s][10]; xsend(s, talk2, 18, 0); xsend(s, chars[currchar[s]].name, 30, 0); for(i=-1;i<(tl-48)-2;i+=2) { xsend(s, &buffer[s][i+13], 2, 0); } if (talk2[9]==0) { chars[currchar[s]].saycolor1=buffer[s][4]; chars[currchar[s]].saycolor2=buffer[s][5]; } if (talk2[9]==2) { chars[currchar[s]].emotecolor1=buffer[s][4]; chars[currchar[s]].emotecolor2=buffer[s][5]; return; } for (i=0;i1)) ok=1; if (ok) { strcpy(temp2,temp); sprintf(temp, "%s%c", temp2, tile.name[j]); if (mode) used=1; } } if ((!used)&&(items[i].amount>1)) { strcpy(temp2,temp); sprintf(temp, "%ss", temp2); } if (items[i].type == 15) { char charges[]="charges"; sprintf(temp, "%s %s %i %s",temp, items[i].name2, items[i].morez, charges); } itemmessage(s, temp, a1, a2, a3, a4); } } } void mounthorse(int s, int x) // Remove horse char and give player a horse item { int j,c; if(npcinrange(s,x,2)==0) return; if (chars[x].ownserial==chars[currchar[s]].serial) // (chars[x].own1==chars[currchar[s]].ser1)&& // (chars[x].own2==chars[currchar[s]].ser2)&& // (chars[x].own3==chars[currchar[s]].ser3)&& // (chars[x].own4==chars[currchar[s]].ser4)) { if (chars[currchar[s]].onhorse) { sysmessage(s,"You are already on a mount."); return; } sprintf(temp, "%s", chars[x].name); chars[currchar[s]].onhorse=1; c=SpawnItem(s, 1, temp, 0, 0x09, 0x15, chars[x].skin1, chars[x].skin2, 0, 0); items[c].id1=0x3E; if (chars[x].id2==0xC8) items[c].id2=0x9F; if (chars[x].id2==0xE2) items[c].id2=0xA0; if (chars[x].id2==0xE4) items[c].id2=0xA1; if (chars[x].id2==0xCC) items[c].id2=0xA2; if (chars[x].id2==0xD2) items[c].id2=0xA3;//desert if (chars[x].id2==0xDA) items[c].id2=0xA4;//Harp if (chars[x].id2==0xDB) items[c].id2=0xA5;//Another if (chars[x].id2==0xDC) items[c].id2=0xA6;//llama setserial(c,currchar[s], 4); items[c].layer=0x19; items[c].x=chars[x].fx1; items[c].y=chars[x].fy1; items[c].z=chars[x].fz1; items[c].moreb1=chars[x].npcWander; items[c].att=chars[x].fx2; items[c].def=chars[x].fy2; wornitems(s, currchar[s]); for (j=0;j0x93))) { x=-1; sysmessage(s, "You cannot open monsters paperdolls."); } if (x!=-1) { if ((chars[currchar[s]].serial==serial) && (!keyboard)) if (unmounthorse(s)==0) x=-1; } if (x!=-1) { pdoll[1]=a1; pdoll[2]=a2; pdoll[3]=a3; pdoll[4]=a4; if (chars[x].priv&0x10) { //GM. sprintf(&pdoll[5], "%s %s", chars[x].name, chars[x].title); } else { //Player. sprintf(&pdoll[5], "%s%s", title3(x), chars[x].name); //Repuation + Name if ((chars[x].towntitle)||(chars[x].townpriv==2)) { //TownTitle. if (chars[x].townpriv==2) { //Mayor sprintf(&pdoll[5], "The Mayor %s of %s, %s %s", chars[x].name, townname(chars[x].town,3), title1(x), title2(x)); } else { //Resident sprintf(&pdoll[5], "%s of %s, %s %s", chars[x].name, townname(chars[x].town,3), title1(x), title2(x)); } } else { //NoTownTitle strcpy(temp,&pdoll[5]); //? if (strlen(chars[x].title)>0) { //Titled & Skill sprintf(&pdoll[5], "%s %s, %s %s", temp, chars[x].title, title1(x), title2(x)); } else { //Just skilled sprintf(&pdoll[5], "%s, %s %s", temp, title1(x), title2(x)); } } } xsend(s, pdoll, 66, 0); } x=-1; x=findbyserial(&itemsp[serial%256], serial, 0); if (x==-1) return; if (items[x].type==16) { if (chars[currchar[s]].dead==1) { buffer[s][7]=chars[currchar[s]].ser1; buffer[s][8]=chars[currchar[s]].ser2; buffer[s][9]=chars[currchar[s]].ser3; buffer[s][10]=chars[currchar[s]].ser4; resurrecttarget(s); sysmessage(s,"You have been resurrected."); return; } } if ((chars[currchar[s]].dead==1)&&(x!=-1)) { x=-1; sysmessage(s, "You may not do that as a ghost."); } // Zippy's snooping change start if (x!=-1) if (((items[x].type==1)||(items[x].type==63)||(items[x].type==65)||(items[x].type==87))&&(server_data.rogue))//&&(items[x].layer==0x15) { int npc, contser; contser=items[x].contserial; //calcserial(items[x].cont1,items[x].cont2,items[x].cont3,items[x].cont4); if (contser<0) { backpack(s,a1,a2,a3,a4); return; } if (items[x].cont1>=0x40) { do { x=findbyserial(&contsp[items[x].contserial%256], items[x].contserial, 0); //calcItemFromSer(items[x].cont1,items[x].cont2,items[x].cont3,items[x].cont4); //printf("Repeat: %i\n",z); //z++; } while (items[x].cont1>=0x40); } npc=findbyserial(&charsp[items[x].contserial%256], items[x].contserial, 1); //calcCharFromSer(items[x].cont1,items[x].cont2,items[x].cont3,items[x].cont4); if ((npcinrange(s,npc,2))||(chars[currchar[s]].priv&0x01)||(iteminrange(s,x,2))) { if ((x!=-1)&&(contser>1)&&(contser!=chars[currchar[s]].serial)&&!(chars[currchar[s]].priv&0x01)) //calcserial(chars[currchar[s]].ser1,chars[currchar[s]].ser2,chars[currchar[s]].ser3,chars[currchar[s]].ser4))&&!(chars[currchar[s]].priv&0x01)) { if ((checkskill(currchar[s],SNOOPING,0,1000))&&(!(chars[npc].priv&0x01))) { backpack(s, a1, a2, a3, a4); sysmessage(s,"You successfully peek into that container."); } else { sysmessage(s,"You failed to peek into that container."); //printf("Priv %i\n",chars[npc].priv); if (chars[npc].npc) npctalk(s,npc, "Art thou attempting to disturb my privacy?"); sprintf(temp,"You notice %s trying to peek into your pack!",chars[currchar[s]].name); sysmessage(calcCharFromSer(items[x].cont1,items[x].cont2,items[x].cont3,items[x].cont4),temp); if (chars[currchar[s]].karma<=1000) chars[currchar[s]].karma-=10; } } else backpack(s, a1, a2, a3, a4); } else { sysmessage(s,"You are too far away!"); } return; } //Zippy's snooping change - end if (!(chars[currchar[s]].priv&0x01)&&(x>=0)&&(items[x].layer!=0)&& // ((items[x].cont1!=chars[currchar[s]].ser1)||(items[x].cont2!=chars[currchar[s]].ser2)|| // (items[x].cont3!=chars[currchar[s]].ser3)||(items[x].cont4!=chars[currchar[s]].ser4))) (items[x].contserial!=chars[currchar[s]].serial)) { x=-1; sysmessage(s, "You cannot use items equipped by other players."); } if (x>=0) if((chars[currchar[s]].objectdelay<=getclock())||(chars[currchar[s]].priv&1)) { chars[currchar[s]].objectdelay=getclock()+(server_data.objectdelay*CLOCKS_PER_SEC); { if (items[x].trigger > 0) { if (iteminrange(s,x,1)) if (items[x].trigtype==0) { if (!items[x].disabled) { triggerwitem(s, x, 1); //if players uses trigger } else { sysmessage(s,"That doesnt seem to work right now."); } } else sysmessage(s, "You are not close enough to use that."); return; } //check this on trigger in the event that the .trigger property is not set on the item //trigger code. Check to see if item is envokable by id if (checkenvoke(items[x].id1,items[x].id2)) { chars[currchar[s]].envokeitem=x; chars[currchar[s]].envokeid1=items[x].id1; chars[currchar[s]].envokeid2=items[x].id2; target(s, 0, 1, 0, 24, "What will you use this on?"); return; } if (items[x].type==15) { if (items[x].morez!=0) { if(castspell(s, (8*(items[x].morex-1))+items[x].morey, 2, x)) { items[x].morez--; if (items[x].morez == 0) { items[x].type = items[x].type2; items[x].morex = 0; items[x].morey = 0; items[x].offspell = 0; } } } return; } if ((items[x].id1==0x0F)&&(items[x].id2==0xA9)) { dyeall[s]=0; target(s, 0, 1, 0, 31, "Which dye vat will you use this on?"); return; } if ((items[x].id1==0x0F)&&(items[x].id2==0xAB)) { addid1[s]=items[x].color1; addid2[s]=items[x].color2; target(s, 0, 1, 0, 32, "Select the clothing to use this on."); return; } if ((items[x].id1==0x14)&&(items[x].id2==0xF0)&&(items[x].type!=103)) { //experimental house code chars[currchar[s]].making=x; chars[currchar[s]].fx1=x; //for deleting it later addid3[s]=items[x].morex; buildhouse(s,items[x].morex); //target(s,0,1,0,207,"Select Location for house."); return; } if ((items[x].type==1)||(items[x].type==63)||(items[x].type==65)||(items[x].type==87)) { if (items[x].moreb1==1) magictrap(s, x); // if ((items[x].cont1==255)&&(items[x].cont2==255)&&(items[x].cont3==255)&&(items[x].cont4==255)) if (items[x].contserial==-1) backpack(s, a1, a2, a3, a4); // else if ((items[x].cont1==chars[currchar[s]].ser1)&&(items[x].cont2==chars[currchar[s]].ser2)&& // (items[x].cont3==chars[currchar[s]].ser3)&&(items[x].cont4==chars[currchar[s]].ser4)) else if (items[x].contserial==chars[currchar[s]].serial) backpack(s, a1, a2, a3, a4); else if (items[x].cont1>='\x40') backpack(s, a1, a2, a3, a4); else if (chars[currchar[s]].priv&0x40) backpack(s, a1, a2, a3, a4); else if (checkskill(currchar[s],SNOOPING,0,1000)) { backpack(s, a1, a2, a3, a4); sysmessage(s,"You successfully peek into their pack."); } else { int npc=-1; sprintf(temp,"You notice %s trying to peek into your pack!",chars[currchar[s]].name); npc=findbyserial(&charsp[items[x].contserial%256], items[x].contserial, 1); if (npc!=-1) { sysmessage(calcSocketFromChar(npc),temp); } if (chars[currchar[s]].karma<=1000) chars[currchar[s]].karma-=10; } //else sysmessage(s, "You may not look into other peoples belongings."); return; } if (items[x].type==2) { for (j=0;j0x2C && items[x].id2<0x6D)) { int success=0; if (items[x].id2==0x2D) //Reactive Armor spell scrolls { success=castspell(s,7, 1, 0); } if ((items[x].id2>=0x2E)&&(items[x].id2<=0x34)) //first circle spell scrolls { success=castspell(s,items[x].id2-0x2D, 1, 0); } if ((items[x].id2>=0x35)&&(items[x].id2<=0x6C)) //2 to 8 circle spell scrolls { success=castspell(s,items[x].id2-0x2D+1, 1, 0); } //remove scrolls if spell cast Tauriel if (success) { if (items[x].amount!=1) { items[x].amount--; for (j=0;j=0x43)&&(items[x].id2<=0x4E)))|| // Axe, Double Axe and Bardiche ((items[x].id1==0x13)&& ((items[x].id2==0xaf)||(items[x].id2==0xb0)|| // War Axe (items[x].id2==0xfa)||(items[x].id2==0xfb)))|| // Large Battle Axe ((items[x].id1==0x14)&& ((items[x].id2==0x42)||(items[x].id2==0x43)|| // Two Handed Axe (items[x].id2==0x3e)||(items[x].id2==0x3f)))) // Halberd { target(s, 0, 1, 0, 76, "What would you like to use that on ?"); return; } if ((items[x].id1==0x0F)&&((items[x].id2==0xB4)||(items[x].id2==0xB5))|| //sledge hammers (items[x].id1==0x0F)&&((items[x].id2==0xBB)||(items[x].id2==0xBC))|| //tongs (items[x].id1==0x13)&&((items[x].id2==0xE3)||(items[x].id2==0xE4))) //smith's hammers { target(s, 0, 1, 0, 50, "Select material to use."); return; } if ((items[x].id1==0x10)&&(items[x].id2>=0x26)&&(items[x].id2<=0x35)) //carpentry tools { target(s, 0, 1, 0, 134, "Select material to use."); return; } if ((items[x].id1==0x0E)&&((items[x].id2==0x85)||(items[x].id2==0x86))|| //pickaxes (items[x].id1==0x0F)&&((items[x].id2==0x39)||(items[x].id2==0x3A))) //shovels { target(s, 0, 1, 0, 51, "Where do you want to dig?"); return; } // Added by Genesis 11-16-98 to implement empty vial to vial of blood if((items[x].id1==0x0E)&&(items[x].id2==0x24)) //empty vial { // if((items[x].cont1==items[packitem(currchar[s])].ser1)&& // (items[x].cont2==items[packitem(currchar[s])].ser2)&& // (items[x].cont3==items[packitem(currchar[s])].ser3)&& // (items[x].cont4==items[packitem(currchar[s])].ser4)) if (items[x].contserial==items[packitem(currchar[s])].serial) { target(s, 0, 1, 0, 186, "What do you want to fill the vial with?"); } else sysmessage(s,"The vial is not in your pack"); return; } if ((items[x].id1==0x0D)&&(items[x].id2==0xF9)) //cotton to thread { chars[currchar[s]].tailitem=x; target(s, 0, 1, 0, 166, "Select spinning wheel to spin cotton."); return; } if ((items[x].id1==0x09)&&(items[x].id2==0xF1)) //Raw meat to Cooked { chars[currchar[s]].tailitem=x; target(s, 0, 1, 0, 168, "Select where to cook meat on."); return; } if ((items[x].type==100)) { for(i=0;i=0xD1 && items[x].id2<=0xD6)) // make shafts { itemmake[s].materialid1=items[x].id1; itemmake[s].materialid2=items[x].id2; target(s, 0, 1, 0, 172, "What would you like to use this with?"); return; } if ((items[x].id1==0x0E)&&(items[x].id2==0x73)) //cannon ball { target(s, 0, 1, 0, 170, "Select cannon to load."); deleitem(x); return; } if ((items[x].id1==0x0F)&&(items[x].id2==0xF8)||(items[x].id2==0xF9)) //pitcher of water to flour { chars[currchar[s]].tailitem=x; target(s, 0, 1, 0, 173, "Select flour to pour this on."); return; } if ((items[x].id1==0x09)&&(items[x].id2==0xC0)||(items[x].id2==0xC1)) //sausages to dough { chars[currchar[s]].tailitem=x; target(s, 0, 1, 0, 174, "Select dough to put this on."); return; } if ((items[x].id1==0x0D)&&(items[x].id2==0xF8)) //wool to yarn { chars[currchar[s]].tailitem=x; target(s, 0, 1, 0, 164, "Select your spin wheel to spin wool."); return; } if ((items[x].id1==0x0F)&&(items[x].id2==0x9D)) //sewing kit for tailoring { target(s, 0, 1, 0, 167, "Select material to use."); return; } if ((items[x].id1==0x19)&&((items[x].id2==0xB7)||(items[x].id2==0xB9)||(items[x].id2==0xBA)||(items[x].id2==0xB8))) { chars[currchar[s]].smeltitem=x; target(s, 0, 1, 0, 52, "Select forge to smelt ore on.");//smelting for all ore changed by Myth 11/12/98 return; } if (((items[x].id1==0x0E)&& ((items[x].id2>=0xC2)&&(items[x].id2<=0xC5)))|| //cleaver skinning knife ((items[x].id1==0x0F)&& ((items[x].id2==0x51)||(items[x].id2==0x52)) || // Dagger ((items[x].id2>=0x5E)&&(items[x].id2<=0x61)))|| // Broad Sword Long Sword1 ((items[x].id1==0x13)&& ((items[x].id2>=0xB5)&&(items[x].id2<=0xBA)|| // Scimitar Long Sword2 Viking Sword (items[x].id2==0xFE)||(items[x].id2==0xFF)))|| // Katana ((items[x].id1==0x14)&& ((items[x].id2==0x00)||(items[x].id2==0x01)|| // Kryss (items[x].id2==0x40)||(items[x].id2==0x41)))) // Cutlass { target(s, 0, 1, 0, 86, "What would you like to use that on ?"); return; } if ((items[x].id1==0x0D)&&((items[x].id2==0xE1)||(items[x].id2==0xE2))) { if(checkskill(currchar[s],CAMPING, 0, 500)) { c=SpawnItem(s,1,"#",0,0x0D,0xE3,0,0,0,0); items[c].type=45; items[c].dir=2; if (items[x].cont1==255 && items[x].cont2==255 && items[x].cont3==255 && items[x].cont4==255) { items[c].x=items[x].x; items[c].y=items[x].y; items[c].z=items[x].z; } else { items[c].x=chars[currchar[s]].x; items[c].y=chars[currchar[s]].y; items[c].z=chars[currchar[s]].z; } items[c].priv=items[c].priv|1; items[c].decaytime=(getclock()+(server_data.decaytimer*CLOCKS_PER_SEC)); for (k=0;k=0xFB)&&(items[x].id2<=0xFE))) { addmitem[s]=x; target(s, 0, 1, 0, 162, "What lock would you like to pick?"); return; } if (((items[x].id1==0x0C)&& ((items[x].id2==0x4f)||(items[x].id2==0x50)||(items[x].id2==0x51)|| (items[x].id2==0x52)||(items[x].id2==0x53)||(items[x].id2==0x54)))) //cotton plants { if (!chars[s].onhorse) action(s,0x0D); else action(s,0x1d); soundeffect(s,0x01,0x3E); c=SpawnItem(s,1,"#",1,0x0D,0xF9,0,0,1,1); setserial(c,packitem(currchar[s]), 1); items[chars[currchar[s]].tailitem].priv=items[chars[currchar[s]].tailitem].priv|0x01; sysmessage(s, "You reach down and pick some cotton."); return; } if ((items[x].id1==0x10)&&(items[x].id2==0x5B)||(items[x].id2==0x5C)|| (items[x].id1==0x10)&&(items[x].id2==0x53)||(items[x].id2==0x54)) //tinker axle { target(s, 0, 1, 0, 183, "Select part to combine the it with."); deleitem(x); return; } if ((items[x].id1==0x10)&&(items[x].id2==0x51)|| (items[x].id2==0x52)|| (items[x].id2==0x55)|| (items[x].id2==0x56)|| (items[x].id2==0x5D)|| (items[x].id2==0x5E)) { itemmake[s].materialid1=items[x].id1; itemmake[s].materialid2=items[x].id2; target(s, 0, 1, 0, 184, "Select part to combine it with."); return; } if ((items[x].id1==0x10)&&(items[x].id2==0x4F)||(items[x].id2==0x50)|| (items[x].id1==0x10)&&(items[x].id2==0x4D)||(items[x].id2==0x4E)) //tinker clock { target(s, 0, 1, 0, 185, "select clock frame to combine with"); deleitem(x); return; } if ((items[x].id1==0x10)&&(items[x].id2==0x59)||(items[x].id2==0x5A))//tinker sextant { if(checkskill(currchar[s],TINKERING, 0, 1000)) { sysmessage(s, "You create the sextant."); sprintf(temp,"a sextant"); c=SpawnItem(s,1,temp,0,0x10,0x57,0,0,1,1); setserial(c,packitem(currchar[s]), 1); items[chars[currchar[s]].tailitem].priv=items[chars[currchar[s]].tailitem].priv|0x01; deleitem(x); }else sysmessage(s, "you fail to create the sextant."); return; } if ((items[x].id1==0x10) && ((items[x].id2==0x70) || (items[x].id2==0x74))) { if (iteminrange(s,x,1)) tdummy(s); else sysmessage(s, "You need to be closer to use that."); return; } if ((items[x].id1==0x10) && ((items[x].id2==0x71) || (items[x].id2==0x75))) { sysmessage(s, "You must wait for it to stop swinging !"); return; } if ((items[x].id1==0x1E)&&(items[x].id2==0xBC)) //tinker's tools { target(s, 0, 1, 0, 180, "Select material to use."); return; } if (items[x].type==103) //Army enlistment { enlist(s, items[x].morex); deleitem(x); return; } if (items[x].type==104) // Teleport object { chars[currchar[s]].x=items[x].morex; chars[currchar[s]].y=items[x].morey; chars[currchar[s]].z=chars[currchar[s]].dispz=items[x].morez; teleport(currchar[s]); return; } if (items[x].type==105) // For drinking { int drinksnd; drinksnd=rand()%2; switch(drinksnd) { case 0: soundeffect2(currchar[s], 0x00, 0x31); break; case 1: soundeffect2(currchar[s], 0x00, 0x30); break; } int j; //Remove a drink if (items[x].amount!=1) { items[x].amount--; for (j=0;j0) { for (i=recvcount;i0)); return count; } void getmsg(int s) // Receive message from client { int count, ho, mi, se, total, i, j, k, book,serial,serhash,ci; char nonuni[512]; if (newclient[s]) { count=recv(client[s], buffer[s], 4, 0); if ((buffer[s][0]=='\x21')&&(count<4)) // UOMon { total=(getclock()-starttime)/CLOCKS_PER_SEC; ho=total/3600; total-=ho*3600; mi=total/60; total-=mi*60; se=total; sprintf(monitor, "UOX3 LoginServer\r\nUOX3 Server: up for %ih %im %is\r\n",ho,mi,se); xsend(s, monitor, strlen(monitor), 0); newclient[s]=0; } else { clientip[s][0]=buffer[s][0]; clientip[s][1]=buffer[s][1]; clientip[s][2]=buffer[s][2]; clientip[s][3]=buffer[s][3]; gentable(s, buffer[s][0], buffer[s][1], buffer[s][2], buffer[s][3]); // Init encryption table newclient[s]=0; if ((buffer[s][0]==0x12)&&(buffer[s][1]==0x34)&&(buffer[s][2]==0x56)&&(buffer[s][3]==0x78)) disconnect(s); } } else { recvcount=0; if (receive(s, 1, 0)>0) { switch(buffer[s][0]) { case 0x01:// Main Menu on the character select screen disconnect(s); break; case 0x80:// First Login receive(s, 62, 1); login1(s); break; case 0xA0:// Server Select receive(s, 3, 1); relay(s); break; case 0x91:// Second Login receive(s, 65, 1); cryptclient[s]=1; charlist(s); break; case 0x83:// Character Delete receive(s, 0x27, 1); chardel(s); break; case 0x00:// Character Create receive(s, 100, 1); charcreate(s); break; case 0x5D:// Character Select receive(s, 0x49, 1); charplay(s); break; case 0x02:// Walk receive(s, 3, 1); walking(currchar[s], buffer[s][1], buffer[s][2]); break; case 0x73:// Keep alive receive(s, 2, 1); xsend(s, buffer[s], 2, 0); break; case 0x22:// Resync Request receive(s, 3, 1); teleport(currchar[s]); break; case 0x03:// Speech receive(s, 3, 0); receive(s, (buffer[s][1]*256)+buffer[s][2], 1); chars[currchar[s]].unicode=0; if(chars[currchar[s]].making==998) //rename house sign { sprintf(items[addid1[s]].name,"%s",buffer[s]+8); chars[currchar[s]].making=0; addid1[s]=0; } else if(chars[currchar[s]].runenumb!=-1) { sprintf(items[chars[currchar[s]].runenumb].name,"Rune to %s",buffer[s]+8); sprintf(temp,"Rune renamed to: Rune to %s",buffer[s]+8); sysmessage(s,temp); chars[currchar[s]].runenumb=-1; } else if(chars[currchar[s]].pagegm==1) { int a1,a2,a3,a4; a1=chars[currchar[s]].ser1; a2=chars[currchar[s]].ser2; a3=chars[currchar[s]].ser3; a4=chars[currchar[s]].ser4; sprintf(gmpages[chars[currchar[s]].playercallnum].reason,"%s",buffer[s]+8); sprintf(temp, "GM Page from %s [%x %x %x %x]: %s", chars[currchar[s]].name, a1, a2, a3, a4, gmpages[chars[currchar[s]].playercallnum].reason); int x=0; for (i=0;i=0x40) && (buffer[s][10]!=0xff) ) pack_item(s); else dump_item(s); break; case 0x72:// Combat Mode receive(s, 5, 1); chars[currchar[s]].war=buffer[s][1]; chars[currchar[s]].targ=-1; xsend(s, buffer[s], 5, 0); walking2(currchar[s]); dosocketmidi(s); break; case 0x12:// Ext. Command receive(s, 3, 0); receive(s, (buffer[s][1]*256)+buffer[s][2], 1); if (buffer[s][3]=='\xC7') // Action { if (!(strcmp(&buffer[s][4],"bow"))) action(s, 0x20); if (!(strcmp(&buffer[s][4],"salute"))) action(s, 0x21); } else if (buffer[s][3]=='\x24') // Skill { i=4; while (buffer[s][i]!=' ') i++; buffer[s][i]=0; skilluse(s, str2num(&buffer[s][4])); } else if ((buffer[s][3]=='\x27')||(buffer[s][3]=='\x56')) // Spell { j=0; k=packitem(currchar[s]); serial=items[k].serial; serhash=serial%256; for (i=0;i0x20) book=(book*10)+(buffer[s][5]-0x30); } if (j!=0 && checkBook(((book-1)/8)+1, (book-1)%8, j)) if (chars[s].priv2&2) sysmessage(s, "You cannot cast spells while frozen."); else castspell(s, book, 0, 0); else sysmessage(s, "You don't have that spell."); } else if ((buffer[s][2]=='\x05')&&(buffer[s][3]=='\x43')) // Open spell book { spellbook(s); } break; case 0x9B:// GM Page receive(s, 0x102, 1); gmmenu(s, 1); break; case 0x7D:// Choice receive(s, 13, 1); choice(s); break; case 0x95:// Color Select receive(s, 9, 1); dyeitem(s); break; case 0x34:// Status Request receive(s, 10, 1); srequest(s); break; case 0x75:// Rename Character receive(s, 0x23, 1); for(i=0;i0)||(strlen(chars[i].title)>0)) { //printf("UOX3: %s is attacking a guarded creature and must be destroyed!\n", chars[currchar[s]].name); spawnguard(currchar[s], s, chars[currchar[s]].x+2, chars[currchar[s]].y, chars[currchar[s]].z); //printf("UOX3: Guards have been dispatched to kill %s!\n", chars[currchar[s]].name); } } } if ((chars[i].npc)&&!(chars[i].npcaitype==0x40)) { if (!(chars[i].war)) npcToggleCombat(i); chars[i].npcmovetime=(unsigned long int)(getclock()+(NPCSPEED*CLOCKS_PER_SEC)); } break; } } else sysmessage(s,"You are dead and cannot do that."); break; case 0xB1:// Gumpmenu choice receive(s, 3, 0); receive(s, (buffer[s][1]*256)+buffer[s][2], 1); gumpbutton(s, buffer[s][14], buffer[s][3], buffer[s][4], buffer[s][5], buffer[s][6], buffer[s][10]); break; case 0xAC:// Textentry input receive(s, 3, 0); receive(s, (buffer[s][1]*256)+buffer[s][2], 1); gumpinput(s); break; case 0x2C:// Resurrect menu choice receive(s, 2, 0); if(buffer[s][1]==0x02) sysmessage(s, "You are now a ghost."); if(buffer[s][1]==0x01) sysmessage(s, "The connection between your spirit and the world is too weak."); break; case 0x3B:// Buy from vendor... receive(s, 3, 0); receive(s, (buffer[s][1]*256)+buffer[s][2], 1); buyaction(s); break; case 0x9F:// Sell to vendor... receive(s, 3, 0); receive(s, (buffer[s][1]*256)+buffer[s][2], 1); sellaction(s); break; case 0x69:// Client text change receive(s, 3, 0);// What a STUPID message... It would be useful if receive(s, (buffer[s][1]*256)+buffer[s][2], 1);// it included the color changed to, but it doesn't! break; case 0x6F:// Secure Trading message receive(s, 3, 0); receive(s, (buffer[s][1]*256)+buffer[s][2], 1); trademsg(s); break; case 0xB6:// T2A Popuphelp request receive(s, 9, 0); break; case 0xB8:// T2A Profile request receive(s, 8, 0); break; default: printf("Unknown message:%x\n", buffer[s][0]); #ifdef DEBUG printf("???\n"); #endif FD_ZERO(&all); FD_SET(client[s],&all); nfds=client[s]+1; if (select(nfds, &all, NULL, NULL, &uoxtimeout)>0) { // recvcount=0; receive(s, 2560, 1); } break; } } else { disconnect(s); } } } void sockinit() // Initialize sockets { int i; char h1=0, h2=0, h3=0, h4=0; int bcode; int on=1, off=0; #ifdef __NT__ wVersionRequested=0x0101; err=WSAStartup(wVersionRequested, &wsaData); if (err) { printf("ERROR: Winsock 1.1 not found...\n"); keeprun=0; error=1; return; } #endif a_socket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (a_socket<0) { printf("ERROR: Unable to create socket\n"); keeprun=0; error=1; return; } #ifndef __NT__ setsockopt(a_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); #endif /* gethostname(hname,40); he=gethostbyname(hname); conns=0; if (he==NULL) { printf("NOTE: No available connections. Using loopback adress for offline operation.\n"); printf(" Remember that this may cause client crashes on startup. Read the readme!.txt\n"); printf(" chapter 'Setup Instructions' on information about how to solve this."); h1=127; h2=0; h3=0; h4=1; } else { do { p=(*he).h_addr_list[conns]; if (p!=NULL) conns++; } while (p!=NULL); if (conns==0) { printf("NOTE: No available connections. Using loopback adress for offline operation."); h1=127; h2=0; h3=0; h4=1; } else if (conns==1) { printf("NOTE: Available connection found."); h1=(*he).h_addr_list[0][0]; h2=(*he).h_addr_list[0][1]; h3=(*he).h_addr_list[0][2]; h4=(*he).h_addr_list[0][3]; } else { printf("NOTE: Multiple available connections found.\n"); printf("IP adresses:\n"); for (i=0;iconns-1)); h1=(*he).h_addr_list[number][0]; h2=(*he).h_addr_list[number][1]; h3=(*he).h_addr_list[number][2]; h4=(*he).h_addr_list[number][3]; } } sprintf(ipa,"%i.%i.%i.%i",h1,h2,h3,h4); */ len_connection_addr=sizeof (struct sockaddr_in); connection.sin_family=AF_INET; // connection.sin_addr.s_addr=inet_addr(ipa); connection.sin_addr.s_addr=INADDR_ANY; // connection.sin_port=htons(UOX_PORT); connection.sin_port=((UOX_PORT%256)*256)+(UOX_PORT/256); bcode=bind(a_socket, (struct sockaddr *)&connection, len_connection_addr); if (bcode<0) { printf("ERROR: Unable to bind socket 1 - Error code: %i\n",bcode); keeprun=0; error=1; return; } listen(a_socket, 42); // printf("\nUOX3: Listening on connection (%i.%i.%i.%i:%i)\n",h1,h2,h3,h4,UOX_PORT); login03[1]=h1; login03[2]=h2; login03[3]=h3; login03[4]=h4; login03[7]=h1; login03[8]=h2; login03[9]=h3; login03[10]=h4; for (i=0;i0) { len=sizeof (struct sockaddr_in); // printf("Waiting at accept()\n"); #if defined(__FreeBSD__) && (__FreeBSD_version >= 400013) client[now]=accept(a_socket, (struct sockaddr *)&client_addr, (socklen_t*)&len); #else client[now]=accept(a_socket, (struct sockaddr *)&client_addr, &len); #endif // printf("Done! :)\n"); if (client[now]<0) { printf("ERROR: Error at client connection!\n"); error=1; keeprun=0; return; } server[now]=-1; newclient[now]=1; acctno[now]=-1; addid1[now]=0; addid2[now]=0; addid3[now]=0; addid4[now]=0; perm[now]=0; funnypack[now]=0; binlength[now]=0; boutlength[now]=0; cryptclient[now]=0; cryptmask[now][0]=0; cryptmask[now][1]=0; usedfree[now]=0; walksequence[now]=-1; #ifdef __NT__ printf("UOX3: Client %i [%i.%i.%i.%i] connected [Total:%i].\n",now,client_addr.sin_addr.S_un.S_un_b.s_b1 _ client_addr.sin_addr.S_un.S_un_b.s_b2 _ client_addr.sin_addr.S_un.S_un_b.s_b3 _ client_addr.sin_addr.S_un.S_un_b.s_b4,now+1); #else printf("UOX3: Client %i connected [Total:%i].\n",now,now+1); #endif now++; return; } if (s<0) { printf("ERROR: Select (Conn) failed!\n"); keeprun=0; error=1; return; } } } void checkmessage () // Check for messages from the clients { int s, i, oldnow; FD_ZERO(&all); FD_ZERO(&errsock); nfds=0; for (i=0;infds) nfds=client[i]+1; if (server[i]>=0) { FD_SET(server[i],&all); FD_SET(server[i],&errsock); if (server[i]+1>nfds) nfds=server[i]+1; } } s=select(nfds, &all, NULL, &errsock, &uoxtimeout); if (s>0) { oldnow=now; for (i=0;i= 0) { if (FD_ISSET(server[i],&errsock)) { closesocket(server[i]); failauth(i); } } if ((FD_ISSET(client[i],&all))&&(oldnow==now)) { getmsg(i); if (executebatch) batchcheck(i); } if (server[i] >= 0) { if ((FD_ISSET(server[i],&all))&&(oldnow==now)) { authtest(i); } } } } /* if (s<0) { printf("ERROR: Select (Mess) failed!\n"); keeprun=0; error=1; return; } */ } //o----------------------------------------------------------------------------o //| Function - void checkkey() //| Date - Unknown //| Programmer - Unknown (Touched up by EviLDeD) //o----------------------------------------------------------------------------o //| Purpose - Facilitate console control. SysOp keys, and localhost //| controls. //o----------------------------------------------------------------------------o #ifdef __NT__ void checkkey () { char c; int i; int lookfor; if (kbhit()) { c=toupper(getch()); if (c=='S') { if (secure) { printf("UOX3: Secure mode disabled.\n"); secure=0; } else { printf("UOX3: Secure mode re-enabled.\n"); secure=1; } } else if (secure==1) { printf("NOTE: Secure mode prevents keyboard commands!\n"); return; } switch(c) { case '\x1B': printf("UOX3: Immediate Shutdown initialized!\n"); if(heartbeat) Writeslot("shutdown"); keeprun=0; break; case 'Q': printf("UOX3: Immediate Shutdown initialized!\n"); if(heartbeat) Writeslot("shutdown"); keeprun=0; break; case 'T': endtime=getclock()+(CLOCKS_PER_SEC*600); endmessage(); break; case '#': cwmWorldState.savenewworld(1); saveserverscript(1); break; case 'L': if (showlayer) { printf("UOX3: Layer display disabled.\n"); showlayer=0; } else { printf("UOX3: Layer display enabled.\n"); showlayer=1; } break; case 'I': readini(); // for (i=0;itclock) overflow=1; else overflow=0; if (endtime) { if (endtime<=tclock) keeprun=0; } lclock=tclock; } void checkauto() // Check automatic/timer controlled stuff (Like fighting and regeneration) { int x, pcalc, timer; char zbuf[10]; unsigned int i,currenttime=getclock(); //\/ getclock only once char t[120]; if ((heartbeat)&&(hbu>5)) { sprintf(zbuf,"%d",saveinterval-5);//printf(zbuf); Writeslot(zbuf);hbu=0; } if (wtype!=0) { if (resendweathertime<=currenttime||(overflow)) { for (i=0;i=saveinterval) { autosaved = 0; cwmWorldState.savenewworld(0); //savenewworld(0); saveserverscript(0); } } //Time functions if (uotickcount<=currenttime||(overflow)) { if (minute < 59) {minute++;hbu++;} else { minute=0; if (hour < 12) hour++; else { hour = 1; ampm = !ampm; if (!ampm) day++; } } uotickcount=currenttime+secondsperuominute*CLOCKS_PER_SEC; if (minute%8==0) moon1=(moon1+1)%8; if (minute%3==0) moon2=(moon2+1)%8; } doworldlight(); //Changes lighting, if it is currently time to. for (i=0;i0) { soundeffect(i, 0x01, 0xFE); chars[i].dead=1; deletechar(i); i++; } } } if(server_data.bg_sounds>=1) { if(server_data.bg_sounds>10) server_data.bg_sounds=10; timer=server_data.bg_sounds*100; if((online(i))&&(!(chars[i].npc))&&(!(chars[i].dead))&&((rand()%(timer))==(timer/2))) bgsound(calcSocketFromChar(i)); } // flee code if (chars[i].npc) //; { if ((chars[i].fleeat==0)) chars[i].fleeat=NPC_BASE_FLEEAT; if ((chars[i].reattackat==0)) chars[i].reattackat=NPC_BASE_REATTACKAT; } if ((chars[i].npc)&& !(chars[i].npcWander==5)&& (chars[i].hpchars[i].st*chars[i].reattackat/100)) { chars[i].npcWander=chars[i].oldnpcWander; chars[i].npcmovetime=(unsigned long int)(currenttime+(NPCSPEED*CLOCKS_PER_SEC)); chars[i].oldnpcWander=0; // so it won't save this at the wsc file } // end of flee code if (!(chars[i].dead)) { if (chars[i].hp>chars[i].st) { chars[i].hp=chars[i].st; updatestats(i, 0); } if (chars[i].stm>chars[i].dx) { chars[i].stm=chars[i].dx; updatestats(i, 2); } if (chars[i].mn>chars[i].in) { chars[i].mn=chars[i].in; updatestats(i, 1); } if ((hungerdamagetimer<=currenttime)||(overflow)) // Damage them if they are very hungry { hungerdamagetimer=currenttime+(server_data.hungerdamagerate*CLOCKS_PER_SEC); if (chars[i].hp>0 && chars[i].hunger<3 && server_data.hungerdamage && !(chars[i].priv&0x80)) { chars[i].hp=chars[i].hp-server_data.hungerdamage; updatestats(i, 0); if(chars[i].hp<=0) { sysmessage(calcSocketFromChar(i),"You have died of starvation"); deathstuff(i); } } } if ((chars[i].regen<=currenttime)||(overflow)) { chars[i].regen=currenttime+(server_data.hitpointrate*CLOCKS_PER_SEC); if (chars[i].hp3 || server_data.hungerrate==0) { if (chars[i].skill[17]<500) chars[i].hp++; else if (chars[i].skill[17]<800) chars[i].hp += 2; else chars[i].hp += 3; if (chars[i].hp>chars[i].st) chars[i].hp=chars[i].st; updatestats(i, 0); } } if ((chars[i].regen2<=currenttime)||(overflow)) { chars[i].regen2=currenttime+(server_data.staminarate*CLOCKS_PER_SEC); if (chars[i].stmhighest) highest=current; } } while (strcmp("EOF",temp)); closescript(); fprintf(lstfile, " %s: %i\n", txt, highest); } int main(int argc, char *argv[]) { int i; unsigned long tempSecs; unsigned long tempMilli; unsigned long loopSecs; unsigned long loopMilli; unsigned long tempTime; #ifdef __NT__ constart(); sprintf(temp, "%s V%s", PRODUCT, VER); SetConsoleTitle(temp); clearscreen(); #else signal(SIGPIPE, SIG_IGN); // This appears when we try to write to a broken network connection signal(SIGTERM, &endmessage); signal(SIGQUIT, &endmessage); signal(SIGINT, &endmessage); signal(SIGILL, &illinst); #endif openings=0; if (argc>1) if (!(strcmp(argv[1],"#"))) { printf("\nUOX3 Menu List Generator Module\n\n"); printf("Creating UOXMENUS.LST...\n"); lstfile=fopen("UOXMENUS.LST","w"); if (lstfile==NULL) { printf("ERROR: UOXMENUS.LST could not be created.\n"); error=1; keeprun=0; return 0; } fprintf(lstfile, "UOX3 Script Menu List\n\n"); fprintf(lstfile, "This file is intended to allow you to do a quick lookup for certain items\n"); fprintf(lstfile, "or menus that you might be searching.\n\n"); fprintf(lstfile, "Maximum used numbers: (Always use numbers higher than those)\n"); scriptmax("GMMENU"); scriptmax("BATCH"); scriptmax("NPC"); scriptmax("SPEECH"); scriptmax("ITEMMENU"); scriptmax("ITEM"); scriptmax("LOCATION"); fprintf(lstfile, "\nShort List: (Menus only)\n"); fprintf(lstfile, "GM Master Item Menu (ITEMMENU 1)\n"); scriptlist(1, 1, 0); fprintf(lstfile, "\nLong List: (Menus and Items)\n"); fprintf(lstfile, "GM Master Item Menu (ITEMMENU 1)\n"); scriptlist(1, 1, 1); fprintf(lstfile, "\nUOX3 Copyright 1998 by UOX Team\n"); fclose(lstfile); printf("List creation complete!\n"); return 0; } uoxtimeout.tv_sec=0; uoxtimeout.tv_usec=0; keeprun=1; error=0; now=0; secure=1; charcount=0; itemcount=0; charcount2=1; itemcount2=0x40000000; donpcupdate=0; wtype=0; cmemover=0; cmemcheck=-1; imemover=0; imemcheck=-1; xcounter=0; ycounter=0; for (i=0;i<301;i++) freecharmem[i]=-1; for (i=0;i<501;i++) freeitemmem[i]=-1; for (i=0;i", PRODUCT, VER, NAME, EMAIL); #else sprintf(idname, "Ultima Offline eXperiment 3 Server Version %s Alpha [LINUX] by %s <%s>", VER, NAME, EMAIL); #endif printf("\n%s V%s Alpha", PRODUCT, VER); #ifdef __NT__ printf(" for Win32"); #else printf(" for Linux"); #endif printf("\n"); printf("(Configured for connections by UO Client versions starting with 1.25.%i)\n", CLIENTVERSION); printf("Copyright (C) 1997, 98 Marcus Rating (Cironian)\n\n"); printf("This program is free software; you can redistribute it and/or modify\n"); printf("it under the terms of the GNU General Public License as published by\n"); printf("the Free Software Foundation; either version 2 of the License, or\n"); printf("(at your option) any later version.\n\n"); printf("%s version %s\n", PRODUCT, VER); printf("Compiled at %s (%s %s)\n",__DATE__,__TIME__,TIMEZONE); printf("Compiled by %s <%s>\n",NAME,EMAIL); if (sizeof(tile_st)!=37) printf("This version of UOX3 was complied incorrectly. sizeof(tile_st) = %d \n", sizeof(tile_st)); printf("\n"); sockinit(); srand(getclock()); // initial randomization call loadserverdefaults(); loadserverscript(); loadnewworld(); // sectioning(); // For sectioning Items and chars arrays clearalltrades(); im_loadmenus( "inscribe.gmp", tellscroll ); //loading gump for inscribe() gcollect(); FD_ZERO(&conn); starttime=getclock(); endtime=0; lclock=0; initque(); // Initialize gmpages[] array loadregions(); towninit(); loadskills(); loadcustomtitle(); // EviLDeD - Make sure to set the WorldSave announce value here // December 27, 1998 cwmWorldState.announce(server_data.announceworldsaves); // EviLDeD - End printf("UOX3: Startup Complete.\n"); savelog("-=Server Startup=-\n=======================================================================\n","server.log"); if (strlen(server_data.archivepath)>1) printf("UOX3: Archiving enabled. (%s)\n",server_data.archivepath); while (keeprun) { #ifdef __NT__ checkkey(); #endif #ifdef _MSVC Sleep(20); //kolours - slight tune to 40 from 50 (09/19/98) #else #ifdef __NT__ delay(20); // My compiler uses sleep() for full seconds, so I had to use this. #else usleep(20000); //kolours - slight tune to 40000 from 50000 (09/19/98) #endif #endif if(loopTimeCount >= 1000) { loopTimeCount = 0; loopTime = 0; } loopTimeCount++; StartMilliTimer(loopSecs, loopMilli); if(networkTimeCount >= 1000) { networkTimeCount = 0; networkTime = 0; } StartMilliTimer(tempSecs, tempMilli); checkconn(); checkmessage(); tempTime = CheckMilliTimer(tempSecs, tempMilli); networkTime += tempTime; networkTimeCount++; if(timerTimeCount >= 1000) { timerTimeCount = 0; timerTime = 0; } StartMilliTimer(tempSecs, tempMilli); checktimers(); tempTime = CheckMilliTimer(tempSecs, tempMilli); timerTime += tempTime; timerTimeCount++; if(autoTimeCount >= 1000) { autoTimeCount = 0; autoTime = 0; } StartMilliTimer(tempSecs, tempMilli); checkauto(); tempTime = CheckMilliTimer(tempSecs, tempMilli); autoTime += tempTime; autoTimeCount++; clearbuffers(); tempTime = CheckMilliTimer(loopSecs, loopMilli); loopTime += tempTime; } sysbroadcast("The server is shutting down"); Writeslot("shutdown"); im_clearmenus(); sockclose(); fclose(mapfile); fclose(sidxfile); fclose(statfile); fclose(verfile); fclose(tilefile); fclose(multifile); fclose(midxfile); // WSACleanup(); (Commented out as this caused weird bugs for some reason; works fine now) cwmWorldState.savenewworld(1); saveserverscript(1); printf("\n"); if (error) { printf("ERROR: Server terminated by error!\n"); savelog("Server Shutdown by Error!\n=======================================================================\n\n\n","server.log"); } else { printf("UOX3: Server shutdown complete!\n"); savelog("Server Shutdown!\n=======================================================================\n\n\n","server.log"); } return 0; } char iteminrange (int s, int i, int distance) { int c=1; int xa, xb, ya, yb, dx, dy; int vr=distance; xa=chars[currchar[s]].x; ya=chars[currchar[s]].y; xb=items[i].x; yb=items[i].y; dx=abs(xa-xb); dy=abs(ya-yb); if (dx>vr) c=0; if (dy>vr) c=0; if (chars[currchar[s]].priv&1) c=1; return c; } char npcinrange (int s, int i, int distance) { int c=1; int xa, xb, ya, yb, dx, dy; int vr=distance; if (i==-1) return 1; xa=chars[currchar[s]].x; ya=chars[currchar[s]].y; xb=chars[i].x; yb=chars[i].y; dx=abs(xa-xb); dy=abs(ya-yb); if (dx>vr) c=0; if (dy>vr) c=0; if (chars[currchar[s]].priv&1) c=1; return c; } void titletarget(int s) { int i,serial; serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); i=findbyserial(&charsp[serial%256], serial, 1); if (i!=-1) { sprintf(chars[i].title,xtext[s]); } } void decay(unsigned int currenttime) // for item decay, only corpses for now { int i,j,k,serial,serhash,ci; if (nextdecaytime<=currenttime||(overflow)) { for (i=0;i= abs(chars[s].z)) && ((abs(items[i].z) - 10 ) <= abs(chars[s].z)) && (items[i].morex+items[i].morey+items[i].morez !=0)) { chars[s].x=items[i].morex; chars[s].y=items[i].morey; chars[s].dispz=chars[s].z=items[i].morez; teleport(s); } // advancement objects if ((items[i].type==80)&&(items[i].x==chars[s].x)&&(items[i].y==chars[s].y) &&((abs(items[i].z) + 10 ) >= abs(chars[s].z)) && ((abs(items[i].z) - 10 ) <= abs(chars[s].z)) &&!(chars[s].npc)) if(items[i].more1!=0 || items[i].more2!=0 || items[i].more3!=0 || items[i].more4!=0) { if(chars[s].ser1==items[i].more1 && chars[s].ser2==items[i].more2 && chars[s].ser3==items[i].more3 && chars[s].ser4==items[i].more4) advancementobjects(s,items[i].morex,0); } else advancementobjects(s,items[i].morex,0); if ((items[i].type==81)&&(items[i].x==chars[s].x)&&(items[i].y==chars[s].y) &&((abs(items[i].z) + 10 ) >= abs(chars[s].z)) && ((abs(items[i].z) - 10 ) <= abs(chars[s].z)) &&!(chars[s].npc)) if(items[i].more1!=0 || items[i].more2!=0 || items[i].more3!=0 || items[i].more4!=0) { if(chars[s].ser1==items[i].more1 && chars[s].ser2==items[i].more2 && chars[s].ser3==items[i].more3 && chars[s].ser4==items[i].more4) advancementobjects(s,items[i].morex,1); } else advancementobjects(s,items[i].morex,1); // The above code lets you restrict a gate's use by setting its MORE values to a char's // serial # // damage objects if ((!(chars[s].priv&4))&& (items[i].type==85)&&(items[i].x==chars[s].x)&& (items[i].y==chars[s].y)&&((abs(items[i].z) + 10 ) >= abs(chars[s].z)) && ((abs(items[i].z) - 10 ) <= abs(chars[s].z))) { chars[s].hp=chars[s].hp-(items[i].morex+RandomNum(items[i].morey,items[i].morez)); if (chars[s].hp<1) chars[s].hp=0; updatestats(s, 0); if (chars[s].hp==0) deathstuff(s); } // monster gates if ((items[i].type==82)&&(items[i].x==chars[s].x)&&(items[i].y==chars[s].y) &&((abs(items[i].z) + 10 ) >= abs(chars[s].z)) && ((abs(items[i].z) - 10 ) <= abs(chars[s].z)) &&!(chars[s].npc)) monstergate(s,items[i].morex); // sound objects if ((items[i].type==86)&&(items[i].x==chars[s].x)&& (items[i].y==chars[s].y)&&((abs(items[i].z) + 10 ) >= abs(chars[s].z)) && ((abs(items[i].z) - 10 ) <= abs(chars[s].z))) { if (RandomNum(1,100)<=items[i].morez) soundeffect3(i, items[i].morex, items[i].morey); } } } void npcToggleCombat(int s) { chars[s].war=(!(chars[s].war)); walking2(s); } int chardir(int a, int b) // direction from character a to char b { int dir,xdif,ydif; xdif = chars[b].x-chars[a].x; ydif = chars[b].y-chars[a].y; if ((xdif==0)&&(ydif<0)) dir=0; else if ((xdif>0)&&(ydif<0)) dir=1; else if ((xdif>0)&&(ydif==0)) dir=2; else if ((xdif>0)&&(ydif>0)) dir=3; else if ((xdif==0)&&(ydif>0)) dir=4; else if ((xdif<0)&&(ydif>0)) dir=5; else if ((xdif<0)&&(ydif==0)) dir=6; else if ((xdif<0)&&(ydif<0)) dir=7; else dir=-1; return dir; } char tileblock(int tilenum) { tile_st tile; seektile(tilenum, &tile); return (tile.flag1&0x40); } char tilewalk(int tilenum) { tile_st tile; seektile(tilenum, &tile); return (tile.flag4&0x04); } char stablock(int x, int y, int oldz) { int k; // Check stablock cache, if enabled. if (STABLOCKCACHESIZE) { k=0; while (k127) k=k-256; if (k>=oldz-5) { k=height(x-1, y, oldz); if (oldz<127 && k>127) k=k-256; if (k>=oldz-5) { k=height(x, y+1, oldz); if (oldz<127 && k>127) k=k-256; if (k>=oldz-5) { k=height(x, y-1, oldz); if (oldz<127 && k>127) k=k-256; if (k>=oldz-5) { stablockcachex[stablockcachei]=x; stablockcachey[stablockcachei]=y; stablockcachez[stablockcachei]=oldz; stablockcacher[stablockcachei]=0; stablockcachei=(stablockcachei+1)%STABLOCKCACHESIZE; return 0; } } } } } stablockcachex[stablockcachei]=x; stablockcachey[stablockcachei]=y; stablockcachez[stablockcachei]=oldz; stablockcacher[stablockcachei]=1; stablockcachei=(stablockcachei+1)%STABLOCKCACHESIZE; return 1; } char oldstablock(int x, int y, int oldz) // Blocking statics at/above given coordinates? { long int pos, pos2, length; int x1, x2; int y1, y2; signed char z, ztemp, found, btemp; int i; // tile_st tile; struct staticrecord { short int itemid; char xoff; char yoff; char zoff; short int extra; // Unknown yet } stat; // EviLDeD - Bug killing memset(&stat,0,sizeof(staticrecord)); stat.itemid=stat.itemid; stat.extra=stat.extra; z=-127; found=0; x1=x/8; // Block y1=y/8; x2=(x-(x1*8)); // Offset y2=(y-(y1*8)); pos=(x1*512*12)+(y1*12); fseek(sidxfile, pos, SEEK_SET); fread(&pos2, 4, 1, sidxfile); if (pos2!=-1) { if (feof(sidxfile)) { printf("Error: Avoiding bad read crash.\n"); return 0; } fread(&length, 4, 1, sidxfile); length=length/7; fseek(statfile, pos2, SEEK_SET); for (i=0;i=stat.zoff-1 && (oldz= MAXCHARS)) { //LogMessage("calcSocketFromChar() - Bad char number (%i)\n" _ i); return -1; } if (chars[i].npc) return -1; for (j=0; j=0) && (i < MAXCHARS)) return (chars[i].ser1*16777216)+(chars[i].ser2*65536)+(chars[i].ser3*256)+chars[i].ser4; else { LogMessage("calcSerFromChar() - char not existant (%i)"_ i); return -1; } } int calcItemFromSer(int ser1, int ser2, int ser3, int ser4) { int serial; serial=calcserial(ser1, ser2, ser3, ser4); return findbyserial(&itemsp[serial%256], serial, 0); } void npcwalk(int i, int j, int type) //type is npcwalk mode (0 for normal, 1 for box, 2 for circle) { int x,y,z; x=chars[i].x; y=chars[i].y; z=chars[i].z; if (chars[i].dir==j) // If we're moving, not changing direction { switch(j) // Switch, based on the direction we're going to move. { case 0: // North if ((validNPCMove(x, y-1, z, i))&&( (!type)|| ((type==1)&&(checkBoundingBox(x, y-1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2, chars[i].fy2)))|| ((type==2)&&(checkBoundingCircle(x, y-1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2)))) ) walking(i, j, 256); // arm code break; case 1: // Northeast if ((validNPCMove(x+1, y-1, z, i) && validNPCMove(x+1, y, z, i) && validNPCMove(x, y-1, z, i))&&( (!type)|| ((type==1)&&(checkBoundingBox(x+1, y-1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2, chars[i].fy2)))|| ((type==2)&&(checkBoundingCircle(x+1, y-1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2)))) ) walking(i, j, 256); // arm code break; case 2: // East if ((validNPCMove(x+1, y, z, i))&&( (!type)|| ((type==1)&&(checkBoundingBox(x+1, y, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2, chars[i].fy2)))|| ((type==2)&&(checkBoundingCircle(x+1, y, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2)))) ) walking(i, j, 256); // arm code break; case 3: // Southeast if ((validNPCMove(x+1, y+1, z, i) && validNPCMove(x+1, y, z, i) && validNPCMove(x, y+1, z, i))&&( (!type)|| ((type==1)&&(checkBoundingBox(x+1, y+1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2, chars[i].fy2)))|| ((type==2)&&(checkBoundingCircle(x+1, y+1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2)))) ) walking(i, j, 256); // arm code break; case 4: // South if ((validNPCMove(x, y+1, z, i))&&( (!type)|| ((type==1)&&(checkBoundingBox(x, y+1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2, chars[i].fy2)))|| ((type==2)&&(checkBoundingCircle(x, y+1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2)))) ) walking(i, j, 256); // arm code break; case 5: // Southwest if ((validNPCMove(x-1, y+1, z, i) && validNPCMove(x-1, y, z, i) && validNPCMove(x, y+1, z, i))&&( (!type)|| ((type==1)&&(checkBoundingBox(x-1, y+1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2, chars[i].fy2)))|| ((type==2)&&(checkBoundingCircle(x-1, y+1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2)))) ) walking(i, j, 256); // arm code break; case 6: // West if ((validNPCMove(x-1, y, z, i))&&( (!type)|| ((type==1)&&(checkBoundingBox(x-1, y, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2, chars[i].fy2)))|| ((type==2)&&(checkBoundingCircle(x-1, y, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2)))) ) walking(i, j, 256); // arm code break; case 7: // Northwest if ((validNPCMove(x-1, y-1, z, i) && validNPCMove(x-1, y, z, i) && validNPCMove(x, y-1, z, i))&&( (!type)|| ((type==1)&&(checkBoundingBox(x-1, y-1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2, chars[i].fy2)))|| ((type==2)&&(checkBoundingCircle(x-1, y-1, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2)))) ) walking(i, j, 256); // arm code break; } } else if (j<8) walking(i, j, 256); } void npcMovement(unsigned int currenttime) { //********************************************************** //kolours - for increase in world performance //********************************************************** //taking it from the point of view of the player's chars, as //i plan to have more npcs than players once the world is //complete (therefore minimal calculations) register int i; register int k; int j, dnpctime, x; for(k=0;k1 || chardir(i, k)!=chars[i].dir) { if (online(k)||chars[k].npc) { j=chardir(i, chars[i].attacker); if (chars[i].blocked) { x=0; if (j/2.0!=j/2) x=1; //if (chars[i].blocked<=2) j =chars[i].dir2; if (chars[i].blocked<=2) j=chars[i].dir2=(j-2-x)%8; //works better else { if (rand()%2) j=chars[i].dir2=(j-2-x)%8; else j=chars[i].dir2=(j+2+x)%8; } } npcwalk(i,j,0); } } } else { switch(chars[i].npcWander) { case 0: // No movement break; case 1: // Follow the follow target k=(chars[i].ftarg); if (!(online(k)||chars[k].npc)) break; if (chardist(i, k)>1 || chardir(i, k)!=chars[i].dir) { j=chardir(i, k); if (chars[i].blocked) { x=0; if (j/2.0!=j/2) x=1; if (chars[i].blocked<=2) j =chars[i].dir2; else { if (rand()%2) j=chars[i].dir2=(j-2-x)%8; else j=chars[i].dir2=(j+2+x)%8; } } npcwalk(i,j,0); } break; case 2: // Wander freely, avoiding obstacles. j=rand()%40; if (j<8 || j>32) dnpctime=5; if (j>7 && j<33) // Let's move in the same direction lots of the time. Looks nicer. j=chars[i].dir; npcwalk(i,j,0); break; case 3: // Wander freely, within a defined box j=rand()%40; if (j<8 || j>32) dnpctime=5; if (j>7 && j<33) // Let's move in the same direction lots of the time. Looks nicer. j=chars[i].dir; npcwalk(i,j,1); break; case 4: // Wander freely, within a defined circle /* if (!(checkBoundingCircle(chars[i].x, chars[i].y, chars[i].fx1, chars[i].fy1, chars[i].fz1, chars[i].fx2))) { doesnt flipping work. chars[i].x=chars[i].fx1; Who wrote this shit? chars[i].y=chars[i].fy1; if (chars[i].fz1==-1) { chars[i].dispz=chars[i].z=height(chars[i].x, chars[i].y, chars[i].z); } else { chars[i].dispz=chars[i].z=chars[i].fz1; } teleport(i); } */ j=rand()%40; j=rand()%40; if (j<8 || j>32) dnpctime=5; if (j>7 && j<33) // Let's move in the same direction lots of the time. Looks nicer. j=chars[i].dir; npcwalk(i,j,0); break; case 5: //FLEE!!!!!! { k=chars[i].targ; //if (!(online(k)||chars[k].npc)) break; if (chardist(i, k)<15) { j=(chardir(i, k)+4)%8; if (chars[i].blocked) { x=0; if (j/2.0!=j/2) x=1; if (chars[i].blocked<=2) j =chars[i].dir2; else { if (rand()%2) j=chars[i].dir2=(j-2-x)%8; else j=chars[i].dir2=(j+2+x)%8; } } npcwalk(i,j,0); } break; } break; } } chars[i].npcmovetime=(unsigned long int)(currenttime+(NPCSPEED*CLOCKS_PER_SEC*(1+dnpctime))); //reset move timer } } } } } } int validNPCMove(int x, int y, int z, int s) { int i, j=0, k=height(x, y, z); chars[s].blocked++; if (abs(k-z)<=5 && !(stablock(x, y, k)) && maptype(x,y)) // If the difference in heights is 5 or less. // This should take care of dynamic object collision, I think. // And there's no static object in the way at the new height. { j=1; for (i=0;i0 & npcaitype!=0) // printf("NPC %s is attempting to open door (NPCAITYPE = %i)\n", chars[s].name, chars[s].npcaitype); if ((strlen(chars[s].title) > 0)||(chars[s].npcaitype != 0)) { // printf("NPC %s has opened the door. (NPCAI = %i)\n", chars[s].name, chars[s].npcaitype); dooruse(-1,i); } // End of change - Dupois //dooruse(-1,i); // Commented out by Dupois for change above chars[s].blocked=0; return 0; } if (items[i].id1==0x39 && (items[i].id2==0x46 || items[i].id2==0x56)) return 0; if (items[i].id1<=2 || (items[i].id1==3 && items[i].id2<=0xE2)) return 0; if (items[i].id1==0x08 && (items[i].id2>0x54 && items[i].id2<0x66)) return 0; } } chars[s].blocked=0; } return j; } int checkBoundingBox(int xPos, int yPos, int fx1, int fy1, int fz1, int fx2, int fy2) { if (xPos>=((fx1=((fy1 (Type 69) xos and yos (X OffSet, Y OffSet) are used to find a random number that is then added to the spawner's x and y (Using the spawner's z) and then place the NPC anywhere in a square around the spawner. This square is random anywhere from -10 to +10 from the spawner's location (for x and y) If the place chosen is not a valid position (the NPC can't walk there) then a new place will be chosen, if a valid place cannot be found in a certain # of tries (50), the NPC will be placed directly on the spawner and the server op will be warned. */ /* if ((items[s].type==69)&&(items[s].contserial==-1)) { if (items[s].more3==0) items[s].more3=10; if (items[s].more4==0) items[s].more4=10; do { if (k>=50) //this CAN be a bit laggy. adjust as nessicary { printf("UOX3: Problem area spawner found at [%i,%i,%i]. NPC placed at default location.\n",items[s].x,items[s].y,items[s].z); xos=0; yos=0; break; } xos=RandomNum(-items[s].more3,items[s].more3); yos=RandomNum(-items[s].more4,items[s].more4); //printf("Spawning at Offset %i,%i (%i,%i,%i) [-%s,%s <-> -%s,%s]. [Loop #: %i]\n",xos,yos,items[s].x+xos,items[s].y+yos,items[s].z,items[s].more3,items[s].more3,items[s].more4,items[s].more4,k); k++; } while (!validNPCMove(items[s].x+xos,items[s].y+yos,items[s].z,c)); } // end Zippy's changes (exept for all the +xos and +yos around here....) if (chars[c].fx1==-1) { chars[c].fx1=items[s].x+xos; chars[c].fy1=items[s].y+yos; if (chars[c].fz1!=-1) chars[c].fz1=items[s].z; } chars[c].x=items[s].x+xos; chars[c].y=items[s].y+yos; chars[c].dispz=chars[c].z=items[s].z; setserial(c,s,6); } } else { if (chars[c].fx1==-1) { chars[c].fx1=(buffer[s][11]*256)+buffer[s][12]+xos; chars[c].fy1=(buffer[s][13]*256)+buffer[s][14]+yos; if (chars[c].fz1!=-1) chars[c].fz1=buffer[s][16]+tileheight(buffer[s][17]*256+buffer[s][18]); } chars[c].x=(buffer[s][11]*256)+buffer[s][12]+xos; chars[c].y=(buffer[s][13]*256)+buffer[s][14]+yos; chars[c].dispz=chars[c].z=buffer[s][16]+tileheight(buffer[s][17]*256+buffer[s][18]); } chars[c].priv=0x10; chars[c].npc=1; chars[c].att=1; chars[c].def=1; // Dupois - added to fix teleporting guards bug. Guards would not teleport because // newly created NPC's would not have their chars[x].region updated on creation // (only after moving the first time). Therefore if NPC was set never to move, or // never did move, its chars[x].region would always be -1 and never allow a guard // to teleport in to guard NPC chars[c].region=calcRegionFromXY(chars[c].x, chars[c].y); openscript("npc.scp"); sprintf(sect, "NPC %i", x); if (!npc_script.find(sect)) { closescript(); return; } do { read2(); if (script1[0]!='}') { if (!(strcmp("NAME",script1))) { sprintf(chars[c].name, "%s", script2); } if (!(strcmp("NAMELIST", script1))) { pos=ftell(scpfile); closescript(); setrandomname(c,script2); openscript("npc.scp"); fseek(scpfile, pos, SEEK_SET); sprintf(script1, "DUMMY"); // To prevent accidental exit of loop. } if (!(strcmp("NPCLIST", script1))) { pos=ftell(scpfile); closescript(); donpcupdate++; if (type==1){ deletechar(c); addrandomnpc(s,script2,1); //Taur v69.02 //addrandomnpc(c,script2,s); }else{ deletechar(c); addrandomnpc(c,script2,-1); } donpcupdate--; openscript("npc.scp"); fseek(scpfile, pos, SEEK_SET); sprintf(script1, "DUMMY"); } if (!(strcmp("TITLE",script1))) sprintf(chars[c].title, "%s", script2); if (!(strcmp("KARMA",script1))) chars[c].karma=str2num(script2); if (!(strcmp("FAME",script1))) chars[c].fame=str2num(script2); if (!(strcmp("ID",script1))) { tmp=hstr2num(script2); chars[c].id1=tmp/256; chars[c].id2=tmp%256; chars[c].xid1=chars[c].id1; chars[c].xid2=chars[c].id2; } if (!(strcmp("SKIN",script1))) { tmp=hstr2num(script2); chars[c].skin1=tmp/256; chars[c].skin2=tmp%256; chars[c].xskin1=chars[c].skin1; chars[c].xskin2=chars[c].skin2; } if (!(strcmp("DIRECTION",script1))) { if (!(strcmp("NE",script2))) chars[c].dir=1; if (!(strcmp("E",script2))) chars[c].dir=2; if (!(strcmp("SE",script2))) chars[c].dir=3; if (!(strcmp("S",script2))) chars[c].dir=4; if (!(strcmp("SW",script2))) chars[c].dir=5; if (!(strcmp("W",script2))) chars[c].dir=6; if (!(strcmp("NW",script2))) chars[c].dir=7; if (!(strcmp("N",script2))) chars[c].dir=0; } if (!(strcmp("BACKPACK", script1))) { if (mypack==-1) { for(z=0;z (Type 69) xos and yos (X OffSet, Y OffSet) are used to find a random number that is then added to the spawner's x and y (Using the spawner's z) and then place the NPC anywhere in a square around the spawner. This square is random anywhere from -10 to +10 from the spawner's location (for x and y) If the place chosen is not a valid position (the NPC can't walk there) then a new place will be chosen, if a valid place cannot be found in a certain # of tries (50), the NPC will be placed directly on the spawner and the server op will be warned. */ if ((items[s].type==69)&&(items[s].contserial==-1)) { if (items[s].more3==0) items[s].more3=10; if (items[s].more4==0) items[s].more4=10; do { if (k>=50) //this CAN be a bit laggy. adjust as nessicary { printf("UOX3: Problem area spawner found at [%i,%i,%i]. NPC placed at default location.\n",items[s].x,items[s].y,items[s].z); xos=0; yos=0; break; } xos=RandomNum(-items[s].more3,items[s].more3); yos=RandomNum(-items[s].more4,items[s].more4); //printf("Spawning at Offset %i,%i (%i,%i,%i) [-%s,%s <-> -%s,%s]. [Loop #: %i]\n",xos,yos,items[s].x+xos,items[s].y+yos,items[s].z,items[s].more3,items[s].more3,items[s].more4,items[s].more4,k); k++; } while (!validNPCMove(items[s].x+xos,items[s].y+yos,items[s].z,c)); } // end Zippy's changes (exept for all the +xos and +yos around here....) if (chars[c].fx1==-1) { chars[c].fx1=items[s].x+xos; chars[c].fy1=items[s].y+yos; if (chars[c].fz1!=-1) chars[c].fz1=items[s].z; } chars[c].x=items[s].x+xos; chars[c].y=items[s].y+yos; chars[c].dispz=chars[c].z=items[s].z; setserial(c,s,6); } } else { if (chars[c].fx1==-1) { chars[c].fx1=(buffer[s][11]*256)+buffer[s][12]+xos; chars[c].fy1=(buffer[s][13]*256)+buffer[s][14]+yos; if (chars[c].fz1!=-1) chars[c].fz1=buffer[s][16]+tileheight(buffer[s][17]*256+buffer[s][18]); } chars[c].x=(buffer[s][11]*256)+buffer[s][12]+xos; chars[c].y=(buffer[s][13]*256)+buffer[s][14]+yos; chars[c].dispz=chars[c].z=buffer[s][16]+tileheight(buffer[s][17]*256+buffer[s][18]); } chars[c].region=calcRegionFromXY(chars[c].x, chars[c].y); //Now find real 'skill' based on 'baseskill' (stat modifiers) for(z=0;z=0xCA)&&(buffer[s][0x12]<=0xCD))))|| ((buffer[s][0x11]==0x12)&&(buffer[s][0x12]>=0xB8)&&(buffer[s][0x12]<=0xBB))|| ((buffer[s][0x11]==0x0D)&& ((buffer[s][0x12]==0x42)||(buffer[s][0x12]==0x43)||(buffer[s][0x12]==0x58)|| (buffer[s][0x12]==0x59)||(buffer[s][0x12]==0x70)||(buffer[s][0x12]==0x85)|| (buffer[s][0x12]==0x94)||(buffer[s][0x12]==0x95)||(buffer[s][0x12]==0x98)|| (buffer[s][0x12]==0xa4)||(buffer[s][0x12]==0xa8)||(buffer[s][0x12]==0x58)))) { treetarget(s); } else if ((buffer[s][0x11]==0x20) && (buffer[s][0x12]==0x06)) { corpsetarget(s); } } void corpsetarget(int s) { int i; int n=0; for (i=0;i=10 && ampm)) i=worlddarklevel; if ((hour>=10&& (!ampm)) || (hour<=3 && ampm)) i=worldbrightlevel; if (i==-1) { i=(((60*(hour-4))+minute) * (worlddarklevel-worldbrightlevel)) / 360; if (ampm) { i=i+worldbrightlevel; } else { i=worlddarklevel-i; } } if (wtype) i=i+2; if (moon1+moon2<4) i=i+1; if (moon1+moon2<10) i=i+1; c=i; setabovelight(c); } void swordtarget(int s) { if (buffer[s][11]==0xFF && buffer[s][12]==0xFF && buffer[s][13]==0xFF && buffer[s][14]==0xFF) return; int k,c; if (((buffer[s][0x11]==0x0C)&& ((buffer[s][0x12]==0xD0)||(buffer[s][0x12]==0xD3)||(buffer[s][0x12]==0xD6)|| (buffer[s][0x12]==0xD8)||(buffer[s][0x12]==0xDA)||(buffer[s][0x12]==0xDD)|| (buffer[s][0x12]==0xE0)||(buffer[s][0x12]==0xE3)||(buffer[s][0x12]==0xE6)|| ((buffer[s][0x12]>=0xCA)&&(buffer[s][0x12]<=0xCD))))|| ((buffer[s][0x11]==0x12)&&(buffer[s][0x12]>=0xB8)&&(buffer[s][0x12]<=0xBB))) { if (!chars[s].onhorse) action(s,0x0D); else action(s,0x1d); soundeffect(s,0x01,0x3E); c=SpawnItem(s,1,"#",1,0x0D,0xE1,0,0,0,0); //Kindling items[c].x=chars[currchar[s]].x; items[c].y=chars[currchar[s]].y; items[c].z=chars[currchar[s]].z; for (k=0;k=0)&&(minute<=14)) sprintf(tstring,"It is"); else if ((minute>=15)&&(minute<=30)) sprintf(tstring,"It is a quarter past"); else if ((minute>=30)&&(minute<=45)) sprintf(tstring,"It is half past"); else { sprintf(tstring,"It is a quarter till"); lhour++; if (lhour==0) lhour=12; } if (lhour==1) sprintf(tstring2,"%s one o'clock",tstring); else if (lhour==2) sprintf(tstring2,"%s two o'clock",tstring); else if (lhour==3) sprintf(tstring2,"%s three o'clock",tstring); else if (lhour==4) sprintf(tstring2,"%s four o'clock",tstring); else if (lhour==5) sprintf(tstring2,"%s five o'clock",tstring); else if (lhour==6) sprintf(tstring2,"%s six o'clock",tstring); else if (lhour==7) sprintf(tstring2,"%s seven o'clock",tstring); else if (lhour==8) sprintf(tstring2,"%s eight o'clock",tstring); else if (lhour==9) sprintf(tstring2,"%s nine o'clock",tstring); else if (lhour==10) sprintf(tstring2,"%s ten o'clock",tstring); else if (lhour==11) sprintf(tstring2,"%s eleven o'clock",tstring); else if ((lhour==12)&&(ampm)) sprintf(tstring2,"%s midnight.",tstring); else sprintf(tstring2,"%s noon.",tstring); if (lhour==12) sprintf(tstring,"%s",tstring2); else if (ampm) { if ((lhour>=1)&&(lhour<6)) sprintf(tstring,"%s in the afternoon.",tstring2); else if ((lhour>=6)&&(lhour<9)) sprintf(tstring,"%s in the evening.",tstring2); else sprintf(tstring,"%s at night.",tstring2); } else { if ((lhour>=1)&&(lhour<5)) sprintf(tstring,"%s at night.",tstring2); else sprintf(tstring,"%s in the morning.",tstring2); } sysmessage(s,tstring); } void updateskill(int s, int skillnum) { char update[8]; int i; for (i=0;i<8;i++) { update[i]=0; } update[0]=0x3A; // Skill Update Message update[1]=0x00; // Length of message update[2]=0x08; // Length of message update[3]=0xff; // Unknown update[4]=0x00; update[5]=skillnum; update[6]=chars[currchar[s]].skill[skillnum]/256; update[7]=chars[currchar[s]].skill[skillnum]%256; if (s!=-1) xsend(s, update, 8, 0); } void setdirtarget(int s) { int i,j,serial; serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); if (buffer[s][7]>=0x40) { i=findbyserial(&itemsp[serial%256], serial, 0); if (i!=-1) { items[i].dir=addx[s]; for (j=0;j0)&&(ydif<0)) dir=1; else if ((xdif>0)&&(ydif==0)) dir=2; else if ((xdif>0)&&(ydif>0)) dir=3; else if ((xdif==0)&&(ydif>0)) dir=4; else if ((xdif<0)&&(ydif>0)) dir=5; else if ((xdif<0)&&(ydif==0)) dir=6; else if ((xdif<0)&&(ydif<0)) dir=7; else dir=-1; return dir; } int fielddir(int s, int x, int y, int z) { int dir=chardirxyz(s, x, y, z); switch (dir) { case 0: case 4: return 0; break; case 2: case 6: return 1; break; case 1: case 3: case 5: case 7: case -1: switch(chars[currchar[s]].dir) { case 0: case 4: return 0; break; case 2: case 6: return 1; break; case 1: case 3: case 5: case 7: return 1; } } return 1; } int checkforchar(int x, int y, int z) { int i; for (i=0;i= MAXCHARS)) && (teffects[i].num != 14) && (teffects[i].num != 13) && (teffects[i].num != 9) && (teffects[i].num != 10) ) { //LogMessage("checktempeffects() - char overflow s (%i) i (%i)\n" _ s _ i); //LogMessage("teffects num = (%i)\n" _ teffects[i].num); //LogMessage("Fixing on the fly..\n"); memcpy(&teffects[i],&teffects[teffectcount-1],sizeof(teffect_st)); teffectcount--; i--; break; } //End of TANiS' change } //if (s != -1) switch(teffects[i].num) { case 1: if (chars[s].priv2&0x02) { chars[s].priv2=chars[s].priv2&0xFD; s=calcSocketFromChar(s); if (s!=-1) sysmessage(s, "You are no longer frozen."); } break; case 2: chars[s].fixedlight=255; dolight(calcSocketFromChar(s), worldbrightlevel); break; case 3: chars[s].dx=chars[s].dx+teffects[i].more1; statwindow(calcSocketFromChar(s), s); break; case 4: chars[s].in=chars[s].in+teffects[i].more1; statwindow(calcSocketFromChar(s), s); break; case 5: chars[s].st=chars[s].st+teffects[i].more1; statwindow(calcSocketFromChar(s), s); break; case 6: chars[s].dx=chars[s].dx-teffects[i].more1; chars[s].stm=min(chars[s].stm, chars[s].dx); statwindow(calcSocketFromChar(s), s); break; case 7: chars[s].in=chars[s].in-teffects[i].more1; chars[s].mn=min(chars[s].mn, chars[s].in); statwindow(calcSocketFromChar(s), s); break; case 8: chars[s].st=chars[s].st-teffects[i].more1; chars[s].hp=min(chars[s].hp, chars[s].st); statwindow(calcSocketFromChar(s), s); break; case 9: switch(teffects[i].more1) { case 0: if (teffects[i].more2!=0) { sprintf(temp, "*%s continues grinding.*", chars[s].name); npcemoteall(s, temp); } soundeffect2(s, 0x02, 0x42); break; } break; case 10: s=calcCharFromSer(teffects[i].sour1, teffects[i].sour2, teffects[i].sour3, teffects[i].sour4); mortar=calcItemFromSer(teffects[i].dest1, teffects[i].dest2, teffects[i].dest3, teffects[i].dest4); createpotion(s, teffects[i].more1, teffects[i].more2, mortar); break; case 11: chars[s].st=chars[s].st-teffects[i].more1; chars[s].hp=min(chars[s].hp, chars[s].st); chars[s].dx=chars[s].dx-teffects[i].more2; chars[s].stm=min(chars[s].stm, chars[s].dx); chars[s].in=chars[s].in-teffects[i].more3; chars[s].mn=min(chars[s].mn, chars[s].in); statwindow(calcSocketFromChar(s), s); break; case 12: chars[s].st=chars[s].st+teffects[i].more1; chars[s].dx=chars[s].dx+teffects[i].more2; chars[s].in=chars[s].in+teffects[i].more3; statwindow(calcSocketFromChar(s), s); break; case 13: mortar=calcItemFromSer(teffects[i].dest1, teffects[i].dest2, // door teffects[i].dest3, teffects[i].dest4); if (items[mortar].dooropen==0) break; items[mortar].dooropen=0; dooruse(calcSocketFromChar(s), mortar); break; case 14: //- training dummies Tauriel check to see if item moved or not before searching for it j = teffects[i].itemptr; if (items[j].ser1 == teffects[i].dest1 && items[j].ser2 == teffects[i].dest2 && items[j].ser3 == teffects[i].dest3 && items[j].ser4 == teffects[i].dest4) {mortar = j;} else mortar=calcItemFromSer(teffects[i].dest1, teffects[i].dest2, teffects[i].dest3, teffects[i].dest4); if ((items[mortar].id1==0x10) && (items[mortar].id2==0x71)) { items[mortar].id2=0x70; items[mortar].gatetime=0; for (j=0;j255) more1=chars[dest].dx-255; chars[dest].dx=chars[dest].dx+more1; statwindow(calcSocketFromChar(dest), dest); teffects[teffectcount].expiretime=getclock()+((chars[source].skill[MAGERY]/10)*CLOCKS_PER_SEC); teffects[teffectcount].num=6; teffects[teffectcount].more1=more1; teffects[teffectcount].more2=0; teffects[teffectcount].dispellable=1; break; case 7: if (chars[dest].in+more1>255) more1=chars[dest].in-255; chars[dest].in=chars[dest].in+more1; statwindow(calcSocketFromChar(dest), dest); teffects[teffectcount].expiretime=getclock()+((chars[source].skill[MAGERY]/10)*CLOCKS_PER_SEC); teffects[teffectcount].num=7; teffects[teffectcount].more1=more1; teffects[teffectcount].more2=0; teffects[teffectcount].dispellable=1; break; case 8: if (chars[dest].st+more1>255) more1=chars[dest].st-255; chars[dest].st=chars[dest].st+more1; statwindow(calcSocketFromChar(dest), dest); teffects[teffectcount].expiretime=getclock()+((chars[source].skill[MAGERY]/10)*CLOCKS_PER_SEC); teffects[teffectcount].num=8; teffects[teffectcount].more1=more1; teffects[teffectcount].more2=0; teffects[teffectcount].dispellable=1; break; case 9: teffects[teffectcount].expiretime=getclock()+(more2*CLOCKS_PER_SEC); teffects[teffectcount].num=9; teffects[teffectcount].more1=more1; teffects[teffectcount].more2=more2; teffects[teffectcount].dispellable=0; break; case 10: teffects[teffectcount].expiretime=getclock()+(12*CLOCKS_PER_SEC); teffects[teffectcount].dispellable=0; teffects[teffectcount].more1=more1; teffects[teffectcount].more2=more2; teffects[teffectcount].num=10; break; case 11: // Bless if (chars[dest].st+more1>255) more1=chars[dest].st-255; if (chars[dest].dx+more2>255) more2=chars[dest].dx-255; if (chars[dest].in+more3>255) more3=chars[dest].in-255; chars[dest].st=chars[dest].st+more1; chars[dest].dx=chars[dest].dx+more2; chars[dest].in=chars[dest].in+more3; statwindow(calcSocketFromChar(dest), dest); teffects[teffectcount].expiretime=getclock()+((chars[source].skill[MAGERY]/10)*CLOCKS_PER_SEC); teffects[teffectcount].num=11; teffects[teffectcount].more1=more1; teffects[teffectcount].more2=more2; teffects[teffectcount].more3=more3; teffects[teffectcount].dispellable=1; break; case 12: // Curse if (chars[dest].stchardist(target, target2)) { chars[target].targ=target2; chars[target].attacker=target2; chars[target].attackfirst=1; } if (((chardist(target2, chars[target2].targ))>chardist(target, target2))&& ((!(chars[target2].npcaitype==0x40))||(!((chars[target2].targ==-1))))) { chars[target2].targ=target; chars[target2].attacker=target; chars[target2].attackfirst=0; } if ((chars[target].hidden)&&(!(chars[target].priv2&8))) { chars[target].hidden=0; updatechar(target); } if ((chars[target2].hidden)&&(!(chars[target2].priv2&8))) { chars[target2].hidden=0; updatechar(target); } if (chars[target].npc) { if (!(chars[target].war)) npcToggleCombat(target); chars[target].npcmovetime=(unsigned long int)(getclock()+(NPCSPEED*CLOCKS_PER_SEC)); } if ((chars[target2].npc)&&!(chars[target2].npcaitype==0x40)) { if (!(chars[target2].war)) npcToggleCombat(target2); chars[target2].npcmovetime=(unsigned long int)(getclock()+(NPCSPEED*CLOCKS_PER_SEC)); } sprintf(temp, "* You see %s attacking %s *", chars[target].name, chars[target2].name); for (i=0;i=1) { dupetimes=addid1[s]; int dupeit; int i; serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); i=findbyserial(&itemsp[serial%256], serial, 0); if (i!=-1) { for (dupeit=0;dupeit MAXCHARS) ) { #ifdef DEBUG printf("impowncreate -> i overflow. (%i)", i); #endif i = 0; } oc[0]=0x78; // Message type 78 oc[1]=0x00; // Length bit 1; oc[2]=0x00; // Length bit 2; oc[3]=chars[i].ser1; // Character serial number oc[4]=chars[i].ser2; // Character serial number oc[5]=chars[i].ser3; // Character serial number oc[6]=chars[i].ser4; // Character serial number oc[7]=chars[i].id1; // Character art id oc[8]=chars[i].id2; // Character art id oc[9]=chars[i].x/256; // Character x position oc[10]=chars[i].x%256; // Character x position oc[11]=chars[i].y/256; // Character y position oc[12]=chars[i].y%256; // Character y position if (z) oc[13]=chars[i].dispz; // Character z position else oc[13]=chars[i].z; oc[14]=chars[i].dir; // Character direction oc[15]=chars[i].skin1; // Character skin color oc[16]=chars[i].skin2; // Character skin color oc[17]=0; // Character flags if (chars[i].hidden || !(online(i)||chars[i].npc)) oc[17]=oc[17]|0x80; // Show hidden state correctly oc[18]=0; if (chars[i].npcaitype&0x0D) oc[18]=1; // If a good NPC, show as blue if (chars[i].npcaitype&0x02) oc[18]=6; // If a bad NPC, show as red. if (chars[i].npcaitype&0x58) oc[18]=6; // EV Being marked as red k=19; for (j=0;j0) { i=rand()%(i); openscript("npc.scp"); if(!npc_script.find(sect)) { closescript(); return -1; } do { read1(); if (script1[0]!='}') { if(j==i) { //script1 = ITEM# storeval=str2num(script1); pos=ftell(scpfile); closescript(); retitem=addmenutarget(-1, 0, storeval); openscript("npc.scp"); fseek(scpfile, pos, SEEK_SET); if(retitem!=-1) { items[retitem].x=50+(rand()%80); items[retitem].y=50+(rand()%80); items[retitem].z=9; setserial(retitem,s,1); } j++; } else j++; } } while (script1[0]!='}'); closescript(); } return retitem; } void setrandomname(int s, char * namelist) { char sect[512]; int i=0,j=0; openscript("npc.scp"); sprintf(sect, "RANDOMNAME %s", namelist); if (!npc_script.find(sect)) { closescript(); sprintf(chars[s].name, "Error Namelist %s Not Found", namelist); return; } do { read1(); if (script1[0]!='}') { i++; } } while (script1[0]!='}'); closescript(); sprintf(chars[s].name,"namecount %i",i); if(i>0) { i=rand()%(i); openscript("npc.scp"); if(!npc_script.find(sect)) { closescript(); sprintf(chars[s].name, "Error Namelist %s Not Found", namelist); return; } do { read1(); if (script1[0]!='}') { if(j==i) { sprintf(chars[s].name, "%s", script1); j++; } else j++; } } while (script1[0]!='}'); closescript(); } } int addrandomnpc(int s, char * npclist, int spawnpoint) { //This function gets the random npc number from the list and recalls //addrespawnnpc passing the new number char sect[512]; unsigned int uiTempList[100]; int i=0,j=0,k=0; openscript("npc.scp"); sprintf(sect, "NPCLIST %s", npclist); if (!npc_script.find(sect)) { closescript(); return -1; } do { read1(); if (script1[0]!='}') { uiTempList[i]=str2num(script1); i++; } } while (script1[0]!='}'); closescript(); if(i>0) { i=rand()%(i); k=uiTempList[i]; } /* openscript("npc.scp"); if(!npc_script.find(sect)) { closescript(); return; } do { read1(); if (script1[0]!='}') { if(j==i) { k=str2num(script1); j++; } else j++; } } while (script1[0]!='}'); closescript(); }*/ if(k!=0) { if (spawnpoint==-1) { addmitem[s]=k; npcmenutarget(s); return -1; } else { return k; //addrespawnnpc(spawnpoint,k,1); } } return -1; } void addrandomitem(int s, char * itemlist, int spawnpoint) //Tauriel will be removed { //This function gets the random npc number from the list and recalls //addrespawnnpc passing the new number char sect[512]; int i=0,j=0,k=0; openscript("items.scp"); sprintf(sect, "ITEMLIST %s", itemlist); if (!items_script.find(sect)) { closescript(); return; } do { read1(); if (script1[0]!='}') { i++; } } while (script1[0]!='}'); closescript(); if(i>0) { i=rand()%(i); openscript("items.scp"); if(!items_script.find(sect)) { closescript(); return; } do { read1(); if (script1[0]!='}') { if(j==i) { k=str2num(script1); j++; } else j++; } } while (script1[0]!='}'); closescript(); } if(k!=0) { if (spawnpoint==-1) { addmitem[s]=k; addmenutarget(s, 0, addmitem[s]); } else { addrespawnitem(spawnpoint,k,1); } } } void showgmque(int s, int type) // Shows next unhandled call in the GM queue { // Type is 0 if it is a Counselor doing the command (or a GM doing /cq) and 1 if it is a GM int i; int x=0; if(type==1) //Player is a GM { for(i=1;i0) { sprintf(temp,"Total pages in queue: %i",x); sysmessage(s,""); sysmessage(s,temp); } else sysmessage(s,"The GM queue is currently empty"); } //end of first if else //Player is a counselor so show counselor queue { for(i=1;i0) { sprintf(temp,"Total pages in queue: %i",x); sysmessage(s,""); sysmessage(s,temp); } else sysmessage(s,"The Counselor queue is currently empty"); } } void initque() // Initilizes the gmpages[] and counspages[] arrays and also jails { int i; for(i=1;i0)break; } } if(x==0) sysmessage(s,"The GM queue is currently empty"); } //end first IF else //Player is only a counselor { x=0; for(i=1;i0)break; } } if(x==0) sysmessage(s,"The Counselor queue is currently empty"); } } void donewithcall(int s, int type) { if(chars[currchar[s]].callnum!=0) //Player is on a call { if(type==1) //Player is a GM { gmpages[chars[currchar[s]].callnum].handled=1; *(gmpages[chars[currchar[s]].callnum].name)='\0'; // was sprintf(gmpages[chars[currchar[s]].callnum].name,""); *(gmpages[chars[currchar[s]].callnum].reason)='\0'; // was sprintf(gmpages[chars[currchar[s]].callnum].reason,""); gmpages[chars[currchar[s]].callnum].ser1=0; gmpages[chars[currchar[s]].callnum].ser2=0; gmpages[chars[currchar[s]].callnum].ser3=0; gmpages[chars[currchar[s]].callnum].ser4=0; chars[currchar[s]].callnum=0; sysmessage(s,"Call removed from the GM queue."); } else //Player is a counselor { counspages[chars[currchar[s]].callnum].handled=1; *(counspages[chars[currchar[s]].callnum].name)='\0'; // was sprintf(counspages[chars[currchar[s]].callnum].name,""); *(counspages[chars[currchar[s]].callnum].reason)='\0'; // was sprintf(counspages[chars[currchar[s]].callnum].reason,""); counspages[chars[currchar[s]].callnum].ser1=0; counspages[chars[currchar[s]].callnum].ser2=0; counspages[chars[currchar[s]].callnum].ser3=0; counspages[chars[currchar[s]].callnum].ser4=0; chars[currchar[s]].callnum=0; sysmessage(s,"Call removed from the Counselor queue."); } } else { sysmessage(s,"You are currently not on a call"); } } void gotocurcall(int s) //Teleport you to the player who called you if they leave { int i; int x=0; if(chars[currchar[s]].callnum==0) { sysmessage(s,"You are not currently on a call."); } else { { for(i=0;itm_hour, local->tm_min, local->tm_sec); x2++; break; } } if (x2==0) { sysmessage(s,"The GM Queue is currently full. Contact the shard operator"); sysmessage(s,"and ask them to increase the size of the queue."); } else { sysmessage(s,"Call successfully transferred to the GM queue."); donewithcall(s,1); } } else { sysmessage(s,"Only Counselors may use this command."); } } else { sysmessage(s,"You are not currently on a call"); } } void jailtarget(int s,int c) { int i,tmpnum=0,serial; int x=0; if (c==-1) { serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); i=findbyserial(&charsp[serial%256], serial, 1); if (i!=-1) tmpnum=i; } else { i=findbyserial(&charsp[c%256], c, 1); tmpnum=i; } if(chars[tmpnum].cell>0) { sysmessage(s,"That player is already in jail!"); return; } for (i=1;i<11;i++) { if(jails[i].occupied==0) { chars[tmpnum].oldx=chars[tmpnum].x; chars[tmpnum].oldy=chars[tmpnum].y; chars[tmpnum].oldz=chars[tmpnum].z; chars[tmpnum].x=jails[i].x; chars[tmpnum].y=jails[i].y; chars[tmpnum].dispz=chars[tmpnum].z=jails[i].z; chars[tmpnum].cell=i; teleport(tmpnum); jails[i].occupied=1; sprintf(temp,"Player %s has been jailed in jail %i.",chars[tmpnum].name,i); sysmessage(s,temp); x++; break; } } if(x==0) sysmessage(s,"All jails are currently full!"); } void releasetarget(int s,int c) { int i,serial; if(c==-1) { serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); i=findbyserial(&charsp[serial%256], serial, 1); } else { i=findbyserial(&charsp[c%256], c, 1); // i=c; } if (i!=-1) { if(chars[i].cell==0) { sysmessage(s,"That player is not in jail!"); } else { jails[chars[i].cell].occupied=0; chars[i].x=chars[i].oldx; chars[i].y=chars[i].oldy; chars[i].dispz=chars[i].z=chars[i].oldz; chars[i].cell=0; teleport(i); sprintf(temp,"Player %s released.",chars[i].name); sysmessage(s,temp); } } } void gmopentarget(int s) { int i,serial,serhash,ci; serial=calcserial(buffer[s][7],buffer[s][8],buffer[s][9],buffer[s][10]); serhash=serial%256; for (ci=0;ci" then doesn't pay the npc for(i=0;i" then doesn't pay the npc sprintf(temp,"%s", "I can teech thee the following skills: "); for(j=0;j10) { sprintf(temp2,"%s, ", strlwr(skillname[j])); strupr(skillname[j]); // I found out strlwr changes the actual string permanently, so this undoes that if(!y) temp2[0]=toupper(temp2[0]); // If it's the first skill, capitalize it. strcat(temp,temp2); y++; } } if(y) { temp[strlen(temp)-2]='.'; // Make last character a . not a , just to look nicer npctalk(s, k, temp); } else { npctalk(s, k, "I am sorry, but I have nothing to teach thee"); } return 1; } } } } // End it .trainer if statement } // The if for if they are asking to train in a specific skill else // They do want to learn a specific skill { for (k=0;k10) { sprintf(temp,"Thou wishest to learn of %s?",strlwr(skillname[x])); strupr(skillname[x]); // I found out strlwr changes the actual string permanently, so this undoes that if(chars[nChar].baseskill[x]>=250) { strcat(temp, " I can teach thee no more than thou already knowest!"); } else { if(chars[k].baseskill[x]<=250) { sprintf(temp2, " Very well I, can train thee up to the level of %i percent for %i gold. Pay for less and I shall teach thee less.",(int)(chars[k].baseskill[x]/2/10),(int)(chars[k].baseskill[x]/2)-chars[nChar].baseskill[x]); } else { sprintf(temp2, " Very well I, can train thee up to the level of %i percent for %i gold. Pay for less and I shall teach thee less.",25,250-chars[nChar].baseskill[x]); } strcat(temp, temp2); chars[nChar].trainer=chars[k].serial; chars[k].trainingplayerin=x; } npctalk(s, k, temp); return 1; } // They cannot teach x skill else {npctalk(s, k, "I am sorry but I cannot train thee in that skill."); return 1; } } } } } // end the else } sprintf(search1," FOLLOW"); sprintf(search2," ME"); response1=(strstr( comm, search1)); response2=(strstr( comm, search2)); if (response1) //if follow { for (k=0;k1)) ok=1; if (ok) { sprintf(itemname, "%s%c", itemname, tile.name[j]); if (mode) used=1; } } return strlen(itemname)+1; } void goldsfx(int s, int goldtotal) { if (goldtotal==1) soundeffect(s, 0x00, 0x35); if ((goldtotal>1)&&(goldtotal<6)) soundeffect(s, 0x00, 0x36); else soundeffect(s, 0x00, 0x37); return; } void buyaction(int s) { char clearmsg[8]; int clear, i, j; int bitems[512]; int amount[512]; int layer[512]; int playergoldtotal; int goldtotal; int itemtotal; int npc; int soldout; int p; p=packitem(currchar[s]); npc=calcCharFromSer(buffer[s][3], buffer[s][4], buffer[s][5], buffer[s][6]); clear=0; goldtotal=0; soldout=0; itemtotal=(((256*(buffer[s][1]))+buffer[s][2])-8)/7; for(i=0;i=goldtotal)||(chars[currchar[s]].priv&1)) { for (i=0;iamount[i]) { if (items[bitems[i]].pileable) { dupeitem(s, bitems[i], amount[i]); } else { for (j=0;j0 // Added Oct 25, 1998 if (items[i].restock && items[i].cont1>=0x40) { serial=items[i].contserial; ci=findbyserial(&itemsp[serial%256], serial, 0); if ((ci!=-1) && (items[ci].layer==0x1A)) { if (s) { items[i].amount=items[i].amount+items[i].restock; items[i].restock=0; } else { if (items[i].restock>0) { a=min(items[i].restock, (items[i].restock/2)+1); items[i].amount=items[i].amount+a; items[i].restock=items[i].restock-a; } } } } }// printf(UOX3: restock() - time to execute =%d\n", (getclock()-tt)); } void who(int s) { int i, j=0; sysmessage(s,"Current Users in the World:"); for (i=0;i=1 && chars[p].id2>90 && chars[p].onhorse==0) npcaction(p, 0x22); //empty bottle after drinking - Tauriel if (items[i].amount!=1) { items[i].amount--; } //empty bottle after drinking - Tauriel if (items[i].contserial!=-1) removefromptr(&contsp[items[i].contserial%256], i); if (items[i].morey!=3) { int k1=items[i].ser1; int k2=items[i].ser2; int k3=items[i].ser3; int k4=items[i].ser4; int kser=items[i].serial; inititem(i); items[i].ser1=k1; items[i].ser2=k2; items[i].ser3=k3; items[i].ser4=k4; items[i].serial=kser; items[i].id1=0x0F; items[i].id2=0x0E; items[i].pileable=1; items[i].x=chars[p].x; items[i].y=chars[p].y; items[i].z=chars[p].z; items[i].priv|=0x01; } else { deleitem(i); } for (j=0;j500) mod=mod+1; if (items[i].morex>900) mod=mod+1; if (items[i].morex>1000) mod=mod+1; if (items[i].morez>1) mod=mod+(3*(items[i].morez-1)); value=(value*mod)/10; } return value; } int tradestart(int s, int i) { int ps, pi, bps, bpi, s2,c; char msg[90]; bps=packitem(currchar[s]); bpi=packitem(i); s2=calcSocketFromChar(i); c=SpawnItem(s2,1,"#",0,0x1E,0x5E,0,0,0,0); items[c].x=26; items[c].y=0; items[c].z=0; setserial(c,currchar[s],4); items[c].layer=0; items[c].type=1; items[c].dye=0; ps=c; sendbpitem(s, ps); if (s2!=-1) sendbpitem(s2, ps); c=SpawnItem(s2,1,"#",0,0x1E,0x5E,0,0,0,0); items[c].x=26; items[c].y=0; items[c].z=0; setserial(c,i,4); items[c].layer=0; items[c].type=1; items[c].dye=0; pi=c; sendbpitem(s, pi); if (s2!=-1) sendbpitem(s2, pi); items[pi].moreb1=items[ps].ser1; items[pi].moreb2=items[ps].ser2; items[pi].moreb3=items[ps].ser3; items[pi].moreb4=items[ps].ser4; items[ps].moreb1=items[pi].ser1; items[ps].moreb2=items[pi].ser2; items[ps].moreb3=items[pi].ser3; items[ps].moreb4=items[pi].ser4; items[pi].morez=0; items[ps].morez=0; msg[0]=0x6F; // Header Byte msg[1]=0; // Size msg[2]=47; // Size msg[3]=0; // Initiate msg[4]=chars[i].ser1; msg[5]=chars[i].ser2; msg[6]=chars[i].ser3; msg[7]=chars[i].ser4; msg[8]=items[ps].ser1; msg[9]=items[ps].ser2; msg[10]=items[ps].ser3; msg[11]=items[ps].ser4; msg[12]=items[pi].ser1; msg[13]=items[pi].ser2; msg[14]=items[pi].ser3; msg[15]=items[pi].ser4; msg[16]=1; sprintf(&(msg[17]), "%s", chars[i].name); xsend(s, msg, 47, 0); msg[0]=0x6F; // Header Byte msg[1]=0; // Size msg[2]=47; // Size msg[3]=0; // Initiate msg[4]=chars[currchar[s]].ser1; msg[5]=chars[currchar[s]].ser2; msg[6]=chars[currchar[s]].ser3; msg[7]=chars[currchar[s]].ser4; msg[8]=items[pi].ser1; msg[9]=items[pi].ser2; msg[10]=items[pi].ser3; msg[11]=items[pi].ser4; msg[12]=items[ps].ser1; msg[13]=items[ps].ser2; msg[14]=items[ps].ser3; msg[15]=items[ps].ser4; msg[16]=1; sprintf(&(msg[17]), "%s", chars[currchar[s]].name); xsend(s2, msg, 47, 0); return ps; } void clearalltrades() { int i, j, k, p,serial,serhash,ci; for (i=0;i=x && location[i].y2>=y) { return location[i].region; } } return -1; } void checkregion(int i) { int calcreg, s, j; calcreg=calcRegionFromXY(chars[i].x, chars[i].y); if (calcreg!=chars[i].region) { s=calcSocketFromChar(i); if (s!=-1) { if (region[chars[i].region].name[0]!=0) { sprintf(temp, "You have left %s.", region[chars[i].region].name); sysmessage(s, temp); } if (region[calcreg].name[0]!=0) { sprintf(temp, "You have entered %s.", region[calcreg].name); sysmessage(s, temp); } j=strcmp(region[calcreg].guardowner, region[chars[i].region].guardowner); if ( (region[calcreg].priv&0x01)!=(region[chars[i].region].priv&0x01) || (region[calcreg].priv&0x01 && j)) { if (region[calcreg].priv&0x01) { if (region[calcreg].guardowner[0]==0) { sysmessage(s, "You are now under the protection of the guards."); } else { sprintf(temp, "You are now under the protection of %s guards.", region[calcreg].guardowner); sysmessage(s, temp); } } else { if (region[chars[i].region].guardowner[0]==0) { sysmessage(s, "You are no longer under the protection of the guards."); } else { sprintf(temp, "You are no longer under the protection of %s guards.", region[chars[i].region].guardowner); sysmessage(s, temp); } } } } chars[i].region=calcreg; if (s!=-1) dosocketmidi(s); } } void dosocketmidi(int s) { int i=0; char midiarray[50]; char sect[512]; openscript("regions.scp"); if (chars[currchar[s]].war) { sprintf(sect, "MIDILIST COMBAT"); } else { sprintf(sect, "MIDILIST %i", region[chars[currchar[s]].region].midilist); } if (region[chars[currchar[s]].region].midilist!=0 && !regions_script.find(sect)) { closescript(); return; } do { read2(); if (script1[0]!='}') { if (!(strcmp("MIDI",script1))) { midiarray[i]=str2num(script2); i++; } } } while (script1[0]!='}'); closescript(); if (i!=0) { i=rand()%(i); playmidi(s, 0, midiarray[i]); } } void wipenpcs (int s) // remove ALL npcs { int j,i,deleted=0; printf("UOX3: %s has initiated an NPC wipe\n",chars[currchar[s]].name); for(j=0;jj) currchar[i]--; } chars[j].free=1; chars[j].x=20+(rand()%40); chars[j].y=50+(rand()%80); chars[j].z=9; chars[j].summontimer=0; if (cmemcheck<300) { cmemcheck++; freecharmem[cmemcheck]=j; } else cmemover=1; deleted++; } } gcollect(); charcount=charcount-deleted; sysbroadcast("All NPC's have been wiped."); } void respawnnow() { int i, j, k,serial,serhash,ci; for(i=0;i30) tracking_data.maxtargets=MAXTRACKINGTARGETS; } if(!(strcmp(script1,"BASE_TRACKING_TIME"))) tracking_data.basetimer=str2num(script2); if(!(strcmp(script1,"TRACKING_MESSAGE_REDISPLAY_TIME"))) tracking_data.redisplaytime=str2num(script2); } while (strcmp(script1, "}")); } void loadbegging() { do { readw2(); if(!(strcmp(script1,"BEGGING_RANGE"))) begging_data.range=str2num(script2); if(!(strcmp(script1,"BEGGING_TEXT0"))) strcpy(begging_data.text[0],script2); if(!(strcmp(script1,"BEGGING_TEXT1"))) strcpy(begging_data.text[1],script2); if(!(strcmp(script1,"BEGGING_TEXT2"))) strcpy(begging_data.text[2],script2); } while (strcmp(script1, "}")); } void loadfishing() { do { readw2(); if(!(strcmp(script1,"BASE_FISHING_TIME"))) fishing_data.basetime=str2num(script2); if(!(strcmp(script1,"RANDOM_FISHING_TIME"))) fishing_data.randomtime=str2num(script2); } while (strcmp(script1, "}")); } void loadspiritspeak() { do { readw2(); if(!(strcmp(script1,"SPIRITSPEAKTIMER"))) spiritspeak_data.spiritspeaktimer=str2num(script2); } while (strcmp(script1, "}")); } void loadtime_light() { do { readw2(); if(!(strcmp(script1,"DAY"))) day=str2num(script2); if(!(strcmp(script1,"HOUR"))) hour=str2num(script2); if(!(strcmp(script1,"MINUTE"))) minute=str2num(script2); if(!(strcmp(script1,"AMPM"))) ampm=str2num(script2); if(!(strcmp(script1,"MOON1UPDATE"))) moon1update=str2num(script2); if(!(strcmp(script1,"MOON2UPDATE"))) moon2update=str2num(script2); if(!(strcmp(script1,"MOON1"))) moon1=str2num(script2); if(!(strcmp(script1,"MOON2"))) moon2=str2num(script2); if(!(strcmp(script1,"DUNGEONLIGHTLEVEL"))) dungeonlightlevel=str2num(script2); if(!(strcmp(script1,"WORLDFIXEDLEVEL"))) worldfixedlevel=str2num(script2); if(!(strcmp(script1,"WORLDCURLEVEL"))) worldcurlevel=str2num(script2); if(!(strcmp(script1,"WORLDBRIGHTLEVEL"))) worldbrightlevel=str2num(script2); if(!(strcmp(script1,"WORLDDARKLEVEL"))) worlddarklevel=str2num(script2); } while (strcmp(script1, "}")); } void loadserverdefaults(void) { // load defaults values server_data.decaytimer=DECAYTIMER; server_data.invisibiliytimer=INVISTIMER; server_data.hungerrate=HUNGERRATE; server_data.skilldelay=SKILLDELAY; server_data.objectdelay=OBJECTDELAY; server_data.hitpointrate=REGENRATE1; server_data.staminarate=REGENRATE2; server_data.manarate=REGENRATE3; server_data.gatetimer=GATETIMER; server_data.minecheck=MINECHECK; server_data.showdeathanim=SHOWDEATHANIM; server_data.combathitmessage=COMBATHITMESSAGE; server_data.monsters_vs_animals=MONSTERS_VS_ANIMALS; server_data.animals_attack_chance=ANIMALS_ATTACK_CHANCE; server_data.animals_guarded=ANIMALS_GUARDED; server_data.npc_base_fleeat=NPC_BASE_FLEEAT; server_data.npc_base_reattackat=NPC_BASE_REATTACKAT; server_data.guardsactive=1; server_data.bg_sounds=2; // EviLDeD - Set default of worldsave saves to 0(false) // December 27, 1998 server_data.announceworldsaves=1; // EviLDeD - End server_data.joinmsg=1; server_data.partmsg=1; server_data.log=1; server_data.rogue=1; *(server_data.archivepath)='\0'; // was strcpy(server_data.archivepath,""); server_data.UOXBot=0; tracking_data.baserange=TRACKINGRANGE; tracking_data.maxtargets=MAXTRACKINGTARGETS; tracking_data.basetimer=TRACKINGTIMER; tracking_data.redisplaytime=TRACKINGDISPLAYTIME; begging_data.range=BEGGINGRANGE; strcpy(begging_data.text[0],"Could thou spare a few coins?"); strcpy(begging_data.text[1],"Hey buddy can you spare some gold?"); strcpy(begging_data.text[2],"I have a family to feed, think of the children."); fishing_data.basetime=FISHINGTIMEBASE; fishing_data.randomtime=FISHINGTIMER; spiritspeak_data.spiritspeaktimer=SPIRITSPEAKTIMER; } int numbitsset( int number ) { int bitsset = 0; while( number ) { if( number & 0x1 ) bitsset++; number >>= 1; } return bitsset; } int whichbit( int number, int bit ) { int i, setbits = 0, whichbit = 0, intsize = sizeof(int) * 8; for( i=0;i>= 1; } return whichbit; } /*#ifndef __NT__ void strupr(char *s) { for (; *s; s++) *s = toupper(*s); } #endif */ int RandomNum(int nLowNum, int nHighNum) { if (nHighNum - nLowNum + 1) return ((rand() % (nHighNum - nLowNum + 1)) + nLowNum); else return nLowNum; } // Added by Krozy on 7-Sep-98 // New getstatskillvalue function. // Takes a string, gets the tokens. // If its one value - It returns that value. // If its two values - It gets a random number between the values int getstatskillvalue(char *stringguy) { char values[512]; int lovalue,hivalue,retcode; strcpy(values, stringguy); gettokennum(values, 0); lovalue=str2num(gettokenstr); gettokennum(values, 1); hivalue=str2num(gettokenstr); if (hivalue) { retcode = RandomNum(lovalue, hivalue); } else { retcode = lovalue; } return retcode; } int addnpcxyz(int s, int x, int type, int x1, int y1, int z1) { int tmp, z,c,n, lost, hist, lodx, hidx, loin, hiin, loresist, hiresist, lomagery, himagery, lotactics, hitactics, loparrying, hiparrying, lowrestling, hiwrestling; char sect[512]; long int pos; int mypack, retitem, storeval, goldmin, goldmax, shoppack1, shoppack2, shoppack3; char rndlootlist[20]; mypack=-1; retitem=-1; storeval=-1; shoppack1=-1; shoppack2=-1; shoppack3=-1; lost=-1; hist=-1; lodx=-1; hidx=-1; loin=-1; hiin=-1; lowrestling=-1; hiwrestling=-1; lotactics=-1; hitactics=-1; lomagery=-1; himagery=-1; loparrying=-1; hiparrying=-1; loresist=-1; hiresist=-1; c=memcharfree (); initchar(c); if (type==1) { chars[c].x=items[s].x; chars[c].y=items[s].y; chars[c].dispz=chars[c].z=items[s].z; setserial(c,s,6); } else { chars[c].x=x1; chars[c].y=y1; chars[c].dispz=chars[c].z=z1; } chars[c].priv=0x10; chars[c].npc=1; chars[c].att=1; chars[c].def=1; openscript("npc.scp"); sprintf(sect, "NPC %i", x); if (!npc_script.find(sect)) { closescript(); return -1; } do { read2(); if (script1[0]!='}') { if (!(strcmp("NAME",script1))) { sprintf(chars[c].name, "%s", script2); } if (!(strcmp("NAMELIST", script1))) { pos=ftell(scpfile); closescript(); setrandomname(c,script2); openscript("npc.scp"); fseek(scpfile, pos, SEEK_SET); sprintf(script1, "DUMMY"); // To prevent accidental exit of loop. } if (!(strcmp("NPCLIST", script1))) { pos=ftell(scpfile); closescript(); donpcupdate++; if (type==1) addrandomnpc(c,script2,s); else addrandomnpc(c,script2,-1); donpcupdate--; openscript("npc.scp"); fseek(scpfile, pos, SEEK_SET); sprintf(script1, "DUMMY"); } if (!(strcmp("TITLE",script1))) { sprintf(chars[c].title, "%s", script2); } if (!(strcmp("KARMA",script1))) { chars[c].karma=str2num(script2); } if (!(strcmp("FAME",script1))) { chars[c].fame=str2num(script2); } if (!(strcmp(script1, "NOTRAIN"))) chars[x].cantrain=0; if (!(strcmp("ID",script1))) { tmp=hstr2num(script2); chars[c].id1=tmp/256; chars[c].id2=tmp%256; chars[c].xid1=tmp/256; chars[c].xid2=tmp%256; } if (!(strcmp("SKIN",script1))) { tmp=hstr2num(script2); chars[c].skin1=tmp/256; chars[c].skin2=tmp%256; chars[c].xskin1=tmp/256; chars[c].xskin2=tmp%256; } if (!(strcmp("DIRECTION",script1))) { if (!(strcmp("NE",script2))) { chars[c].dir=1; } if (!(strcmp("E",script2))) { chars[c].dir=2; } if (!(strcmp("SE",script2))) { chars[c].dir=3; } if (!(strcmp("S",script2))) { chars[c].dir=4; } if (!(strcmp("SW",script2))) { chars[c].dir=5; } if (!(strcmp("W",script2))) { chars[c].dir=6; } if (!(strcmp("NW",script2))) { chars[c].dir=7; } if (!(strcmp("N",script2))) { chars[c].dir=0; } } if (!(strcmp("BACKPACK", script1))) { if (mypack==-1) { int serial,ci; serial=chars[c].serial; for (ci=0;ci0)&&(hiwrestling>0)) { if (lowrestling!=hiwrestling) chars[c].baseskill[WRESTLING]=(rand()%(hiwrestling-lowrestling)+lowrestling); else chars[c].baseskill[WRESTLING]=lowrestling; } if((lotactics>0)&&(hitactics>0)) { if (lotactics!=hitactics) chars[c].baseskill[TACTICS]=(rand()%(hitactics-lotactics)+lotactics); else chars[c].baseskill[TACTICS]=lotactics; } if((lomagery>0)&&(himagery>0)) { if (lomagery!=himagery) chars[c].baseskill[MAGERY]=(rand()%(himagery-lomagery)+lomagery); else chars[c].baseskill[MAGERY]=lomagery; } if((loparrying>0)&&(hiparrying>0)) { if (loparrying!=hiparrying) chars[c].baseskill[PARRYING]=(rand()%(hiparrying-loparrying)+loparrying); else chars[c].baseskill[PARRYING]=loparrying; } if((loresist>0)&&(hiresist>0)) { if (loresist!=hiresist) chars[c].baseskill[MAGICRESISTANCE]=(rand()%(hiresist-loresist)+loresist); else chars[c].baseskill[MAGICRESISTANCE]=loresist; } // Setup the npc's str,dex and other values if((lost>0)&&(hist>0)) { if (hist!=lost) chars[c].st=(rand()%(hist-lost))+(lost); else chars[c].st=lost; chars[c].st2=chars[c].st; chars[c].hp=chars[c].st; } if((hiin>0)&&(loin>0)) { if (hiin!=loin) chars[c].in=(rand()%(hiin-loin))+(loin); else chars[c].in=loin; chars[c].in2=chars[c].in; chars[c].mn=chars[c].in; } if((hidx>0)&&(lodx>0)) { chars[c].dx=(rand()%(hidx-lodx))+(lodx); if (hidx!=lodx) chars[c].dx=(rand()%(hidx-lodx))+(lodx); else chars[c].dx=lodx; chars[c].dx2=chars[c].dx; chars[c].stm=chars[c].dx; } if (chars[c].fx1==-1) { if (type==1) { chars[c].fx1=items[s].x; chars[c].fy1=items[s].y; if (chars[c].fz1!=-1) chars[c].fz1=items[s].z; } else { chars[c].fx1=(buffer[s][11]*256)+buffer[s][12]; chars[c].fy1=(buffer[s][13]*256)+buffer[s][14]; if (chars[c].fz1!=-1) chars[c].fz1=buffer[s][16]+tileheight(buffer[s][17]*256+buffer[s][18]); } } if (donpcupdate==0) { /*if (c==charcount) { charcount++; charcount2++; }*/ updatechar(c); } return c; } void StartMilliTimer(unsigned long &Seconds, unsigned long &Milliseconds) { #ifdef __NT__ struct timeb t; ftime(&t); Seconds = t.time; Milliseconds = t.millitm; #else #endif } unsigned long CheckMilliTimer(unsigned long &Seconds, unsigned long &Milliseconds) { #ifdef __NT__ struct timeb t; ftime(&t); return(1000*(t.time - Seconds) + (t.millitm - Milliseconds)); #else return(0); #endif } void advancementobjects(int s, int x, int allways) { char sect[512]; int hairobject=-1, beardobject=-1; int j,pos,packnum,i; if ((chars[s].advobj==0)||(allways==1)) { staticeffect(s, 0x37, 0x3A, 0, 15); soundeffect2(s, 0x01, 0xE9); chars[s].advobj=x; openscript("advance.scp"); sprintf(sect, "ADVANCEMENT %i", x); if (!advance_script.find(sect)) { closescript(); printf("ADVANCEMENT OBJECT: Script section not found. Aborting.\n"); chars[s].advobj=0; return; } else do { read2(); if (script1[0]!='}') { if ((!(strcmp("STR",script1)))||(!(strcmp("STRENGTH",script1)))) { chars[s].st = getstatskillvalue(script2); chars[s].st2 = chars[s].st; } if ((!(strcmp("DEX",script1)))||(!(strcmp("DEXTERITY",script1)))) { chars[s].dx = getstatskillvalue(script2); chars[s].dx2 = chars[s].dx; } if ((!(strcmp("INT",script1)))||(!(strcmp("INTELLIGENCE",script1)))) { chars[s].in = getstatskillvalue(script2); chars[s].in2 = chars[s].in; } if ((!(strcmp("ALCHEMY",script1)))||(!(strcmp("SKILL0",script1)))) chars[s].baseskill[ALCHEMY] = getstatskillvalue(script2); if ((!(strcmp("ANATOMY",script1)))||(!(strcmp("SKILL1",script1)))) chars[s].baseskill[ANATOMY] = getstatskillvalue(script2); if ((!(strcmp("ANIMALLORE",script1)))||(!(strcmp("SKILL2",script1)))) chars[s].baseskill[ANIMALLORE] = getstatskillvalue(script2); if ((!(strcmp("ITEMID",script1)))||(!(strcmp("SKILL3",script1)))) chars[s].baseskill[ITEMID] = getstatskillvalue(script2); if ((!(strcmp("ARMSLORE",script1)))||(!(strcmp("SKILL4",script1)))) chars[s].baseskill[ARMSLORE] = getstatskillvalue(script2); if ((!(strcmp("PARRYING",script1)))||(!(strcmp("SKILL5",script1)))) chars[s].baseskill[PARRYING] = getstatskillvalue(script2); if ((!(strcmp("BEGGING",script1)))||(!(strcmp("SKILL6",script1)))) chars[s].baseskill[BEGGING] = getstatskillvalue(script2); if ((!(strcmp("BLACKSMITHING",script1)))||(!(strcmp("SKILL7",script1)))) chars[s].baseskill[BLACKSMITHING] = getstatskillvalue(script2); if ((!(strcmp("BOWCRAFT",script1)))||(!(strcmp("SKILL8",script1)))) chars[s].baseskill[BOWCRAFT] = getstatskillvalue(script2); if ((!(strcmp("PEACEMAKING",script1)))||(!(strcmp("SKILL9",script1)))) chars[s].baseskill[PEACEMAKING] = getstatskillvalue(script2); if ((!(strcmp("CAMPING",script1)))||(!(strcmp("SKILL10",script1)))) chars[s].baseskill[CAMPING] = getstatskillvalue(script2); if ((!(strcmp("CARPENTRY",script1)))||(!(strcmp("SKILL11",script1)))) chars[s].baseskill[CARPENTRY] = getstatskillvalue(script2); if ((!(strcmp("CARTOGRAPHY",script1)))||(!(strcmp("SKILL12",script1)))) chars[s].baseskill[CARTOGRAPHY] = getstatskillvalue(script2); if ((!(strcmp("COOKING",script1)))||(!(strcmp("SKILL13",script1)))) chars[s].baseskill[COOKING] = getstatskillvalue(script2); if ((!(strcmp("DETECTINGHIDDEN",script1)))||(!(strcmp("SKILL14",script1)))) chars[s].baseskill[DETECTINGHIDDEN] = getstatskillvalue(script2); if ((!(strcmp("ENTICEMENT",script1)))||(!(strcmp("SKILL15",script1)))) chars[s].baseskill[ENTICEMENT] = getstatskillvalue(script2); if ((!(strcmp("EVALUATINGINTEL",script1)))||(!(strcmp("SKILL16",script1)))) chars[s].baseskill[EVALUATINGINTEL] = getstatskillvalue(script2); if ((!(strcmp("HEALING",script1)))||(!(strcmp("SKILL17",script1)))) chars[s].baseskill[HEALING] = getstatskillvalue(script2); if ((!(strcmp("FISHING",script1)))||(!(strcmp("SKILL18",script1)))) chars[s].baseskill[FISHING] = getstatskillvalue(script2); if ((!(strcmp("FORENSICS",script1)))||(!(strcmp("SKILL19",script1)))) chars[s].baseskill[FORENSICS] = getstatskillvalue(script2); if ((!(strcmp("HERDING",script1)))||(!(strcmp("SKILL20",script1)))) chars[s].baseskill[HERDING] = getstatskillvalue(script2); if ((!(strcmp("HIDING",script1)))||(!(strcmp("SKILL21",script1)))) chars[s].baseskill[HIDING] = getstatskillvalue(script2); if ((!(strcmp("PROVOCATION",script1)))||(!(strcmp("SKILL22",script1)))) chars[s].baseskill[PROVOCATION] = getstatskillvalue(script2); if ((!(strcmp("INSCRIPTION",script1)))||(!(strcmp("SKILL23",script1)))) chars[s].baseskill[INSCRIPTION] = getstatskillvalue(script2); if ((!(strcmp("LOCKPICKING",script1)))||(!(strcmp("SKILL24",script1)))) chars[s].baseskill[LOCKPICKING] = getstatskillvalue(script2); if ((!(strcmp("MAGERY",script1)))||(!(strcmp("SKILL25",script1)))) chars[s].baseskill[MAGERY] = getstatskillvalue(script2); if ((!(strcmp("MAGICRESISTANCE",script1)))||(!(strcmp("RESIST",script1)))||(!(strcmp("SKILL26",script1)))) chars[s].baseskill[MAGICRESISTANCE] = getstatskillvalue(script2); if ((!(strcmp("TACTICS",script1)))||(!(strcmp("SKILL27",script1)))) chars[s].baseskill[TACTICS] = getstatskillvalue(script2); if ((!(strcmp("SNOOPING",script1)))||(!(strcmp("SKILL28",script1)))) chars[s].baseskill[SNOOPING] = getstatskillvalue(script2); if ((!(strcmp("MUSICIANSHIP",script1)))||(!(strcmp("SKILL29",script1)))) chars[s].baseskill[MUSICIANSHIP] = getstatskillvalue(script2); if ((!(strcmp("POISONING",script1)))||(!(strcmp("SKILL30",script1)))) chars[s].baseskill[POISONING] = getstatskillvalue(script2); if ((!(strcmp("ARCHERY",script1)))||(!(strcmp("SKILL31",script1)))) chars[s].baseskill[ARCHERY] = getstatskillvalue(script2); if ((!(strcmp("SPIRITSPEAK",script1)))||(!(strcmp("SKILL32",script1)))) chars[s].baseskill[SPIRITSPEAK] = getstatskillvalue(script2); if ((!(strcmp("STEALING",script1)))||(!(strcmp("SKILL33",script1)))) chars[s].baseskill[STEALING] = getstatskillvalue(script2); if ((!(strcmp("TAILORING",script1)))||(!(strcmp("SKILL34",script1)))) chars[s].baseskill[TAILORING] = getstatskillvalue(script2); if ((!(strcmp("TAMING",script1)))||(!(strcmp("SKILL35",script1)))) chars[s].baseskill[TAMING] = getstatskillvalue(script2); if ((!(strcmp("TASTEID",script1)))||(!(strcmp("SKILL36",script1)))) chars[s].baseskill[TASTEID] = getstatskillvalue(script2); if ((!(strcmp("TINKERING",script1)))||(!(strcmp("SKILL37",script1)))) chars[s].baseskill[TINKERING] = getstatskillvalue(script2); if ((!(strcmp("TRACKING",script1)))||(!(strcmp("SKILL38",script1)))) chars[s].baseskill[TRACKING] = getstatskillvalue(script2); if ((!(strcmp("VETERINARY",script1)))||(!(strcmp("SKILL39",script1)))) chars[s].baseskill[VETERINARY] = getstatskillvalue(script2); if ((!(strcmp("SWORDSMANSHIP",script1)))||(!(strcmp("SKILL40",script1)))) chars[s].baseskill[SWORDSMANSHIP] = getstatskillvalue(script2); if ((!(strcmp("MACEFIGHTING",script1)))||(!(strcmp("SKILL41",script1)))) chars[s].baseskill[MACEFIGHTING] = getstatskillvalue(script2); if ((!(strcmp("FENCING",script1)))||(!(strcmp("SKILL42",script1)))) chars[s].baseskill[FENCING] = getstatskillvalue(script2); if ((!(strcmp("WRESTLING",script1)))||(!(strcmp("SKILL43",script1)))) chars[s].baseskill[WRESTLING] = getstatskillvalue(script2); if ((!(strcmp("LUMBERJACKING",script1)))||(!(strcmp("SKILL44",script1)))) chars[s].baseskill[LUMBERJACKING] = getstatskillvalue(script2); if ((!(strcmp("MINING",script1)))||(!(strcmp("SKILL45",script1)))) chars[s].baseskill[MINING] = getstatskillvalue(script2); if ((!(strcmp("DYEHAIR",script1)))) { int serial,serhash,ci; serial=chars[s].serial; serhash=serial%256; for (ci=0;ci-1) { x=hstr2num(script2); items[hairobject].color1=x/256; items[hairobject].color2=x%256; for (j=0;j-1) { x=hstr2num(script2); items[beardobject].color1=x/256; items[beardobject].color2=x%256; for (j=0;j=0x0F0F)&&(item<=0x0F20)) // Any gem stone (typically smaller) { soundeffect(s, 0x00, 0x32); break; } if ((item>=0x0F21)&&(item<=0x0F30)) // Any gem stone (typically larger) { soundeffect(s, 0x00, 0x34); break; } if ((item>=0x1BE3)&&(item<=0x1BFA)) // Any Ingot { soundeffect(s, 0x00, 0x33); break; } soundeffect(s, 0x00, 0x42); break; // play default item move sfx // 00 48 } } // Dupois - end void bgsound (int s) // Plays background sounds of the game { int x, ds, dx, sound; int distance=(VISRANGE+5); int inrange[15]; int y=0; int basesound=0; for (x=1;x<=charcount;x++) { if((chars[x].npc)&&(!(chars[x].dead))&&(!(chars[x].war))&&(y<=10)) { ds=abs(chars[s].x-chars[x].x); dx=abs(chars[s].y-chars[x].y); if((ds<=distance)&&(dx<=distance)) { y++; inrange[y]=x; } } } if (y!=0) { sound=((rand()%(y))+1); switch(chars[inrange[sound]].id1) { case 0x00: { switch(chars[inrange[sound]].id2) { case 0x01: basesound=0x01AB; break; // Ogre case 0x02: // Ettin case 0x12: basesound=0x016F; break; // Ettin with stone ax case 0x03: basesound=0x01D7; break; // Zombie case 0x04: basesound=0x0174; break; // Gargoyle case 0x05: basesound=0x008f; break; // Eagle case 0x06: basesound=0x007d; break; // Bird case 0x07: // Full armed Orc case 0x11: // Orc case 0x29: basesound=0x01b0; break; // Orc with club case 0x08: basesound=0x01ba; break; // Reaper case 0x09: // Daemon case 0x0a: basesound=0x0165; break; // Daemon with sword case 0x0c: // Green Dragon case 0x3b: // Red Dragon case 0x3c: // Smaller Green Dragon case 0x3d: basesound=0x016A; break; // Smaller Red Dragon case 0x0D: basesound=0x0107; break; // Wind Elemental case 0x0E: basesound=0x010C; break; // Earth Elemental case 0x0F: basesound=0x0111; break; // Fire Elemental case 0x10: basesound=0x0116; break; // Water Elemental case 0x15: // Giant Snake case 0x34: basesound=0x00db; break; // Snake case 0x16: basesound=0x0179; break; // Gazer case 0x18: basesound=0x019C; break; // Liche case 0x1a: basesound=0x017E; break; // Floating Skeleton case 0x1C: basesound=0x0183; break; // Giant Spider case 0x1D: basesound=0x009E; break; // Gorilla case 0x1E: basesound=0x0192; break; // Harpy case 0x1F: basesound=0x0197; break; // Headless case 0x21: // Lizardman case 0x23: case 0x24: basesound=0x01A1; break; case 0x27: basesound=0x01A6; break; // Mongbatt case 0x2A: // Ratman case 0x2C: case 0x2D: basesound=0x01B5; break; case 0x2F: basesound=0x01BA; break; // Reaper case 0x30: basesound=0x018D; break; // Giant Scorpion case 0x32: // Skeleton case 0x38: // Skeleton with ax case 0x39: basesound=0x01C3; break; // Skeleton with sword and shield case 0x33: basesound=0x01C8; break; // Slime case 0x35: // Troll 1 case 0x36: // Troll 2 case 0x37: basesound=0x01CD; break; // Troll 3 case 0x3A: basesound=0x01D2; break; // Wisp case 0x97: basesound=0x008A; break; // Dolphin case 0xc9: basesound=0x0069; break; // Cat case 0xca: basesound=0x005A; break; // Alligator case 0xcb: basesound=0x00C4; break; // Pig case 0xcf: // Sheep case 0xdf: basesound=0x00D7; break; // Sheep case 0xd0: basesound=0x006E; break; // Chicken case 0xd1: basesound=0x0099; break; // Goat case 0xd3: // Brown Bear case 0xd5: basesound=0x005f; break; // Polar Bear case 0xd4: basesound=0x00a3; break; // Grizzly Bear case 0xd6: basesound=0x00ba; break; // Panther case 0xd7: // Rat case 0xee: basesound=0x0188; break; // Rat case 0xd8: // Cow case 0xe7: // Cow case 0xe9: basesound=0x0078; break; // Cow case 0xd9: basesound=0x0085; break; // Dog case 0xdd: basesound=0x00e0; break; // Walrus case 0xe1: basesound=0x00e5; break; // Jackal case 0xe8: basesound=0x0064; break; // Bull case 0xe2: // Horse case 0xe4: // Horse case 0xc8: // White Horse case 0xcc: basesound=0x00a8; break; // Brown Horse case 0x96: basesound=0x01bf; break; // Sea Serpent } } case 0x01: { switch(chars[inrange[sound]].id2) { case 0x22: basesound=0x00c4; break; // Pig case 0x23: basesound=0x01a1; break; // Pack Horse with Saddle Bags } } } if (basesound !=0) { sfx[2]=basesound/256; sfx[3]=basesound%256; sfx[6]=chars[inrange[sound]].x/256; sfx[7]=chars[inrange[sound]].x%256; sfx[8]=chars[inrange[sound]].y/256; sfx[9]=chars[inrange[sound]].y%256; xsend(s, sfx, 12, 0); } } } void monstergate(int s, int x) { int tmp, n, z, lovalue, hivalue, mypack, retitem, j; int storeval, shoppack1, shoppack2, shoppack3; //unsigned short int tempskill; char sect[512]; long int pos; char rndlootlist[20]; if (chars[s].npc) return; mypack=-1; retitem=-1; storeval=-1; shoppack1=-1; shoppack2=-1; shoppack3=-1; openscript("npc.scp"); sprintf(sect, "NPC %i", x); if (!npc_script.find(sect)) { closescript(); return; } *(chars[s].title)='\0'; // was sprintf(chars[s].title, ""); for(z=0;z10000)||(nCurKarma<-10000)) if(nCurKarma>10000) chars[nCharID].karma=10000; else chars[nCharID].karma=-10000; if(nCurKarma0) { nChange=((nKarma-nCurKarma)/75); chars[nCharID].karma=(nCurKarma+nChange); nEffect=1; } if((nCurKarma>nKarma)&&(chars[nKilledID].karma>0)|| (nCurKarma>nKarma)&&(nKilledID==-1)) { nChange=((nCurKarma-nKarma)/50); chars[nCharID].karma=(nCurKarma-nChange); nEffect=0; } if((nChange==0)||(chars[nCharID].npc==1)) return; if(nChange<=25) if(nEffect) { sysmessage(calcSocketFromChar(nCharID), "You have gained a little karma."); return; } else { sysmessage(calcSocketFromChar(nCharID), "You have lost a little karma."); return; } if(nChange<=50) if(nEffect) { sysmessage(calcSocketFromChar(nCharID), "You have gained some karma."); return; } else { sysmessage(calcSocketFromChar(nCharID), "You have lost some karma."); return; } if((nChange<=100)||(nChange>100)) if(nEffect) { sysmessage(calcSocketFromChar(nCharID), "You have gained alot of karma."); return; } else { sysmessage(calcSocketFromChar(nCharID), "You have lost alot of karma."); return; } } //added by Genesis 11-8-98 void Fame(int nCharID, int nFame) { int nCurFame, nChange=0, nEffect=0; nCurFame = chars[nCharID].fame; if(nCurFame>nFame) // if player fame greater abort function { if(nCurFame>10000) chars[nCharID].fame=10000; return; } if(nCurFame100)) if(nEffect) { sysmessage(calcSocketFromChar(nCharID), "You have gained alot of fame."); return; } else { sysmessage(calcSocketFromChar(nCharID), "You have lost alot of fame."); return; } } void enlist(int s, int listnum) // listnum is stored in items morex { int x,pos,i,j; char sect[50]; openscript("items.scp"); sprintf(sect, "ITEMLIST %i", listnum); if (!items_script.find(sect)) { closescript(); printf("UOX3: ITEMLIST not found, aborting.\n"); return; } do { read2(); if (script1[0]!='}') { x=str2num(script1); pos=ftell(scpfile); j=SpawnItemBackpack2(s, x, 0); openscript("items.scp"); fseek(scpfile, pos, SEEK_SET); sprintf(script1, "DUMMY"); for (i=0;i= x1 -20)&& (items[i].y<= y1 +20)&& (items[i].y>= y1 -20) ) { loscache[loscachecount]=i; loscachecount++; } } for (i=0;i \ | y ^ \ | | \| * target */ if ((x2==65535)&&(y2==65535)) return not_blocked; // target cancled a=abs(x1-x2)+1; // length of side a b=abs(y1-y2)+1; // length of side b asquared=(a * a); bsquared=(b * b); csquared=(asquared + bsquared); c=sqrt(csquared);// length of c(hypotenuse==line of sight) a_divide = (a / a1_incrament); c1_incrament = (c / a_divide); if(a==1) { c1_incrament=1; a1_incrament=0; a_divide = b; } b1_incrament=sqrt((c1_incrament*c1_incrament)-(a1_incrament*a1_incrament)); if (b==1) { a1_incrament=1; a_divide=a; b1_incrament=0; } ////////////////////////////////////////////////////////// // X position if (x2==x1) // Target has same x value { a1_incrament=(a1_incrament * 0); // sets x incraments to zero, no incrament } if (x2>x1) // Target has greater x value { a1_incrament=(a1_incrament * 1); // sets x incrament positive } if (x2y1) // Target has greater y value { b1_incrament=(b1_incrament * 1); // sets y incraments positive } if (y2z2) // going down { b2_incrament = (b2_incrament * -1); } if (z1==z2) // level ground { b2_incrament = 0; } aplus=a1_incrament; bplus=b1_incrament; b2plus=b2_incrament; // going up or down //////////////////////////////////////////////////////// //////////////// This determines what to check for i=0; itemtype=1; checkthistotal=0; while (checkfor) { if ((checkfor>=itemtype)&&(checkfor<(itemtype * 2))&&(checkfor)) { checkthis[i]=itemtype; ++i; checkfor = (checkfor - itemtype); ++checkthistotal; itemtype=1; } else if (checkfor) { itemtype=(itemtype * 2); } } /////////////////////////////////////////////////////////////////////////// //////////////////// This next stuff is what searches each tile for things for (checkcount=1; checkcount<=a_divide; checkcount++) { if (xcheck!=x2) xcheck=(x1 + aplus); // x coord to check if (ycheck!=y2) ycheck=(y1 + bplus); // y coord to check if (zcheck!=z2) zcheck=(z1 + b2plus); // z coord to check if ((xcheck!=prexcheck)||(ycheck!=preycheck)||(zcheck!=prezcheck)) { // Texture mapping x1check=xcheck/8; // Block y1check=ycheck/8; xoff=(xcheck-(x1check*8)); // Offset yoff=(ycheck-(y1check*8)); pos=(x1check*512*196)+(y1check*196)+(yoff*24)+(xoff*3)+4; fseek(mapfile, pos, SEEK_SET); fread(&map1, 3, 1, mapfile); if (map1.id!=2) { if ( // Mountain walls ((map1.id>=431)&&(map1.id<=432))|| ((map1.id>=467)&&(map1.id<=475))|| ((map1.id>=543)&&(map1.id<=560))|| ((map1.id>=1754)&&(map1.id<=1757))|| ((map1.id>=1787)&&(map1.id<=1789))|| ((map1.id>=1821)&&(map1.id<=1824))|| ((map1.id>=1851)&&(map1.id<=1854))|| ((map1.id>=1881)&&(map1.id<=1884)) ) { sysmessage(s, "There seems to be something in the way!"); return blocked; } } // Statics // x1check=xcheck/8; // Block // y1check=ycheck/8; // xoff=(xcheck-(x1check*8)); // Offset // yoff=(ycheck-(y1check*8)); /// Uses same blocks and offsets as above pos=(x1check*512*12)+(y1check*12); fseek(sidxfile, pos, SEEK_SET); fread(&pos2, 4, 1, sidxfile); if (pos2!=-1) { fread(&length, 4, 1, sidxfile); length=length/7; fseek(statfile, pos2, SEEK_SET); for (i=0;i=stat.zoff)&& (zcheck<=(stat.zoff+tile.height))) { itemids[checkitemcount]=stat.itemid; checkitemcount++; }// if }// for }// if // Items for (i=0;i=items[dyncount].z)&& (zcheck<=(items[dyncount].z+tile.height))&& (items[dyncount].visible==0)) { itemids[checkitemcount]=((items[dyncount].id1 * 256) + items[dyncount].id2); checkitemcount++; } } else {// Multi's if ((abs(x1-x2)<=BUILDRANGE)&&(abs(y1-y2)<=BUILDRANGE)) { seekmulti((items[dyncount].id1*256+items[dyncount].id2)-0x4000, &mfile, &length); length=length/sizeof(st_multi); if (length == -1) { printf("LoS - Bad length in multi file. Avoiding stall.\n"); length = 0; } for (j=0;j=items[dyncount].z+multi.z)&& (zcheck<=(items[dyncount].z+multi.z + tile.height))) { itemids[checkitemcount]=multi.tile; checkitemcount++; } } } } }// end else } // for if ((xcheck==x2)&&(ycheck==y2)&&(zcheck==z2)) checkcount=a_divide+1; prexcheck=xcheck; preycheck=ycheck; prezcheck=zcheck; } // if statment if (xcheck!=x2) aplus=aplus+a1_incrament; if (ycheck!=y2) bplus=bplus+b1_incrament; if (zcheck!=z2) b2plus=b2plus+b2_incrament; } // for loop for (i=0;i=3215)&&(itemids[i]<=3218))|| ((itemids[i]>=3272)&&(itemids[i]<=3280))||(itemids[i]==3283)||(itemids[i]==3286)|| (itemids[i]==3288)||(itemids[i]==3290)||(itemids[i]==3293)||(itemids[i]==3296)|| (itemids[i]==3299)||(itemids[i]==3302)||(itemids[i]==3305)||(itemids[i]==3306)|| (itemids[i]==3320)||(itemids[i]==3323)||(itemids[i]==3326)||(itemids[i]==3329)|| (itemids[i]==3381)||(itemids[i]==3383)||(itemids[i]==3384)||(itemids[i]==3394)|| (itemids[i]==3395)||((itemids[i]>=3416)&&(itemids[i]<=3418))|| (itemids[i]==3440)||(itemids[i]==3461)||(itemids[i]==3476)||(itemids[i]==3480)|| (itemids[i]==3484)||(itemids[i]==3488)||(itemids[i]==3492)||(itemids[i]==3496)|| (itemids[i]==3512)||(itemids[i]==3513)||((itemids[i]>=4792)&&(itemids[i]<=4795))) { // sprintf(temp, "You can't see the forest for the trees!"); // sysmessage(s, temp); return blocked; } break; case 2 : // Walls, Chimneys, ovens, not fences if (((itemids[i]>=6)&&(itemids[i]<=748))||((itemids[i]>=761)&&(itemids[i]<=881))|| ((itemids[i]>=895)&&(itemids[i]<=1006))||((itemids[i]>=1057)&&(itemids[i]<=1061))|| (itemids[i]==1072)||(itemids[i]==1073)||((itemids[i]>=1080)&&(itemids[i]<=1166))|| ((itemids[i]>=2347)&&(itemids[i]<=2412))||((itemids[i]>=16114)&&(itemids[i]<=16134))|| ((itemids[i]>=8538)&&(itemids[i]<=8553))||((itemids[i]>=9535)&&(itemids[i]<=9555))|| (itemids[i]==12583)) { // sprintf(temp, "There seems to be some sort of wall in the way!"); // sysmessage(s, temp); return blocked; } break; case 4 : // Doors, not gates if (((itemids[i]>=1653)&&(itemids[i]<=1782))||((itemids[i]>=8173)&&(itemids[i]<=8188))) { // sprintf(temp, "Only ghosts do things through doors!"); // sysmessage(s, temp); return blocked; } break; case 8 : // Roofing Slanted if (((itemids[i]>=1414)&&(itemids[i]<=1578))||((itemids[i]>=1587)&&(itemids[i]<=1590))|| ((itemids[i]>=1608)&&(itemids[i]<=1617))||((itemids[i]>=1630)&&(itemids[i]<=1652))|| ((itemids[i]>=1789)&&(itemids[i]<=1792))) { // sprintf(temp, "The roof is too steep!"); // sysmessage(s, temp); return blocked; } break; case 16 : // Floors & Flat Roofing (Attacking through floors Roofs) if (((itemids[i]>=1169)&&(itemids[i]<=1413))||((itemids[i]>=1508)&&(itemids[i]<=1514))|| ((itemids[i]>=1579)&&(itemids[i]<=1586))||((itemids[i]>=1591)&&(itemids[i]<=1598))) { if (z1==z2) // in case of char and target on same roof { return not_blocked; } else { // sprintf(temp, "You would love to do that, but the is a floor in the way!"); // sysmessage(s, temp); return blocked; } } break; case 32 : // Lava, water if (((itemids[i]>=4846)&&(itemids[i]<=4941))||((itemids[i]>=6038)&&(itemids[i]<=6066))|| ((itemids[i]>=12934)&&(itemids[i]<=12977))||((itemids[i]>=13371)&&(itemids[i]<=13420))|| ((itemids[i]>=13422)&&(itemids[i]<=13638))||((itemids[i]>=13639)&&(itemids[i]<=13665))) { // sprintf(temp, "Yah, you wish!"); // sysmessage(s, temp); return blocked; } break; } // switch } //for } //for return not_blocked; } //function